行业动态
wechat ·
@极客之家
离谱!8G 内存把 2.78 万亿参数的 Kimi K3 跑起来了
未提供
正文
上周在 GitHub 上看到一个项目,叫 kimi-k3-in-c。开发者叫 Fareed Khan,他用纯 C 语言给 Kimi K3 写了一个推理引擎,不要显卡,也不依赖 PyTorch 这类深度学习框架,8GB 内存的电脑就能把 2.78 万亿参数的 Kimi K3 完整跑一遍。
Kimi K3 的权重文件有 1.56TB,这种规模的模型一般都是跑在服务器集群上的,8GB 内存就是一台普通家用电脑的配置。我把这个项目的 README 和测试数据从头看完了,这篇文章给大家说说它是怎么回事。
8G 内存是怎么回事
我看到不少文章的标题写"8GB 内存跑 2.78 万亿参数",这话没错,但容易理解偏。
准确的说法是这样的:模型文件还是 1.56TB,放在硬盘上,一个字节都没少。真正压下来的是运行时必须占用的内存,这个项目实测的内存峰值是 8.24GB。
整个引擎编译出来只有 176KB,我手机里随便一张照片都比它大,但就这么个东西,读得动 1.56TB 的模型文件。
官方实测数据
它是怎么做到的
我研究了一下,思路说起来不复杂:模型的大部分参数平时不放进内存,要用的时候才从硬盘读进来。
Kimi K3 是一个混合专家模型,一共 93 层,除了第一层,每层有 896 个专家,可以理解成 896 组负责不同内容的参数。模型每生成一个字,每层只用到其中的 16 组,剩下 880 组在那一步根本用不上。
用不上的就不用进内存,算下来,每生成一个字真正参与计算的参数大概 1040 亿个,只占总量的 3.7%。其余 96.3% 平时就存在硬盘上,哪一步用到了再读进来。
每一层只用到 16 个专家
专家之外还有一块绕不开的部分,大概 113GB,包括每层都要经过的注意力结构和输入输出层,作者管这块叫主干。以前的做法是把主干整个塞进内存,这个项目把它重新打包成一个 109GB 的大文件,每层放在固定的位置上。内存够,就多放几层在内存里,内存不够,就一层一层从硬盘现读。
另外,占模型大头的专家权重,发布出来的时候就是用很紧凑的格式存的,一个参数只占半个字节多一点。一般的做法是先解压成浮点数再算,这个项目直接在压缩格式上算,连解压都省了。
这几件事加起来,内存门槛就从 5.56TB 降到了 8.24GB。
内存和速度是两回事
这个项目测了 12 档内存配置,从 8GB 一直到 224GB。
12 档跑出来的内容完全一样,一个字都不差。区别只有速度:8GB 那档生成一个 token 要 32.69 秒,224GB 那档要 19.21 秒。token 可以粗略理解成模型每次输出的一小段文字,可能是一个词,也可能是一个字。
两个数字放在一起看:内存翻了 28 倍,速度只快了 1.7 倍。这说明真正拖后腿的是硬盘,内存大小和 CPU 性能反而不是主要问题。我算了一下,8GB 配置下,每生成一个 token 要从硬盘读大约 135GB 的数据,所以速度快慢基本取决于硬盘。最好用一块快一点的 NVMe 固态,机械硬盘基本不用考虑了。
12 档内存的实测数据
README 里还有一个反常识的发现,内存紧张的时候,专门留一块空间缓存刚用过的专家,几乎不能提速,因为模型每一步用到的专家都不太一样,刚缓存好的下一步就用不上了。真想提速的话,内存要优先留给那个每步都绕不开的 109GB 主干。作者实测过,同样 128GB 的内存预算,这样分配能快 1.69 倍。
这个项目还有一点做得不错,每一档测试的原始数据都放在仓库里,谁都可以自己去核对。
我自己跑了一遍
我自己实际装了一遍,过程记在这里,给也想试试的朋友做个参考。
有个设计我觉得很实用:不下载模型也能先验证代码对不对。
仓库克隆下来大概 45MB,编译只要几秒钟,一共 7 个 C 文件。然后跑一句 make test,它会用一个 13 层的小模型把整套计算流程走一遍,跟 PyTorch 的参考实现逐个数字对比,全部对上会打印一行"ENGINE MATCHES THE REFERENCE EXACTLY"。
整个过程不需要模型文件,不需要网络,连 Python 都不用,一分来钟完事,毕竟 1.56TB 的下载,谁也不想下了一天一夜才发现引擎有问题。
git clone https://github.com/FareedKhan-dev/kimi-k3-in-c.git
cd kimi-k3-in-c
make -j
make test
验证过了再决定要不要下模型,模型在 Hugging Face 上,下载脚本支持断点续传,下完会自动校验每个分片的大小,哪个分片坏了只重下那一个,不用整个重来。
下完之后还有一步,把主干打包成那个 109GB 的大文件,四分钟左右,然后选一个内存档位就能跑了。我用的是 laptop 档:
./bin/k3 ~/k3model --trunk ~/k3trunk --preset laptop \
--tok ~/k3model --prompt "The capital of France is" --gen 8 --incremental
它一个词一个词往外输出,最后给出了"Paris"。8 个词,等了四分多钟,内存占用最高 8.24GB。
引擎的整体结构
还有几个地方要注意,硬盘至少要腾出 1.7TB,模型本体 1.56TB,加上打包后的主干 109GB,最好放在本地的高速固态上,网络存储会慢很多。
想输入中文的话,别把中文直接写在命令里,shell 会把编码搞乱,把提示词存成文本文件,用 --prompt-file 读进去就正常了。
生成内容长一点的话,记得带上 --incremental,不然每生成一个新词,前面所有内容都要重算一遍。如果不想自己算该用哪档配置,它带了一个检查脚本,跑一下会量你的内存和硬盘速度,直接告诉你用哪档。
什么人适合玩,什么人不适合
先把丑话说前面,如果你想本地部署一个 Kimi K3 日常聊天,这个项目不适合你。生成一个词等半分钟,一句话等好几分钟,这个体验没法用。而且它是基座模型,没有聊天模板,你问它问题,它是接着你的话往后写,并不是在回答你。图片理解也没有,这些功能都还没实现。
但有两种情况,我觉得它挺值得花时间的。
一种是自己写代码、想看看不隔着框架的大模型长什么样的人。 这个仓库一共 7 个 C 文件,从读盘到计算每一步都摆在明面上,顺着源码能一路看到底。平时接触到的大模型实现,外面都包着厚厚一层框架,这种能直接看到最下面的机会不多。
另一种是手头有机器、又存得下 1.7TB 数据的人,可以装一个跑跑看。 速度慢是慢,但看着 2.78 万亿参数在自己电脑上正常工作,还是挺有意思的一件事。顺带说一句,作者的测试机器上其实插着四张显卡,全程闲置,真正干活的只有一颗 CPU 和一块固态硬盘。
最后说两句
这个项目对我个人来说没什么实际用途,速度慢,功能也不全,日常聊天我还是用官方的产品,但它的价值不在这。
以前大家默认一件事:模型太大,内存装不下,那就跑不了。这个项目说明这个默认是可以打破的。模型放在硬盘上,用多少读多少,慢一点,但是能完整跑完,结果一点不差。而且它不是跑通就完了,每一步花了多少内存、读了多少数据、瓶颈在哪,全都量了出来。
以后再讨论个人电脑能不能跑大模型,至少有一个真实的参照摆在前面。
开源地址
https://github.com/FareedKhan-dev/kimi-k3-in-c