大模型服务扩容一个新实例,第一个请求总要慢上好几秒,之后的请求却快得正常——这个现象背后就是冷启动。消除冷启动的核心手段是预热:在实例正式接客之前,把该准备的东西提前备好,让第一次请求和第十次请求一样快。
为什么第一次特别慢?因为新实例面前堆着一整串「第一次」:第一次把模型权重从存储搬进显存,第一次分配计算所需的缓冲区,第一次编译计算图,甚至连缓存的连接池都是空的。每一项都是几秒级的开销,叠起来就是用户可感知的漫长等待。通义千问这类对话服务看起来随叫随到,是因为背后的常驻实例早就把这些「第一次」消耗光了。
冷启动到底慢在哪一步
把几秒钟拆开看,大头通常在模型加载:几十GB的权重文件从存储系统读到显存,受带宽限制,时间下限摆在那里。其次是计算图编译与显存池初始化,推理框架第一次运行时要确定每层算子怎么排布。最后还有零碎的小头,例如首个请求触发的词表加载、探测请求的往返。找准最慢的一段,预热才有靶子。
预热的几种常见做法
最常见的预热是权重预载:实例启动后、接入流量前,先跑一遍完整的加载流程。更进一步是请求试跑——用几条虚构的请求打一遍新实例,把编译、缓冲区分配这些惰性初始化全部触发出来,试跑通过才允许正式接客。还有一层是连接预热:提前和上下游依赖(存储、鉴权、缓存)把连接建好,避免第一个真实用户替系统交学费。用秘塔AI搜索查一份部署文档,页面几乎秒开,背后同样是预渲染和缓存在兜底,道理相通。
三种预热做法各自省掉哪段开销:
| 预热做法 | 怎么触发 | 省掉的开销 |
|---|---|---|
| 权重预载 | 实例启动后、接入流量前,跑一遍完整加载流程 | 权重从存储搬进显存的漫长等待 |
| 请求试跑 | 用几条虚构请求打一遍新实例,通过才准接客 | 计算图编译与缓冲区分配的惰性初始化 |
| 连接预热 | 提前和存储、鉴权、缓存把连接建好 | 第一个真实用户替系统交的学费 |
预热时机与触发条件怎么定
预热做几次、什么时候做,取决于扩容的触发方式。定时预热适合流量有明显潮汐的场景,比如早高峰前半小时批量预热一批实例。事件驱动预热则挂在扩容信号上:调度器决定加机器,新实例先预热再上线。这里的关键判断是「预热完成」要有明确信号——权重加载完毕、试跑请求返回正常——而不是靠猜测等待时间。
预热的验证与观测
预热做了不算完,要能看见效果。给首个请求单独打标,持续追踪它的耗时分布,是判断预热是否到位的直接证据;预热失败的实例要有隔离机制,不能混进正常流量池;扩容风暴时批量预热可能挤占存储带宽,把预热任务的优先级排进调度,避免为了准备反而拖慢线上。
冷启动预热自查清单
- 权重预载完成后再接入流量,顺序不可反
- 至少跑一次请求试跑,触发全部惰性初始化
- 上下游连接提前建立,别让首个用户交学费
- 「预热完成」有明确信号,而非等待固定秒数
预热只是消除冷启动的一环,周边配套同样决定体验。实例退场换新时,参考推理服务的优雅停机?内部门道在这保证存量请求不受伤;跨区域新副本的首请求问题,结合多地域部署是怎么降延迟的?过程拆开看一起看更完整;加载本身慢,提速手段在模型加载是怎么提速的?从原理到落地;显存吃紧时的退让策略,见显存不够时的卸载方案?每一步都讲透;把重复问题的答案先存起来,则靠结果缓存层是怎么搭的?机制细节全梳理。
冷启动快问快答三则
- 预热会浪费算力吗?:它会占用一小段机器时间,但换来的是首请求体验,对面向用户的服务来说这笔开销通常值得。
- 有没有完全不冷启动的架构?:保留最小数量的常驻实例兜底,扩容部分走预热,是工程上常见的折中做法。
- 怎么知道预热有没有效果?:对比预热前后首个请求的耗时分布,差异明显就是起效了,反之要检查是不是漏了某个惰性环节。


