Skip to content

[Bugfix] Fix DeepSeek V4 mHC broadcast buffer for weight sync - #52626

Merged
jeejeelee merged 1 commit into
vllm-project:mainfrom
HollowMan6:mhc_refit
Aug 18, 2026
Merged

jeejeelee merged 1 commit into
vllm-project:mainfrom
HollowMan6:mhc_refit

Conversation

@HollowMan6

@HollowMan6 HollowMan6 commented Aug 17, 2026

Copy link
Copy Markdown
Contributor

Purpose

Fix Stale broadcast weights after refit. finalize_mhc_broadcast_weights() rebound layer.hc_attn_fn_broadcast to a freshly-allocated tensor on every call. CUDA graphs captured against the original tensor's address keep replaying with the old pointer, so a weight refit (repeat load_weights() after capture, e.g. RL weight sync) left captured graphs reading stale broadcast weights. Fixed by allocating only when the buffer is None and otherwise copy_()-ing in place, keeping the address stable.

Test Plan

Two unit tests added to tests/kernels/test_mhc_kernels.py:

  1. test_deepseek_v4_mhc_broadcast_finalize_sums_hc_streams — first finalize allocates the buffer with the stream-summed values.
  2. test_deepseek_v4_mhc_broadcast_refit_refreshes_in_place — after mutating hc_attn_fn and re-finalizing, the buffer is the same tensor object with updated values (the refit contract).
    pytest tests/kernels/test_mhc_kernels.py -k mhc_broadcast -v
    pytest tests/kernels/test_mhc_kernels.py -k "hc_head_tilelang or mhc_broadcast"

End to end tests on verl side with DSV4 training

Test Result

  • -k mhc_broadcast: 2 passed.
  • Combined with the tilelang hc_head kernel tests (which flip
    torch.set_default_device to CUDA earlier in the file): 10 passed.
  • Full file collects all 53 tests cleanly.
  • Mutation check: with the model.py fix reverted to HEAD, the refit test
    fails on the buffer-identity assertion and the sums test still passes — the
    pair pins both the pre-existing semantics and the new in-place contract.
  • End to end tests on verl side with DSV4 training returned to normal training inference mismatch.

Essential Elements of an Effective PR Description Checklist
  • The purpose of the PR, such as "Fix some issue (link existing issues this PR will resolve)".
  • The test plan, such as providing test command.
  • The test results, such as pasting the results comparison before and after, or e2e results
  • (Optional) The necessary documentation update, such as updating supported_models.md and examples for a new model.

Copilot AI lite review requested due to automatic review settings August 17, 2026 13:50

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copilot was unable to review this pull request because the user who requested the review has reached their quota limit.

@mergify mergify Bot added deepseek Related to DeepSeek models bug Something isn't working labels Aug 17, 2026

@claude claude Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Claude Code Review

This pull request is from a fork — automated review is disabled. A repository maintainer can comment @claude review to run a one-time review.

@aoshen02 aoshen02 added the ready ONLY add when PR is ready to merge/full CI is needed label Aug 17, 2026
@aoshen02

Copy link
Copy Markdown
Collaborator

/ci run

@mergify

mergify Bot commented Aug 17, 2026

Copy link
Copy Markdown
Contributor

Hi @HollowMan6, the pre-commit checks have failed. Please run:

uv pip install pre-commit>=4.5.1
pre-commit install
pre-commit run --all-files

Then, commit the changes and push to your branch.

For future commits, pre-commit will run automatically on changed files before each commit.

@github-actions

Copy link
Copy Markdown

✅ No earlier CI build exists for this PR. Use /ci run first.

Fix Stale broadcast weights after refit. finalize_mhc_broadcast_weights()
rebound layer.hc_attn_fn_broadcast to a freshly-allocated tensor on every
call. CUDA graphs captured against the original tensor's address keep
replaying with the old pointer, so a weight refit (repeat load_weights()
after capture, e.g. RL weight sync) left captured graphs reading stale
broadcast weights. Fixed by allocating only when the buffer is None and
otherwise copy_()-ing in place, keeping the address stable.

Signed-off-by: Hollow Man <hollowman@opensuse.org>
@HollowMan6

Copy link
Copy Markdown
Contributor Author

/ci run

@github-actions

Copy link
Copy Markdown

✅ Triggered Buildkite CI #84213 for commit e1060155aca7.

@jeejeelee
jeejeelee merged commit d5f5de7 into vllm-project:main Aug 18, 2026
61 checks passed
@HollowMan6
HollowMan6 deleted the mhc_refit branch August 18, 2026 12:18
zufangzhu pushed a commit to zufangzhu/vllm that referenced this pull request Aug 24, 2026
…roject#52626)

Signed-off-by: Hollow Man <hollowman@opensuse.org>
Signed-off-by: Zhu, Zufang <zufang.zhu@intel.com>
garrett361 added a commit to PrimeIntellect-ai/prime-rl that referenced this pull request Sep 17, 2026
Points the wheel-URL source at the v0.29.0 release, raises the gpu extra
floor to match, and drops the vllm exclude-newer exception as its comment
intended. 0.29.0 carries vllm-project/vllm#52626, which makes
finalize_mhc_broadcast_weights update hc_attn_fn_broadcast in place on a
weight reload instead of rebinding it, so captured CUDA graphs stop
reading a freed pointer. That was worth 0.159 to 0.0225 on DeepSeek V4's
production mismatch KL.

Lock churn: flashinfer-python 0.6.16.post3 -> 0.6.18, new vLLM dependency
instanttensor 0.1.9. vLLM 0.29.0 still pins quack-kernels 0.6.4 and
nvidia-cutlass-dsl 4.6.2, so the overrides stand.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
garrett361 added a commit to PrimeIntellect-ai/prime-rl that referenced this pull request Sep 21, 2026
Points the wheel-URL source at the v0.29.0 release, raises the gpu extra
floor to match, and drops the vllm exclude-newer exception as its comment
intended. 0.29.0 carries vllm-project/vllm#52626, which makes
finalize_mhc_broadcast_weights update hc_attn_fn_broadcast in place on a
weight reload instead of rebinding it, so captured CUDA graphs stop
reading a freed pointer. That was worth 0.159 to 0.0225 on DeepSeek V4's
production mismatch KL.

Lock churn: flashinfer-python 0.6.16.post3 -> 0.6.18, new vLLM dependency
instanttensor 0.1.9. vLLM 0.29.0 still pins quack-kernels 0.6.4 and
nvidia-cutlass-dsl 4.6.2, so the overrides stand.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

bug Something isn't working deepseek Related to DeepSeek models ready ONLY add when PR is ready to merge/full CI is needed

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants