Skip to content

[WS2][CUDA][MiniMax-H3] ws2 tensor / sequence / context parallel and the hierarchical cross-node collective (RFC #420 stack 3/5) - #569

Open
fusheng-ji wants to merge 15 commits into
RL-Align:test-h3from
fusheng-ji:feat/h3-ws2-parallel
Open

fusheng-ji wants to merge 15 commits into
RL-Align:test-h3from
fusheng-ji:feat/h3-ws2-parallel

Conversation

@fusheng-ji

@fusheng-ji fusheng-ji commented Oct 22, 2026 •

Copy link
Copy Markdown
Contributor

RFC #420 H3 stack 3/5 (base test-h3, merge in this order): #586 -> #587 -> #588 -> foundation -> projection rows -> WS2 parallel -> token refiner -> full transformer. This PR merges after its parent; until then GitHub also shows the parent's commits. This PR's own diff.

Evidence location: the measurement outputs of this PR (JSON, figures) are not part of its diff. They are on the fork's pr_assets branch under pending/h3-ws2-parallel/ (links in this description are fixed to that commit). Paths such as reports/experiments/... below name where a runner writes its output.

Help wanted: single-node 8-GPU Hopper. We only have access to Hopper nodes with 4 GPUs (2 nodes x 4 H100), so every 8-way result here (TP / SP / CP at 8 ranks, the 8-GPU NCCL cases) comes from the two-node runner, not from one 8-GPU node. Two inherited tests are skipped for the same reason: test_h3_tp_adaln.py and test_h3_sp_norm_adaln.py ("needs 8 GPUs"). If you have a single-node 8 x H100/H200 machine, please run pytest tests/models/minimax_h3/test_h3_parallel.py tests/models/minimax_h3/test_h3_tp_adaln.py tests/models/minimax_h3/test_h3_sp_norm_adaln.py and the WS2 evidence runner there and post the result; I will gladly credit you and fold the numbers into this PR.

What

Contract h3-parallel-v1: eight canonical reduction units, so tensor parallel 1 / 2 / 4 / 8 add the same partials in the same tree.

  • Row-parallel O (K = 7168, unit 896) and down (K = 14336, unit 1792): FP32 per-unit GEMM, local tree, collective tree, one BF16 rounding.
  • Column-parallel backward dX: unit j is block j of every fused weight, in q,k,v / hidden,gate order.
  • Ulysses context parallel: exact all-to-all over a ragged SeqShard; sequence parallel: all-gather / reduce-scatter; coshard slices metadata with the rows.
  • HierarchicalCollective (hierarchical_ipc_nccl_tree): node-local deterministic tree, NCCL all-gather of the group partials, fixed balanced add. The input dtype is the accumulation dtype, so the result matches the single-node tree bit for bit.
  • Runner h3_parallel_run.py launches a layout on N processes and compares every rank with the single-GPU canonical block.

Prior art & reuse decision

Existing implementation Why not bound
NCCL all-reduce (ring / tree) reduction order follows topology and rank count; not invariant across TP sizes
Megatron-LM / vLLM tensor parallel same all-reduce; no bitwise statement across TP sizes
DeepSpeed-Ulysses all-to-all layout reused as the idea; ours is exact and ragged
this repo's DeterministicCollective reused node-locally; extended with the hierarchical layer

Decision: canonical-unit partial sums plus a fixed tree; NCCL only moves bytes between nodes.

Results (H100 / Hopper, 2 nodes x 4 GPUs)

Measured on NVIDIA H100 (93 GiB, sm90), driver 580, CUDA 13.0, torch 2.13.0+cu130, pinned MiniMax-H3@42ed227 weights, at head 5ae9f5eb. Block 0 of the pinned checkpoint, 264 packed rows; forward and input gradient compared bitwise with the single-GPU canonical block for every layout, and in addition every weight-gradient shard (to_q/k/v, to_out, ff hidden/gate/down) for the layouts without CP (TP2, TP4, TP8).

Layout GPUs Nodes Collective Bitwise equal to single GPU Mean forward per rank
TP2 x CP1 2 1 cuda_ipc_fixed_tree yes 0.033 s
TP4 x CP1 4 1 cuda_ipc_fixed_tree yes 0.033 s
TP4 x CP2 8 2 cuda_ipc_fixed_tree yes 0.032 s
TP4 x CP2 + SP 8 2 cuda_ipc_fixed_tree yes 0.033 s
TP8 x CP1 8 2 hierarchical_ipc_nccl_tree yes 0.032 s

WS2 layouts

Numbers: reports/experiments/h3-ws2-parallel-h100/ (one report per layout; host names are replaced by node-a, node-b).

Results (B200 / Blackwell, 1 node x 8 GPUs)

Measured on NVIDIA B200 (179 GiB, sm100), driver 580.126, CUDA 13.0, torch 2.13.0+cu130, pinned MiniMax-H3@42ed227 weights, clean tree at 5ae9f5eb. One node with 8 GPUs, one process per GPU; same block, 264 packed rows and comparisons as the H100 table above (forward and input gradient against the single-GPU canonical block for every layout, plus every weight-gradient shard for the layouts without CP).

Layout GPUs Nodes Collective Bitwise equal to single GPU Mean forward per rank
TP2 x CP1 2 1 cuda_ipc_fixed_tree yes 9.3 ms
TP4 x CP1 4 1 cuda_ipc_fixed_tree yes 9.0 ms
TP4 x CP2 8 1 cuda_ipc_fixed_tree yes 9.5 ms
TP4 x CP2 + SP 8 1 cuda_ipc_fixed_tree yes 9.2 ms
TP8 x CP1 (node-local tree) 8 1 cuda_ipc_fixed_tree yes 13.2 ms
TP8 x CP1 (2 x 4 hierarchical tree, one node) 8 1 hierarchical_ipc_nccl_tree yes 14.0 ms

WS2 layouts on B200

Numbers: h3-ws2-parallel-b200/ (one report per layout, tests.json; host names replaced by node-a).

  • All six layouts are bitwise equal to the single-GPU reference, including the 8-rank TP8, TP4 x CP2 and TP4 x CP2 + SP cases, on a single 8-GPU node.
  • The hierarchical row runs the same TP8 group with --local-size 4, which selects the hierarchical IPC + NCCL tree and treats the 8 GPUs as two groups of four inside one physical node. It exercises that code path; it is not a measurement of the cross-node network, which was only measured on H100 (two nodes).
  • Forward times are those of a 264-row block and are not a scaling claim.
  • The first attempt of the job was preempted inside the third layout and requeued; every report above is from the second, complete attempt.
  • This is Blackwell, not Hopper: the single-node 8-GPU Hopper request at the top of this description is still open, and test_h3_tp_adaln.py / test_h3_sp_norm_adaln.py were not run on the B200 either.

Status

All five layouts are bitwise equal to the single-GPU reference on real nodes; ranks are packed node-major with 1 / 2 / 4 / 8 nodes supported.

B200 status: all six layouts, including the 8-rank cases on one 8-GPU node, are bitwise equal to the single-GPU block (128 of 128 tests pass); the cross-node collective is not measured on B200.

Tests

python -m pytest tests/models/minimax_h3/test_h3_parallel.py tests/models/minimax_h3/test_h3_projection_rows.py -q    # 122 passed (4 x H100)

The 8-GPU NCCL cases need eight GPUs in one node or two nodes: we only have 4-GPU Hopper nodes, so they are covered by the two-node runner above and not run on a single 8-GPU Hopper node (open for anyone with that resource, see the note at the top).

B200: the same two files on 8 x B200, 128 passed, 0 failed, 0 skipped (the 8-GPU NCCL cases ran on one node).

Scope / Known limitations

  • No single-node 8-GPU Hopper run. 8-way layouts were measured on 2 nodes x 4 H100 only; test_h3_tp_adaln.py:: and test_h3_sp_norm_adaln.py:: 8-GPU cases are skipped here. Help from anyone with a single-node 8 x Hopper machine is welcome.

Strict mode is fail-closed: no TF32, no fast-math, no split-K; FP32 accumulation with one final rounding; unsupported shapes, dtypes and devices raise instead of falling back. ws2_pipeline_parallel is not included. Not part of this PR: video projections (#562), O / gate_up / down GEMMs (#554, #535), full attention (#553), ROCm, SGLang adapter, pipeline parallel.

@coderabbitai

coderabbitai Bot commented Oct 22, 2026 •

Copy link
Copy Markdown

Important

Review skipped

Too many files!

This PR contains 139 files, which is 39 over the limit of 100.

To get a review, reduce the PR to 100 files or fewer by splitting it into smaller PRs or changing its base branch.

Upgrade to a paid plan to raise the limit.

This review couldn't start because sufficient usage credits or metered capacity aren't available. Add credits or update usage-based reviews in the billing tab, then retry.

Check out review usage here.

Run configuration
Commits

Reviewing files that changed from the base of the PR and between d22d4b4 and a9013d9.

Files selected for processing: 139
  • .github/workflows/ci.yml
  • benchmarks/models/benchmark_h3_conditioning.py
  • build_tools/extensions.py
  • csrc/bindings/ops.cpp
  • csrc/cuda/h3/adaln_row_gather.cu
  • csrc/cuda/h3/det_linear.cu
  • csrc/cuda/h3/gate_residual.cu
  • csrc/cuda/h3/rmsnorm_modulate.cu
  • csrc/cuda/h3/timestep_sinusoid.cu
  • docs/.nav.yml
  • docs/operators/README.md
  • docs/operators/h3-adaln-gate-residual.md
  • docs/operators/h3-adaln-projection.md
  • docs/operators/h3-adaln-row-gather.md
  • docs/operators/h3-final-adaln-out.md
  • docs/operators/h3-one-block.md
  • docs/operators/h3-parallel.md
  • docs/operators/h3-projection-rows.md
  • docs/operators/h3-rmsnorm.md
  • docs/operators/h3-sp-norm-adaln.md
  • docs/operators/h3-timestep-mlp.md
  • docs/operators/h3-timestep-sinusoid.md
  • docs/operators/h3-tp-adaln-3mod.md
  • examples/models/minimax_h3/README.md
  • examples/models/minimax_h3/candidate.sbatch
  • examples/models/minimax_h3/diagnose-block.sbatch
  • examples/models/minimax_h3/full-model-ensemble-rule.json
  • examples/models/minimax_h3/full-model-thresholds.json
  • examples/models/minimax_h3/generation-compare.sbatch
  • examples/models/minimax_h3/generation-contract.json
  • examples/models/minimax_h3/generation-inputs.json
  • examples/models/minimax_h3/generation-prompt.txt
  • examples/models/minimax_h3/generation-resume-check.sbatch
  • examples/models/minimax_h3/generation.sbatch
  • examples/models/minimax_h3/reference-manifest.json
  • examples/models/minimax_h3/reference.sbatch
  • rl_engine/_C.pyi
  • rl_engine/backends/cuda/model_specific/__init__.py
  • rl_engine/backends/cuda/model_specific/minimax_h3/__init__.py
  • rl_engine/backends/cuda/model_specific/minimax_h3/adaln_modulation.py
  • rl_engine/backends/cuda/model_specific/minimax_h3/adaln_projection.py
  • rl_engine/backends/cuda/model_specific/minimax_h3/adaln_row_gather.py
  • rl_engine/backends/cuda/model_specific/minimax_h3/det_linear.py
  • rl_engine/backends/cuda/model_specific/minimax_h3/final_adaln_out.py
  • rl_engine/backends/cuda/model_specific/minimax_h3/gate_residual.py
  • rl_engine/backends/cuda/model_specific/minimax_h3/parallel.py
  • rl_engine/backends/cuda/model_specific/minimax_h3/projection.py
  • rl_engine/backends/cuda/model_specific/minimax_h3/rmsnorm.py
  • rl_engine/backends/cuda/model_specific/minimax_h3/sp_norm_adaln.py
  • rl_engine/backends/cuda/model_specific/minimax_h3/timestep_mlp.py
  • rl_engine/backends/cuda/model_specific/minimax_h3/timestep_sinusoid.py
  • rl_engine/backends/cuda/model_specific/minimax_h3/tp_adaln_projection.py
  • rl_engine/backends/cuda/model_specific/minimax_h3/ws2_comm.py
  • rl_engine/backends/shared/triton/gemm/h3_projection.py
  • rl_engine/distributed/algorithms/hierarchical.py
  • rl_engine/reference/minimax_h3/__init__.py
  • rl_engine/reference/minimax_h3/adaln_projection.py
  • rl_engine/reference/minimax_h3/adaln_row_gather.py
  • rl_engine/reference/minimax_h3/block.py
  • rl_engine/reference/minimax_h3/final_adaln_out.py
  • rl_engine/reference/minimax_h3/fixed_order.py
  • rl_engine/reference/minimax_h3/gate_residual.py
  • rl_engine/reference/minimax_h3/projection.py
  • rl_engine/reference/minimax_h3/rmsnorm.py
  • rl_engine/reference/minimax_h3/timestep_mlp.py
  • rl_engine/reference/minimax_h3/timestep_sinusoid.py
  • rl_engine/runtime/registry.py
  • rl_engine/validation/models/h3_block.py
  • rl_engine/validation/models/h3_cases.py
  • rl_engine/validation/models/h3_chain.py
  • rl_engine/validation/models/h3_full_manifest.json
  • rl_engine/validation/models/h3_full_model.py
  • rl_engine/validation/models/h3_generation_resume.py
  • rl_engine/validation/models/h3_manifest.json
  • rl_engine/validation/models/h3_provider.py
  • rl_engine/validation/models/h3_report.py
  • rl_engine/validation/models/h3_tp.py
  • rl_engine/validation/models/h3_weights.py
  • rl_engine/validation/models/h3_ws2.py
  • rl_engine/validation/operators/operator_inputs.py
  • rl_engine/validation/operators/operator_specs.py
  • tests/build/test_build_platform_collectives.py
  • tests/models/minimax_h3/conftest.py
  • tests/models/minimax_h3/test_h3_adaln_gate_residual.py
  • tests/models/minimax_h3/test_h3_adaln_modulation.py
  • tests/models/minimax_h3/test_h3_adaln_projection.py
  • tests/models/minimax_h3/test_h3_adaln_row_gather.py
  • tests/models/minimax_h3/test_h3_benchmark_timing.py
  • tests/models/minimax_h3/test_h3_chain_replay_cli.py
  • tests/models/minimax_h3/test_h3_cli.py
  • tests/models/minimax_h3/test_h3_conditioning_e2e.py
  • tests/models/minimax_h3/test_h3_det_linear.py
  • tests/models/minimax_h3/test_h3_final_adaln_out.py
  • tests/models/minimax_h3/test_h3_full_model.py
  • tests/models/minimax_h3/test_h3_generation_resume.py
  • tests/models/minimax_h3/test_h3_native_validation.py
  • tests/models/minimax_h3/test_h3_one_block.py
  • tests/models/minimax_h3/test_h3_parallel.py
  • tests/models/minimax_h3/test_h3_projection_rows.py
  • tests/models/minimax_h3/test_h3_report.py
  • tests/models/minimax_h3/test_h3_rmsnorm.py
  • tests/models/minimax_h3/test_h3_sp_norm_adaln.py
  • tests/models/minimax_h3/test_h3_timestep_mlp.py
  • tests/models/minimax_h3/test_h3_timestep_sinusoid.py
  • tests/models/minimax_h3/test_h3_tp_adaln.py
  • tests/models/minimax_h3/test_h3_weights.py
  • tests/models/minimax_h3/test_h3_ws2_processes.py
  • tests/models/minimax_h3/test_prepare_h3_weights.py
  • tests/runtime/test_dispatch.py
  • tests/validation/operators/test_ws1_gtest_gpu.py
  • tools/migration/README.md
  • tools/migration/layout.json
  • tools/validation/models/h3_bitwise_reuse.py
  • tools/validation/models/h3_block_diagnostic.py
  • tools/validation/models/h3_block_replay.py
  • tools/validation/models/h3_block_ulp_sweep.py
  • tools/validation/models/h3_candidate_prepare.py
  • tools/validation/models/h3_chain_replay.py
  • tools/validation/models/h3_evidence.py
  • tools/validation/models/h3_evidence_integrity.py
  • tools/validation/models/h3_first_step_diagnostic.py
  • tools/validation/models/h3_full_compare.py
  • tools/validation/models/h3_full_ensemble_rule.py
  • tools/validation/models/h3_full_generation.py
  • tools/validation/models/h3_full_model.py
  • tools/validation/models/h3_full_provider_spread.py
  • tools/validation/models/h3_generation_adopt.py
  • tools/validation/models/h3_generation_compare.py
  • tools/validation/models/h3_parallel_run.py
  • tools/validation/models/h3_prior_art.py
  • tools/validation/models/h3_projection_bench.py
  • tools/validation/models/h3_projection_charts.py
  • tools/validation/models/h3_ws2_charts.py
  • tools/validation/models/h3_ws2_evidence.py
  • tools/validation/models/plot_h3_bitwise_reuse.py
  • tools/validation/models/plot_h3_block.py
  • tools/validation/models/plot_h3_evidence.py
  • tools/validation/models/plot_h3_prior_art.py
  • tools/weights/prepare_h3_weights.py

You can disable this status message by setting the reviews.review_status to false in the CodeRabbit configuration file.

  • Autofix · Keep fixing CodeRabbit findings and required CI, and resolving merge conflicts

Comment @coderabbitai help to get the list of available commands.

fusheng-ji and others added 12 commits October 22, 2026 22:54
…fixed-order Triton GEMM

Signed-off-by: Wenbo Ji <36562829+fusheng-ji@users.noreply.github.com>
(cherry picked from commit 650e2148c6f0e5dcdef136537e0e62f745020273)
Signed-off-by: Wenbo Ji <36562829+fusheng-ji@users.noreply.github.com>
(cherry picked from commit d099c0b)
Signed-off-by: Wenbo Ji <36562829+fusheng-ji@users.noreply.github.com>
(cherry picked from commit b41f868)
…de collective, 2-node H100 evidence

Signed-off-by: Wenbo Ji <36562829+fusheng-ji@users.noreply.github.com>
(cherry picked from commit 7f1296a970efb0cfcebd9300ff92551de08cf311)
Signed-off-by: Wenbo Ji <36562829+fusheng-ji@users.noreply.github.com>
(cherry picked from commit d56c391)
…il-closed test instead of a skip

Signed-off-by: Wenbo Ji <36562829+fusheng-ji@users.noreply.github.com>
(cherry picked from commit 74e5b83)
Signed-off-by: Wenbo Ji <36562829+fusheng-ji@users.noreply.github.com>
(cherry picked from commit 33cbcd6)
…l keys

Review finding (RL-Align#568): jointly permuting x and g changed dW/dbias because the token axis
was reduced in call order. All projection ops (audio in/out, text context, Q/K/V) now take an
optional logical_keys [T,2|3] (negative first column = padding); rows are reduced in ascending
key order with padding dropped, active keys must be unique. Key format follows RL-Align#562.
Adds the reviewer's repro plus permutation/padding tests for every row and Q/K/V.

Co-authored-by: Yitao Wang <75578057+walker-ai@users.noreply.github.com>
Signed-off-by: Wenbo Ji <36562829+fusheng-ji@users.noreply.github.com>
(cherry picked from commit d2941f0)
Signed-off-by: Wenbo Ji <36562829+fusheng-ji@users.noreply.github.com>
(cherry picked from commit 5f4e34c)
…ready ordered rows

Follows the canonical-row design of RL-Align#562: the Q/K/V node of the block graph supplies
(batch row, position) keys so its dW is reduced in logical order, and rows that already arrive in
canonical order are reduced in place (same bytes, no gather of x and g).

Co-authored-by: Yitao Wang <75578057+walker-ai@users.noreply.github.com>
Signed-off-by: Wenbo Ji <36562829+fusheng-ji@users.noreply.github.com>
(cherry picked from commit 0da0583)
Signed-off-by: Wenbo Ji <36562829+fusheng-ji@users.noreply.github.com>
(cherry picked from commit d086b5c)
…block 0 node-by-node and 50-block/generation gates

Squashes the one-block branch (its row-by-row history: timestep sinusoid, RMSNorm, AdaLN rows,
sequence/tensor parallel norm rows, final AdaLN, one block, 50-block qualification) onto the current
test-h3 so the pull request carries a reviewable, signed history. RFC RL-Align#420.

Signed-off-by: Wenbo Ji <36562829+fusheng-ji@users.noreply.github.com>
…pull request

Signed-off-by: Wenbo Ji <36562829+fusheng-ji@users.noreply.github.com>
…hard leaves

Signed-off-by: Wenbo Ji <36562829+fusheng-ji@users.noreply.github.com>
@fusheng-ji
fusheng-ji force-pushed the feat/h3-ws2-parallel branch from d086b5c to 5ae9f5e Compare October 22, 2026 21:04
fusheng-ji added a commit to fusheng-ji/RL-Kernel that referenced this pull request Oct 23, 2026
… on one 8-GPU node

128 tests pass (8-GPU NCCL cases included) and all six layouts (TP2, TP4, TP4xCP2, TP4xCP2+SP, TP8 with the node-local tree,
TP8 with the 2x4 hierarchical tree inside one node) are bitwise equal to the single-GPU block. Host names replaced by node-a.

Signed-off-by: Wenbo Ji <36562829+fusheng-ji@users.noreply.github.com>
@Flink-ddd Flink-ddd added platform: cuda Specific optimizations or bugs in NVIDIA graphics cards (such as FlashInfer, TMA optimizations) new-model MiniMax-H3 WS2 labels Oct 23, 2026
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>

This branch has not been deployed

No deployments
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

MiniMax-H3 new-model platform: cuda Specific optimizations or bugs in NVIDIA graphics cards (such as FlashInfer, TMA optimizations) WS2

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants