vLLM与Ollama本地部署大模型:从脚本到生产的实战指南

为什么单机脚本调用无法满足生产需求
在上手大模型时,很多人的第一步是下载一个开源模型(如 Qwen),然后用 ModelScope 或 Transformers 加载分词器和模型,实例化 tokenizer 和 model,最后调用 model.generate() 完成文本生成。
model.generate() 是 Hugging Face Transformers 库提供的文本生成方法,底层实现了自回归解码(autoregressive decoding)过程:模型每次根据已有的 token 序列预测下一个 token,然后将新 token 拼接到序列末尾,循环往复直到满足停止条件。这一过程支持多种解码策略,包括贪心搜索(Greedy Search)、束搜索(Beam Search)、Top-k 采样和 Top-p(Nucleus)采样等。
具体来说,贪心搜索每一步都选择概率最高的 token,生成结果确定但容易陷入重复或局部最优;束搜索同时维护 k 条候选路径(beam),在每一步扩展所有候选并保留得分最高的 k 条,能找到全局更优的序列,但计算开销随 beam width 线性增长。Top-k 采样在每一步只从概率最高的 k 个 token 中随机采样,引入了多样性但可能采到不合理的候选;Top-p(Nucleus)采样则更为灵活,它动态选取累积概率超过阈值 p 的最小 token 集合进行采样,当模型置信度高时候选集自动缩小,不确定时自动放大,因此在生成质量和多样性之间取得了更好的平衡,也是当前生产环境中最常用的采样策略。
虽然接口简洁,但 model.generate() 是单线程、同步阻塞的调用方式,不具备请求排队、批处理(batching)和异步响应能力,因此无法直接用于多用户并发的生产场景。
这套流程确实能跑通,但它有一个根本性的局限:只能在模型下载所在的那台服务器上操作。
换句话说,这种方式本质上只是加载权重文件做了一个 demo 级别的生成演示,与真实的生产环境相去甚远。在实际业务中,一个大语言模型(LLM)需要接受来自各式各样用户的请求,这些请求可能来自多个不同的服务器;甚至你的业务代码和模型部署都不在同一台机器上——代码在 server1,模型在 server2,这种跨机部署的场景非常普遍。

要解决这些问题,就需要把模型做本地化部署,将它从一个孤立的脚本变成一个可以被广泛调用的服务。
大模型部署的三大核心目标
在选择 vLLM 或 Ollama 这类具体工具之前,先要搞清楚大模型本地部署到底要解决什么问题。总结下来主要有两大方向:高效部署与可被访问。
显存与性能的平衡:追求最优性价比
高效部署首先体现在显存的性价比上。关键不是追求最小显存,也不是盲目堆砌最高配置,而是找到性价比最高的方案。核心是要平衡「显存占用与推理速度」和「模型性能」这两组关系。
如果把模型的全部权重参数都放到显存上做推理,效果无疑最好,但显存占用也最大。以 7B 参数的模型为例,FP16(半精度浮点数)下每个参数占 2 字节,仅模型权重就需要约 14GB 显存,加上 KV Cache(注意力层的键值缓存)、激活值和框架开销,实际需求通常在 16-20GB 以上。
这里需要特别理解 KV Cache 为何是显存占用的大头。在 Transformer 的自注意力机制中,每生成一个新 token,模型都需要用到之前所有 token 的 Key 和 Value 向量来计算注意力权重。如果每次都重新计算整个序列的 K/V,计算量会随序列长度呈二次增长,效率极低。KV Cache 的策略是将已计算过的 K/V 向量缓存在显存中,每一步只需计算新 token 对应的 K/V,然后与缓存拼接即可。这大幅降低了计算量,但代价是显存占用随序列长度和并发请求数线性增长。对于一个 7B 模型、序列长度 2048、32 层注意力、128 维度的 head,单个请求的 KV Cache 就可能占用数百 MB 到数 GB 显存,当并发用户增多时,KV Cache 往往比模型权重本身还占空间,成为显存管理中最关键的优化对象。
反过来,如果为了省显存把所有权重全塞到 CPU 上,虽然不占用 GPU,但推理速度会慢到几乎不可用。这是因为 GPU 的并行计算能力(数千个 CUDA 核心同时执行矩阵运算)天然适合 Transformer 中密集的矩阵乘法操作,而 CPU 虽然单核性能强、擅长复杂逻辑控制,但并行度远不及 GPU。以 NVIDIA A100 为例,其 FP16 算力可达 312 TFLOPS,而高端服务器 CPU 的浮点算力通常只在个位数 TFLOPS 级别,差距可达两个数量级。因此,在模型推理这种计算密集型任务上,CPU-only 方案的延迟往往是 GPU 方案的数十倍甚至上百倍。
为降低显存压力,业界广泛采用量化(Quantization)技术,如 GPTQ、AWQ、GGUF 等格式,将权重从 FP16 压缩到 INT8 甚至 INT4,可将显存占用降至原来的 1/2 到 1/4,代价是模型精度会有一定程度的损失。
这三种量化方案各有侧重:GPTQ(GPT-Quantization) 是一种训练后量化方法(Post-Training Quantization),基于近似二阶信息(Hessian 矩阵的逆)逐层量化权重,在 INT4 精度下就能保持接近 FP16 的模型表现,是 GPU 推理场景中最广泛使用的量化格式之一。AWQ(Activation-aware Weight Quantization) 则观察到模型权重中只有约 1% 的「显著权重」(salient weights)对激活值影响巨大,它通过保护这些关键通道并对其余权重激进量化,在相同比特数下通常比 GPTQ 有更好的精度保持,且量化速度更快。GGUF(GPT-Generated Unified Format) 是 llama.cpp 生态定义的量化格式,提供了从 Q2_K 到 Q8_0 等十余种量化级别,最大的优势是对 CPU 推理的深度优化,支持纯 CPU 或 CPU+GPU 混合推理,非常适合没有高端显卡的设备。选择哪种量化方案,取决于你的硬件条件(纯 GPU、纯 CPU 还是混合)、精度要求和部署框架的兼容性。
值得一提的是,量化并非没有代价。在实践中,从 FP16 到 INT8 的量化通常对模型性能影响较小(perplexity 增幅在 1% 以内),但进一步压缩到 INT4 时,某些知识密集型任务(如专业领域问答、数学推理)的准确率可能出现明显下降。业界通常建议在量化后对目标任务进行基准测试(benchmark),确认精度损失在可接受范围内再投入生产使用。
找到量化精度与模型表现之间的最佳平衡点,正是「显存性价比」这一命题的核心所在。因此,如何用合理的显存部署出最高效的模型,是本地大模型面向生产时必须考虑的成本问题,而部署方案正是其中的关键变量。

部署的便捷性:一两行命令搞定
第二个维度是部署的便捷程度。理想的部署方式应该是「一两行命令就能解决」,而不是写一大堆代码再反复调试。我们期望有统一、稳健的 API 接口,能够适配各类模型的部署需求。
当前业界已形成以 OpenAI API 格式为事实标准的接口规范,主要包括 /v1/chat/completions(对话补全)和 /v1/completions(文本补全)两个端点,请求和响应均使用 JSON 格式。
OpenAI API 格式之所以能成为事实标准,不仅因为 OpenAI 是大模型商业化的先行者,更因为这套接口设计本身足够简洁和通用:请求体中用 messages 数组描述对话历史(包含 system、user、assistant 等角色),用 temperature、top_p、max_tokens 等参数控制生成行为,响应体则统一返回 choices 数组。这种设计抽象程度恰到好处——既屏蔽了底层模型架构的差异(无论是 GPT、Qwen 还是 LLaMA),又保留了足够的控制粒度。因此,围绕这一接口已经形成了庞大的工具生态,包括 LangChain、LlamaIndex、OpenAI Python SDK、各种 IDE 插件(如 Cursor、Continue)等,都默认支持这一格式。当你的本地模型服务兼容 OpenAI API 时,就等于自动接入了整个生态,这远比自定义接口带来的工程价值大得多。
此外,OpenAI API 还支持流式响应(Streaming),通过 Server-Sent Events(SSE)协议逐 token 返回生成结果,客户端可以在模型还在推理时就开始展示输出,极大提升了用户体验中的感知速度。在对话场景中,设置 stream: true 参数后,服务端会以 data: {...} 格式逐块推送生成内容,而非等待全部生成完毕后一次性返回。vLLM 和 Ollama 都完整支持这一流式传输能力。
vLLM 和 Ollama 都支持这一兼容格式,这意味着原本为 OpenAI 编写的客户端代码,只需修改 base_url 指向本地服务地址,即可无缝切换到本地模型,无需改动业务逻辑。这种标准化大大降低了模型迁移和多模型切换的工程成本。
统一而稳定的部署接口,可以大幅降低上手门槛和后期维护成本。

高并发承载能力
第三个维度是并发能力。在生产级应用中,同时请求模型服务的用户可能非常多——从几个到几十上百个用户同时发起请求都很常见。能够扛住更高并发量的部署方案,显然更具竞争力。
高并发处理能力的关键技术之一是 Continuous Batching(连续批处理)。传统的静态批处理(Static Batching)要求一批请求中所有序列都生成完毕后才能处理下一批,导致短序列请求被长序列拖慢,GPU 计算资源大量空转。
为了更直观地理解这一差异,可以想象一个餐厅的出菜流程:Static Batching 相当于一桌菜必须全部做完才能上,哪怕有一道菜特别复杂(长序列),其他早做好的菜也只能等着凉掉(GPU 空闲)。而 Continuous Batching 则像是做好一道就上一道,同时空出的炉灶立即开始做下一桌的菜。在技术实现上,Continuous Batching 采用「迭代级调度」(iteration-level scheduling)——不是在批次级别做调度决策,而是在每一个解码步(iteration)都重新评估:哪些请求已经完成可以移出?等待队列中有没有新请求可以插入?这种细粒度的调度使得 GPU 在任意时刻都在处理尽可能多的有效请求,几乎消除了填充(padding)带来的计算浪费。
关于填充(padding)的浪费值得进一步说明:在 Static Batching 中,同一批次内的序列长度往往参差不齐,但 GPU 的矩阵运算要求张量维度对齐,因此短序列必须用无意义的 padding token 填充到与最长序列等长。这些 padding 位置虽然不贡献有效计算结果,却占用了完全相同的计算资源和显存。当批次中序列长度差异较大时(比如最短 50 tokens、最长 2000 tokens),padding 带来的计算浪费可能高达 80% 以上。Continuous Batching 通过让每个请求独立进出,从根本上避免了这种对齐需求。
Continuous Batching 允许在每个解码步骤动态地加入新请求、移除已完成的请求,使 GPU 始终保持高利用率。这一机制配合高效的显存管理,可以在单张 GPU 上同时服务数十甚至上百个并发请求,吞吐量相比逐条推理可提升一个数量级。
模型服务化:让部署的模型可被外部访问
部署的另一大核心目标,是让模型「能被大家访问到」。这要求我们部署的不再是一段本地脚本,而是一个真正的模型服务(Model Server)。
在工程实践中,启动一个服务后,它会对外暴露一个端口(比如 8000、9000 等)。一旦端口暴露出来,只要网络互通,来自任意位置的用户都可以访问这个服务。无论请求方是手机、client server1 还是 client server2,服务端都不需要关心具体来源,只要双方遵循 HTTPS 等通用协议,就能调用模型。

这种服务化的设计,正是解决「跨机部署」「多用户并发请求」等问题的根本思路。模型服务化后,通常还需要考虑负载均衡、健康检查、自动重启等运维层面的配套能力,以保障服务在生产环境中的稳定性和可用性。
在实际的生产部署中,模型服务前面通常还会部署一层反向代理(如 Nginx、Traefik)或 API 网关(如 Kong、APISIX),用于实现请求路由、速率限制(rate limiting)、身份认证和 TLS 终止等功能。反向代理的核心价值在于将客户端与后端服务解耦:客户端只需知道代理的地址,由代理负责将请求转发到实际的模型服务实例。这不仅隐藏了后端拓扑,还能实现多种负载均衡策略(轮询、加权、最少连接等),当某个模型实例故障时自动摘除,对客户端完全透明。API 网关则在此基础上增加了更丰富的流量治理能力,如请求限流(防止突发流量压垮模型服务)、API 密钥认证(控制访问权限)、请求/响应变换和可观测性(日志、指标、链路追踪)等。
对于更大规模的部署,还可能引入 Kubernetes 进行容器编排,结合 Horizontal Pod Autoscaler(HPA)根据请求量自动扩缩模型服务实例数。在 Kubernetes 架构下,模型服务通常被打包为 Docker 容器镜像,通过 Deployment 控制副本数,通过 Service 提供稳定的内部访问端点,通过 Ingress 对外暴露 HTTPS 接口。HPA 可以基于 CPU 利用率、GPU 利用率或自定义的请求队列深度等指标,自动增减 Pod 数量。例如,当排队请求数超过阈值时自动扩容新的模型实例,流量回落后再缩容以节省资源。一些团队还会结合 NVIDIA GPU Operator 和 Device Plugin 实现 GPU 资源的自动调度与隔离。这些运维基础设施虽然不在模型推理本身的范畴内,但却是从「能用」到「可靠」的关键一环。
vLLM 与 Ollama 对比:两条主流本地部署路线
基于上述目标,业界形成了几套成熟的大模型本地化部署方案,其中 vLLM 和 Ollama 是最具代表性的两个工具,它们分别面向不同的使用场景。
vLLM:面向生产的高性能推理引擎
vLLM 是一个专注于高吞吐量、高并发的大模型推理框架。它通过 PagedAttention 等核心技术显著提升了显存利用率和推理速度,非常适合生产环境下的高并发请求场景。
PagedAttention 是 vLLM 团队在 2023 年提出的核心创新,灵感来源于操作系统的虚拟内存分页管理机制。在操作系统中,物理内存被划分为固定大小的「页框」(page frame),进程的虚拟地址空间被划分为同等大小的「页」(page),通过页表(page table)建立虚拟页到物理页框的映射。进程看到的是连续的虚拟地址空间,但实际的物理内存可以是完全不连续的——这就消除了外部碎片问题,极大提升了内存利用率。PagedAttention 将完全相同的思想引入了 GPU 显存管理:KV Cache 的逻辑序列被划分为固定大小的「KV 块」(类比虚拟页),GPU 显存被划分为等大的物理块(类比页框),通过块表(block table,类比页表)完成映射。这样,即使不同请求的 KV Cache 在物理显存中散落各处,逻辑上仍然是连续的,系统可以按需分配和回收显存块,几乎完全消除了碎片浪费。
在传统 Transformer 推理中,每个请求的 KV Cache 需要预先分配一块连续的显存空间,由于序列长度不可预知,系统往往按最大长度预分配,导致大量显存碎片和浪费,实际利用率有时不足 50%。PagedAttention 将 KV Cache 拆分成固定大小的「页」(block),按需动态分配,不同请求的页可以在物理显存中不连续存放,通过页表映射实现逻辑连续。这一机制使显存利用率提升到接近 100%,直接带来 2-4 倍的吞吐量提升,是 vLLM 在高并发场景下远超朴素实现的关键原因。
PagedAttention 还带来了一个重要的附加优势——前缀共享(Prefix Sharing),也称为 Automatic Prefix Caching。在许多实际场景中(如同一系统提示词下的多轮对话、批量处理相似请求),不同请求的输入序列往往共享相同的前缀。由于 PagedAttention 的分页机制,这些共享前缀对应的 KV Cache 页可以通过引用计数在多个请求间共享,而不需要为每个请求独立存储一份副本。这进一步降低了显存占用,在有大量相似请求的场景下效果尤为显著。
vLLM 还原生实现了 Continuous Batching,配合 PagedAttention 可以在单张 GPU 上同时服务大量并发请求。此外,vLLM 还支持张量并行(Tensor Parallelism)和流水线并行(Pipeline Parallelism),可以将一个大模型拆分到多张 GPU 上进行分布式推理,突破单卡显存限制,进一步扩展可服务的模型规模。
这两种并行策略的工作方式有本质区别:张量并行将同一层的权重矩阵沿某个维度切分到多张 GPU 上,每张卡处理矩阵的一部分,然后通过 AllReduce 等集合通信操作汇聚结果,适合层内并行,对 GPU 间通信带宽(NVLink 等)要求较高。流水线并行则将模型的不同层分配到不同 GPU 上,数据像流水线一样依次经过各卡,适合层间并行,通信量较小但需要精心设计微批次(micro-batch)调度以减少流水线气泡(pipeline bubble)。在实际部署中,两种并行策略常常组合使用——例如在 8 卡环境下,4 路张量并行 × 2 路流水线并行,以同时兼顾计算效率和显存分布。
当你需要同时服务大量用户、追求推理性能与显存性价比的最优平衡时,vLLM 往往是首选方案。
Ollama:零门槛的本地大模型部署工具
Ollama 的定位更偏向「开箱即用」。它把模型的下载、加载、服务启动封装得极为简洁,真正做到了几行命令就能在本地跑起一个模型服务,并对外暴露标准 API。
Ollama 底层基于 llama.cpp 构建,后者是由 Georgi Gerganov 于 2023 年 3 月发起的开源项目,最初的目标是让 Meta 的 LLaMA 模型能在 MacBook 上纯 CPU 运行。llama.cpp 用纯 C/C++ 重写了 Transformer 推理逻辑,不依赖 Python、PyTorch 或任何深度学习框架,编译后就是一个独立的可执行文件。这种极简的工程哲学使其具备了极强的跨平台能力——从树莓派到服务器级 GPU,从 x86 到 ARM 架构,都能高效运行。llama.cpp 内部大量使用了 SIMD(Single Instruction, Multiple Data)指令集优化(如 AVX2、ARM NEON)来加速 CPU 端的矩阵运算,并支持 Metal(macOS/iOS)、CUDA(NVIDIA GPU)、Vulkan 等多种硬件加速后端。随着项目发展,llama.cpp 已经支持了远超 LLaMA 家族的数十种模型架构,包括 Qwen、Mistral、Phi、Gemma 等,成为边缘设备和个人电脑上运行大模型的事实标准运行时。
Ollama 默认使用 GGUF(GPT-Generated Unified Format)模型格式,这是 llama.cpp 生态定义的二进制格式,将模型权重、分词器、元数据统一封装在单个文件中,支持多种量化级别(如 Q4_K_M、Q5_K_S、Q8_0 等)。其中 Q4_K_M 是社区最推荐的「性价比」量化级别,它使用 4 比特量化并对不同层采用混合精度策略(K 表示 k-quant,M 表示 medium),在模型质量和文件大小之间取得了良好平衡。这种一体化设计使 Ollama 无需额外安装 Python 环境或深度学习框架,真正做到了下载即用。
Ollama 还提供了类似 Docker 的模型管理体验:ollama pull 下载模型(类比 docker pull),ollama run 交互式运行(类比 docker run),ollama list 查看本地已有模型。它还支持通过 Modelfile(类似 Dockerfile)自定义模型配置,如设置系统提示词、调整温度参数、指定量化版本等。这种对开发者友好的 CLI 设计,配合内置的 HTTP API 服务(默认监听 11434 端口),使得从下载到服务化的全流程可以在几分钟内完成。
不过,由于 llama.cpp 主要针对单用户或少量并发优化,Ollama 在高并发吞吐量上通常不及 vLLM。对于希望快速验证想法、注重数据隐私、想在本地体验大模型的开发者来说,Ollama 是理想的入门工具。
小结
从单机脚本到服务化部署,是大模型从「玩具」走向「生产」的关键一步。理解部署的三大核心目标(显存性价比、便捷性、高并发)以及服务化的核心思路(对外暴露端口、遵循通用协议),能帮助你在面对 vLLM、Ollama 等工具时做出更合理的选择。
结合 Qwen 等优秀开源模型,用 Ollama 快速起步验证、用 vLLM 扛住生产级高并发压力,再配合纯本地部署带来的数据隐私优势,普通开发者也能构建出既好用又可靠的大模型应用。
核心要点
核心要点
相关推荐

ComfyUI双语提示词节点实测:不懂英文也能玩转标签
一位B站UP主借助GPT打造的ComfyUI双语标签提示词拓展节点实测:中英标签双向联动、30万词库支持、未知标签一键翻译沉淀,让不懂英文的小白也能玩转提示词,目前适配anima本地部署模型。

16G显存跑Qwen3 27B:192K上下文+视觉实测
在16G显存显卡上部署Qwen3 27B模型,通过llama.cpp Adaptive KV Streaming实现192K超长上下文与视觉能力。本文详解KV缓存瓶颈原理、量化版本选择及RTX 5080实测速度与任务能力。

MiniMax H3本地部署实测:开源视频模型效果与完整教程
MiniMax H3 开源视频模型本地部署实测:涵盖硬件要求、ComfyUI 完整部署教程,以及文生视频、图生视频的真实生成效果与耗时,适合想入门本地 AI 视频生成的用户参考。