Nodes/BSAI-ComfyUI-FastH3/BSAI FastH3 Euler Sampler (4-step / 8-step / OmniRef)
ComfyUI Node

BSAI FastH3 Euler Sampler (4-step / 8-step / OmniRef)

Keeping H3's Audio Track From Drifting

By xm6018924·Created 2 months ago·Updated 9 days ago· 9
BSAI FastH3 Euler Sampler (4-step / 8-step / OmniRef)
    • SAMPLER
    ◄shift_video12.00►
    ◄shift_audio3.00►
    ◄schedule_modeauto►
    ◄recipe8-step OmniRef (999,874,749,624,500,375,250,125 · shift 12/3 · keep 10%)►

    H3 generates video and audio together, which means your latent isn't one thing - it's a packed sequence with a video span and an audio span, and those two want different noise schedules. Video runs at flow shift 12 (10 on the V2 checkpoint). Audio runs at shift 3. Hand a stock Euler sampler that latent and it advances both parts on the same curve: the picture may look fine while the audio gets progressively further out of step with it.

    BSAIFastH3EulerSampler is a small Euler implementation that knows about both halves. It's the actual sampler, not a scheduler wrapper - you wire it into SamplerCustomAdvanced.sampler, alongside BSAIFastH3Timesteps feeding sigmas.

    How it works

    Under the hood it's a KSAMPLER wrapping a hand-written Euler loop: predict the denoised latent, form the derivative as (x - denoised) / sigma, step by the sigma delta. Nothing clever there, and that's the point - Euler is the sampler FastH3's distillation was evaluated on, and a distilled 4-step model has no denoising budget to spend on a fancier integrator's assumptions.

    The interesting part is the two schedule modes.

    On native - which auto selects whenever the model's sampling object exposes an audio shift, i.e. ComfyUI 0.31+ with ModelSamplingAV - the model handles the audio/video split itself and the sampler just advances the whole latent on one schedule. Clean, and it's what you want on a current install.

    On legacy_dual it splits the latent by element count: everything before the video span's size is video, the rest is audio. Video takes the plain Euler step; audio gets its sigma remapped through the same flow-shift transform that maps shift 12 onto shift 3, then divided by the transform's slope so the step size stays consistent. That's the arithmetic that keeps a spoken line landing where the mouth is.

    The four inputs

    recipe is the sane way in. 4-step Preview gives video 12 / audio 3, 8-step V2 gives video 10 / audio 3, 3-step TaoMate gives 12 / 3. Those shift values are the checkpoint's contract - V2 at shift 12 is the single most common FastH3 mistake, because everyone learned "12" from the 4-step card and never updated. This node also exposes shift_video and shift_audio directly, but they only apply when recipe is custom; otherwise the preset wins and your typed numbers are politely ignored.

    schedule_mode is auto, native, or legacy_dual. Leave it on auto unless you're deliberately reproducing an older graph or you've patched the model in a way that hides its audio shift - then force one and see which behaves.

    Output is a single SAMPLER. It goes into SamplerCustomAdvanced's sampler slot. That node takes no step count: the number of steps comes entirely from the length of the SIGMAS you feed it, which is why the timesteps node and this one are a matched pair. Four sigmas intervals, four forwards, four steps. You cannot accidentally run a 4-step model for twenty steps, and you don't get to "just add a few steps" either - the ladder is the ladder.

    Install

    Manager → BSAI-ComfyUI-FastH3. Or:

    cd ComfyUI/custom_nodes
    git clone https://github.com/xm6018924/BSAI-ComfyUI-FastH3.git
    

    Restart ComfyUI. No requirements file, no extra pip install for this node specifically; comfy_kitchen only matters if you want the native sparse-attention kernel in the VSA node. Weights are the pack's shared set - the FastH3 _4step or _8step/v2 checkpoint, the Qwen3-VL text encoder, int8 video VAE, fp32 audio VAE.

    Where it goes wrong

    BSAI FastH3 Euler requires a MiniMax-H3 video+audio latent is the one error you'll actually hit, and it only comes from legacy_dual. That path needs to know the latent's packed shapes to split video from audio, and it reads them from the conditioning; feed it a plain video latent - something from a non-H3 pipeline, or a graph where the conditioning got rebuilt - and it has no idea where the audio starts. Use a latent produced by EmptyMiniMaxH3LatentAV or the H3 image-to-video node.

    Audio that drifts out of sync late in the clip usually means auto picked dual-schedule on a build that has native ModelSamplingAV, or a mismatch between the shift on the sampler and the shift patched onto the model by the VSA node. Both values are printed in the VSA stats output as model shift (v/a) - if that says 12/3 while your sampler recipe says V2, you found it.

    The console prints every step with its sigma transition and, in dual mode, the RMS of the video and audio halves. Audio RMS collapsing toward zero mid-run is a real signal that something upstream is wrong.

    One more: don't stack a speed LoRA on top and expect the sampler to sort it out. The 3-step TaoMate LoRA is a different distillation on a different base, and stacking it on FastH3 V2 is an unofficial combo the pack author leaves to recipe=custom territory. Off the official recipes, change one thing at a time.

    CategoryBSAI/FastH3

    Inputs (4)

    NameTypeDefaultDescription
    shift_videoFLOAT12.000.01–100Video-stream flow shift (FastH3 official shift-12 rectified schedule).
    shift_audioFLOAT3.000.01–100Audio-stream flow shift (FastH3 official shift-3).
    schedule_modeCOMBOautoauto: detect ModelSamplingAV; single-schedule Euler if present, otherwise dual audio/video schedule. native: force single schedule. legacy_dual: force dual schedule.
    recipeCOMBO8-step OmniRef (999,874,749,624,500,375,250,125 · shift 12/3 · keep 10%)Official one-click recipe shift presets. 4-step / OmniRef: video 12 / audio 3; 8-step V2: video 10 / audio 3 (note V2 video shift is NOT 12!); 3-step TaoMate: video 12 / audio 3. custom: use the shift parameters above.

    Outputs (1)

    NameTypeDescription
    SAMPLERSAMPLER—