摘要:同一个大模型在本地部署后为何表现明显变化?量化格式、KV Cache精度、Attention Backend、底层Kernel与推理框架共同决定模型的实际运行效果。

本地部署大模型的人,大多碰到过一种很难解释的落差。
模型排行榜看起来很强,官方在线版本也很稳。把权重下载回来,显存不够,做个 4bit 量化,再套上本地推理框架,短对话还不错。等它开始读长代码、跑 Agent、连续调用工具,表现忽然就不对了:前面记得的东西后面忘了,函数参数开始乱填,JSON 偶尔缺括号,Shell 命令越来越怪,同一个任务线上 API 能完成,本地版本却经常走偏。
最方便的解释是“量化以后模型变笨了”。
可这个说法太粗。
8 月,Level1Techs 上一组针对本地推理的实验把问题往下挖了几层。作者固定模型和工作负载,分别改变 Attention Backend、KV Cache 精度、权重量化和底层 Kernel,观察完整 logits 的变化。测试采用了一段从真实 Agent 工作流捕获的、接近 100K Token 的长上下文,其中包含多次工具调用和实际工作产物,比三五个短 Prompt 更接近本地 Agent 的日常负载。
结果很值得本地模型用户重新看一遍自己的部署栈:模型权重只是最终行为的一部分。推理框架、Attention 实现、CUDA Kernel、KV Cache、量化格式、Sampler 和硬件共同决定了你最后拿到的那个“模型”。
权重一样,为什么答案还能不一样
LLM 每生成一个 Token,都要计算词表中大量候选 Token 的 logits,然后经过 softmax、采样器等步骤选出下一步。
Level1Techs 的实验在同一套 BF16 权重上比较 FlashAttention 2、Flash Inference 和 Triton Attention。其他软硬件条件保持稳定,只替换 Attention Backend。前几千个 Token,各组对 top-1 Token 的判断基本一致;上下文继续增长以后,差异开始成簇出现。
作者还做了同一 Backend 的重复运行,结果可以 bit-for-bit 重现。由此可以排除采样随机性,差异来自不同矩阵乘加路径积累出的数值误差。
这件事以前很容易被忽略,因为我们习惯把大模型看成“一个权重文件”。
一个Token选错,在聊天里可能没事,在Agent里可能直接出事故
普通聊天容忍度很高。
“帮我总结这篇文章”,某个地方选了另一个近义词,大多数人根本感觉不到。
Agent 的输出经常带有离散、刚性的结构。
接口名必须完全正确;JSON 必须可解析;数据库字段不能拼错;网络设备端口号差一位就会访问另一台接口;Shell 命令少一个字符,执行结果就完全不同。
Level1Techs 给出的一个例子很典型。模型需要针对 Cisco 路由器上的 GigabitEthernet0/0/1.201 执行工具调用,某个 Attention Backend 的一次 Token Flip 把目标接口带到了错误位置,随后模型继续在错误上下文里推理,又连续执行了错误命令。
从概率分布角度看,最初只是一处很小的偏差。到了 Agent 行为层,它已经变成“操作错对象”。
这也是为什么以后评估本地 Agent,单看 MMLU、HellaSwag 或几个聊天问题远远不够。
更有价值的测试应该贴近工作负载:长上下文、真实 Tool Calling、结构化输出、代码修改、领域知识、连续几十步的任务完成率。一个模型在 8K 上下文里答题漂亮,无法证明它跑到 80K 时仍然保持相同稳定性。
最容易被低估的,是KV Cache
本地部署里,KV Cache 是显存大户。
Transformer 在生成新 Token 时,如果每次都把前面几万 Token 的 Attention 重新算一遍,成本会高得难以接受。推理框架会把历史 Token 对应的 Key 和 Value 保存下来,后续直接复用,这就是 KV Cache。
上下文越长,KV Cache 越大。
模型从 8K 扩到 64K、128K 以后,即使权重已经量化,KV Cache 仍可能迅速吃掉大量显存。因此很多推理引擎提供 FP8、INT8、INT4 等 KV Cache 量化选项。
看起来很合理:权重都能从 BF16 压到 4bit,Cache 为什么不能?
Level1Techs 做了一个很干净的对照实验:权重和 Activation 保持 BF16,Attention Backend 固定,只改变 KV Cache 精度。
结果在长上下文里逐步分化。BF16 正常完成工具调用,INT8 出现偏差后还能恢复,INT4 最终没有恢复,形成可重复的 Tool Calling 失败。
这类问题很隐蔽。

“4bit模型”这个说法的信息量其实很低
本地模型社区经常用 Q4、INT4、FP4 来描述模型,好像位宽相同,质量和速度就大致在同一档。
实际部署远比这个复杂。
Level1Techs 的实验同时比较 BF16、官方 FP8、W8A16 INT8、NVIDIA NVFP4、AWQ W4A16 等配置。虽然名字都围绕“几 bit”,执行路径却完全不同。
因此,“这个模型是 4bit”并不能回答最重要的问题。
同一个 27B 模型,换一套配置,确实可能表现得像两个不同产品。
Ollama、vLLM、SGLang选的其实是三种工作方式
ByteByteGo 8 月 22 日的一篇文章把 Ollama、vLLM 和 SGLang 放在一起比较。单看“谁更快”容易把问题说窄,这三个项目的重点原本就不一样。
Ollama 优先解决的是本地使用体验。
拉模型、管理 GGUF、启动 API、在笔记本或工作站上快速跑起来,它把很多繁琐步骤包掉了。对个人开发、原型验证和轻量服务来说,安装成本很低。
vLLM 从一开始就更关心服务器吞吐。
它的 Continuous Batching 会把新请求动态塞进正在运行的 Batch,不必等上一批请求全部结束再开始下一批。PagedAttention 则把 KV Cache 按页管理,降低显存碎片和浪费。面对大量并发用户时,GPU 利用率和吞吐能够显著提升。
SGLang 很适合另一种负载:大量请求拥有相同或相似的前缀。
Agent 正好如此。几十个 Agent 可能共享同一份 System Prompt、同一组 Tool Schema、同一个代码仓库背景;多轮对话里,前面绝大部分上下文也没有变化。SGLang 的 Prefix-aware Scheduler 和 RadixAttention 会尝试把这些公共前缀缓存起来,后续请求直接复用,少做大量重复 Prefill。
于是问题从“哪个框架跑分高”变成了“你的请求长什么样”。
单用户、本地体验优先,Ollama 很合适;做高并发 API 服务,vLLM 的调度能力更重要;长上下文、多轮 Agent、共享前缀很多,SGLang 值得认真测试。
tokens/s以后会越来越像一个不完整的指标
现在讨论本地大模型,最常见的截图还是:显存多少、每秒多少 Token。
这两个指标当然有用,却很容易诱导错误优化。
一个 Agent 以 180 tok/s 输出错误工具参数,不如 90 tok/s 稳定完成任务。一个 4bit KV Cache 能把并发翻倍,却让 60K 上下文之后的调用成功率下降,也未必给企业省钱。
对于生产环境,更值得统计的是一组组合指标:
TTFT,也就是首 Token 延迟;Prefill 吞吐;Decode 吞吐;并发能力;KV Cache 占用;Prefix Cache 命中率;长上下文精度;JSON/函数调用成功率;任务完成率;失败后重试次数;单位成功任务消耗的 GPU 时间。
最后那个指标尤其值得关注。
企业采购 GPU,最终看的是工作完成量和可靠性,Token 只是过程指标。
未来本地模型推理优化的目标,很可能会从“这张卡一分钟吐多少字”,逐渐变成“这张卡一小时能可靠完成多少个任务”。
所以,下次一个本地模型跑起来让你觉得“怎么比官方版本笨这么多”,先别急着删权重。
模型也许没有变。变的是它脚下整条推理流水线。
参考资料
- Level1Techs:Why your local LLM feels dumber than it is,2026-08
- ByteByteGo:EP223: Ollama vs vLLM vs SGLang,2026-08-22
- Horizon Daily:2026-08-23 技术资讯汇总