Repository navigation
fix: keep MiniMax-H3 VAE weights resident across temporal chunks - #2103
Merged
Merged
Conversation
Each temporal chunk of the MiniMax-H3 video VAE decode and encode went through VAE::decode/VAE::encode, whose trailing runner_end() evicts the ~5GB weights from the compute backend, so the next chunk re-staged them (under auto-fit even re-reading the safetensors from disk). Keep the runner alive across the temporal chunk loop and end it once when the loop finishes. VAE::decode/VAE::encode gain a non-virtual overload with an auto_end flag; the virtual signatures are unchanged so existing overrides are unaffected.
losewayy
force-pushed
the
h3-vae-runner-lifetime
branch
from
October 6, 2026 07:32
2710b40 to
fb30e52
Compare
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Each temporal chunk of the MiniMax-H3 video VAE decode (and encode) goes through
VAE::decode/VAE::encode, whose trailingrunner_end()evicts the weights from the compute backend (~4.6GB for the decoder). With 7 temporal chunks per decode this re-stages the full weights 7 times, and under auto-fit on a VRAM-constrained GPU the params land on the disk tier, so every chunk re-reads the safetensors (~3s each, ~20s wasted per video).Keep the runner alive across the temporal chunk loop and end it once when the loop finishes.
VAE::decode/VAE::encodegain a non-virtual overload taking anauto_endflag (mirroringcompute()'sauto_runner_end); the virtual signatures are unchanged, so every existingoverridekeeps working.MiniMax-H3 is the only affected model: it is the only VAE runner that drives
VAE::decode/VAE::encodeinside a temporal chunk loop (Wan/LTX do temporal tiling inside_computewithin a single runner lifetime).Tested
sd-cli -M vid_gen, MiniMax-H3 (Q4_K DiT + Q2_K_M Qwen3-VL + fp16 video VAE), 864x480, 124 frames, 8 steps, seed 12345, auto-fit defaults, CUDA 13 / Windows / RTX 5070 Ti Laptop (12 GB)decode_first_stage: 53.4s -> 34.3s (-36%);generate_video: 299.7s -> 281.7s; decoded output is bit-identical to unpatched (per-frame pixel diff 0.0)The encode path shares the same defect and is fixed the same way; it cannot be exercised end-to-end on a 12 GB card because the H3 encoder workspace demand (~9.8GB per chunk) exceeds the device budget — the same failure occurs on unpatched stock, so this is not a regression.