如何用 Colibrì 的冻结语料草稿(COLI_DRAFT_CORPUS)加速重复问答解码?
【免费下载链接】colibriRun frontier MoE models on hardware you already own — pure C, zero deps, experts streamed from disk. Tiny engine, immense model. 🐦项目地址: https://gitcode.com/GitHub_Trending/colibri3/colibri
如果你的 Colibrì 部署反复回答同一批问题——比如基准回放、回归测试、或者一个只处理固定题库的问答服务——那么大部分生成内容其实早已存在于历史输出里。COLI_DRAFT_CORPUS就是为此设计的:把某次运行的生成 token id 冻结成一个语料文件,之后每个解码步引擎都会从该语料里检索与当前上下文后缀匹配的一整段续文作为推测草稿,进入引擎原有的 verify 批量验证。它默认关闭、纯 opt-in,不设变量时解码行为完全不变。
它解决什么问题,能快多少
Colibrì 主引擎(c/colibri.c)本来就有 n-gram 草稿:拿当前序列的末两个 token 去同序列中找更早的位置来提议续文。冻结语料把它推广到一个外部文件:引擎加载历史运行的 token id,每步提议"当前上下文最长后缀"(后缀长度 8 递减到 3,取语料中最近一次出现)之后跟随的续文。MTP 每次 forward 只提议一个 token,语料命中则一次提议一整段;有提议时语料源优先于 MTP,MTP 只填补语料未命中的空档。
docs/corpus-draft.md 给出的实测(GLM-5.2 int4、96-token 贪心解码、回放语料中已有生成的 prompt,均为文档测量值):
| 主机 | 基线(MTP) | 加语料草稿 |
|---|---|---|
| H200,专家全常驻 | 1.78 tok/forward,3.69 tok/s | 6.00 tok/forward,4.52 tok/s(+22%),90% 接受率 |
| CPU(24C Xeon,120 GB pin) | 1.76 tok/forward,0.82 tok/s | 7.92 tok/forward,1.00 tok/s(+22%),100% 接受率 |
注意这两个数字是最好情况,不是普遍加速:forward 少了 3–4 倍,墙钟只快约 22%。在 MoE 里 verify batch 的每一行都会激活各自的专家,推测只能摊销 dense 路径、attention 和每次 forward 的固定开销,摊不掉专家计算本身。所以文档的结论是:把 forward 次数当作被优化的量,墙钟收益要单独测量,别拿倍数直接折算。
什么时候有用,什么时候没用
- 有用:基准回放、回归 harness、反复回答相同问题的负载——几乎每一步都有长后缀可匹配。
- 基本没用:真正新颖的文本。语料提不出东西,草稿回落到 MTP/n-gram,收益趋近于零(查询本身便宜但不是免费的)。回答新问题的通用聊天助手是收益最低的场景,这正是它默认关闭的原因。
- 语料近邻的风险:与语料无关的 prompt 完全不花成本(后缀匹配找不到东西,源保持休眠,实测 forward 次数与无语料运行相同)。真正的开销来自语料"近邻区"——前缀接近但不完全相同的 prompt 会触发虚假匹配。为此源内置了暂停保护:在 24 条提议的窗口内接受率低于
COLI_CORPUS_MINACC(默认 50%)时,源暂停 256 个 token 后重新武装。50% 是实测盈亏线(90% 接受率给 +22%,19% 给 −25%)。
第一步:冻结一份语料
用TOKENS=1跑一次目标 prompt,它会把生成的 token id 以[TOKENS] N generated: ...的形式 dump 到 stderr,再用sed抽出数字部分写入语料文件(以下命令来自 docs/corpus-draft.md,"..."换成你的实际 prompt):
# 1. 冻结一次运行的输出 id(TOKENS=1 已会把 id 打到 stderr) TOKENS=1 COLI_TEMP=0 ./coli run --ngen 96 "..." 2>&1 | sed -n 's/.*\[TOKENS\][0-9 ]*generated://p' > corpus.txtCOLI_TEMP=0表示贪心/argmax、确定性解码(见 docs/ENVIRONMENT.md),保证冻结下来的 id 可复现。语料文件格式是空白分隔的 token id,-1分隔不同的 span,提议永远不会跨越分隔符。
第二步:在后续运行中启用语料草稿
# 2. 后续运行从语料提草稿 COLI_DRAFT_CORPUS=corpus.txt COLI_CORPUS_K=8 COLI_TEMP=0 ./coli run --ngen 96 "..."涉及三个环境变量(均见 docs/ENVIRONMENT.md 的 "Advanced / experimental / debug" 一节):
COLI_DRAFT_CORPUS=<file>— 冻结 token id 文件路径。未设置或文件不可读 = 源关闭(不可读时 stderr 会打印[CORPUS] cannot open <path>,成功加载时打印[CORPUS] <N> ids from <path> (draft depth <k>))。COLI_CORPUS_K=n— 提议深度,默认 8,上限 48(受 spec_decode 的 batch 尺寸限制)。更深的提议会抬高 forward 倍率和每次 forward 的开销;8 是在 GLM-5.2 上实测最好的折中。COLI_CORPUS_MINACC=pct— 暂停阈值,默认 50,即上文所述的接受率保护线。
验证结果
运行结束时引擎在统计段打印一行(仅当有提议发生时):
corpus drafts: NN% acceptance (a/b proposed from N frozen ids)b是提出的 token 数、a是被接受的数、N是语料冻结 id 总数(对应 c/colibri.c 中的统计输出)。同时对比统计行里的speculation: X.XX tokens/forward:语料命中时这个比值应明显高于 MTP 基线。
无损性有两条文档给出的独立核查:
- CPU 路径下,深度 8、100% 接受率的 96-token 生成与关闭该源的同参数生成字节级相同;语料源只提议、不约束采样,verify 循环只接受模型自己本会产出的 token。
- 用
TOKENS=1分别跑开/关语料的两遍,比较 stderr 里[TOKENS]行的 id 序列是否一致,是最直接的 A/B 手段(TOKENS本身在 ENVIRONMENT.md 里就被标注为 "dumps generated token ids to stderr for A/B comparison")。
限制与已知问题
- CUDA 路径不保证逐位一致:长段连续接受的草稿在 CUDA 上可能与非批处理路径在单个 near-tie token 上分叉(文档实测 96 个 token 中第 85 位 1 个 token 不同,前 84 个相同);同一语料 GPU 接受率 90%、CPU 100% 的差距即由此而来。CPU 路径是字节精确的。
- 这是一个相关的未关闭 bug:CUDA 上
S>=8的投机 verify batch 会在 near-tie token 上偏离非批处理路径(上游 issue #689,属于 verify 路径而非本语料源)。语料命中率高时最容易触发它。若你的负载对 CUDA 上的逐 token 复现有硬要求,这一点需要在启用前评估。 - 语料文件会整份读进内存(引擎按 64K id 起容量、倍增扩容),超大语料的加载开销在文档中未量化,冻结的 id 规模建议先从小语料试起,观察
corpus drafts行的接受率再决定。
如果接受率长期贴地(远低于COLI_CORPUS_MINACC),说明当前工作负载与语料相关性不够,直接去掉COLI_DRAFT_CORPUS回到默认解码即可——未设置该变量时,解码路径与关闭时完全一致。
【免费下载链接】colibriRun frontier MoE models on hardware you already own — pure C, zero deps, experts streamed from disk. Tiny engine, immense model. 🐦项目地址: https://gitcode.com/GitHub_Trending/colibri3/colibri
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考