Add max_anchors and max_context_window support to P-EAGLE - #590
Add max_anchors and max_context_window support to P-EAGLE#590orestis-z wants to merge 5 commits into
Conversation
|
Important Review skippedAuto incremental reviews are disabled on this repository. Please check the settings in the CodeRabbit UI or the ⚙️ Run configurationConfiguration used: Path: .coderabbit.yaml Review profile: CHILL Plan: Pro Run ID: You can disable this status message by setting the Use the checkbox below for a quick retry:
📝 WalkthroughWalkthroughTwo new training-time limits— ChangesP-EAGLE anchor/context window limits
🚥 Pre-merge checks | ✅ 4 | ❌ 1❌ Failed checks (1 warning)
✅ Passed checks (4 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. ✨ Finishing Touches🧪 Generate unit tests (beta)
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
|
The quality checks have failed. Please run |
41574e4 to
90483a4
Compare
|
This pull request has merge conflicts that must be resolved before it can be |
8981f20 to
fa168ed
Compare
There was a problem hiding this comment.
Actionable comments posted: 3
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Inline comments:
In `@src/speculators/models/dflash/core.py`:
- Line 159: The line using `kwargs.get("max_anchors") or 3072` silently converts
any falsy value (including 0) to 3072, which masks explicit user input and can
cause unexpected behavior. Replace this logic with an explicit None check
instead of relying on truthiness, so that only when max_anchors is not provided
(None) should it default to 3072, allowing valid falsy values like 0 to be
respected.
In `@src/speculators/models/peagle/data.py`:
- Around line 50-70: The max_context_window constraint is only being applied in
the if block when all_valid_indices.shape[0] exceeds max_anchors. In the else
block (lines 68-69), the code falls back to using the full seq_length without
applying any windowing, which bypasses the max_context_window guard. Modify the
else block to also apply the max_context_window constraint by capping the
window_end to window_start plus max_context_window, ensuring that sample_indices
respects the max_context_window limit regardless of whether max_anchors was
exceeded.
In `@tests/integration/models/test_model_forward.py`:
- Around line 341-349: The test_varying_max_anchors method does not cover the
max_context_window branch because with MAX_LEN=128 and the default
max_context_window=4096, the condition window_end - window_start >
max_context_window is never triggered. Add an additional test case (either by
extending this test or creating a new parametrized case) where you pass a small
max_context_window value to make_peagle_model or use a sparse loss_mask in the
batch so that the window size exceeds the max_context_window limit and the COD
sampling branch is executed and validated.
🪄 Autofix (Beta)
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: Path: .coderabbit.yaml
Review profile: CHILL
Plan: Pro
Run ID: 5bbfeff8-7feb-4bd0-b556-eb4091de0003
📒 Files selected for processing (7)
scripts/train.pysrc/speculators/models/dflash/core.pysrc/speculators/models/peagle/config.pysrc/speculators/models/peagle/core.pysrc/speculators/models/peagle/data.pytests/integration/conftest.pytests/integration/models/test_model_forward.py
|
|
||
| sample_indices = [torch.arange(seq_length, device=device)] | ||
| n_per_depth = [seq_length] | ||
| if max_anchors is not None and all_valid_indices.shape[0] > 0: |
There was a problem hiding this comment.
I'm a little bit worried that this bit causing more graph breaks but otherwise this diff looks great!
Cap the number of COD chain starting points and contiguous window size during P-EAGLE training to bound memory usage on long sequences. Also fix DFlash max_anchors default to 256 (was 3072). Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> Signed-off-by: Orestis Zambounis <orestis.zambounis@gmail.com>
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> Signed-off-by: Orestis Zambounis <orestis.zambounis@gmail.com>
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> Signed-off-by: Orestis Zambounis <orestis.zambounis@gmail.com>
- Use explicit None check for DFlash max_anchors default instead of falsy-value coercion - Apply max_context_window guard even when valid anchors <= max_anchors - Add test exercising max_context_window branch with small window size Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> Signed-off-by: Orestis Zambounis <orestis.zambounis@gmail.com>
Directly tests generate_cod_sample_indices to verify max_context_window is applied even when valid anchors don't exceed max_anchors. Reproduces the bug where sparse loss masks with few valid positions bypassed the memory guard. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> Signed-off-by: Orestis Zambounis <orestis.zambounis@gmail.com>
c318752 to
2a19d62
Compare
|
This pull request has merge conflicts that must be resolved before it can be |
|
ON HOLD, see #567 (comment) |
Closes #567. ## Summary - Add `max_anchors` config to P-EAGLE's COD sampling that randomly subsamples chain starting points at depth 1+, capping attention mask size for longer sequences while keeping depth 0 as the full sequence - Change `--max-anchors` CLI default from 256 to None so P-EAGLE uses all positions by default (DFlash retains its 3072 hardcoded fallback) - Add unit tests verifying depth-0 preservation, chain capping, sorted order, and backward compatibility ## Motivation P-EAGLE's COD sampling starts a chain from every `loss_mask=1` position, producing attention masks that OOM at 8K+ sequences. The ablation study (#567 (comment)) showed that randomly subsampling with `max_anchors=1024` actually **improves** d0 accuracy by +3.1pp while dramatically reducing memory, enabling training at longer sequence lengths. Supersedes #590 (contiguous window approach, which degraded quality) and #683. ## Test plan - [x] 6 new unit tests in `tests/unit/models/test_peagle_data.py` — all pass - [x] 38 existing P-EAGLE integration tests — all pass - [x] `ruff check` clean on all changed files - [ ] CI green 🤖 Generated with [Claude Code](https://claude.com/claude-code) --------- Signed-off-by: Orestis Zambounis <orestis.zambounis@gmail.com> Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
…ct#687) Closes vllm-project#567. ## Summary - Add `max_anchors` config to P-EAGLE's COD sampling that randomly subsamples chain starting points at depth 1+, capping attention mask size for longer sequences while keeping depth 0 as the full sequence - Change `--max-anchors` CLI default from 256 to None so P-EAGLE uses all positions by default (DFlash retains its 3072 hardcoded fallback) - Add unit tests verifying depth-0 preservation, chain capping, sorted order, and backward compatibility ## Motivation P-EAGLE's COD sampling starts a chain from every `loss_mask=1` position, producing attention masks that OOM at 8K+ sequences. The ablation study (vllm-project#567 (comment)) showed that randomly subsampling with `max_anchors=1024` actually **improves** d0 accuracy by +3.1pp while dramatically reducing memory, enabling training at longer sequence lengths. Supersedes vllm-project#590 (contiguous window approach, which degraded quality) and vllm-project#683. ## Test plan - [x] 6 new unit tests in `tests/unit/models/test_peagle_data.py` — all pass - [x] 38 existing P-EAGLE integration tests — all pass - [x] `ruff check` clean on all changed files - [ ] CI green 🤖 Generated with [Claude Code](https://claude.com/claude-code) --------- Signed-off-by: Orestis Zambounis <orestis.zambounis@gmail.com> Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
…ct#687) Closes vllm-project#567. ## Summary - Add `max_anchors` config to P-EAGLE's COD sampling that randomly subsamples chain starting points at depth 1+, capping attention mask size for longer sequences while keeping depth 0 as the full sequence - Change `--max-anchors` CLI default from 256 to None so P-EAGLE uses all positions by default (DFlash retains its 3072 hardcoded fallback) - Add unit tests verifying depth-0 preservation, chain capping, sorted order, and backward compatibility ## Motivation P-EAGLE's COD sampling starts a chain from every `loss_mask=1` position, producing attention masks that OOM at 8K+ sequences. The ablation study (vllm-project#567 (comment)) showed that randomly subsampling with `max_anchors=1024` actually **improves** d0 accuracy by +3.1pp while dramatically reducing memory, enabling training at longer sequence lengths. Supersedes vllm-project#590 (contiguous window approach, which degraded quality) and vllm-project#683. ## Test plan - [x] 6 new unit tests in `tests/unit/models/test_peagle_data.py` — all pass - [x] 38 existing P-EAGLE integration tests — all pass - [x] `ruff check` clean on all changed files - [ ] CI green 🤖 Generated with [Claude Code](https://claude.com/claude-code) --------- Signed-off-by: Orestis Zambounis <orestis.zambounis@gmail.com> Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com> Signed-off-by: Eros483 <arnabmandal2912@gmail.com>
Closes #567
Purpose
Add
max_anchorsandmax_context_windowsupport to P-EAGLE to cap memory usage during training on long sequences.P-EAGLE's COD sampling predicts next tokens for every starting position, producing attention masks of size
(seq_len × 2.73)². Whenmax_anchorsis set,generate_cod_sample_indicesselects a random contiguous window containing at mostmax_anchorsvalid (loss_mask=1) positions, shrinking the effective attention footprint while preserving context for the selected anchors.max_context_window(default 4096) hard-caps the window size to prevent sparse loss masks from reinflating it.Changes:
max_anchorsandmax_context_windowfields toPEagleSpeculatorConfigPEagleDraftModelandgenerate_cod_sample_indices--max-context-windowCLI arg; make--max-anchorsdefault toNone(was 256), defaulting per-model (256 for DFlash, unlimited for P-EAGLE)max_anchorsdefault from 3072 to 256max_anchorsfalsy-value handling: use explicitis Nonecheck instead oforcoercionmax_context_windowclamp fires even whenlen(valid_indices) < max_anchors. Previously, sparse sequences would fall back to the full sequence length, inadvertently causing the exact OOMs the window was designed to prevent.Tests
test_varying_max_anchorsparametrized over[4, 16, None]test_max_context_windowwith small window size (32) to exercise the cap branchtest_peagle_data.py) directly testinggenerate_cod_sample_indicesfor the sparse bypass bug, normal cap path, and no-windowing caseChecklist
I have filled in: