Repository navigation
[WS1][CUDA][MiniMax-H3] ws1_one_h3_block + full-model qualification: block 0 node-by-node and 50-block/generation gates (RFC #420 stack 10/10) - #539
Open
fusheng-ji wants to merge 265 commits into
Conversation
Signed-off-by: Wenbo Ji <36562829+fusheng-ji@users.noreply.github.com>
Signed-off-by: Wenbo Ji <36562829+fusheng-ji@users.noreply.github.com> # Conflicts: # csrc/ops.cpp
Signed-off-by: Wenbo Ji <36562829+fusheng-ji@users.noreply.github.com>
Signed-off-by: Wenbo Ji <36562829+fusheng-ji@users.noreply.github.com> # Conflicts: # scripts/plot_h3_evidence.py
Signed-off-by: Wenbo Ji <36562829+fusheng-ji@users.noreply.github.com>
Signed-off-by: Wenbo Ji <36562829+fusheng-ji@users.noreply.github.com>
Signed-off-by: Wenbo Ji <36562829+fusheng-ji@users.noreply.github.com>
Validate pinned tensor contents at preparation and load time. Execute chain prerequisites for selected stages and require checkpoint weights for weighted evidence. Reject invalid CUDA tile and backward inputs, align the CUDA wrapper guards, skip unsupported devices, and rotate comparative timing with raw samples. Validation: 143 H3 tests passed on B200 after a fresh CUDA build; illegal FP32 tiles fail compilation; isolated AdaLN replay and pinned-weight evidence generation passed; Black, isort, Ruff, and Flake8 passed. Signed-off-by: Wenbo Ji <36562829+fusheng-ji@users.noreply.github.com>
Check timestep and modality bounds on the device before computing gather addresses, including unchecked calls and overflowing int64 indices. Reject non-prefix replay stage selections and partial backward chains before loading weights. Validation: rebuilt the CUDA extension on B200; tests/h3: 175 passed, including 12 isolated native bounds probes and 16 CLI regressions. Signed-off-by: Wenbo Ji <36562829+fusheng-ji@users.noreply.github.com>
CodeRabbit skips automatic reviews targeting non-default branches by default. Allow the test-h3 base branch so pushes to the H3 stack receive incremental reviews. Validation: configuration validated against the official CodeRabbit JSON schema. Signed-off-by: Wenbo Ji <36562829+fusheng-ji@users.noreply.github.com>
Include the RFC 420 target branch in CodeRabbit automatic reviews so pushes to the H3 stack are reviewed instead of silently skipped. Validation: configuration parses and validates against the published CodeRabbit v2 schema; the additional branch pattern matches only test-h3. Signed-off-by: Wenbo Ji <36562829+fusheng-ji@users.noreply.github.com>
Signed-off-by: Wenbo Ji <36562829+fusheng-ji@users.noreply.github.com>
Signed-off-by: Wenbo Ji <36562829+fusheng-ji@users.noreply.github.com>
Signed-off-by: Wenbo Ji <36562829+fusheng-ji@users.noreply.github.com>
Signed-off-by: Wenbo Ji <36562829+fusheng-ji@users.noreply.github.com>
Signed-off-by: Wenbo Ji <36562829+fusheng-ji@users.noreply.github.com>
Signed-off-by: Wenbo Ji <36562829+fusheng-ji@users.noreply.github.com>
Signed-off-by: Wenbo Ji <36562829+fusheng-ji@users.noreply.github.com>
Signed-off-by: Wenbo Ji <36562829+fusheng-ji@users.noreply.github.com>
Signed-off-by: Wenbo Ji <36562829+fusheng-ji@users.noreply.github.com>
Signed-off-by: Wenbo Ji <36562829+fusheng-ji@users.noreply.github.com>
…on, byte-equal to WS1 RFC RL-Align#420 WS2 row `tp_adaln_3mod` (stacked on final_adaln_out). - Ownership: rank r owns the contiguous output columns [r*N/tp, (r+1)*N/tp) of the 3 x 6 x 5376 table (the same weight/bias rows); N/tp must be a multiple of the 64-row d_input chunk, so a shard never splits a WS1 partial. Unsupported TP sizes fail closed. - Every floating-point op is the WS1 kernel: the local tensor-core GEMV gives the WS1 columns, a rank-ordered all-gather (a copy) rebuilds the table, dW/db are shard-local, and d_temb all-gathers the WS1 chunk partials and runs the WS1 ascending fold on every rank. No collective reduction arithmetic. - det_linear: d_input split into h3_det_linear_backward_input_partials and h3_det_linear_fold_chunks (same kernels; backward_input composes them). - ws2_comm.gather_rows: rank-ordered row gather that pads outputs of at most 256 KiB past DeterministicCollective's single-block byte-copy path (~4 us/KiB); keeps the T = 1 forward at ~0.12 ms. - Readback: tp, rank, owned columns and (modality, chunk) slots, collective backend, kernel ids, fallback. - Tests: ownership, single-GPU shard arithmetic (columns and chunk partials equal the WS1 slice, the fold equals WS1 d_input), fail-closed inputs, and real NCCL TP2/4/8 on the pinned block-0 weights. - scripts/h3_ws2_evidence.py + figure; operator doc. Signed-off-by: Wenbo Ji <36562829+fusheng-ji@users.noreply.github.com>
…ated residual, byte-equal to WS1 RFC RL-Align#420 WS2 row `sp_norm_adaln` (stacked on tp_adaln_3mod). - Ownership: rank r holds packed positions [r*S//sp, (r+1)*S//sp) of every batch item with the matching metadata; any S >= sp. The (S,) row index is replicated and every rank derives the same reduction plan from it. - Forward, dx, d_sublayer and d_residual: the WS1 kernels on local rows. - d_norm_weight, d_shift/d_scale, d_gate keep the WS1 two-level order (256-element tiles, then an ascending fold): each tile is computed by the rank holding its first row, after all-gathering the tile's rows from other ranks (only tiles crossing a shard boundary move rows); the partials are all-gathered into WS1 tile order and every rank runs the WS1 fold. Rank-ordered all-gathers only; no collective arithmetic. - New bindings around the unchanged WS1 kernels: h3_rmsnorm_backward_{dx,partials}, h3_rmsnorm_fold_partials, h3_gate_residual_backward_dy, h3_gate_grad_{partials,fold}; the WS1 dweight tile kernel also takes explicit row lists (same arithmetic). - The plan is built once per index object and shared by every norm and gated residual that uses it. - Tests: layout, per-rank backward vs WS1 for SP 2-8 on one GPU (odd S, B = 2, shards smaller than a tile, block and interleaved packing, bf16/fp32), fail-closed inputs, and the autograd block region over real NCCL SP2/4/8. - h3_block_layout (H3's block packing), evidence sweep with rows exchanged, timing and a naive-SP comparison; figure; operator doc. Signed-off-by: Wenbo Ji <36562829+fusheng-ji@users.noreply.github.com>
…gure Produced by scripts/h3_ws2_evidence.py --worlds 1,2,4,8 at 4947996 on a clean tree (real NCCL, one GPU per rank); rendered with scripts/plot_h3_evidence.py and embedded in the operator doc. Signed-off-by: Wenbo Ji <36562829+fusheng-ji@users.noreply.github.com>
…gure Produced by scripts/h3_ws2_evidence.py --op sp_norm_adaln --worlds 1,2,4,8 at 6c0d380 on a clean tree (real NCCL, one GPU per rank); rendered with scripts/plot_h3_evidence.py (equality-grid label moved to the panel title) and embedded in the operator doc. Signed-off-by: Wenbo Ji <36562829+fusheng-ji@users.noreply.github.com>
… golden The gtest gold skipped two roundings diffusers' norm_out performs, so the BF16 check missed d_norm_weight from S=257 and d_temb/dW from S=1024 for CUDA and the PyTorch reference alike. With them declared straight-through, the BF16 gtest passes at S=257/1024/4097; FP32 is unchanged and its long-reduction misses are documented. Signed-off-by: Wenbo Ji <36562829+fusheng-ji@users.noreply.github.com>
Signed-off-by: Wenbo Ji <36562829+fusheng-ji@users.noreply.github.com>
A position's six gathered rows are bitwise the same whichever other positions share the call (single positions, spans, the tail, a shuffled repacking), and a table row's gradient from the full packing equals the one from a packing of only its own positions, across tile boundaries. Signed-off-by: Wenbo Ji <36562829+fusheng-ji@users.noreply.github.com>
… golden forward_modulated_fp32 computed both in FP64, but the model stores them in x's dtype. 1 + scale is shared by every position of a row, so against the old golden the CUDA d_weight missed the BF16 reduction tolerance from S=1024 and d_scale at S=4097. With both declared straight-through every gradient passes at S=257/1024/4097; the new test fails on the old golden. No evidence changes: the report uses its own FP64 reference. Signed-off-by: Wenbo Ji <36562829+fusheng-ji@users.noreply.github.com>
Brings in the seeded row-gather op-backward check and its regenerated evidence. Signed-off-by: Wenbo Ji <36562829+fusheng-ji@users.noreply.github.com>
Brings in the seeded row-gather op-backward check and its regenerated evidence. Signed-off-by: Wenbo Ji <36562829+fusheng-ji@users.noreply.github.com>
Brings in the seeded row-gather op-backward check and its regenerated evidence. Signed-off-by: Wenbo Ji <36562829+fusheng-ji@users.noreply.github.com>
Brings in the seeded row-gather op-backward check and its regenerated evidence. Signed-off-by: Wenbo Ji <36562829+fusheng-ji@users.noreply.github.com>
Brings in the seeded row-gather op-backward check and its regenerated evidence. Keeps this branch's golden-availability check in _gather_accuracy, and re-pins the row-gather evidence links to 00fd890, the commit holding the regenerated report. Signed-off-by: Wenbo Ji <36562829+fusheng-ji@users.noreply.github.com>
_mlp_perf drew its timestep features from the process's default CUDA generator, so the inputs depended on how many draws ran first. Seed them per T. Only timing inputs change; no reported accuracy field depends on them, so the committed report needs no regeneration. Signed-off-by: Wenbo Ji <36562829+fusheng-ji@users.noreply.github.com>
Brings in the seeded timestep_mlp timing inputs (89466c7). Signed-off-by: Wenbo Ji <36562829+fusheng-ji@users.noreply.github.com>
…e report _projection_perf and the batch-invariance part of _projection_accuracy drew temb from the process's default CUDA generator. Seed both. The per-draw accuracy inputs were already seeded; the full accuracy section from this commit is identical to the committed report's, so it needs no regeneration. Signed-off-by: Wenbo Ji <36562829+fusheng-ji@users.noreply.github.com>
Brings in the seeded timing and invariance inputs of the evidence report. Signed-off-by: Wenbo Ji <36562829+fusheng-ji@users.noreply.github.com>
_gather_perf drew its table rows and upstream gradients from the process's default CUDA generator. Seed them. Only timing inputs change; no reported accuracy field depends on them. Signed-off-by: Wenbo Ji <36562829+fusheng-ji@users.noreply.github.com>
Brings in the seeded timing and invariance inputs of the evidence report. Signed-off-by: Wenbo Ji <36562829+fusheng-ji@users.noreply.github.com>
_norm_accuracy drew the inputs of its four plain-norm bitwise checks from the process's default CUDA generator. Draw them from one seeded generator. All four checks stay bitwise equal to F.rms_norm, and the rest of the accuracy section matches the committed report (the CUDA dscale error differs only in the 16th digit, from the FP64 reference's atomic index_select backward), so it needs no regeneration. Signed-off-by: Wenbo Ji <36562829+fusheng-ji@users.noreply.github.com>
The gather case of test_backward_perf_cases_prepare_fresh_cpu_graphs_before_events redirects torch.randn to the CPU. _gather_perf now draws from a seeded CUDA generator, which cannot produce a CPU tensor, so the shim swaps it for a CPU generator with the same seed (one per CUDA generator, so the draw sequence continues). Signed-off-by: Wenbo Ji <36562829+fusheng-ji@users.noreply.github.com>
Brings in the seeded timing and invariance inputs of the evidence report. Keeps this branch's _norm_accuracy structure (names list, weight source) and seeds its plain-norm inputs the same way as feat/h3-rmsnorm. Signed-off-by: Wenbo Ji <36562829+fusheng-ji@users.noreply.github.com>
Brings in the seeded timing and invariance inputs of the evidence report. Signed-off-by: Wenbo Ji <36562829+fusheng-ji@users.noreply.github.com>
Brings in the seeded timing and invariance inputs of the evidence report. Signed-off-by: Wenbo Ji <36562829+fusheng-ji@users.noreply.github.com>
Brings in the seeded timing and invariance inputs of the evidence report. Signed-off-by: Wenbo Ji <36562829+fusheng-ji@users.noreply.github.com>
Brings in the seeded timing and invariance inputs of the evidence report. Signed-off-by: Wenbo Ji <36562829+fusheng-ji@users.noreply.github.com>
The full-model qualification kit named the scheduler partition, account and job name in its job scripts, a job ID in the reference manifest's name and contents, and an absolute local path in generation-inputs.json. - The three .sbatch scripts keep only site-neutral resource requests; partition, account and job name are given at submission (README). - reference-1106656.json becomes reference-manifest.json without its job_id field. verify_inventory reads only "files", whose 1,635 hashes are unchanged, so the reference evidence still verifies. - generation-inputs.json records the source suite relative to its pinned source_revision. - The README describes the reference run by its source commit. Signed-off-by: Wenbo Ji <36562829+fusheng-ji@users.noreply.github.com>
This was referenced Oct 13, 2026
Open
…/seed sweep A stored gradient's max|err| / max|golden| moves in whole ulps of its largest element. run_block_backward now also reports each leaf's error in ulps of its storage dtype at max|golden|, and h3_block_ulp_sweep.py runs the backward over layouts and seeds and records candidate - provider ulps per leaf, to size an ulp allowance for the block-0 gradient test. Signed-off-by: Wenbo Ji <36562829+fusheng-ji@users.noreply.github.com>
…ve error test_block_backward compared max|err| / max|golden| of each leaf gradient with 1.5x diffusers' + 5e-3. For a BF16 leaf that number is set by one rounded element and moves in whole ulps (0.004 relative for attn.norm_q.weight), and diffusers' own error depends on the torch build: the check failed on seed 2 with torch 2.13 and on seed 0 with torch 2.9.1 (+1.86 and +4.15 ulps over diffusers), although no row operator moves it. A BF16 leaf now also passes when its error is at most 6 ulps above diffusers'. FP32 leaves keep the relative rule. The allowance comes from h3_block_ulp_sweep.py over tiny/small x seeds 0-9 on both torch versions (max +4.15) and 34 single-node candidate/provider swaps (max +5.15); the two sweep reports, generated at 5e5df82 from clean trees, are added. Signed-off-by: Wenbo Ji <36562829+fusheng-ji@users.noreply.github.com>
This branch has not been deployed
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.
What
RFC #420 row
ws1_one_h3_block: one real H3 block, forward and backward, with every intermediate and a first-drift report.MiniMax-H3@42ed227runs as a 17-node graph, from the AdaLN projection to the second gated residual. It runs on packed FL2VA layouts whoseposition_idsand tags are bitwise equal to the pinned diffusers pipeline'sbuild_packed_sequence; the hashes are pinned in a CPU test.first_{,isolated_,repeat_,batch_}drift.temband all 12 block parameters (repeat, error vs golden);first_grad_{repeat,batch}_drift.block_tensors). They are extracted byprepare_h3_weights.py --blockfrom the same shard, so the existing conditioning file is unchanged.Bindings
adaln_projectionadaln_projection_3modnorm1,norm2h3_rmsnormresidual_attn,residual_mlpadaln_gate_residualq/k/v_proj,o_proj,ffn_gate_up,ffn_downh3_qkv_gemm,h3_attention_o_gemm,h3_ffn_gate_up_gemm,h3_ffn_down_gemmq_norm,k_normh3_qk_rmsnorm_d128H3RMSNormCudaOpon the 128-wide heads (bitwise equal tonn.RMSNorm)rope_q,rope_kh3_mm_rope_3axis_partialattentionh3_full_attentionDeterministicAttentionOp(causal=False)swigluh3_swigluSwiGLUCudaOpWhen an owning row lands, swapping its node's
candidatecallable is the whole integration, and the report entries become that operator's block-level evidence.Full-model and generation qualification (added 2026-10-12, in progress). This part covers the WS1 closeout rows
ws1_full_h3_transformerandws1_dual_trajectory, which are not claimed yet; it reuses the block graph above for every layer.tools.validation.models.h3_full_modelruns the real 50 transformer blocks, both text-refiner layers and the input/conditioning/output components. Each candidate block binds its own parameters to the block-0 graph, and the row/interim/reference labels are kept. Every parameter and input gradient is checked.examples/models/minimax_h3/full-model-thresholds.json, and a 1,635-file SHA-256 reference inventory.generation-contract.json: the pinned public reference image and prompt, seeds 42/43/44, 124 frames, 1344×768, 24 fps with joint 32 kHz audio. The comparator checks identical initial noise and shapes and reports PSNR/SSIM, temporal RMSE and audio differences.Prior art & reuse decision
This is a validation closeout, not a new kernel; no operator is written here.
MiniMaxH3TransformerBlockis the executable reference. It is replayed op for op as the provider (h3_provider), which pins its dtypes and op order without importing diffusers.rl_engine/validation/models/chain_gate.py). Its method is reused: per-node digests and first drift in graph order. Its graph is Qwen3's (causal, no AdaLN, Qwen shapes), so the H3 block is built on theh3_chainstage pattern of [WS1][CUDA][MiniMax-H3] timestep_sinusoid_h3: FP32 timestep features + shared H3 harness (RFC #420 stack 1/10) #483.TritonDetGemmOp.__call__reduces K as a tree with BF16 nodes; its FP32-accumulate kernel is equally deterministic and row-invariant, matches cuBLAS's accuracy, and is 9–17× faster (B200, error vs FP64):Direct bitwise comparison
The H3 block is composed of the WS1 rows below it, and their reuse candidates are compared byte for byte with
tools/validation/models/h3_bitwise_reuse.py(committed in #483, merged down the stack). It runs every candidate thath3_prior_art.candidates()defines on identical inputs and compares every output and leaf gradient with diffusers' path and with the rl-kernel op. Each row's report, written from a clean tree on its own branch: #483timestep_sinusoid; #484timestep_mlp; #485adaln_projection; #486adaln_row_gather; #487norm_modulate; #488gate_residual; #489final_adaln_out.Results
Block-0 replay, generated from a clean tree at
41e4293on an otherwise idle B200 (torch 2.13.0+cu130), withtools/validation/models/h3_block_replay.py --layouts tiny,small,medium:report.json.adaln_projection/adaln_projectionadaln_projection/adaln_projectionadaln_projection/adaln_projectionnorm1/norm2,q_norm/k_norm, RoPE, and both gated residuals. The first drift is the first reduction whose tree differs from cuBLAS.adaln_proj.weight,adaln_proj.biasandtemb. diffusers'index_selectbackward accumulates in BF16 atomics; the row operators use FP32 segment sums.attn.norm_q.weightat S = 3160 (9.5e-3 vs 5.5e-3). At S = 925 the same leaf is 2× more accurate than diffusers, so the 128-element gradient's error follows BF16 rounding, not one side.h3_full_attention.Status
2681cadb): FP32/BF16 provider passes over all 50 blocks, both refiners and the boundaries, with 638 parameter-gradient artifacts per precision. Reference generation and repeats passed for seeds 42/43/44 at 124 frames, 1344×768, 24 fps and 32 kHz audio, and all 49 predicted-velocity steps matched their repeated provider controls. These are provider results, not candidate acceptance.98b07a3f, one B200): native build and every reference/checkpoint hash check passed, then the block-0 golden regression gave 8 passed, 1 failed: theattn.norm_q.weightgradient's relative error 0.03398705939217804 exceeds the unchanged bound 0.03044327425907444 (provider 0.016962182839382958). The full-model and generation stages therefore did not run. Logs, JUnit and the binary are kept.9317a5e1with 34 single-node substitution controls (one provider node in the candidate graph, and the reverse) is queued. These hybrids localise the drift and cannot establish acceptance. Thresholds are unchanged.41e4293/caaf754(Results) has no known failures. The full-model gate's stricter block-0 bound is what fails above.9317a5e1. The DCO check reports a failure because it cannot read more than 250 commits; all 262 commits on this branch carrySigned-off-by(checked withgit log).test_h3_adaln_modulation.py::TestFusedModulation::test_backward_keeps_table_gradient_fp32in [WS1][CUDA][MiniMax-H3] adaln_row_gather: fused six-way AdaLN row gather (RFC #420 stack 4/10) #486 (46347118), merged here. Its golden rounded an FP64 SiLU where the kernel rounds the FP32 SiLU, andtembwas unseeded; the kernel was deterministic.History
KERNEL_ALIGN_USE_FAST_MATH=1adds--use_fast_mathto the whole_Cbuild, which approximatesexpf/sinf/cosf/rsqrtf/division and flushes denormals. Before the fix a fast-math build of the top of the stack failed 33 H3 tests (thetimestep_sinusoid_h3andh3_rmsnormbitwise tests and the chain/block tests built on them;det_linear,adaln_row_gatherandgate_residualstill passed). Everycsrc/cuda/h3source is now inH3_BITWISE_SOURCESand left out of fast-math builds, the bindings are gated onKERNEL_ALIGN_WITH_H3_KERNELS, and dispatch falls back to the PyTorch references. On this branch: merge4ba3a8fband9cb10d03(block dispatch-check skip). Results for both builds are under Tests.0348e37b). The.sbatchscripts keep only site-neutral resource requests (partition, account and job name are given at submission), the reference manifest isreference-manifest.jsonwithout a job ID (its 1,635 file hashes are unchanged, so the reference evidence still verifies), andgeneration-inputs.jsonrecords the source suite relative to its pinned revision.9317a5e1). 14 report links outside the MkDocs tree now point to immutable GitHub URLs at68e472b7; the strict docs build passes. No evidence or numbers changed.ae620486onward; see What). An earlier reference attempt completed its backward stages but failed generation because torchvision/the video processor was missing; the processor repair and a matching torchvision overlay fixed the rerun. Earlier local expanded CPU results (149 passed, 358 hardware skips, three subprocess-startup timeouts) are historical, not an all-pass claim.03cd824b). The one-blockreport.jsonandfigure.pngmoved toreports/experiments/h3-one-block-b200/with identical SHA-256; the report keeps its41e4293measurement revision. Docs, the plotting example and the layout audit map were updated; no GPU numbers were rerun.caaf754,tests/models/minimax_h3on 2× B200: 501 passed, 5 skipped; with the fast-math guard (2× B200, passed / skipped / failed): default 545 / 7 / 0, fast-math 196 / 356 / 0; after the flaky-test fix at27bb0295: default 550 passed / 7 skipped, fast-math 201 / 356, 0 failed.Tests
At this PR's head
3bd2300a, 8× B200, pinnedMiniMax-H3@42ed227weights; each build compiled from a clean checkout of that commit:_CKERNEL_ALIGN_USE_FAST_MATH=1Default-build skips (environment only): 1 × could not import 'matplotlib'; 1 × could not import 'sglang.kernels.ops.diffusion.modulate.timestep_embedding_jit'; 1 × extension enforcement is CI-only (orchestrator sets RL_KERNEL_REQUIRE_EXT=1). The branch head has since moved to
0348e37b, which only changes the full-model kit's job scripts, manifest name and README (see History).Fast-math regression tests:
tests/build/test_build_platform_collectives.py::test_cuda_build_compiles_h3_kernels_without_fast_math,::test_fast_math_build_excludes_bitwise_h3_kernels,tests/runtime/test_dispatch.py::test_h3_timestep_falls_back_when_fast_math_build_omits_kernel,::test_h3_ops_prefer_cuda_and_fall_back_to_pytorch_reference.tests/models/minimax_h3/test_h3_one_block.pychecks the block-0 replay: on CPU, that the layouts are pinned to diffusers, the graph is well formed and MM-RoPE rotates 96 of 128 channels; on GPU forward (S = 264, 925), that every node repeats and is batch-row bitwise, promised nodes are isolated-bitwise and node and output errors are at most 1.25 × diffusers' + 1e-3; on GPU backward (S = 264), that every leaf repeats, dX is batch-row bitwise, no gradient drifts and leaf errors are at most 1.5 × diffusers' + 5e-3.On this PR the GitHub checks are DCO, CodeRabbit and the CPU lint/unit/docs workflow; GPU results come from the run above. The full-model candidate gate is separate (Status).
Scope / Known limitations
h3_mm_rope_3axis_partiallands.tembis the provider's (the conditioning chain is [WS1][CUDA][MiniMax-H3] timestep_sinusoid_h3: FP32 timestep features + shared H3 harness (RFC #420 stack 1/10) #483–[WS1][CUDA][MiniMax-H3] adaln_row_gather: fused six-way AdaLN row gather (RFC #420 stack 4/10) #486).Qwen3VLProcessorneeds its video processor even for image conditioning.