为什么换这个角度

很多本地部署教程把注意力全放在「4-bit 还是 8-bit」上。量化档只解决「能不能装下」,不解决「请求来了模型在不在」。真实使用中,最贵的成本不是显存,而是每次冷启动那几十秒到几分钟的加载时间——这段时间用户拿不到 Token,团队就会回头去用云端 API。

所以本文的目标不是榨显存,而是让「热模型」始终在线、让「冷模型」按需出现,把首 Token 延迟压到可接受范围。

操作步骤

第一步:用 Ollama 常驻一个「日常档」小模型

Ollama 的 keep_alive 参数决定模型在最后一次请求后驻留多久。默认 5 分钟,对日常对话偏短。

```bash

# 让 7B/8B 级别模型常驻,避免反复加载

curl http://localhost:11434/api/generate -d '{

"model": "qwen2.5:7b-instruct",

"prompt": "ping",

"keep_alive": -1

}'

```

keep_alive: -1 表示不主动卸载。适合显存放得下、调用频率高的小模型。若显存紧张,用 "keep_alive": "30m" 之类的时间值,让它在空闲一段时间后自动让位。

要点:常驻模型要选「够用就好」的尺寸,它的职责是承接 80% 的日常请求(摘要、分类、改写、简单问答),把大模型留给真正需要的任务。

第二步:用 systemd 管住 vLLM 的「按需档」

vLLM 启动一个 32B 级别模型通常要几十秒到一两分钟(取决于权重加载速度与是否启用 --enforce-eager)。不要在脚本里裸跑 python -m vllm.entrypoints.openai.api_server,用 systemd 单元管理生命周期,才能被路由按需唤醒、空闲回收。

```ini

# /etc/systemd/system/vllm-large.service

[Unit]

Description=vLLM large model (on-demand)

After=network.target

[Service]

Type=simple

ExecStart=/opt/venv/bin/python -m vllm.entrypoints.openai.api_server \

--model /models/Qwen2.5-32B-Instruct-AWQ \

--served-model-name large \

--port 8000 \

--gpu-memory-utilization 0.85 \

--max-model-len 8192

Restart=on-failure

[Install]

WantedBy=multi-user.target

```

关键点:

  • --served-model-name 固定成 large,路由层就不用关心具体权重路径;
  • --gpu-memory-utilization 留出余量,避免和常驻小模型抢显存时 OOM;
  • 用 Restart=on-failure 兜住加载失败。

第三步:写一个「唤醒 + 等待就绪」的钩子

路由在把请求转给 vLLM 之前,先探测 /v1/models。不通就 systemctl start,然后轮询直到就绪。

```python

import subprocess, time, requests

def ensure_large(timeout=180):

url = "http://127.0.0.1:8000/v1/models"

try:

requests.get(url, timeout=2)

return True

except Exception:

pass

subprocess.run(["systemctl", "start", "vllm-large"], check=False)

deadline = time.time() + timeout

while time.time() < deadline:

try:

requests.get(url, timeout=2)

return True

except Exception:

time.sleep(2)

return False

```

注意:首次唤醒的请求会等很久,路由层要给它一个独立的、更长的超时,并且不要让所有请求都触发唤醒——只有被判定为「需要大模型」的请求才走这条路径。

第四步:加一个空闲回收定时器

按需档不能一直占着显存,否则常驻小模型会被挤掉。用 systemd timer 或一个简单的守护脚本,在连续 N 分钟无请求后 systemctl stop vllm-large。

```bash

# 粗略示例:检查最近请求时间,超时则停止

systemctl stop vllm-large

```

回收阈值取决于你的使用节奏。团队白天高频、夜间低频,可以设成夜里停、白天保活。

第五步:路由层做「两级分流」

一个最小的分流规则:

  1. 请求带 model: small 或未指定 → 直接打 Ollama 的 OpenAI 兼容端点(http://localhost:11434/v1);
  2. 请求带 model: large 或长度/任务复杂度超过阈值 → 先 ensure_large(),再打 vLLM 的 /v1/chat/completions;
  3. 大模型唤醒失败 → 降级回小模型并记录日志,保证「不断供」。

这样客户端只认一个 base_url,背后是「常驻 + 按需」两条供给。

注意事项

  • 显存是共享资源:常驻模型和按需模型必须算好总占用。经验上,小模型常驻 + 大模型 --gpu-memory-utilization 0.85 的组合在多卡机器上更稳;单卡时要把小模型调小或改用时间型 keep_alive。
  • 冷启动时间不可消除:权重加载受磁盘速度影响很大。把模型放在 NVMe 上,或使用 --load-format 相关选项,能明显缩短唤醒时间。
  • 不要把「唤醒等待」算进用户体验:异步任务(批处理、离线摘要)适合走按需档;交互式对话尽量只走常驻档。
  • Ollama 与 vLLM 的端口要分开,并在路由里显式配置,避免默认端口冲突。
  • 日志要记全:唤醒次数、唤醒耗时、降级次数,这三个指标直接决定这套方案值不值得留。
  • 模型名称、版本与许可证以各项目官方仓库为准;商用前确认权重许可。

适用场景

  • 团队日常有大量轻量请求(分类、抽取、改写),偶尔需要大模型做复杂推理;
  • 只有一两张卡,显存不足以同时常驻两个模型;
  • 对「首 Token 延迟」敏感,但对「复杂任务可以等一会」可以接受;
  • 希望把云端 API 的调用量压下来,把 Token 成本变成固定的电费与硬件折旧。

与量化档方案的区别

量化档方案回答的是「一张卡能装多大模型」;本文回答的是「模型什么时候该在显存里」。两者不冲突:你可以先按显存预算选好量化档,再用本文的常驻/按需分层决定谁一直在线、谁按需出现。