共计 3824 个字符,预计需要花费 10 分钟才能阅读完成。
上周我在为内部团队搭建一个由 8 个自主 Agent 驱动的代码审查流水线时,服务器直接崩了。底层原本挂着 Ollama 跑 Qwen2.5-14B,平时单人聊聊天挺惬意,但在 8 个 Agent 同时发起长文本检索与工具调用时,请求队列瞬间堵死,首字延迟(TTFT)直接飙升到 20 秒开外,甚至频发 500 超时。
Ollama 固然是个人桌面端极简体验的王者,但它的并发推理与显存复用机制在真正的工程化场景下非常吃力。要解决高吞吐、多并发且兼顾 OpenAI 标准协议的本地调用,目前工业界最成熟的轻量组合拳莫过于 vLLM(推理引擎)+ LiteLLM(网关反代)。今天我把这套部署架构、参数优化细节以及避坑指南完整拆解出来。
一、架构痛点:为什么 Ollama 抗不住多 Agent 压测?
根本差异在于 KV Cache(键值缓存)的管理策略:
- 内存碎片化问题 :传统框架在分配 KV Cache 时采用连续内存预分配,面对长度不一的请求,大量显存被预留但未使用,直接限制了并发 Batch Size。
- 并发调度策略 :vLLM 的杀手锏是 PagedAttention,它借鉴了操作系统的虚拟内存分页思想,将 KV Cache 离散切分为固定大小的 Block。显存利用率能直接从 Ollama 的 60% 左右拉升到 90% 以上,吞吐量提升 2 到 4 倍。
- API 网关缺失 :裸跑推理引擎无法解决权限隔离、限流(Rate Limit)、Fallback 容灾等工程需求。LiteLLM 的接入正好填补了这一环,抹平各种模型接口差异,提供真正的 OpenAI-compatible Proxy。
二、底层引擎部署:vLLM 生产级启动与显存压榨
环境是一台配备单张 RTX 4090(24GB 显存)的 Linux 宿主机,目标模型选用 Qwen/Qwen2.5-14B-Instruct-AWQ(量化后显存占用约 9.5GB,留出 14GB+ 作为 KV Cache 应对高并发)。
我踩过的一个深坑是:Docker 启动 vLLM 时如果不预先设置共享内存,高并发 context 传输会引发 Bus error。必须在容器运行时挂载 /dev/shm 并放开 --ipc=host。
# 拉取官方最新镜像
docker pull vllm/vllm-openai:latest
# 启动 vLLM 容器
docker run -d --gpus all \
--name vllm-qwen14b \
--restart always \
--ipc=host \
-p 8000:8000 \
-v /data/models/huggingface:/root/.cache/huggingface \
vllm/vllm-openai:latest \
--model Qwen/Qwen2.5-14B-Instruct-AWQ \
--quantization awq \
--dtype half \
--gpu-memory-utilization 0.92 \
--max-model-len 8192 \
--max-num-seqs 64 \
--trust-remote-code \
--served-model-name qwen2.5-14b
核心参数实战解析:
--gpu-memory-utilization 0.92:分配 92% 显存给 vLLM,剩余留给 CUDA Runtime 上下文。如果设为 0.98,跑大批量请求时极容易触发 PyTorch 显存碎片 OOM。--max-model-len 8192:虽然 Qwen2.5 支持 128K,但在 24G 显卡上如果拉满 32K,KV Cache 会迅速吃光所有显存,导致并发数直接降到个位数。根据业务需求锁死 8K 是保证并发吞吐的关键。--max-num-seqs 64:允许最大连续批处理的并发序列数为 64,完美压榨 PagedAttention 的流水线能力。
三、中间层治理:LiteLLM 网关与动态路由实战
直接把 8000 端口暴露给应用并不稳妥。我们使用 LiteLLM 搭建一个聚合网关,实现 API Key 鉴权、负载路由以及备选方案(Fallback 到外部 API)。
1. 编写 config.yaml 配置文件
model_list:
- model_name: local-agent-brain
litellm_params:
model: openai/qwen2.5-14b
api_base: http://vllm-qwen14b:8000/v1
api_key: "none"
tpm: 1000000
rpm: 3000
- model_name: local-agent-brain
litellm_params:
model: deepseek/deepseek-chat
api_key: "os.environ/DEEPSEEK_API_KEY"
router_settings:
routing_strategy: "latency-based-routing"
num_retries: 2
timeout: 45
general_settings:
master_key: "sk-nassky-master-secure-token"
通过这个配置,当本地 vLLM 实例因为不可抗力超载或崩溃时,LiteLLM 会毫秒级无缝自动 Fallback 到 DeepSeek 云端 API,调用端的业务代码完全无感。
2. 编写 Docker Compose 整合调度
新建 docker-compose.yml,将两套组件编排在同一私有网络下:
version: '3.8'
services:
vllm:
image: vllm/vllm-openai:latest
container_name: vllm-qwen14b
deploy:
resources:
reservations:
devices:
- driver: nvidia
count: 1
capabilities: [gpu]
ipc: host
restart: always
volumes:
- /data/models:/root/.cache/huggingface
command: >
--model Qwen/Qwen2.5-14B-Instruct-AWQ
--quantization awq
--dtype half
--gpu-memory-utilization 0.92
--max-model-len 8192
--max-num-seqs 64
--trust-remote-code
--served-model-name qwen2.5-14b
litellm:
image: ghcr.io/berriai/litellm:main-latest
container_name: litellm-gateway
restart: always
ports:
- "4000:4000"
volumes:
- ./config.yaml:/app/config.yaml
environment:
- DEEPSEEK_API_KEY=sk-xxxxxx
command: ["--config", "/app/config.yaml", "--port", "4000"]
depends_on:
- vllm
执行 docker compose up -d,整个高并发模型网关服务在几秒内就能完成就绪。
四、基准压测对比:Ollama vs vLLM
为了用数据说话,我使用自写的 Python 异步压测脚本模拟真实业务请求:构造 20 个客户端并发,每个请求输入 1200 Token(代码段),期望输出 300 Token,连续压测 500 次请求。
| 指标维度 | Ollama (Qwen2.5-14B-Q4_K_M) | vLLM (Qwen2.5-14B-AWQ) | 性能提升幅度 |
|---|---|---|---|
| 平均吞吐量 (Tokens/s) | 68.4 | 234.1 | + 242% |
| 平均 TTFT (首字延迟) | 4820 ms | 610 ms | 降低 87.3% |
| 请求成功率 (20 并发) | 84% (超时频发) | 100% | 稳定无丢包 |
| 显存碎片利用率 | 动态挤占,波动剧烈 | 固定分片,无溢出 | 极度平稳 |
测试数据差距明显。在并发场景下,Ollama 内部处理队列出现明显的 Head-of-line Blocking(队头阻塞),而 vLLM 凭借连续批处理(Continuous Batching)把 GPU 的计算核心始终喂得满满当当。
五、必须注意的避坑细节
1. AWQ 与 GPTQ 的选型陷阱
在 vLLM 上,优先选用 AWQ 量化格式而非 GPTQ。实测 AWQ 的 Marlin 内核在 Ampere 和 Ada 架构(30 系 /40 系)上的解码吞吐比标准 GPTQ 高出约 20-30%,且反量化损失在代码理解任务上肉眼几乎不可见。
2. 流式断连造成的孤儿请求
在前端或 Agent 取消请求时,如果未配置 --enforce-eager 或底层未捕获客户端断开信号,vLLM 可能会继续推导完该请求的所有 Token,造成算力空耗。LiteLLM 作为网关层能很好地截断下游连接,确保 GPU 及时终止无效生成。
总结与避坑心得
从纯体验和本地玩具定位来说,Ollama 依然是开箱即用的第一梯队。但只要你的业务涉及以下场景之一: 多 Agent 自动化流水线、小型团队内部共享推理节点、批量高并发长文本解析 ,就必须尽快将底层引擎迁移到 vLLM + LiteLLM 方案。
这套方案不仅兼容所有支持 OpenAI SDK 的现成开发框架(如 LangChain、LlamaIndex、AutoGPT),更重要的是它能将一张原本只能承载 2-3 个并发的消费级显卡,直接压榨出服务数十人团队的并发吞吐能力。建议大家在部署时严格限定 --max-model-len,把显存的控制权牢牢握在自己手里。