Summary
We're reproducing the 8×8 H200 DeepSeek-V4-Flash GRPO profile entirely from public artifacts — the radixark/miles:deepseek-v4 image (digest-pinned), the #1046 overlay (yueming-yuan/miles@032721cd + sgl-project/sglang@b69485ff), and sgl-project/DeepSeek-V4-Flash-FP8 — on Modal (clustered RDMA, no shared NFS). We believe this is the first outside-radixark reproduction. Everything runs end-to-end (checkpoint pipeline, 64-GPU load, SGLang rollout, weight sync, training step); this issue reports two findings from getting there and asks one question.
Finding 1: the deepseek-v4 branch predates the PR #1505 fix — blockwise-FP8 training asserts on public checkpoints
With the profile's --fp8-format e4m3 --fp8-recipe blockwise, the first train step raises:
AssertionError: All-gather requires quantizable tensor for quantizer Float8BlockQuantizer
We traced this to what #1505 (72696ef, merged 2026-06-29) fixes on main — keeping the DSA indexer linear_weights_proj in BF16 via --te-precision-config-file. The pinned deepseek-v4 branch (2026-05-15) predates it. Backporting just the precision-config YAML from #1505 onto the branch resolves the assert (the branch's Megatron already supports te_precision_config_file).
Suggestion: backport #1505 to the deepseek-v4 branch (or note it in the #1046 instructions), since that branch is what the roadmap points public reproducers at.
Finding 2 (data point): pure-BF16 training measures step-0 train/rollout KL ≈ 0.5 on V4-Flash
Before finding #1505 we worked around the assert by dropping the two FP8 flags (BF16 training). Result: train_rollout_kl ≈ 0.506, logprob_abs_diff ≈ 0.69 at step 0 — vs ≈0.02 in the published day-0 numbers — with the R3 replay check (when enabled via --ci-test) reporting 5–20% zero-overlap router top-6 per micro-batch. Everything consistent with FP8-rollout vs BF16-training activation divergence over 43 layers. Presumably why the profile trains blockwise-FP8; sharing since the day-0 write-up's "FP8 rollout + BF16 training" phrasing might lead others down the same path.
Question: is that phrasing intended to describe BF16 master weights with FP8 GEMMs (i.e. the blockwise recipe), rather than pure-BF16 training? A clarifying note would save reproducers a few $290/hr runs.
Minor: tools/fp8_cast_bf16.py on the public FP8 checkpoint
mtp.0.e_proj.weight / mtp.0.h_proj.weight in sgl-project/DeepSeek-V4-Flash-FP8 carry no scale_inv, so the cast passes them through as FP8 ("Warning: Missing scale_inv tensor"), which later breaks torch dist-ckpt serialization (inline_container.cc:664 unexpected pos). Upcasting the two tensors to BF16 before conversion fixes it — a fallback upcast in the cast tool would make the public checkpoint work out of the box.
Happy to share full logs/configs, and to test patches — we have the pipeline cached and can turn runs around quickly.
Summary
We're reproducing the 8×8 H200 DeepSeek-V4-Flash GRPO profile entirely from public artifacts — the
radixark/miles:deepseek-v4image (digest-pinned), the #1046 overlay (yueming-yuan/miles@032721cd+sgl-project/sglang@b69485ff), andsgl-project/DeepSeek-V4-Flash-FP8— on Modal (clustered RDMA, no shared NFS). We believe this is the first outside-radixark reproduction. Everything runs end-to-end (checkpoint pipeline, 64-GPU load, SGLang rollout, weight sync, training step); this issue reports two findings from getting there and asks one question.Finding 1: the
deepseek-v4branch predates the PR #1505 fix — blockwise-FP8 training asserts on public checkpointsWith the profile's
--fp8-format e4m3 --fp8-recipe blockwise, the first train step raises:We traced this to what #1505 (72696ef, merged 2026-06-29) fixes on
main— keeping the DSA indexerlinear_weights_projin BF16 via--te-precision-config-file. The pinneddeepseek-v4branch (2026-05-15) predates it. Backporting just the precision-config YAML from #1505 onto the branch resolves the assert (the branch's Megatron already supportste_precision_config_file).Suggestion: backport #1505 to the
deepseek-v4branch (or note it in the #1046 instructions), since that branch is what the roadmap points public reproducers at.Finding 2 (data point): pure-BF16 training measures step-0 train/rollout KL ≈ 0.5 on V4-Flash
Before finding #1505 we worked around the assert by dropping the two FP8 flags (BF16 training). Result:
train_rollout_kl ≈ 0.506,logprob_abs_diff ≈ 0.69at step 0 — vs ≈0.02 in the published day-0 numbers — with the R3 replay check (when enabled via--ci-test) reporting 5–20% zero-overlap router top-6 per micro-batch. Everything consistent with FP8-rollout vs BF16-training activation divergence over 43 layers. Presumably why the profile trains blockwise-FP8; sharing since the day-0 write-up's "FP8 rollout + BF16 training" phrasing might lead others down the same path.Question: is that phrasing intended to describe BF16 master weights with FP8 GEMMs (i.e. the blockwise recipe), rather than pure-BF16 training? A clarifying note would save reproducers a few $290/hr runs.
Minor:
tools/fp8_cast_bf16.pyon the public FP8 checkpointmtp.0.e_proj.weight/mtp.0.h_proj.weightinsgl-project/DeepSeek-V4-Flash-FP8carry noscale_inv, so the cast passes them through as FP8 ("Warning: Missing scale_inv tensor"), which later breaks torch dist-ckpt serialization (inline_container.cc:664 unexpected pos). Upcasting the two tensors to BF16 before conversion fixes it — a fallback upcast in the cast tool would make the public checkpoint work out of the box.Happy to share full logs/configs, and to test patches — we have the pipeline cached and can turn runs around quickly.