这几年做大模型应用,最常被问的一句话是:模型有了,用什么把它跑起来?开源推理引擎的选项越来越多,vLLM、SGLang、Ollama、llama.cpp 这四个名字几乎天天出现在各种群里。但真到选型时,不少人都犯过同一个错——别人说哪个快就用哪个,结果不是装不上,就是显存不够,要么接口和自己业务对不上。我在本地笔记本、单卡工作站、多卡服务器上都部署过开源模型,踩过的坑比教程里写过的步骤都多,下面这套选型逻辑和部署记录,应该能帮你少走点弯路。这篇内容不吹不黑,把四个引擎的机制差异、适用场景、部署步骤和常见问题一次讲清楚,适合正在做 AI 应用开发、想搞私有大模型,或者刚开始接触自建推理服务的朋友。
1. 开源推理引擎全景:它们到底在解决什么问题
1.1 推理引擎不是模型,而是“让模型跑起来的那层基础设施”
先说个常见误解。很多人以为推理引擎就是模型本身,其实完全不是一回事。模型训练完之后,留下来的是一堆权重文件,比如 safetensors、GGUF。推理引擎负责的是把权重加载进内存或显存、执行前向计算、管理 KV Cache、调度并发请求,最后对外暴露一个能调用的接口。可以打个比方:模型是菜谱,引擎是后厨,同样的菜谱在不同后厨做出来的速度和翻台率完全不一样。
那为什么开源社区会冒出这么多引擎?核心原因是需求分化得厉害。有人要把模型部署成高并发在线服务,每一毫秒都要抠吞吐量;有人只在个人电脑上跑个私有大模型,图省事和稳定;还有人要在没有独显的办公机上、甚至在 Android 手机上跑模型。需求完全不同,最优化方向自然不一样。没有哪个引擎是绝对王者,只有“在某个场景下最合适”的说法。
1.2 四个引擎的定位差异与适用画像
先把四个引擎的特点拉成一张表,这样后面看机制时脑子里有张地图:
| 引擎 | 定位 | 核心优势 | 典型场景 | 上手难度 |
|---|---|---|---|---|
| vLLM | 高并发服务化推理 | PagedAttention 显存优化、连续批处理吞吐高 | 线上 API 服务、批量推理、多卡部署 | 中 |
| SGLang | 前沿特性与结构化生成 | RadixAttention 前缀复用、约束解码 | 多轮对话、JSON/工具调用、长上下文 | 中高 |
| Ollama | 个人/私有化一键部署 | 模型管理完善、命令简单、开箱即用 | 本地聊天、知识库、开发调试 | 低 |
| llama.cpp | 轻量级底层内核 | 纯 C/C++、CPU 友好、支持 GGUF 量化 | 无 GPU 机器、安卓端、嵌入式 | 中 |
这里要特别注意,Ollama 和另外三个不完全在同一维度。Ollama 更像是一个“模型管家”,它底层吸收了 llama.cpp 等推理内核,再包了一层统一的命令行和 REST API。vLLM 和 SGLang 则从一开始就是奔着服务化去的,重点处理并发、批处理、显存复用这些底层问题。选型第一步不是比谁跑分高,而是想清楚自己手里有什么硬件、要跑什么业务、有多少并发。
2. 核心机制拆解:四款引擎各自怎么工作
2.1 vLLM 的 PagedAttention 与连续批处理机制
vLLM 能成为服务化部署的主流选择,靠的是两个关键机制。第一个是 PagedAttention,它解决的是 KV Cache 显存浪费的问题。在它出现之前,做推理时要按最大序列长度预分配 KV Cache 显存,哪怕很多请求根本用不到那么长,显存也一直占着。PagedAttention 把 KV Cache 切成固定大小的块,按需分配,不够了再申请,就像操作系统里的虚拟内存分页。每个请求不需要连续显存,碎片问题缓解了,显存利用率上来了,能同时跑的请求自然就多了。
第二个机制是连续批处理。传统批处理要等一批请求全部生成完才收下一批,前一个请求卡住了,整批都得等。vLLM 的做法是每个 step 动态决定:哪些请求继续生成、哪些已经结束可以腾位置、哪些新请求可以加进来。这么一来,吞吐量提升非常明显,显存一直处于“有活就干”的状态。与之配套的还有一套调度逻辑,热搜里常有人问 vLLM scheduler 是什么,简单说就是维护 waiting、running、swapped 三种队列:显存不够时把部分请求的 KV Cache 换到 CPU 上,腾出地方给新请求,显存空出来了再换回去。--max-num-seqs、--gpu-memory-utilization这些参数调的就是这套调度行为的边界。
2.2 SGLang 的 RadixAttention 与结构化解码
SGLang 和 vLLM 属于同一个赛道,但它的发力点更前沿。最核心的是 RadixAttention,中文可以理解为“路径前缀复用”。AI 服务的请求通常有大量共享前缀,比如多轮对话里后面每一轮都带着前几轮的历史,再加个系统提示词;再比如 RAG 场景下很多请求会带上同一段检索文档。SGLang 会对所有请求的 KV Cache 建一棵公共前缀树,识别出完全相同的前缀路径直接复用,不再重复计算。请求量越大、前缀重合度越高,这个优势越明显。
另一个让我非常喜欢的能力是结构化生成。它提供了一套前端 DSL,可以在请求里声明“输出必须符合 JSON Schema”“必须匹配某个正则”这类约束,后端在解码阶段直接按约束生成。什么意思呢?传统的做法是先让模型生成,再用程序去解析校验,失败了就重试,既浪费 token 又慢。SGLang 直接从源头保证输出格式合法,这对做工具调用、Agent 场景特别实用。代价是生态还在快速迭代,某些老模型或者冷门算子在 SGLang 上的兼容性不一定比 vLLM 稳,遇到问题要会看 GitHub Issues。
2.3 Ollama 的一体化体验与管理机制
Ollama 的优势不在底层调度,而是把整个流程包成了一个“傻瓜式”工具。它底层确实吸收了 llama.cpp 等内核的能力,但普通用户根本不需要关心 CG 编译、量化格式、KV Cache 这些细节。你只需要ollama pull qwen2.5:7b,它就自动下载合适的量化版本,一条ollama run qwen2.5:7b直接进交互式对话,再执行ollama serve就能提供http://localhost:11434的本地接口。
Ollama 还解决了模型文件管理的问题。不需要手动去 Hugging Face 或魔搭下载权重、自己指定路径,它会把模型放到固定目录(Windows 下默认是C:\Users\用户名\.ollama\models),用ollama list就能看到已下载了哪些模型。它提供了 OpenAI 兼容的接口,很多工具链可以直接接上来,比如 AnythingLLM、Dify、LangChain、Chroma,甚至桌面端的 Goose 这类 Agent 工具也能连本地 Ollama。这也解释了为什么“AnythingLLM 与 Ollama”“difi + Ollama”这些组合这么流行——都是因为这层 OpenAI 兼容接口降低了对接成本。
但 Ollama 的短板也很清楚,它的动态批处理和并发调度能力远不如 vLLM。如果你要支撑几十个用户同时调用,或者跑高吞吐的离线任务,它很容易成为瓶颈。它更适合个人调试、私有化使用和中小规模团队内部共享。
2.4 llama.cpp 的极简内核与全平台覆盖
llama.cpp 是这里资历最老、也是最“硬核”的一个。它用纯 C/C++ 实现,几乎不依赖外部库,可以跑到 Windows、Linux、macOS、Android,甚至是树莓派那种嵌入式环境。它对 CPU 推理做了大量优化,所以即使是老旧的笔记本,也能跑 7B 参数的量化模型,只是速度别抱太高期望。
它的另一个核心能力是 GGUF 量化格式。量化说白了就是把模型权重的高精度浮点数压成低精度整数,换来更小的体积和更低的内存占用。Q4_K_M、Q5_K_M、Q8_0 这些符号代表不同压缩级别。比如原始 7B 模型大约要 14GB 显存,用 Q4 量化后能压到 4GB 左右,代价是少量回答质量损失。对内存小的设备来说,这是能不能跑起来的关键。
llama.cpp 自带一个llama-server,启动后也提供 OpenAI 兼容 API。很多人不知道这一点,以为它只能命令行玩,其实完全可以作为本地服务挂给其他工具用,这也是“llama.cpp 本地编程助手”这类玩法的来源。比如在 VS Code 的 Continue 插件里配置一个本地 llama.cpp 服务,用几 GB 大小的 Code 模型,就能在断网环境下做代码补全和报错解释。手机端同样有安卓版,通过 Termux 这类环境跑小模型,应急查些技术问题完全够用。
3. 部署实操:从 Docker 到本地的完整流程
3.1 用 vLLM 部署一个 OpenAI 兼容服务(Docker 方式)
vLLM 的部署通常会直接上 Docker,因为本地 pip 安装要匹配一堆 CUDA、PyTorch 版本,很容易搞出依赖地狱。先说一个很多人问过的问题:Docker 镜像里带模型吗?答案是不带。官方镜像vllm/vllm-openai里只有推理引擎和运行环境,模型权重需要你自己下载,再通过目录挂载给容器用。我第一次用的时候以为镜像会内置模型,启动后直接报找不到模型文件,白等了半天。
具体的流程是四步。第一步,提前准备好模型目录。可以从魔搭社区这类国内平台下载模型的 safetensors 版本,放到宿主机某个目录,比如/models/deepseek-r1-distill-qwen-7b。第二步,拉取镜像。不建议直接用最新版 tag 跑生产,最好锁定具体版本,比如vllm/vllm-openai:v0.7.2,因为新版本升级快,偶尔会有 breaking change。第三步,执行 docker run 启动容器:
docker run --runtime nvidia --gpus all \ -v /models:/models \ -p 8000:8000 \ --ipc=host \ vllm/vllm-openai:v0.7.2 \ --model /models/deepseek-r1-distill-qwen-7b \ --served-model-name my-model \ --max-model-len 8192 \ --gpu-memory-utilization 0.9第四步,验证服务。请求http://localhost:8000/v1/models能看到模型列表,再通过/v1/chat/completions发一次对话测试。
这几个启动参数值得多解释一下。--served-model-name是给外部系统看的模型名,不影响实际加载的权重文件,业务系统固定写这个名字,以后换模型文件也不用改代码——但如果你要严格按“后来调用”,请知悉。--max-model-len决定了模型能处理的最大上下文长度,这个值直接影响 KV Cache 的显存占用,显存小就不要贪心。--gpu-memory-utilization控制 KV Cache 最多能占显存的比例,遇到 OOM 时先调这两个参数。多卡场景可以加--tensor-parallel-size,但它必须小于等于 GPU 数量,单卡机器不要设,我见过不少人单卡加了个--tensor-parallel-size 2然后启动失败。
3.2 用 Ollama 部署私有大模型:离线安装包、模型路径与镜像加速
Ollama 的部署省心很多,难点通常集中在几个小地方:安装、下载、路径。Windows 用户直接下ollamasetup.exe安装包,装完后命令行里敲ollama list验证是否正常。这里有个很常见的需求:如何把 Ollama 安装在 D 盘?严格说官方安装器比较难直接改安装目录,但真正占空间的不是程序本身,而是模型文件。所以正确做法是设置环境变量OLLAMA_MODELS,把它指到 D 盘某个目录,比如D:\ollama\models,设置完重启 Ollama,新拉的模型就会写在 D 盘。已经有模型的老用户,把旧的模型目录整体拷过去再改环境变量也行。
网上吐槽最多的就是“Ollama 下载太慢了”。这个问题的解法要分情况。如果只是偶尔一次网络慢,重复执行ollama pull,它有断点续传机制,重新拉取会接着下载。如果是稳定慢到没法用,我推荐一个不依赖代理的思路:去魔搭社区这类国内模型社区先把 GGUF 文件下载下来,然后写一个 Modelfile,内容大致是:
FROM ./qwen2.5-7b-instruct-q4_k_m.gguf再执行ollama create my-local-model -f Modelfile,模型就注册到本地库里了。这种方式完全不依赖 Ollama 的在线拉取,局域网内离线部署也是一样的做法。
日常使用就几条命令:ollama pull拉模型,ollama run对话,ollama list查看已下载的模型,ollama stop停止当前服务。很多朋友关心“注册 Ollama 账号手机号怎么填”——如果你只是本地用,根本不需要注册任何账号,Ollama 是本地服务,所有功能开箱即用;不要把网页社区账号和本地部署混为一谈。
3.3 llama.cpp 部署:本地编程助手与 Android 端
llama.cpp 的部署可以从 Release 页面下载预编译包,Windows 用户拿 zip 包解压就能用,Android 用户找对应的 APK 版本。如果你想自己编译,也是一条命令的事:
cmake -B build -DCMAKE_BUILD_TYPE=Release cmake --build build --config Release -j启动本地服务用llama-server,最简命令是:
llama-server -m /models/qwen2.5-7b-instruct-q4_k_m.gguf \ --port 8080 \ -ngl 99 \ --alias qwen25这里-ngl 99表示尽可能多地把层放到 GPU 上,直接设成 99 就是“全部放 GPU”的意思;如果是纯 CPU 机器,设成-ngl 0反而能避免不必要的显存检测。--alias是给模型起个别名,方便调用时记忆。
我之前在无 GPU 的办公机上配过一个本地编程助手,流程是这样的:拉一个 3B 到 7B 的 Code 类模型 GGUF 量化版,启动llama-server,然后在 VS Code 里装 Continue 插件,把 Model Provider 配成 OpenAI 兼容接口,base URL 填http://localhost:8080/v1。效果虽然比不上云端大模型,但胜在完全离线、代码不出本机,用来解释报错、生成测试用例、补全常见函数完全够用。
3.4 SGLang 部署要点
SGLang 的启动方式和 vLLM 很像,最小化启动命令是:
python -m sglang.launch_server \ --model-path /models/deepseek-r1-distill-qwen-7b \ --host 0.0.0.0 \ --port 30000如果要支持多卡并行,可以用--tp指定张量并行数。不过这里要提醒一句,并行参数不是越多越好,--tp必须和你的 GPU 拓扑、显存大小匹配,乱设容易直接启动失败或者训练出很低效的通信开销。SGLang 里和显存强相关的参数是--mem-fraction-static,它控制静态 KV Cache 显存占比,显存紧张时往低了调,效果等同于 vLLM 的--gpu-memory-utilization。
SGLang 最适合发挥的场景是带约束的输出。比如有些业务需要模型严格返回 JSON,普通推理引擎可能要你写 JSON Mode 或者碰运气,但 SGLang 可以直接声明 JSON Schema 来硬约束输出结构。如果只是普通聊天,它未必比 vLLM 有明显差距;但如果你是做 Agent 调用、RAG 管道、或者多轮对话里大家共享同一段上下文,它的前缀复用优势会非常直观。
4. 常见问题与排查技巧实录
4.1 Ollama 常见报错和模型下载问题
先聊聊高频问题:ollama run直接报 500 internal server error,信息里通常带一句llama-server process。这个报错不是单一原因,我至少遇过四种情况:模型文件没下完整、磁盘空间被写满、内存不够、模型版本和 Ollama 版本不兼容。排查思路按顺序来。先看磁盘空间,模型体积动辄几个 GB,C 盘满了最容易被忽略。然后用ollama list看已下载模型的大小,如果模型标称十几 GB,列表里显示只有几 GB,基本就是没下完,重新ollama pull就行。最后不行就看日志,Windows 日志文件在C:\Users\用户名\AppData\Local\Ollama\server.log,或者直接前台执行ollama serve看终端输出,很多真正的错误信息都在日志里。
Ollama 的模型管理也值得多说两句。热搜里有人问“如何查看 Ollama 下载了哪些模型”,其实一条ollama list就解决了,显示的是模型标签、大小和拉取时间。还有人问“Ollama 怎么强制某个模型不思考”,这要看具体模型是否内置了思考开关。最通用的办法是在系统提示词里直接写“不要输出思考过程”,有些推理模型会遵守。如果你是调用 OpenAI 兼容接口,可以试着在请求体里传think相关的参数,具体字段名取决于模型训练时的设计,建议先看模型卡文档再动手。
4.2 vLLM 部署常见坑:镜像版本、参数与显存
vLLM 的部署坑主要集中在三个位置。第一个是版本匹配。新模型架构对 vLLM 版本有依赖,比如 GLM、DeepSeek 这类模型,官方通常会在模型卡里写“Recommended vLLM version”。我的习惯是部署前先去对应模型的 GitHub 页面或模型卡里敲一眼,没有明确要求就用近三个月内发布的稳定版镜像,不要直接用 latest。第二个是模型目录挂载不对。再次强调,镜像里没有模型,启动报“model not found”时先检查-v是否把宿主机模型目录正确挂进了容器,容器里的路径和启动参数里的--model是否一致。第三个是显存 OOM。遇到这个先调--max-model-len,8K 改 4K,显存占用立刻下来;再不够就调低--gpu-memory-utilization到 0.7 甚至 0.6;最后再用nvidia-smi检查是不是有其他进程抢了显存。
关于“vLLM 部署 DeepSeek 用什么参数”,如果是 DeepSeek-R1-Distill 系列蒸馏模型,权重架构其实是 Qwen 或 Llama,vLLM 会自动匹配模型模板,常规对话场景不需要额外加高级参数。重点就是控制好--max-model-len和--gpu-memory-utilization。原版超大模型如果没有足够的 GPU 集群资源,不建议硬上,先用蒸馏版验证链路。
4.3 选型速查表与避坑经验
把选型经验压缩成一张速查表,方便以后直接抄:
| 实际场景 | 优先级推荐 | 理由 |
|---|---|---|
| 个人没事聊聊天、写写文案 | Ollama | 一键拉模型,够省事 |
| 团队内部几十人共用一个小 API | Ollama 或 vLLM | 并发低用 Ollama,并发上来换 vLLM |
| 线上高并发、对外提供 API | vLLM | 连续批处理和显存调度强 |
| 业务要求严格 JSON / 工具调用 | SGLang | 约束解码省 token 且稳定 |
| 老电脑、无独显、安卓端 | llama.cpp | CPU 优化好,GGUF 体积小 |
| LangChain + Chroma 本地知识库 | Ollama | Embedding 模型管理方便,接口兼容 OpenAI |
再补几条我用真金白银换来的经验。第一,先明确场景再选引擎,不要看哪个项目 star 多就换哪个。第二,模型格式要和引擎匹配,vLLM 原生模型尽量用 safetensors,Ollama 和 llama.cpp 用 GGUF,跨格式混用不是不行,但会平白多一道转换和兼容的坑。第三,所有主流引擎都提供 OpenAI 兼容接口,业务代码里最好统一走/v1路径,把 base URL 抽成配置。这样后天想从 Ollama 换到 vLLM,改一个地址就行,代码不用动。第四,小步快跑,先用 3B 或 7B 的小模型把整个链路调通,再换大模型。很多人在 70B 模型上花了两小时排查接口问题,最后发现用 7B 模型十分钟就能定位到是代码的 bug 而不是模型的问题。
我个人在实际操作中的体会是,日常 80% 的需求其实 Ollama 就能搞定,剩下 18% 是 vLLM 的主场,最后那 2% 的长尾场景才轮到 llama.cpp 和 SGLang 出手。工具这种东西,不是越高级越好,而是看它能稳稳接住你的哪部分工作。选型定下来之后,还有一个经常被忽略的小技巧:每个引擎启动服务前,先用一条最简单的 curl 请求验证接口通了,再开始接业务逻辑。这一步能帮你把“引擎问题”和“业务代码问题”迅速切分开,省下大量排查时间。希望这篇内容能让你在开源推理引擎里找到顺手那把刀。