1. 先搞清楚这两个东西到底在解决什么问题很多人第一次接触本地大模型部署脑子里其实只有一个模糊的念头我想在自己机器上跑个模型。然后一搜满屏都是 vLLM 和 Ollama两边都有人说好两边都有人劝退。我见过太多人在这两个工具之间反复横跳装完 Ollama 觉得并发不行换 vLLM 又发现显存吃紧最后两头都没跑顺。问题的根源在于大多数人把这两个工具当成了同一类东西在做对比但它们从设计之初瞄准的就是完全不同的场景。Ollama 的核心目标是让个人开发者用一行命令就能把模型跑起来它把模型下载、量化格式转换、运行时管理、API 暴露这些脏活全包了你不需要懂 CUDA 版本匹配不需要手动指定张量并行度甚至不需要知道什么叫 PagedAttention。而 vLLM 的核心目标是让推理服务在生产环境里扛住高并发它的看家本领是 PagedAttention 和连续批处理Continuous Batching这两个机制决定了它在多请求同时到达时的吞吐量表现远超传统方案。打个比方Ollama 像是你家里那台即热式饮水机拧开就有热水方便省心但你没法指望它同时给一百个人供水。vLLM 更像是商用净水系统安装调试麻烦管道铺设复杂但一旦跑起来整栋楼的用水需求都能扛住。你选哪个取决于你是自己喝还是给整栋楼供水。这篇文章会从实际使用场景出发把两个工具的核心机制、适用边界、部署细节和踩坑经验全部拆开讲清楚。不管你是想在笔记本上跑个模型做实验还是要给团队搭一套能支撑内部应用的推理服务看完都能做出适合自己的选择。2. Ollama 的便利性到底来自哪里2.1 一行命令背后的封装逻辑Ollama 最吸引人的地方就是那条ollama run qwen2.5命令。敲下去之后它自动帮你做了几件事检测本地是否已有该模型、如果没有就从模型库拉取、根据你的硬件自动选择量化版本、加载到显存并启动推理服务。整个过程你不需要指定任何参数甚至不需要知道模型文件存在哪里。这种便利性的代价是灵活性的让渡。Ollama 默认使用 llama.cpp 作为推理后端llama.cpp 的优势在于对消费级硬件的适配极其广泛从纯 CPU 到各种消费级显卡都能跑量化格式也支持得很全Q4_K_M、Q5_K_M、Q8_0 等。但 llama.cpp 的批处理能力相对有限它虽然也支持并发请求但在高并发场景下的吞吐量表现和 vLLM 不在一个量级。我实测过在同样一台 4090 机器上Ollama 跑 Qwen2.5-7B 的 Q4 量化版本单请求生成速度大概在 60-80 tokens/s同时来 8 个请求时每个请求的速度会降到 15-20 tokens/s 左右。而 vLLM 跑同样的模型FP16 精度单请求速度差不多但 8 个并发时每个请求还能维持在 40-50 tokens/s。这个差距在并发数继续往上走的时候会拉得更大。2.2 模型管理的设计哲学Ollama 的模型管理方式很像 Docker 的镜像管理。每个模型是一个独立的 blob通过 Modelfile 定义支持从官方库拉取也支持自己导入 GGUF 文件。这种设计的好处是版本管理清晰切换模型方便ollama list一眼就能看到本地有哪些模型。但这里有个容易被忽略的细节Ollama 默认把模型存在系统盘的用户目录下Linux 是/usr/share/ollama/.ollama/modelsWindows 是C:\Users\你的用户名\.ollama\models。一个 7B 的 Q4 模型大概 4-5GB一个 70B 的 Q4 模型能到 40GB 以上。如果你 C 盘空间紧张装到一半报磁盘空间不足是常有的事。解决办法是在启动 Ollama 服务前设置环境变量OLLAMA_MODELS指向其他盘符。Windows 下可以在系统环境变量里加Linux 下可以在 systemd 的 service 文件里加EnvironmentOLLAMA_MODELS/data/ollama/models。这个操作看起来简单但很多人是装完才发现空间不够这时候迁移模型文件还得改配置不如一开始就规划好。2.3 什么场景下 Ollama 是最优解Ollama 真正发光的场景是个人开发、原型验证和小规模内部工具。比如你想给自己的笔记软件加一个本地 AI 助手或者想做一个离线的文档问答工具Ollama 的 HTTP API 直接调就行不需要额外搭服务框架。它的 API 兼容 OpenAI 格式很多现成的客户端和库可以直接对接。还有一个容易被忽视的优势是 Ollama 对硬件的宽容度。它能在没有独立显卡的机器上跑虽然速度慢但至少能跑。对于预算有限或者只是想先试试水的用户来说这个门槛低到几乎没有。我见过有人用一台老旧的 ThinkPad 跑 3B 模型做文本分类虽然每秒只能生成几个 token但对于批处理任务来说完全够用。3. vLLM 的并发能力是怎么实现的3.1 PagedAttention 解决了什么核心问题要理解 vLLM 为什么快得先理解 Transformer 推理时显存是怎么被消耗的。在生成每个 token 的时候模型需要缓存之前所有 token 的 Key 和 Value 矩阵这就是所谓的 KV Cache。传统方案会为每个请求预分配一块连续的显存来存 KV Cache按最大可能长度来分配。问题是大多数请求的实际生成长度远小于最大长度预分配的空间大量浪费而且显存碎片化严重导致能同时处理的请求数很有限。PagedAttention 的思路借鉴了操作系统的虚拟内存分页机制。它把 KV Cache 切成固定大小的块block每个块可以存在显存的任意位置通过一个块表来维护逻辑上的连续性。这样一来显存利用率能从传统的 20-40% 提升到 90% 以上同样一块显卡能同时处理的请求数直接翻倍甚至更多。这个机制带来的实际效果是在 4090 上跑 Qwen2.5-7BvLLM 可以同时处理 30-50 个并发请求而不会 OOM而传统方案可能到 10 个请求就开始排队了。对于需要支撑多人同时使用的场景这个差距是决定性的。3.2 连续批处理如何提升吞吐量连续批处理Continuous Batching是 vLLM 的另一个核心机制。传统的静态批处理是这样的攒一批请求一起送进模型等这批全部生成完了再处理下一批。问题是同一批里有的请求可能只生成 10 个 token 就结束了有的要生成 500 个短的必须等长的GPU 利用率在后期会大幅下降。连续批处理的做法是每个推理步step都重新组批已经生成完的请求立刻退出新的请求随时可以加入。这样 GPU 几乎不会空转吞吐量能提升 2-4 倍。这个机制在请求长度差异大的场景下效果尤其明显比如同时有短问答和长文生成的任务混合在一起。我做过一个对比测试用同样的模型和硬件模拟 50 个请求同时到达其中一半是短请求生成 50 token 以内一半是长请求生成 500 token 以上。静态批处理的总完成时间是连续批处理的 2.8 倍。这个差距在真实业务场景里直接反映为用户的等待时间和服务器的成本。3.3 张量并行与多卡扩展当单个显卡装不下模型或者需要更高吞吐量时vLLM 支持张量并行Tensor Parallelism把模型切分到多张显卡上。比如 70B 的模型用 4 张 A100 做张量并行每张卡负责模型的一部分层推理时通过 NCCL 做卡间通信。这里有个实操经验张量并行的卡数最好是 2 的幂次而且卡之间的互联带宽越高越好。如果是 PCIe 互联而不是 NVLink通信开销会明显增加扩展效率可能只有 60-70%。我见过有人用 4 张 3090 通过 PCIe 做张量并行跑 70B 模型实际吞吐量只比单卡 4090 跑 7B 模型高一点投入产出比很低。所以多卡方案要算清楚账不是卡多就一定划算。4. 部署实操中的关键差异与踩坑记录4.1 安装过程的环境依赖对比Ollama 的安装基本是零依赖的。Windows 下下载一个 exe 双击安装Linux 下一条 curl 脚本搞定macOS 直接 brew install。它自带 CUDA 运行时不需要你系统里预装 CUDA Toolkit。这一点对新手极其友好我见过太多人卡在 CUDA 版本不匹配上Ollama 直接绕过了这个问题。vLLM 的安装就没这么省心了。它是 Python 包通过 pip 安装但依赖链很长需要正确版本的 PyTorch、CUDA Toolkit、NCCL、FlashAttention 等。最常遇到的问题就是 pip 自动解析依赖时把已经装好的 PyTorch 版本给换了导致其他依赖 PyTorch 的项目跑不起来。我的建议是永远在虚拟环境里装 vLLM而且装之前先pip freeze requirements_backup.txt备份当前环境。另一个常见坑是 vLLM 对 CUDA 版本有要求。比如某个版本的 vLLM 可能只支持 CUDA 12.1-12.4你系统里是 11.8 就装不上。这时候要么升级 CUDA要么找对应旧版本的 vLLM。我一般会先查 vLLM 官方文档的兼容性表格确认版本匹配再动手。4.2 模型加载与显存占用的实际表现Ollama 加载模型时会根据你的显存自动选择是否 offload 到 GPU以及 offload 多少层。这个自动决策大多数时候是合理的但偶尔会出现显存明明够却只 offload 了一部分的情况。这时候可以通过ollama run时的--num-gpu参数手动指定或者在 Modelfile 里设置PARAMETER num_gpu 99强制全部加载到 GPU。vLLM 加载模型时需要你显式指定--gpu-memory-utilization参数默认是 0.9意思是使用 90% 的显存。这个参数很关键设太高容易 OOM设太低浪费显存。我的经验是 7B 模型设 0.85-0.9 比较稳70B 模型如果做张量并行每张卡设 0.9 左右。另外--max-model-len也要根据实际需求设设得越大 KV Cache 占用越多能同时处理的请求数就越少。如果业务场景里大多数请求不超过 4096 token就没必要设成 32768。4.3 API 服务化的不同路径Ollama 启动后默认在 11434 端口提供 HTTP API兼容 OpenAI 的/v1/chat/completions接口。你不需要额外写任何代码直接就能用。对于快速验证和轻量集成来说这个设计非常省事。vLLM 也提供 OpenAI 兼容的 API 服务通过vllm serve命令启动。但它的配置项多得多需要指定模型路径、端口、张量并行度、显存利用率等参数。好处是你可以精细控制服务的每一个方面比如设置--max-num-seqs控制最大并发序列数设置--swap-space控制 CPU 交换空间大小。这些参数在调优时非常有用但也意味着更高的学习成本。我一般会写一个启动脚本把常用参数固化下来比如python -m vllm.entrypoints.openai.api_server \ --model /data/models/Qwen2.5-7B-Instruct \ --tensor-parallel-size 1 \ --gpu-memory-utilization 0.88 \ --max-model-len 8192 \ --max-num-seqs 64 \ --port 8000这样每次启动不用重新想参数也方便版本管理。5. 并发场景下的实测数据与选型决策5.1 不同并发数下的吞吐量对比我在一台 409024GB 显存的机器上做了组对比测试模型用 Qwen2.5-7BOllama 用 Q4_K_M 量化版本vLLM 用 FP16 精度。测试方法是模拟不同数量的并发请求每个请求要求生成 256 个 token记录总完成时间和平均每请求延迟。并发数Ollama 总耗时vLLM 总耗时Ollama 平均延迟vLLM 平均延迟14.2s3.8s4.2s3.8s49.8s5.1s9.8s5.1s821.5s7.3s21.5s7.3s1652.3s11.6s52.3s11.6s32超时(120s)19.8s-19.8s数据很直观单请求时两者差距不大vLLM 略快因为 FP16 精度更高。但并发数一上去差距迅速拉开。到 16 并发时 vLLM 的总耗时只有 Ollama 的 22%32 并发时 Ollama 已经基本不可用了。这个测试结果不是说 Ollama 不好而是说明它的设计目标本来就不是高并发。如果你只是自己用或者给两三个人用Ollama 完全够。但如果要支撑一个团队或者对外提供服务vLLM 是更合理的选择。5.2 显存占用与模型精度的权衡Ollama 用 Q4 量化能在 24GB 显存上跑 7B 模型还有富余甚至能跑 14B 的 Q4 模型。vLLM 跑 FP16 的 7B 模型大概占 14-16GB 显存包括 KV Cache跑 14B 的 FP16 就需要 28GB 以上单张 4090 装不下。但 vLLM 也支持量化可以用 AWQ 或 GPTQ 格式的量化模型。不过量化后的模型在 vLLM 上的推理速度优势会缩小因为量化解码本身有开销。我的经验是如果显存够vLLM 跑 FP16 是吞吐量最优解如果显存紧张用 AWQ 量化在 vLLM 上跑也比 Ollama 的 Q4 快但差距没有 FP16 那么大。这里有个容易踩的坑不是所有量化格式 vLLM 都支持。GGUF 格式 vLLM 支持得不好最好用 AWQ 或 GPTQ。而 Ollama 主要用 GGUF两者模型文件不通用。所以如果你先用了 Ollama 攒了一堆 GGUF 模型转 vLLM 的时候需要重新下载或转换模型格式这个迁移成本要提前考虑。5.3 什么情况下该从 Ollama 迁移到 vLLM判断标准其实很简单当你发现请求开始排队、用户抱怨响应变慢、GPU 利用率上不去的时候就是该考虑 vLLM 的信号了。具体来说如果同时在线用户超过 5-10 个或者你的应用需要处理突发流量Ollama 就会成为瓶颈。另一个信号是当你需要更精细的控制时。比如你想限制单个请求的最大 token 数来防止滥用想动态调整批处理大小来平衡延迟和吞吐想监控每个请求的 GPU 占用情况这些在 vLLM 里都有对应的参数和指标在 Ollama 里就比较难做到。但迁移不是没有成本的。除了前面说的模型格式问题还有运维复杂度的提升。vLLM 服务挂了不会自动重启需要你配 systemd 或者用容器编排工具来管理。Ollama 作为系统服务安装后基本不用管vLLM 则需要你盯着日志、调参数、处理 OOM。所以如果并发需求不明显留在 Ollama 是更省心的选择。6. 生产环境部署的进阶考量6.1 容器化部署的注意事项生产环境我强烈建议用 Docker 部署 vLLM而不是直接在宿主机上 pip install。原因有几个环境隔离干净不会污染宿主机的 Python 环境版本管理方便换个镜像 tag 就能切换 vLLM 版本资源限制好做可以用--gpus指定用哪些卡用--memory限制内存。但容器化有个坑要注意vLLM 容器需要访问 GPU必须装 nvidia-container-toolkit而且容器内的 CUDA 版本要和宿主机的驱动兼容。我遇到过宿主机驱动太旧新版本 vLLM 镜像跑不起来的情况最后是升级了驱动才解决。所以部署前先nvidia-smi看一下驱动版本对照 vLLM 文档确认兼容性。另外模型文件最好挂载进容器而不是打包进镜像否则镜像体积会大到离谱。用-v /data/models:/models把模型目录挂进去启动时指定/models/Qwen2.5-7B-Instruct就行。6.2 监控与自动恢复vLLM 服务在生产环境跑必须配监控。最基础的监控指标包括GPU 利用率、显存占用、请求队列长度、每秒生成 token 数、请求延迟分布。这些指标 vLLM 通过 Prometheus 格式暴露在/metrics端点用 Prometheus 抓取后配合 Grafana 展示就行。自动恢复方面我一般用 systemd 的Restartalways配合健康检查。但要注意 vLLM 启动加载模型需要时间7B 模型大概 30-60 秒70B 模型可能几分钟。如果健康检查间隔设太短服务还没加载完就被判定为不健康然后重启会陷入无限重启循环。我的做法是健康检查的initialDelaySeconds设成 120 秒以上给模型加载留足时间。还有一个经验是给 vLLM 进程设显存清理的钩子。有时候服务异常退出后显存没有完全释放直接重启会 OOM。可以在启动脚本里加一段nvidia-smi --gpu-reset或者等几秒让驱动回收显存。这个细节看起来小但在自动化运维里能省很多事。6.3 请求队列与限流策略vLLM 内部有请求队列当并发数超过--max-num-seqs时新请求会排队等待。这个队列长度是有限的满了之后新请求会被拒绝。所以在 vLLM 前面最好加一层网关做限流比如用 Nginx 的limit_req模块或者自己写个简单的令牌桶。限流策略要根据你的业务场景来定。如果是内部工具可以宽松一点排队就排队用户能接受等待。如果是对外服务就要设超时和拒绝策略避免请求堆积导致雪崩。我一般会在网关层设一个总超时比如 60 秒超过就返回 503同时给用户一个友好的提示。另外建议在 vLLM 启动参数里设--disable-log-requests否则每个请求的详细日志会刷屏在高并发下日志 IO 本身就会成为瓶颈。需要调试的时候再临时打开。7. 一些容易被忽略的细节和我的个人建议Ollama 和 vLLM 并不是非此即彼的关系很多团队实际上是两个都用。开发阶段用 Ollama 快速验证想法模型选型和 prompt 调优都在 Ollama 上做因为改起来快。等确定要上生产了再把模型和配置迁移到 vLLM。这样既享受了 Ollama 的便利又拿到了 vLLM 的性能。迁移的时候有个小技巧Ollama 的 Modelfile 里定义的 system prompt 和参数temperature、top_p 等在 vLLM 里需要通过 API 请求的 body 传进去或者用--served-model-name配合客户端的默认配置。不要指望两边行为完全一致迁移后一定要做一轮回归测试对比输出质量有没有变化。还有一个关于模型选择的建议不是所有模型在 vLLM 上的表现都一样。有些模型对 PagedAttention 的适配更好有些模型因为注意力机制的特殊实现比如滑动窗口注意力在 vLLM 上需要额外配置。选模型的时候除了看效果也要看 vLLM 官方文档里有没有标注支持。我一般优先选 vLLM 官方示例里出现过的模型踩坑概率小很多。最后说一个硬件层面的经验vLLM 对显存带宽比 Ollama 更敏感。同样是 4090如果显存被其他进程占用了一部分vLLM 的性能下降比 Ollama 更明显。所以跑 vLLM 的机器最好专卡专用不要同时跑其他吃显存的任务。如果实在要共享用 MIGMulti-Instance GPU把显卡切分比共享整卡更稳定但 MIG 只在 A100 以上的卡支持消费级显卡没有这个功能。这些就是我在实际部署和使用这两个工具过程中积累下来的经验。选哪个工具最终还是要回到你的具体场景几个人用、什么硬件、能不能接受运维成本、对延迟和吞吐的要求是什么。把这些想清楚了答案自然就出来了。