从 O(n²) 到 O(n):DeepSeek NSA 与 Kimi MoBA 稀疏注意力底层原理深度拆解

从 O(n²) 到 O(n):DeepSeek NSA 与 Kimi MoBA 稀疏注意力底层原理深度拆解

!封面(https://picsum.photos/seed/17867203758764/800/400)

引言:开源浪潮背后,注意力正在被重写

2026 年 8 月 13 日,DeepSeek V4 Pro 正式版上线;紧接着月之暗面宣布将全球参数规模最大的开源大模型 Kimi K3 全量开源,阿里 Qwen3.8-2.4T-A95B 也把 Max 级旗舰权重开放。这波"中国开源军团"集体冲刺的底气,不只是算力和数据,更来自一套底层架构的成熟------训练时就内建的稀疏注意力机制

中国信通院《人工智能产业发展研究报告》明确把 DeepSeek 的 NSA(Native Sparse Attention) 和月之暗面的 MoBA(Mixture of Block Attention) 列为提升大模型推理效率的关键技术路径。两者都在 2025 年 2 月 18 日前后脚发布,被戏称为"一时瑜亮"。它们要解决的是同一个痛点:当上下文从 64K 冲向 1M token,传统 Full Attention 的 O(n²) 计算和线性膨胀的 KV Cache,正在把推理成本和显存双双逼到墙角。

本文不聊 API、不聊跑分,只从底层把这两套机制拆开:注意力为什么稀疏、KV Cache 为什么是瓶颈、块级稀疏如何对齐硬件、以及 NSA 和 MoBA 到底差在哪。

一、问题本源:注意力是 O(n²) 的,KV Cache 是吃显存怪兽

先复习一下 Self-Attention 的公式:`Attention(Q,K,V) = softmax(QK^T / √d) · V`。对于长度为 n 的序列,QK^T 是一个 n×n 的矩阵,计算量随序列长度二次方爆炸

更致命的是 KV Cache。自回归解码时,每个历史 token 的 K、V 都要缓存下来供后续步骤复用,显存占用为:

python 复制代码
def kv_cache_bytes(seq_len, n_layers=32, n_kv_heads=8, head_dim=128, dtype_bytes=2):
    """估算单条请求的 KV Cache 显存占用(字节)"""
    return 2 * n_layers * n_kv_heads * head_dim * seq_len * dtype_bytes

# 一条 128K 上下文的请求,Llama-70B 量级配置:
print(f"{kv_cache_bytes(131072) / 1024**3:.2f} GB")   # ≈ 8 GB / 请求

单条请求 8GB、并发 100 条就是 800GB------KV Cache 成了"不参与计算却占满显存"的隐形怪兽。而解码阶段每生成一个 token 都要把整条序列的 KV 读一遍,访存(memory-bound)取代计算成为瓶颈

二、注意力本质上是稀疏的:5% 的 token 扛起 95% 的注意力

优化之前,先问一个问题:注意力矩阵真的需要"全量"计算吗?

大量研究给出了否定的答案。H2O(Heavy-Hitter Oracle)论文发现,只需保留约 5% 的"重击 token"(Heavy Hitters),就能复现接近全量注意力的输出;CNN/DailyMail 摘要任务上的实验显示,即使 KV Cache 砍掉 50%,关键 token 的累计注意力得分仍能保持 90%~95%。换句话说,绝大多数 token 之间的注意力分数趋近于零------稀疏是注意力的天然属性,Full Attention 是在为大量无意义的计算买单

但"知道稀疏"和"利用稀疏"之间隔着天堑:如果稀疏模式是数据相关的、动态的,怎么在 GPU 上高效实现?这正是 NSA 与 MoBA 的用武之地。

三、块级稀疏:把"选 token"变成"选块"

早期稀疏方案(如滑动窗口)是静态的:只看邻近的 w 个 token,O(n·w),但对远距离依赖无能为力。动态稀疏(按 token 重要性挑选)理论上更好,但 token 级 gather/scatter 在 GPU 上是灾难------不规则的内存访问会把带宽优势全部磨平。

NSA 和 MoBA 的共识是:以块(block)为单位做稀疏。把序列切成固定大小(如 64/128 token)的 KV 块,先给每个块算一个"代表向量",让 query 和块代表向量打分,选 Top-K 个块,再只在这 K 个块上做细粒度注意力。块级粒度的好处是:内存访问连续、形状规则,能对齐 GPU 的 tile 访存,把稀疏性真正转化为带宽收益。

下面用 PyTorch 写一个最小可运行的块级 Top-K 稀疏注意力(MoBA 的核心思路):

python 复制代码
import torch
import torch.nn.functional as F

def block_sparse_attention(q, k, v, block_size=64, top_k=8):
    """MoBA 风格块级稀疏注意力:Q 按块路由到 Top-K 个 KV 块"""
    B, H, T, D = q.shape
    n_blocks = T // block_size

    # 1) 把 K 按块压缩成代表向量(块内均值池化)
    k_blocks = k.view(B, H, n_blocks, block_size, D).mean(dim=3)  # (B,H,nb,D)

    # 2) 路由打分:每个 Q 块用代表向量与所有 KV 块打分,选 Top-K
    q_blocks = q.view(B, H, n_blocks, block_size, D).mean(dim=3)  # (B,H,nb,D)
    scores = torch.einsum("bhnk,bhmk->bhnm", q_blocks, k_blocks)  # (B,H,nb,nb)
    top_idx = scores.topk(top_k, dim=-1).indices.sort(dim=-1).values  # 升序便于切片

    out = torch.zeros_like(q)
    for i in range(n_blocks):
        sel = top_idx[:, :, i]                      # (B,H,K)
        k_sel = torch.gather(k_blocks, 2, sel.unsqueeze(-1).expand(-1,-1,-1,D))
        # 细粒度注意力只在被选中的块上计算
        # (工程实现会用 block-sparse GEMM / cuDNN 加速,这里展示语义)
        att = torch.einsum("bhtd,bhkd->bhtk", q[:, :, i*block_size:(i+1)*block_size], k_sel)
        att = att / (D ** 0.5)
        att = F.softmax(att, dim=-1)
        v_sel = torch.gather(v.view(B,H,n_blocks,block_size,D), 2,
                             sel.unsqueeze(-1).unsqueeze(-1).expand(-1,-1,-1,block_size,D))
        out[:, :, i*block_size:(i+1)*block_size] = torch.einsum(
            "bhtk,bhkvd->bhtvd", att, v_sel).reshape(B, H, block_size, D)
    return out

计算量从 O(n²) 降到 O(n·top_k·block_size),而 top_k·block_size 远小于 n。稀疏注意力是线性复杂度的,序列越长优势越大------这正是长上下文模型(Kimi K3、DeepSeek V4 系列动辄百万 token 上下文)的底气。

四、NSA:三种注意力分兵合击

DeepSeek 的 NSA 是"混合策略"的集大成者,每条 query 同时走三条分支:

  1. 压缩分支(Compressed):沿序列维度做可学习的 token 压缩,把历史信息压成粗粒度表示,负责捕捉全局语义------这是对远处历史的"速览";

  2. 滑动窗口分支(Sliding Window):最近的 w 个 token 无条件参与注意力,保证局部精度;

  3. 选择分支(Selected):块级稀疏,按压缩后的代表性 key 打分,动态挑选 Top-K 个历史块做细粒度计算。

三个分支的结果拼接后统一做 softmax。妙处在于"分治":全局靠压缩、局部靠窗口、关键靠选择。NSA 论文报告在 64K 解码时相比 Full Attention 有显著加速,且训练阶段就引入稀疏,避免了"训练用稠密、推理用稀疏"的分布偏移------这是此前大量推理期剪枝方案效果打折的根本原因。

值得展开的是"硬件对齐"这个容易被忽视的细节。NSA 在实现上借鉴了稀疏矩阵计算的成熟思路:把稀疏模式约束为块内稠密、块间稀疏 的规整结构(类似 NVIDIA 2:4 结构化稀疏的推广),让 GPU 的 Tensor Core 可以按固定 tile 形状批量计算,同时减少对 `torch.nonzero` 之类不规则索引的依赖。论文还专门做了针对长序列解码的 kernel 优化,通过预计算压缩索引、避免重复的索引查找,把"选块"的开销摊薄到可忽略的程度。这也是为什么 NSA 能同时拿到训练加速和推理加速------稀疏结构从第一天起就是为硬件设计的,而不是事后补救。

五、MoBA:把 MoE 的路由思想搬进注意力

MoBA 的思路更"激进"也更优雅:既然 MoE 能用路由让每个 token 只激活部分专家,为什么不让每个 Q 块只路由到自己关心的 KV 块? 它几乎复刻了 MoE 的三件套------块切分、门控打分、Top-K 选择,把"选专家"换成"选 KV 块"。

一个值得注意的工程细节:MoBA 作者在实践中发现,路由自由度高反而可能抵消收益------当每个 Q head 各自为政、选中的块互不相交时,IO 优化会被磨平。MHA(每 Q 独享 KV)下 MoBA 效果最好,GQA 次之,MQA(多 Q 共享一份 KV)下最差。这也解释了为什么 2026 年的长上下文模型在注意力头设计上如此谨慎。

六、NSA vs MoBA:同门师兄弟的三处分歧

虽然内核相似,两套方案在细节上分道扬镳:

全局策略不同。NSA 保留了静态的滑动窗口分支作为"保底",局部上下文永远不被稀疏裁剪,因此对短距离依赖更稳;MoBA 则完全依赖路由,连邻近块都要靠路由选中才会参与计算,纯度更高但更"赌"。

压缩方式不同。NSA 使用可学习的 token 压缩网络(类似低秩投影),压缩表示本身参与训练;MoBA 则用块内 mean-pooling 之类的固定聚合得到块代表向量,简单直接、零额外参数。

兼容性取向不同。NSA 为现代 GQA/MQA 架构做了针对性设计,宣称与这些高效注意力头结构兼容;MoBA 论文则坦言其路由机制在 MHA 下收益最大、MQA 下收益最差,工程上对注意力头数量的选择更敏感。

一句话总结:NSA 是"工程派",用混合策略求稳;MoBA 是"架构派",把 MoE 哲学贯彻到底。二者互相印证了"块级稀疏 + 训练时内建"是长上下文时代绕不开的方向。

七、工程落地:稀疏不只是论文里的故事

对普通开发者,这篇文章的落点很简单:当你的 RAG 知识库、Agent 长记忆、代码仓库级上下文开始"卡显存"时,别再盲目堆卡------先算算 KV Cache 账,再看看你的推理框架(vLLM、SGLang)是否已开启稀疏/量化路径。2026 年的开源旗舰(Kimi K3、DeepSeek V4 系列、Qwen3.8)已经把稀疏注意力做成出厂配置,这意味着同样的显存预算下,你能跑的上下文长度和并发数都比上一代模型高一个量级------这不是渐进优化,而是架构级的重新定价。

最后留一个思考题:如果注意力可以稀疏,那么 KV Cache 的存储结构、显存分配器、甚至 PCIe 带宽规划,是不是都该为"块级稀疏"重新设计?注意力稀疏性,是继 MoE 之后大模型"降本增效"的下一张底牌------牌已经打出来了,读懂它的人将率先吃到长上下文时代的第一波红利。

相关推荐
深念Y2 小时前
基于 NapCat 与本地 RAG 的群聊 AI 机器人方案(ARM64 部署)
人工智能·ai·机器人·node.js·自动化·情感陪伴·bot
晴天162 小时前
Cordis框架: 为可逆软件系统而生的元框架-Day18
ai·架构
liulilittle4 小时前
LLM 推理引擎与内核系统工程原理
c++·ai·llm·内存·memory·core·kernel
星花月5 小时前
【无标题】
ai·语言模型·pdf·deep learning
感谢地心引力5 小时前
DeepSeek-V4-Pro正式版发布,API价格翻倍,DeepSeek Harness体验如何?
ai·deepseek·harness
晴天165 小时前
Cordis 框架代码核心解析:一个可逆插件系统的实现-Day18
人工智能·ai·架构
特立独行的猫a6 小时前
DeepSeek Harness插件和工具的区别介绍及开发入门指南
前端·ai·agent·插件·deepseek·harness
安逸sgr6 小时前
优化器是什么?SGD、Momentum、Adam 有什么区别?
人工智能·ai·大模型·agent·智能体
王莹月6 小时前
全店商品图风格怎么统一?生图API 用 nano banana pro 批量出同一套视觉
gpt·ai·chatgpt·ai作画·aigc·agi