冷启动慢在哪里
推理服务的启动不止是读文件:权重从磁盘读入显存、引擎按上下文上限分配 KV 池、图捕获或即时编译在首批请求时完成,这些步骤叠加起来可能耗时数十秒到数分钟。如果新实例还没热就被接入流量,会出现一段首请求失败或超时的窗口,滚动发布与自动扩容时尤其明显。
预热脚本(示意)
预热脚本(示意)
# 服务就绪后先发几条真实形状的请求,把图捕获与编译路径跑热
for i in 1 2 3; do
curl -s http://127.0.0.1:8000/v1/chat/completions \
-H 'Content-Type: application/json' \
-d '{"model":"<模型>","messages":[{"role":"user","content":"预热请求"}],"max_tokens":16}'
done
# 预热请求应覆盖业务里的典型上下文长度,而不是只发一句短话冷启动耗时来源
| 权重加载 | 磁盘带宽与文件数量共同决定,网络盘会更慢 |
|---|---|
| 显存分配 | KV 池按配置上限一次性预留 |
| 图捕获或编译 | 首次前向计算时完成,之后复用 |
| 常驻策略 | 网关保活与定时心跳让实例保持热状态 |
阶段与检查点
| 阶段 | 耗时特征 | 检查方式 |
|---|---|---|
| 进程启动 | 秒级,取决于依赖加载 | 服务日志首个时间戳 |
| 权重加载 | 十秒到数分钟,随盘速与模型规模变化 | 日志中加载完成的时间点 |
| 引擎初始化 | 秒级到数十秒,与并行配置有关 | 启动日志里的初始化段落 |
| 预热完成 | 取决于请求形状与数量 | 用真实形状请求测首延迟 |
典型使用场景
- 滚动发布:新实例预热完成后再接入流量,避免首批请求超时
- 自动扩容:扩容出的实例先跑预热脚本,再注册到负载均衡
- 低峰保活:靠定时心跳让常驻实例保持热状态,避免首个用户等待
- 故障切换:备实例平时也保持热,切换时才能立刻承接流量
- 压测准备:压测前先预热,否则前几分钟的数据不具代表性
用模型清单端点探活成功不代表服务可服务:该请求不触发模型计算路径,就绪判断应使用能触发计算的最小请求。
扩容的新实例未预热就接入流量会出现首请求超时窗口:就绪探针要覆盖真实计算路径,滚动发布期间尤其要注意。