←Back to Science Coding Hub/Part D/D3
D3Medium★ Core Essential · Industrial BedrockPart D · Attention Mechanisms & Transformer Blocks

Grouped-Query & Multi-Query Attention

Industrial-grade implementation and mathematical foundations of Grouped-Query & Multi-Query Attention.

⏱️ Time Complexity: O(B * H_q * S^2 * D_k) 计算量微弱节省
💾 Space Complexity: KV Cache 显存开销降为原先的 H_kv / H_q
💡

Core Mental Anchor / Mnemonic

Master Grouped-Query & Multi-Query Attention: enforce numerical stability, check tensor shapes, and eliminate redundant memory allocations.

📐 Mathematical Derivation & Core Formula

HQ 个 Query 头分为 G 组,每组共享 1 个 Key/Value 头,KV 显存缩减至 1HQ/HKVH_Q \text{ 个 Query 头分为 } G \text{ 组,每组共享 } 1 \text{ 个 Key/Value 头,KV 显存缩减至 } \frac{1}{H_Q / H_{KV}}
### Mathematical Derivation & Theoretical Principles
Detailed first-principles formulation and architectural mechanics for Grouped-Query & Multi-Query Attention.

Refer to the LaTeX equation above for the core operator definition. The operator is designed to ensure strict numerical bounds, avoiding floating-point overflows and gradient anomalies.

🔄 Tensor Dimensions & Shape Flow

k: (B, H_kv, S, D_k) -> repeat_kv -> (B, H_q, S, D_k) -> 与 q: (B, H_q, S, D_k) 点积 -> (B, H_q, S, D_k)

🛡️ Industrial Numerical Stability & Pitfalls

  • Ensure proper multi-dimensional tensor broadcasting and keepdims retention.
  • Enforce numerical guards (eps clamping and overflow thresholds) during exponentiation and division.
  • Verify train versus eval mode behavioral distinctions (e.g. frozen running statistics and dropout bypass).

💻 Industrial Code Implementation

import numpy as np

def repeat_kv(x: np.ndarray, num_rep: int) -> np.ndarray:
    """
    将 KV 头重复展开以对齐 Query 头的数量。
    x 形状: (B, H_kv, S, D_k)
    返回: (B, H_q, S, D_k),其中 H_q = H_kv * num_rep
    """
    if num_rep == 1:
        return x
    B, H_kv, S, D_k = x.shape
    # 增加扩展维度并广播
    x = x[:, :, np.newaxis, :, :]  # (B, H_kv, 1, S, D_k)
    x = np.repeat(x, num_rep, axis=2)  # (B, H_kv, num_rep, S, D_k)
    return x.reshape(B, H_kv * num_rep, S, D_k)

def grouped_query_attention(
    q: np.ndarray,      # (B, H_q, S, D_k)
    k: np.ndarray,      # (B, H_kv, S, D_k)
    v: np.ndarray,      # (B, H_kv, S, D_k)
    is_causal: bool = True
) -> np.ndarray:
    B, H_q, S, D_k = q.shape
    H_kv = k.shape[1]
    assert H_q % H_kv == 0, "Query 头数必须是 KV 头数的整数倍"
    num_rep = H_q // H_kv
    
    # 将 KV 广播扩展为与 Q 头数相同
    k_expanded = repeat_kv(k, num_rep)  # (B, H_q, S, D_k)
    v_expanded = repeat_kv(v, num_rep)  # (B, H_q, S, D_k)
    
    # 执行常规多头注意力点积
    scores = np.matmul(q, k_expanded.swapaxes(-1, -2)) / np.sqrt(D_k)
    if is_causal:
        mask = np.triu(np.ones((S, S), dtype=bool), k=1)
        scores = np.where(mask, -1e9, scores)
    
    scores_max = np.max(scores, axis=-1, keepdims=True)
    probs = np.exp(scores - scores_max)
    probs /= np.sum(probs, axis=-1, keepdims=True)
    return np.matmul(probs, v_expanded)

🧪 Runnable Assertions & Validation

Copy and run directly in Python / Jupyter to verify correctness:

import numpy as np
B, S, D_k = 2, 4, 8
H_q = 8
H_kv = 2  # 4 个 Q 头共享 1 个 KV 头
q = np.random.randn(B, H_q, S, D_k)
k = np.random.randn(B, H_kv, S, D_k)
v = np.random.randn(B, H_kv, S, D_k)
out = grouped_query_attention(q, k, v)
assert out.shape == (B, H_q, S, D_k), "输出形状不正确"
print("✓ GQA 分组查询注意力自测通过")

🎯 Core Architecture Follow-up Q&A

Q1:What are the key trade-offs and memory bottlenecks when deploying Grouped-Query & Multi-Query Attention in high-throughput inference?
Memory bandwidth (HBM to SRAM I/O) is the primary latency factor. Fusing element-wise operations and avoiding intermediate tensor materialization significantly outperforms naive implementations.
Q2:How does Grouped-Query & Multi-Query Attention handle extreme numerical boundaries or precision reduction (FP16/BF16/INT8)?
Under low precision, operations must be upcasted to FP32 during accumulation to prevent underflow/overflow, followed by proper scaling and clamping before converting back to the target format.
←Prev: Multi-Head Attention (MHA)All 69 KernelsNext: KV Cache Autoregressive Generation Loop→