ARTICLE · INTELLIGENCE

战地情报 · 详情页

来自尧图项目组的一线实战观察与深度解析

大模型推理框架选型与部署实战:vLLM、SGLang、TensorRT-LLM、Ollama、XInference全解析

大模型推理框架选型与部署实战:vLLM、SGLang、TensorRT-LLM、Ollama、XInference全解析

2024年对大模型开发者来说,推理部署已经从“要不要做”变成了“怎么做才快、省、稳”。vLLM、SGLang、TensorRT-LLM、Ollama、XInference这五个框架,几乎覆盖了从个人电脑到生产集群的全部需求场景。这篇文章不讲虚的,直接把这五个框架的工作原理、部署实操、调优参数、选型逻辑全部过一遍,新手能照着做,老手也能查漏补缺。

先回答一个最实际的问题:这五个框架到底有什么不同,为什么不能只用一个?答案很简单——它们的定位完全不同。Ollama是拿来跑通流程的,XInference是拿来快速体验多模态的,vLLM和SGLang是拿来扛线上并发和吞吐的,TensorRT-LLM是榨干特定硬件性能的。你看,这根本不是一个维度的东西,而是从入门到生产、从通用到极致的递进关系。搞懂这层关系,选型就不会再纠结。


1. 为什么需要专门的推理框架:先搞清楚部署的本质矛盾

很多第一次接触模型部署的人会问一个问题:模型文件加载进去然后调用,不就行了吗?为什么还要讲究框架?实际上,大模型推理和传统深度学习推理最大的差异在于“自回归生成”这个机制,所有框架的优化都是围绕这个机制展开的。

1.1 自回归生成背后的显存压力

大模型推理时,模型每生成一个token,都要回顾之前生成过的所有token的上下文信息,并且把这个上下文信息保存下来供下一次生成使用。这些被缓存下来的历史token的Key和Value信息,就是业界常说的KV Cache。它不是模型权重,而是运行时的临时数据,但它的大小非常惊人。

如果模型一次最多支持4096个token的上下文,那么KV Cache的大小可以这样估算:2(K和V两组数据)× 层数 × 隐藏层维度 × 精度字节数。以现在常见的7B模型为例,32层、隐藏层维度4096,用FP16精度保存,当上下文写满时KV Cache大约占用1GB左右显存。72B级别的模型这个数值会直接冲到十几GB。在长上下文场景、多用户并发场景下,KV Cache占用的显存有时候比模型权重本身还要大。

这就是纯GPU推理第一个要解决的问题:如何高效管理KV Cache这块运行时内存。如果框架不做任何优化,每个请求都会独立申请并保留一份连续显存块,大量显存会因为碎片化和预留浪费而白白牺牲。这个问题不解决,并发数一上来,再大的显存也会在几秒钟内被打爆。

1.2 吞吐与延迟的权衡:从静态批处理到连续批处理

另一个核心矛盾是吞吐和延迟之间的冲突。早期没有推理框架的时候,大家直接用推理后端跑模型,只能做静态批处理:等一批请求凑齐了,统一进行一次前向计算,把这一批的所有结果算完再返回。这个方案实现简单,但存在一个致命问题:一批请求中,生成快的请求必须要等生成慢的请求完全结束后才能一起返回,GPU算力被大量浪费在等待上。

后来主流的推理框架引入了连续批处理(Continuous Batching)机制。这个机制的核心逻辑是:不再等待整批请求全部结束后再释放GPU算力,而是当一个请求的token生成完毕时,立刻把它从当前批次中移出,然后从等待队列中补充一个新请求进来。每个请求的生成进度独立管理。形象地说,传统静态批处理是计时翻台餐厅,一桌客人全部吃完才清桌;连续批处理是快餐店,一吃完马上收拾让给下一位。在高并发场景下,这种机制大幅提升GPU利用率和系统整体吞吐。

vLLM、SGLang、TensorRT-LLM、XInference这几个框架都实现了连续批处理或等效机制,但各自在细节实现上有不同取舍,这也就形成了各自在吞吐、延迟、易用性上的差异。理解了这个底层的机理,再看后面的框架对比,思路就会清晰很多:所谓框架选型,本质上是在吞吐、延迟、显存效率、易用性、硬件适配这些维度上做权衡。


2. 五大主流推理框架逐个拆解:定位、特点与适用场景

这一节是全文的核心。逐个讲清楚每个框架的底层逻辑、优势劣势和适用边界。只有先搞清楚每个框架的“性格”,后续选型时才不会拍脑袋。

2.1 vLLM:高吞吐生产环境的默认选项

vLLM目前是开源社区影响力最大的推理框架之一。它的制胜点是PagedAttention机制。这个机制借鉴了操作系统虚拟内存中分页管理的思想:KV Cache不再需要存储在连续的一段显存空间中,而是划分成固定大小的块,分散存储。生成token时通过块索引查找对应数据。这个设计彻底解决了KV Cache显存碎片化问题,把显存利用率提升到了接近理论极限。同一个GPU上能跑的并发请求数因此大幅增加,表现在业务上就是吞吐量的显著提升。

除了PagedAttention,vLLM还内置了连续批处理、前缀缓存、跳跃解码等多项优化机制。前缀缓存的意思是:如果多个请求共享相同的系统提示词或热门前缀,那么这部分的KV Cache可以直接复用而不是重复计算。对于大量使用长System Prompt的线上业务来说,这个特性能够极大降低首个token延迟。

vLLM对外提供OpenAI兼容的API服务,这意味着如果你是做应用开发的,可以直接把请求地址从OpenAI官方改成vLLM的地址,原来的SDK、调用逻辑几乎不用改。生态极其成熟,多种主流开源模型都能直接支持,包括各种版本的Llama系列、Qwen系列、Mistral系列等。它还支持张量并行,也就是多张GPU卡协同算同一个模型的技术,对于70B以上规模的模型部署来说这是刚需。

vLLM适合什么样的场景?适合高并发的生产在线服务,需要稳定支撑大量用户请求的项目,依赖成熟的社区生态来快速解决问题。它不追求单请求的极致延迟,但在吞吐维度上表现非常优异。如果说有什么短板,那就是它更偏向于服务开源通用模型,对于某些特定硬件上的极致性能表现,不如专门针对该硬件深度优化的方案那么突出。

2.2 SGLang:多轮对话与高并发场景的隐藏强手

SGLang是一个相对新但增长非常快的推理框架。它最核心的设计是RadixAttention,一个基于基数树的前缀复用机制。如果把vLLM的前缀缓存比作只能缓存完整固定前缀的字典,那么SGLang的RadixAttention则是能对共享前缀做精细化拆分的树结构。举个例子,两个请求前半段是相同提示词,后半段出现分叉问答,再后来其中一个请求又回到了与另一个请求相同的路径上,SGLang能自动识别并复用所有重合部分。这意味着在多轮对话、Few-shot场景、Agent类应用中,它有着非常恐怖的前缀命中率。

SGLang还有一个优势是原生支持结构化输出。你可以在生成请求中直接声明输出的JSON Schema约束,框架会通过约束解码的方式保证输出严格符合这个结构。这个特性对做函数调用、工具调用、结构化信息抽取的功能开发来说极其好用,因为以前那些需要反复提示模型修正JSON格式的工作,在SGLang里变成了一次性的约束声明。

在性能方面,SGLang在部分场景下能做到比vLLM更高吞吐,尤其是共享前缀非常多的对话类负载。不过它也有自己的取舍:发展时间相对短,生态成熟度稍逊于vLLM;部分高级功能的文档不够完善,遇到问题时Google能找到的方案相对有限。但如果你做的是高并发的多轮对话服务、Agent应用或者需要强结构化输出,SGLang绝对值得作为首选测试方案,因为它针对这类负载的优化深度是其他框架短期难以超越的。

2.3 TensorRT-LLM:极致性能导向的编译派选手

TensorRT-LLM是GPU厂商官方推出的推理优化方案,走的是“编译优化”这条路线。它不像vLLM和SGLang那样即装即用,而是先把模型结构、优化参数、权重、计算图等信息编译成一个高度优化的引擎文件(Engine),然后部署时才加载这个引擎来提供服务。这个编译过程有点像写代码后进行静态编译:启动慢、构建时间长,但生成的可执行文件运行速度极快。

TensorRT-LLM的优势在于量化支持和硬件深入优化。它对FP8、INT8、INT4等低精度推理做了深度优化,能把模型压缩到很低的内存占用而尽量保持生成质量。在支持的显卡硬件上,它性能释放非常彻底,单卡表现几乎就是理论天花板,多卡扩展同样出色。正因如此,许多追求极致性能和最低成本的商业推理业务最终都选了TensorRT-LLM,比如那些GPU成本极其敏感同时请求量又很大的业务。

但它的代价是显著的灵活性下降。每次更换模型版本、修改上下文长度、调整量化精度,都需要重新编译引擎。模型更新一个版本,整个编译流程可能要重新走一遍。同时它对环境的依赖要求非常严苛,必须匹配特定的系统版本、驱动版本、工具包版本,可以说是一套“娇贵但爆发力惊人”的方案。如果业务处于快速迭代期,模型经常更换,TensorRT-LLM的编译成本可能让人崩溃;但如果业务模型已经稳定、硬件环境确定、请求量巨大,那么释放的这些性能会直接体现在成本降低和用户体验提升上。

2.4 Ollama:把本地模型部署的门槛降到最低

Ollama的火爆很大程度上归功于它极度友好的上手体验。它默认使用GGUF格式的量化模型,这种格式能在普通消费级显卡甚至纯CPU环境下以可接受的速度运行模型。Ollama的常见操作方法只有一行命令,通过一条命令拉取模型并启动,再通过一条命令调用接口。它内置了OpenAI兼容的HTTP服务,同时还有命令行交互模式。对于只是想在自己电脑上跑跑模型效果、做PPT展示、验证开源模型能力的人来说,这几乎是最快路径。

Ollama的价值不在于性能,而在于“心智负担最小”。它不需要理解Python环境、不需要处理CUDA版本冲突、不需要写代码调参。你可以把它理解成大模型界的解释型托管服务:丢进去一个模型名,它自动帮你处理模型下载、量化格式转换、上下文长度设置、GPU/CPU自动切换调度。遇到显存不够的情况,它会自动把部分层卸载到CPU计算,虽然速度会明显下降,但至少不会直接崩掉。

Ollama适合个人开发者、学生、产品经理做快速验证,也适合边缘设备、离线环境、教学场景。但它的性能优化空间远不及前面几个框架,在极高并发、大批量请求、长上下文的场景下会明显捉襟见肘。我的经验是:用Ollama验证模型效果完全没问题,一旦你的应用要面向多人提供服务,就要考虑迁移到vLLM或SGLang这类专业框架。但反过来,用Ollama做前期效果验证再迁移,这个路径会非常顺畅,因为它的模型格式和API设计都尽量保持了通用性。

2.5 XInference:多模态与分布式部署的一站式工具

XInference是一个更偏“全家桶”定位的推理服务平台。它最核心的差异点在于同时覆盖了语言大模型和多模态模型的推理部署,支持的模型格式也很多,包括GGUF、GPTQ等多种量化权重格式。它内置了WebUI界面,打开网页就能看到模型状态、并发请求数、推理进度等信息,交互起来比命令行直观很多。

XInference也提供了OpenAI兼容的API接口,所以在应用接入上同样省心。不过它和Ollama的区别在于,XInference可以实现跨机器的分布式部署:把一个大模型切分到多台机器的多张GPU卡上协同推理。这一点对于手头有多台闲置机器但单机显存不足的情况意义很大。它内部还集成了模型管理、模型下载、量化参数配置等功能,几乎把部署过程中的一连串繁琐步骤都封装起来了。

XInference的优势是集成度和易用性,在快速启动多模态模型、管理多个模型实例、给团队做统一模型网关这些场景下非常顺手。代价则是它如此厚重的功能封装会带来一定的性能损耗和黑盒感:底层优化不如vLLM和TensorRT-LLM那么深入;出现问题时的排查链路更长。我的定位是:XInference适合做内部模型测试平台、中小团队的模型管理门户,以及需要同时在线提供多个不同模型服务的能力中枢。

2.6 五个框架横向对比

这里给出一张直观的对照表,方便快速做技术选型判断。表格不可能覆盖所有细节,但核心差异一目了然:

框架核心优化机制模型格式并发吞吐延迟表现上手难度典型场景
vLLMPagedAttention、连续批处理、前缀缓存HF格式(原生)、AWQ/GPTQ等较高较优中等开源模型高并发在线服务
SGLangRadixAttention前缀树复用、约束解码HF格式高(共享前缀场景尤优)较优中等多轮对话、Agent、结构化输出
TensorRT-LLM编译引擎、低精度量化深度优化HF转Engine高最佳较高模型稳定、硬件固定、成本敏感
OllamaGGUF量化、CPU/GPU自动调度GGUF低一般极低本地体验、教学演示、边缘设备
XInference多模型管理、分布式部署、内置WebUIGGUF/GPTQ/HF等中低一般低多模态快速体验、团队模型管理

表格之外,还有两个隐藏因素会影响选型。一是生态成熟度。vLLM在GitHub上的社区讨论量、教程数量、兼容工具数量遥遥领先,遇到问题几乎都能搜到方案。二是硬件友好度。如果从头到尾都使用同一家GPU厂商的硬件,TensorRT-LLM释放的性能会更加彻底;如果环境比较复杂,CPU和GPU混用、不同架构并存,那么vLLM和Ollama的通用性和跨平台表现反而是更稳妥的选择。


3. 从零到一实操:完成一次真实的大模型推理部署

这一节直接给出可复现的部署流程。我会以vLLM和Ollama为主线展开,因为它们分别代表了“生产可用”和“快速上手”两端。实际操作时你可以按顺序做一遍,遇到问题先记录现象再对照第4节的排查表去定位。

3.1 部署前规划:算清楚你到底需要多少显存

部署模型前最常被忽略的一步是估算显存需求。很多人直接凭感觉选模型,然后运行时报OOM才回头调整。这里给出一个能落地的估算方法。模型权重显存大约是:参数量(以B为单位)× 精度字节数。7B模型FP16精度就是约14GB,BF16同理。但这只是权重部分,运行时还需要加上KV Cache、激活值、推理框架自身预留的缓存空间。

一个保守且可用的估算公式是:总显存需求 ≈ 模型权重显存 + 最大上下文长度 × 隐藏层大小 × 层数 × 2 × 精度字节数 × 并发请求数(粗略覆盖KV Cache)。对于7B FP16模型,如果要求8K上下文、8个并发请求,差不多需要预留约20到24GB显存。这就是为什么部署7B模型通常推荐至少24GB显存的原因。实际部署时,vLLM提供了--gpu-memory-utilization参数来指定框架可使用的显存比例上限,默认值是0.9。设置这个参数的目的,是给推理服务之外的程序留出一些显存余量,避免OOM崩溃。如果你想把显存压榨到极限,可以调到0.95左右;如果希望稳妥,建议从0.85起步。

3.2 用vLLM部署一个开源模型:完整流程

vLLM的安装非常简单,前提是Python环境和CUDA环境正确。整体流程分四步:

第一步,确认基础环境。验证GPU驱动正常、cuda可用。很多初学者卡在vLLM安装上,原因几乎都是环境变量没配好或者依赖包冲突。建议新建一个干净的Python虚拟环境,避免和系统其他Python包混用。

第二步,安装vLLM。直接用pip安装预编译版本即可,会自动拉取torch等依赖。如果你的GPU架构较新,vLLM官方对主流架构都有预编译支持,不需要从源码编译。

第三步,启动OpenAI兼容服务。使用一行命令即可拉起服务:

vllm serve Qwen/Qwen2.5-7B-Instruct --port 8000 --gpu-memory-utilization 0.9 --max-model-len 8192

这个命令做了几件事:加载指定模型,开放8000端口提供服务,设置显存利用上限90%,设定模型最大上下文长度为8192个token。这里重点解释下--max-model-len参数:这个值设置得越大,KV Cache占用的显存就越多,可支持的并发数就越少。如果业务并不需要超长上下文,不建议盲目调大。

第四步,验证服务是否正常。用curl命令发送一个标准对话请求,看能否正常返回结果:

curl http://localhost:8000/v1/chat/completions \ -H "Content-Type: application/json" \ -d '{"model": "Qwen/Qwen2.5-7B-Instruct", "messages": [{"role": "user", "content": "你好"}]}'

如果返回了包含回复内容的JSON结构,说明服务已经正常。这时候任何支持OpenAI接口格式的SDK或成熟应用,都可以通过设置base_url为本地服务地址直接接入,原先的业务代码基本不需要改动。

3.3 用Ollama在个人电脑快速体验模型

Ollama的流程相对简单很多。第一步是安装。安装完成后,从一个模型仓库中拉取并运行模型。以Qwen2.5-7B为例,只需一行命令即可自动完成下载、量化转换和模型启动:

ollama run qwen2.5:7b

Ollama会自动检测当前机器的GPU显存情况。显存足够就把模型完全放入GPU;显存不够会智能地把部分计算层放到CPU上。这个自动调度机制极大降低了门槛。默认情况下,Ollama把模型存放在系统的用户目录下。如果你的系统盘空间有限,可以通过设置环境变量修改模型存放路径,避免系统盘被大模型文件占满。这一点在实际使用中很多人会踩坑:模型动辄几GB,下载两三个就把系统盘塞满了。

Ollama启动后,默认在本地11434端口开放服务。应用接入时把base_url指向这个地址即可。由于它也实现了OpenAI兼容API,所以主流编程语言的OpenAI SDK都可以直接接进来。这种兼容策略大大减少了开发切换成本,也是Ollama能广泛应用的重要原因之一。

3.4 部署后的基础运维与压测

服务上线不是终点,你需要掌握基础的压测手段来验证能扛多少并发。

一个最简单的压测脚本是并发发送一定数量的对话请求,统计成功率和响应耗时。核心观察指标有三个:TTFT(首个token生成前的时间),反映的是服务响应速度;TPOT(每个输出token的平均生成时间),反映生成速度;吞吐(每秒钟处理完的请求数),反映整体承载能力。vLLM内部自带一个压测工具,你可以指定并发数、请求总数来直接获得这几个指标。TensorRT-LLM和SGLang也有类似的性能测试脚本。运维层面,最简单有效的手段是持续观察GPU显存幂和利用率,使用GPU监控工具定期采集数据。如果显存利用率持续接近100%但GPU利用率不高,通常是显存带宽瓶颈;如果GPU利用率高而显存利用率低,往往说明请求数不足以吃满并行能力,需要调大并发;两者都高才是健康的运行状态。


4. 场景选型决策指南与踩坑排查速查表

最后一节,也是最贴近真实业务决策的一节。这一节的内容是我在多个部署项目里反复演练后沉淀下来的实践判断,希望能让读者少走一些弯路。

4.1 什么样的场景选什么样的框架

不要问“哪个框架最好”,要问“哪个框架最匹配我的约束条件”。我给一个比较实用的决策逻辑:

如果需求是“我只有一台个人电脑,想快速体验某个模型”,直接选Ollama,这没什么可犹豫的,它是这个场景下体验最平滑的方案。如果需求是“我要给团队搭一个模型测试平台,同时试跑语言模型、多模态模型,最好有图形界面管理”,选XInference,它解决的就是快速启停和管理多种模型的问题。

如果需求是“我要上线一个面向真实用户的高并发在线服务”,那么vLLM和SGLang是主力选项。vLLM胜在生态成熟、稳定性有保障、问题容易排查;SGLang在共享前缀多、多轮对话多、需要强结构化输出的场景下表现出更优的性能。这两个框架不是替代关系,而是可以根据负载特征去做A/B测试再确定。如果需求是“我的硬件环境固定、模型版本固定、请求量巨大,想尽可能压缩单Token生成成本和提升吞吐”,TensorRT-LLM是最佳选择,前提是你愿意承担编译和版本迭代带来的工程复杂度。

如果需求是“公司在做Agent类应用,很多人同时调用工具函数,输出格式要求严格”,优先测试SGLang,因为它的结构化输出和前缀复用恰好命中这类应用的最大痛点。

4.2 高频问题的定位与排查

部署推理框架过程中遇到的问题高度集中,以下是我见过最高频的几类问题,附上定位方法和解决思路,做成一份速查表方便实际使用:

现象可能原因定位方法解决思路
服务启动即OOM显存小于模型权重需求查看启动日志中的显存分配信息换更小量化模型;调低--gpu-memory-utilization;纯CPU推理(慢)
并发一高就OOM或请求失败KV Cache占用超限观察显存监控曲线降低--max-model-len;限制--max-num-seqs;增加GPU卡做张量并行
启动时报并行库加载错误CUDA和驱动版本不匹配检查驱动版本信息、CUDA版本信息按框架官方要求的驱动版本重新安装;重建虚拟环境
同样的模型,不同框架速度差异很大框架优化机制差异分别压测同负载同一模型据负载特征选框架;前缀复用场景优先SGLang
量化后生成效果明显变差量化精度损失或校准不当对比原始精度结果换更高精度量化(如INT8代替INT4);用代表性数据集校准
多卡推理速度反而比单卡慢模型过小或通信开销大观察卡间通信时间占比小模型不用张量并行;确认NVLink等卡间连接正常

有两个值得特别强调的经验。第一,日志是最重要的排障线索,不要在论坛里盲目复制别人贴的配置,先看自己日志报错的具体行。第二,不要在部署的同一台机器上再跑其他大型GPU任务,否则显存竞争会引发大量莫名其妙的问题。

4.3 从实际项目中沉淀的几个经验教训

这部分想分享几个纯经验层面的内容,不涉及具体项目名称,但都是我真实踩过的坑:

第一个经验是关于模型上下文长度设置。早前我在某个模拟项目X里部署7B模型时,直接把上下文长度设置成模型支持的最大值,结果并发能力只有预期的一半。原因很简单,上下文长度直接决定了KV Cache的大小。后来我把上下文长度从32K降到8K,并发能力立刻起来了。业务侧用户实际用到的上下文长度远低于最大值,没必要为极端情况牺牲整体吞吐。

第二个经验是量化方案选择要分场景。曾有一个图像处理Demo用INT4量化后,输出质量下降到了不可接受的程度。换成INT8量化之后,质量恢复明显,显存只多占了一部分。在成本和效果之间需要找到一个平衡,不要一味追求最低精度。

第三个经验是框架迁移不要一步到位。建议先在Ollama或XInference上跑通业务逻辑,然后迁到vLLM或SGLang做并发验证,最后再根据性能瓶颈决定是否有必要上TensorRT-LLM。这种渐进式迁移可以让每一步的问题范围都足够小,出了问题能快速定位。我见过太多人一上来就直接上最难部署的框架,折腾了好几天还没把模型跑起来。

第四个经验是关于显存用量的预期管理。有段时间在做某跨平台系统的推理服务时发现GPU利用率不低,但吞吐上不去。排查后发现是显存容量不够,部分层被卸载到了CPU上做计算。这类问题不会直接报错,只会表现为速度莫名其妙变慢,排查起来特别隐蔽。所以部署完整流程后第一步建议就是确认模型确实完全加载到了GPU上,而不是部分在CPU上。


最后说一个我自己常用的技巧:不管最终上线用的是什么框架,我都会在本地留一套Ollama环境。它的存在不是为了替代生产方案,而是当我需要快速验证一个新模型效果、一个新提示词写法、或者做一次线上数据异常对照实验时,Ollama是我启动最快、心智负担最小的环境。生产框架负责稳定、负责性能,研究环境负责快、负责灵活,两边各司其职,配合起来是很舒服的工作流。如果你也是从零开始接触大模型推理部署,我建议你按照这个思路:先用Ollama跑通,再用vLLM或SGLang扛住线上,最后用TensorRT-LLM榨干硬件性能。这条路走通之后,再回头看每个框架的设计细节,你会理解得更透彻。

RELATED READING

延伸阅读

更多一线实战笔记与深度复盘,助您持续精进