Skip to content

Implement QK attention head chunking for CSA [Deepseek v4] - #5116

Open
octatrifan wants to merge 3 commits into
octatrifan-dsv4-indexer-lossfrom
octatrifan-dsv4-qk-chunking
Open

Implement QK attention head chunking for CSA [Deepseek v4]#5116
octatrifan wants to merge 3 commits into
octatrifan-dsv4-indexer-lossfrom
octatrifan-dsv4-qk-chunking

Conversation

@octatrifan

@octatrifan octatrifan commented Sep 3, 2026

Copy link
Copy Markdown
Collaborator

Description

Stacked on PR 5033 .
Dense attention scoring materializes full $[B, H, S, S]$ QK interaction tensors across all heads.
This causes OOM issues at longer context lengths.
PR #4564 addressed this for MLA by chunking over the heads dimension with jax.lax.scan. This PR extends that optimization to DeepSeek-V4 Compressed Sparse Attention (CSA).
This requires some changes as CSA uses compressed blocks.

BUGS: b/556431288

Changes

Chunking is applied to two sites using mla_qk_head_chunk_size:

  1. DeepseekV4Indexer: Scans over index_n_heads // head_chunk_size using jax.checkpoint on the scan body so backward activation memory stays bounded to 1 chunk.
  2. calculate_csa_indexer_loss: Scans over heads // head_chunk_size. Since teacher inputs use stop_gradient, jax.checkpoint is omitted.
    Defaults to 0 (native unchunked path).

Tests

Added 3 unit tests in tests/unit/deepseek_v4_indexer_loss_test.py:

  • test_csa_indexer_scoring_head_chunking_parity: Verifies mathematical parity ($< 1\text{e}-6$ max diff) between unchunked ($c=0$) and chunked ($c=2, 4$) across all indexer routing heads.
  • test_csa_indexer_loss_head_chunking_parity: Verifies mathematical parity ($< 1\text{e}-6$ max diff) between unchunked and chunked teacher CSA loss across multiple chunk sizes.
  • test_csa_indexer_chunked_gradients_flow: Verifies gradient flow through the chunked scan body into query, key, and indexer projections.

Checklist

Before submitting this PR, please make sure (put X in square brackets):

  • I have performed a self-review of my code. For an optional AI review, add the gemini-review label.
  • I have necessary comments in my code, particularly in hard-to-understand areas.
  • I have run end-to-end tests tests and provided workload links above if applicable.
  • I have made or will make corresponding changes to the doc if needed, including adding new documentation pages to the relevant Table of Contents (toctree directive) as explained in our documentation.

@gemini-code-assist

Copy link
Copy Markdown

Warning

You have reached your daily quota limit. Please wait up to 24 hours and I will start processing your requests again!

@octatrifan
octatrifan force-pushed the octatrifan-dsv4-qk-chunking branch 2 times, most recently from f2ab1ae to 1317a0f Compare September 3, 2026 22:25
@codecov

codecov Bot commented Sep 3, 2026

Copy link
Copy Markdown

Codecov Report

✅ All modified and coverable lines are covered by tests.

📢 Thoughts on this report? Let us know!

@octatrifan
octatrifan force-pushed the octatrifan-dsv4-qk-chunking branch from 9979754 to ad65b6c Compare September 4, 2026 20:53
raw_probs = jax.nn.softmax(safe_scores.astype(jnp.float32), axis=-1)
raw_probs = jnp.where(valid_tokens_mask[:, None, :, None], raw_probs, 0.0)
target_probs = jnp.sum(raw_probs, axis=1)
target_probs = jax.lax.optimization_barrier(target_probs)

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

Do we need this in the chunking branch too? Tbh not sure.

float32_qk_product: false # in dot_product attention, whether to cast to fp32 the inputs to qk product
float32_logits: false # in dot_product attention, whether to cast to fp32 the inputs to softmax
mla_qk_head_chunk_size: 0 # Limits HBM footprint by sequentially evaluating the QK matrix in the Indexer across the unsharded local heads dimension natively.
mla_qk_head_chunk_size: 0 # Limits HBM footprint by sequentially evaluating the QK matrix in MLA and CSA Indexers across the unsharded local heads dimension natively.

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

Might already exist, but raise an error when we validate flags to ensure this divides head size.

float32_qk_product: false # in dot_product attention, whether to cast to fp32 the inputs to qk product
float32_logits: false # in dot_product attention, whether to cast to fp32 the inputs to softmax
mla_qk_head_chunk_size: 0 # Limits HBM footprint by sequentially evaluating the QK matrix in the Indexer across the unsharded local heads dimension natively.
mla_qk_head_chunk_size: 0 # Limits HBM footprint by sequentially evaluating the QK matrix in MLA and CSA Indexers across the unsharded local heads dimension natively.

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

Also I think we have overloaded this flag as it is for MLA originally and now its name is confusing.

I think you should rename it and update:
google3/cloud/cluster/supercomputer/ubench/core/workloads/maxtext_training/configs/tpu7x-4x8x8/deepseekv3.2_671b_128K.yaml

Or just split to its own flag.

np.testing.assert_array_equal(np.array(topk_chunked), np.array(topk_native))
np.testing.assert_allclose(np.array(scores_chunked), np.array(scores_native), rtol=1e-5, atol=1e-5)

def test_csa_indexer_chunked_gradients_flow(self):

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

I don't think we are testing whether the chunked gradients are equal to the non-chunked gradients.

@dandragona dandragona left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

Mostly minor comments.

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