Daedalus 18层只留6层注意力,CPU长上下文解码比孪生模型快1.76倍

Daedalus-150M: A Convolution-Attention Hybrid Designed for CPU Inference

Christos Koutsiaris

cs.IR, cs.AI, cs.CL, cs.LG

2026-08-21

面向单用户CPU推理,18层里12层用两步短卷积替代注意力。59.9B token从零训出47.31五任务均分,2048上下文解码比同规模全注意力快1.76倍。

这篇在解决什么

小模型上 CPU,常见路径是先按 GPU 大模型的样子搭 Transformer,再量化、剪枝、压缓存。单用户、一次一个 token 的场景里,这条路对不上账。

没有 batch 可以摊权重读取。每生成一个 token,整份权重要从内存扫一遍,速度由每 token 读多少字节决定,不由算力。注意力层还要带着一份随对话变长的 KV cache,也就是已生成 token 的 key 和 value;上下文越长,每一步都要把前面所有 token 再读一遍。GPU 大 batch 服务里这点税可以忍。CPU 上 batch=1 时,长对话的延迟就是被它拖出来的。

多数层如果只维护一份固定大小的状态,解码代价对上下文长度就会变平。这是这篇真正下手的地方。

方法

Daedalus-150M 有 160.49M 参数、18 个 block、宽度 768、上下文 2048。18 层里只有 6 层做完整注意力,其余 12 层换成核长为 3 的 depthwise 卷积,每个通道独立滑动。排布是 CCCC A CC A C A C A C A CC A C,注意力落在第 4、7、9、11、13、16 层,刻意散开而不是扎堆,让检索能力分布在不同抽象层级。

卷积块先把输入投影成三路 B、C、x,对 B 门控后的 x 做 depthwise conv1d,再用 C 门控后投影回去。核长 3,循环状态永远只有前两步,跟对话写到多长无关。B 和 C 两个门给固定核补上随输入变化的行为。解码过一层卷积,第 2000 个 token 和第 2 个 token 花一样多的钱。

6 层注意力上用了 grouped-query attention:12 个 query head 共享 4 个 KV head,这 6 层的缓存再缩到三分之一。词表 49,152,输入输出 embedding 绑在一起,那张 37.7M 的表只存一份,占全模型 23%。FFN 内宽 2048,是 2.67 倍宽度而不是常规 4 倍,把参数从最吃带宽的宽张量挪到深度和注意力上。

对照模型是一个参数量差 0.5% 以内的全注意力孪生:24 层、宽度 640、FFN 2304,共 161.25M。两边同一份数据、同一套 schedule,各训 5B token,赢的规则事先写死,验证集 bits-per-byte 领先超过 0.5% 才算赢。选短卷积而不是 Mamba 一类 selective scan,是因为它能直接落到现成 CPU 推理内核上,不用新算子。目标运行时是 llama.cpp 的 Q40。MoE 在设计阶段就否了,这个规模没有先例,而且目标运行时的 mix 路径绑死了特定厂商的 gating,导不出去。蒸馏因为存教师 logits 要约 288 GB、盘只有 250 GB,也取消了。

完整模型从十源英语混合上训,16.93B 独特 token,预算 59.9B,大约 3.5 个 epoch,单源最多重复 4 次。硬件是一张 RTX 5090。

结果

完整模型验证 bits-per-byte 为 0.8685。五任务均分 47.31,事先钉死的及格线是 GPT-2 124M 的 42.20。同一套 harness 复测(MobileLLM 未能在该 harness 上跑通,沿用其发表数字):

模型训练 token五任务均分
Daedalus-150M59.9B47.31
MobileLLM-125M1T46.3(发表值)
GPT-2 124M42.2
OPT-125M180B42.1
GPT-neo-125M300B41.9
Pythia-160M300B41.0
Peer-135M2T51.2

分任务:PIQA 65.78、ARC-Easy 50.42、WinoGrande 50.04、HellaSwag 37.93、OpenBookQA 32.40。WinoGrande 卡在 50 的随机线,这个规模上它几乎不测东西。2T 的 Peer-135M 仍高 3.9 分,训练前就认了:同等规模下拿质量换解码速度。同一架构只训 5B token 已经 44.7,过了 42.2 的线。

5B token 的对照才是架构本身的证据。混合模型 valbpb 0.9104,全注意力孪生 0.9178,领先 0.81%,过了预先设的 0.5% 门槛。五任务均分 44.68 对 44.82,差 0.14 分,大约 0.24σ,任务之间互有胜负,按噪声处理。4-bit 成品 95.56 MiB 对 101.62 MiB,小 6.3%。

CPU 解码用 Q40、8 线程、生成 128 个 token,两条曲线的形状才是论点:

上下文混合 tok/s全注意力 tok/s倍率
01111.9922.81.20×
512960.3664.41.45×
2048739.3420.31.76×

空上下文几乎没优势,越长越拉开。对外部 135M 模型同样:空上下文 1.06×,2048 处 2.08×(648.6 对 312.4 tok/s)。按每 token 读多少字节算,混合模型的 KV 流量是孪生的一半(每上下文 token 6144 B 对 12288 B),2048 处只该快 1.17×,实测 1.76×。差额被归到注意力 softmax 的延迟,以及孪生模型多跑 6 层的固定开销。一个只是更瘦的模型会给出常数加速,给不出这种随长度发散的曲线。

为什么重要

给要在普通 CPU 上跑本地小模型的人看。长对话、把文档塞进 prompt、处理文件,都会坐在那张表的右端。短 prompt、空上下文、问完就走,几乎吃不到这个架构。成品 95.56 MiB,2048 上下文的 KV cache 大约 12.6 MB,单用户会话能压进 128 MB,可以跟应用住在同一进程里。

方法上没有新算子。事情是把 cache-free 层和注意力层的比例,当成 CPU 上 batch=1 时最该调的变量,再用预先登记的对照把它从训练配方里拆出来。Griffin 一类混合模型走同一条家族路线,这里的区别是卷积短到能直接用现成内核,比例由内存流量拍板,不由 GPU 经验拍板。

这是一篇钉在部署约束上的渐进改进,不是再刷一个小模型榜。

局限与存疑

量化感知训练第一步就出非有限 loss,被关掉了,4-bit 困惑度代价约 6%(半精度 9.18,Q40 为 9.75),小规模时只有 2.5%。约 47.9% 的卷积通道对输出没贡献,大约 13.6M 参数白占,浪费 8.5%;想在导出时剪掉,llama.cpp 按固定宽度做 shape check,期望 768 收到 640 直接拒载。词表 49,152 是给蒸馏计划留的,计划取消后没改,按缩放律 150M 模型更合适 24k-32k,embedding 占了 23% 参数。训练混合物的 L1 偏离 10.42,超过预先设的 10.0。最后 8% 从 checkpoint 恢复,优化器动量清零,数据游标重置,语料还少了 0.42B token。

所有数字来自单一种子,0.81% 的对照优势不是置信区间。模型只覆盖英语。加速只测到训练过的 2048,而且只测生成、不含 prefilling。WinoGrande 贴随机线,五任务均分有一项在充数。

术语

原文与代码

相关论文

全部论文解读