LLM 推理引擎与本地 AI 硬件(2026 版)

@TheAhmadOsman
英语2个月前 · 2026年5月20日
391K
814
109
18
2.0K

TL;DR

全面解析 vLLM、llama.cpp 和 MLX 等 LLM 推理引擎,重点探讨如何将软件与 VRAM 及内存带宽等硬件限制进行匹配。

你不会先选推理引擎。你会先决定硬件策略、工作负载形态和服务模式。引擎是随之而来的选择。

这是思考 LLM 推理引擎最有效的方式。

系列说明:这是《自托管 LLM / 本地 AI》系列的第 3 部分。

这两篇文章解释了硬件容量和带宽的计算方法。

本文则介绍将硬件转化为可用推理的软件层。

引擎

这些工具服务于不同目的 / 占据不同层次:

  • 本地便携性
  • 消费级 CUDA
  • Apple 统一内存工作流
  • 量化推理
  • 生产级服务
  • 分布式编排
  • 供应商优化的数据中心执行

一个有用的思维模型:

Ahmad - inline image

推理引擎不是“模型”。它是交通警察、内存管理器、内核调度器、调度程序、缓存会计、并行性规划器、API 接口,有时还是部署框架。

最好的引擎需要匹配你的内存层次结构、互连方式、量化格式、延迟和吞吐量目标、模型架构以及运维成熟度。

一页决策指南

Ahmad - inline image
  • 笔记本 / 边缘设备 / 非标硬件 → llama.cpp
  • Mac 优先的工作流 → MLX / MLX-LM
  • 单卡 RTX 本地推理 → ExLlamaV2
  • 2-4 张 NVIDIA / CUDA GPU → ExLlamaV3
  • 通用生产级服务 → vLLM
  • 长上下文 / MoE / 路由 → SGLang
  • NVIDIA 极致性能 → TensorRT-LLM
  • 集群编排 → NVIDIA Dynamo

本指南的其余部分将解释原因。

推理引擎实际做什么

推理引擎加载权重、分词输入、执行前向传播、采样 token、维护 KV 缓存并流式输出结果。严肃的引擎还处理批处理、调度、前缀缓存、量化、并行执行、API 服务、指标收集和分布式执行。

工作负载分为两个阶段:

Prefill(预填充)阶段读取提示并构建初始 KV 缓存,属于计算密集型。

Decode(解码)阶段一次生成一个 token,反复读取权重和 KV 缓存,受内存带宽限制。解码速度更多地取决于内存带宽而非峰值计算能力。

这一区别解释了几乎所有问题:

  • 短提示、长回答:解码占主导 → 内存带宽和批处理重要。
  • 长提示、短回答:预填充占主导 → 注意力核和分块预填充重要。
  • 多用户:调度器质量重要 → 连续批处理、缓存分页、公平性。
  • 长上下文:KV 缓存占主导 → 分页注意力、KV 量化、卸载。
  • MoE:专家路由占主导 → 专家并行、互连、分组 GEMM。
  • 多节点:互连占主导 → NVLink、RDMA、流水线并行、分离架构。

PagedAttention 解决了 KV 缓存碎片问题。FlashAttention 使用 IO 感知分块来减少 HBM(高带宽内存)流量。推测解码先草拟廉价 token 再并行验证。重复出现的主题是:推理性能等于内存移动加上调度。

真正的瓶颈

Ahmad - inline image
  1. 内存带宽,而不仅仅是 VRAM 大小。VRAM 决定能否容纳。带宽决定解码速度。Apple M3 Ultra 提供高达 819 GB/s 的统一内存带宽。NVIDIA H100 SXM 标称 3.35 TB/s 的 GPU 内存带宽。统一内存让你能容纳消费级 VRAM 容纳不了的模型。HBM 则让你在模型能容纳时更快地提供服务。能容纳不等于速度快。容量不等于带宽。
  1. KV 缓存增长。KV 缓存随批大小和上下文长度增长。长上下文工作负载即使权重能容纳,也可能耗尽内存。PagedAttention 将 KV 缓存划分为块,提高利用率并支持更大的批次。
  1. 互连。一旦模型跨越 GPU 边界(多 GPU),你就要付出通信成本。张量并行需要频繁的全规约集合。流水线并行在阶段边界通信。专家并行需要 MoE 的全对全流量。vLLM 的文档指出,如果没有 NVLink,流水线并行可能优于张量并行。
  1. 调度器质量。好的调度器决定哪些请求进入批次、预填充和解码如何共享加速器、长提示是否会阻塞短解码,以及如何避免饥饿。支持批处理不等于拥有生产级调度器的行为。
  1. 运行时开销。CUDA 图、内核融合、采样开销、分词器开销、HTTP 开销、LoRA 切换、结构化解码,这些都很重要。在高规模下,那烦人的 2% 开销会合并起来,需要你关注(无意双关)。

引擎家族

Ahmad - inline image

有四大家族:

便携式本地运行时:llama.cpp、MLC LLM、ONNX Runtime GenAI、OpenVINO、Ollama 类工具。它们关心的是“让它在本地运行”。

Apple / 统一内存运行时:MLX 和 MLX-LM。它们关心的是“善用大共享内存和 Apple 的栈”。

消费级 CUDA 量化引擎:ExLlamaV2 和 ExLlamaV3。它们关心的是“让我的 3090/4090/5090 满载运行低位权重量化模型”。

生产级服务引擎:vLLM、SGLang、TensorRT-LLM、TGI、LMDeploy。它们关心的是并发用户、KV 缓存、批处理、并行性、可观测性和每 token 成本。

此外还有像 Dynamo 这样的编排层,位于引擎之上,协调集群、分离式预填充/解码、路由和自动伸缩。

llama.cpp:便携性之王

当硬件很另类、受限制、离线、偏 CPU、边缘场景,或者不是整洁的 NVIDIA 数据中心节点时,llama.cpp 就是答案。

它支持 Apple Silicon(通过 ARM NEON、Accelerate 和 Metal)、x86(通过 AVX/AVX2/AVX512/AMX)、RISC-V、低位宽量化、CUDA、AMD(通过 HIP)、MUSA、Vulkan、SYCL 以及 CPU+GPU 混合卸载。这就是为什么 llama.cpp 在“只管让它跑起来”这条赛道上独占鳌头。

其 HTTP 服务器功能远超过“玩具级本地运行器”。llama-server 提供 OpenAI 兼容路由、Anthropic Messages API 兼容性、重排序、连续批处理、多模态支持、JSON Schema 约束、函数调用、推测解码和 Web UI。

关键限制:llama.cpp 不适合严肃的多节点生产服务。其 RPC 后端被明确标注为概念验证、脆弱且不安全。

结论:当便携性、离线运行、GGUF 或混合卸载比集群规模服务更重要时,使用 llama.cpp。

不要在 多 GPU 场景 下使用。

MLX 和 MLX-LM:Apple Silicon 的利器

MLX 是 Apple 的 Apple Silicon 数组框架,MLX-LM 是基于它构建的 LLM 包。这是一个 Mac 优先的 ML 栈。

关键的硬件事实是统一内存。Apple Silicon 让 CPU 和 GPU 直接访问同一内存池。MLX 数组存在于统一内存中,你可以在执行操作时选择设备,而不是在独立内存空间之间移动数组。

这改变了本地推理的权衡。在独立 GPU 系统上,问题是“它能塞进 VRAM 吗?”。在拥有大统一内存的 M 系列 Mac 上,问题变成“它能放进内存吗?内存系统能足够快地喂给 GPU 吗?”。大尺寸量化模型可以在那些同等模型在 24 GB 消费级 GPU 上无法运行的机器上运行。

不过,它的速度也更慢。

MLX-LM 增加了 Hugging Face Hub 集成、量化、LoRA 和全量微调、分布式推理,以及庞大的 MLX 社区模型生态。MLX 不再仅限 Mac:它提供 Linux 上的 CUDA 和纯 CPU 包。分布式通信支持 MPI、基于 TCP 的 Ring、基于 Thunderbolt 的 RDMA 的 JACCL 以及用于 CUDA 的 NCCL。

MLX-LM 的服务器本身也警告说,由于它只实现了基本的安全检查,不建议用于生产环境。

结论:在 Mac 优先的 ML 和 LLM 工作流中使用 MLX。对于高并发的公共服务,请使用真正的服务栈。

ExLlamaV2 和 V3:消费级 CUDA,调优且快速

ExLlamaV2 是为那些希望消费级 NVIDIA GPU 超常发挥的人准备的本地 CUDA 量化引擎。它支持分页注意力、动态批处理、提示缓存、KV 缓存去重、批量生成、流式输出和推测解码。要记住的关键词是“本地”。它让量化模型在现代 CUDA GPU 上跑得快,尤其是消费级显卡。

最适用场景:单张 RTX 3090/4090/5090 机器、本地编码助手、本地聊天、EXL2 量化模型、专业用户工作站。

ExLlamaV3 将这一理念扩展到多 GPU 和 MoE 本地推理。它增加了基于 QTIP 的 EXL3 量化格式、面向消费硬件的灵活张量并行和专家并行、通过 TabbyAPI 实现的 OpenAI 兼容服务器、连续动态批处理和多模态支持。

当你拥有 2-4+ 张消费级 NVIDIA GPU 或需要本地 MoE 时,V3 很有吸引力。但要注意:某些模型在 ExLlamaV3 中不支持张量并行或专家并行。

结论:ExLlamaV2 是发烧友级别的本地 CUDA 引擎。ExLlamaV3 是多 GPU(2-4 张)本地设置的前沿选择。能力更强,但边缘更粗糙。

vLLM:默认的开源生产级服务器

对于严肃的开源 LLM 服务,vLLM 是大多数团队应该首先评估的引擎。

它提供基于 PagedAttention 的 KV 内存管理、连续批处理、分块预填充、前缀缓存、CUDA/HIP 图、丰富的量化支持(FP8、MXFP8/MXFP4、NVFP4、INT8、INT4、GPTQ、AWQ、GGUF)、优化的注意力核和 GEMM/MoE 核、推测解码、torch.compile 以及分离式预填充/解码/编码。

它也很灵活:支持张量/流水线/数据/专家/上下文并行、流式输出、结构化输出、工具调用、OpenAI 兼容和 Anthropic Messages API、gRPC、多 LoRA,并支持 NVIDIA、AMD、x86/ARM/PowerPC CPU,以及 TPU、Gaudi、Ascend、Apple Silicon 等插件。

vLLM 的文档指出,多节点部署通常使用 Ray,如果没有 NVLink,流水线并行可能优于张量并行。陷阱在于,人们会假设 vLLM 消除了系统思考的必要性。你仍然需要调整批处理、上下文长度、GPU 内存利用率、并行布局和路由。vLLM 给了你一个非常好的引擎,但它仍然需要良好的系统设计。

结论:如果有人说“我们需要在生产环境中服务开源模型”,vLLM 是默认的起点。

SGLang:vLLM 的系统思维表亲

当服务负载很复杂时——结构化输出、长上下文、MoE、分离架构和路由——SGLang 就是你的选择。

它提供 RadixAttention 前缀缓存、预填充-解码分离、推测解码、连续批处理、分页注意力、张量/流水线/专家/数据并行、结构化输出、分块预填充和多 LoRA 批处理。它支持 NVIDIA、AMD、Intel Xeon、Google TPU、Ascend NPU 等。

SGLang 的差异化在于服务架构。它的预填充-解码分离将计算密集型的预填充和内存密集型的解码分配到专门的实例,并在它们之间传输 KV 缓存。这可以防止长的预填充批次打断解码并导致 token 延迟飙升。

结论:SGLang 适用于那些瓶颈不再是“我们能跑这个模型吗?”而是“我们能在恶劣流量下运行它而不烧掉延迟、内存和成本吗?”的团队。

TensorRT-LLM:极致 NVIDIA 性能

TensorRT-LLM 是 NVIDIA 极致性能栈。它经过优化、高度专业化、功能强大,并且不假装有便携性。

它提供 Python API 来构建带有最先进优化的 TensorRT 引擎,以及 Python 和 C++运行时。它包括用于注意力核、GEMM 和 MoE 的自定义内核;预填充-解码分离、广域专家并行、推测解码;以及与 NVIDIA Dynamo 和 Triton Inference Server 集成的高级 Python API。

B200 GPU 可以加载 FP4 权重并使用优化内核。H100 及更高版本支持 FP8 量化,可以将性能提升一倍、内存消耗减半(对比 16 位),且准确率损失极小。

它的优势场景:H100/H200/B200/GB200/GB300 级集群、纯 NVIDIA 数据中心、FP8/FP4 部署、多节点服务和规模化 MoE。它的劣势场景:AMD、Apple 或 Intel 的便携性;快速多变的实验性模型;小型本地设置;以及需要“通吃一切”的团队。

结论:如果你已锁定 NVIDIA 并在意绝对性能,TensorRT-LLM 值得纳入测试。你用便携性换取了性能。高度专业化,但功能较少。

其他工具

TGI 是 Hugging Face 的生产级服务器,提供跟踪、指标、张量并行和连续批处理。当 HF 集成和简洁性重要时使用它。

MLC LLM 是编译器优先的通用部署引擎,提供跨 REST、Python、JavaScript、iOS 和 Android 的 OpenAI 兼容 API。最适合“把 LLM 部署到任何地方”,尤其是浏览器、移动端和原生应用。

ONNX Runtime GenAI 在 ONNX Runtime 之上实现了完整的生成循环,并驱动 Foundry Local、Windows ML 和 VS Code AI Toolkit。它支持 CPU、CUDA、DirectML、TensorRT-RTX、OpenVINO、QNN、WebGPU 和 AMD GPU。最适合应用部署和 ONNX 工作流。

OpenVINO GenAI 是 Intel 针对 Xeon CPU、Arc GPU、Core Ultra 和 NPU 优化的方案。它提供兼容 OpenAI 的服务,支持连续批处理和分页注意力。最适合 Intel 硬件。

LMDeploy 是一个以 CUDA 为中心的工具包,具有用于性能的 TurboMind 和用于易用性的 PyTorch。对想要 vLLM/SGLang/TensorRT-LLM 替代方案的 CUDA 用户最有吸引力。

NVIDIA Dynamo 是一个位于 vLLM、SGLang 和 TensorRT-LLM 等引擎之上的分布式编排层,支持分离架构、智能路由和多层 KV 缓存。当单引擎服务不再足够时使用。

注意:不要使用 Ollama。

硬件策略方案

Ahmad - inline image

纯 CPU 服务器:优先 llama.cpp。Intel Xeon 用 OpenVINO。应用/ONNX 部署用 ONNX Runtime GenAI。

MacBook / Mac Studio:Mac 原生工作流用 MLX / MLX-LM。GGUF 便携性用 llama.cpp。

单张 RTX 3090 / 4090 / 5090:EXL2 本地推理用 ExLlamaV2。GGUF 或便携性用 llama.cpp。服务多用户用 vLLM。

双卡或四卡消费级 RTX 机器:多 GPU 量化推理或 MoE 用 ExLlamaV3。服务行为重要时用 vLLM。测试路由或长上下文模式时用 SGLang。

8×H100 / H200 节点:从 vLLM 或 SGLang 开始。如果纯 NVIDIA 且性能值得调优,则用 TensorRT-LLM 做基准测试。当需要多节点编排时使用 Dynamo。

B200 / GB200 / GB300 级基础设施:对 TensorRT-LLM、SGLang 和 vLLM 做基准测试。添加 Dynamo 进行集群级编排、KV 感知路由和自动伸缩。

AMD MI300 / MI325 / MI350 / MI355:在 ROCm 上从 vLLM 或 SGLang 开始。避免假设 NVIDIA 的基准测试结果可以直接移植。

Intel Xeon / Core Ultra / Arc:OpenVINO GenAI 或 OpenVINO Model Server。如果应用嵌入重要,用 ONNX Runtime GenAI。

浏览器、移动端、应用原生:MLC LLM / WebLLM 或 ONNX Runtime GenAI。

基准测试:测量什么

糟糕的基准测试:“我跑到了 180 token/s。”

Ahmad - inline image

好的基准测试包括:

模型:精确的模型名称、架构、参数量、激活的 MoE 参数。

权重:数据类型、量化格式、分组大小、校准数据。

引擎:版本、提交号、后端、标志位。

硬件:GPU 型号、内存容量、带宽、互连方式、CPU、RAM。

工作负载:输入/输出长度分布、并发数、是否流式、共享前缀、结构化输出。

指标:首 token 生成时间 (TTFT)、每输出 token 时间 (TPOT)、端到端延迟、p50/p95/p99、每秒 token 数、每秒请求数、GPU 内存使用量、KV 缓存命中率、预填充吞吐量、解码吞吐量、每百万 token 成本。

基准测试规则:

  1. 永远不要只用单用户每秒 token 数来比较引擎。
  2. 测试你实际场景的提示和输出分布。
  3. 使用现实的并发数进行测试。
  4. 将预填充和解码分开测量。
  5. 追踪 p95 和 p99,而不仅仅是平均值。
  6. 在目标上下文长度下测量内存余量。
  7. 如果你的应用有重复前缀,测试缓存复用。
  8. 单独测试结构化输出;语法会带来额外开销。
  9. 单独测试 LoRA 和多 LoRA。
  10. 在驱动程序、CUDA、ROCm、模型或引擎升级后重新测试。

常见错误

仅凭 VRAM 容量选择引擎。VRAM 决定能否容纳。带宽和调度器决定速度。大统一内存机器可以容纳巨大模型,但 H100 在模型能容纳时由于高得多的 HBM 带宽而解码更快。

在弱互连上使用张量并行。没有 NVLink 或 NVSwitch 时,先测试流水线并行。vLLM 的文档指出了这一点,尤其是对于 L40S 类设置。

忽略 KV 缓存。长上下文和高并发可能使 KV 缓存成为限制因素。PagedAttention、前缀缓存、KV 量化和分离架构在规模下不是可选项,而是必须项。

将本地引擎当作生产服务器。llama.cpp 服务器很强大。MLX-LM 服务器很方便。Ollama 很宜人但绝对不要使用。

然而,生产环境意味着安全性、可观测性、背压、路由、自动伸缩和 SLA 行为。MLX-LM 自身也警告其服务器不建议用于生产环境。

假设所有量化格式都是可移植的。GGUF、EXL2、EXL3、AWQ、GPTQ、FP8、FP4、MLX 格式和 ONNX 不可互换。正确的格式是你的引擎有优化内核的格式。

忽略模型架构。密集模型、MoE、混合注意力、多模态模型和长上下文变体对引擎的不同部分施加压力。广泛支持并不意味着每个优化都同等有效。

盲目相信没有负载形状的基准测试图表。一份针对 Llama 3.1 8B 在 1K 输入 / 128 输出下的图表,对运行在 Qwen 3.6 27B / Gemma 4 26B-A4B 上的 80K 上下文编码 Agent,或具有 500 个并发用户的 RAG 服务,几乎没有参考价值。

主观最终地图

本地 AI 用户:LM Studio 或 Harbor 追求便利性。llama.cpp 追求控制。Mac 上用 MLX。CUDA 本地性能用 ExLlamaV2/V3。

构建本地 Agent:基本上都可以,但鉴于大多数人使用的工具:便携性用 llama.cpp。用户在 Apple Silicon 上用 MLX。本地模拟生产服务用 vLLM。

服务内部团队:从 vLLM 开始。如果结构化输出、长上下文、多 LoRA、MoE 或路由重要,则使用 SGLang。

大规模服务客户:对 vLLM、SGLang 和 TensorRT-LLM 做基准测试。如果路由和分离重要,SGLang 和 Dynamo 值得关注。

NVIDIA 数据中心:极致性能用 TensorRT-LLM。灵活性用 vLLM。复杂服务用 SGLang。集群编排用 Dynamo。

Apple Silicon:原生开发用 MLX。GGUF 用 llama.cpp。统一内存在容量上是超能力,但存在带宽权衡,不是 HBM。

边缘、应用、浏览器或 Windows 原生:根据技术栈选择 llama.cpp、MLC LLM、ONNX Runtime GenAI 或 OpenVINO。

最终原则

推理引擎的选择会有后果。

在选引擎之前,先回答这些问题:

  1. 我实际上有什么硬件?
  2. 模型能放进快速内存,还是只能放进系统/统一内存?
  3. 瓶颈是解码还是预填充?
  4. 我关心的上下文长度和并发量是多少?
  5. 提示信息是否足够共享以利用前缀缓存?
  6. 模型是密集、MoE、多模态还是混合?
  7. 我需要本地便利、生产服务还是集群编排?
  8. 目标引擎上哪种量化格式有优化内核?
  9. 我的互连是 PCIe、NVLink、NVSwitch、以太网、RDMA 还是 Thunderbolt?
  10. 我在优化什么:延迟、吞吐量、成本、隐私、便携性还是开发速度?

引擎会跟随答案而选择。

下次见。

  • Ahmad
存到 YouMind

使用 YouMind 深度阅读爆款文章

保存原文、追问细节、总结观点,并在一个 AI 工作空间里把爆款文章沉淀成可复用笔记。

了解 YouMind
写给创作者

把你的 Markdown 变成干净的 𝕏 文章

图片上传、表格、代码块,往 𝕏 上手动重排太痛苦。YouMind 把整篇 Markdown 一键转成干净、可直接发布的 𝕏 文章草稿。

试试 Markdown 转 𝕏

更多可拆解样本

近期爆款文章

探索更多爆款文章