Repository navigation
[WS1][CUDA][Qwen3-Next] Comparison benchmarks and plots for the Qwen3-Next stack: MoE, attention, logprob, EP (RFC #428 stack 11/11) - #551
Conversation
…rouped expert GEMM RFC RL-Align#428 moe_route_combine_contract (CUDA). - Routing: FP32 router through the pinned vLLM batch-invariant GEMM, a fixed-order softmax, stable descending argsort (ties go to the lower expert id) and FP32 renormalisation of the ten selected weights. - Experts: per-route gate_up and down projections through vLLM 0.30.0's fused_moe Triton kernel with the batch-invariant tile passed explicitly (BLOCK 64/64/32, SPLIT_K=1); no routed-weight multiply and no sum inside the kernel, so every (token, route) row has one writer. Bitwise equal to the previous per-expert GEMM loop at TP4 and TP1 widths; fails closed if VLLM_TRITON_USE_TD is enabled. - Combine: ten ordered FP32 multiply-adds and one BF16 cast; no atomics. - Backward: per-expert pinned GEMMs into one dense gradient buffer; dx is summed in ascending expert order. - TP4 block: HF load/export for all 512 experts, replicated router and shared-expert gate, Megatron-style copy/reduce autograd boundaries moved into qwen3_next_tp.py. - Prior-art runner and plot comparing HF transformers, vLLM fused_moe (BI=0/1) and FlashInfer cutlass_fused_moe; TP4 real-weight gate script. Signed-off-by: Wenbo Ji <36562829+fusheng-ji@users.noreply.github.com>
Prep for RFC RL-Align#428 full_model_chain; serves the gdn_state_bridge row. - GDN: packed recurrent prefill/decode through the pinned vLLM 0.30.0 provider with an explicit state boundary (qwen3_next_gdn.py), the depthwise causal convolution with cache handoff (qwen3_next_conv.py), their combined shared core (qwen3_next_provider.py) and the TP4 block with HF GQA-interleaved weight mapping (qwen3_next_tp_gdn.py), now on the shared TP boundaries in qwen3_next_tp.py. - Attention: the deterministic CUDA attention kernel accepts head dim 256 (ROCm stays 128) and validates backward inputs; shared_attention and TP4FullAttention with the KV head replicated on each rank pair, partial RoPE at absolute positions and explicit per-slot KV state. - Real-weight TP4 gates for GDN (layer 0) and attention (layer 3), sharing scripts/qwen3_next_gate_common.py with the MoE gate. Signed-off-by: Wenbo Ji <36562829+fusheng-ji@users.noreply.github.com>
…nce (B200, 2e950f3) Signed-off-by: Wenbo Ji <36562829+fusheng-ji@users.noreply.github.com>
Signed-off-by: Wenbo Ji <36562829+fusheng-ji@users.noreply.github.com>
Compares RL-Kernel's deterministic attention with torch SDPA, vLLM FlashAttention-2 (num_splits auto and 1), vLLM's Triton unified attention and FlashInfer's ragged prefill: batch, chunked-prefill and decode invariance, backward repeatability, accuracy against FP64 and latency. Signed-off-by: Wenbo Ji <36562829+fusheng-ji@users.noreply.github.com>
…nce (B200, 9e6c4f2/6517077) Signed-off-by: Wenbo Ji <36562829+fusheng-ji@users.noreply.github.com>
Signed-off-by: Wenbo Ji <36562829+fusheng-ji@users.noreply.github.com>
RFC RL-Align#428 full_model_chain (CUDA). - Engine adapters: the native vLLM rollout (exact-prefill scheduler, paged KV, traced response rows), the VIME/Megatron replay and training actor, engine weight import/export and the logprob adapter, all on the shared TP4 providers. - Stage runners (preflight, layers, l2, train1, train2, train) with the validated acceptance contract (version 4) and scripts/qwen3_next_run.py, a launcher that works inside any four-GPU allocation: each stage gets a clean clone, an immutable run.json identified by a fresh execution_id, and refuses a predecessor that did not pass or pins another identity. Scheduler-independent helpers live in scripts/qwen3_next_runtime.py. - Sub-node digests: both engines observe the normed mixer input, the mixer output, the normed MLP input, the selected expert ids and the MoE output of every layer, plus the embedding; the first divergence names the layer and sub-node. - scripts/qwen3_next_chain_report.py writes a ChainGateReport-compatible report (schema qwen3-next-chain-v1, compatible with ws1-c10-c11-v5) with first_drift_family/layer/cell; scripts/qwen3_next_publish_evidence.py publishes a chain's records without site paths, hosts or users. - Native rollout caps raised to 64 sequences, 16384 batched tokens and a 4 GiB KV budget so the batch-invariance matrix runs under the same certified profile; the exact-prefill scheduler still fixes every chunk. - The operator-case registry is regenerated from collection by scripts/qwen3_next_operator_cases.py. - Packaging: transformers may be 5.13.1-5.17.0; a qwen3-next extra pins the audited runtime. Signed-off-by: Wenbo Ji <36562829+fusheng-ji@users.noreply.github.com>
RFC RL-Align#428 batch_invariance_ci (CUDA). - Stage bi (after a passed l2, same certified profile): 97 pinned cells in rl_engine/testing/qwen3_next_bi_cases.py / qwen3_next_bi_manifest.json. concurrency (1-64 requests, target first or last), interference (companion content, lengths, arrival during prefill/decode, generation lengths), chunk boundaries (prompts 63-1024 around 64/128/528/1024, chunk 64/128, first chunk 1/63/65, compared with the replay recompute) and replay THD packing (1-7 neighbours, target first or last). A quick CI subset runs one cell per family plus 64 concurrent requests. - Native rollout: version 2 requests run one traced target next to untraced companions; the exact-prefill scheduler admits each request at its arrival step, pins the target's planned chunk at every step and fails on any preemption; the trace records only the target. - Replay: packed_layout() packs variable-length neighbours with the traced target in one THD batch. - bi-matrix.json names each failing cell's first divergent layer, sub-node and layer family; the chain report gains a batch_invariance section, and the evidence publisher takes the bi run with --also. - gtest: bitwise judgments compare raw bits (signed zero, NaN/Inf and dtype now count), not allclose with zero tolerance. Signed-off-by: Wenbo Ji <36562829+fusheng-ji@users.noreply.github.com>
…lout profile Batch-invariance chunk cells use prompts such as 129 tokens; the state-shape check only admitted the four L2 lengths, which their own validators already pin. Signed-off-by: Wenbo Ji <36562829+fusheng-ji@users.noreply.github.com>
Signed-off-by: Wenbo Ji <36562829+fusheng-ji@users.noreply.github.com>
Editable sources, base interpreters and build directories in package metadata now keep only their last path component; cgroup paths keep only their file name. The leftover check matches absolute paths only, so package paths such as vllm/.../cpu/data/ are not flagged, and any mention of the batch scheduler blocks publication. Signed-off-by: Wenbo Ji <36562829+fusheng-ji@users.noreply.github.com>
…r-art runner - Megatron-core 0.16 MoELayer with Transformer Engine grouped GEMM and fused permute, configured as VIME runs Qwen3-Next (FP32 softmax router, top-10, all-to-all dispatcher), including its backward. - SGLang 0.5.21 Triton fused_moe in default and deterministic-inference mode. sgl_kernel cannot load next to torch 2.13, so its two kernels on this path are replaced by SGLang's own Triton moe_sum_reduce and JIT moe_align_block_size; any other sgl_kernel call fails loudly. - --only and --merge combine reports from different Python environments. Signed-off-by: Wenbo Ji <36562829+fusheng-ji@users.noreply.github.com>
…ured (B200, c58816b) Every library in the reuse table is now measured: Megatron-core 0.16 + TE 2.16 as VIME configures Qwen3-Next, and SGLang 0.5.21 in default and deterministic-inference mode. The TP4 gate evidence is unchanged (2e950f3, identical MoE code). Signed-off-by: Wenbo Ji <36562829+fusheng-ji@users.noreply.github.com>
Signed-off-by: Wenbo Ji <36562829+fusheng-ji@users.noreply.github.com>
…gatron-core attention Add three engines to the attention prior-art runner: - FlashAttention-4 (CuTe DSL) varlen as vendored by vLLM, forward and backward. - Transformer Engine DotProductAttention on THD-packed sequences, in inference mode (cuDNN fused) and in training mode (on SM100 TE has no fused head-dim-256 backward and falls back to its unfused path). - Megatron-core's local DotProductAttention, one launch per sequence. The backward check now compares the target's dq/dk/dv alone against the same sequence packed first and last, so engines with a packed backward are checked for batch invariance rather than repeatability. A prefill/decode crash is recorded per candidate without skipping its other checks. --only and --merge combine reports from different Python environments. Signed-off-by: Wenbo Ji <36562829+fusheng-ji@users.noreply.github.com>
The decode and forward+backward latency sections are keyed by candidate directly, the prefill section by size first; merge them at any depth. 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>
…p as E402-exempt The gate scripts insert the repo root into sys.path before importing rl_engine and tools, which flake8 reports as E402. Mark those imports with noqa, as the other tools/ scripts do. Signed-off-by: Wenbo Ji <36562829+fusheng-ji@users.noreply.github.com>
…p as E402-exempt The gate scripts insert the repo root into sys.path before importing rl_engine and tools, which flake8 reports as E402. Mark those imports with noqa, as the other tools/ scripts do. Signed-off-by: Wenbo Ji <36562829+fusheng-ji@users.noreply.github.com>
Annotate the latency samples and accept the default-argument lambdas used as timed calls. No behaviour change. Signed-off-by: Wenbo Ji <36562829+fusheng-ji@users.noreply.github.com>
Signed-off-by: Wenbo Ji <36562829+fusheng-ji@users.noreply.github.com>
… runner Annotate the latency samples and accept the default-argument lambdas used as timed calls. No behaviour change. Signed-off-by: Wenbo Ji <36562829+fusheng-ji@users.noreply.github.com>
Merge the migrated TP4 mixers (and through them the refactored test-qwennext) and move the full-model chain into the new layout: - model-level TP4 pieces (embedding, engine weights, logprob, sub-node observations) into rl_engine/models/qwen3_next/; - vLLM adapters and the native rollout into rl_engine/integrations/engines/rollout/vllm/; - VIME providers into rl_engine/integrations/orchestrators/vime/providers/ and the native VIME lifecycle (recompute, training, workers, profile) into rl_engine/integrations/orchestrators/vime/experiments/qwen3_next/; - the provider identity into rl_engine/integrations/common/; - chain report, L2/case fixtures and manifests into rl_engine/validation/models/; - stage runners and the launcher into tools/validation/models/, CI scripts into ci/scripts/, tests into tests/models/qwen3_next/. Imports point at canonical modules; the provider-source digest list names the canonical RMSNorm backend instead of its compatibility alias. Recorded contract identities (e.g. sample_counter_owner) are unchanged. Signed-off-by: Wenbo Ji <36562829+fusheng-ji@users.noreply.github.com>
…nce matrix Merge the migrated full-model chain and move the batch-invariance work into the new layout: the case generator and manifest into rl_engine/validation/models/, the stage runner into tools/validation/models/, its tests into tests/models/qwen3_next/. The raw-bit comparison for bitwise judgments now lives in the canonical rl_engine/validation/operators/forward_invariance.py (the old module is a compatibility alias). The evidence README gives the commands in the current layout and says where the runners were at the measured commit; no measured file changed (SHA256SUMS verified). Signed-off-by: Wenbo Ji <36562829+fusheng-ji@users.noreply.github.com>
Signed-off-by: Wenbo Ji <36562829+fusheng-ji@users.noreply.github.com>
…ouched The published chain evidence is a byte-exact copy covered by SHA256SUMS; a pytest JUnit XML without a final newline would otherwise be rewritten by end-of-file-fixer and break the checksum. Same treatment as reports/archive/. Signed-off-by: Wenbo Ji <36562829+fusheng-ji@users.noreply.github.com>
Signed-off-by: Wenbo Ji <36562829+fusheng-ji@users.noreply.github.com>
…ouched Signed-off-by: Wenbo Ji <36562829+fusheng-ji@users.noreply.github.com>
|
🔍 OpenCodeReview found 8 issue(s) in this PR.
📄
|
| def run(local, targets): | ||
| loss = vocab_parallel_cross_entropy(local.float()[:, None, :], targets[:, None]) | ||
| return -loss.squeeze(1) |
There was a problem hiding this comment.
vocab_parallel_cross_entropy performs its all-reduce over Megatron's global parallel_state tensor-parallel group, not the group argument passed to this factory, and this candidate never initializes parallel_state. At TP4 the call therefore either raises (tensor-parallel group uninitialized) and is recorded as unavailable, or — if a stale/other group happens to exist — reduces the max/target/sum-exp over the wrong ranks. In both cases the Megatron logprob prior-art number is not measuring Megatron's real TP4 reduction and will silently misrepresent it. Initialize parallel_state to match tp (and the rank layout) before calling, or dispatch through an explicit group-aware reduction.
|
@fusheng-ji The automated OCR review has completed. Please review and address all automated review bot findings, then push your updates. Maintainers will begin manual review after the bot findings have been addressed. |
a203719 parametrised test_cuda_gated_parameter_vjp_contributions_match_the_fold over shape and added four norm tests, but the registry still pinned the old ids, so the preflight operator gate reported them as not found. Regenerated with qwen3_next_operator_cases.py --write. Signed-off-by: Wenbo Ji <36562829+fusheng-ji@users.noreply.github.com>
…ecompute create_actor(training=False) built the full actor through setup_model_and_optimizer, which wraps the model in DDP and allocates optimizer state. The recompute/logprob path never steps, and on 80 GB GPUs that state does not fit. With training=False the model is now built through get_model(wrap_with_ddp=False) and loaded without an optimizer, and (args, model, None, None) is returned. The training=True path is unchanged. Signed-off-by: Wenbo Ji <36562829+fusheng-ji@users.noreply.github.com>
VIME's load_checkpoint requires skip_load_to_model_and_opt; both create_actor calls omitted it, so the full-model l2 recompute failed with a TypeError before any model work. The stub in the actor test now requires it. Signed-off-by: Wenbo Ji <36562829+fusheng-ji@users.noreply.github.com>
…t.toml, gate the remaining new tests Signed-off-by: Wenbo Ji <36562829+fusheng-ji@users.noreply.github.com>
…k, not assert Signed-off-by: Wenbo Ji <36562829+fusheng-ji@users.noreply.github.com>
…arty, logprob and EP plots 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>
|
Replies to the six OpenCodeReview summary items. The plot fixes are compiled but I have not re-rendered the figures from the evidence.
|
…issing TP group run_qwen3_next_chain_gate.sh read the report with a bare open() and indexed JSON-only keys, so a truncated file, a non-object report or one without first_drift_family raised a traceback and exited 1, the code reserved for a failed gate. Read it in a with-block, require an object and the payload-only first_drift_family, and send every such failure through invalid() (exit 2). The TP reduce dereferenced collective_for_group(...), which returns None for a missing group; raise a clear RuntimeError as the EP exchange does. 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>
|
One OpenCodeReview summary item:
|
What
Per the layout review on #549, every comparison benchmark and plot of the Qwen3-Next stack lives here, under
benchmarks/models/qwen3_next/; the validation PRs keep only checks and CI tests. Code is moved from the validation PRs with imports and paths adjusted, except the new EP benchmark.moe_route_candidates.pyqwen3_next_moe_prior_art.pyplot_qwen3_next_moe_prior_art.pyattention_candidates.pyqwen3_next_attention_prior_art.pyplot_qwen3_next_attention_prior_art.pyplot_qwen3_next_chain.pyplot_qwen3_next_batch_invariance.pylogprob_candidates.pyqwen3_next_logprob_prior_art.pyplot_qwen3_next_distributed_logprob.pymoe_ep_candidates.pyqwen3_next_moe_ep_prior_art.pyplot_qwen3_next_moe_ep.pyMiles and verl are measured, not read:
thirdparty_sources.pyimports their own kernels unmodified from checkouts of pinned commits (radixark/miles@23d3d38,volcengine/verl@e5a627c) and records the SHA-256 of every file used. New here:qwen3_next_miles_moe_backward.py(Miles' routed-MoE backward, 20 identical launches on the real layer-0 weights, RL-Kernel as the control),qwen3_next_logprob_backward.py(verl, Miles and RL-Kernel logprob backward),miles_fusedandverl_fusedin the logprob candidates, andplot_qwen3_next_thirdparty.py.Results summaries (download link, SHA-256, tested commit, commands) are in
reports/experiments/qwen3_next/:qwen3-next-logprob-comparison-b200.md,qwen3-next-moe-ep-comparison-b200.mdandqwen3-next-thirdparty-comparison-b200.mdhere; the MoE-route, attention, chain and BI summaries in their validation PRs.Prior art & reuse decision
N/A: benchmarks only. The reuse decisions are in each validation PR; this PR provides the code that measures them.
Results
Expert-parallel MoE (new, for the EP PR), layer 0 real weights, EP4 under 13 NCCL settings and EP1, 4 × B200, measured at
7db4a14b(summary, raw results ZIP, SHA-2562375ec36…97c6cf):VLLM_BATCH_INVARIANT=1all_reducecutlass_fused_moe(CUTLASS)Miles and verl (for #503, #549, EP PR), measured at
6ad63611(MoE backward, logprob forward) and03a5898e(logprob backward, TP1 and TP4) (summary, raw results ZIP, SHA-256d0eaa326…f2ff):dx/dWgate/up /dWdown equal the firsttl.atomic_add)dxof probe rows alone == in batch (10 cells)Miles' MoE backward is not reproducible; both libraries' logprob forward depends on the NCCL algorithm like Megatron's and VIME's. Their logprob backward also depends on the NCCL algorithm at TP4 (it consumes the all-reduced forward statistics) and differs from TP1, while RL-Kernel's does not. Not what the source suggested: verl's backward
tl.atomic_adddid not change the bits between launches, and its forwardatomic_addonly runs forreductionsum/mean.TP logprob (#549): measured in #549 (summary and ZIP there): TP4 median latency 2.55 ms (RL-Kernel), 1.51 ms (vLLM), 0.57 ms (Megatron), 0.56 ms (VIME); invariance as in #549.
The routed-MoE, attention, chain and BI figures are rendered by the moved plot scripts from the ZIPs attached to their PRs (checked: each renders from the downloaded evidence layout).
Figures of the validation PRs, rendered by the plot scripts in this PR from the evidence ZIPs of those PRs:
Status
015bec4a, on top of [WS1][CUDA][Qwen3-Next] EP4 distributed logprob parity: expert-parallel MoE, full-model L2 bitwise on TP4 x EP4 (RFC #428 stack 10/11) #557 (88c4f02e). CI is green on this head: lint, unit-tests, docs and DCO pass;providerandws1-gtestskip because no self-hosted runner is attached.3a5263d2); Megatron was first measured only without deterministic algorithms (added in6e316f4b); v2 adds FlashInfer, vLLM's own all-reduce dispatch, a two-dimensional batch grid and the backward. The first v2 launch crashed in vLLM's parallel-state setup because the job'sTMPDIRpath exceeded the IPC socket path limit; the published run uses a short node-localTMPDIR(recorded in the summary).History
pull_requestpaths were missing Qwen3-Next modules that its checks import; merged the additions of [WS1][CUDA][Qwen3-Next] Full-model chain: vLLM rollout vs VIME recompute, raw-bit through two updates and a reload (RFC #428 stack 7/11) #543 and [WS1][CUDA][Qwen3-Next] Batch-invariance matrix for the full model, 97/97 cells bitwise (RFC #428 stack 8/11) #544 (015bec4a). Workflow-only change; shared infrastructure such asrl_engine/opsandrl_engine/platformsstays out of the filter.cc7dc4bc. Kernel arithmetic is unchanged, so the measured results stand.test-qwennextafter [WS1][CUDA][Qwen3-Next] C1: zero-centred RMSNorm references and CUDA kernel (RFC #428 stack 2/4) #467 landed (c382dd4b), through [WS1][CUDA][Qwen3-Next] EP4 distributed logprob parity: expert-parallel MoE, full-model L2 bitwise on TP4 x EP4 (RFC #428 stack 10/11) #557's new head85297004, in5364c406. No conflicts.Tests
--helpand every plot rendered from its published evidenceScope
CUDA, B200. Benchmarks and plots only.