先想清楚:本地部署到底「免费」在哪
本地跑开源模型不是零成本,它把「按 Token 计费」换成了「按硬件和电费计费」。真正的免费区间是:你已经有一台带独显的机器(或公司闲置的推理卡),且调用量足够大,摊到每百万 Token 的边际成本趋近于电费。
所以本文的目标不是「教你装 Ollama」,而是把本地模型包装成一个和 OpenAI API 同构的 Token 供给层,让现有代码一行不改就能切过去,云端只在本地扛不住的时候兜底。
操作步骤
第一步:按显存选模型和量化档位
粗略的显存占用公式(推理,非训练):
```
显存 ≈ 参数量(B) × 每参数字节数 + KV Cache + 框架开销
```
每参数字节数取决于量化:
| 量化 | 每参数字节 | 7B 约需 | 14B 约需 | 32B 约需 | 70B 约需 |
|---|---|---|---|---|---|
| FP16 | 2.0 | ~14 GB | ~28 GB | ~64 GB | ~140 GB |
| Q8 | 1.0 | ~7 GB | ~14 GB | ~32 GB | ~70 GB |
| Q4_K_M | ~0.55 | ~4 GB | ~8 GB | ~18 GB | ~40 GB |
再给 KV Cache 留出余量:上下文越长、并发越高,KV Cache 越大。经验值是在模型权重之外再留 20%–40% 显存,长上下文场景留得更多。
实用结论:
- 单张 8GB 消费卡:跑 7B–8B 的 Q4 量化,上下文控制在 8K 以内,单路体验尚可。
- 单张 16GB:14B Q4 或 7B Q8,可以开少量并发。
- 单张 24GB(3090/4090 一类):32B Q4 是甜点,或 14B Q8 跑更高并发。
- 多卡 / 48GB 以上:70B Q4 才现实,否则别硬上。
第二步:Ollama —— 单机快速起一个 OpenAI 兼容端点
Ollama 默认就在 11434 端口暴露 OpenAI 兼容的 /v1 路由,这是它最被低估的一点。
```bash
# 安装后拉模型
ollama pull qwen3:8b
ollama pull llama3.1:8b
# 确认 OpenAI 兼容端点可用
curl http://localhost:11434/v1/chat/completions \
-H "Content-Type: application/json" \
-d '{
"model": "qwen3:8b",
"messages": [{"role":"user","content":"用一句话解释 KV Cache"}]
}'
```
注意:Ollama 的 /v1 端点不校验 API Key,随便填一个非空字符串即可(很多 SDK 要求字段非空)。
用 Modelfile 固化系统提示词和采样参数,避免每次请求都塞长 system prompt(那会白烧上下文):
```dockerfile
# Modelfile
FROM qwen3:8b
PARAMETER temperature 0.3
PARAMETER num_ctx 8192
PARAMETER num_predict 1024
SYSTEM """你是一个严谨的技术助手。回答简洁,不确定时明确说不知道。"""
```
```bash
ollama create my-assistant -f Modelfile
ollama run my-assistant
```
让 Ollama 常驻并接受外部连接(默认只监听本机):
```bash
# Linux systemd 环境下
sudo systemctl edit ollama.service
# 加入:
# [Service]
# Environment="OLLAMA_HOST=0.0.0.0:11434"
# Environment="OLLAMA_KEEP_ALIVE=-1" # 模型常驻显存,避免反复加载
# Environment="OLLAMA_NUM_PARALLEL=4" # 并发请求数
```
OLLAMA_KEEP_ALIVE=-1 很关键:默认模型空闲几分钟就卸载,下次请求要重新加载,首 Token 延迟会飙到几十秒。
第三步:vLLM —— 要并发和吞吐就换它
Ollama 适合单用户、低并发。一旦你要给团队或服务用,vLLM 的 PagedAttention 和连续批处理(continuous batching)在吞吐上通常有数倍优势。
```bash
pip install vllm
# 起一个 OpenAI 兼容服务
vllm serve Qwen/Qwen3-8B \
--served-model-name qwen3-8b \
--host 0.0.0.0 --port 8000 \
--max-model-len 8192 \
--gpu-memory-utilization 0.90 \
--max-num-seqs 32
```
关键参数逐个说:
--gpu-memory-utilization 0.90:允许 vLLM 占用 90% 显存做权重 + KV Cache 池。调太低浪费,调太高容易 OOM。--max-model-len:这是最容易踩的坑。不设的话 vLLM 会按模型标称的最大上下文(可能 32K/128K)去预留 KV Cache,直接把显存吃爆。按你实际需要设。--max-num-seqs:同时处理的序列数上限。并发高但显存小就调低。--tensor-parallel-size N:多卡张量并行,N 等于卡数。--quantization:跑 AWQ / GPTQ / FP8 量化权重时指定。
量化权重建议从 Hugging Face 上找现成的 AWQ 或 GPTQ 版本,比自己在本地量化省事得多。
第四步:用 LiteLLM 做本地优先、云端兜底
这一步才是把「本地无限 Token」变成「可用的 Token 管道」的关键。LiteLLM Proxy 可以把本地端点和云端端点放在同一个 OpenAI 兼容接口后面,按顺序 fallback。
```yaml
# litellm_config.yaml
model_list:
- model_name: assistant
litellm_params:
model: openai/qwen3-8b
api_base: http://localhost:8000/v1
api_key: "not-needed"
- model_name: assistant
litellm_params:
model: openai/gpt-4o-mini
api_key: os.environ/OPENAI_API_KEY
router_settings:
routing_strategy: simple-shuffle
num_retries: 2
fallbacks: [{"assistant": ["assistant"]}]
```
```bash
litellm --config litellm_config.yaml --port 4000
```
调用方只认 http://localhost:4000 和模型名 assistant。本地服务在,就走本地;本地挂了或超时,自动落到云端。日常流量吃本地,云端只在异常时被触发,额度消耗能压到很低。
第五步:验证与压测
别凭感觉判断「够不够用」,跑个并发测试:
```bash
# 简单的并发探测
for i in $(seq 1 10); do
curl -s http://localhost:8000/v1/chat/completions \
-H "Content-Type: application/json" \
-d '{"model":"qwen3-8b","messages":[{"role":"user","content":"写一段 100 字的测试文本"}],"max_tokens":128}' &
done
wait
```
关注三个指标:首 Token 延迟(TTFT)、每 Token 输出速度(tok/s)、并发到第几路时开始排队。这三个数决定你能把它当生产接口还是只能当玩具。
注意事项
- 量化会掉质量,且不是线性的。 Q4_K_M 在多数任务上和 FP16 差距很小,但涉及长链推理、代码生成、数学时,掉点会明显。关键任务别用最低档量化。
- 上下文长度是显存杀手。 32K 上下文 + 高并发,KV Cache 可能比模型权重还大。先用小
max-model-len跑通,再逐步加。 - Ollama 的并发能力有限。
OLLAMA_NUM_PARALLEL调太高反而会因显存不足导致频繁换入换出,吞吐下降。单卡从 2–4 开始试。 - 别把裸端点暴露到公网。 Ollama 的
/v1不校验 Key,vLLM 默认也没有鉴权。要对外必须前置一层带鉴权的网关(LiteLLM 的 virtual key、Nginx + Basic Auth、或云厂商的私有网络)。 - 模型许可要看清。 开源权重不等于任意商用,Llama 系列、Qwen 系列、Mistral 系列的许可条款各不相同,商用前逐条核对。
- 电费和散热是真实成本。 一张 300W 的卡 7×24 跑,一年电费并不便宜。算清楚再决定值不值得。
- 本地模型不等于云端模型。 除非你的任务足够窄,否则别指望 8B 模型能顶替前沿闭源模型。它的定位是「高频、低难度、可容错的流量卸载」。
适用场景
适合本地供给层:
- 高频、格式固定的任务:文本分类、信息抽取、翻译、摘要、日志分析。
- 数据不能出内网的场景:法务、医疗、金融的敏感文本处理。
- 批量离线处理:几万条数据的清洗、打标,跑本地比按 Token 付费便宜得多。
- 开发和测试环境:不想为调试烧额度。
不适合:
- 需要前沿推理能力的复杂任务。
- 极高并发且无自有硬件的场景(这时租 GPU 或买 API 更划算)。
- 对延迟极敏感的实时交互(消费级卡的 TTFT 通常打不过云端)。
一句话总结
本地部署的价值不在于「免费」,而在于把可预测的高频流量从按量计费里摘出来。用 Ollama 起服务、vLLM 扛并发、LiteLLM 做路由和兜底,你得到的是一条边际成本接近电费的 Token 管道,而不是一个玩具。