
最近总有人在后台问我同一个问题想把 DeepSeek、Qwen 这类开源大模型放到自己的机器上跑起来但翻了一圈教程vLLM、SGLang、Ollama、llama.cpp 这四个名字反复出现每个都说自己好用到底选哪个我跟你们说这四个还真不是同一类东西。选错了轻则多花几天折腾环境重则上线一压测就崩。这篇文章我就从机制和部署两条线把这四个引擎的底细掰开讲清楚。看完你至少能明白两件事第一它们的性能差距到底从哪来第二以你的显存、并发和场景应该选哪个。1. 先把定位搞清楚这四个引擎不在一个赛道上1.1 一句话说清每个工具的本质我用一张表把这四个家伙的定位列出来你第一眼就能看出差别。引擎底层实现启动方式核心目标典型用户vLLMPython GPU Kernel 深度优化python -m vllm.entrypoints.openai.api_server高并发、高吞吐的生产服务有 GPU 服务器的工程团队SGLangPython 前缀缓存优化python -m sglang.launch_server高吞吐 长前缀复用做 RAG、多轮对话、结构化输出的团队OllamaGo 封装底层走 llama.cpp 等ollama run qwen2.5:7b零配置的本地私有化个人开发者、桌面用户llama.cpp纯 C/C无 Python 依赖编译后直接运行二进制极致的轻量与跨平台老设备、开发板、Android/iOS 端侧注意看最后两列。vLLM 和 SGLang 的目标是“同时喂给模型尽可能多的请求把 GPU 用满”这是一个典型的服务端思维。而 Ollama 和 llama.cpp 的目标是“让你在个人电脑上能跑起来”更偏单机体验。后者当然也能开 API但在并发能力上跟前者不是一个量级。1.2 大多数人选错的根源我见过太多人踩同一个坑看 vLLM 各种 benchmark 跑分漂亮就在自己那台 8G 显存的老笔记本上硬装结果装了半天 CUDA 和 Triton 编译冲突最后连模型都加载不出来。转头看到 Ollama 一条命令就能跑又把它直接搬到生产环境当多用户 API 用并发一上来立刻 OOM。这就是典型的“不看定位只看名气”。选型不是比谁技术上更牛而是看你的服务形态你是给自己一个人用还是给公司 200 个同事用你跑的是 2K 上下文的闲聊还是 32K 上下文的 RAG 检索你手头是 4090 单卡还是 8 张 A100 的集群这些问题的答案直接决定你应该选哪个引擎。1.3 服务形态决定引擎取向打个比方。如果大模型推理像运输货物llama.cpp 像一辆三轮车灵活、便宜、什么路都能走但载货量小Ollama 像一辆网约车随叫随到不用你操心适合个人跑腿vLLM 像一辆公交车专门为“拉很多人”优化但需要专用道路和调度SGLang 则像带了行包寄存服务的定制班车如果大家出发的路线重合共享前缀能省下大量重复路程。你要先搞清楚自己是在送一个包裹还是在运营一条客运线路。这个基本面不解决后面调什么参数都白搭。2. 吞吐与延迟的博弈vLLM 的连续批处理和显存管理2.1 continuous batching把 GPU 的空闲时间榨干vLLM 拉开差距的核心是它2019年以后在推理调度上采用的 continuous batching连续批处理。传统静态批处理是这么干的攒够一批请求比如 8 个一起丢给模型跑。这一批必须全部解码完下一批才能进来。问题是每个请求的长短不一样快的请求跑完了只能干等慢的GPU 在那段时间里实际上是闲置的。连续批处理改成了迭代级调度每一轮解码结束后哪些请求完成了就直接退出新请求立刻补位。翻译成人话就是GPU 上一秒还在处理你的问题下一秒空闲算力就开始处理下一个排队的人。实测下来在请求长短不一、有快有慢的真实流量里这种方式能把吞吐量提升数倍而且不需要你改任何模型代码。2.2 PagedAttention 和 KV Cache显存是这样被“抠”出来的大模型生成每个 token都要把之前的 Key 和 Value 缓存下来这就是 KV Cache。这个缓存有多大以 7B 级别模型为例每多缓存一个 token 往往要吃掉几十到上百 KB 显存上下文越长越夸张。传统实现为了快会按最大可能长度一次性预分配显存但实际请求根本用不了那么多于是大量显存被占着却空转还碎成一片一片的。vLLM 的 PagedAttention 借鉴了操作系统内存分页的思路。KV Cache 不再是一整块连续显存而是拆成一个个物理块逻辑上连续的显存可以散落在不同的物理位置用到哪块才分配哪块。这个设计把显存利用率从原来的六七成拉到了接近九成以上。2.3 为什么低并发时 vLLM 的优势反而体现不出来这里必须说句公道话如果你只是单人在命令行界面下和模型对话vLLM 的高吞吐优势完全没有用武之地。吞吐需要“同时服务的请求数量”撑起来一个人只有一个请求再强的批处理调度也只是解一道题。更麻烦的是vLLM 为了追求大吞吐会引入一定程度的排队和调度开销在单请求场景下首字延迟甚至可能比 Ollama 还慢。所以经常有朋友跑来问我“为什么我装了 vLLM 反而感觉变慢了”因为场景根本不匹配。3. SGLang 的缓存复用思路以及无 NVLink 多卡的真实影响3.1 RadixAttention把重复计算的前缀直接砍掉SGLang 在工程上做得比较漂亮的一点是它的 RadixAttention 前缀树缓存机制。大家平时跑大模型很多请求的前缀是重复的。比如你搭了一个知识库问答系统每个问题前面都带着一大段“请你根据以下资料回答”这样的系统提示词和检索出来的文档再比如多轮对话每一轮都要带上前面好几轮的历史消息。这些前缀每个请求都在重复算一遍纯属浪费。SGLang 用一棵前缀树把 KV Cache 按公共前缀存起来。新请求过来时如果它的前缀在树里命中就直接复用模型只需要计算新增的部分。这个优化在 RAG、多轮对话这类场景里的收益是肉眼可见的——同样一堆请求算力消耗可能直接减掉一大半。vLLM 后来也做了 prefix caching但 SGLang 的树形结构粒度更细处理公共前缀的复用更激进。3.2 认真聊聊SGLang 无 NVLink 多卡影响多大被问得最多的一个具体问题是“我的服务器两张卡中间没有 NVLink用 SGLang 开张量并行会不会很吃亏”先说结论两张卡的情况下影响有但没有想象中那么致命。真正被拉开差距的是四卡以上的大集群。原理是这样的。张量并行TP要把模型切到多张卡上每一层做完之后都要跨卡同步一次权重结果这个操作叫 AllReduce。有 NVLink 时比如 H100 的 NVLink 带宽能达到 900GB/s 级别走 PCIe 4.0 x16 的话单向带宽只有大概 32GB/s差了一个数量级以上。模型切得越碎、上下文越长这个跨卡通信在每一步推理里占的时间比重就越大。具体到实践单卡能塞下的模型永远优先单卡跑别给自己找跨卡通信的麻烦。两张无 NVLink 的 24G 卡跑 14B 左右的量化模型TP2 能跑但你会感觉到比理论算力翻倍要慢不少正常现象。四张以上无 NVLink 的卡跑 70B 级别长上下文通信开销会明显拖后腿。这种场景我建议观望一下并行方式改用流水线并行或者干脆投资支持 NVLink 的平台。3.3 SGLang 部署时的常见启动报错SGLang 的启动命令不算复杂python -m sglang.launch_server \ --model-path /models/your-model \ --tp-size 2 \ --port 30000直观讲它同样暴露 OpenAI 兼容接口。最容易翻车的点有两个第一显存不够。SGLang 默认会尽量利用显存如果你模型切分加 KV Cache 超过物理显存会直接抛 CUDA OOM。解决思路是先量化模型、降低--max-total-tokens而不是无脑开--tp-size。第二离线部署时模型下载问题。我个人的建议是提前用相应工具把权重整体拉到本地目录启动时把--model-path指向这个本地路径。提前下载还有个额外好处后续启动非常快不用每次联网校验。4. vLLM 部署实战镜像、启动参数与显存估算4.1 为什么我建议你从 Docker 镜像入手vLLM 的本体是一个 Python 包但它在底层强依赖的 CUDA 编译器、Triton、PyTorch 版本之间的兼容性足够让人崩溃。你辛辛苦苦装好跑起来报一个版本不匹配的错误心态很容易爆炸。所以我推荐走官方 Docker 路线。官方镜像像vllm/vllm-openai:v0.27.1一样已经把 CUDA、PyTorch、Triton 全打包好了你只要给它传一块 GPU 就行。这样做还有个好处以后你想升级 vLLM 版本直接换镜像 tag 重新起容器不会把宿主机环境搞乱。4.2 一份可以直接改着用的启动命令docker run --gpus all \ -p 8000:8000 \ -v /models:/models \ --ipchost \ vllm/vllm-openai:v0.27.1 \ --model /models/deepseek-ai/DeepSeek-R1-Distill-Qwen-7B-AWQ \ --tensor-parallel-size 1 \ --gpu-memory-utilization 0.85 \ --max-model-len 8192 \ --served-model-name deepseek-r1-7b \ --trust-remote-code几个参数背后的逻辑我得讲清楚--gpu-memory-utilization 0.85表示把 85% 的显存预留给推理框架使用。别贪心调到 0.98模型权重、KV Cache、中间激活层还有 CUDA 自身都要吃显存你全部塞满稍微来几个长请求就 OOM。我自己的经验值是 0.85 到 0.92 之间。--max-model-len是单条请求的最大上下文长度它和 KV Cache 成正比。开 32K 很爽但显存占用会翻好几倍按需设置即可。--served-model-name是你对外公布的模型名。这里起个别名方便以后后端换模型不惊动调用方。4.3 显存估算先算清楚再下单很多人问我这个显卡到底能不能跑我来教你们一个粗算法。推理显存主要三块模型权重、KV Cache、运行时激活。以 7B 模型为例FP16 权重要 14GB用 4bit AWQ 或 GPTQ 量化后权重可以压到 4-5GB。KV Cache 在 7B 上每 token 大概是几十到上百 KB2K 上下文大概就是几百 MB 的量级。所以一张 24G 的 4090 跑 7B 模型量化版顺带开个 4K-8K 上下文完全没问题。如果跑 14B 量化版大概需要 8-10GB 权重剩余显存也能撑起中等长度上下文。想用 FP16 硬跑 70B 模型单张 24G 卡就别想了不是 Quantization 层级的优化能解决的必须多卡张量并行或者换更大显存的卡。4.4 API 兼容性与验证vLLM 跑起来之后是标准的 OpenAI 兼容接口你可以直接拿openai这个 Python 包来调用from openai import OpenAI client OpenAI( base_urlhttp://localhost:8000/v1, api_keyEMPTY ) resp client.chat.completions.create( modeldeepseek-r1-7b, messages[{role: user, content: 介绍一下 vLLM}] ) print(resp.choices[0].message.content)先启动服务再用curl http://localhost:8000/v1/models看一眼模型列表确认服务起来了再调代码能省很多排查时间。这里还有个容易踩的坑一个 vLLM 实例最好只服务一种模型类型。有人图省事想同时塞一个对话模型和一个 Embedding 模型进同一个服务经常出现路由混乱的问题。Embedding 模型要用专门的/v1/embeddings端点建议单独起一个容器。5. Ollama 与 llama.cpp桌面、老系统和端侧设备5.1 Ollama 的便利以及绕不开的毛病Ollama 最大的价值是“开箱即用”。以前我同事配个本地模型要折腾一上午用 Ollama 以后装好、选模型、拉取、开聊十分钟内完成。它默认监听 11434 端口/api/chat能直接支持聊天较新的版本也提供了/v1/chat/completions这种 OpenAI 兼容路径方便接各种客户端工具。你可以通过环境变量把模型存储目录改到其他盘例如# Linux 下修改模型目录 export OLLAMA_MODELS/data/ollama/models ollama serveWindows 下就在系统环境变量里加一个OLLAMA_MODELS指向你要放的盘符目录。注意先关掉 Ollama 再改改完重启才生效。Ollama 最让人头大的是下载速度和稳定性。网络波动时动不动拉半天下不动或者直接报500 internal server error: llama-server process这种错误。后者的排查思路通常是三步第一步看显存是否够模型量化档调低一档再试第二步看模型文件是不是没拉完整重新拉一遍模型第三步看是不是端口被占用或旧进程残留重启 Ollama 服务。还有一个很多人问的问题Ollama 里怎么关掉某些模型的思考过程。这个要看具体模型像 Gemma 或是带推理链的模型可以通过 API 参数控制推理努力程度或者调整停止符把分析部分截断。不同版本支持的参数不一样最稳妥的办法是去 Ollama 文档里查对应模型的能力参数或者干脆换一个不带固有思维链输出的量化版本。5.2 llama.cpp从 Windows 7 到 Android 都能跑llama.cpp 是我见过兼容性最离谱的推理引擎。它是纯 C/C 写的不需要 Python、不需要 PyTorch交叉编译之后在什么平台上都能塞。官方针对性适配了 ARM NEON、Apple Metal 这些指令集和框架就算没有 NVIDIA GPU靠 CPU 也能跑起来。Windows 7你没看错老机器也能跑。如果你还有 Win7 环境的部署需求别追最新 release去找支持该系统的老版本二进制。新版本对系统版本要求通常更高两者取舍看你能不能接受老版本缺少的新特性。Android两个途径。一是在 Termux 里编译二是用项目文档里提供的安卓演示版本。跑个小尺寸 4bit 量化模型没问题延迟也能接受。开发板像 RK3588 这类边缘设备跑一个 1-4B 的量化小模型做离线文案理解、指令解析都够了。注意llama.cpp 目前是纯语言模型主战场视觉类的 YOLO 任务还是要交给专门的视觉推理框架。5.3 GGUF 量化格式的选择逻辑llama.cpp 生态统一使用 GGUF 格式这也是它和 vLLM 那些引擎的一个关键差异。GGUF 的最大优势是单文件携带全部元数据拷到哪都能跑不需要去对齐 HuggingFace 的目录结构。量化档位里我的个人建议是Q4_K_M性价比之选日常使用首选模型体积大概是 FP16 的 30% 左右。Q5_K_M质量优先且显存够的时候选它比 Q4 更接近原始精度。Q8_0体积接近半精度显存充裕、追求质量时用。不到万不得已别用 Q2 档效果下降比较明显。Ollama 和 llama.cpp 可以共用 GGUF 模型所以如果你用 Ollama 拉模型遇到问题完全可以手动下载 GGUF 文件放进 Ollama 的模型目录里导入灵活度一下子高很多。6. 资源分档与选型结论照着这张表做决定6.1 按显存和硬件规模划分你的硬件推荐引擎模型规模建议注意事项8GB 显存以下 / 纯 CPUOllama 或 llama.cpp1-4B 量化模型优先 GGUF 的 Q4_K_M 档12-16GB 显存Ollama 或 llama.cpp7B-14B 量化模型本地个人使用首选 Ollama24GB 单卡vLLM 或 SGLang7B-14B 量化中长度上下文可以承载小团队 API 服务多卡 24G NVLinkvLLM 或 SGLang32B-70B 量化或蒸馏模型开 TP 并行把通信带宽用满多卡无 NVLinkvLLM 或 SGLang14B-32B 量化TP2四卡以上长上下文要谨慎老设备 / 开发板llama.cpp1-3B 量化优先利用 Metal/Vulkan/NEON 加速6.2 按使用形态划分个人桌面问答首选 Ollama或者有图形界面需求的选 LM Studio。这类工具底层大多也是 llama.cpp 的 GGUF 推理但给你封装好了模型管理不需要敲命令。小团队共享 APIvLLM。吞吐是硬指标OpenAI 兼容生态最成熟各种监测、灰度、路由工具都能直接接入。RAG、复杂多轮、批量离线任务SGLang。前缀缓存能显著节省算力尤其适合你们文档库和系统提示词很长、高度重复的场景。CPU 老电脑、嵌入式设备、端侧llama.cpp。没有比它更轻的选择。6.3 我的选择与掏心窝建议我自己办公桌上那张 4090平时就在 Ollama 里跑一个 14B 的量化模型够我日常写代码审文档用。给团队搭内部服务的时候我会单独起一个 vLLM 容器接上统一的 API 入口遇到压测高峰期也不会卡死。偶尔做 RAG 实验我会用 SGLang 看看前缀复用的效果。而那块旧笔记本和 Android 小平板清一色是 llama.cpp。最后分享一点个人的经验先定并发再定引擎。很多人一上来就纠结“哪个引擎速度快”但真正的决策变量其实是“同时服务多少人、跑多长上下文、显存容量多少”。这三个数字定了选型表一查答案基本就出来了。别听谁吹哪个框架天下第一就无脑换合适才是硬道理。