Minimax H3 Stages#

class TextEncoderStage : public trt_edgellm::rt::multiStage::IStage#

How the video VAE splits a request into clips and tiles; the config.json of the VAE engine. ! ! The VAE decodes tileLatentFrames latent frames at a time, one clip of chunkLatentFrames per step, ! and cross-fades chunkFrameOverlap frames into the next clip. struct VideoLayout { int32_t spatialRatio{0}; int32_t temporalRatio{0}; int32_t tileLatentFrames{0}; int32_t tileLatentSize{0}; int32_t tileMinOverlap{0}; int32_t chunkLatentFrames{0}; int32_t chunkFramePadding{0}; int32_t chunkFrameOverlap{0};.

static VideoLayout fromConfig(nlohmann::json const& config);

int32_t tilePixels() const noexcept { return tileLatentSize * spatialRatio; }

! Frames each clip adds to the video. int32_t clipFrames() const noexcept { return chunkLatentFrames * temporalRatio - chunkFramePadding; }

! Latent frames of a video of numClips clips. int32_t latentFrames(int32_t numClips) const noexcept { return numClips * chunkLatentFrames + tileLatentFrames - chunkLatentFrames; } };

/*!

Prompt to the hidden state that conditions the denoiser.

Runs the Qwen3-VL text tower of text_encoder.engine on the prompt input, UTF-8 text or INT32 token ids, and publishes text_hidden: FP16 [1, tokens, hidden] on the device. The tokenizer is read from the artifact directory.

Public Functions

explicit TextEncoderStage(multiStage::StageInitContext const &init)#
virtual void preallocate() override#

Init-time allocation. Every device buffer this stage will ever use is claimed here, sized by maxBatch x maxSeq. Nothing on the step path may allocate.

virtual bool admit(
multiStage::StageExecContext const &ctx,
std::string &reason
) override#

Per-request admission. Reject here – it costs nothing – rather than failing mid-step.

Returns:

false plus a reason when this stage cannot serve the request.

virtual void prepare(multiStage::StageExecContext &ctx) override#

Per-request setup, once the inputs this stage reads are published. A throw fails only this request, so what prepare() writes must be this member’s own or scratch that the next member’s prepare() rewrites.

virtual multiStage::StageStatus step(
multiStage::StageExecContext &ctx
) override#
virtual void finish(
multiStage::StageExecContext &ctx,
multiStage::FinishReason reason
) override#

Called for every member on every active stage when run() ends: success, failure and cancellation alike. Emits the terminating chunk and reports metrics. A stage that only cleans up on success is a leak. take() without run() skips it; see reset().

virtual void reset() override#

Idempotent. Drops per-request state; anything longer-lived survives.

virtual nlohmann::json diagnostics(
multiStage::RequestSlot const &slot
) const override#

What this stage did on slot's request, for that caller’s report.

Read after finish() and before reset(). Keys are the stage’s own; the runtime nests them under the stage id and never interprets them. An empty object means the stage has nothing to say, which is the default. Taking the slot is what keeps a cohort’s members from all reporting the same numbers. A throw fails only that request, which keeps the other stages’ reports.

This is deliberately not gated on profiling: a caller needs to know why generation stopped even when no timing was collected.

class DenoiserStage : public trt_edgellm::rt::multiStage::IStage#

Rectified-flow denoising of the packed [text | audio | video] sequence, one step per call.

Reads the frame height, width, and num_frames from the style input and the noise seed from sampling. After the last step of gen.engine it publishes FP32 device latents: audio_latents [2, frames, channels] (left, then right) and video_latents [frames, height / 2, width / 2, channels * 4] over the latent grid.

Public Functions

explicit DenoiserStage(multiStage::StageInitContext const &init)#
virtual void preallocate() override#

Init-time allocation. Every device buffer this stage will ever use is claimed here, sized by maxBatch x maxSeq. Nothing on the step path may allocate.

virtual bool admit(
multiStage::StageExecContext const &ctx,
std::string &reason
) override#

Per-request admission. Reject here – it costs nothing – rather than failing mid-step.

Returns:

false plus a reason when this stage cannot serve the request.

virtual void prepare(multiStage::StageExecContext &ctx) override#

Per-request setup, once the inputs this stage reads are published. A throw fails only this request, so what prepare() writes must be this member’s own or scratch that the next member’s prepare() rewrites.

virtual multiStage::StageStatus step(
multiStage::StageExecContext &ctx
) override#
virtual void finish(
multiStage::StageExecContext &ctx,
multiStage::FinishReason reason
) override#

Called for every member on every active stage when run() ends: success, failure and cancellation alike. Emits the terminating chunk and reports metrics. A stage that only cleans up on success is a leak. take() without run() skips it; see reset().

virtual void reset() override#

Idempotent. Drops per-request state; anything longer-lived survives.

virtual nlohmann::json diagnostics(
multiStage::RequestSlot const &slot
) const override#

What this stage did on slot's request, for that caller’s report.

Read after finish() and before reset(). Keys are the stage’s own; the runtime nests them under the stage id and never interprets them. An empty object means the stage has nothing to say, which is the default. Taking the slot is what keeps a cohort’s members from all reporting the same numbers. A throw fails only that request, which keeps the other stages’ reports.

This is deliberately not gated on profiling: a caller needs to know why generation stopped even when no timing was collected.

class AudioDecoderStage : public trt_edgellm::rt::multiStage::IStage#

Stereo waveform from the denoised latents of the audio VAE, audio_decoder.engine.

Emits the request’s whole waveform on the audio terminal as one interleaved 16-bit chunk.

Public Functions

explicit AudioDecoderStage(multiStage::StageInitContext const &init)#
virtual void preallocate() override#

Init-time allocation. Every device buffer this stage will ever use is claimed here, sized by maxBatch x maxSeq. Nothing on the step path may allocate.

virtual bool admit(
multiStage::StageExecContext const &ctx,
std::string &reason
) override#

Per-request admission. Reject here – it costs nothing – rather than failing mid-step.

Returns:

false plus a reason when this stage cannot serve the request.

virtual void prepare(multiStage::StageExecContext &ctx) override#

Per-request setup, once the inputs this stage reads are published. A throw fails only this request, so what prepare() writes must be this member’s own or scratch that the next member’s prepare() rewrites.

virtual multiStage::StageStatus step(
multiStage::StageExecContext &ctx
) override#
virtual void finish(
multiStage::StageExecContext &ctx,
multiStage::FinishReason reason
) override#

Called for every member on every active stage when run() ends: success, failure and cancellation alike. Emits the terminating chunk and reports metrics. A stage that only cleans up on success is a leak. take() without run() skips it; see reset().

virtual void reset() override#

Idempotent. Drops per-request state; anything longer-lived survives.

virtual nlohmann::json diagnostics(
multiStage::RequestSlot const &slot
) const override#

What this stage did on slot's request, for that caller’s report.

Read after finish() and before reset(). Keys are the stage’s own; the runtime nests them under the stage id and never interprets them. An empty object means the stage has nothing to say, which is the default. Taking the slot is what keeps a cohort’s members from all reporting the same numbers. A throw fails only that request, which keeps the other stages’ reports.

This is deliberately not gated on profiling: a caller needs to know why generation stopped even when no timing was collected.

class VideoDecoderStage : public trt_edgellm::rt::multiStage::IStage#

Video frames from the denoised latents, one clip per call, with the tiled VAE of vae_decoder.engine.

Emits each clip on the video terminal as packed 8-bit RGB frames.

Public Functions

explicit VideoDecoderStage(multiStage::StageInitContext const &init)#
virtual void preallocate() override#

Init-time allocation. Every device buffer this stage will ever use is claimed here, sized by maxBatch x maxSeq. Nothing on the step path may allocate.

virtual bool admit(
multiStage::StageExecContext const &ctx,
std::string &reason
) override#

Per-request admission. Reject here – it costs nothing – rather than failing mid-step.

Returns:

false plus a reason when this stage cannot serve the request.

virtual void prepare(multiStage::StageExecContext &ctx) override#

Per-request setup, once the inputs this stage reads are published. A throw fails only this request, so what prepare() writes must be this member’s own or scratch that the next member’s prepare() rewrites.

virtual multiStage::StageStatus step(
multiStage::StageExecContext &ctx
) override#
virtual void finish(
multiStage::StageExecContext &ctx,
multiStage::FinishReason reason
) override#

Called for every member on every active stage when run() ends: success, failure and cancellation alike. Emits the terminating chunk and reports metrics. A stage that only cleans up on success is a leak. take() without run() skips it; see reset().

virtual void reset() override#

Idempotent. Drops per-request state; anything longer-lived survives.

virtual nlohmann::json diagnostics(
multiStage::RequestSlot const &slot
) const override#

What this stage did on slot's request, for that caller’s report.

Read after finish() and before reset(). Keys are the stage’s own; the runtime nests them under the stage id and never interprets them. An empty object means the stage has nothing to say, which is the default. Taking the slot is what keeps a cohort’s members from all reporting the same numbers. A throw fails only that request, which keeps the other stages’ reports.

This is deliberately not gated on profiling: a caller needs to know why generation stopped even when no timing was collected.

std::unique_ptr<multiStage::IStage> trt_edgellm::rt::minimax_h3::createAudioDecoderStage(
multiStage::StageInitContext const &init
)#
multiStage::RunnerDecl trt_edgellm::rt::minimax_h3::audioDecoderDeclaration(
)#
std::unique_ptr<multiStage::IStage> trt_edgellm::rt::minimax_h3::createDenoiserStage(
multiStage::StageInitContext const &init
)#
multiStage::RunnerDecl trt_edgellm::rt::minimax_h3::denoiserDeclaration(
)#
std::unique_ptr<multiStage::IStage> trt_edgellm::rt::minimax_h3::createTextEncoderStage(
multiStage::StageInitContext const &init
)#
std::unique_ptr<multiStage::IStage> trt_edgellm::rt::minimax_h3::createVideoDecoderStage(
multiStage::StageInitContext const &init
)#
multiStage::RunnerDecl trt_edgellm::rt::minimax_h3::textEncoderDeclaration(
)#
multiStage::RunnerDecl trt_edgellm::rt::minimax_h3::videoDecoderDeclaration(
)#