DeepSeek开源DeepSelect:比torch.topk快二十倍!


DeepSelect 是 DeepSeek 开源的一个高性能 TopK 算子库,专门用于加速其稀疏注意力机制(DSA)和采样器中的关键计算步骤。

项目核心目标

在 DeepSeek 的稀疏注意力机制中,需要从海量 token 里快速找出与当前查询最相关的 TopK 个 token。DeepSelect 的目标就是高效地完成这个“筛选”工作,相比 PyTorch 原生的 torch.topk,它能带来 2 到 20 倍 的速度提升。

两大应用场景

DeepSelect 针对 DeepSeek 模型中的两种典型工作负载进行了专门优化:

*   闪电索引器场景:用于 DeepSeek V3.2、V4 及 V4.1 等模型的稀疏注意力模块(DSA)中,快速筛选出关键的 Key/Value 对。
    *   输入数据类型:torch.bfloat16
    *   核心参数:topk 值需 ≤ 4096
*   采样器场景:用于模型推理时的 token 采样环节,从词表(Vocab)中挑选概率最高的候选 token。
    *   输入数据类型:torch.float32
    *   核心参数:词表大小通常在 128K 左右,topk 值同样需 ≤ 4096


DeepSelect 的推出,也侧面解释了 DeepSeek V4.1 Flash 等模型在推理速度上表现优异的部分原因。

DeepSeek开源DeepSelect把GPU挑TopK的速度拉高二十倍!

你的显卡可能一直在等一个不到一百行的函数!

DeepSeek开源DeepSelect,专治GPU上TopK挑选慢,闪电索引器和采样器两场景加速,torch.topk慢在内存搬运和多余排序,DeepSelect独立安装不绑推理框架,关掉排序和返回值还能再快一截,实测最高二十倍。

显卡算力堆成山,TopK却慢成蜗牛!

大模型读入一段话时,内部会给每个token打一个分数,分数越高的token越重要。TopK(从一堆数里挑出最大的前K个)就是在一大堆分数里挑出最高的前几个,像老师从一千份卷子里找出前十名,剩下的九百九十份直接扔进碎纸机。这个动作听起来简单到不值一提,可它偏偏成了GPU上最拖后腿的环节之一。

一张现代显卡的理论内存带宽能到1800 GB/s,而PyTorch(一个主流深度学习框架)自带的torch.topk函数,在处理某些尺寸的数据时,有效内存带宽只有12.7 GB/s。算一下,实际效率连理论值的百分之一都不到!你花三万块买的显卡,跑起TopK来像被绑住了手脚,问题跟算力一点关系都没有。

DeepSeek开源的DeepSelect(一个独立TopK算子库)直接卡住了这个生态位。它不绑TensorRT-LLM推理管线,不绑vLLM框架,不绑SGLang框架,pip装一下就能在代码里替换torch.topk。TensorRT-LLM的Guess-Verify-Refine Top-K确实针对Blackwell架构做了优化,可你要用它的优化,就得把整个推理栈都换掉。DeepSelect反过来,它只服务两个具体场景,却在这两个场景里把每一纳秒都榨干。

torch.topk拖后腿,DeepSelect另起炉灶!

PyTorch从2.6版本升级到2.7版本的时候,torch.topk还出现过严重的性能倒退:在Nvidia L20显卡上,同样的输入,延迟从11.30毫秒直接涨到17.32毫秒,暴跌了51%。提取十亿个浮点数里最大的前一千个,在H20显卡上从36毫秒暴涨到了1.6秒,这种波动让整个行业都在踩坑。

你可能会想,换个更快的库不就行了?问题是深度学习框架的生态不是你说换就能换的,torch.topk从PyTorch诞生那天起就在那里,无数模型的代码里写着它,无数推理引擎依赖着它。你改了它,整个训练和推理管线都可能崩掉。DeepSeek的做法是承认torch.topk短期内不可能被替换,但在它旁边重新造了一个专用工具,只在最需要速度的地方用它。

DeepSelect跟torch.topk最根本的区别在工程哲学层面:torch.topk是一个通用工具,要处理各种数据类型、各种张量形状、各种奇怪的输入,像一个万能扳手,什么螺丝都能拧,但拧得都不快。DeepSelect只服务闪电索引器(Lightning Indexer)场景和采样器场景,它知道自己的输入长什么样,并且专门为这种输入重新设计了内存搬运方式。vLLM里的flashinfer多CTA topk实现需要40微秒,SGLang的单block实现需要65微秒以上,而且这两个实现都不保证结果稳定。DeepSelect稳定且快,这就怪了!

闪电索引器要快,采样器还要稳!

DeepSeek的稀疏注意力(DSA)需要从海量token里快速找出与当前查询最相关的TopK个token,闪电索引器场景的输入是bfloat16(一种16位浮点格式),TopK值不超过4096,DeepSelect利用这个约束条件把数据分块搬运,用异步流水线把计算和读写重叠起来,让GPU在搬运数据的同时就已经在比较大小了。torch.topk拿到同样的数据,得先全部搬进显存,再统一排序,中间白白浪费了大量带宽。

采样器场景的输入是float32(32位浮点格式),词表大小通常在128K左右,TopK值同样不超过4096,DeepSelect专门为这种数据类型重新设计了筛选路径。两个场景的数据类型不同,最优内存访问模式也不同,torch.topk用同一套通用逻辑去处理,自然做不到两头都快。DeepSelect把适用范围缩小到两个具体场景,然后在这两个场景里做到极致。

vLLM的flashinfer和SGLang的单block实现都不保证结果稳定,什么叫不稳定?就是同样的输入跑两次可能给出不同的TopK结果。对于模型推理来说,同一个问题问两次可能得到不同的回答,这在生产环境里是致命的。DeepSelect解决了这个矛盾:它的结果稳定,它的速度是torch.topk的2到20倍,而且它不绑定任何推理框架,pip装一下就能直接替换。对吗?

竞品各绑各的栈,独立替换才是狠招!

Nvidia的TensorRT-LLM确实有自己优化过的Top-K内核,叫Guess-Verify-Refine Top-K,专门针对Blackwell架构,但这个内核是绑定在TensorRT-LLM推理管线里的。你要用它的优化,就得把整个推理栈都换成TensorRT-LLM,而DeepSeek的模型跑在vLLM、SGLang等多个推理框架上,不可能为了一个TopK算子把所有框架都改一遍。DeepSelect的安装方式简单到令人发指:git clone下来,更新子模块,pip install -v .,然后就能在代码里调用deep_select.topk。

vLLM社区有flashinfer多CTA topk实现,SGLang有单block实现,速度数字看着不错,但它们都绑在各自的框架里,而且不保证结果稳定。DeepSelect不绑任何框架,结果稳定,速度还快2到20倍。这种独立替换能力是DeepSelect唯一不可替代的差异,也是它跟所有竞品最根本的分界线。

DeepSelect的API设计非常简洁,跟torch.topk类似:deep_select.topk(x, topk, sorted_index=True, indices_type=torch.int32, return_value=True)。你不需要改模型结构,不需要换推理引擎,只需要把torch.topk换成deep_select.topk。TensorRT-LLM做不到这一点,vLLM的flashinfer做不到这一点,SGLang的单block实现也做不到这一点。事情没那么简单!

关掉排序省十趴,不要数值再快一截!

DeepSelect有一个参数叫sorted_index,意思是“要不要把找出来的TopK结果按顺序排好”。官方建议是:如果下游不需要按顺序排列的结果,就把它关掉。为什么?因为排序需要额外的计算和内存操作,关掉之后速度还能再快一截。torch.topk没有这个选项,它永远帮你排好序,哪怕你根本不需要。

第二个参数叫return_value,意思是“除了位置编号,要不要把对应的数值也返回”。官方建议是:如果只需要知道“哪些位置被选中了”,不需要知道“它们的值是多少”,就把它设成False,这样能再快约10%。torch.topk也没有这个选项,它永远把值和索引一起返回,哪怕你只想要索引。

这两个参数看着不起眼,但它们揭示了一个更深层的道理:torch.topk慢,不仅因为它内存搬运效率低,还因为它做了太多你根本不需要的事情。就像你去餐厅点一碗面,厨师不光给你煮面,还顺便把厨房擦了、账单算了、明天早上的粥也熬上了。DeepSelect的做法是:你告诉我你到底要什么,我只做你要的那部分。TensorRT-LLM绑管线,vLLM和SGLang绑框架,只有DeepSelect能让你按需裁剪还保持稳定。

参数翻倍反更快,黑箱里还藏着问号!

DeepSeek V4.1 Flash的主干参数达到了5520亿,比上一代V4 Flash的2840亿几乎翻了一倍,参数越多、模型越大,推理应该越慢才对。但实际结果是:预填充(Preill)阶段每token只激活80亿参数,解码(Decode)阶段只激活160亿参数,比上一代激活的130亿还少。这就是MoE(混合专家)架构的魔法,也是CSA2跨层复用TopK索引的功劳,DeepSelect在底层默默贡献的力量不可忽视。

DeepSeek V4.1 Flash能在首日测试中跑到每秒280到500个token的输出速度,峰值超过500,而上一代的V4 Flash在自家API上的输出速度只有每秒120到140个token,速度翻了三倍多。你问它一个问题,它一秒钟能吐出大半页纸的内容。DeepSelect的稳定性和独立替换能力,让这种速度提升不依赖任何特定推理框架,vLLM能跑,SGLang也能跑,TensorRT-LLM想用也可以用。

目前公开的性能测试都是在固定输入尺寸、固定显卡型号上跑出来的单次基准测试。在大规模并发推理的场景下,当几百个请求同时涌入、batch size动态变化的时候,DeepSelect还能保持2到20倍的速度优势吗?当显存碎片化、多请求竞争GPU资源的时候,它的结果稳定性还能维持吗?DeepSeek的技术报告只给出了理想条件下的性能数字,真实的线上表现仍然是一个黑箱。这个黑箱里面藏着的,可能是下一个让所有人重新审视GPU算子设计思路的关键线索。