之前的业务迭代里,我们经常把大模型训练好之后就直接丢给开发同学对接,结果每次一到联调阶段就出问题:模型推理慢得离谱、GPU 显存频繁爆掉、多路并发请求直接排队超时,甚至服务端直接用 CPU 跑推理,生成一段话要等上半分钟。后来系统地梳理了“大模型推理服务器”的搭建和部署方案,才逐渐把这块从“玄学”变成了“工程”。这篇文章会把我在实际项目中积累的推理服务器选型思路、环境准备、vLLM/Ollama 两种主流部署方案、性能优化与常见排错经验整理成一份可落地的教程。不管你是刚开始接触大模型部署的算法工程师,还是需要自行维护推理服务的后端开发,都可以参考这套闭环实践。
1. 大模型推理服务器到底解决什么问题
1.1 什么是大模型推理服务器
在正式开始之前,先对齐一下概念。大模型训练完成之后,模型本身只是一组权重参数,真正要让业务系统使用它,必须有一个能够接收请求、加载模型、执行推理(也就是一次前向计算)、返回结果的常驻服务。这个服务所依赖的软硬件环境和配套组件,就统称为“推理服务器”。
与大模型训练服务器不同,推理服务器更关注响应延迟、吞吐量、并发能力以及资源利用效率。训练阶段可能用几百张 GPU 卡跑上几周,推理阶段则希望单张 GPU 卡能够稳定支撑多个业务请求,并且在几百毫秒内返回结果。从业务角度来看,推理服务器可以理解成一个“模型即服务”的中间层:上层业务不需要关心模型的权重文件放在哪里、用什么框架加载,只需要通过 HTTP 接口或 SDK 调用就行。
1.2 为什么不能直接把模型扔进业务代码
初学者最容易踩的坑,就是把模型加载逻辑直接写进业务服务里。比如在 Flask 或 Spring Boot 中初始化一个 model,每个请求进来直接调用 model.generate()。这种方式在小流量 demo 里看起来没问题,但一旦进入生产环境就会暴露出几个致命问题:
- 模型加载速度慢,每次重启服务都要重新加载权重,动辄几十秒甚至几分钟,导致发布和扩容成本极高。
- 多进程模型重复加载,如果后端使用 Gunicorn 多 worker,每个 worker 都会复制一份模型,显存直接翻倍。
- 并发请求缺乏调度,多个请求同时触发推理时,GPU 计算资源无法被合理复用,容易造成显存溢出。
- 缺失流式输出、batch 动态合并、token 级流控等能力,无法满足 Chat 场景的体验要求。
推理服务器本质上就是把“模型加载”和“请求推理”这两件事独立出来,并且额外承担并发调度、显存管理、连续批处理(Continuous Batching)、流式输出、接口协议转换等工作。这也是 vLLM、TGI、Ollama 等推理框架存在的意义。
1.3 典型应用场景
从我接触过的项目来看,大模型推理服务器的应用场景可以分成几类:
- 智能对话系统:例如客服机器人、AI 助手,需要支持多轮对话和流式回复。
- 文档摘要与知识问答:例如基于 RAG 架构的企业知识库,需要把检索到的文档片段交给大模型生成答案。
- 代码生成与代码补全:例如 IDE 插件后台服务,对延迟非常敏感。
- 内容创作辅助:例如营销文案生成、周报总结等,吞吐量要求较高。
- 离线批量推理:例如批量给历史工单打标、批量生成商品描述,需要的不是低延迟而是高吞吐。
不同场景对推理服务器的要求差异很大。在线对话场景要优先保证首 token 延迟和流式体验;离线批量任务则希望吞吐量最大化,哪怕单个请求耗时几十秒也能接受。理解这些差异,才能在做技术选型时找到最合适的方案。
2. 推理服务器的核心组成与技术栈
2.1 硬件层:GPU、CPU、内存的配合
推理服务器的硬件选型有很强的路径依赖。很多时候不是你想用什么卡就能用什么卡,而是要看你手头有什么资源。
首先是 GPU,当前主流的大模型推理主要依赖 NVIDIA 的 CUDA 生态。显存大小决定了一个模型能否加载到显卡上,也直接影响最大并发数。一张 24GB 显存的显卡可以比较流畅地运行 7B~13B 量级的量化模型;如果需要运行 70B 甚至更大模型,通常需要多卡张量并行或者使用 CPU Offload 策略。
其次是 CPU 和内存。很多人会忽略 CPU 在推理过程中的作用。推理并不只是 GPU 在计算,token 的采样、beam search 等解码逻辑、请求调度、Python 层的 overhead 都需要 CPU 参与。CPU 核数过少会拖慢调度效率;内存大小则决定了能否承载 KV Cache 以及模型参数做 CPU Offload 时的空间。服务器内存和推理卡之间是互相配合的关系:当 GPU 显存不足以完整容纳模型时,可以把部分参数放到内存中,通过 PCIe 传输数据,但这种方式会显著增加单次推理延迟,只适合对延迟不敏感的场景。
2.2 推理框架层
推理框架负责把 PyTorch 等训练框架产出的模型权重高效地跑起来。当前比较主流的方案包括:
- vLLM:对连续批处理和 PagedAttention 的实现非常成熟,吞吐量表现优秀,社区活跃度高,兼容 OpenAI 接口协议,是目前生产环境使用最广的方案之一。
- Text Generation Inference(TGI):Hugging Face 推出的推理服务器,支持原生 HF 生态,功能完善,但部署和配置相对更重。
- Ollama:轻量化的本地部署工具,安装简单,对个人开发和中小团队非常友好,适合快速把开源模型跑起来,也支持 OpenAI 兼容接口。
- TensorRT-LLM:NVIDIA 官方出品,优化深度最强,性能上限最高,但编译和部署流程复杂,适合对延迟有极致要求的场景。
选择推理框架不能只看跑分,还要考虑团队维护成本、模型兼容性、周边生态以及接口协议是否容易对接。
2.3 服务化层
推理框架之上还需要服务化层来提供 API 网关、鉴权、限流、监控、日志采集等能力。vLLM 自带 OpenAI 兼容服务端,Ollama 也可以通过环境变量开启服务模式。但生产环境通常还会在前面套一层 Nginx 或 API Gateway,以及配合 Prometheus + Grafana 做监控告警。
为了便于理解,可以把推理服务器拆成三层:
| 层级 | 职责 | 常见组件 |
|---|---|---|
| 硬件资源层 | 提供 GPU、CPU、内存 | NVIDIA GPU、云服务器 |
| 推理引擎层 | 加载模型、执行推理、并发调度 | vLLM、Ollama、TGI、TensorRT-LLM |
| 服务暴露层 | 对外提供 API、鉴权、限流 | OpenAI API、Nginx、Gateway |
3. 环境准备与版本说明
3.1 操作系统与基础环境
本文的部署示例以 Linux 环境为主,Ubuntu 20.04 / 22.04 均可。Windows 环境目前可以通过 WSL2 运行 vLLM 和 Ollama,但生产环境建议还是使用 Linux 服务器。
在开始部署之前,需要确保以下基础环境已经就绪:
# 查看操作系统版本 cat /etc/os-release # 查看 GPU 型号和驱动信息 nvidia-smi # 查看 CUDA 版本(注意与驱动版本的兼容关系) nvcc --version如果 nvidia-smi 命令无法识别,说明 NVIDIA 驱动没有正确安装,需要先解决驱动问题再继续。版本方面,不需要过度追求最新,建议根据推理框架的官方要求来匹配。比如 vLLM 对 CUDA 版本有明确要求,过旧或过新的 CUDA 都可能出现编译失败或运行报错。
3.2 Python 环境与虚拟环境
vLLM 是基于 Python 的推理框架,建议使用 Python 3.10 或 3.11,并创建一个独立的虚拟环境,避免污染系统 Python。
# 安装虚拟环境工具(如果没有) sudo apt update sudo apt install -y python3-venv python3-pip # 创建虚拟环境 mkdir -p ~/llm-inference cd ~/llm-inference python3 -m venv venv # 激活虚拟环境 source venv/bin/activate # 确认 Python 版本 python --version3.3 依赖版本说明
部署大模型推理服务时,版本匹配是坑最多的地方。以 vLLM 为例,不同版本的 vLLM 对 PyTorch、CUDA、Python 版本都有对应关系。本文不会刻意指定某个“最佳版本”,因为框架迭代太快。你需要根据自己选择的模型和硬件,去检查 vLLM 官方 Release Notes 和 PyTorch 的安装向导。
这里给出一个稳妥的操作思路:
- 先确定 GPU 驱动和 CUDA 版本。
- 根据 CUDA 版本选择对应的 PyTorch 安装命令。
- 安装与 PyTorch 兼容的 vLLM 版本。
- 用一个小模型跑通全流程,再切换目标大模型。
这样即使版本升级,也不会因为依赖问题卡住整条部署链路。
4. 实战:基于 vLLM 搭建 OpenAI 兼容推理服务器
4.1 安装 vLLM
在激活 Python 虚拟环境后,通过 pip 安装 vLLM 是最直接的方式。官方发布的是预编译 wheel 包,不需要从源码编译,可以节省大量时间。
pip install vllm如果你的网络环境无法直接访问默认 PyPI 源,可以切换到国内镜像:
pip install vllm -i https://mirrors.aliyun.com/pypi/simple/安装完成后,可以验证一下版本:
python -c "import vllm; print(vllm.__version__)"如果输出正常,说明 vLLM 安装成功。这里有一个小技巧:尽量先用小模型测试,避免一上来就加载几十 GB 的大模型,排错成本太高。
4.2 使用命令行启动推理服务
vLLM 提供了一个服务端命令vllm serve,可以比较方便地启动 OpenAI 兼容的推理服务。
vllm serve Qwen/Qwen2.5-7B-Instruct \ --host 0.0.0.0 \ --port 8000 \ --tensor-parallel-size 1 \ --gpu-memory-utilization 0.9 \ --max-model-len 8192这里逐个解释关键参数:
Qwen/Qwen2.5-7B-Instruct:模型名称。可以是 Hugging Face 上的模型 ID,也可以是本地模型目录路径。--host 0.0.0.0:监听所有网卡,这样其他机器可以通过 IP 访问。如果只在本机调试,可以改成 127.0.0.1。--port 8000:服务监听端口。--tensor-parallel-size 1:张量并行数。单卡设置为 1,多卡时可以设置为 GPU 数量。--gpu-memory-utilization 0.9:允许 vLLM 使用的 GPU 显存比例。设置成 0.9 表示最多用 90% 显存,预留一部分给 CUDA context 和其他进程。--max-model-len 8192:模型最大上下文长度。这个值受显存限制,设置过大会导致显存不足。
如果服务器只有一张卡,同时显存也比较有限,可以先用量化模型。vLLM 支持 AWQ、GPTQ 等量化格式,加载方式是在模型名称后面加上量化参数。这里只做一个思路演示,实际需要根据你下载的模型格式来调整。
启动成功后的日志中会显示模型加载耗时、显存分配情况以及监听端口。如果日志中出现Application startup complete类似的信息,说明服务已经正常启动。
4.3 调用推理接口验证
vLLM 启动后会在本机 8000 端口暴露一个 OpenAI 兼容的接口,接口路径是/v1/chat/completions。可以使用 curl 快速验证:
curl http://127.0.0.1:8000/v1/chat/completions \ -H "Content-Type: application/json" \ -d '{ "model": "Qwen/Qwen2.5-7B-Instruct", "messages": [ {"role": "user", "content": "用一句话介绍大模型推理服务器"} ], "temperature": 0.7, "max_tokens": 200, "stream": false }'预期会返回一个 JSON 结构,里面包含模型生成的回复内容、token 数量、请求耗时等元信息。这里的model字段要和启动服务时传入的模型名称保持一致。
除了 curl,也可以使用 Python 的openai库发起请求:
from openai import OpenAI client = OpenAI( base_url="http://127.0.0.1:8000/v1", api_key="EMPTY" ) response = client.chat.completions.create( model="Qwen/Qwen2.5-7B-Instruct", messages=[ {"role": "user", "content": "用一句话介绍大模型推理服务器"} ], temperature=0.7, max_tokens=200, stream=False ) print(response.choices[0].message.content)这里的api_key不需要是真的密钥,因为 vLLM 默认不校验密钥,只是为了兼容 OpenAI SDK 的调用习惯。如果你的服务前面挂了 API 网关,就需要在网关层处理真正的鉴权逻辑。
4.4 开启流式输出
对话类应用通常需要流式输出,让用户看到 token 一个一个蹦出来,体验会好很多。vLLM 天然支持流式,只需要把请求参数改成"stream": true。
curl http://127.0.0.1:8000/v1/chat/completions \ -H "Content-Type: application/json" \ -d '{ "model": "Qwen/Qwen2.5-7B-Instruct", "messages": [ {"role": "user", "content": "给我写一段 50 字的欢迎语"} ], "max_tokens": 100, "stream": true }'返回内容会变成多个 SSE(Server-Sent Events)数据块,每个块里包含一部分增量内容。后端在对接时,只需要按 SSE 协议解析这些数据块即可。
4.5 模型加载与部署过程中的显存问题
在启动 vLLM 时,如果模型权重比较大,经常遇到显存不够的错误。通常表现为CUDA out of memory或者Not enough memory。处理思路是:
- 确认 GPU 显存没有被其他进程占用,使用
nvidia-smi查看。 - 降低
--max-model-len的值,因为 KV Cache 会根据最大长度预分配显存。 - 降低
--gpu-memory-utilization,但这个方法只能解决服务启动崩溃的问题,不能解决模型本身装不下的问题。 - 如果一张卡确实装不下,考虑使用多卡张量并行,也就是把
--tensor-parallel-size调整为大于 1 的值。
这里需要特别注意:张量并行会增加 GPU 之间的通信开销,不是显卡数量翻倍性能就翻倍。实际项目里需要根据模型规模、卡间通信方式(NVLink 还是 PCIe)做实测。
5. 轻量替代方案:基于 Ollama 部署推理服务
5.1 为什么还要考虑 Ollama
vLLM 性能好,但配置和排错对新手有一定门槛。如果只是想在本地快速跑起来一个开源模型,或者团队里没有专门负责推理优化的同学,Ollama 会更顺手。它的优势在于模型管理简单、命令行交互友好、自动处理量化转换,一条命令就能把模型服务跑起来。
当然,Ollama 在做高并发生产环境时,性能调优空间不如 vLLM 大。对于中小团队或者个人开发者的 demo 项目,Ollama 已经足够。
5.2 安装与启动
Ollama 提供了非常简洁的安装脚本:
curl -fsSL https://ollama.com/install.sh | sh安装完成之后,先拉取一个模型。以 Qwen2.5 的 7B 量化版本为例:
ollama pull qwen2.5:7b然后启动常驻服务:
ollama serve默认端口是 11434。验证服务是否正常:
curl http://127.0.0.1:11434/api/generate -d '{ "model": "qwen2.5:7b", "prompt": "说一下大模型应用的基本流程", "stream": false }'Ollama 同样提供了 OpenAI 兼容接口,调用http://127.0.0.1:11434/v1即可,这对已有 OpenAI SDK 的项目非常友好。
5.3 如何提高 Ollama 的推理生成速度
这是一个被问得非常多的问题。Ollama 默认配置比较保守,很多场景下没有充分挖掘 GPU 能力。可以从几个方向尝试:
首先是设置并发参数。Ollama 支持通过环境变量调节并发请求数和同时加载的模型数:
# 设置最多并行处理 4 个请求 OLLAMA_NUM_PARALLEL=4 # 设置最多同时加载 2 个模型 OLLAMA_MAX_LOADED_MODELS=2 # 设置 KV Cache 大小,例如 8GB OLLAMA_KV_CACHE_SIZE=8G这些环境变量需要在启动ollama serve之前设置,常见做法是写入 systemd service 配置或者启动脚本中。
其次是确保 GPU 真的被使用。如果 Ollama 运行在 CPU 模式,生成速度会非常慢。可以执行ollama ps查看模型的运行设备,显示 GPU 表示已使用 GPU 推理。如果显示 CPU,需要检查驱动和 CUDA 环境。
最后是考虑使用更小的量化版本。Ollama 的模型标签通常有:7b-q4_K_M、:7b-q8_0等后缀,q4 量化比 q8 占用更少显存,推理速度也更快,但精度会有轻微损失。实际项目里需要在速度和效果之间找一个平衡点。
6. 常见问题与排查思路
6.1 高频问题汇总
| 问题现象 | 常见原因 | 解决思路 |
|---|---|---|
| 启动时报 CUDA out of memory | 显存被其他进程占用,或 max-model-len 设置过大 | 使用 nvidia-smi 查看占用,降低 max-model-len 或 gpu-memory-utilization |
| 推理速度很慢 | 模型没有被加载到 GPU,或量化精度过高 | 执行 ollama ps 查看设备,确认 GPU 可用;尝试更小的量化模型 |
| 并发请求排队严重 | 推理框架并发调度参数未开启 | 使用 vLLM 的连续批处理;调整 Ollama 的 OLLAMA_NUM_PARALLEL |
| 请求超时 | 服务端单 token 生成太慢,或网络链路有问题 | 检查首 token 延迟和生成速度,确认服务端日志;排查防火墙和代理 |
| 加载本地模型报错 | 模型目录结构不符合推理框架要求 | 确认包含 config.json、tokenizer.json、权重文件且格式匹配 |
| 多卡推理时显存不均衡 | 没有启用张量并行或配置错误 | 设置 --tensor-parallel-size 为实际卡数,确认 NCCL 通信正常 |
| nccl 初始化失败 | 多卡环境网络或驱动配置问题 | 检查 CUDA_VISIBLE_DEVICES 设置,确认驱动版本和 NVLink/PCIe 状态 |
6.2 一个典型的启动失败排错流程
假设你执行vllm serve后立刻报错退出,按照下面顺序排查成功概率更高:
- 查看完整报错信息,不要只看最后一行。通常真正原因在堆栈中部。
- 确认模型路径或模型 ID 是否正确。如果网络不通,Hugging Face 模型下载会失败,建议先
huggingface-cli download到本地再加载。 - 确认显存是否足够。使用
nvidia-smi查看 GPU 剩余显存。 - 确认 CUDA 版本和 PyTorch 版本是否匹配。vLLM 对 PyTorch 版本有要求,升级或降级时容易踩坑。
- 如果本地模型使用自定义分词器或特殊结构,可能出现不兼容问题,建议先用官方标准模型测试环境本身是否正常。
6.3 远程访问不通的处理
如果在另一台机器上访问推理服务器失败,先检查监听地址。--host设置为0.0.0.0才能被外部访问。其次检查安全组和防火墙策略,云服务器尤其要注意安全组是否放行了对应端口。最后确认服务本身是否正常,比如在服务器本机执行 curl 测试,如果本机正常而外部不通,问题基本在网络层。
7. 推理服务器的工程化最佳实践
7.1 显存与内存预算
在部署一个大模型推理服务之前,建议先做一个简单的资源估算。一个模型的权重文件大小、KV Cache 大小、运行时开销共同决定了显存需求。实际项目中,最稳妥的方式是先启动一个空服务,用监控工具观察基线显存占用,再逐步增加并发请求,观测显存曲线。
需要注意的一点是,不要把显存用到 100%。至少要预留 5%~10% 的显存给 CUDA context 和其他系统开销,否则容易出现莫名其妙的不稳定问题。
7.2 模型版本与权重管理
大模型的迭代非常快,同一个模型系列可能隔几天就发布新版本。推理服务器必须把模型版本管理纳入工程规范。建议在模型启动脚本中明确记录模型名称、版本、量化方式、上下文长度等关键参数,并使用配置文件管理这些信息,而不是散落在启动命令中。
比如可以维护一份model_config.yaml:
model_name: Qwen/Qwen2.5-7B-Instruct model_version: 20250210 quantization: null tensor_parallel_size: 1 max_model_len: 8192 gpu_memory_utilization: 0.9启动时统一读取这份配置,方便追溯线上服务到底跑了哪个模型。
7.3 流式接口、超时与重试
在线对话业务接入推理服务器时,重点要处理好流式输出过程中的连接管理和超时策略。大模型生成时间比较长,如果客户端或网关没有配置合理的读超时,很容易出现连接被断开的问题。
推荐的做法是:
- 使用 SSE 时,客户端逐行读取数据,不要一次性等待整个 chunk 完成。
- 网关层读超时设置要大于模型最大生成时间,一般建议至少 120 秒以上。
- 重试机制只对幂等请求开放,对于已经消耗了大量计算资源的生成请求,重复重试可能导致资源浪费。
7.4 安全与权限边界
推理服务器属于计算密集型的内部服务,一般不建议直接暴露到公网。生产环境至少要做到以下几点:
- 在 API 网关层增加鉴权,使用 API Key 或 JWT 校验请求来源。
- 限制单客户端调用频率,防止恶意刷接口造成 GPU 资源耗尽。
- 对用户输入的 prompt 做长度限制和敏感内容过滤,避免潜在的内容安全合规问题。
- 不赋予推理服务访问数据库、文件系统等高权限,保持最小权限原则。
7.5 监控与日志
推理服务的监控和普通 Web 服务有所不同,除了常规的 QPS、错误率,还要关注 GPU 相关指标:
- GPU 显存使用率。
- GPU 计算利用率。
- 首 token 延迟(TTFT)。
- 每 token 生成延迟(TPOT)。
- 正在排队的请求数。
- KV Cache 使用率。
推荐使用 Prometheus 抓取 vLLM 的监控指标,配合 Grafana 展示。vLLM 默认会暴露/metrics接口,直接接入即可。Ollama 也提供了一定的指标能力,但相对简单,可以结合日志分析和自定义脚本做补充。
8. 结语与下一步学习建议
这篇文章从推理服务器的概念、核心组成、环境准备、vLLM 与 Ollama 两种部署方式、常见问题排查到工程化最佳实践,走完了一条相对完整的落地路径。如果只是用来做本地实验,Ollama 完全可以作为首选;如果要把大模型推理能力接入线上业务,vLLM 的优势会更明显。实际项目中还有很多细节无法在单一教程里覆盖,比如多卡张量并行的性能调优、量化模型与推理框架的兼容性、RAG 场景下的检索与生成链路配合等。你可以先跑通本文里的两个最小示例,再根据自己手头的模型和硬件逐步深入。大模型推理服务器的技能树很长,但一旦掌握了这套方法论,后续接触新的推理框架和硬件方案时就不会觉得无从下手。