为什么你的本地大模型感觉比实际更笨
本文通过一系列技术实验,揭示本地部署大模型时,因硬件、软件和推理后端差异导致的输出偏差,解释了为何本地模型感觉不如官方基准聪明,并提供了衡量和改善的方法。
快速介绍我们都在论坛、聊天、Reddit、Discord、YouTube或其他地方听到过“哦!模型XYZ太棒了!zomgwtfbbq”,然后下载了它(或者更可能是它的某种量化版本),并说“呃……这太烂了!
”这篇文章将是一系列技术性较强的实验,旨在展示推理过程中特定实现风险的影响。我将使用“参考实现”一词来描述发布模型并提供第一方托管、发布原始基准声明的实验室。他们的硬件会与你的不同。他们的软件会与你的非常不同。
本文中的比较不会运行带有几个测试提示的2.58位gguf-in-ollama。我故意略过了整个新兴研究领域、大量的研究论文和文献综述,以便让读者更容易理解。不要挑剔我的过度简化,否则我会让你读那篇又长又难懂还带数学的版本。
你的本地实现很糟糕。但没关系,因为其他人的也一样。如今,运行LLM的每一个硬件和软件实例都略有不同,在某些情况下甚至差异很大。普通家庭实验室用户可能会混用多代GPU。这些芯片上的指令集各不相同。
这些指令集会以不同于任何其他人的方式实现和执行数学运算来计算你的下一个token,即使运行完全相同的权重也是如此。这就引出了第一个问题:你的特定设置有多糟糕?事实证明,有多种方法可以衡量这一点。
实用的方法很直接:运行标准基准测试,多种基准测试。terminal bench、HLE、SWE-bench、HELLAswag、MMLU等等,任你选择。只要确保它代表你的实际工作负载/用例。不要将温度调到零,粘贴3个测试提示,然后就说它好或坏。
零样本测试并不能很好地模拟大多数智能体任务。你需要长上下文工具调用和特定领域知识评估,来找出在与他人复制相同基准时,你的设置在哪里较弱。但纯粹的数学答案是我关注的起点,因为正如@wendell所说:数学就是数学!
“Logits”是模型对每个可能的下一个token的评分。它们被归一化为概率,通过配置的采样器,并由去分词器转换回文本,在解码过程中生成THE→NE→XT→TOK→EN。关于采样器设置的补充说明:HF上的模型卡通常明确指定你应该使用的采样器设置(和聊天模板)。
温度1.0、top-p 0.95等,因模型而异,所以请确保使用正确的设置。
顺便说一句,温度设置太低就是你的Qwen卡在循环中无法跳出THINK输出的原因。不客气,很高兴我能帮你解决这个问题。
当下一个token的概率变化足够大时,THE→NE→XT就变成了THE→NE→W→DAY……虽然这些微小变化可能没问题,但这很可能就是你内心深处感觉有些不对劲的开始。你们中的一些人可能听说过KLD或KL散度这个术语。
别担心,我不会让你做任何数学运算,也不会用一堆小数表格淹没你的大脑。但如果你想要简单版本:将输出的logits转换为概率分布,并测量该分布与所选基线的偏离程度。较低的KLD意味着更接近基线,而不是自动“更聪明”。
KLD也是方向性的,所以两个分布的顺序很重要。一个警告:不要被量化HF模型卡上低得离谱的KLD声明所迷惑。除非作者披露参考checkpoint、完整的运行时环境、评估文本、校准数据、上下文长度、采样位置、KL方向、任何词汇截断以及测量结果的聚合方式,否则无法解释该数字。
方法论与数字本身同样重要,而且很多人都会搞错。vllm到底在做什么?
现在,我们需要简要了解一下你的推理引擎上那堆庞大的软件在做什么,以理解其中一些分歧来源。这个过度简化的图表中的每一步都有组件,可以根据你的特定硬件/软件环境、模型、量化、张量形状等进行配置或更改。
我抓取的夜间版VLLM容器镜像中有734个(252个uv/pip Python)包。那是734个代码库,每个都有自己的bug和未记录的怪癖。你的特定实现穿过那堆代码的路径将是独特的。测试1:注意力后端的精度基准让我们从推理流程图的一部分开始。
在预填充(提示处理)期间,你的推理引擎会从几个注意力后端中选择。这会影响预填充的速度和精度,同时需要针对每个GPU系列/SM计算能力使用不同的CUDA内核。CUDA平台——CUDA编程指南。让我们测试它们并比较。
(我真的很抱歉,但我必须这么做……)我从Qwen3.6-27B的官方BF16 checkpoint开始,在RTX PRO 6000 Blackwell GPU上,张量并行度为1。KV缓存为BF16,没有权重/激活或KV缓存量化。
软件是固定的夜间版vllm构建。我使用了eager执行,禁用了CUDA图、前缀缓存和MTP,并使用2k token的分块预填充。Qwen3.6-27B是密集模型,不是MoE,但它仍然是混合模型。
64层以三个Gated DeltaNet/线性注意力层后跟一个全注意力层的模式重复。在本实验中,只有那16个全注意力层使用可选的注意力后端;Gated DeltaNet路径保持固定。
这里重放的工作负载是“Prompt 2”,一个从真实的Turnstone实验室工作流中捕获的约10万token上下文,包含多个工具调用和真实工作产品。选择它是为了模拟本地智能体实际做的事情,而不是合成的大海捞针测试。
也许更重要的是,它没有出现在当今任何基准或训练数据集中。没有人能为此进行基准测试,或校准他们的量化以适应它。对于此工作负载,vllm中有三个可用的全注意力后端:FlashAttention 2、Flash Inference和Triton Attention。
这是执行之间唯一的更改,硬件和软件堆栈的其余部分保持稳定。我还执行了同一后端跨GPU的可重复性控制。对于此图,我每32个提示token捕获BF16中的全词汇logits。随后在FP64中根据存储的logits计算KLD等分布比较。
Top-1一致性是指具有最高logit的token(贪婪argmax)是否相同。所有三个后端都根据相同的强制token历史进行评估。因此,“top-1翻转”意味着该后端在该位置会选择不同的贪婪下一个token。
我们没有让该选择改变剩余的历史。这保持了数学比较的可控性,但它没有显示无约束生成会分支多远,或者工具调用最终是否会失败……这将在测试2中展示;
D下图显示了导致token翻转的采样logits百分比:对于前几千个token,无论后端如何,模型的每次运行都同意下一个token是什么。然后在提示的后面部分,后端开始产生分歧。选择Triton作为基线,以简化即将到来的量化操作。
每个8k token窗口包含250个采样位置,每32个token一个探针。百分比是其他后端得分最高的token与Triton不同的探针比例。