Repository navigation
feat: add DeepSeek V4 Flash GRPO support - Automodel path #3595
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Merged
sharonyu-115
merged 45 commits into
NVIDIA-NeMo:main
from
zpqiu:dsv4-automodel-r060-port
Sep 14, 2026
Merged
Changes from all commits
Commits
Show all changes
45 commits
Select commit
Hold shift + click to select a range
5e861c6
feat(deepseek-v4): port native automodel rollout support
zpqiu bde75f0
feat(recipes): add DeepSeek V4 Automodel CP baseline
zpqiu ab4c0ff
fix(deepseek-v4): port FP8 refit correctness
zpqiu 1174e6f
feat(recipes): enable DeepSeek V4 DeepGEMM rollout
zpqiu 918e528
fix(deepseek-v4): stabilize Automodel full-model training
zpqiu a724001
chore(deepseek-v4): trim unrelated FP8 config changes
zpqiu e509d9d
fix: use vLLM V1 executor for DeepSeek V4 FP8
zpqiu c251d27
refactor: remove redundant DeepSeek V4 refit loaders
zpqiu f2137fa
refactor: simplify DeepSeek V4 FP8 refit integration
zpqiu 6f82d57
fix(dsv4): bound FP8 refit memory
zpqiu f5ca329
fix(automodel): simplify FusedAdam memory handling
zpqiu 3f7a89c
refactor(dsv4): simplify FP8 refit handling
zpqiu e927a0e
refactor(dsv4): extend base FP8 module lookup
zpqiu b0219fd
refactor(dsv4): simplify FP8 refit paths
zpqiu 73a7e4d
Extract DeepSeek V4 FP8 refit helpers
zpqiu f719e51
Clarify refittable FP8 KV cache scales
zpqiu 0b5a30f
Scope GRPO KV scale restrictions
zpqiu b98584a
Simplify DeepSeek V4 tokenizer selection
zpqiu f45e1e3
chore: clarify vendored vLLM license
zpqiu 4deb3ea
fix(dsv4): preserve tokenizer renderer kwargs across workers
zpqiu 3dc35af
fix(automodel): align optimizer setup and model load dtype
zpqiu a054161
fix(automodel): stream EP-sharded expert exports safely
zpqiu 2894011
fix(dsv4): scope optimizer and checkpoint memory handling
zpqiu 39e5327
fix(dsv4): narrow and harden vLLM block-FP8 refit
zpqiu 6512a6e
refactor(dsv4): simplify optimizer path
zpqiu 6ad018b
refactor(automodel): minimize mesh setup changes
zpqiu cd61677
refactor(vllm): simplify DeepSeek V4 FP8 refit
zpqiu a2b1bc8
refactor(vllm): use reload-aware FP8 parameter replacement
zpqiu da974a1
chore(vllm): preserve upstream FP8 comments
zpqiu 02c1802
chore(vllm): reduce upstream diff noise
zpqiu 523e2c2
refactor(dsv4): remove unused expert rank filter
zpqiu abf7ad7
style: fix pre-commit formatting
zpqiu 0ad893e
docs: add DeepSeek V4 Flash guide and recipe
zpqiu b971b94
fix: resolve DeepSeek V4 lint failures
zpqiu d5b1b3c
fix: simplify DeepSeek V4 refit export
zpqiu 39e5647
chore: enable pyrefly for DeepSeek V4 encoding
zpqiu 321159a
chore: enable pyrefly for DeepSeek V4 tokenizer
zpqiu 436c109
fix: avoid eager DSV4 FP8 imports
zpqiu 83d6ea3
docs: restore async checkpoint comment
zpqiu 6962d5d
fix: harden DeepSeek V4 refit validation
zpqiu f3dae62
test: enable DeepSeek V4 Flash nightly coverage
zpqiu 0aa1b61
test: align DSV4 refit fixtures after upstream rebase
zpqiu d74d503
fix: guard DeepSeek V4 FP8 refit and tighten validation
zpqiu d01a0da
fix: scope FP8 MoE parameter replacement to DeepSeek V4
zpqiu 628e0cc
Merge branch 'main' into dsv4-automodel-r060-port
sharonyu-115 File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
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
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,169 @@ | ||
| # DeepSeek V4 Flash | ||
|
|
||
| This guide describes GRPO training of DeepSeek V4 Flash and Flash Base with the | ||
| AutoModel training backend and vLLM generation. | ||
|
|
||
| > [!IMPORTANT] | ||
| > **Status: Functionally Ready.** The reference recipe has been validated with | ||
| > an end-to-end colocated run on 16 H100 nodes. Its five-step smoke test is | ||
| > registered in the recurring nightly suite. This is not a long-run convergence | ||
| > claim; see [Known Limitations](#known-limitations) for precision alignment and | ||
| > hardware coverage. | ||
|
|
||
| ## Support Status | ||
|
|
||
| | Model | Training backend | Validated training parallelism | Generation backend | Status | | ||
| | --- | --- | --- | --- | --- | | ||
| | `deepseek-ai/DeepSeek-V4-Flash-0731` | AutoModel | TP1 + CP8 + EP128 | vLLM with TP8 + EP1 | Functionally Ready | | ||
| | `deepseek-ai/DeepSeek-V4-Flash-Base` | AutoModel | TP1 + CP8 + EP128 | vLLM with TP8 + EP1 | Functionally Ready | | ||
|
|
||
| ## Validated Scope | ||
|
|
||
| - **Models**: `deepseek-ai/DeepSeek-V4-Flash-0731` and | ||
| `deepseek-ai/DeepSeek-V4-Flash-Base`. | ||
| - **Algorithm**: GRPO with `DAPOMath17K` for training and | ||
| `DAPOMathAIME2024` for validation. | ||
| - **Training backend**: AutoModel with BF16 training, activation checkpointing, | ||
| TileLang attention, and the DeepEP expert dispatcher. | ||
| - **Training parallelism**: TP1, CP8, and EP128 on 128 GPUs. CP and EP are | ||
| model-owned parallel dimensions that coexist on the same device mesh; they | ||
| are not multiplicative. | ||
| - **Generation backend**: vLLM with TP8, EP1, blockwise FP8 weights, and the | ||
| `fp8_ds_mla` KV cache. | ||
| - **Sequence length**: 1,024 prompt tokens plus up to 2,048 response tokens, | ||
| for a maximum total sequence length of 3,072. | ||
| - **Reference allocation**: 16 nodes with 8 H100 GPUs per node. | ||
| - **Deployment**: Colocated training and generation on the same GPUs. Only | ||
| this deployment on H100 has been tested. | ||
| - **MTP**: Disabled by setting `num_nextn_predict_layers: 0`. | ||
|
|
||
| Recipe YAML files under `examples/configs/recipes/` are the source of truth for | ||
| resource, parallelism, dataset, and checkpointing settings. | ||
|
|
||
| ## How to Run | ||
|
|
||
| ### 1. Prepare the Environment | ||
|
|
||
| Use the dependency lock and AutoModel submodule recorded by the NeMo RL | ||
| revision that contains this guide. From the repository root, run: | ||
|
|
||
| ```bash | ||
| git submodule update --init --recursive | ||
| uv sync --locked | ||
| ``` | ||
|
|
||
| For a large multi-node run, use a container built from the same checkout so its | ||
| backend-specific worker environments match the lockfile. See the | ||
| [installation guide](../../../about/installation.md) and | ||
| [Dependency Management](../../../design-docs/dependency-management.md) for | ||
| container and development setup details. | ||
|
|
||
| The recipe downloads the following model and datasets from Hugging Face: | ||
|
|
||
| - `deepseek-ai/DeepSeek-V4-Flash-0731` or | ||
| `deepseek-ai/DeepSeek-V4-Flash-Base` | ||
| - `BytedTsinghua-SIA/DAPO-Math-17k` | ||
| - `BytedTsinghua-SIA/AIME-2024` | ||
|
|
||
| Set `HF_HOME` to a cache visible from every node: | ||
|
|
||
| ```bash | ||
| export HF_HOME=<path-to-shared-huggingface-cache> | ||
| export WANDB_API_KEY=<your-wandb-api-key> | ||
| ``` | ||
|
|
||
| The reference recipe enables W&B logging. If W&B is not configured, pass | ||
| `logger.wandb_enabled=false` when launching. | ||
|
|
||
| ### 2. Choose the Reference Recipe | ||
|
|
||
| | Model | Algorithm | Backend | Scale | Recipe | | ||
| | --- | --- | --- | --- | --- | | ||
| | DeepSeek-V4-Flash-0731 | GRPO | AutoModel | 16n8g | [`grpo-deepseek-v4-flash-0731-16n8g-automodel-cp8ep128.yaml`](../../../../examples/configs/recipes/llm/grpo-deepseek-v4-flash-0731-16n8g-automodel-cp8ep128.yaml) | | ||
|
|
||
| The associated | ||
| [`grpo-deepseek-v4-flash-0731-16n8g-automodel-cp8ep128.sh`](../../../../tests/test_suites/llm/grpo-deepseek-v4-flash-0731-16n8g-automodel-cp8ep128.sh) | ||
| test runs five training steps and is registered as a recurring nightly | ||
| functional test in [`nightly.txt`](../../../../tests/test_suites/nightly.txt). | ||
|
|
||
| ### 3. Launch | ||
|
|
||
| From a 16-node allocation with 8 H100 GPUs per node, launch the standard GRPO | ||
| entry point: | ||
|
|
||
| ```bash | ||
| uv run examples/run_grpo.py \ | ||
| --config examples/configs/recipes/llm/grpo-deepseek-v4-flash-0731-16n8g-automodel-cp8ep128.yaml | ||
| ``` | ||
|
|
||
| The recipe defaults to `DeepSeek-V4-Flash-0731`. To run Flash Base with the | ||
| same configuration, override the model and tokenizer: | ||
|
|
||
| ```bash | ||
| uv run examples/run_grpo.py \ | ||
| --config examples/configs/recipes/llm/grpo-deepseek-v4-flash-0731-16n8g-automodel-cp8ep128.yaml \ | ||
| policy.model_name=deepseek-ai/DeepSeek-V4-Flash-Base \ | ||
| policy.tokenizer.name=deepseek-ai/DeepSeek-V4-Flash-Base | ||
| ``` | ||
|
|
||
| See the [GRPO guide](../../grpo.md) for algorithm and common configuration | ||
| details and [Cluster Setup](../../../cluster.md) for multi-node launch setup. | ||
| Before changing the node count, review the training and generation parallel | ||
| dimensions instead of changing `cluster.num_nodes` alone. | ||
|
|
||
| ## Important Recipe Settings | ||
|
|
||
| - `policy.dequantize_base_checkpoint: true` loads either checkpoint as BF16 | ||
| weights for training. Flash-0731 stores its expert weights in FP4, while | ||
| Flash Base stores them in FP8. Training-side FP8 fake quantization is not | ||
| enabled. | ||
| - `policy.hf_config_overrides.expert_dtype: fp8` selects the FP8 expert layout | ||
| used for generation. Keep the checkpoint's own `quantization_config` intact | ||
| so AutoModel can dequantize the training weights correctly. | ||
| - Generation uses DeepGEMM with UE8M0 power-of-two scales. Keep | ||
| `VLLM_USE_DEEP_GEMM_E8M0=1`, `use_deep_gemm: true`, and | ||
| `pow2_weight_scaling_factors: true` aligned. | ||
| - `policy.generation.vllm_kwargs.attention_config.backend: FLASHMLA_SPARSE_DSV4` | ||
| pins the validated FlashMLA sparse attention backend. | ||
| - The policy tokenizer uses `chat_template: deepseek_v4`, while vLLM uses | ||
| `tokenizer_mode: deepseek_v4`. The reference recipe disables thinking mode. | ||
| - Eager execution (`enforce_eager: true`) remains part of the validated | ||
| configuration. | ||
|
|
||
| ## Reference Training Curves | ||
|
|
||
| The following curves were produced with `DeepSeek-V4-Flash-0731` on the | ||
| 16-node H100 configuration described above. They show the raw, unsmoothed | ||
| training and validation metrics through training step 50. | ||
|
|
||
|  | ||
|
|
||
| ## Known Limitations | ||
|
|
||
| - The checked-in support is limited to `DeepSeek-V4-Flash-0731` and | ||
| `DeepSeek-V4-Flash-Base` with the AutoModel training backend and vLLM | ||
| generation. DeepSeek V4 Pro, Megatron training, and SGLang generation are not | ||
| covered by this guide. | ||
| - **Hardware and deployment coverage**: Only colocated training and generation | ||
| on H100 GPUs have been tested. Non-colocated deployments and Blackwell GPUs | ||
| have not been validated. On Blackwell, DeepGEMM with E8M0 scales has a | ||
| potential refit issue: changes to the FP8 scale layout can leave the MoE | ||
| kernel referencing stale scales. | ||
| - Training uses dequantized BF16 weights, while generation uses refitted FP8 | ||
| weights. This numerical precision mismatch causes significant train/inference | ||
| inconsistency. The current recipe does not include training-side | ||
| quantization-aware training (QAT) to reduce this mismatch. | ||
| - MTP is disabled in the reference configuration. | ||
| - Long-run convergence has not been documented for this recipe. | ||
|
|
||
| The separate | ||
| [`deepseek-v4-support` development branch](https://github.com/NVIDIA-NeMo/RL/tree/deepseek-v4-support) | ||
| includes QAT through training-side FP8 fake quantization. It reduces the | ||
| train/inference mismatch and has enabled stable training beyond 100 steps. | ||
| See the [development branch guide](https://github.com/NVIDIA-NeMo/RL/blob/deepseek-v4-support/docs/guides/deepseek-v4.md) | ||
| for its recipes and validation results. | ||
| These results apply to that development branch, not the current recipe. The | ||
| branch uses an older NeMo-RL codebase and a customized AutoModel dependency, | ||
| so its changes cannot be merged directly into `main`. We plan to upstream the | ||
| relevant changes incrementally into NeMo-RL `main` and the upstream dependency | ||
| frameworks, including AutoModel. | ||
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
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,17 @@ | ||
| # DeepSeek | ||
|
|
||
| This section contains guides for running DeepSeek models with NeMo RL. For the | ||
| complete support matrix, see [Model Support](../../../about/model-support.md). | ||
|
|
||
| ## Version Guides | ||
|
|
||
| - **[DeepSeek V3](../../deepseek.md)** — Prepare a BF16 Hugging Face checkpoint for DeepSeek V3. | ||
| - **[DeepSeek V4 Flash](deepseek-v4-flash.md)** — Run GRPO with DeepSeek V4 | ||
| Flash or Flash Base using the AutoModel training backend and vLLM generation. | ||
|
|
||
| ```{toctree} | ||
| :hidden: | ||
| :maxdepth: 1 | ||
|
|
||
| deepseek-v4-flash.md | ||
| ``` |
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
129 changes: 129 additions & 0 deletions
129
examples/configs/recipes/llm/grpo-deepseek-v4-flash-0731-16n8g-automodel-cp8ep128.yaml
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
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,129 @@ | ||
| defaults: ../../grpo_math_1B.yaml | ||
| grpo: | ||
| batch_multiplier: 4 | ||
| max_num_epochs: 100 | ||
| max_num_steps: 1000 | ||
| normalize_rewards: false | ||
| use_leave_one_out_baseline: false | ||
| adv_estimator: | ||
| normalize_rewards: false | ||
| use_leave_one_out_baseline: false | ||
| max_val_samples: 960 | ||
| val_batch_size: 960 | ||
| use_dynamic_sampling: true | ||
| reward_scaling: | ||
| enabled: true | ||
| target_min: -1.0 | ||
| reward_shaping: | ||
| enabled: true | ||
| overlong_buffer_length: 1024 | ||
| max_response_length: 2048 | ||
| loss_fn: | ||
| token_level_loss: false | ||
| reference_policy_kl_penalty: 0.0 | ||
| use_importance_sampling_correction: true | ||
| truncated_importance_sampling_type: tis | ||
| truncated_importance_sampling_ratio: 2 | ||
| ratio_clip_max: 0.28 | ||
| ratio_clip_c: 10 | ||
| checkpointing: | ||
| checkpoint_dir: results/grpo-deepseek-v4-flash-0731-16n8g-automodel-cp8ep128 | ||
| keep_top_k: 1 | ||
| save_period: 2 | ||
| checkpoint_must_save_by: 00:03:45:00 | ||
| model_save_format: null | ||
| policy: | ||
| model_name: deepseek-ai/DeepSeek-V4-Flash-0731 | ||
| refit_buffer_size_gb: 1 | ||
| tokenizer: | ||
| chat_template: deepseek_v4 | ||
| chat_template_kwargs: | ||
| enable_thinking: false | ||
| dequantize_base_checkpoint: true | ||
| hf_config_overrides: | ||
| num_nextn_predict_layers: 0 | ||
| expert_dtype: fp8 | ||
| train_micro_batch_size: 1 | ||
| logprob_batch_size: 1 | ||
| max_total_sequence_length: 3072 | ||
| logprob_chunk_size: 1024 | ||
| offload_optimizer_for_logprob: true | ||
| make_sequence_length_divisible_by: 64 | ||
| optimizer: | ||
| kwargs: | ||
| lr: 1.0e-06 | ||
| weight_decay: 0.1 | ||
| scheduler: | ||
| - name: torch.optim.lr_scheduler.LinearLR | ||
| kwargs: | ||
| start_factor: 0.01 | ||
| end_factor: 1.0 | ||
| total_iters: 5 | ||
| - name: torch.optim.lr_scheduler.ConstantLR | ||
| kwargs: | ||
| factor: 1.0 | ||
| total_iters: 10000000000 | ||
| - milestones: | ||
| - 5 | ||
| dtensor_cfg: | ||
| context_parallel_size: 8 | ||
| expert_parallel_size: 128 | ||
|
zpqiu marked this conversation as resolved.
Resolved
|
||
| activation_checkpointing: true | ||
| moe_parallelizer: | ||
| ignore_router_for_ac: true | ||
| reshard_after_forward: false | ||
| automodel_kwargs: | ||
| backend: | ||
| _target_: nemo_automodel.components.models.common.BackendConfig | ||
| attn: tilelang | ||
| linear: torch | ||
| rms_norm: torch_fp32 | ||
| experts: torch_mm | ||
| dispatcher: deepep | ||
| fake_balanced_gate: false | ||
| rope_fusion: false | ||
| enable_hf_state_dict_adapter: true | ||
| enable_fsdp_optimizations: true | ||
| sequence_packing: | ||
| enabled: false | ||
| dynamic_batching: | ||
| enabled: true | ||
| generation: | ||
| max_new_tokens: 2048 | ||
| vllm_cfg: | ||
| precision: fp8 | ||
| kv_cache_dtype: fp8_ds_mla | ||
| env_vars: | ||
| VLLM_USE_DEEP_GEMM_E8M0: '1' | ||
| use_deep_gemm: true | ||
| pow2_weight_scaling_factors: true | ||
| tensor_parallel_size: 8 | ||
| enable_expert_parallel: true | ||
| enforce_eager: true | ||
| vllm_kwargs: | ||
| tokenizer_mode: deepseek_v4 | ||
|
sharonyu-115 marked this conversation as resolved.
Resolved
|
||
| attention_config: | ||
| backend: FLASHMLA_SPARSE_DSV4 | ||
| data: | ||
| max_input_seq_length: 1024 | ||
| train: | ||
| dataset_name: DAPOMath17K | ||
| validation: | ||
| dataset_name: DAPOMathAIME2024 | ||
| default: | ||
| prompt_file: null | ||
| env: | ||
| math: | ||
| num_workers: 16 | ||
| math_verify_impl: dapo_math_verify | ||
| logger: | ||
| wandb_enabled: true | ||
| tensorboard_enabled: true | ||
| num_val_samples_to_print: 2 | ||
| num_train_samples_to_print: 2 | ||
| wandb: | ||
| project: nemo-rl | ||
| name: grpo-deepseek-v4-flash-0731-16n8g-automodel-cp8ep128 | ||
| cluster: | ||
| gpus_per_node: 8 | ||
| num_nodes: 16 | ||
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
Oops, something went wrong.
Oops, something went wrong.
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.
Uh oh!
There was an error while loading. Please reload this page.