Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
18 commits
Select commit Hold shift + click to select a range
ce03136
Record four-device MiniMax-H3 lossless preflight contract
amy-why-3459 Nov 2, 2026
a42a0e0
Record first four-device full-compute warmup receipt
amy-why-3459 Nov 2, 2026
8710bbd
Record four-card H3 baseline repeatability and shutdown failure
amy-why-3459 Nov 2, 2026
9c528c7
Record clean four-rank H3 diagnostic shutdown
amy-why-3459 Nov 3, 2026
b804413
Freeze requested lossless thirty-percent latency target
amy-why-3459 Nov 3, 2026
9d15818
Record full fifteen-second baseline and dense attention bottleneck
amy-why-3459 Nov 3, 2026
15f291f
Preserve negative dense-kernel and QKV screening results
amy-why-3459 Nov 3, 2026
37e4ad5
Record rejected H3 residency and prompt attention screens
amy-why-3459 Nov 3, 2026
552b5db
Record interrupted pinned-host screen and TP4 follow-up
amy-why-3459 Nov 3, 2026
c189b2f
Preserve H3 TP4 placement regression and operator screening
amy-why-3459 Nov 3, 2026
f5b76d8
Record H3 placement fix NPU validation and next dense screening
amy-why-3459 Nov 3, 2026
54118d0
Retain H3 hybrid capacity failure and query partition results
amy-why-3459 Nov 3, 2026
6c86fcc
Preserve H3 denoise interval analysis and fused projection plan
amy-why-3459 Nov 3, 2026
b54dc33
Record FIA v2 negative screen and prospective queue revision
amy-why-3459 Nov 3, 2026
df3723c
Record fused projection screening and exact Laser layout candidate
amy-why-3459 Nov 3, 2026
14de17a
Record strict elementwise H3 acceptance and operator screens
amy-why-3459 Nov 3, 2026
4298c2a
Distinguish frozen H3 preflight status from the current receipt
cursoragent Nov 4, 2026
b566845
Merge main into amy/h3-ref2va-4x910b1 to resolve PR #321 conflicts
cursoragent Nov 4, 2026
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions evidence/h3-ref2va-4x910b1-320/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
# MiniMax-H3 Ref2VA on four Ascend 910B1 devices

Governing [issue #320](https://github.com/InferMatrixLab/InferRSI/issues/320). This is preparation evidence, **INCONCLUSIVE**, with no performance or quality claim. Original runtime logs, local launch scripts, weights and generated media remain external. Public receipts will retain negative and incomplete results without exposing private paths or unrelated device users.
3 changes: 3 additions & 0 deletions evidence/h3-ref2va-4x910b1-320/patch/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
# Candidate status

No engine change is made by this preparation. Original source is pinned in the RunSpec. Existing eight-device lifecycle and QKV changes are candidate sources, not qualified four-device improvements. Configuration changes also require separate measurements and attribution.
152 changes: 152 additions & 0 deletions evidence/h3-ref2va-4x910b1-320/patch/laser-fp16-layout-candidate.patch
Original file line number Diff line number Diff line change
@@ -0,0 +1,152 @@
diff --git a/docs/user_guide/diffusion/attention_backends/dense_backends.md b/docs/user_guide/diffusion/attention_backends/dense_backends.md
index 2cb7019be..53535e65e 100644
--- a/docs/user_guide/diffusion/attention_backends/dense_backends.md
+++ b/docs/user_guide/diffusion/attention_backends/dense_backends.md
@@ -31,6 +31,21 @@ when a compatible package is installed.
vllm-omni serve <model> --diffusion-attention-backend FLASH_ATTN
```

+### Experimental Ascend Laser input layout
+
+For the packed-prefix BF16 path with `MINDIE_SD_FA_TYPE=ascend_laser_attention`,
+`--additional-config '{"npu_laser_fp16_layout":true}'` requests a contiguous
+head-first FP16 cast before calling the public MindIE attention API. This
+combines dtype conversion with layout materialization while preserving the
+FP16 input and BF16 output conversion boundaries of MindIE-SD 3.1 Laser.
+Model-provided input scaling and valid-prefix slicing remain in effect.
+
+The option defaults to false. It is intended for the legacy FP16 Laser path;
+it does not preserve the arithmetic of newer native-BF16 Laser implementations.
+Synthetic operator parity is insufficient to establish model quality or
+end-to-end speedup. Validate the installed MindIE version and actual workload
+before enabling it.
+
### FlashAttention 4 on Blackwell

Install the optional CUDA 13 extra:
diff --git a/tests/diffusion/attention/test_flash_attn.py b/tests/diffusion/attention/test_flash_attn.py
index 1da5894cc..1c6798ea3 100644
--- a/tests/diffusion/attention/test_flash_attn.py
+++ b/tests/diffusion/attention/test_flash_attn.py
@@ -1373,6 +1373,68 @@ def test_prefix_kv_slice_no_scaling_without_factor(monkeypatch):
torch.testing.assert_close(out, torch.ones(1, 8, 2, 4))


+@pytest.mark.cpu
+@pytest.mark.parametrize("input_scale", [1.0, 256.0])
+@pytest.mark.parametrize("dtype", [torch.bfloat16, torch.float32])
+def test_laser_fp16_layout_preserves_conversion_boundaries(monkeypatch, input_scale, dtype):
+ monkeypatch.setenv("MINDIE_SD_FA_TYPE", "ascend_laser_attention")
+ calls = []
+
+ def reference_adapter(query, key, value, *, head_first=False, **kwargs):
+ calls.append((query, key, value, head_first, kwargs))
+ output_dtype = query.dtype
+ tensors = (query, key, value) if head_first else (x.transpose(1, 2) for x in (query, key, value))
+ q, k, v = (x.to(torch.float16).contiguous() for x in tensors)
+ # A deterministic stand-in for the unchanged native kernel. This test
+ # checks the real adapter's dtype/layout/range boundaries, not Laser.
+ out = q.float() * 1.3 + k.float().mean(2, keepdim=True) + v.float().mean(2, keepdim=True)
+ out = out.to(torch.float16).to(output_dtype)
+ return out if head_first else out.transpose(1, 2)
+
+ _fake_mindiesd(monkeypatch, attention_forward=reference_adapter)
+ impl = _npu_impl()
+ q, k, v = (torch.randn(1, 16, 2, 4, dtype=dtype)[:, ::2] for _ in range(3))
+ cu = torch.tensor([0, 5, 8], dtype=torch.int32)
+ extra = {
+ "cu_seqlens_q": cu,
+ "cu_seqlens_k": cu,
+ "max_seqlen_q": 5,
+ "max_seqlen_k": 5,
+ "laser_input_scale": input_scale,
+ }
+ baseline = impl._forward_prefix_kv_slice_npu(q, k, v, extra)
+ impl.npu_laser_fp16_layout = True
+ candidate = impl._forward_prefix_kv_slice_npu(q, k, v, extra)
+ assert candidate.dtype == dtype and candidate.shape == q.shape
+ assert torch.equal(baseline, candidate)
+ cq, ck, cv, head_first, kwargs = calls[-1]
+ assert head_first is (dtype == torch.bfloat16)
+ if head_first:
+ assert all(x.is_contiguous() and x.dtype == torch.float16 for x in (cq, ck, cv))
+ assert cq.shape == (1, 2, 8, 4) and ck.shape == cv.shape == (1, 2, 5, 4)
+ assert kwargs["attn_mask"] is None
+ assert kwargs["scale"] == 0.5 * input_scale**2
+
+
+@pytest.mark.cpu
+def test_laser_fp16_layout_requires_boolean_config(monkeypatch):
+ from vllm_omni.diffusion.attention.backends import flash_attn
+
+ monkeypatch.setattr(
+ flash_attn,
+ "get_current_diffusion_config_or_none",
+ lambda: SimpleNamespace(additional_config={"npu_laser_fp16_layout": "false"}),
+ )
+ with pytest.raises(ValueError, match="must be a boolean"):
+ _npu_impl()
+ monkeypatch.setattr(
+ flash_attn,
+ "get_current_diffusion_config_or_none",
+ lambda: SimpleNamespace(additional_config={"npu_laser_fp16_layout": True}),
+ )
+ assert _npu_impl().npu_laser_fp16_layout is True
+
+
# --- Test group E: NPU piecewise block-causal attention ----------------------
#
# ``forward_fa_npu`` must honour ``full_attn_spans`` the way ``forward_cuda``
diff --git a/vllm_omni/diffusion/attention/backends/flash_attn.py b/vllm_omni/diffusion/attention/backends/flash_attn.py
index 87cb63121..cd9b95bf4 100644
--- a/vllm_omni/diffusion/attention/backends/flash_attn.py
+++ b/vllm_omni/diffusion/attention/backends/flash_attn.py
@@ -281,6 +281,10 @@ class FlashAttentionImpl(AttentionImpl[AttentionMetadata]):
self._kernel_variant = "fa4" if IS_FLASH_ATTN_4 else "aiter" if IS_AITER else None
cfg = get_current_diffusion_config_or_none()
self.fa_deterministic = bool(getattr(cfg, "fa_deterministic", False)) if cfg is not None else False
+ additional = getattr(cfg, "additional_config", None) or {}
+ self.npu_laser_fp16_layout = additional.get("npu_laser_fp16_layout", False)
+ if not isinstance(self.npu_laser_fp16_layout, bool):
+ raise ValueError("npu_laser_fp16_layout must be a boolean")
if backend_kwargs:
logger.warning("FlashAttentionImpl ignoring backend_kwargs: %s", list(backend_kwargs.keys()))

@@ -1313,6 +1317,7 @@ class FlashAttentionImpl(AttentionImpl[AttentionMetadata]):
"""
self._warn_fa_deterministic_non_dense("piecewise-npu")
logger.debug("Using piecewise NPU attention for mixed causal/full mask")
+ assert attn_metadata.full_attn_spans is not None
return piecewise_attn(
query,
key,
@@ -1458,6 +1463,29 @@ class FlashAttentionImpl(AttentionImpl[AttentionMetadata]):
def _postprocess(out: torch.Tensor) -> torch.Tensor:
return out * input_scale if preserve_input_range else out

+ if self.npu_laser_fp16_layout and query.dtype == torch.bfloat16:
+ # Preserve the MindIE-SD 3.1 Laser FP16 conversion boundaries,
+ # while materializing BNSD during the cast instead of copying
+ # once for dtype and again for contiguous layout. Keep opt-in:
+ # newer native-BF16 Laser implementations have different math.
+ output_dtype = query.dtype
+ q, k, v = (
+ tensor.transpose(1, 2).to(dtype=torch.float16, memory_format=torch.contiguous_format)
+ for tensor in (query, key, value)
+ )
+ out = attention_forward(
+ q,
+ k,
+ v,
+ attn_mask=None,
+ head_first=True,
+ opt_mode="manual",
+ op_type="ascend_laser_attention",
+ layout=layout,
+ scale=scale,
+ )
+ return _postprocess(out.to(output_dtype).transpose(1, 2))
+
return _postprocess(
attention_forward(
query,
96 changes: 96 additions & 0 deletions evidence/h3-ref2va-4x910b1-320/patch/tp4-denoise-placement.patch
Original file line number Diff line number Diff line change
@@ -0,0 +1,96 @@
diff --git a/docs/design/feature/offloader/module_offload.md b/docs/design/feature/offloader/module_offload.md
index 43ef49194..3b73dcffd 100644
--- a/docs/design/feature/offloader/module_offload.md
+++ b/docs/design/feature/offloader/module_offload.md
@@ -46,6 +46,11 @@ contract:
setup; and
- disabling removes all model-local offload hooks or contexts.

+Preparation that reads component buffers before its first `forward` must also
+enter the component's residency context. MiniMax-H3 enters that context before
+denoise-time RoPE table preparation. On context exit, explicit selection still
+controls offloading: an unselected DiT remains device resident.
+
The delegation is currently duck typed. If another independent implementation
is added, formalize the enable/disable pair as a protocol rather than expanding
attribute-name heuristics.
diff --git a/tests/diffusion/models/minimax_h3/test_ref2va_initial_noise_preparation.py b/tests/diffusion/models/minimax_h3/test_ref2va_initial_noise_preparation.py
index a2f2bc517..1579b690f 100644
--- a/tests/diffusion/models/minimax_h3/test_ref2va_initial_noise_preparation.py
+++ b/tests/diffusion/models/minimax_h3/test_ref2va_initial_noise_preparation.py
@@ -3,7 +3,9 @@

import weakref
from concurrent.futures import ThreadPoolExecutor
+from contextlib import nullcontext
from threading import Event
+from types import SimpleNamespace

import pytest
import torch
@@ -138,6 +140,45 @@ def test_consumed_host_noise_is_released_before_denoising(pipeline, monkeypatch)
)


+def test_module_offload_places_dit_before_denoise_preparation(pipeline, monkeypatch):
+ from vllm_omni.diffusion.models.minimax_h3 import pipeline_minimax_h3 as module
+ from vllm_omni.diffusion.offloader import apply_sequential_offload, sequential_backend
+
+ # A real CPU-to-meta move exposes preparation before the first forward
+ # without requiring an accelerator or a model checkpoint.
+ transformer = torch.nn.Module()
+ transformer.register_buffer("inv_freq", torch.ones(4))
+ pipeline.transformer = transformer
+ pipeline.device = torch.device("meta")
+ # Adapt only the accelerator boundary: Tensor.data cannot be reassigned
+ # from CPU to meta, whereas Module.to supports this allocation-free move.
+ monkeypatch.setattr(sequential_backend.SequentialOffloadHook, "_to_gpu", lambda hook, model: model.to(hook.device))
+ monkeypatch.setattr(
+ sequential_backend,
+ "current_omni_platform",
+ SimpleNamespace(synchronize=lambda: None, get_free_memory=lambda: 0),
+ )
+ apply_sequential_offload(
+ [transformer],
+ [],
+ device=pipeline.device,
+ pin_memory=False,
+ offload_dit_modules=(),
+ )
+ pipeline._model_cpu_offload_modules = [transformer]
+ monkeypatch.setattr(pipeline, "progress_bar", lambda **kwargs: nullcontext(SimpleNamespace(update=lambda: None)))
+
+ def prepare_before_first_forward(**kwargs):
+ assert kwargs["model"].inv_freq.device == pipeline.device
+ raise RuntimeError("preparation device checked")
+
+ monkeypatch.setattr(module, "minimax_h3_denoise_loop", prepare_before_first_forward)
+ with pytest.raises(RuntimeError, match="preparation device checked"):
+ pipeline.diffuse(**_ref2va_kwargs(42))
+ # Encoder-only offload must keep the unselected DiT resident on exit.
+ assert transformer.inv_freq.device == pipeline.device
+
+
@pytest.mark.parametrize("failure_stage", ["text", "media"])
def test_encoder_failure_cancels_pending_noise_and_joins_worker(pipeline, monkeypatch, failure_stage):
from vllm_omni.diffusion.models.minimax_h3 import pipeline_minimax_h3 as module
diff --git a/vllm_omni/diffusion/models/minimax_h3/pipeline_minimax_h3.py b/vllm_omni/diffusion/models/minimax_h3/pipeline_minimax_h3.py
index 476c3cca8..939b06481 100644
--- a/vllm_omni/diffusion/models/minimax_h3/pipeline_minimax_h3.py
+++ b/vllm_omni/diffusion/models/minimax_h3/pipeline_minimax_h3.py
@@ -2368,7 +2368,14 @@ class MiniMaxH3Pipeline(
cache_runtime = getattr(self, "_cache_dit_runtime", None)
if cache_runtime is not None:
cache_runtime.refresh(len(inputs["sigmas_video"]) - 1)
- with self._resident_dit_layers_on_device(enabled=transformer is self.transformer):
+ # RoPE preparation runs before the first transformer forward, so its
+ # buffers must already be placed by the module-offload hook.
+ component_scope = (
+ self._component_on_device(transformer)
+ if getattr(self, "_model_cpu_offload_modules", None)
+ else nullcontext()
+ )
+ with component_scope, self._resident_dit_layers_on_device(enabled=transformer is self.transformer):
with self.progress_bar(total=len(inputs["sigmas_video"]) - 1) as progress:
video_rows, audio_rows = minimax_h3_denoise_loop(
sampler=inputs["sampler"],
9 changes: 9 additions & 0 deletions evidence/h3-ref2va-4x910b1-320/plan/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
# Four-device preflight plan

This scope is 4x Ascend 910B1, not eight devices or 910C. See [acceptance issue](https://github.com/InferMatrixLab/InferRSI/issues/320).

The initial 5s preflight runs two warmups and one measured request, 50 steps, seed zero. It is not a formal A/B or final acceptance. Startup is excluded from HTTP timing. The original baseline shutdown remains intact, so its known eight-device lifecycle concern must be checked here rather than silently repaired. Full 15s execution and independent paired comparisons remain pending.

Runtime wrapper adapts the existing #293 harness: device-count assertion and all parallelism flags are four; output namespace and service port are isolated. Only the dense baseline arm is enabled. Outer reservation budget is five hours, with a 280-minute command deadline and 180-second kill grace; HTTP and DLO wave timeouts are 7200 seconds. This is a bringup ceiling, not a measured latency or a final experiment budget.

The allocated physical IDs are recorded at execution. NPU scheduling is respected; no resource is claimed before allocation. Later A/B work must pin the same allocation throughout the pair and independently freeze its budget and order.
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
{
"plan/acceptance-30pct.json": "fa3edf7110bb18bf05ed9f95b93fbd3cf7aecff2a57729155bb61c8dd24e1f84"
}
19 changes: 19 additions & 0 deletions evidence/h3-ref2va-4x910b1-320/plan/acceptance-30pct.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
{
"target": "At least30percent lower E2E latency without quality loss",
"metric": "1 - candidate_e2e_ms / matched_baseline_e2e_ms >= 0.30",
"workloads_s": [
5,
15
],
"hardware": "Same4physical Ascend910B1 devices",
"precision": "BF16; full50steps; same dense attention and inputs; no approximate cache, sparsity, quantization or distillation",
"evidence_required": [
"Separate matched baseline/candidate repetitions at both durations with clean worker lifecycle",
"Individual optimization attribution plus directly measured final combination",
"Independent audio/video coverage and quality checks; baseline nondeterminism explicitly adjudicated",
"Frozen source/runtime/input identity; no profiler or CPU scoring concurrent with timing",
"One engine PR and RSI evidence publication"
],
"status": "Not achieved. Existing5s814.064s sample is feasibility-only, not the final acceptance denominator.",
"target_note": "Latency reduction30percent is stricter than throughput1.30x; this campaign uses latency reduction to match requested E2E objective."
}
13 changes: 13 additions & 0 deletions evidence/h3-ref2va-4x910b1-320/plan/acceptance-elementwise-v2.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
{
"recorded_at": "2026-11-03T09:38:07.485443+00:00",
"supersedes_lossless_adjudication_only": "acceptance-30pct.json",
"user_instruction": "必须逐元素一致;不接受仅靠质量指标判定无损",
"requirements": [
"Elementwise exact model output tensors and decoded audio/video equality; perceptual thresholds cannot substitute for equality.",
"Baseline nondeterminism does not excuse candidate mismatch. Locate and resolve repeatability before final acceptance.",
"Keep full 50 steps, BF16, dense compute, frozen inputs and same 4x910B1 devices.",
"Matched E2E latency reduction >=30% independently for 5s and 15s, clean lifecycle and complete requests.",
"Operator equality is screening only, not end-to-end lossless acceptance."
],
"target_achieved": false
}
18 changes: 18 additions & 0 deletions evidence/h3-ref2va-4x910b1-320/plan/input-source-audit.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
{
"source_revision": "c7f56f0155953c7d4a77276a2f4fcbd844ab0da2",
"source_file": "tests/e2e/accuracy/minimax_h3/test_minimax_h3_i2va_ref2va_similarity.py",
"prompt_sha256": "91c1340ea893aede82312dec30a6ae8c975c1def921348fc1cc45ccc86b315dd",
"comparisons": [
{
"constant": "I2VA_PROMPT",
"exact": false,
"stripped_equal": false
},
{
"constant": "REF2VA_PROMPT",
"exact": true,
"stripped_equal": true
}
],
"scope": "Source/input identity only; no quality acceptance"
}
8 changes: 8 additions & 0 deletions evidence/h3-ref2va-4x910b1-320/plan/preflight-integrity.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
{
"README.md": "d5822814310a69a38020d9ea161d7fbd65e1172d378ddd3754ec774814ac5f1e",
"plan/runspec.json": "a953c51e12cb5d9d6e3772de7662502495081e63c9bb63ee4ba970fa85e3a90b",
"plan/README.md": "0a69099873380e1df33668c29ac13e446c91f032e6bcc4f9acbf1cfb741dcd03",
"results/status.json": "8e24eafc59dfc6b21ee9fe86f6b31abb7811796c6eab343b817d0a0d67eb5294",
"patch/README.md": "cb31b290e76ef8ae3c416f3cca9558ed8c37d7deaf8bbbb192231004d8fb3760",
"validator/README.md": "f9e01f0416e51c8f86ad7162eeb6fcc7c5f1cc0b3c5ce5f0e8a7651e9d5fc4bc"
}
33 changes: 33 additions & 0 deletions evidence/h3-ref2va-4x910b1-320/plan/runspec.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
{
"status": "preflight_only",
"hardware": "4x Ascend 910B1 64GiB",
"baseline": "c7f56f0155953c7d4a77276a2f4fcbd844ab0da2",
"workload": {
"width": 1344,
"height": 768,
"fps": 24,
"steps": 50,
"seed": 0,
"durations_s": [
5,
15
],
"concurrency": 1
},
"preflight": {
"duration_s": 5,
"warmups": 2,
"measured": 1,
"limitation": "bringup and repeatability only; not formal speedup evidence"
},
"lossless": "No cache, quantization, sparse attention, distillation or reduced steps. Exact decoded parity is sufficient; nonidentical output is not accepted on perceptual thresholds alone. Assess baseline repeatability first.",
"later_validation": "Freeze individual candidate and final ABBA protocols before search; quality independent of timing; raw complete HTTP samples, stage diagnostics separately, all-rank memory and exits.",
"sources": [
"https://github.com/vllm-project/vllm-omni/pull/9698",
"https://github.com/InferMatrixLab/InferRSI/pull/318",
"https://github.com/vllm-project/vllm-omni/pull/5929",
"https://github.com/vllm-project/vllm-omni/pull/5764",
"https://github.com/vllm-project/vllm-omni/pull/4150"
],
"issue": "https://github.com/InferMatrixLab/InferRSI/issues/320"
}
Loading
Loading