From d54f6943390490f03ceaf579fb4d5a1158943e43 Mon Sep 17 00:00:00 2001 From: Will Lin Date: Sat, 22 Aug 2026 06:38:09 +0000 Subject: [PATCH] [bugfix] MiniMax-H3: prepare compile after FP8 conversion --- fastvideo/models/dits/minimax_h3.py | 12 +++++++++++- .../inference/test_inference_regional_compile.py | 16 +++++++++++++++- 2 files changed, 26 insertions(+), 2 deletions(-) diff --git a/fastvideo/models/dits/minimax_h3.py b/fastvideo/models/dits/minimax_h3.py index 8312af920..65c126cee 100644 --- a/fastvideo/models/dits/minimax_h3.py +++ b/fastvideo/models/dits/minimax_h3.py @@ -741,6 +741,13 @@ class MiniMaxH3Transformer3DModel(BaseDiT): compiled block forwards (H3 compiles per-block by default). Say so once instead of leaving the flag looking active. """ + compile_state = next(self.parameters(), None) + if compile_state is None: + compile_state = next(self.buffers(), None) + if compile_state is None: + raise RuntimeError("MiniMax H3 has no materialized parameter or buffer to identify its compile device.") + compile_device = compile_state.device + gate_states: list[bool] = [] prepared_vsa_impls = 0 for block in self.transformer_blocks: @@ -751,7 +758,10 @@ class MiniMaxH3Transformer3DModel(BaseDiT): gate_states.append(attention._gate_compress_active) prepare_vsa = getattr(attention.distributed_attention.attn_impl, "prepare_for_regional_compile", None) if callable(prepare_vsa): - prepare_vsa(attention.to_q.weight.device) + # Generic post-load quantization may replace to_q.weight with + # packed buffers before this hook runs. The transformer state + # remains materialized on the same local device. + prepare_vsa(compile_device) prepared_vsa_impls += 1 if gate_states: logger.info( diff --git a/fastvideo/tests/inference/test_inference_regional_compile.py b/fastvideo/tests/inference/test_inference_regional_compile.py index 418ff34ba..822672a1f 100644 --- a/fastvideo/tests/inference/test_inference_regional_compile.py +++ b/fastvideo/tests/inference/test_inference_regional_compile.py @@ -117,13 +117,27 @@ def _gate_model(*weights: float) -> MiniMaxH3Transformer3DModel: def test_minimax_h3_prepare_for_compile_resolves_loaded_vsa_gates() -> None: model = _gate_model(0.0, 2.0) + expected_device = next(model.parameters()).device model.prepare_for_compile() assert [block.attn._gate_compress_active for block in model.transformer_blocks] == [False, True] for block in model.transformer_blocks: impl = block.attn.distributed_attention.attn_impl - assert impl.devices == [block.attn.to_q.weight.device] + assert impl.devices == [expected_device] + + +def test_minimax_h3_prepare_for_compile_does_not_require_quantized_q_weight() -> None: + model = _gate_model(2.0) + attention = model.transformer_blocks[0].attn + removed_weight = attention.to_q._parameters.pop("weight") + attention.to_q.register_buffer("_fp8_weight", removed_weight.detach(), persistent=False) + expected_device = next(model.parameters()).device + + model.prepare_for_compile() + + impl = attention.distributed_attention.attn_impl + assert impl.devices == [expected_device] def test_unprepared_vsa_gate_cannot_mutate_cache_during_compile(monkeypatch) -> None: