云计算百科
云计算领域专业知识百科平台

【LLM推理与Serving⑦】主流推理框架对比:vLLM/TGI/TensorRT-LLM/SGLang/LMDeploy选型指南

【LLM推理与Serving⑦】主流推理框架对比:vLLM/TGI/TensorRT-LLM/SGLang/LMDeploy选型指南

系列文章索引:本系列从基础概念到工程实践,系统梳理LLM推理与Serving的核心知识。本文为第7篇,聚焦主流推理框架的横向对比与选型方法论。

一、开篇:选推理框架不是选"最快的",而是选最匹配业务的

刚接触LLM Serving的同学,经常会问一个问题:“哪个推理框架最快?” 我的回答通常是:“这取决于你的业务是什么。”

如果你是做一个简单的聊天机器人Demo,vLLM可能3分钟就能跑起来;如果你要在A100集群上跑千亿参数模型追求极致吞吐,TensorRT-LLM可能是更好的选择;如果你团队以Python为主、又需要结构化输出能力,SGLang可能让你事半功倍。

推理框架的选型,本质上是一个多目标优化问题:吞吐要高、延迟要低、显存要省、API要兼容、运维要简单、生态要完善……这些目标之间往往存在冲突,我们需要根据业务场景做权衡。

这篇文章不做"谁是第一"的排行,而是带你建立一套选型方法论,让你能根据自己的业务特点,在vLLM、TGI、TensorRT-LLM、SGLang、LMDeploy等主流框架中做出最合适的选择。

二、选型时应该看哪些维度

在对比框架之前,我们先建立一个评估维度清单。你可以把它当作一个"打分表",每一项根据业务重要性赋予不同权重。

2.1 模型支持广度

  • 支持的模型架构:LLaMA、Qwen、Baichuan、ChatGLM、Mistral、Gemma……你的目标模型是否在支持列表中?
  • 新模型跟进速度:SOTA模型发布后,框架多久能跟上?
  • 自定义模型适配成本:如果是自研模型,接入需要改多少代码?

2.2 API兼容性

  • 是否兼容OpenAI API格式:这是事实标准,兼容意味着上层应用几乎不用改
  • 是否支持流式输出(SSE):对话场景的刚需
  • 是否支持Function Calling / 工具调用:Agent场景必备

2.3 性能指标

  • 吞吐(Throughput):单位时间能处理多少token,决定了服务容量和成本
  • 首Token延迟(TTFT):用户从发请求到看到第一个字的时间,影响体验
  • 每Token延迟(TPOT):后续每个token的生成速度,影响打字流畅度
  • 显存占用:同样的模型,谁用的显存少,谁就能塞下更多并发

2.4 KV Cache与Prefix优化

  • PagedAttention / Continuous Batching:是否支持动态批处理,这是高吞吐的基石
  • Prefix Caching / 共享前缀:系统提示词(System Prompt)能否复用KV Cache,对RAG和Agent场景很重要
  • KV Cache量化:FP8/INT8/INT4量化KV,进一步省显存

2.5 高级特性

  • 量化支持:GPTQ、AWQ、FP8、SmoothQuant……支持哪些量化方案?
  • 结构化输出:JSON Schema、Regex、Grammar约束输出格式
  • Speculative Decoding:投机解码,用小模型加速大模型
  • LoRA动态加载:多租户场景下能否按需加载不同的LoRA适配器

2.6 分布式与部署

  • Tensor Parallel(张量并行):单模型跨多张卡
  • Pipeline Parallel(流水线并行):超大模型分层部署
  • 多节点支持:能否跨机器分布式推理
  • 容器化部署:是否有官方Docker镜像,K8s适配如何

2.7 运维与生态

  • 监控指标:Prometheus metrics、日志完善程度
  • 社区活跃度:GitHub stars、issue响应速度、迭代频率
  • 文档质量:新手友好度、示例丰富度
  • 商业支持:出了问题有没有人兜底

三、主流框架速览

下面我们逐个认识这些主流框架,了解它们的"性格特点"。

3.1 vLLM:Python友好的高吞吐引擎

一句话定位:UC Berkeley出品,用PagedAttention彻底改变了LLM推理的吞吐游戏规则。

vLLM最大的贡献是提出了PagedAttention——把操作系统中虚拟内存的分页思想用到了KV Cache管理上。传统方式下KV Cache是连续分配的,容易产生碎片;PagedAttention把KV Cache分成固定大小的"页",可以非连续存储,大大提升了显存利用率和并发数。

# vLLM 启动示例(OpenAI兼容API)
# 命令行启动
# vllm serve meta-llama/Llama-2-7b-chat-hf \\
# –tensor-parallel-size 1 \\
# –gpu-memory-utilization 0.9 \\
# –max-model-len 4096

# Python 客户端调用(OpenAI SDK兼容)
from openai import OpenAI

client = OpenAI(
base_url="http://localhost:8000/v1",
api_key="token-abc123",
)

response = client.chat.completions.create(
model="meta-llama/Llama-2-7b-chat-hf",
messages=[
{"role": "system", "content": "你是一个乐于助人的助手。"},
{"role": "user", "content": "请解释什么是PagedAttention。"}
],
stream=True,
)

for chunk in response:
if chunk.choices[0].delta.content:
print(chunk.choices[0].delta.content, end="")

核心特点:

  • 安装简单,pip install vllm 基本搞定
  • 原生支持OpenAI兼容API,开箱即用
  • Continuous Batching + PagedAttention 带来极高吞吐
  • 支持多种量化:AWQ、GPTQ、FP8、SqueezeLLM
  • 支持Speculative Decoding、LoRA、Prefix Caching

适合场景:绝大多数生产场景的首选,尤其是Python技术栈团队。

3.2 TGI:Hugging Face官方框架

一句话定位:Hugging Face亲儿子,transformers生态无缝衔接。

TGI(Text Generation Inference)是Hugging Face官方推出的推理服务框架。如果你已经在用transformers库,TGI的学习成本几乎为零——因为它底层就是transformers + 一些优化。

# TGI Docker 启动示例
# docker run -p 8080:80 \\
# –gpus all \\
# -e MODEL_ID=meta-llama/Llama-2-7b-chat-hf \\
# -e MAX_BATCH_PREFILL_TOKENS=4096 \\
# -e MAX_INPUT_LENGTH=1024 \\
# -e MAX_TOTAL_TOKENS=2048 \\
# ghcr.io/huggingface/text-generation-inference:latest

核心特点:

  • 与Hugging Face生态深度整合,模型加载方式一致
  • 支持Flash Attention、Paged Attention(v2.0+引入)
  • 内置Proteus(动态批处理调度器)
  • 支持Tensor Parallel多卡推理
  • 完善的日志和Prometheus监控

适合场景:已经深度使用Hugging Face生态的团队,或者对模型可解释性、调试需求高的场景。

3.3 TensorRT-LLM:NVIDIA极限性能框架

一句话定位:NVIDIA亲生的,追求极致性能就选它。

TensorRT-LLM是NVIDIA基于TensorRT打造的LLM推理加速库。它的核心优势在于极致的kernel优化和FP8精度支持——毕竟NVIDIA最懂自己的硬件。

代价是:使用门槛相对较高,需要编译、构建引擎,Python接口相对底层。

# TensorRT-LLM 简化示例(构建引擎+推理)
# 实际使用通常需要先编译、构建engine,再通过Python或C++调用

# 1. 构建引擎(命令行工具)
# python build.py \\
# –model_dir ./Llama-2-7b-hf \\
# –dtype float16 \\
# –max_batch_size 64 \\
# –max_input_len 2048 \\
# –max_output_len 512 \\
# –output_dir ./trt_engines/llama-2-7b

# 2. Python 推理示例(简化版)
from tensorrt_llm.runtime import ModelRunner

runner = ModelRunner.from_dir(
engine_dir="./trt_engines/llama-2-7b",
max_batch_size=64,
)

output = runner.generate(
prompt="解释一下什么是TensorRT-LLM:",
max_new_tokens=200,
temperature=0.7,
)
print(output)

核心特点:

  • 极致的kernel优化,FP8训练/推理全链路支持
  • 支持In-flight Batching(连续批处理)
  • 支持TP、PP多种并行策略
  • 支持SmoothQuant、AWQ、GPTQ等量化
  • 多GPU、多节点扩展性强

适合场景:对性能要求极致、有专门的推理优化团队、大规模部署的场景。

3.4 SGLang:结构化输出强,RadixAttention前缀共享

一句话定位:结构化输出的王者,前缀缓存做得非常出色。

SGLang(Structured Generation Language)是一个相对新的框架,但它有两个杀手级特性:

  • RadixAttention:基于前缀树(Trie)的KV Cache共享,相同前缀的请求可以共享KV Cache。这对于RAG、Agent、多轮对话场景效果拔群——系统提示词只需要算一次。

  • 结构化生成:原生支持JSON Schema、Regex、Grammar约束,输出格式100%可控,不需要事后校验和重试。

  • # SGLang 结构化输出示例
    import sglang as sgl
    from pydantic import BaseModel

    # 定义输出结构
    class UserInfo(BaseModel):
    name: str
    age: int
    hobbies: list[str]

    @sgl.function
    def extract_user_info(text):
    user_info = text + "\\n请从上述文本中提取用户信息:"
    result = sgl.gen(
    "json_output",
    response_format=UserInfo, # 直接用Pydantic模型约束
    )
    return result

    # 运行
    with sgl.Endpoint("http://localhost:30000"):
    state = extract_user_info.run(
    text="李明,28岁,喜欢编程、阅读和打篮球。"
    )
    print(state["json_output"])
    # 输出:{"name": "李明", "age": 28, "hobbies": ["编程", "阅读", "打篮球"]}

    核心特点:

    • RadixAttention前缀共享,系统提示词/长上下文复用率高
    • 极强的结构化生成能力,支持JSON/Regex/Grammar
    • 支持Function Calling、多模态(LLaVA)
    • 连续批处理、PagedAttention
    • 性能接近vLLM,某些场景甚至更快

    适合场景:Agent、RAG、结构化数据提取等大量共享前缀或需要严格输出格式的场景。

    3.5 LMDeploy:国产模型友好,部署量化一体化

    一句话定位:上海AI实验室出品,国产模型适配做得最好的框架之一。

    LMDeploy是上海AI实验室开发的LLM部署工具包。它最大的优势是对国产大模型(Qwen、Baichuan、InternLM、ChatGLM等)的支持非常完善,量化方案(W4A16、W8A8)也做得比较成熟。

    # LMDeploy 启动示例
    # pip install lmdeploy

    # 1. 离线推理
    # lmdeploy chat turbomind \\
    # –model-path Qwen/Qwen-7B-Chat \\
    # –tp 1

    # 2. 启动API服务(OpenAI兼容)
    # lmdeploy serve api_server \\
    # Qwen/Qwen-7B-Chat \\
    # –server-port 23333 \\
    # –tp 1 \\
    # –quant-policy 4 # W4A16量化

    核心特点:

    • 国产模型支持全面,文档对中文用户友好
    • TurboMind推理引擎,性能优秀
    • 支持W4A16、W8A8量化,显存压缩比高
    • 支持连续批处理、PagedAttention
    • 多模态支持(LLaVA、Qwen-VL等)

    适合场景:以国产模型为主的团队,尤其是需要量化部署降低成本的场景。

    3.6 DeepSpeed-MII:DeepSpeed生态延续

    一句话定位:微软DeepSpeed家族的推理产品,训练用DeepSpeed的团队可以无缝衔接。

    DeepSpeed-MII(Microsoft Inferencing for Inference)是DeepSpeed在推理侧的延伸。如果你训练时用了DeepSpeed做ZeRO优化,推理用MII可以形成完整闭环。

    核心特点:

    • DeepSpeed生态一致,学习成本低
    • 支持DeepSpeed-Inference的多种优化
    • 支持张量并行、流水线并行
    • 与Azure等微软云服务集成好

    适合场景:已经在用DeepSpeed训练、希望统一技术栈的团队。

    四、定性对比与选型建议

    看完了每个框架的特点,我们来做一个横向对比,并给出不同场景下的选型建议。

    4.1 关键特性对比表

    特性维度vLLMTGITensorRT-LLMSGLangLMDeploy
    安装难度 简单 简单 较复杂 简单 简单
    Python友好度 高 高 中 高 高
    吞吐性能 高 中高 极高 高 高
    延迟表现 好 好 极好 好 好
    模型支持 广 广 中 中 广(国产优)
    OpenAI API兼容 原生 是 需包装 是 是
    结构化输出 一般 一般 一般 极强 一般
    Prefix缓存 有 有 有 Radix(极强) 有
    量化支持 多 中 多 中 多(W4A16优)
    分布式能力 TP+PP TP TP+PP+EP TP TP
    社区活跃度 极高 高 高 快速增长 高

    4.2 不同场景的选型建议

    场景1:快速上线 / 初创团队 / Python栈
    → 首选 vLLM。理由:生态最成熟、文档最丰富、坑已经被踩得差不多了,社区响应快。

    场景2:Agent / RAG / 大量共享前缀
    → 首选 SGLang。理由:RadixAttention能让系统提示词的KV Cache几乎零成本复用,结构化输出省去大量后处理逻辑。

    场景3:极致性能 / 大规模集群 / 有专门优化团队
    → 首选 TensorRT-LLM。理由:在NVIDIA硬件上它的性能天花板最高,FP8能带来显著的吞吐提升和显存节省。

    场景4:国产模型为主 / 量化降本需求强
    → 首选 LMDeploy。理由:国产模型适配完善,W4A16量化成熟,中文文档友好。

    场景5:Hugging Face重度用户 / 重视可调试性
    → 首选 TGI。理由:和transformers完全一致的模型加载方式,调试和自定义最方便。

    一个实用建议:先用vLLM跑通业务,验证PMF(产品市场契合度);业务量上来后,再根据瓶颈点考虑切换到更合适的框架。

    五、用OpenAI-compatible API做统一冒烟测试

    好消息是:主流框架几乎都支持OpenAI兼容API。这意味着我们可以用同一套测试代码对不同框架做冒烟测试,快速验证功能正确性和基础性能。

    # unified_smoke_test.py —— 统一冒烟测试脚本
    import time
    import json
    from openai import OpenAI

    def smoke_test(base_url, model_name, test_cases):
    """统一冒烟测试:功能验证 + 基础性能指标"""
    client = OpenAI(base_url=base_url + "/v1", api_key="test")

    results = []
    for i, tc in enumerate(test_cases):
    print(f"\\n=== Test Case {i+1}: {tc['name']} ===")
    start = time.time()
    first_token_time = None
    total_tokens = 0

    try:
    stream = client.chat.completions.create(
    model=model_name,
    messages=tc["messages"],
    stream=True,
    max_tokens=tc.get("max_tokens", 500),
    temperature=0.7,
    )

    for chunk in stream:
    if first_token_time is None:
    first_token_time = time.time()
    ttft = first_token_time – start
    print(f" 首Token延迟 (TTFT): {ttft:.3f}s")

    content = chunk.choices[0].delta.content
    if content:
    total_tokens += 1
    # 打印前几个字符,确认输出正常
    if total_tokens <= 20:
    print(content, end="", flush=True)

    total_time = time.time() – start
    tpot = (total_time – ttft) / max(total_tokens – 1, 1)

    print(f"\\n 总Token数: {total_tokens}")
    print(f" 总耗时: {total_time:.3f}s")
    print(f" 每Token延迟 (TPOT): {tpot*1000:.2f}ms")
    print(f" 生成速度: {total_tokens/total_time:.2f} tokens/s")

    results.append({
    "case": tc["name"],
    "success": True,
    "ttft": ttft,
    "tpot": tpot,
    "total_tokens": total_tokens,
    "throughput": total_tokens / total_time,
    })

    except Exception as e:
    print(f" ERROR: {e}")
    results.append({"case": tc["name"], "success": False, "error": str(e)})

    return results

    if __name__ == "__main__":
    # 测试用例
    test_cases = [
    {
    "name": "短文本生成",
    "messages": [{"role": "user", "content": "用一句话介绍LLM推理框架。"}],
    "max_tokens": 100,
    },
    {
    "name": "长文本生成",
    "messages": [{"role": "user", "content": "请详细介绍PagedAttention的工作原理,包括它解决了什么问题、核心数据结构、以及优缺点。"}],
    "max_tokens": 500,
    },
    {
    "name": "系统提示词复用(Prefix测试)",
    "messages": [
    {"role": "system", "content": "你是一位资深的LLM推理工程师,回答要专业、准确、简洁。" * 10}, # 长系统提示词
    {"role": "user", "content": "什么是KV Cache?"},
    ],
    "max_tokens": 200,
    },
    ]

    # 分别测试不同框架(根据实际部署调整URL和模型名)
    frameworks = {
    "vLLM": ("http://localhost:8000", "meta-llama/Llama-2-7b-chat-hf"),
    # "SGLang": ("http://localhost:30000", "meta-llama/Llama-2-7b-chat-hf"),
    # "TGI": ("http://localhost:8080", "meta-llama/Llama-2-7b-chat-hf"),
    }

    all_results = {}
    for name, (url, model) in frameworks.items():
    print(f"\\n{'='*50}")
    print(f"Testing Framework: {name}")
    print(f"{'='*50}")
    all_results[name] = smoke_test(url, model, test_cases)

    # 保存结果
    with open("smoke_test_results.json", "w", encoding="utf-8") as f:
    json.dump(all_results, f, ensure_ascii=False, indent=2)
    print("\\n测试结果已保存到 smoke_test_results.json")

    这个脚本能帮你做什么?

    • 验证框架是否正常工作(功能正确性)
    • 测量TTFT、TPOT、生成速度等基础性能指标
    • 对比不同框架在相同硬件和模型下的表现
    • 测试Prefix场景下的KV Cache复用效果

    六、生产上线Checklist

    选型只是第一步,真正上线前还有很多事情要确认。这里给你一份生产上线Checklist,按图索骥,避免踩坑。

    6.1 正确性验证

    • 基础生成测试:prompt能否正常输出,输出质量是否符合预期
    • 长文本测试:接近max_seq_len的输入输出是否正常
    • 边界case:空输入、超长输入、特殊字符是否有优雅降级
    • 一致性验证:相同输入+固定seed,输出是否一致(尤其是量化后)
    • 多轮对话:多轮上下文是否正确维护

    6.2 性能压测

    • 吞吐测试:不同并发下的tokens/s,找到瓶颈点
    • 延迟测试:不同负载下的P50/P95/P99延迟
    • 稳定性测试:连续跑24小时以上,有没有内存泄漏、性能衰减
    • 峰值测试:打满GPU后服务是否还能正常响应,会不会OOM

    6.3 显存与资源

    • 显存占用:空载、满载时的显存使用情况,是否留有安全余量
    • 显存碎片:长时间运行后显存碎片是否严重
    • CPU/内存:CPU是否成为瓶颈,内存是否足够
    • 网络带宽:多卡/多机场景下通信是否够用

    6.4 高级特性验证

    • 流式输出:SSE是否正常,中断后能否正确处理
    • 量化验证:量化后精度损失是否在可接受范围内
    • Prefix缓存:共享前缀的请求是否真的命中缓存、加速明显
    • 结构化输出:JSON/Function Calling格式是否100%正确

    6.5 API与集成

    • API兼容性:和现有业务代码的对接是否顺畅
    • 错误处理:各种异常情况下的错误码和错误信息是否合理
    • 超时机制:请求超时是否正确断开,资源是否释放
    • 限流能力:是否支持QPS/并发限制

    6.6 运维与监控

    • 健康检查:/health 端点是否正常工作
    • 监控指标:QPS、延迟、显存、GPU利用率等是否能接入Prometheus
    • 日志:请求日志、错误日志、慢请求日志是否完善
    • 灰度发布:能否做A/B测试、灰度切换
    • 回滚能力:出问题能否快速回退到上一版本

    6.7 安全与合规

    • 输入过滤:是否有Prompt注入防护
    • 输出审核:是否需要接入内容安全
    • 数据隐私:用户数据是否会泄露、是否落盘
    • 鉴权机制:API Key / Token 认证是否到位

    七、小结与思考

    这篇文章我们做了三件事:

  • 建立了推理框架的选型维度体系——下次再有人问"哪个框架好",你可以先反问"你的业务场景是什么?"
  • 梳理了五大主流框架的特点和适用场景——vLLM的通用性、SGLang的结构化输出、TensorRT-LLM的极致性能、LMDeploy的国产模型友好、TGI的HF生态
  • 给出了生产上线Checklist——从正确性到性能,从安全到运维,帮你系统性地规避风险
  • 最后分享一个观点:框架选型是手段,业务成功才是目的。 不要陷入"技术选型内卷"——今天vLLM出了新版本就想换,明天SGLang又有新特性又想试。选一个够用的框架,把业务跑起来,比什么都重要。等业务量上来了,再针对性地优化框架,那时候每一分性能提升都能换算成实实在在的成本节省。

    赞(0)
    未经允许不得转载:网硕互联帮助中心 » 【LLM推理与Serving⑦】主流推理框架对比:vLLM/TGI/TensorRT-LLM/SGLang/LMDeploy选型指南
    分享到: 更多 (0)

    评论 抢沙发

    评论前必须登录!