为什么还要从 Ollama 再往前走一步

Ollama 的价值在于「五分钟跑起来」:一条 ollama run 命令就能拉模型、量化、起服务,还自带 OpenAI 兼容接口。但它的默认调度策略是为单用户、低并发设计的。当你开始用它跑批量推理、给团队做内部网关、或者要同时服务多个 Agent 会话时,会遇到两个硬墙:

  • 吞吐上不去:请求排队严重,GPU 利用率长期在 30% 以下。
  • 显存利用率低:KV Cache 按最大长度预分配,长上下文场景浪费明显。

vLLM 解决的正是这两点。它用 PagedAttention 管理 KV Cache(把显存按块分配,碎片率大幅降低),配合连续批处理(continuous batching),在同样的卡上通常能把吞吐提升数倍。代价是配置更重、对显存更敏感。

下面这条路线假设你已经有一台带 NVIDIA 显卡的机器(消费级 8GB~24GB 或数据中心卡均可),并且已经用过 Ollama。

第一步:按显存选模型和量化档位

先做减法,别一上来就拉最大的模型。经验值(实际以你跑起来为准):

| 显存 | 建议模型规模 | 量化 | 典型用途 |

| --- | --- | --- | --- |

| 8GB | 7B~8B | Q4 / AWQ 4bit | 单路对话、代码补全 |

| 12~16GB | 8B~14B | Q4 / FP8 | 小团队内部助手 |

| 24GB | 14B~32B | Q4 / AWQ | 批量数据处理 |

| 多卡 48GB+ | 32B~70B | FP8 / AWQ | 高并发网关 |

注意 vLLM 对「非量化」精度更友好,但如果你显存吃紧,AWQ 和 GPTQ 是成熟选择;FP8 需要较新的卡(Hopper 及之后)支持。

从 Ollama 迁移时的坑:Ollama 用的 GGUF 格式 vLLM 原生不支持。你需要去 Hugging Face 找同一模型的 safetensors 版本,或者用 AWQ/GPTQ 量化版。这一步是整条路线里最容易卡住的地方,提前确认模型有对应权重再动手。

第二步:装 vLLM 并起一个 OpenAI 兼容服务

推荐用官方 Docker 镜像,省去 CUDA 版本对齐的麻烦:

```bash

docker run --runtime nvidia --gpus all \

-v ~/.cache/huggingface:/root/.cache/huggingface \

-p 8000:8000 \

--ipc=host \

vllm/vllm-openai:latest \

--model Qwen/Qwen2.5-7B-Instruct-AWQ \

--quantization awq \

--max-model-len 8192 \

--gpu-memory-utilization 0.90

```

几个关键参数的含义:

  • --max-model-len:直接决定 KV Cache 大小。设太大容易 OOM,设太小长文档会被截断。先从 8192 试。
  • --gpu-memory-utilization:vLLM 允许占用的显存比例,默认 0.9。如果你还要在同一张卡上跑别的进程,调低到 0.7~0.8。
  • --tensor-parallel-size:多卡时设成卡数(如 2 卡设 2),单卡保持 1。

裸机安装也可以用 pip install vllm,但 CUDA、PyTorch、驱动三者版本必须匹配,Docker 路线能省掉大量排查时间。

第三步:把现有代码从 Ollama 切过来

这是迁移最省事的一点:vLLM 暴露的是 OpenAI 兼容接口,你之前指向 Ollama 的代码基本只改 base_url 和 model 名。

```python

from openai import OpenAI

client = OpenAI(

base_url="http://localhost:8000/v1",

api_key="EMPTY" # vLLM 默认不校验,占位即可

)

resp = client.chat.completions.create(

model="Qwen/Qwen2.5-7B-Instruct-AWQ",

messages=[{"role": "user", "content": "用一句话解释 PagedAttention"}],

temperature=0.7,

)

print(resp.choices[0].message.content)

```

如果你原来用的是 Ollama 的 /api/chat 端点,改成上面这种 OpenAI 风格即可;如果本来就用的 OpenAI SDK 指到 Ollama,那几乎零改动。

建议加一层环境变量(如 LLM_BASE_URL),这样本地开发和线上切换不用改代码。

第四步:验证吞吐确实涨了

别凭感觉。用 vLLM 自带的 benchmark 脚本压一下:

```bash

vllm bench serve \

--backend openai-chat \

--base-url http://localhost:8000 \

--model Qwen/Qwen2.5-7B-Instruct-AWQ \

--num-prompts 200 \

--request-rate 8

```

重点看两个数:output token throughput(每秒输出 token 数)和 TTFT(首 token 延迟)。和 Ollama 同条件对比,通常能看到数倍差距,尤其是在并发数上去之后。

如果吞吐没涨,先查是不是 --max-model-len 设得过大导致 KV Cache 挤爆、或者请求率根本没到瓶颈。

第五步:什么时候别用 vLLM

vLLM 不是万能的,以下场景反而是 Ollama / llama.cpp 更合适:

  • 只有 CPU 或 Apple Silicon:vLLM 对纯 CPU 推理支持有限,llama.cpp(Ollama 的底层)在这类硬件上更成熟。
  • 显存很小(< 8GB)且只跑单路对话:vLLM 的调度开销不划算,Ollama 更轻。
  • 需要频繁切换很多不同模型:Ollama 的模型管理体验更好,vLLM 每次换模型要重启服务。
  • 要跑 GGUF 量化:vLLM 不认 GGUF,这种情况留用 llama.cpp 系。

一个折中做法:本地开发用 Ollama,压测和上线用 vLLM,两者接口都是 OpenAI 兼容,切换成本很低。

注意事项

  1. 显存是硬约束。先算清楚:模型权重 + KV Cache + 激活值。OOM 时优先降 --max-model-len,其次降 --gpu-memory-utilization,再考虑换更小的量化。
  2. 许可证要看清。开源权重不等于随便商用,Llama、Qwen、Mistral 各有自己的许可条款,企业内部使用前确认合规。
  3. Docker 的 --ipc=host 别省。vLLM 多进程共享内存需要它,否则可能报共享内存不足。
  4. 别把服务裸奔在公网。vLLM 默认不做鉴权,api_key 是摆设。要对外提供就前面挂一层网关做认证和限流。
  5. 版本迭代快。vLLM 更新频繁,参数名偶有变动,遇到报错先查对应版本的文档,别照抄旧教程。
  6. 模型来源可信。从 Hugging Face 拉权重时注意仓库作者,优先选官方组织发布的版本。

适用场景

  • 团队内部需要一个不产生 API 账单的推理网关。
  • 批量处理大量文本(分类、抽取、摘要),对吞吐敏感、对延迟不敏感。
  • 数据敏感、不能出内网的场景。
  • 做 Agent / RAG 系统,需要高并发调用本地模型。

如果你的需求是「偶尔问几个问题」,Ollama 就够了,不必折腾 vLLM。真正值得迁移的信号是:你开始为排队和 GPU 空闲发愁。

成本核算

这套方案的「免费」指的是零 API 费用,不是零成本。真实成本是:

  • 硬件折旧(自己的卡或租用 GPU 云主机)。
  • 电费(消费级卡满载通常 200~400W)。
  • 你的时间成本。

如果只是轻度使用,租按量计费的 GPU 云主机可能比自己买卡划算;如果长期高频使用,自有硬件摊薄后更省。这笔账要自己算,别被「免费」两个字带偏。