你攒了好久的算力,终于跑起了 Kimi K2.6——模型吐第一个字却等了快十秒。显存占满不说,多问两句就开始排队,你盯着命令行里 1.2 token/s 的速度,感觉自己像个在高速公路上开三轮车的人。
这不是你的机器不行,是你的推理框架还在用“一人一车”的古老调度方式。今天我们来聊聊 vLLM 这把扳手,怎么把 Kimi K2.6 从“单车道”搬到“立体交通网”。
为什么默认跑法吃掉你所有显存
当你用 Hugging Face 的 transformers 直接 .generate() 时,推理引擎会提前给每个请求预留一大块连续显存,就像电影院提前给你划好一整排座位,哪怕你只坐一个角落。一个请求占一排,来了第二个请求,没有整排空位就直接“满座”。
Kimi K2.6 是 MoE 架构(混合专家,每层只激活部分子模型),参数总量可能破千亿,但它每次推理激活的参数量其实小得多。可常规框架不管这些,照样给每个序列分配大块静态缓存,结果就是:显存里塞满了预留的空气,真正干活的空间没多少。
这就是 KV 缓存碎片化 问题。
vLLM 的解法:PagedAttention 就像图书馆借书登记
vLLM 的核心武器叫 PagedAttention——它不是给每个请求画一整块领地,而是把 KV 缓存(模型推理时的“草稿纸”,记录已生成的上下文信息)切成许多大小固定的“页”,像图书馆管理散装借书卡。
每个新请求进来,vLLM 只分配刚刚够用的几页,不够再追加,哪里有空位就填哪里。这样显存利用率能从 30% 左右提到接近 90%,因为碎片被压缩到零。
结果:相同显存下,vLLM 能同时服务 10~20 倍于传统方法的并发请求,单请求延迟反而更低。而且 vLLM 还支持 连续批处理——请求 A 生成长文本时,新来的请求 B 可以挤进同一批推理,不用等 A 结束。这就像公交车中途还在上客,不用非得等下一班。
这对 Kimi K2.6 这类体量的模型致命重要:你不想等一个回答花掉一杯咖啡的时间。
方案对比:Ollama vs vLLM
在你动手之前,可能想过用 Ollama(0.24.0)直接 ollama run kimi-k2.6。对个人体验来说,Ollama 确实省心,但它目前的调度粒度还没到显存页级别,高并发下吞吐量会明显下降。
| 特性 | Ollama(Kimi K2.6) | vLLM(0.21.0) |
|---|---|---|
| 安装难度 | 一键安装,几乎零配置 | 需手动配置,有一定门槛 |
| 并发吞吐 | 适合单用户,多请求易排队 | 高并发下吞吐量领先一个数量级 |
| 显存效率 | 常规预留,碎片多 | PagedAttention,利用率 ~90% |
| 适用于 | 本地玩赏、单次对话 | 生产级 API 服务、多用户 |
如果你是给自己用,偶尔问一问,Ollama 足够。但如果你想把 Kimi K2.6 变成一个面向同事或用户的 API 服务,vLLM 是难以绕开的刚需。
三步部署 vLLM + Kimi K2.6
前提:一台带 NVIDIA GPU 的 Linux 服务器,CUDA 12.1 以上,Python 3.10+。推荐至少双卡(如 2×A100),单卡跑 Kimi K2.6 大概率会 OOM。
1. 安装 vLLM
pip install vllm==0.21.0
# 验证安装,看版本号
python -c "import vllm; print(vllm.__version__)"
如果你跟我一样在容器里折腾,记得提前装好 nvidia-container-toolkit,不然 CUDA 根本用不上。
2. 获取 Kimi K2.6 权重
模型权重可以先从官方渠道下载到本地路径 /models/kimi-k2.6。因为模型体积巨大(几百 GB),建议用高速 SSD 存放,否则模型加载时会卡到你怀疑人生。
注意:权重路径结构要保留原样,别随便改文件夹名,否则 vLLM 找不到配置文件。
3. 启动 OpenAI 兼容服务
vLLM 自带一个兼容 OpenAI API 的服务端,可以直接用作 Drop-in 替代。
python -m vllm.entrypoints.openai.api_server \
--model /models/kimi-k2.6 \
--tensor-parallel-size 4 \
--dtype auto \
--max-model-len 8192 \
--gpu-memory-utilization 0.92 \
--port 8000
参数解释(非程序员友好版):
– --tensor-parallel-size 4:把模型切成 4 片,分别放在 4 张 GPU 上并行计算。你有多少张卡就写多少,但需是 2 的倍数。
– --dtype auto:让 vLLM 自己选最优数据类型,免去你纠结 float16 还是 bfloat16。
– --max-model-len 8192:单个请求上下文窗口上限,过长会爆显存,可以按需减小。
– --gpu-memory-utilization 0.92:显存用满 92%,预留一点给系统,避免 OOM。
如果只有 2 张 GPU,tensor-parallel-size 2,同时把 max-model-len 降到 4096,否则显存压力大。模型如果支持量化(如 AWQ),可以加上 --quantization awq 进一步压缩——量化就像把高清图压成 JPG,肉眼几乎看不出差别,但文件小了很多。
4. 发送第一条测试请求
curl http://localhost:8000/v1/chat/completions \
-H "Content-Type: application/json" \
-d '{
"model": "/models/kimi-k2.6",
"messages": [
{"role": "user", "content": "用一句话解释什么是递归"}
],
"temperature": 0.7,
"max_tokens": 100
}'
如果返回 200 且带出回答,你的 Kimi K2.6 服务就上线了。这个接口和 OpenAI 格式一模一样,任何支持自定义 API 端点的前端(如 Open WebUI 0.9.5)都能直连。
这对你意味着什么
过去跑一个千亿参数模型对外服务,最少需要高级运维团队来调显存、拼并发。vLLM 把这个门槛打到了“一个熟悉命令行的工程师,半天内搭起生产级服务”的程度。成本直接下探:你可以在云上租 4 张 A100 Spot 实例,用 vLLM 撑起一个内部使用的 Kimi 助手,而不用咬牙包年一台八卡机。
局限也得说清楚:vLLM 的控制面几乎全是命令行,没有图形界面,报错信息有时像天书;模型首次加载要对权重做一次转换,耗时可能十几分钟;不是所有小众模型都支持得无缝,像 Kimi K2.6 这类新模型偶尔需要你去 GitHub issue 里找一次补丁。
但如果你需要的是“效率”,这些弯路值得走。
下次再看到 Kimi K2.6 生成第一个 token 前那短暂的静止,也许你会想起——不是模型慢,是你的调度引擎还活在单线程时代。
