Cursor开源MoK,将token调度、跨GPU通信和专家计算整合到同一GPU内核中。该方案在GB300 NVL72上实现MXFP8前向最高2.37倍、反向1.78倍的性能提升,512张GB300 GPU训练吞吐提升41%至1070.2 tokens/s。Signaling延迟从103μs降至18μs。分析指出,在NVLink带宽已达130 TB/s的今天,GPU等数据的时间成为新的性能瓶颈,这一突破,标志着AI竞争进入“全栈主权“阶段,代码离显存和寄存器越近的公司将拥有更大定价权。
文章作者、来源:雷峰网
7月21日,NVIDIA公布了GB300 NVL72训练DeepSeek-V3的最新成绩:256张GPU上,单卡性能达到1,648 TFLOPS。
不到两周后,Cursor开源了Mixture-of-Kittens,简称MoK。它没有继续折腾更快的矩阵乘法,而是直接重写了一层MoE的执行方式,把token调度、跨GPU通信和专家计算塞进同一个GPU内核。

这件事有点反直觉。因为GB300 NVL72已经把72张GPU放进同一个NVLink Domain,整机架NVLink总带宽达到130 TB/s。按这个规格看,GPU之间传数据应该已经足够快。
可在大规模MoE训练里,通信依然会拖住专家计算。
问题出在MoE的数据流。Router每一步都会重新决定token去哪个专家,而专家分散在不同GPU上。token要先跨卡送过去,算完再传回来;发送之前还要整理位置,到达之后还要等待数据完整。随着MXFP8和Blackwell Tensor Core把专家计算压得越来越短,这些原本还能藏在计算后面的等待开始越来越显眼。
Cursor做MoK,就是从这里下手。它没有只追求一次Dispatch能传多快,而是重新安排token怎么到达专家、什么时候开始计算,以及通信和计算怎样同时占用GPU。
在算力资源被Blackwell和NVLink堆到极致的今天,开发者发现:硬件跑得再快,也救不了低效的软件编排。
MoK的开源不仅是一个内核的胜利,它标志着“应用层定义算子“的时代的开始:为了压榨最后30%的算力,AI创业公司正在发起一场底层主权的夺权战争。
不过要理解Cursor的这套设计为什么有效,先是得看清一层MoE到底在什么地方交了“通信税“。

01
MoE的「通信税」
远不止把token传过去
在普通稠密FFN里,token要经过哪些权重基本是固定的。MoE加入Router之后,每个token临时选择几个专家。采用Expert Parallel时,专家又被拆到很多GPU上,于是一次前向传播至少要发生两轮跨卡通信。

第一轮叫Dispatch,把token送到专家所在的GPU;专家计算完成后,再通过Combine把结果送回token原来的位置。训练还有反向传播,对应再执行两轮反方向的通信。
如果只是把一大块连续数据从A搬到B,NVLink已经足够快。MoE麻烦在于,Router每一步给出的数据分布都不同。
某个专家这一步可能收到很多token,下一步又很少。系统需要先数清楚每个专家有多少token,再决定这些token放在目标GPU的什么位置,还要把同一专家的数据尽量排在一起。Grouped GEMM才能拿到规整的输入,高效喂给Tensor Core。

通信结束后也不能立刻开算。目标GPU要确认远端写入已经全部完成,数据确实可见。专家负载又不完全均匀,一部分GPU可能早早结束,仍然得等最忙的专家收尾。
所以一个“通信“阶段里,其实混着数据搬运、布局生成、同步和负载失衡几件事。130 TB/s描述的是整机架能够提供的峰值带宽,并不代表每一次动态、零碎的MoE通信都能把这些链路同时跑满。
DeepEP已经把其中的数据搬运做得很快。它本身就是面向Expert Parallel的高性能通信库,提供专门的Dispatch和Combine内核,支持FP8,并允许控制通信占用的SM数量。最新版本甚至可以用明显更少的SM保持很高的通信吞吐。
可一层MoE仍然要在Dispatch、Grouped GEMM和Combine之间不断交接。

这时会碰到一个很实际的矛盾:如果等足够多的token到齐再计算,矩阵很大,Tensor Core跑得舒服,但计算启动得晚;如果token到一点就算一点,通信和计算能更早重叠,矩阵又太小,GPU很多SM没有足够的工作。
多个CUDA Stream可以让通信和计算并发,却很难始终保证两边拿到恰到好处的GPU资源。
MoK后面的设计,基本都在处理这个“节奏“问题。

02
怎么让token一边传,一边算
MoK最有意思的改动之一,是把前向Dispatch从Push改成了Pull。
传统Push很直观:源GPU手里有token,就主动把它写进目标GPU。麻烦出在目标地址。一张GPU会同时收到很多其他GPU发来的token。
每个发送方都得提前知道自己应该写到哪一段,不能互相覆盖;同一个专家的token最好还要连续排列,否则后面的GEMM又要重新整理。

随着参与GPU越来越多,这个调度过程会越来越重。Pull换了一种方式:保存专家的目标GPU自己去读取需要的token。它只要知道token在哪张源GPU、位于源数据的什么位置,本地存放在哪儿由自己安排。

这一下省掉了多张发送方之间对目标地址的协调。收到的数据也可以直接按照本地专家排好。
有意思的是,Pull并没有少传数据。Cursor的微基准里,同一个256×256 BF16数据块,Push在NVLink上移动约159.6 KB,Pull反而达到172.0 KB,因为读取还要额外发送请求。

Pull胜在另一件事:MoE的通信很碎,而且负载不均衡。NVLink的两个方向拥有独立通道,Pull能同时利用请求和数据返回两个方向。在专家负载不均衡的测试中,Cursor测到最高29%的NVLink利用率提升。
同步上的差距更明显。Push写完以后,目标GPU需要等待其他GPU的完成信号,Expert Parallel规模大时,一个rank最多可能涉及另外71个peer。Pull是本地GPU自己发起读取,数据回来以后就能直接使用。

Cursor的多节点微基准中,这段signaling延迟从Push的约103微秒降到了Pull的18微秒。
MoK也没有所有地方都用Pull。前向是Pull Dispatch、Push Combine;反向则使用Pull Reverse-Combine和Push Reverse-Dispatch。Dispatch阶段需要把很多来源的token重新组织成专家输入,Pull更省协调;Combine时每个结果应该回到哪个token已经很清楚,直接Push回去更简单。
改变通信方向以后,MoK还把通信和专家计算放进同一个Megakernel。
它把GPU的SM分成两部分。一部分负责Dispatch、Combine和状态管理,另一部分专门执行Expert FFN。通信侧拿到一批完整token后,通过GPU本地计数器通知计算侧;计算完成,再通知通信侧把结果传回去。

这样可以直接决定通信用多少SM、计算用多少SM,不用完全交给多个CUDA Stream自己竞争。这里最关键的参数叫minibatch,也就是一次交给专家计算多少token。
它不能太大。太大意味着第一批计算得等很久。也不能太小。专家GEMM最终要拆成大量计算任务分给SM,如果token太少,任务数量不够,很多SM会闲着。

Cursor用wave来判断这个边界。一个完整wave,可以简单理解成所有计算SM都分到了工作。MoK希望一个minibatch至少能够形成两个完整wave,让Tensor Core有足够的任务持续执行。
实际结果很能说明问题。在Hidden Size为7168、专家中间维度为2048的Kimi 2.5形状上,Cursor估算minibatch至少需要大约2368个token。512 token时,MoK前向耗时为5.981 ms;增加到2560 token后,下降到3.425 ms。再继续增加,速度已经没有明显改善。

换句话说,通信切得更碎并不会一直变快。真正高效的重叠,需要让通信尽早交出数据,同时又不能把GEMM切得太小。
但MoE还有一个麻烦:Router跑完之前,根本不知道每张GPU最后会收到多少token。
如果按照最坏情况准备buffer,会浪费很多显存。如果先让GPU数完token,再通知CPU分配对应空间,GPU又得停下来等CPU。
MoK使用固定大小的Ring Token Buffer。一块空间先装Dispatch进来的token,专家算完、Combine把结果传走以后,这块空间立即重新给下一批token使用。前一个macrobatch的Combine,还可以和下一个macrobatch的Dispatch同时进行。

Ring Buffer在这里很像一个缓冲层:通信暂时跑得更快,数据就在里面积累;计算消费得更快,就等下一批token到达。整个过程靠GPU上的状态推进,不需要CPU每一轮都进来决定下一步。
Cursor还把MXFP8 activation的量化塞进了Dispatch、Grouped GEMM和SwiGLU的数据路径里,少掉独立quantize kernel,也少一次中间结果在HBM里的来回读写。
Pull、minibatch、SM分区和Ring Buffer放到一起后,MoK才真正变成了一条连续的MoE流水线。


03
一整套高度特化的执行方式
Cursor的benchmark测的是完整MoE层,包括Schedule、Dispatch、Expert FFN、Combine和最后的加权合并,对比对象包括NCCL + PyTorch、DeepEP、TransformerEngine以及HybridEP + Megatron。
在GB300 NVL72上,相比每种场景最快的公开基线,MoK的MXFP8前向最高提升2.37倍,反向最高提升1.78倍;BF16前向和反向最高分别提升1.92倍和1.58倍。

更重要的是端到端训练。Cursor原来的生产方案已经用了DeepEP。在512张GB300 GPU上,换成MoK后,单卡吞吐从每秒760.9个token提高到1070.2个,提升约41%。

这组结果也要看清边界。Cursor没有公开完整的逐项消融,所以无法准确说2.37倍里面有多少来自Pull、多少来自Megakernel、多少来自Ring Buffer。

可以单独确认的是Pull对NVLink利用率和signaling延迟的改善,其余收益更多来自整套执行方式组合后的结果。
MoK对硬件的依赖也很强。它面向Blackwell和NVL72这样的高速NVLink Domain。Pull的远端读取、通信和计算的细粒度交错,都建立在GPU之间能够低延迟访问彼此显存的基础上。模型的Hidden Size、Top-k、专家规模一发,合适的minibatch和通信SM数量也会跟着变。

这也是MoK最值得看的地方。过去讨论MoE优化,很容易盯着两个数字:GEMM有多少TFLOPS,All-to-All有多少GB/s。到了GB300这一代,仅仅把这两个数字继续往上推,已经解释不了全部性能。
token什么时候到、怎样排成专家需要的布局、攒多少开始计算、通信拿多少SM、buffer什么时候释放,这些执行细节开始直接决定训练速度。
一个拥有130 TB/s NVLink带宽的机架,最后仍然需要为MoE重写GPU内核,原因也就在这里:链路已经很快了,接下来要省的是GPU等数据的时间。
Cursor重写GPU内核的行为,标志着AI 2.0时代的竞争进入了“全栈主权“的新阶段。
以前,我们笃信“术业有专攻”,做应用就该做应用(Cursor),做底层就该做底层(NVIDIA)。但如今的AI竞争已经到了“去中间商化“的新阶段,Cursor并不是因为“想做“而去做内核,而是因为“不得不做“。
DeepSeek开启了工程榨取的新纪元,Cursor则把这团火烧到了应用层。这种“去中间商化“的趋势正在重塑AI的定价权:以后,决定AI公司估值的,不再是它拥有多少Token,而是它的代码离显存和寄存器到底有多近。
那些无法穿透底层黑盒的AI公司,最终将会留在“平庸税“的泥潭里。