Skip to content

[Bugfix][CPU] Validate attention head size at CPU backend selection - #63508

Open
patrk wants to merge 2 commits into
vllm-project:mainfrom
patrk:fix/cpu-head-size-validation
Open

patrk wants to merge 2 commits into
vllm-project:mainfrom
patrk:fix/cpu-head-size-validation

Conversation

@patrk

@patrk patrk commented Oct 24, 2026 •

Copy link
Copy Markdown
Contributor

Overview

Fixes #63507. The CPU platform now rejects attention head sizes its kernel can't run, at backend selection instead of on the first request.

Claims

  • A model with an unsupported head size (e.g. 26, 40, 56, 72) fails at startup with ValueError: Head size N is not supported by the CPU attention backend. Supported head sizes: [...]. Before this, the engine reported ready and died on the first request.
  • 48 is added to CPUAttentionBackend.get_supported_head_sizes(). The kernel already supports it (HEAD_DIMS_16), and without it the new check would reject a working model.
  • Encoder attention that runs through zentorch SDPA is exempt, since it doesn't use the CPU kernel.
  • Supported head sizes, MLA and the KV cache dtype check are unchanged.

Validation

macOS arm64 (Apple M4 Pro), CPU source build, on main @ e7473bf.

Check main this PR
pytest tests/kernels/attention/test_cpu_attn.py -k "head_size or kv_cache_dtype_validation or rejects_quantized" 3 failed, 17 passed, 2 skipped 20 passed, 2 skipped (zentorch)
test_cpu_attn.py, tests/platforms/test_cpu.py, test_attention_selector.py, tests/config/test_kv_cache_dtype.py 939 passed, 0 failed (x86-only and zentorch cases skipped)
pytest -m cpu_model tests/models/language/generation/test_cpu_attn_head_size.py (new, vllm_runner) 1 failed: RuntimeError: Unsupported CPU attention configuration: head_dim=56 at the first request 1 passed
test_cpu_attn.py -k "vec16 and -48-" (kernel test for the newly listed 48) 90 passed
pre-commit run --files <changed files> passed
Dummy weights: Qwen2 with head size 56 / 72, BERT (pooling) with 26 engine ready, then EngineDeadError on first request ValueError at startup, before weights load
Same, head size 48 / 80 generates generates

I could not test the zentorch exemption: it needs a Zen CPU with zentorch. Its test uses the file's existing _skip_no_zentorch_sdpa marker, so it only runs on such hosts. If you'd rather fail closed there, I can drop it.

New tests on main
$ pytest tests/kernels/attention/test_cpu_attn.py -k head_size
FAILED test_cpu_attn.py::test_cpu_attn_rejects_unsupported_head_size[26] - Failed: DID NOT RAISE <class 'ValueError'>
FAILED test_cpu_attn.py::test_cpu_attn_rejects_unsupported_head_size[40] - Failed: DID NOT RAISE <class 'ValueError'>
FAILED test_cpu_attn.py::test_cpu_attn_rejects_unsupported_head_size[72] - Failed: DID NOT RAISE <class 'ValueError'>

Details

  • Root cause: CpuPlatform.get_attn_backend_cls never checked supports_head_size, so get_supported_head_sizes() was never enforced on CPU. The kernel dispatch falls through to TORCH_CHECK(false, "Unsupported CPU attention configuration ...") at the first forward.
  • As in [Bugfix][CPU] Reject unsupported --kv-cache-dtype at CPU attention backend selection #62665, I call supports_head_size instead of the full validate_configuration, which also checks block size and would change behaviour for configs that work today.
  • test_attention_selector.py: the CPU cases used head size 16, which is in neither HEAD_DIMS_32 nor HEAD_DIMS_16, so those tests selected a backend that can't run. I changed them to 64. The ROCm case in test_fp32_fallback already notes that 16 is unsupported there.
  • Added 48 to HEAD_SIZES_VEC16 so the kernel test covers it.
  • CI: test_cpu_attn.py runs in the CPU kernel tests job, which this PR triggers because it changes that file. The vllm_runner test runs in the CPU language model tests job (-m cpu_model over tests/models/language/generation). It uses dummy weights because the error is raised before weights load. I checked the models in the CPU CI jobs (language, pooling, multimodal, quantization, distributed, spec decode, Arm). All use head sizes 32–256; vision and audio towers go through MMEncoderAttention, not this selector.
  • Not in this PR: fp8 KV cache with head sizes 48/80/112 is still only rejected later, in _get_attn_isa. That is a separate check.

This PR was written with AI assistance (Claude Code). I reviewed every changed line and ran the checks above myself.


Pull Request Checklist
  • I used vLLM's /pr-checklist skill. (Mandatory for agents, optional for humans).

  • AI assistance was used during the creation of this PR.

  • Design Fit: Minimizes impact on core components, reuses existing functionality, and justifies added complexity.

  • Testing and Validation: Validates the change and ensures any added tests are meaningful and reliable, with CI coverage or documented CI resource constraints and validation performed outside CI.

  • Code Quality and Style: Keeps code and comments clear and concise, and updates relevant documentation and examples.

  • Pull Request Contents: Includes a brief summary and relevant links, supports claims with evidence, explains root causes and implementation trade-offs, and follows the contributing guide.

Co-authored-by: Claude <noreply@anthropic.com>
Signed-off-by: Patryk Mikulski <7378686+patrk@users.noreply.github.com>

@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.

@mergify mergify Bot added cpu Related to CPU backends bug Something isn't working labels Oct 24, 2026

This branch has not been deployed

No deployments
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

bug Something isn't working cpu Related to CPU backends

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[Bug]: CPU backend accepts unsupported attention head sizes; engine dies on first request

1 participant