将你的 GPU 推理自动缩放至零(Autoscaling to zero)看起来是显而易见的成本控制策略。GPU 是账单中最昂贵的项目,流量具有突发性,而空闲时间纯粹是浪费。所以你开启了缩放至零(scale-to-zero),看着云端账单下降,并以此自得。
然而,在一段沉寂之后,一位用户出现了,他们的第一次请求需要 60 秒才能返回一个 token。运行 Serverless LLM 推理的生产部署经常报告冷启动超过 40 秒才出现第一个 token —— 相比之下,模型预热后的每个 token 延迟大约仅为 30 毫秒。这是冷路径和热路径之间千倍的延迟差距,而这完全取决于你的流量空闲情况。
这是没有人会写在 PPT 上的权衡。缩放至零并没有消除成本;它将稳定的金钱成本转化为了突发性的延迟成本,然后将这种延迟成本隐藏在仪表盘很少关注的 p99 尾部。
这种情况比你已经了解的 Serverless 冷启动更糟糕的原因是结构性的。无状态函数的冷启动涉及容器拉取和运行环境启动 —— 耗时几百毫秒到几秒。LLM 冷启动不仅包含这些,还包括将模型权重移动到 VRAM、CUDA 上下文初始化、算子编译(kernel compilation)和 CUDA 图捕获(CUDA graph capture),以及 KV 缓存分配。模型权重不是冷状态的副作用。模型权重本身就是 冷状态。你无法通过懒加载(lazy-load)来解决 16 GB 检查点带来的问题,因为这个检查点正是请求所需要的。
冷启动剖析
当 Serverless 平台从零开始扩展一个 GPU 工作节点时,用户的请求会被阻塞在由一系列顺序阶段组成的流水线之后:
GPU 分配与调度。 平台寻找物理 GPU,挂载它,并将你的容器调度到上面。在繁忙的区域,仅这一步就需要排队。
容器拉取与启动。 你的镜像 —— 在内置了 CUDA、PyTorch 和推理服务后通常有几个 GB —— 被获取并启动。
权重获取。 模型检查点从对象存储或网络卷读取到主机内存中。对于半精度的 70B 级模型,这涉及超过 100 GB 的传输。
权重加载到 VRAM。 主机内存通过 PCIe 总线复制到 GPU。
预热。 CUDA 上下文创建、如果你使用了 torch.compile 则需要编译、算子自动调优、CUDA 图捕获以及 KV 缓存预分配。
这里的关键属性是,这些阶段大多是顺序进行的,并且由其中一项主导。对于大型模型,权重移动压倒了其他一切。这既是好消息也是坏消息。坏消息:你无法通过优化微小的阶段来获得显著的收益。好消息:只有一个值得攻克的瓶颈,而所有的缓解工具包都针对它。
没有人诚实建模的成本与延迟边界
在寻求缓解措施之前,先算算账,因为诚实的计算会让许多缩放至零的部署胎死腹中。
缩放至零是一场赌博,赌的是节省的空闲成本超过了产生的延迟成本。空闲成本显而易见:它是 GPU 小时单价乘以原本不被使用的小时数。延迟成本则更难衡量,因为它由用户而非财务团队支付,并且表现为用户流失和差评,而不是账单上的条目。
存在一个盈亏平衡的流量率,但大多数团队从未计算过。逻辑很简单:如果你的请求到达间隔足够长,以至于平台在两次请求之间缩减了规模,那么每一个请求都是冷启动。考虑一个实际推理需要 5 秒但冷启动需要 30 秒的工作负载:85% 的挂钟时间 —— 以及你支付的 85% 的 GPU 计费时长 —— 都花在了等待而不是处理上。你并没有在省钱。你是在为“慢”这一特权支付溢价。
2025–2026 年生产实践中总结出的普遍指导意见非常直接:如果你的平均 GPU 利用率超过大约 40–50%,那么专用的常驻容量不仅比 Serverless 更快,而且更便宜。Serverless 适用于真正的突发性或零散工作负载 —— 如内部工具、批处理任务、尚在寻找产品与市场匹配度(product-market fit)的新功能 —— 这些场景下空闲时间占主导,且偶尔的冷启动是可以容忍的。对于稳定的、对延迟敏感的流量,它表现极差,而这正是面向用户的聊天或语音产品所产生的流量。
陷阱在于这种情况会悄无声息地发生逆转。功能上线,流量增长,利用率越过盈亏平衡线,却没有人重新计算。发布时正确的 Serverless 配置,现在比预留 GPU 既慢又贵,而唯一的信号是每个人都习惯忽视的、缓慢恶化的 p99。
缓解工具包 如果你算过账后,发现 Serverless 依然胜出 —— 突发流量、存在真实的空闲间隙 —— 那么工程问题就是如何减轻冷启动带来的痛苦。有三类修复方案,且可以组合使用。
分层池:保留一小部分预热基础。 最有效的策略是拒绝完全缩放至零。保持一两个工作节点永久预热,以吸收突发流量的第一个请求,让超出该基线的部分再从零开始缩放。第一个用户访问到预热节点并获得正常响应;冷层在他们身后启动以处理后续浪涌。你为一个小的常驻基础付费,但你已将冷启动从“面向用户”的事件转变为“容量规划”事件。大多数 Serverless GPU 平台现在直接提供最小实例或最小并发的配置选项 —— 使用它并不罕见,而是基本操作。
更快的权重加载。 既然权重移动是主导项,那就直接攻克它。流式加载器(如 NVIDIA 的 Run:ai Model Streamer)从存储中并发读取检查点分片,并直接导向 GPU 内存,使存储读取与主机到设备的复制重叠进行,而不是串行。研究系统进一步推动了这一点:利用未被充分利用的 GPU 内存和本地存储的多级检查点加载,据报道可将启动时间缩短 6–8 倍。流水线化的冷启动设计将库加载和运行环境准备隐藏在模型获取之后 ,因此只有不可避免的传输仍处于关键路径上。
快照与恢复。 最强大的技术几乎完全跳过了冷启动流水线。通过使用 CUDA 检查点/恢复技术(例如通过 CRIU 机制),你在容器完成初始化后对其进行快照:权重已加载到 VRAM、CUDA 上下文已构建、算子已编译、图形已捕获。下一次冷启动将直接恢复该冻结状态,而不是重新构建。数据非常惊人:运行小型 Qwen 模型的 vLLM 服务已从 45 秒的冷启动缩短到约 5 秒,其他工作负载也有约 10 倍的提升,因为 torch.compile 和算子预热完全不再运行。缺点是快照/恢复依赖于较新的 NVIDIA 驱动分支,目前仍处于较新阶段 —— 请将其视为一种快速发展的能力,而非成熟定论。
一个相关的想法是“睡眠”而非“停止”:与其拆除工作节点,不如将权重卸载到 CPU 内存(或丢弃权重但保持进程和 CUDA 上下文活跃),并按需重新加载。据报道,这种模式下的唤醒速度比完整的冷启动加载快 18–200 倍,代价是空闲时仍需占用主机内存。它是“完全热”和“完全冷”之间的中间层,通常是中等频率流量的正确默认选择。
测试空闲间隙,而非吞吐量 这里有一个贯穿始终的失效模式:冷启动对于大多数团队的负载测试方式来说是不可见的。
标准的负载测试会逐渐增加到目标请求速率并保持稳定。在持续负载下,工作节点永远不会缩容,因此测试仅衡量了“热”路径。它会告诉你系统很快,会告诉你 p99 指标良好。但对于真正伤害用户的事情,它会完全保持沉默,因为真正伤害用户的是“间隙后的第一个请求”,而持续吞吐量测试中没有任何间隙。
一个能捕捉到冷启动的负载测试必须模拟真实的空闲行为:由足够触发缩容的安静期分隔开的突发流量,然后是一个定时落在冷路径上的探测请求。真正重要的指标不是平均延迟,甚至不是普通的 p99 —— 而是空闲窗口后第一个请求的延迟,并将其作为独立的分布进行衡量。如果你的仪表盘上没有这个数字,那么你的冷启动从设计上就是未被监控的,你将以每个人都会经历的方式发现它:来自用户的投诉,或者一群悄无声息再也没有回来的流失用户。
同样的盲点也适用于告警。平均延迟的告警永远不会在冷启动时触发,因为根据定义,冷启动是罕见的 —— 这正是缩容至零(scale-to-zero)的初衷。你需要一个专门针对“空闲后首个请求延迟”的告警,否则你根本没有告警。
架构维度的认知 更深层的一点是,缩容至零将模型视为代码,但事实并非如此。代码的加载成本很低;你可以按需分发、分页加载和 JIT 编译。模型权重是“状态级别的数据” —— 在运行第一条有用指令之前,数十到数百 GB 的数据必须物理上占据加速器。如果 Serverless 抽象无视这一点,那么它卖给你的是一种在你所需的延迟下无法真正交付的弹性。
因此,实际的准则是:在启用缩容至零之前进行盈亏平衡计算,并在每次流量发生实质性变化时重新计算 —— 正确的配置不是一个发布时的决定,而是一个常态化的决策。保持一个根据突发起始速率确定的“热底座”,而不是盲目追求字面意义上的零。将权重加载时间视为唯一值得优化的数字,并依次尝试流式加载器和快照/恢复技术。最后,去测试空闲间隙,因为一个没有间隙的测试,是一个预先约定好不去发现 Bug 的测试。
缩容至零是一个真实的工具。它只是并非免费,其代价不在定价页面上 —— 而是在你的 p99 尾部延迟中,由任何碰巧第一个到达的用户支付。
会员专享
余下内容仅对会员开放。 会员可读完整内容 —— 每一个公开发布的观点背后,那些框架、决策与推理的全貌。
— 完整文章,包含未公开存档的部分 — 可落地的工作框架,附带权衡与决策依据 — 新文章抢先看,先于公开发布 登录以继续阅读→ 随时取消 · 一次订阅,畅读全部