vllm与llama.cpp哪个性能好

模型与算力

给自建推理服务的工程师讲清 vLLM 和 llama.cpp 性能差异从哪来、在不同硬件和负载下各测什么、怎么按自己的场景做对比。

你可能已经跑通了 vLLM 或 llama.cpp,却发现两个人报的性能数字差好几倍——一个说吞吐上百,一个说单机就够用。问题通常不在框架本身,而在硬件、量化格式、并发数和上下文长度这四个变量没对齐。这篇不给你一个「谁更快」的结论,而是给一套可复现的对比方法:先明确你要优化的是首 token 延迟、单路输出速度还是总吞吐,再按硬件档位选择测量项,最后用同一份权重和同一组请求压出可比的数字。

你可能已经跑通了 vLLM 或 llama.cpp,却发现两个人报的性能数字差好几倍——一个说单机吞吐够用,一个说批量任务必须上调度框架。先别急着下结论说谁更快,大多数时候问题不在框架本身,而在硬件、量化格式、并发数和上下文长度这四个变量根本没对齐。对比之前先把这四个变量摆平,数字才有意义。

这篇不给你一个「谁更快」的固定答案,而是给一套能自己跑一遍的对比方法:先想清楚你要优化的是首 token 延迟、单路输出速度还是总吞吐,再按硬件档位挑测量项,最后用同一份权重和同一组请求压出可比的数字。下面按这个顺序讲。

为什么同一个模型,两个人的性能数字能差几倍

性能差异基本由四个主变量决定,任何一个没对齐,两个数字就没法放一起看。第一是硬件,消费卡、数据中心卡、统一内存设备、纯 CPU,四类机器上的瓶颈完全不是一回事;第二是量化格式,GGUF 和 safetensors 加 AWQ/GPTQ 走的根本不是同一条计算路径;第三是并发数,单请求和批量请求的曲线形状完全不同;第四是上下文长度,长上下文下 KV 缓存的压力会盖过权重本身。

  • 硬件档位:显存容量与带宽决定了模型能不能完整驻留,驻留与否是数量级差别
  • 量化格式:同一模型不同精度,权重体积、计算路径、质量损失都不同,不能混着比
  • 并发数:单路快不代表批量快,批量快也不代表单路延迟低
  • 上下文长度:短提示词测出来的吞吐,放到长上下文场景往往不成立

还有一个容易被忽略的点:vLLM 从设计上就是面向多并发批处理做调度的,llama.cpp 起家于单机单路和低资源设备,两者优化的目标函数本来就不一样。你拿 vLLM 的批量吞吐去比 llama.cpp 的单路延迟,等于让短跑选手和马拉松选手比同一件事,结论没有价值。所以第一步是先问自己:我要压的到底是延迟还是吞吐?问题问错了,后面测什么都白搭。

两条技术路线的差别:调度思路决定性能天花板

分页式 KV 缓存
把显存按固定大小的块分配,不同请求的缓存不再要求连续,碎片少了、浪费少了
连续批处理
新请求可以插进正在执行的批次里,不用等整批跑完,并发上来后吞吐上升明显
单路低延迟
请求排队和批处理开销小,一个请求进来就能开始算,首 token 时间通常更短
异构硬件覆盖
同一套代码能在 CPU、核显、独显、统一内存设备上跑起来,部署面更宽

vLLM 的核心是分页式 KV 缓存加连续批处理,显存按块分配,新请求能插进正在跑的批次,所以并发拉高之后总吞吐上升很快。代价是调度本身有开销,单请求场景下这个开销不一定划算。llama.cpp 反过来,它把权重和 KV 缓存尽量塞进有限的显存或内存里,单路延迟低、启动成本小,在显存紧张或只有 CPU、统一内存的机器上更实际。

多卡张量并行、多机扩展这类能力,vLLM 的做法更成熟;llama.cpp 的优势在端侧覆盖和部署简单。注意,如果窗口大小或并发规模变了,两边的相对位置会翻转,别把它们当成一条直线上的两个点。想知道两类路线在算子支持上的差异,可以到 /ai-dict/category/tech 翻术语条目对照。

按硬件分档:你的机器该重点看哪一项

不同硬件档位下,值得盯的指标不一样,挑错了指标等于测了个没用的数。下面按几类常见机器给判断标准,具体每档显存容量和卡数怎么对应你的模型规模,到 /compute/sizing 和 /models/deploy 按自己的参数量和精度算一遍。

硬件档位优先看的指标判断标准
消费级单卡,显存紧张单路输出速度、能否完整驻留量化档位的影响通常比框架选择更大
数据中心卡或多卡并发吞吐、长上下文显存利用率批处理调度能力会在这里被放大
统一内存设备内存带宽、量化后能否放下单路可用性比峰值吞吐更重要
纯 CPU 或低端核显能否跑起来、单路延迟先确认量化档位,再谈性能优化

数据中心卡场景下,别只测单请求。多卡张量并行开起来之后,通信开销会吃掉一部分收益,这时候要看的是并发扩容曲线,而不是单点峰值。统一内存设备是个例外:内存带宽是硬上限,加并发不会让带宽变多,所以关注点应该放在「能不能稳定跑起来、会不会爆内存」上。

要测什么指标:别只盯一个 token/s

token/s 是个被用烂了的指标,它不区分首 token 时间、单路速度和总吞吐,三个数里任何一个都能让你得出完全相反的结论。工程上至少要记三组数,再加一条并发扩容曲线,才算把性能摸清楚。

  • 首 token 延迟:决定交互式应用的手感,长提示词下这个差距最明显
  • 单路输出速度:决定单用户等待时间,量化格式和显存带宽是主导因素
  • 总吞吐:每秒处理的总 token 数,决定批量任务和多人共用的成本,只看它会掩盖延迟恶化
  • 并发扩容曲线:并发从低往上加,吞吐在哪开始持平、延迟在哪开始明显掉,这条拐点比任何单点数字都有用
  • 显存占用峰值:它决定你下一档并发能不能再加,漏了这个数扩容就会翻车

测之前先量一遍链路基线。用 /tools/speed-test 跑一下网络和接口延迟,免得把网关排队、代理转发的耗时算到框架头上。做中转站或聚合服务的团队尤其容易踩这个坑,框架本身没问题,锅在链路。

可复现的对比步骤:照着做一遍就有自己的数字

  1. 固定权重与量化档位两个框架尽量用等价的精度,量化差异可以到 /ai-dict/category/tech 查各格式说明。精度不一致后面全白测
  2. 固定输入输出长度用同一批请求,提示词和生成长度写死;先跑单并发拿延迟基线,再按倍数往上加并发
  3. 记录三组数加峰值首 token 时间、单路 token/s、总吞吐三组都记,同时记下显存占用峰值,缺一项就没法解释异常
  4. 每档跑两轮第一轮当预热丢掉,第二轮才取数;抖动大的配置标注出来,别当稳定结果用
  5. 整理成表对比 SLA把结果和自己的服务等级目标对比,而不是和网上的数字对比,后者参考价值有限

这套流程跑下来,你手里会有一张自己的表:每档并发对应的三项指标加显存峰值。这张表比任何别人的结论都可靠,因为它是你自己机器、你自己模型、你自己请求分布下的数字。想省事的话,可以先用 /tools/speed-test 粗测一轮,确认链路没问题再上正式压测。

结果怎么看:什么时候 vLLM 明显占优,什么时候不适用

多用户、长输出、并发持续的在线服务场景,vLLM 的批处理调度优势通常会被放大,因为它的设计目标就是这个。反过来,单用户交互、显存吃紧、端侧或异构硬件场景,llama.cpp 的体积和部署成本优势更实际,强行上调度框架反而多一层开销。

你的场景特征更可能占优的一方原因
多人同时用、输出较长vLLM新请求可插入运行中的批次,并发越高吞吐越明显
单人交互、要求快响应llama.cpp单路调度开销小,首 token 通常更短
显存小、设备杂llama.cpp量化档位多,能在低资源设备上跑起来
多卡、要横向扩vLLM张量并行和多实例扩展的做法更成熟

不适用的情况也得说清楚。第一,模型权重或某些算子不被某个框架支持时,性能对比没有意义,先解决能不能跑的问题,再谈谁快。第二,量化档位降到很低时,输出质量损失可能盖过性能差异,快但答案变差等于没意义。第三,如果你的服务其实是低频调用,瓶颈在冷启动和模型加载时间上,推理速度根本不是主要矛盾。相关价目和规格口径可以到 /official-api 与 /compute/gpus 对照。

常见坑:这些做法会让对比结果失真

  • 两边用了不同量化精度,或一边开了张量并行一边没开,结论直接作废
  • 只测一轮、只测一个并发,把峰值当常态报出去
  • 先后跑两个框架但没清缓存、没留足显存,前一个进程的影响会带进后一个
  • 用短提示词测,却要上线长上下文场景,KV 缓存压力完全不是一回事
  • 忽略服务包装层:上层工具会再叠一层调度,测出来不是纯框架表现

最后一个坑值得展开说:很多团队用的其实是包装过 llama.cpp 的上层工具,那测出来的数字里包含了包装层的排队和调度开销,不能直接拿去和裸 vLLM 比。同理,用网关或中转层做转发时,链路延迟也会被算进去。做对比前先确认你测的是哪一层,把这个写进报告的前提里。

下一步把你自己机器上的三组指标和并发拐点记下来,再和站内整理的中转与接口基准对照,就能判断问题出在框架、链路还是量化档位上。

常见问题

同样一张卡、同一个模型,为什么别人说 vLLM 快好几倍?

大概率是并发数不同。单路请求时两者差距不大,甚至 llama.cpp 更低延迟;并发上去后,vLLM 的连续批处理会把多路请求压进同一批计算,吞吐优势才出来。如果你想比的是一对一速度,先确认对方测的是单路还是批量,再对比才有意义。

显存不够的机器上还有必要试 vLLM 吗?

先算一下模型加 KV 缓存能不能放下。放不下时 vLLM 常见做法是降量化或做多卡切分,而 llama.cpp 本身就更擅长在显存紧张时把部分层放到内存或统一内存里。可以先用 /models/deploy 估一遍显存,再决定值不值得折腾。

量化档位不同还能对比两个框架的性能吗?

不建议。量化方式直接改变显存带宽占用和计算路径,GGUF 的不同档位和 safetensors 配 AWQ/GPTQ 本来就不是同一条实现。要对比框架就固定精度;要对比量化档位,就固定框架。混着比出来的数字没法归因。

只跑本地个人助手,需要关心吞吐吗?

通常不用。单用户场景真正影响体验的是首 token 延迟和单路输出速度,以及模型是否常驻显存。吞吐指标在多人共用或批量离线任务时才有意义。你要盯的是切换模型或提问时的等待时间,不是每秒能出多少 token。

测出来结果和官方文档里的数字差很远,是哪里错了?

多数是硬件、驱动版本、模型精度和测试参数四者之一不一致。官方的性能页通常标注了具体的卡型、批大小和序列长度,先对齐这几项;对不齐就以你自己的机器为准,把参数一起记下来,下次换配置时才有可比基线。

本文依据各平台公开文档与官方公告整理,只做中文归纳;具体做法、参数与限制以官方文档为准。