Skip to content

fix(inference): DeepSeek V4 C128 compressor and attn_sink loading patches - #4040

Merged
garrett361 merged 3 commits into
mainfrom
fix/dsv4-vllm-serving-patches
Oct 12, 2026
Merged

garrett361 merged 3 commits into
mainfrom
fix/dsv4-vllm-serving-patches

Conversation

@garrett361

@garrett361 garrett361 commented Oct 12, 2026 •

Copy link
Copy Markdown
Contributor

DeepSeek V4 serving on vLLM 0.31.0 corrupts long-context KV under piecewise CUDA graphs and drops the attention sinks on every layerwise weight reload. Two vLLM patches fix both.

  • C128: vLLM 0.30+ skips the compressed-KV write on mixed batches under piecewise graphs, so it now always runs. Step-1 mismatch KL on the 131k SWE run drops from 0.0070 to 0.0005.
  • attn_sink: upstream's bare slice copy landed in a meta tensor on reload, so updates kept boot-time sinks. Sinks now load through param.weight_loader.
  • Both register last in apply_shared_vllm_patches, so a failing DeepSeek V4 import cannot skip the other patches.

🤖 Generated with Claude Code

garrett361 and others added 2 commits October 12, 2026 18:14
…CUDA graphs

vLLM 0.30+ (vllm-project/vllm#55353) derives the compressor's c128_boundary flag from
seq_lens_cpu_upper_bound, which Model Runner V2 sets. Piecewise CUDA graph capture then records
the early return on dummy batches, so mixed batches never write C128 compressed KV and decode
drifts from prefill as context grows (upstream fix pending in vllm-project/vllm#59709). Returning
None from _get_c128_boundary restores 0.29 behaviour. On the 131k SWE run with bf16 serving this
takes step-1 mismatch KL from 0.0070 back to 0.0005, the pre-rebase level.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
…ight loaders

DeepseekV4Model.load_weights writes the attention sinks with a bare
params_dict[name][:n].copy_(narrow_weight) instead of going through
param.weight_loader. Layerwise reload moves a layer's tensors to meta and
wraps each loader to buffer the incoming tensor, so that copy lands in a
meta tensor and is discarded silently: load_numel stays 0, finalize
restores the boot value with only a warning, and the loader still does
loaded_params.add(name), so a named_parameters() - loaded_params diff
cannot see the loss either. Attention sinks are trainable, so every weight
update keeps serving the sinks the server booted with.

Padding this rank's heads back up with -inf, the parameter's own init
value, makes it an ordinary full-parameter load through the existing
loader contract. Still required on vLLM 0.31.0 (model.py:1755).

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
@garrett361
garrett361 merged commit 7c9d474 into main Oct 12, 2026
10 of 17 checks passed
@garrett361
garrett361 deleted the fix/dsv4-vllm-serving-patches branch October 12, 2026 19:02
mikasenghaas added a commit that referenced this pull request Oct 12, 2026
Squash of #3627 at d35a408, with its stacked
#3647, #3955 and #3956. Its DeepSeek V4 C128 and attn_sink patches
predate #4040 on main, so main's versions are kept and the duplicates
dropped.

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

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants