@_avichawla: https://x.com/_avichawla/status/2077653695123378321
摘要
本文认为,vLLM及类似的服务框架由于设计限制,在单个GPU上运行多个小型AI模型时效率低下。它介绍了SIE开源推理引擎,作为同时服务多个模型以降低成本的一种解决方案。
查看缓存全文
缓存时间: 2026/07/16 12:16
为什么到2026年,正经的AI项目不能再依赖vLLM了
每增加一个新的Agent和每一次额外调用,推理账单都会水涨船高。因此在实际生产中,团队更倾向于将重复性步骤加载到小型任务专用模型上,以降低成本。
Karpathy 最近也在模型层面下了同样的赌注,他认为一个大约十亿参数的“认知核心”(从更大模型中蒸馏得到)就足以完成工作中的“思考”部分。
这个方向是对的,但仅仅使用SLM并不意味着省钱,因为这些模型仍然需要被部署和服务。而如何在不浪费底层GPU的情况下服务好这些模型,则是一个需要单独解决的问题。
今天,我们来深入理解为什么会出现这种情况,要真正良好地服务众多小模型需要什么,以及 SIE 开源推理引擎 如何端到端地解决这个问题。
开始吧!
传统AI流水线的工作流程
一个生产级的AI系统通常由一系列独立任务堆叠而成,每个任务都由最适合它的模型来处理。
例如,单个请求可能包含:
-
将文档或图片解析为干净的文本
-
将该文本嵌入成用于检索的向量
-
根据相关性对检索结果进行重排序
-
提取相关的特定字段、实体或标签
-
在将输出发送给用户之前,对照安全策略进行检查
直到最近,默认的本能仍然是使用你能找到的最大通用模型,让它尽可能多地承担这些工作,并为每一次调用支付前沿模型的费用。
这种本能现在正在逆转,转向使用为每个任务微调的小模型。由于大多数任务并不总是需要前沿的推理能力,这些小模型可以用极低的成本完成相同的步骤。
但团队常常忽略的陷阱是:更便宜的模型并不意味着更便宜的系统。
这是因为模型成本不仅仅取决于每次调用的收费,还取决于你为响应该调用而一直运行的硬件。
一个用多个小模型替换了一个大模型的流水线,现在需要服务多个模型,每个模型各自占用一个GPU。
为什么我们不把多个模型放在一个GPU上?
显而易见的反驳是:我们应该把它们都放在一张卡上。
这样做之所以有用,是因为没有GPU供应商会为你在其上完成的计算量收费。他们不计量FLOPs。
你租用的是整个GPU在一段挂钟时间内的使用权,无论这块卡是忙碌还是闲置,计时器都在走。
因此,你持有的每一个GPU都会为总账单增加一项:
这里 C 是每个GPU每秒的价格,T 是你持有它的时间。
四个模型在四张卡上,意味着总和中有四项。如果一张卡就能承载所有四个模型的流量,那么其中三项就消失了。工作内容没有任何改变,但账单却减少了75%。
这个论点在内存方面也站得住脚。一个小型嵌入模型、一个交叉编码器重排序器和一个实体提取器加起来只需要几个GB。
一张L4有24GB内存,所以它们可以轻松装下,硬件上没有任何障碍。
几乎没人这么做的原因是:从服务框架到驱动程序,每一层堆栈都是围绕“一个模型独占一个GPU”构建的。
vLLM 和 TEI 是两种常见的服务器。
- TEI 是 Hugging Face 的嵌入和重排序服务器,启动时需要指定模型ID。
来源:TEI 的 GitHub 仓库
来源:TEI 的 GitHub 仓库
- vLLM 的引擎也是围绕一个模型构建的。
因此,要将四个模型放在一张卡上,就需要在这张卡上运行四个独立的服务器进程。这两个工具中没有任何东西来协调这些进程,你必须自己来管理这项工作。
实际上,每个进程都会预先声明自己的内存,并且无法看到相邻进程。
vLLM 的 --gpu-memory-utilization 默认值为0.9。这个设置在启动时预分配该比例的视频内存,而不是根据需求动态调整。
vLLM 自己的文档说明这是一个“实例级别”的限制,会忽略同一GPU上的其他vLLM实例,并且运行两个实例意味着需要手动将每个实例的值设置为0.5。
因此,内存分割是一个在你手动计算的常量,在任何流量到达之前就确定了。
它必须覆盖每个模型的峰值,因为激活内存会随着批次大小和序列长度而增长。
四个最坏情况的切片钉在一张卡上,正是你试图逃避的过度配置,只不过现在它们被移动到了一个GPU内部。
即使你完美地规划了它们的大小,如果后来有两个模型同时达到峰值,它们也会拖垮整张卡。
例如,如果提取模型遇到了一个异常长的文档,请求的内存超出了其切片允许的范围,它不仅会自己失败,还会连累OCR、嵌入和重排序一起崩溃。
这就解释了为什么“一个模型一个GPU”从来不是硬件的需求,而是一条阻力最小的路径,贯穿了整个堆栈:每个工具都是为了很好地服务一个模型而构建的,没有一个是用来共享的。
共享需要一种不同类型的服务器。一台服务器容纳所有四个模型,而不是四台服务器各容纳一个。
-
它拥有整张卡的内存,因此无需手动分割。
-
它能看到每一个请求,因此可以决定哪个先运行。
-
它在需要时加载模型,在内存不足时卸载模型,这样没有被调用的模型就不会占用它不需要的内存。
通过并排运行四个服务器是无法实现这一点的。这需要一个完全不同的堆栈。
团队试图避免这种情况的三种方法
在这一点上,团队常有的一个反应是不再以天真的方式运行GPU。常见的有三种逃避路线,每一种都是将问题换成另一个问题。
第一种是托管API。 调用OpenAI或Cohere,完全不用考虑GPU。
-
这是起步的好方法,但随着规模扩大,问题迅速显现。
-
当工作变得常规时,账单会随着使用量线性增长。
-
而且你只能运行提供商托管的模型,因此你为自己的任务微调的模型通常无法部署在那里,而且每次调用你的提示词和文档都会离开你的环境。
第二种是无服务器GPU。 你部署自己的模型,只在运行时付费。
-
这从理论上解决了空闲时间的问题。
-
问题在于冷启动。一个已经缩到零的模型需要将数GB的权重拉入内存后才能响应,这会给第一个请求增加数秒的延迟,而搜索中间的重排序器不能花费数秒来唤醒。
-
为了避免这种情况,你需要保持实例的热度,这样你就又开始为空闲的GPU付费了,这恰恰是我们来这里要逃避的问题。
第三种方法对于成本和可控性来说实际上是正确的。 你在自己租用的GPU上自托管模型,数据留在你的环境中,账单是固定的每小时费率,而不是按token计费。
-
这是大多数严肃团队最终选择的路径。
-
那么你自托管,就需要使用标准的服务工具。而这就是基础设施问题变得具体的地方。下面我们来进一步了解这些工具的问题。
标准服务工具在多模型流水线中的问题
开发人员在这里使用的工具是为与你不同的工作而构建的,这体现在两个方面。
首先,每个工具服务于一种形状的模型。
-
vLLM 是为服务LLM而构建的。
-
TEI 是为服务嵌入和重排序模型而构建的。
-
两者都不做OCR、视觉或文档解析。
这本身并不是模型层面的差距。这些任务的模型都已经存在并且非常出色,例如用于文档的docling和PaddleOCR,用于视觉的SigLIP和Florence,用于提取的GLiNER。
缺失的是一个能运行所有这些模型的单一服务器。
因此,当Agent需要解析文档、嵌入、重排序和检查策略时,你需要vLLM负责一部分,TEI负责另一部分,以及某个别人写的FastAPI封装来完成剩下的部分。
这就给了你四个服务器 + 四个API + 四个部署,全部位于一个Agent背后。
现在,注意到这种设置对GPU做了什么:每个服务器都持有整张卡。
vLLM 在启动时会占用90%的GPU。TEI会抢走它的一部分。OCR封装也需要一些。
每一个都是基于自己拥有整张卡的假设编写的,没有一个会向其他工具归还内存,因为它们都不知道彼此的存在。
它们之间没有共享队列,也无法说明实时搜索比后台索引任务更重要。我们已经讨论了这种情况在一张卡上是什么样子,当进程来自四种不同的工具而不是同一工具的四个副本时,情况并不会好转。
你转向小模型是为了省钱。
但到目前为止的讨论证明,只有当你能够将多个小模型放在同一个GPU上时,这些节省才会显现。
标准工具无法实现这一点,因为它们强制一个模型一个服务器,一个服务器一张卡,这又把你推回了“一个模型一个GPU”的老路。
工具的碎片化重新制造了我们试图避免的浪费。
小型模型的服务堆栈应该是什么样的
让我们退一步,忽略具体工具,理解我们期望的理想工具应该做什么。
-
它应该运行Agent需要的每一种模型:嵌入、重排序、OCR、视觉、提取和生成,全部通过一个API。这是摆脱四个服务器、整合到一个服务器的唯一途径。
-
它应该填满GPU,而不是填充它。而这需要比一个好的调度器更多的东西,因为要将不同长度的请求打包到一个批次中而不浪费计算,引擎必须控制它所服务的每一种架构的批处理和注意力路径。
-
它应该根据流量的变化加载和驱逐模型,保持忙碌的模型加载,让空闲的模型移出,这样当没有请求时,模型就不会像冷的无服务器工作节点或填充的vLLM实例那样占用内存。
-
它应该直接提供包含路由、自动扩缩容、监控和GPU池的生产层。这一点很重要,因为像vLLM这样的裸运行时只是引擎。单独使用时,它无法跨副本分配负载,无法根据流量变化增减GPU,也无法在混合了廉价和大容量GPU卡的舰队中放置模型。如今,开发人员需要自己编写所有这些,这解释了为什么自托管比听起来更费劲。
-
添加一个新模型应该是一个配置更改,而不是一次重新部署。
所有这些都很困难,需要数月的工程时间,因为不同的模型系列底层运行方式不同。
-
BERT 和 Qwen 对位置和注意力的处理不同。
-
ColBERT 为每个token返回一个向量。
-
重排序器只返回一个分数,根本不返回向量。
构建一个能够容纳所有这些形状,并能将其中任何一个打包成完整批次的引擎,是至关重要的工作,这也是为什么这个解决方案尚未作为一个开源包存在的原因。
开源解决方案:Superlinked Inference Engine
所有这些问题的解决方案实际上已经在开源的 Superlinked 推理引擎(SIE) 中实现了:
它在你自己的云中作为一个集群运行,并且正是为了我们一直在描述的那种流水线而构建的:多个不同种类的小模型在共享GPU上连续运行。
它通过一个API(包含四个调用)运行每一种模型,因此文档解析、视觉、内容安全检查以及开放模型的生成都在同一个服务器上运行:
-
encode将文本或图像转换为向量 -
score根据查询对一组文档进行重排序(返回一个数字) -
extract从原始文档中提取结构化字段、实体或Markdown(返回文本跨度) -
generate在提示词上运行开放的LLM(返回文本和token用量) -
TEI 可以返回向量和相关性分数,但一个TEI进程恰好服务一个模型,因此嵌入加重排序已经意味着两个独立的部署。并且TEI不覆盖提取、OCR、视觉或生成,因此这些仍然需要各自的服务器。
-
一个单一的SIE集群可以在一个服务器中服务所有四种形状。
它没有浪费空间地打包这些请求。
来源:Superlinked 文档
来源:Superlinked 文档
-
即使在一个完整的批次内,也存在第二种浪费。请求长度各异,同时运行它们的简单方法是将较短的请求填充到与最长的请求相同,然后像处理真实数据一样处理填充。
-
SIE 根据计算成本而不是条目数量进行批处理。它将相似长度的请求分组,并且只填充到该批次中最长的项目,而不是全局最大值,因此几乎没有卡的时间用于填充。
-
一个关键区别在于批次形成的位置。标准堆栈首先将每个请求路由到一个工作节点,每个工作节点只对自己收到的流量切片进行批处理,因此队列运行不均匀,混合大小打包得很差。
-
SIE 反转了这个顺序。网关将所有工作发布到一个共享队列中,每个工作节点从该池中提取,并在接触GPU之前形成一个完整的批次。
它根据流量加载和驱逐模型:
-
当一个模型第一次被请求时,它会加载到GPU内存中,当内存不足时,最近最少使用的模型会被丢弃,这与浏览器缓存的概念相同。
-
这也正是对“预留但空闲”问题的具体回答。多个公开的vLLM问题报告指出,模型在加载时保留了大约80%的显卡内存,而嵌入期间的利用率却低于40%。
-
优化的加载和驱逐策略让你可以运行整个流水线中的多个模型。
它已经内置了生产层。
-
一个网关位于前面,将每个请求路由到一个工作节点,当出现突发流量时,它会接受请求并保持它,同时启动更多的工作节点。
-
工作节点在负载下自动扩容,在流量下降时缩至零,这样你就不会为空闲的GPU付费。
-
它将工作分布在你提供的任何卡上,并附带用于监控的仪表盘和用于在AWS或GCP上部署的Terraform,因此相同的设置可以在你的笔记本电脑和完整的集群上运行。
-
它也可以完全离线运行,模型权重预先下载,适用于数据不能外泄的环境。
每个模型都经过调优并可以直接使用。
-
对于 vLLM 或 Triton,每个模型都需要手动调优,即批次大小、内存分数、精度、最大序列长度和注意力实现都需要针对该特定架构和特定GPU进行设置。
-
在 SIE 中,目录中的85+模型每一个都附带一个配置文件,其中已经填好了这些值,因此你只需通过名称引用模型,引擎就会加载已知在生产中有效的设置。
-
添加或切换只需要指向一个不同的配置文件,而无需重新开始调优。
实现
下面,让我们来看一个涉及对一个服务器进行三次调用的流水线。
我们将构建一个小型检索流水线:嵌入一些文本、对其进行重排序、从上下文中提取命名实体字段,然后生成最终答案,全部通过一个SIE服务器完成。
这将涉及四种不同的模型架构,全部访问一个端点。前三个调用在CPU上运行,因此你可以直接在笔记本上跟着做。
生成步骤是例外,因为它底层运行在SGLang上,需要GPU。
首先安装并启动服务器。local 参数会拉取CPU运行时,serve 命令在8080端口启动服务器。
pip install "sie-server[local]"
sie-server serve
当健康检查返回“正常”时,就说明服务器就绪了。
curl http://localhost:8080/readyz # 正常
现在,实例化客户端并指向正在运行的服务器:
from sie_sdk import SIEClient
from sie_sdk.types import Item
client = SIEClient("http://localhost:8080")
query = "发票是谁开具的?应付金额是多少?"
passages = [
"发票 INV-4471 由 Northwind Logistics 于 2026 年 3 月 14 日开具。",
# ... 更多段落
]
相似文章
大语言模型与本地AI硬件的推理引擎(2026版)
本文提供了一份全面的指南,针对2026年本地AI硬件上的大语言模型推理引擎,解释了如何根据硬件策略、工作负载和服务模型进行选择,并涵盖了诸如llama.cpp、MLX、ExLlamaV2/3、vLLM、SGLang、TensorRT-LLM和NVIDIA Dynamo等引擎。
如果你只是自己使用模型而不对外提供服务,vLLM 真的值得用吗?
一名用户讨论了在 AMD 硬件上进行本地单用户推理时,使用 vLLM 与 llama.cpp 之间的权衡,质疑在非企业级环境中 vLLM 的性能优势是否足以弥补其带来的复杂性。
@_avichawla: 一个棘手的LLM面试题:你在vLLM上部署推理模型,长序列时GPU内存总是不够用。于是你加入KV缓存压缩,驱逐了90%的缓存token。显存占用依旧,GPU仍然内存不足。为什么?
解释了为什么在vLLM上部署推理模型时,驱逐90%的KV缓存token无法释放GPU内存,原因是分页注意力碎片化。同时介绍了NVIDIA的TriAttention解决方案,可实现2.5倍加速和10.7倍内存缩减。
@0xSero:关于 LLM 推理与部署,看这一篇就够了。你听说过:- vLLM - SGLang - llama.cpp - …
vLLM、SGLang、llama.cpp 与 ExLlamaV3 等主流开源推理引擎概览,助你轻松托管并运行大模型。
@no_stp_on_snek: 当所有人都在讨论 @SpaceXAI、@AnthropicAI 和 @OpenAI 的更新(但 @GoogleAI 呢?)... 我去测试了…
Unsloth 的 NVFP4 量化模型在 vLLM 和 llama.cpp 之间推理性能的详细比较,重点说明了 vLLM 在预填充速度上的优势,但 llama.cpp 在单流智能体工作负载中的解码和缓存优势。