1. Model Introduction
Qwen3.8 continues Alibaba’s Qwen3 line. The dense Qwen3.8-27B ships the sameconfig.json as
Qwen3.5-27B and Qwen3.6-27B —
same hybrid GDN backbone, same gated attention, same tokenizer and vocabulary.
It therefore reuses the Qwen3.5 Megatron spec
(miles_plugins.models.qwen3_5.get_qwen3_5_spec), and
scripts/models/qwen3.8-27B.py is a one-line derivation of the Qwen3.5-27B
model args; the three expand to byte-identical Megatron flags.
The sparse Qwen3.8-2.4T-A95B is a different recipe entirely — see
section 6.
Key highlights (27 B):
- Dense GDN backbone: 27 B parameters, hybrid linear / full attention (
full_attention_interval 4). - Attention-output gate: shared with Qwen3.5, trained alongside attention weights.
- Extended rotary base:
--rotary-base 10000000,--rotary-percent 0.25. - Larger vocabulary: 248320 tokens.
- Shape:
hidden-size 5120,ffn-hidden-size 17408, 64 layers. - Multimodal:
Qwen3_5ForConditionalGeneration; the RL recipe below trains the text path only.
2. Supported Variants
Sections 3–6 cover the dense 27 B.
3. Environment Setup
3.1 Download model + datasets
3.2 HF → Megatron torch_dist conversion
Run it on all eight GPUs; the tool shards the 64 layers over the ranks
(--pipeline-model-parallel-size is derived from WORLD_SIZE) and the output
re-shards at load, so the conversion layout does not have to match the training one:
4. Launch
4.1 Quick start
scripts/run_qwen3_dense.py is the shared dense launcher; --model-name Qwen3.8-27B
selects this recipe, which targets 1 node × 8 GPU. Checkpoints come from --model-dir
(default /root/models) and datasets from --data-dir (default /root/datasets);
checkpoints are written under --output-dir (default /root/shared_data).
4.2 What one step costs
Measured on 1 × 8 H200 with the recipe below,rollout-batch-size 32,
n-samples-per-prompt 8, rollout-max-response-len 8192:
perf/tokens_per_gpu_per_sec 478. Mean response length 4585 tokens, 33 % truncated at the
8192 cap. Step 0 reported rollout/raw_reward 0.64 and
train/train_rollout_logprob_abs_diff 0.010, i.e. the SGLang and Megatron forward passes
agree closely — see True On-Policy for what that
metric does and does not tell you.
5. Recipe Configuration
5.1 Parallelism
--sequence-parallel is enabled. Activation checkpointing is on
(--recompute-granularity full --recompute-method uniform --recompute-num-layers 1).
5.2 Algorithm
GRPO with low-variance KL:5.3 Rollout & SGLang
Decode re-reads all 53 GB of weights every step regardless of batch size, so the small
batch was pure bandwidth waste. Under colocate the training model is offloaded to host RAM
during rollout, and the training-phase peak at 0.8 measured 88–90 GB of 140 GB, so the
higher fraction costs nothing. Two further levers if rollout is still the bottleneck:
--rollout-num-gpus-per-engine 2 (halves per-GPU weights and shards the GDN state), and
--sglang-mamba-ssm-dtype bfloat16 (halves the state, at a precision cost worth checking
against train/train_rollout_logprob_abs_diff).
5.4 Optimizer
CPU Adam is enabled (--optimizer-cpu-offload --overlap-cpu-optimizer-d2h-h2d --use-precision-aware-optimizer).
5.5 Notable quirks
Fromscripts/models/qwen3.8-27B.py, which defers to scripts/models/qwen3.5-27B.py:
--spec miles_plugins.models.qwen3_5 get_qwen3_5_spec— Qwen3.8 reuses the Qwen3.5 spec (gated attention, FP32A_log).--rotary-base 10000000,--rotary-percent 0.25.--vocab-size 248320.--apply-layernorm-1p,--qk-layernorm,--group-query-attention.--attention-output-gate.
A_log out of the low-precision optimizer path.
6. Qwen3.8-2.4T-A95B
The sparse 2.4 T / 95 B-active flagship shares nothing operational with the dense 27 B: the rollout engines serve the native ModelOpt NVFP4 experts-only checkpoint (RadixArk/Qwen3.8-2.4T-A95B-NVFP4) while the Megatron trainer runs BF16 off atorch_dist built from the BF16 parent, and
weight sync ships LoRA adapters only — the quantized base never leaves the engines. The
implementation is radixark/miles#2488
(“Qwen 3.8 day-0 lora RL support”): scripts/run_qwen3_8.py plus the
scripts/models/qwen3.8-2.4T-A95B{,_4layer,_full}.py definitions. It is LoRA-only in
practice — the native raw-mode --lora path is the validated route; treat full-weight
training as unvalidated.
6.1 Variants
--model-variant selects between them and sets the matching checkpoint paths and
megatron_model_type (scripts/models/qwen3.8-2.4T-A95B{_4layer,_full}.py):
6.2 Environment Setup
Use thedocker.io/radixark/miles:dev image — it is multi-arch, so the same tag serves
GB300 (aarch64) and x86 nodes. Inside the container, multi-node rollout engines need
NCCL ≥ 2.30.7 (2.28.x deadlocks CUDA-graph-captured cross-node collectives):
--model-dir (default /root/models) as
Qwen3.8-2.4T-A95B-NVFP4_<variant> (rollout) and
Qwen3.8-2.4T-A95B-bf16_<variant> (trainer source):
--skip-prepare is passed, the launcher’s prepare step downloads
zhuzilin/dapo-math-17k and runs the BF16 → torch_dist conversion itself
(tools/convert_hf_to_torch_dist.py via the qwen3.8-2.4T-A95B_<variant> model args); the
output re-shards at load, so the conversion layout does not have to match the training one.
Training then takes the NVFP4 directory as --hf-checkpoint and the converted
torch_dist as --ref-load — both wired up by the launcher.
6.3 Launch
Single-node smoke test (default--model-variant 4layer, 8 GPUs):
export MILES_SCRIPT_EXTERNAL_RAY=1, then run on the head):
6.4 Memory: the alternating-backup budget
The recipe fits 956 GB hosts only if, at any moment, exactly one side keeps a host backup: during rollout the sleeping trainer’s tms backup (~390 GB/node); during train the sleeping engines’ NVFP4 mirror (~372 GB/node,--lora-base-cpu-backup →
SGLang enable_weights_cpu_backup, which is also what lets every weight update skip the
base re-ship). Anything that double-books breaks it. The flags that hold the line:
--drop-checkpoint-page-cache-after-load— a multi-TB DCP read leaves its page cache on every node; lazy reclaim loses the race against pinned-allocation spikes at the rollout/train handoff.--colocate-memory-peak-device gpuand no--use-kl-lossatkl-loss-coef 0— a zero coefficient still loads a full ref checkpoint and pins a second per-rank base copy.- Weight sync must not clone the sleeping side’s backup (
get_cpu_backup(zero_copy=True)in #2488); the clone variant retains ~75 GB/rank in malloc arenas per update.
7. Pairs Well With
- Qwen3.5 — same architecture at 4 B / 9 B / 27 B
- True On-Policy
- Low Precision RL

