先想清楚:本地部署到底「免费」在哪

本地跑开源模型不是零成本,它把「按 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)、并发到第几路时开始排队。这三个数决定你能把它当生产接口还是只能当玩具。

注意事项

  1. 量化会掉质量,且不是线性的。 Q4_K_M 在多数任务上和 FP16 差距很小,但涉及长链推理、代码生成、数学时,掉点会明显。关键任务别用最低档量化。
  2. 上下文长度是显存杀手。 32K 上下文 + 高并发,KV Cache 可能比模型权重还大。先用小 max-model-len 跑通,再逐步加。
  3. Ollama 的并发能力有限。 OLLAMA_NUM_PARALLEL 调太高反而会因显存不足导致频繁换入换出,吞吐下降。单卡从 2–4 开始试。
  4. 别把裸端点暴露到公网。 Ollama 的 /v1 不校验 Key,vLLM 默认也没有鉴权。要对外必须前置一层带鉴权的网关(LiteLLM 的 virtual key、Nginx + Basic Auth、或云厂商的私有网络)。
  5. 模型许可要看清。 开源权重不等于任意商用,Llama 系列、Qwen 系列、Mistral 系列的许可条款各不相同,商用前逐条核对。
  6. 电费和散热是真实成本。 一张 300W 的卡 7×24 跑,一年电费并不便宜。算清楚再决定值不值得。
  7. 本地模型不等于云端模型。 除非你的任务足够窄,否则别指望 8B 模型能顶替前沿闭源模型。它的定位是「高频、低难度、可容错的流量卸载」。

适用场景

适合本地供给层:

  • 高频、格式固定的任务:文本分类、信息抽取、翻译、摘要、日志分析。
  • 数据不能出内网的场景:法务、医疗、金融的敏感文本处理。
  • 批量离线处理:几万条数据的清洗、打标,跑本地比按 Token 付费便宜得多。
  • 开发和测试环境:不想为调试烧额度。

不适合:

  • 需要前沿推理能力的复杂任务。
  • 极高并发且无自有硬件的场景(这时租 GPU 或买 API 更划算)。
  • 对延迟极敏感的实时交互(消费级卡的 TTFT 通常打不过云端)。

一句话总结

本地部署的价值不在于「免费」,而在于把可预测的高频流量从按量计费里摘出来。用 Ollama 起服务、vLLM 扛并发、LiteLLM 做路由和兜底,你得到的是一条边际成本接近电费的 Token 管道,而不是一个玩具。