Title: OutOfResources: shared memory (98304 > 65536) on Turing (SM75) — global attention layers with head_dim=512

Title: OutOfResources: shared memory (98304 > 65536) on Turing (SM75) — global attention layers with head_dim=512

Summary

I am unable to serve this checkpoint on NVIDIA Turing (compute capability 7.5) GPUs. vLLM fails during Triton JIT compilation of the unified attention kernel, requesting more shared memory per SM than Turing physically provides.

Environment

  • GPUs: 2× NVIDIA Quadro RTX 6000 (Turing, SM75, 24 GB each, 64 KB shared memory per SM)
  • vLLM: 0.26.0 (official Docker image)
  • Parallelism: tensor-parallel-size 2, NCCL_P2P_DISABLE=1 (no NVLink, VMware passthrough)
  • Model: google/gemma-4-31B-it-qat-w4a16-ct
  • Deployment: offline / air-gapped

Error

triton.runtime.errors.OutOfResources: out of resource: shared memory,
Required: 98304, Hardware limit: 65536.
Reducing block sizes or `num_stages` may help.

Analysis

At startup, vLLM logs the Gemma 4 attention configuration:

head_dim=256, global_head_dim=512

Gemma 4 interleaves local sliding-window attention layers (head_dim=256) with full global attention layers (global_head_dim=512).

In vllm/v1/attention/ops/triton_unified_attention.py, the kernel launch parameters are computed as:

head_size = q.shape[2]

BLOCK_M = (
    16 if num_queries_per_kv <= 16 else triton.next_power_of_2(num_queries_per_kv)
)
BLOCK_Q = BLOCK_M // num_queries_per_kv

launch_num_warps: int | None = None
launch_num_stages: int | None = None

tuned_large_head = (
    head_size == 256
    and max_seqlen_q > 1
    and num_queries_per_kv <= 16
    and current_platform.is_device_capability_family(100)
)
if tuned_large_head:
    BLOCK_M = 32
    BLOCK_Q = BLOCK_M // num_queries_per_kv
    launch_num_warps = 8
    launch_num_stages = 2

The reported shared-memory requirement matches the default path exactly:

BLOCK_M × head_size × 2 bytes (fp16) × 3 (Q/K/V) × num_stages
= 16 × 512 × 2 × 3 × 2
= 98304 bytes

This is precisely the number in the error message, and 1.5× Turing’s 65536-byte limit.

Two observations:

  1. The tuned_large_head branch matches only head_size == 256, and is additionally gated on current_platform.is_device_capability_family(100) (Blackwell). The head_size == 512 global attention layers therefore receive no special handling on any platform, and on Turing this branch is dead code regardless.
  2. I diffed the file between vLLM 0.26.0 and 0.30.0rc1 — this logic is byte-for-byte identical in both, so upgrading vLLM does not change this code path.

This is consistent with an earlier experiment: I manually changed launch_num_stages = 2 → 1 inside the if tuned_large_head: block and it had zero effect on the error — expected, since that block never executes on SM75.

Already attempted

  • Alternative attention backends: FLASHINFER, XFORMERS
  • Various --block-size values
  • Lowering --max-num-batched-tokens
  • --limit-mm-per-prompt (to disable image input)
  • Both --tensor-parallel-size 1 and 2

None of these changed the outcome.

Proposed workaround

Forcing a single pipeline stage when the head size exceeds 256 brings the allocation to 16 × 512 × 2 × 3 × 1 = 49152 bytes, which fits within the Turing limit:

if launch_num_stages is None and head_size > 256:
    launch_num_stages = 1

Placed immediately after the if tuned_large_head: block, this leaves all existing tuned paths untouched and only affects head sizes that currently have no handling at all.

Questions

  1. Are Turing (SM75) GPUs considered supported for this checkpoint, or for Gemma 4 on vLLM in general?
  2. Is there a supported configuration flag that avoids this, rather than patching the kernel source?
  3. If a kernel-level fix for head_size > 256 on pre-Ampere hardware would be welcome upstream, I’m happy to open a vLLM issue or PR with the above analysis.

Thanks in advance for any pointers.

Gemma 4 models with global_head_dim=512 cannot run on Turing (SM75) GPUs by default in vLLM, because the Triton attention kernel requires 98,304 bytes of shared memory per block, exceeding Turing’s 65,536-byte hardware limit. No configuration flag currently avoids this; a code patch is required. The recommended workaround is to reduce num_stages to 1 for head_size > 256, which brings shared memory usage below the limit and allows inference to proceed. This is not yet merged upstream, but has been validated by multiple users and discussed as a general solution for Turing-class GPUs. Turing GPUs are not officially supported for Gemma 4 in vLLM without this patch, and upgrading vLLM does not resolve the issue as of v0.30.0rc1. See the linked issue for patch details and discussion.

Would you like a step-by-step guide to applying the patch or more detail on the kernel logic?

Sources:

Hint: Mention @Herald in the post for followups.

Yes, I like a step-by-step guide to applying the patch