@charles_irl: 在上周关于@modal快速冷启动技术内部细节的博客文章中,新增了一个小段。本节……

X AI KOLs Following 新闻

摘要

Modal解释了如何使用云缓冲区、自定义文件系统、检查点/恢复以及CUDA检查点/恢复,将AI推理冷启动速度提升40倍,并将云缓冲区管理框架化为一个线性优化问题,用GLOP求解。

在上周关于@modal快速冷启动技术内部细节的博客文章中,新增了一个小段。 本节描述了如何将云缓冲区管理框架化为线性优化问题并用GLOP求解。 https://t.co/DQ4wvuXjre https://t.co/jYqlri4cKv
查看原文
查看缓存全文

缓存时间: 2026/05/19 08:45

上周的博客文章中新增了一小部分内容,关于@modal快速冷启动的技术内幕。

这部分描述了如何将云端缓冲管理表述为线性优化问题,并使用GLOP求解。

https://t.co/DQ4wvuXjre https://t.co/jYqlri4cKv


通过LP、FUSE、C/R和cuda-checkpoint将推理冷启动速度提升40倍

来源:https://modal.com/blog/truly-serverless-gpus 图表说明了在基线云系统和Modal上启动推理服务器的延迟

我们正处于推理时代。数十亿到万亿参数的神经网络在专用加速器上以每秒千万亿次运算的速度运行,用于大规模生成媒体(https://modal.com/blog/runway-chooses-modal-to-power-real-time-inference-for-runway-characters)、编写软件(https://modal.com/blog/lovable-case-study)和折叠蛋白质(https://modal.com/blog/seamless-computational-bio-at-chai-discovery)。

推理工作负载比以往占主导地位的训练工作负载更具变化性和不可预测性。这使得它们天然适合无服务器计算——在这种模式下,应用程序在(虚拟)机器之上定义,以便能够更灵活地扩缩容以应对变化的负载。

但只有在新的副本能够快速启动的情况下,无服务器计算才能发挥作用——快得能跟上需求变化(这种变化可能以秒为单位)。如果简单地启动一个运行着服务十亿参数大语言模型的SGLang实例在B200上,可能需要几十分钟,或者因GPU可用性问题而停滞数小时。

在Modal,过去五年我们为此进行了深入的工程工作。在这篇博客文章中,我们将详细介绍我们的做法。

有四个关键要素:

  • 云端缓冲:维护一个健康的空闲GPU小缓冲区,用于承接新负载
  • 自定义文件系统:从内容可寻址的多层云原生缓存中惰性加载容器镜像
  • 检查点/恢复:通过直接将进程恢复到内存,快速跳过CPU侧的初始化
  • CUDA检查点/恢复:通过直接将CUDA上下文恢复到内存,快速跳过GPU侧的初始化

结合这些技术,AI推理服务器副本的扩展时间从数千秒缩短至仅需几十秒。

我们一路上已经分享了一些片段(https://www.youtube.com/watch?v=3jJ1GhGkLY0)和点滴(https://modal.com/blog/jono-containers-talk),因为我们相信保密是一道糟糕的护城河。如果更多人学会如何高效使用GPU,市场上就会有更多可用资源供我们使用!

但这篇博客文章是我们首次将整个故事完整呈现。我们希望它能说服您,我们的系统值得使用(https://modal.com/signup)——或者加入我们(https://modal.jobs/)一同构建。

为什么要在乎无服务器GPU?为了最大化推理工作负载的GPU分配利用率。

首先,让我们清晰地定义问题。GPU昂贵且稀缺,所以我们希望最大化其利用率(https://modal.com/blog/gpu-utilization-guide),其中“利用率”是一个无量纲量:

利用率 := 已完成输出 ÷ 已付费容量

衡量利用率的方式有很多——即如何定义输出和容量。其中最复杂也最严格的大概是“模型FLOP/s利用率”,它将原始算法操作需求除以聚合算术带宽。

这对工程师来说是极具吸引力的。它对于大规模训练的“英雄运行”也至关重要,因此吸引了大量投资和关注,例如最近大家纷纷批评xAI大约10%的MFU(https://x.com/theinformation/status/2050606311440531809?s=20)。

但在堆栈的另一端,有一种更基本的利用率形式,它会破坏推理工作负载中已完成输出与已分配容量之间的关系,即GPU分配利用率:

GPU分配利用率 := 运行应用程序代码的GPU秒数 ÷ 付费的GPU秒数

关于“GPU利用率”术语的补充说明nvidia-smi 及类似工具报告的“GPU利用率”介于上述两个极端之间。它报告的是内核代码在GPU上运行的时间比例——确切地说,是GPU上有CUDA流运行的时间比例。更多详情参考这里(https://modal.com/blog/gpu-utilization-guide)。

推理应用程序的规模变化很大。与训练不同,容量需求不在工程组织的直接控制和管理之下,而是由外部用户行为驱动——来自市场、社交媒体算法或产品团队。

以下是我们用于模拟推理应用程序的时变泊松过程的每分钟请求示例。请注意不仅有季节性变化(每日周期),还有随着平均需求增加而出现的长期需求波动加剧趋势。

图:时变泊松过程模拟的推理流量示例,带有季节性变化和尖峰

尖峰需求带来了严重的工程问题。借用AWS的Marc Brooker(https://brooker.co.za/blog/2023/03/23/economics.html)的话:“系统的成本与其(短期)峰值流量成正比,但对于大多数应用程序,系统产生的价值与其(长期)平均流量成正比。”尖峰需求意味着高峰值-平均比,这对系统经济性构成挑战。

具体来说,设想一下此类应用程序的容量规划。您的需求(在延迟目标内服务请求所需的GPU数量)可能如下所示:

使用固定的、过度配置的GPU分配,利用率很低

为了妥善服务预期负载,您分配(自行部署、从超大规模云租赁)了140个GPU。但其中大多数GPU在大部分时间处于空闲状态——GPU分配利用率很低。

您可能会指责我们在这里自说自话。但指出这一点的不仅仅是我们!另请参见Hebbia的优秀博客文章(https://www.hebbia.com/blog/the-hidden-economics-of-llm-inference)。而且我们拥有数据,而不仅仅是感觉:根据2024年AI基础设施规模报告(https://ai-infrastructure.org/the-state-of-ai-infrastructure-at-scale-2024/),大多数组织在峰值需求运行时的GPU分配利用率不到70%。实际的GPU分配利用率通常接近10-20%。

在固定分配下,需求也可能在意外尖峰时超过供应。试图预测这些尖峰只会进一步增加成本——而非增加收入。

无服务器GPU的难点是什么?启动延迟。

直接的解决方案是配置自动扩缩容能力:当需求增加时,增加供应。

如果简单地做,这实际上会恶化问题:

如果分配缓慢,利用率和QoS都会受损

在没有优化的情况下,从超大规模云API请求到运行的服务副本可能需要几十分钟。

您需要完成以下步骤:

  • 启动新实例并进行健康检查(数分钟到数十分钟)
  • 加载应用程序程序和文件系统状态(数分钟)
  • 在宿主机上启动应用程序程序,准备服务请求(几十秒)
  • 在设备上启动应用程序程序,准备服务请求(数分钟到数十分钟)

在此过程中,负载超过容量,QoS通常会下降(表现为更高的并发或队列导致尾部延迟膨胀,更糟的情况下出现503错误)。这意味着用户不满。如果容量上线太慢,甚至可能错过瞬时尖峰。但由于需求的不可预测性和分配的困难,这些容量通常会长时间保持运行,利用不足。

在Modal(https://modal.com/),我们将推理应用程序在GPU上的启动时间从几十分钟优化到了几秒或几十秒。通过这些优化,各种GPU推理应用程序都可以“真正无服务器”地运行:供应容量与系统需求紧密匹配。

通过快速自动分配,利用率和QoS都可以很高

在本文的其余部分,我们将解释我们采用的工程方法以及针对上述四个步骤实现的性能优化,这些步骤涵盖从云存储系统机器管理本地磁盘CPU,当然还有GPU的整个堆栈。

通过这些优化,Modal上的推理启动速度提升了40倍:从2000秒降至50秒。

图:基线云系统和Modal上推理服务器启动延迟对比图表 在基础云系统中,推理服务器启动需要超过2千秒,而在Modal上只需约50秒。实现这一加速的关键架构优化已标注,并用颜色编码对应其针对的关键系统组件——GPU和GPU内存、CPU和CPU内存、本地固态硬盘(SSD)或机器/实例管理。我们在整篇文章中均使用此配色方案和示意图。

通过将实例分配和健康检查移出热路径,可以消除数十分钟的延迟

考虑副本启动的第一步:

  • 启动新实例并进行健康检查(数分钟到数十分钟)

我们可以通过提前完成这一步来将其移出热路径:维护一个由许多应用程序共享的空闲健康GPU缓冲区,将新副本调度到这些单元上,并异步地将新设备启动到缓冲区中。当缓冲区过大时,我们也可以在副本下线时释放单元。

在已分配机器之上维护一个小的、现成但未使用的机器缓冲区,可以快速将新副本调度到空闲机器上(用亮色表示)。从缓冲区服务请求可将副本启动延迟减少数十分钟。

图:通过云实例缓冲区减少推理启动延迟数十分钟的示意图

关于系统级和应用级缓冲区的补充说明如果您运行的是单个工作负载而非多工作负载系统,您可能会问为什么我们只将实例分配移出“热路径”并放入缓冲区。难道我们不能将更多的设置工作移到缓冲区中吗?当然可以!Modal用户可以通过buffer_containers(https://modal.com/docs/guide/cold-start#run-more-warm-containers)维护一个已准备好服务请求的应用程序层副本缓冲区。但即便如此,吸收给定幅度尖峰所需的缓冲区大小与创建新副本的速度成正比,因此下面描述的优化对于单工作负载系统仍然重要。

管理活动实例和这个缓冲区是一个有趣的线性规划问题,正如我们在别处所写(https://modal.com/blog/resource-solver)。大致如下:

数学优化公式,用于选择GPU实例启动。参数定义了总请求GPU、缓冲GPU、可能的实例类型、成本和扩展限制。输出是要启动的实例类型向量。目标是最小化总成本,约束条件是提供至少请求加缓冲的GPU数量(假设每个实例8个GPU),并保持每个实例计数在其特定类型的扩展限制内。

我们使用Google的GLOP求解器(https://developers.google.com/optimization/lp/lp_advanced),输入爬取的云提供商价格和用户任务。由于云提供商并不总是在他们宣传的价格和区域有容量,我们还需要反馈观察到的供应情况。

图:求解器服务示意图

运行缓冲区会将峰值分配利用率限制在100%以下。这是一个合理的折衷,因为100%利用率通常是海市蜃楼。想想看,通常当其他资源(如CPU或IOPS)利用率过高时,我们会启动新副本甚至呼叫工程师!

这对于鲁棒性很重要。100%利用率的系统没有容错余地,因此故障往往会变成事故。我们可以亲自建议您在生活里增加更多缓冲区——在浴室里多备一把牙刷;在办公室、家里和随身携带的包里各放一个关键设备的充电器。

这个缓冲区对于在单个系统上容纳更广泛的工作负载特别有用。在Modal,我们积极拥抱(https://modal.com/blog/agents-devex)支持各种“开发”工作负载,而不仅仅是生产服务,因为我们可以快速创建新的开发环境。额外好处是,这些环境默认可重现,且运行在生产级基础设施上。缩小与生产基础设施的差距也能提高开发速度。

当然,魔鬼在细节中。一个关键点:健康检查对GPU至关重要,GPU的故障率远高于其他硬件,包括像机械硬盘这样出了名挑剔的组件。我们关于GPU健康检查系统的详细内容在此(https://modal.com/blog/gpu-health)。简而言之,根据我们的经验,您需要在启动时进行一次简短的主动健康检查,并持续监控(https://modal.com/docs/guide/gpu-health)之后可能出现的健康问题,但可以将更密集的检查(如dcgmi diag)放在较慢的节奏上(对我们来说是每周一次)。

按(匿名化)云分组,每小时每个GPU的关键级别Xid错误(https://modal.com/docs/guide/gpu-health)数量。故障率远非可忽略!

通过从内容可寻址缓存中惰性提供文件,可以将容器启动时间从几分钟缩短到几秒

现在考虑下一步:

  • 加载应用程序程序和文件系统状态(数分钟)

在当代实践中,这通常意味着启动一个或多个容器或虚拟机。

大致来说,容器是一个根文件系统,支持具有有限权限的进程。对于容器的大规模分布式部署,性能瓶颈在于根文件系统在工作节点上的构建。

操作系统发行版的根文件系统非常庞大——成千上万个文件,大小达到GB。简单使用docker run之类的命令,你需要加载整个文件系统,通常以云以太网支持的几GB/s速度进行。更糟糕的是,容器镜像分为多个层,必须顺序应用。

解决方案是将容器启动器(Docker的runc,gVisor的runsc)与容器镜像交付分离。我们使用一个自定义文件系统,称为ImageFS,基于libfuse构建,结合了惰性加载和专为匹配云提供商特性设计的多层内容可寻址缓存。

我们在自定义文件系统中实现的快速容器启动的“诀窍”是明智地懒惰(就像所有优秀工程师所做的那样)。容器镜像包含许多文件,比如全球时区和区域设置信息,大多数应用程序永远不会读取它们。你可以跳过在容器启动前加载整个文件系统,而是只阻塞至加载元数据(索引)。元数据只有几兆字节,因此可以在100毫秒或更短的时间内加载,连同启动容器所需的其他一切。

图:在容器启动的同时惰性加载容器文件系统内容的示意图

其余内容可以与其他工作并行加载——甚至根本不加载!大多数文件不会被读取,正如USENIX FAST ’16的Slacker论文(https://www.usenix.org/conference/fast16/technical-sessions/presentation/harter)中图5所报告,如下所示。

我们目前使用libfuse(https://github.com/libfuse/libfuse)实现此文件系统。它是一个用于在user空间编写Linuxfilesystems的library。内核中间

相似文章