[Feature] Mask Replay - #49577
Conversation
|
This pull request has merge conflicts that must be resolved before it can be |
|
@codex review |
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 5c9f82aeb9
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
| topk_values, topk_indices = torch.topk(processed_logits, max_top_k, dim=-1) | ||
| sparse_values = topk_values[sparse_row_indices] | ||
| sparse_token_ids = topk_indices[sparse_row_indices].to(torch.int32) |
There was a problem hiding this comment.
Preserve all tied tokens in sparse top-k masks
When multiple logits tie at the top-k boundary, apply_top_k_top_p_pytorch retains every tied token because it masks only values strictly below the kth value, so the actual sampling support can contain more than top_k tokens. Truncating the sparse representation with torch.topk(..., max_top_k) silently omits some supported tokens; if an omitted token is sampled, _build_sampling_mask_lists raises an error, and otherwise replay receives an incomplete support set and computes incorrect normalization. Build the sparse row from every finite processed logit, or otherwise preserve all boundary ties.
Useful? React with 👍 / 👎.
Signed-off-by: vx120 <893600387@qq.com>
Signed-off-by: vx120 <893600387@qq.com>
Co-authored-by: Codex <noreply@openai.com> Signed-off-by: aoshen02 <aoshen@inferact.ai>
…-comments Address sampling mask review feedback
|
/ci run |
|
✅ Triggered Buildkite CI #83627 for commit |
Co-authored-by: OpenAI Codex <noreply@openai.com> Signed-off-by: aoshen02 <aoshen@inferact.ai>
…test Fix sampling mask support assertions
|
/ci run |
|
✅ Triggered Buildkite CI #83630 for commit |
Co-authored-by: OpenAI Codex <noreply@openai.com> Signed-off-by: aoshen02 <aoshen@inferact.ai>
Fix sampling mask Rust wire compatibility
|
/ci run |
|
✅ Triggered Buildkite CI #83650 for commit |
Co-authored-by: OpenAI Codex <codex@openai.com> Signed-off-by: aoshen02 <aoshen@inferact.ai>
Fix Rust sampling mask test formatting
|
/ci run |
|
✅ Triggered Buildkite CI #83656 for commit |
|
/ci retry |
|
✅ Queued 4 failed job(s) for retry in Buildkite CI #83656. |
Signed-off-by: vx120 <893600387@qq.com> Signed-off-by: vx120 <57470515+vx120@users.noreply.github.com> Signed-off-by: aoshen02 <aoshen@inferact.ai> Co-authored-by: aoshen02 <aoshen@inferact.ai> Co-authored-by: Codex <noreply@openai.com> Co-authored-by: Claude Opus 4.6 (1M context) <noreply@anthropic.com> Co-authored-by: OpenAI Codex <codex@openai.com>
Summary
This PR adds experimental support for sampling distribution replay.
A sampling mask represents the vocabulary support retained after top-k/top-p filtering. It is not an attention mask and does not affect causal attention or KV-cache behavior.
When enabled, vLLM returns the sampling support for each generated token in a CSR-style representation:
The feature is opt-in and does not change default generation behavior.
Motivation
With top-p sampling, rollout probabilities are normalized over a truncated vocabulary, while training commonly recomputes probabilities over the full vocabulary. This creates a systematic mismatch in importance ratios and KL estimates.
Sampling replay returns the rollout-time support so training can recompute log-probabilities over the same distribution.
Experiment
We compare GRPO training with sampling replay enabled and disabled under top-p sampling.
For each generated token:
logp_diff = training_logprob - rollout_logprobimportance_ratio = exp(logp_diff)Ideally, the rollout and training distributions match, so
logp_diffis close to0andimportance_ratiois close to1.Mean Importance Ratio
With replay enabled, the mean importance ratio remains tightly centered around
1. Without replay, it is consistently below1and shows larger fluctuations.This indicates that replay restores the rollout-time top-p normalization during training, while the non-replay baseline compares the truncated rollout distribution with a full-vocabulary training distribution.
Mean Log-Probability Difference
With replay enabled, the mean log-probability difference remains close to
0. Without replay, it has a persistent negative bias.This is expected: a token probability normalized over the full vocabulary is generally lower than the probability normalized over the retained top-p support.
Standard Deviation of the Log-Probability Difference
Replay lowers the standard deviation of the log-probability difference. This means it improves not only the average alignment, but also token-level consistency between rollout and training probabilities.
Lower variance produces more stable importance weights and reduces the impact of probability-ratio outliers.
Approximate KL
Replay produces a lower and more stable approximate KL estimate, with fewer large spikes. This indicates that the training-time distribution stays closer to the rollout-time distribution throughout optimization.
Conclusion
Across all four metrics, sampling replay improves rollout/training distribution consistency:
importance_ratio_meanstays close to1;logp_diff_meanstays close to0;logp_diff_stdis lower;approx_klis lower and more stable.These results demonstrate the intended algorithmic effect of sampling replay: improved probability alignment and lower-variance importance weights.
This experiment does not, by itself, establish an improvement in downstream reward or task accuracy.
Limitations
The current implementation requires:
logprobs_mode="processed_logprobs";SamplingParams.logprobs=1;temperature > 0.Speculative decoding, custom samplers, and custom logits processors are not currently supported.