Repository navigation
feat(draft): support packed context-parallel co-training #3757
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
Open
seonjinn
wants to merge
398
commits into
NVIDIA-NeMo:main
Choose a base branch
from
seonjinn:seonjinn/draft-cotrain-cp-v1-linear
base: main
Could not load branches
Branch not found: {{ refName }}
Loading
Could not load tags
Nothing to show
Loading
Are you sure you want to change the base?
Some commits from the old base branch may be removed from the timeline,
and old review comments may become outdated.
Open
Changes from all commits
Commits
Show all changes
398 commits
Select commit
Hold shift + click to select a range
0f097a2
fix(draft): synchronize TP input shapes
seonjinn 4ce4c30
Merge NVIDIA-NeMo/RL main into PR9
seonjinn 3dfef44
Merge NVIDIA-NeMo/RL main into PR9
seonjinn 9721015
style(vllm): normalize speculator runtime imports
seonjinn ef32181
fix(vllm): fail closed on FP8 KV postprocess errors
seonjinn 3921a78
feat(refit): represent train context parallelism
seonjinn b05e245
fix(refit): validate CP refit mesh setup
seonjinn 52e50b4
fix(refit): validate PP before communicator setup
seonjinn c8bbc46
feat(draft): bucket refit payloads by CP lane
seonjinn 4539a29
fix(draft): synchronize CP lane refit preflight
seonjinn 39ee71e
feat(draft): bind refit owners to MCore CP lanes
seonjinn 692d3ea
fix(draft): forward metadata through quant refit
seonjinn bc3d4e5
fix(draft): satisfy refit metadata typing
seonjinn fb7a1c7
style(refit): format CP validation test
seonjinn c467540
test(draft): cover real-quant metadata transport
seonjinn 74ab3d2
test(refit): cover cross-group draft failure
seonjinn 6de4b13
fix(refit): fail together before draft transport
seonjinn 6bbf215
fix(refit): preflight draft metadata before meta context
seonjinn 3e36e97
fix(refit): narrow synchronized error chaining
seonjinn 56494c3
feat(draft): support packed context-parallel co-training
seonjinn 7d73fce
fix(dspark): require target-owned vocabulary
seonjinn c26ff0a
test(draft): compose TP2 with packed CP groups
seonjinn 438134e
chore(draft): include stable IDs in type checks
seonjinn 1ae1a9c
test(dspark): patch isolated provider fixture
seonjinn 0198f9e
chore(draft): add missing copyright headers
seonjinn a393e03
docs(draft): document optimizer update probes
seonjinn 915a2db
test(draft): cover target TP and optional draft config
seonjinn 7f51cb4
fix(draft): enforce supported topology and preserve no-draft training
seonjinn d0f67cc
docs(draft): add block-draft guide and nightly
seonjinn 1888640
test(draft): require CP-invariant split gradients
seonjinn 30b76f2
test(dspark): require revision-aware checkpoint loading
seonjinn ed3dac7
test(draft): require CP-invariant leader metrics
seonjinn e166171
fix(draft): normalize CP gradients and metrics
seonjinn 4e17585
fix(dspark): separate checkpoint revision from model ID
seonjinn 0195822
fix(dflash): preserve CP autograd for empty queries
seonjinn 0dc5f9a
test(dspark): allowlist public revision literal
seonjinn 55e677b
fix(dflash): accept inherited auxiliary layer field
seonjinn 4be3c96
test(dspark): add packed CP nightly coverage
seonjinn 27cdb2d
fix(draft): allow capable providers with packed policies
seonjinn fbe73bf
test(draft): require post-update refit coverage
seonjinn 24956bc
test(draft): mark completed post-update refits
seonjinn d832b1a
test(draft): expose resumed refit marker ordering
seonjinn 44b13d3
fix(draft): track pending post-update refits
seonjinn 218ec64
test(dflash): align CP attention oracles
seonjinn 3856435
fix(dflash): accept singleton CP groups
seonjinn 8a90d63
test(dflash): require stable CUDA graph recipe
seonjinn a39b04f
fix(dflash): use stable CUDA graph compilation
seonjinn b4e6c7b
ci(dspark): allowlist official artifact hashes
seonjinn 8871c2f
fix(dflash): pass unpacked benchmark layout
seonjinn 2b6295f
test(dflash): populate expanded attention plans
seonjinn ba7ecbc
test(dflash): pass unpacked block mask layout
seonjinn 2471561
test(draft): assert CP denominator group by call intent
seonjinn ee222de
test(draft): compare CUDA metrics as scalars
seonjinn 54a3d9b
Fix TP checkpoint group handling and shard tagging in DSpark heads
seonjinn 829a1d6
fix(test): forward GPU topology to Ray launcher
seonjinn 7700a07
Remove redundant TP metadata collective and document DFlash loss cont…
seonjinn a5ef756
fix(draft): route packed CP training through split API
seonjinn 7b80930
fix(draft): align split routing with provider capabilities
seonjinn abc74d7
Document artifact pin and TP ceiling, test error branches, rename PP-…
seonjinn 446ea90
fix(dflash): reconstruct target-SP mask embeddings
seonjinn ddae591
fix(draft): isolate transient outputs from packed policy loss
seonjinn 88643a6
fix(draft): resolve context parallel size at finish
seonjinn c49fd46
test(draft): assert context parallel gradient correction
seonjinn 42cefa8
Add chunk parametrization, raise tests, rename shadowed var, document…
seonjinn d43a5b6
fix(dflash): satisfy import ordering
seonjinn 3e6ecae
fix(draft): share TP-safe DSpark Markov embeddings
seonjinn 8887579
test(draft): assert streaming loss normalization shape
seonjinn 0728112
fix(grpo): aggregate CUDA draft metrics safely
seonjinn 3922322
fix(metrics): share CUDA-safe step reduction
seonjinn 895e0c2
Validate caller-supplied bin_ids range in streaming soft CE
seonjinn f272799
test(dspark): cover target-SP masks and graph config
seonjinn 9735386
test(dspark): assert reconstructed mask block shape
seonjinn 815b783
fix(dspark): reconstruct target-SP mask blocks
seonjinn 8a03385
Guard nccl_reshard bulk receive with fail-closed refit lifecycle
seonjinn f85be2e
Test wire-decode failure surface, document vestigial control hook
seonjinn 59c875a
Merge PR9 dependency into PR10
seonjinn be3b9d1
Merge refreshed PR10 dependency into PR11
seonjinn be40c54
test(refit): match wire-status error contract
seonjinn 4649436
Merge PR10 refit test correction into PR11
seonjinn 1574946
Restore TP shape agreement, gate CP inheritance, tolerate zero-window…
seonjinn da1bd0e
test(refit): initialize NCCL lifecycle fixture
seonjinn 2c97a5b
Merge PR10 NCCL fixture correction into PR11
seonjinn ea57fed
test(refit): cover non-owner payload allocation failure
seonjinn d4129f6
test(draft): prove CP finish normalization parity
seonjinn 47922aa
test(draft): report CP normalization mutation
seonjinn 443e724
Merge refreshed PR10 payload coverage into PR11
seonjinn b4f7744
Run reshard preflight inside the fail-closed refit guard
seonjinn 1deb4be
Gate embedding TP reduction on consumer sharding, not head sharding
seonjinn c31cead
Match real-quant finalize to the finalize_draft lifecycle signature
seonjinn 4a7f8ca
Pass finalize_draft in real-quant lifecycle test
seonjinn 52e2553
Accept coverage kwarg in real-quant weight loading
seonjinn 8f39756
Merge current PR9 into PR10
seonjinn a021b04
Merge refreshed PR10 into PR11
seonjinn df9daf6
fix(draft): preserve typed disabled refit config
seonjinn c8f1b6c
test(draft): cover asymmetric qwen moe attention widths
seonjinn c47fd50
test(draft): use locked python for focused runner
seonjinn 2ba2da2
test(draft): add qwen moe body behavior probe
seonjinn 273dfc1
fix(draft): allow asymmetric qwen attention projections
seonjinn fadae4e
fix(draft): preserve asymmetric qwen tp export shapes
seonjinn d0c4f11
test(draft): include asymmetric tp export regression
seonjinn 14239a8
test(vllm): accept coverage in real-quant IPC load
seonjinn 87c7572
test(draft): select qwen mcore regressions
seonjinn a063fba
chore(draft): add headers to qwen test tools
seonjinn 1fe5fde
test(draft): isolate qwen runner arguments
seonjinn 3c3fc10
test(vllm): match unprepared coverage fixture
seonjinn 3c9218b
Merge current PR9 CI fix into PR10
seonjinn edc838a
Merge current PR10 into PR11
seonjinn af952e8
Reject near-miss typo keys in Eagle3DraftConfig
seonjinn 9c792dc
Validate caller-supplied bin_ids range in streaming soft CE
seonjinn fd12c9c
Add split parity regression test and shared draft_loss metric key
seonjinn ec3a939
Fix parity test tolerance and stub for draft loss metric key
seonjinn 246b391
Document and pin zero decay for draft norm and bias params
seonjinn 866de64
Skip draft optimizer test collection without megatron bridge
seonjinn 8442dc9
Fix TP checkpoint group handling and shard tagging in DSpark heads
seonjinn 9f5c59c
fix(draft): share TP-safe DSpark Markov embeddings
seonjinn f63dee4
Gate embedding TP reduction on consumer sharding, not head sharding
seonjinn ed16b85
Remove redundant TP metadata collective and document DFlash loss cont…
seonjinn f0df99e
Add chunk parametrization, raise tests, rename shadowed var, document…
seonjinn c4c0f32
Format restacked draft config regression
seonjinn eee45f4
fix(refit): frame packed collective failures
seonjinn fa2afa0
fix(modelopt): finalize cotrained draft refits
seonjinn bc853fe
fix(refit): drain packed collective failures
seonjinn e2da091
fix(loss): validate projected soft CE bin ids
seonjinn 03cc0e2
fix(loss): avoid duplicate projected bin validation
seonjinn 4ee518b
test(vllm): add lifecycle test copyright header
seonjinn f185535
Merge remote-tracking branch 'nvidia-current/main' into fix/pr3715-ho…
seonjinn 2d4ed91
test(draft): cover single DFlash metadata agreement
seonjinn accd30e
Merge origin/main into sna/megatron-sft-prepacked-inputs
seonjinn 8dfcf14
Fix submodule pointers to match main after merge
seonjinn bc265c8
Fix cp_normalize in direct-packed loss and lazy-import megatron in test
seonjinn d0cff7e
fix(sft): finalize direct-packed config and docs
seonjinn 77bd36c
docs(sft): clarify context-parallel packing requirement
seonjinn 064fcf9
Merge remote-tracking branch 'origin/main' into review/pr-3703-main-m…
seonjinn a141bfa
Merge remote-tracking branch 'origin/main' into review/pr-3703-main-m…
seonjinn cbda213
Merge remote-tracking branch 'origin/main' into review/pr-3703-main-m…
seonjinn 3e4cc82
feat(draft): expose draft soft-CE token_chunk_size as config
seonjinn f633cab
Fix import ordering in loss wrapper
seonjinn d9068ad
Add draft.token_chunk_size to grpo reference config
seonjinn e9c1c25
Merge remote-tracking branch 'origin/main' into review/pr-3703-main-m…
seonjinn f8aacd4
Merge remote-tracking branch 'origin/main' into review/pr-3715-main-m…
seonjinn 5f29007
Merge remote-tracking branch 'origin/main' into review/pr-3711-main-m…
seonjinn 965062d
Merge remote-tracking branch 'origin/main' into review/pr-3726-main-m…
seonjinn 3b98b9c
Merge remote-tracking branch 'origin/main' into review/pr-3723-main-m…
seonjinn d21e05d
Merge remote-tracking branch 'origin/main' into review/pr-3744-main-m…
seonjinn de44de0
Merge latest main into drafter weight transport
seonjinn 20de8a2
Merge latest main into packed context-parallel draft co-training
seonjinn 236f359
Address review: draft export contract, dtype header codes, chunk-size…
seonjinn 3ad5841
Address review: reject draft refit on nccl_reshard and real-quant paths
seonjinn 18736c0
Address review: drop CP axis from the expert source mesh
seonjinn 87434d3
Address review: gate draft layout on provider, keep draft IDs through…
seonjinn a068c1a
Expose draft soft-CE token chunk size and fix dspark import spacing
seonjinn 2ee5b2d
Expose draft soft-CE token chunk size as policy.draft.token_chunk_size
seonjinn 931d410
Merge remote-tracking branch 'origin/main' into review/pr-3757-main-m…
seonjinn e511070
Document the draft token chunk size default
seonjinn 2bcc783
Document draft token chunk size in the loss config
seonjinn b52b1f4
Document draft token chunk size in the loss config
seonjinn 446bd6b
Merge remote-tracking branch 'origin/main' into review/pr-3723-main-m…
seonjinn fa49016
Merge remote-tracking branch 'origin/main' into review/pr-3703-main-m…
seonjinn e110f51
Merge remote-tracking branch 'origin/main' into review/pr-3711-main-m…
seonjinn 369ffab
Merge remote-tracking branch 'origin/main' into review/pr-3715-main-m…
seonjinn 82cf47b
Merge remote-tracking branch 'origin/main' into review/pr-3744-main-m…
seonjinn 1285665
Merge remote-tracking branch 'origin/main' into review/pr-3726-main-m…
seonjinn ae7f72c
Merge remote-tracking branch 'origin/main' into review/pr-3750-main-m…
seonjinn 8ca4869
fix(sft): harden prepacked input validation
seonjinn 80625d5
fix(refit): align weight finalizer contract
seonjinn 6017c37
fix(draft): address co-training review feedback
seonjinn 711cb08
Merge branch 'main' into seonjinn/pr9-v3-latest-main
seonjinn 122af10
Merge branch 'main' into seonjinn/draft-cotrain-streaming-loss-20260818
seonjinn 18c8f46
Merge branch 'main' into seonjinn/draft-cotrain-dspark-core
seonjinn b84eba1
Merge main into sna/megatron-sft-prepacked-inputs
seonjinn 864e872
Merge streamed soft CE dependency updates
seonjinn cf40c00
Merge commit '864e8720eef9a56a3f3072e18ee3842d23f1e677' into HEAD
seonjinn 4dc91df
Merge commit '122af108cea19cef0781cd9cf3a8c163ed34e56e' into HEAD
seonjinn c6e1df1
Merge commit '18c8f468cae199290c015c5fde9f4f9fffb133f7' into HEAD
seonjinn b86a79b
Merge commit '711cb08e6276bbb6460188966fb67ad6f641d75a' into review/p…
seonjinn cfc4de3
Merge context-parallel refit dependency into PR #3757
seonjinn 626a143
Merge prepacked SFT dependency into PR #3757
seonjinn acffbba
style: apply lint fixes
seonjinn 040ddcc
Merge branch 'main' into PR #3723
seonjinn 77084ae
Merge branch 'main' into PR #3726
seonjinn 37ba21a
Merge branch 'main' into PR #3744
seonjinn 4ed8a37
Merge branch 'main' into PR #3750
seonjinn 3ff97fd
Merge branch 'main' into PR #3757
seonjinn 53a43d9
Merge remote-tracking branch 'origin/main' into review/pr-3723-remote…
seonjinn 92bef67
Merge remote-tracking branch 'origin/main' into review/pr-3726-remote…
seonjinn cc792ac
Merge remote-tracking branch 'origin/main' into review/pr-3744-remote…
seonjinn b5499bf
Merge remote-tracking branch 'origin/main' into review/pr-3750-remote…
seonjinn c499596
Merge remote-tracking branch 'origin/main' into review/pr-3757-remote…
seonjinn b6bbca2
Merge remote-tracking branch 'origin/main' into review/pr-3723-remote…
seonjinn e9726dd
Merge remote-tracking branch 'origin/main' into review/pr-3726-remote…
seonjinn 4228147
Merge latest main into PR #3723 and retain only unmerged extensions
seonjinn 60ed04e
Merge latest main into PR #3726 and retain only unmerged extensions
seonjinn c27aba8
Merge latest main into PR #3744 and retain only unmerged extensions
seonjinn 48b90df
Merge latest main into PR #3750 and retain only unmerged extensions
seonjinn 9dd469b
Merge latest main into PR #3757 and reconcile packed draft contracts
seonjinn e606829
Merge branch 'main' into review/pr-3723-remote-main-merge
seonjinn 430d777
Merge branch 'main' into review/pr-3726-remote-main-merge
seonjinn a6f15d5
chore(draft): merge latest main for PR #3723
seonjinn 868223f
chore(draft): merge latest main for PR #3726
seonjinn 3477890
chore(draft): merge latest main for PR #3723
seonjinn 0fc5b29
chore(draft): merge latest main for PR #3726
seonjinn 9b0561b
Merge latest main after #3706 into PR #3726
seonjinn 3186bd1
Merge latest main after #3706 into PR #3723
seonjinn 9641ffb
test: collect draft worker coverage and exercise input guards
seonjinn 76929b6
test: record coverage after pytest-cov finalizes collection
seonjinn f93fef0
Merge upstream/main into PR #3744 for vLLM 0.29
seonjinn 3f080f6
Merge upstream/main into PR #3744 for vLLM 0.29
seonjinn 02804d3
feat(refit): restore context-parallel draft transport on vLLM 0.29
seonjinn f37420f
Merge commit '48b90df00f147dbc1d6627428366c900de8fa035' into codex/re…
seonjinn c7846bb
test(vllm): use a realized model fixture for refit preflight
seonjinn 3bca316
fix(vllm): validate native refit before manifest setup
seonjinn e4cea11
fix(refit): preflight draft weights before IPC streaming
seonjinn 1a94309
test(refit): run IPC preflight checks in MCore shard
seonjinn 2873461
test(refit): preserve lazy IPC parameter iteration
seonjinn 9f5aad7
Merge latest main into DFlash body
seonjinn 0d1abdb
Merge latest main into DSpark objectives
seonjinn 816aae5
docs: explain DFlash body contract and limits
seonjinn a8efe44
docs: describe DSpark objectives and normalization
seonjinn 2e7667e
docs: correct DSpark token chunk description
seonjinn 12c2799
Merge latest main into PR #3744
seonjinn e88f972
Merge latest main into PR #3750 and clarify CP draft refit
seonjinn 6d6c30b
docs(draft): clarify packed DFlash and DSpark setup
seonjinn 6c6f18c
Merge NVIDIA-NeMo/RL main into DFlash body PR
seonjinn 3f10b44
fix(draft): use supported all-gather for TP metadata
seonjinn 2f3d2e0
Merge latest main into DFlash tensor-parallel body
seonjinn e7becda
docs(draft): clarify DFlash weight ownership
seonjinn 9ef0240
docs(draft): explain DFlash body usage and computation
seonjinn c8b3c60
docs(draft): explain DFlash body at a conceptual level
seonjinn 227e965
docs(draft): keep DFlash overview conceptual
seonjinn 8176428
fix(draft): address DFlash body review threads
seonjinn f3413fe
Merge remote-tracking branch 'origin/main' into seonjinn/pr9-v3-lates…
seonjinn fe6f97d
fix(refit): let a later refit recover a partial-refit worker
seonjinn 698e97a
fix(refit): reject TRTLLM draft refit when preparing refit info
seonjinn 2215395
Merge #3744 fixes and origin/main into draft CP refit
seonjinn 63d1d41
fix(refit): reject vLLM context parallelism through real config keys
seonjinn 19412fc
fix(refit): send every draft bucket failure to the PP lane consensus
seonjinn 667c4cd
fix(refit): fail closed when draft weights drift from prepared metadata
seonjinn 1d890ab
test(refit): cover watchdog abort and preflight_checked framing
seonjinn 677b41b
fix(refit): require draft coverage on the nccl_reshard misc stream
seonjinn d086dee
Merge origin/main into DSpark objective
seonjinn daf91e0
test(unit): register shard options in the coverage lifecycle stubs
seonjinn 269a7bc
fix(dspark): keep acceptance targets when the valid mask is permuted
seonjinn 7ae38a8
fix(dspark): give every dtype a distinct TP agreement code
seonjinn a38a93d
Merge PR #3723 DFlash draft body into the rebuild base
seonjinn c48e028
Merge PR #3726 DSpark objective into the rebuild base
seonjinn ab5493b
Restore DFlash files dropped by the rebuild-base merge
seonjinn dcbc08e
Merge #3757 head 6d6c30bf97 onto post-merge main stack base
seonjinn 5cf651f
Reject unsupported draft trainer layouts at GRPO setup
seonjinn 075ccf7
Drain packed refit frames when lazy consumer stops early
seonjinn 5a85b30
Pin DFlash recipe drafter and extend chained nightly budget
seonjinn 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
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,39 @@ | ||
| # DFlash Draft Body | ||
|
|
||
| The target model provides hidden states for an input sequence. The DFlash draft | ||
| body uses these states as context for short blocks of draft-token positions. | ||
| It updates all positions in a block together and returns hidden states for a | ||
| separate draft-loss calculation. The body does not produce vocabulary logits. | ||
|
|
||
| ## How It Works | ||
|
|
||
| 1. **Choose anchors.** An anchor is a valid position in the target sequence. | ||
| `build_dflash_batch_plan` chooses anchors and records which draft positions | ||
| belong to each one. The same input mask, sample IDs, optimizer step, and seed | ||
| produce the same plan. Rows with the same sample ID get the same anchors, so | ||
| give each rollout row a unique sample ID. A sample with no valid window | ||
| contributes no draft loss. | ||
| 2. **Build draft blocks.** Each block has one anchor position followed by | ||
| `gamma` draft positions. The caller supplies an embedding for each position. | ||
| The target model supplies selected hidden states from its layers. | ||
| 3. **Update the blocks.** `DFlashBody` projects the target hidden states and | ||
| passes the block embeddings through draft decoder layers. Within a layer, | ||
| each block can read the target prefix before its anchor and all positions | ||
| in that same block. It cannot read another block. Attention computes outputs | ||
| for block positions only. It does not update the target sequence. | ||
| 4. **Compute the loss.** The body returns one hidden state per block position. | ||
| The caller uses `plan.loss_mask` to exclude the anchor and invalid positions | ||
| from the draft loss. The body returns zero for invalid positions. | ||
|
|
||
| With this separation, the caller can use the same target-model context for | ||
| all draft blocks. The attention of each block stays independent. | ||
|
|
||
| ## Scope | ||
|
|
||
| The body implements the draft-state update only. The caller supplies token | ||
| embeddings and uses the returned states to compute vocabulary logits and loss. | ||
|
|
||
| The body supports tensor parallelism. The tensor-parallel size must divide | ||
| `num_key_value_heads`, so the default config supports a maximum of 8. The body | ||
| does not support sequence parallelism or context parallelism greater than 1. | ||
| The caller controls pipeline-parallel placement. |
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,24 @@ | ||
| # DSpark Objectives | ||
|
|
||
| `dspark_tiled_objective` computes three losses for valid draft slots: | ||
|
|
||
| | Loss | Purpose | | ||
| | --- | --- | | ||
| | Hard cross-entropy (CE) | Train on sampled draft labels. | | ||
| | Total variation (TV) | Compare the draft and target token distributions. | | ||
| | Confidence | Predict token acceptance when a confidence head is present. | | ||
|
|
||
| The function processes draft tokens in bounded chunks. It keeps target | ||
| logits and the target output head stop-gradient. The Markov head uses | ||
| previous-token IDs from the target vocabulary. Loss labels use the selected | ||
| draft-vocabulary order. The two vocabularies can have different sizes. | ||
|
|
||
| Each loss returns raw numerator and valid-slot count bins. The combined loss | ||
| uses the configured CE, TV, and confidence weights. Position weights scale | ||
| both numerators and denominators. Reduce counts across data-parallel ranks | ||
| before calling `DSparkLossBins.normalized`. | ||
|
|
||
| `build_dspark_provider` attaches the Markov head and optional confidence head | ||
| to a checkpointable draft body. PR #3711 defines the head shapes and | ||
| checkpoint keys. | ||
| Training-loop configuration and rollout execution are outside this change. |
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,213 @@ | ||
| # Train DFlash and DSpark Online | ||
|
|
||
| DFlash and DSpark are block-parallel speculative decoders. NeMo RL trains either | ||
| draft model with a Megatron policy. It then refits both models into vLLM for | ||
| rollout generation. | ||
|
|
||
| This guide covers the supported online co-training path. For GRPO setup, see | ||
| the [GRPO guide](grpo.md). For the Eagle3 workflow, which has different packing | ||
| constraints, see [Train with Eagle3 Speculative Decoding](eagle3-speculative-decoding.md). | ||
|
|
||
| ## Supported Topologies | ||
|
|
||
| Use one of the layouts below. NeMo RL rejects unsupported layouts before | ||
| training. | ||
|
|
||
| | Component | Supported configuration | | ||
| | --- | --- | | ||
| | Training backend | Megatron Core | | ||
| | Target tensor parallelism | TP2 | | ||
| | Target pipeline parallelism | PP1 with no virtual pipeline parallelism | | ||
| | Target context parallelism | CP1, CP2, or CP4 | | ||
| | Sequence packing | Optional at CP1; required at CP2 and CP4 | | ||
| | Target sequence parallelism | Supported only with sequence packing | | ||
| | DFlash/DSpark body sequence parallelism | Disabled | | ||
| | Generation topology | CP1 and PP1 | | ||
|
|
||
| Set `use_fused_linear_logprobs: false`. For CP2 or CP4, use the split | ||
| begin/microbatch/finish training path. Run `examples/run_grpo.py` with | ||
| `data_plane.enabled=true` to select the synchronous TransferQueue trainer, | ||
| which uses that path. | ||
|
|
||
| ## Configure DFlash | ||
|
|
||
| The repository includes a one-node Qwen3-8B recipe at | ||
| `examples/configs/recipes/llm/grpo-qwen3-8b-1n8g-megatron-dflash.yaml`. | ||
| The core DFlash configuration is: | ||
|
|
||
| ```yaml | ||
| policy: | ||
| model_name: Qwen/Qwen3-8B | ||
| megatron_cfg: | ||
| enabled: true | ||
| tensor_model_parallel_size: 2 | ||
| pipeline_model_parallel_size: 1 | ||
| context_parallel_size: 1 | ||
| sequence_parallel: false | ||
| use_fused_linear_logprobs: false | ||
| dtensor_cfg: | ||
| enabled: false | ||
| sequence_packing: | ||
| enabled: false | ||
| draft: | ||
| speculator_type: dflash | ||
| enabled: true | ||
| model_name: z-lab/Qwen3-8B-DFlash-b16 | ||
| loss_weight: 1.0 | ||
| gamma: 5 | ||
| anchors_per_sample: 2 | ||
| mask_token_id: 151669 | ||
| target_hidden_state_layer_ids: [1, 9, 17, 25, 33] | ||
| num_layers: 5 | ||
| seed: 13 | ||
| vocab_tile_size: 256 | ||
| position_decay: 1.0 | ||
| max_cp_boundary_exclusion_fraction: 0.25 | ||
| generation: | ||
| backend: vllm | ||
| vllm_kwargs: | ||
| speculative_config: | ||
| method: dflash | ||
| model: ${policy.draft.model_name} | ||
| num_speculative_tokens: ${policy.draft.gamma} | ||
| draft_tensor_parallel_size: 1 | ||
| ``` | ||
|
|
||
| `gamma` is the number of masked speculative positions after the anchor, so a | ||
| training block contains `gamma + 1` positions. `anchors_per_sample` controls how | ||
| many training blocks are sampled from each logical sequence. Blocks never cross | ||
| packed sample boundaries. | ||
|
|
||
| ## Configure DSpark | ||
|
|
||
| DSpark uses the same block-parallel body and adds a Markov head plus an optional | ||
| confidence head. Use `block_size`, not the DFlash-only `gamma` field: | ||
|
|
||
| ```yaml | ||
| policy: | ||
| model_name: Qwen/Qwen3-8B | ||
| megatron_cfg: | ||
| enabled: true | ||
| tensor_model_parallel_size: 2 | ||
| pipeline_model_parallel_size: 1 | ||
| context_parallel_size: 1 | ||
| sequence_parallel: false | ||
| use_fused_linear_logprobs: false | ||
| dtensor_cfg: | ||
| enabled: false | ||
| sequence_packing: | ||
| enabled: false | ||
| draft: | ||
| speculator_type: dspark | ||
| enabled: true | ||
| model_name: deepseek-ai/dspark_qwen3_8b_block7 | ||
| model_revision: 03326e5043815da1f81b109078b2889737c26017 | ||
| loss_weight: 1.0 | ||
| block_size: 7 | ||
| anchors_per_sample: 2 | ||
| mask_token_id: 151669 | ||
| target_hidden_state_layer_ids: [1, 9, 17, 25, 33] | ||
| num_layers: 5 | ||
| markov_rank: 256 | ||
| markov_head_type: vanilla | ||
| confidence_enabled: true | ||
| confidence_with_markov: true | ||
| ce_loss_weight: 0.1 | ||
| tv_loss_weight: 0.9 | ||
| confidence_loss_weight: 1.0 | ||
| loss_decay_gamma: 4.0 | ||
| generation: | ||
| backend: vllm | ||
| vllm_kwargs: | ||
| speculative_config: | ||
| method: dspark | ||
| model: ${policy.draft.model_name} | ||
| revision: ${policy.draft.model_revision} | ||
| num_speculative_tokens: ${policy.draft.block_size} | ||
| draft_tensor_parallel_size: 1 | ||
| ``` | ||
|
|
||
| DSpark online training uses the live target vocabulary and target-owned | ||
| embedding/output weights. Omit `draft_vocab_size`, or set it to exactly the | ||
| target vocabulary size. A different draft vocabulary is rejected because the | ||
| online remapping path is not supported. | ||
|
|
||
| ## Enable Packed Context Parallel Training | ||
|
|
||
| The following command runs the DFlash recipe with TP2 and CP4 on eight training | ||
| GPUs. It enables sequence packing and target sequence parallelism. Colocated | ||
| vLLM generation uses CP1 and PP1. | ||
|
|
||
| ```bash | ||
| uv run examples/run_grpo.py \ | ||
| --config examples/configs/recipes/llm/grpo-qwen3-8b-1n8g-megatron-dflash.yaml \ | ||
| data_plane.enabled=true \ | ||
| policy.megatron_cfg.tensor_model_parallel_size=2 \ | ||
| policy.megatron_cfg.pipeline_model_parallel_size=1 \ | ||
| policy.megatron_cfg.context_parallel_size=4 \ | ||
| policy.megatron_cfg.sequence_parallel=true \ | ||
| policy.sequence_packing.enabled=true \ | ||
| policy.make_sequence_length_divisible_by=16 | ||
| ``` | ||
|
|
||
| For TP2 x CP2, set `context_parallel_size=2` and | ||
| `make_sequence_length_divisible_by=8`. Set the latter to a multiple of | ||
| `2 * TP * CP`. Keep packing enabled for CP2 or CP4. Target sequence | ||
| parallelism is optional with packing, but requires packing when enabled. | ||
|
|
||
| Packed sequences carry sample IDs and sequence boundaries. NeMo RL uses them | ||
| to reconstruct target sequence-parallel captures, gather projected key/value | ||
| tensors across CP, and assign each draft window to one CP rank. Do not add | ||
| layout fields to the input data. | ||
|
|
||
| ## Loss, Diagnostics, and Optimizer Settings | ||
|
|
||
| The total objective is the policy loss plus `policy.draft.loss_weight` times the | ||
| provider-specific draft loss. NeMo RL logs the normalized value as | ||
| `train/draft_loss`. | ||
|
|
||
| Set `policy.draft.update_probe_enabled=true` for a short diagnostic run. After | ||
| the optimizer step, NeMo RL checks that the draft model had nonzero gradients | ||
| and that at least one draft parameter changed. Disable the probe for ordinary | ||
| training. | ||
|
|
||
| To use a separate learning-rate schedule for draft parameters, set: | ||
|
|
||
| ```yaml | ||
| policy: | ||
| draft: | ||
| optimizer: | ||
| lr: 1.0e-5 | ||
| min_lr: 1.0e-6 | ||
| weight_decay: 0.01 | ||
| ``` | ||
|
|
||
| If `optimizer` is `null`, draft parameters use the policy optimizer settings. | ||
|
|
||
| ## Checkpoint and Refit Behavior | ||
|
|
||
| - `policy.draft.model_name` initializes the trainer-owned draft model. | ||
| - Training checkpoints include the draft model and its optimizer state when | ||
| draft training is enabled. | ||
| - `policy.generation.vllm_kwargs.speculative_config.model` initializes the vLLM | ||
| drafter before the first refit. | ||
| - Each successful refit updates both target and draft weights. The generation | ||
| `method` must match `policy.draft.speculator_type`. | ||
| - DFlash and DSpark generation requires PP1. Keep generation CP at 1 even when | ||
| policy training uses CP2 or CP4. | ||
|
|
||
| ## Common Configuration Errors | ||
|
|
||
| - `context_parallel_size > 1` with packing disabled | ||
| - `context_parallel_size > 1` without `data_plane.enabled=true`, or with | ||
| `grpo.async_grpo.enabled=true` | ||
| - async GRPO with `data_plane.enabled=false` | ||
| - target sequence parallelism with packing disabled | ||
| - target TP other than 2, or training PP/virtual PP greater than 1 | ||
| - generation CP or PP greater than 1 | ||
| - `use_fused_linear_logprobs=true` | ||
| - a generation method that does not match the training speculator | ||
| - `gamma` in a DSpark block or `block_size` in a DFlash block | ||
| - a DSpark `draft_vocab_size` different from the live target vocabulary | ||
|
|
||
| NeMo RL rejects these combinations during configuration or worker setup. | ||
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
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
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.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
FYI (wording).
require_draft_update(diagnostics.py:120-142) accepts zero gradient with unchanged parameters as a consistent no-op, so the probe does not prove "nonzero gradients". Suggest: "checks that gradients and parameter deltas are consistent: either both are zero (no eligible windows) or both are nonzero". The nightlymin(train/draft_loss) > 0check (dflash.sh:43-44) is what actually guards against a never-trained draft.