跳到正文
Modal Blog· Charles Frye·· 2026-05-12精选AI 评分62

Modal 如何实现真正的无服务器 GPU

How we achieved truly serverless GPUs

AI 导读

Modal 发文拆解其无服务器 GPU 的四项关键工程:云缓冲区、内容寻址的懒加载文件系统 ImageFS、CPU 检查点/恢复与 CUDA 检查点/恢复,把推理副本启动从约 2 千秒降到约 50 秒。

推荐理由

Modal 拆解了把推理副本冷启动从数千秒压到数十秒的四层工程手段,可迁移到自建推理服务。

正文 · AI 翻译

Diagram indicating latency to scale up an inference server in a baseline cloud system and on Modal

我们正处于推理时代。数十亿到数万亿参数的神经网络在专用加速器上以每秒数千万亿次运算的速度运行,大规模地生成媒体、编写软件和折叠蛋白质。

推理工作负载比之前占主导地位的训练工作负载更加多变且难以预测。这使得它们天然适合无服务器计算,在这种计算模式下,应用程序在(虚拟)机器之上的一层定义,因此可以更容易地扩展和缩减以应对变化的负载。

但无服务器计算只有在能够快速启动新副本时才有效——速度要跟得上需求变化,而需求变化可能以秒为单位。天真地启动一个新实例,比如在 B200 上运行一个十亿参数 LLM 的 SGLang,可能需要数十分钟,或者因 GPU 可用性而停滞数小时。

在 Modal,我们在过去五年中进行了深入的工程工作来解决这个问题。在这篇博客文章中,我们将介绍我们所做的工作。

有四个关键要素:

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

它们共同将 AI 推理服务器副本的扩展时间从数千秒缩短到仅数十秒。

我们一路分享了这项工作的点点滴滴和片段,因为我们相信保密是一种糟糕的护城河。而且,如果更多人学会如何高效使用 GPU,市场上就会有更多可用的 GPU 供我们使用!

但这篇博客文章是我们第一次将整个故事汇集在一处。我们希望它能说服您,我们的系统值得投入——或者加入我们共同构建它。

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

首先,让我们清晰地界定问题。GPU 昂贵且稀缺,因此我们希望最大化其利用率,这里的“利用率”是以下无量纲量:

利用率 := 实现的输出 ÷ 支付的容量

衡量利用率——定义输出和容量——有很多方法。其中最复杂、最严格的可能是“模型 FLOP/s 利用率”,它将原始算法运算需求除以总算术带宽。

这对工程师来说极具吸引力。它对“英雄式”大规模训练尤其关键,因此吸引了大量投资和关注,例如最近大家都在抨击 xAI 约 10% 的 MFU。

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

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

关于“GPU 利用率”术语的补充说明

nvidia-smi 及类似工具报告的“GPU 利用率”介于这两个极端之间。它报告的是 内核代码 在 GPU 上运行的时间占比——字面意思就是 GPU 上有 CUDA 流运行的时间占比。阅读更多

这里

.

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

以下是我们用于对推理应用建模的时变泊松过程中每分钟请求数的示例轨迹。请注意不仅有季节性变化(每日周期),还有随着平均需求增加而需求变异性增大的长期趋势。

Diagram of simulated inference traffic from a time-varying Poisson process with seasonal variation and spikes

尖峰式需求带来了严重的工程问题。借用 AWS 的 Marc Brooker 的话:“系统的成本随其(短期)峰值流量而扩展,但对大多数应用而言,系统产生的价值随其(长期)平均流量而扩展。”尖峰式需求意味着高峰均比,这对系统经济性构成挑战。

具体来说,想象一下对这样一个应用进行容量规划。你的需求(以在延迟目标内服务请求所需的 GPU 数量衡量)可能看起来像这样:

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

为了恰当地服务你预期的负载,你分配(上架部署、在超大规模云厂商处租用)140 块 GPU。但其中大多数 GPU 大部分时间都处于空闲状态——GPU 分配利用率很低。

你可能会指责我们在这里自说自话。但我们并不是唯一指出这一点的人!参见 Hebbia 的这篇优秀博文。而且我们有数据,不只是感觉:根据 2024 年《大规模 AI 基础设施现状报告》,大多数组织在峰值需求运行时的 GPU 分配利用率低于 70%。实际的 GPU 分配利用率通常更接近 10-20%。

在固定分配下,需求也可能在意料之外的尖峰期间超过供给。试图预测它们只会进一步增加成本——其增加幅度超过收入的增加。

无服务器 GPU 难在哪里?启动延迟。

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

如果做得幼稚,这实际上会加剧问题:

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

如果不加优化,从超大规模云厂商 API 请求到运行中的服务副本可能需要数十分钟。

你需要执行以下操作:

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

在所有这些时间里,负载都超出了容量,QoS 通常会下降(被吸收到更高的并发或队列中,从而推高尾部延迟,或者更糟,503)。这意味着用户会愤怒。如果容量上线时间过长,甚至可能错过瞬时的峰值。但鉴于需求不可预测且分配困难,这些容量通常会长期闲置,利用率不足。

在 Modal,我们优化了 GPU 上推理应用的启动过程,从几十分钟缩短到几秒或几十秒。通过这些优化,各种 GPU 推理应用都可以“真正无服务器化”运行:预置供应与系统需求紧密匹配。

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

在本文档的剩余部分,我们将解释我们采取工程方法以及针对上述四个步骤实施的性能优化,这些步骤跨越了从云存储系统和机器管理到本地磁盘、CPU,当然还有GPU的整个技术栈。

这些优化共同使 Modal 上的推理启动速度提高了 40 倍:从 2k 秒缩短到 50 秒。

Diagram indicating latency to scale up an inference server in a baseline cloud system and on Modal
朴素启动需要长达 2 千秒的推理服务器,在 Modal 上约 50 秒即可启动。实现这一加速的关键架构优化已按其所针对的关键系统组件进行了标注和颜色编码——GPU 和 GPU 内存、CPU 和 CPU 内存、本地固态硬盘(SSD)或机器/实例管理。我们在整篇文章中都使用这种配色方案和示意图。

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

考虑副本启动的第一步:

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

我们可以提前完成这项工作,从而将其从热路径中移除:运行一个由许多应用共享的空闲、健康 GPU 缓冲区,将新的副本调度到这些单元上,并异步地将新设备加入缓冲区。当缓冲区变得过大时,我们也可以随着副本的缩减而释放单元。

在已分配的机器之上维护一小批就绪但未使用的机器,可以让新副本快速调度到空闲机器上(以亮色表示)。

从缓冲区处理请求可消除副本启动时数十分钟的延迟。

Diagram indicating latency reduction of tens of minutes for inference startup with a cloud instance buffer.

关于系统级和应用级缓冲区的补充说明

如果你运行的是单个工作负载,而不是多工作负载系统,你可能会问,为什么我们只把实例分配移出“热路径”并放入缓冲区。难道我们不能把更多的设置工作移入缓冲区吗?你可以!Modal 用户可以维护一个应用层副本缓冲区,随时准备处理请求,使用

buffer_containers

. 但即便如此,吸收给定规模峰值所需的缓冲区大小,会随着你创建新副本的速度而变化,因此下文描述的优化对于单工作负载系统仍然重要。

管理活动实例和这个缓冲区是一个有趣的线性规划问题,正如我们在别处所写。大致来说,它看起来像:

A mathematical optimization formulation for selecting GPU instance launches. Parameters define total requested GPUs, buffer GPUs, possible instance types, costs, and scaling limits. The output is a vector of instances to launch by type. The objective minimizes total cost, subject to providing at least the requested plus buffer GPUs, assuming 8 GPUs per instance, and keeping each instance count within its type-specific scaling limit.

我们使用 Google 的 GLOP 求解器,向它输入从云提供商处抓取的价格以及来自用户的任务。由于云提供商并不总是能在其宣传的价格和区域内提供容量,我们还需要将观测到的供应情况反馈回去。

Diagram of the solver service

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

这对稳健性很重要。一个 100% 利用率的系统没有容错余地,因此故障常常会演变成失效。我们个人建议在生活中多加点缓冲区——在浴室里多放一支牙刷;在家里、办公室和身上各备一个关键设备的充电器。

这个缓冲区对于在单一系统上容纳更广泛的工作负载特别有用。在 Modal,我们倾向于支持各种“开发”工作负载,而不仅仅是生产服务,因为我们可以快速创建新的开发环境。额外的好处是,这些环境默认可复现,并且运行在生产就绪的基础设施上。缩小与生产基础设施的差距也能提高开发速度。

当然,细节决定成败。一个关键点:健康检查对 GPU 至关重要,GPU 的故障率远高于其他硬件,包括像旋转磁盘这样出了名挑剔的组件。我们在这里详细介绍了我们的 GPU 健康检查系统。简而言之,根据我们的经验,你需要在启动时运行一次简短的主动健康检查,并监控之后出现的健康问题,但可以将更密集的检查(如 dcgmi diag)推迟到更慢的节奏(对我们来说是每周一次)。

每 GPU 每小时的关键级别 Xid 错误,按(匿名化的)云分组。故障率远非可忽略不计!

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

现在让我们考虑下一步:

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

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

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

操作系统发行版的根文件系统很厚重——数万个文件,数 GB 大小。天真地使用像 docker run 这样的命令,你需要加载整个东西,通常以云以太网支持的几 GB/s 的速度。更糟糕的是,容器镜像被分成若干层,必须按顺序应用。

解决方案是将容器启动器(Docker 用 runc,gVisor 用 runsc)与容器镜像交付解耦。我们使用一个自定义文件系统,称之为 ImageFS,用 libfuse 构建,它将惰性加载与一个多层、内容寻址的缓存相结合,旨在匹配云提供商的能力。

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

Diagram showing lazy loading of container filesystem contents concurrently with spinup

其余部分可以与其他工作并发加载——或者根本不加载!正如 USENIX FAST '16 的 Slacker 论文图 5 所报告的那样,大多数文件不会被读取,该图转载如下。

我们目前使用 libfuse 实现此文件系统。它是一个用于在use空间中编写 Linux f文件系统的lib库。内核在一个使用标准系统调用操作文件的用户空间程序与另一个实现新文件系统(最终拥有自己的系统调用,其中一个系统调用最终通过内核返回到原始程序)的用户空间程序之间进行中介。这比在内核模块中构建和分发自定义文件系统要简单得多。

Diagram showing lazy loading of container filesystem contents concurrently with spinup

代价是:用户空间和内核空间之间的上下文切换次数翻倍。这对于延迟主导的工作负载(例如从终端字符设备读取)可能很痛苦,但对我们使用它的吞吐量主导的工作负载影响较小。关于性能影响的详细有用分析,请参阅 USENIX FAST '17 的 To FUSE or Not to FUSE。

但天下没有免费的午餐:容器确实访问的所有数据仍然需要加载。如果你天真地从对象存储中获取典型容器访问的数千个文件中的每一个,那么从“容器启动”到torch.cuda.is_available将需要数小时。因此另一个关键组件是一个分层的、内容寻址的缓存,我们急切地(但异步地)填充它。

我们使用内容寻址缓存,因为跨容器的镜像内容重叠巨大。许多推理应用程序使用相同的软件(例如 Python、PyTorch、CUDA 栈)。

但基于路径的缓存和 Docker 的分层缓存会损失性能。例如,共享字节不保证位于完全相同的容器镜像层中。

Diagram depicting multiple container filesystems with overlapping content stored in a content-addressed cache

该缓存是分层的,就像 CPU 和 GPU 内部的缓存一样,以映射到云提供商可用的存储层次结构。下面的图表和表格列出了关键组件及其吞吐量、延迟和成本。

系统读取延迟(微秒)读取吞吐量(GiB/s)
页面缓存0.001 - 0.110-40
SSD1004
可用区缓存服务器100010
区域 CDN100,0003-10
Blob 存储200,0003-10

关键断点是:

  • 内存:Linux 页面缓存。这是主要的内存目标。它是你实现微秒级延迟的唯一选择,并且具有高吞吐量,但容量有限(RAM 昂贵,而且越来越贵)。
  • 磁盘:本地固态存储。SSD 从内存降级比旋转磁盘要温和得多,但仍然明显。我们使用大容量驱动器,并迅速用最常用的内容填充它们。
  • 网络存储:Blob/对象存储。这基本上具有无限容量——在超大规模厂商耗尽存储资金之前,你会先耗尽推送字节的资金。但它的延迟要高得多。这种延迟惩罚很严厉,但请注意,在许多云配置中,峰值带宽可能高于磁盘!

要真正让这变得飞快,你可能会在 SSD 和对象存储之间构建更多层,比如 RDMA 层或可用区内点对点共享。两者在数据上都很有吸引力,但会增加大量工程复杂性,所以我们还没有添加它们——暂时。

总的来说,我们把容器启动时间缩短了一分钟。对于启动只需几秒的简单应用来说,这绝对是游戏规则改变者。对于像 LLM 推理服务器这样的重型应用,它从几分钟的启动时间中减少了大约一分钟。

Diagram indicating latency reduction of 33% for inference startup with the custom container filesystem.

带来整数倍加速的重大架构举措之后,是百分点的苦磨。我们在这篇博文中详细介绍了这种苦磨。这里是一些亮点。

首先,libfuse 暴露了一些性能调节旋钮。我们发现最大的收益来自调整 read_ahead_kb,它指示内核在每个请求之前预读那么多千字节(如下图所示)。我们将默认值 128 提高到 32 * 1024。更大的值有利于容器镜像加载的大量读取特性。更高的值(以 GB 为单位)会导致严重的抖动。

Diagram showing requested blocks and read blocks with different levels of readahead.

其次,我们跳过容器镜像层的 gzip 解/压缩。DEFLATE 本质上是单线程的(LZ77、Huffman),这限制了你只能达到约 100 MB/s,远低于任何缓存层的吞吐量。如果你能完全控制容器镜像的创建,你可能会选择使用 zstd,并在镜像压缩时付出前期成本,以节省传输期间的带宽,并避免解压缩期间网络瓶颈。但我们也尽量保持镜像创建快速,特别是为了更好地支持动态代理工作负载。

你可以通过 CPU 内存快照快进数十秒的应用主机端启动时间。

现在,让我们考虑我们的第三步:

  • 在主机上启动应用程序,使其准备好服务请求(数十秒)

这涵盖了从应用程序的容器进程启动到第一个“有用”工作开始——处理第一个请求——之间需要完成的所有工作。

例如,考虑执行 Python 语句 import torch。这会启动数千行 Python 代码,其中包括执行数万次系统调用以加载各种文件并与驱动程序交互。对典型推理应用中使用的所有库重复此过程,你就会在“进程启动”和“请求在途”之间有许多秒的工作要做。

这里的关键见解是,任何正在运行的进程都是一个堆、一些线程和一个文件描述符表。像这样:

Diagram showing the internals of a Linux process as a data structure - memory mappings, thread state, file descriptor table.

如果你能重建那个状态(“创建检查点”),你就能重建正在运行的进程(“从检查点恢复”)。正确打包该状态,你就可以从存储中重建进程,比通过执行新副本重建它更快。

Diagram demonstrating the 'skipped work' when restoring a process from a checkpoint.

这就是透明检查点/恢复接口背后的核心理念——之所以说透明,是因为用户程序无需感知自己正在被检查点和恢复。Linux 中透明检查点/恢复的实现被称为 Checkpoint/Restore In Userspace (CRIU)。透明 C/R 的用途之一是,将运行中的程序迁移到不同的机器上。由于我们的首要目标是减少冷启动时间,透明检查点/恢复并非我们系统的必需项。

因此,我们通过容器生命周期管理接口向用户暴露 C/R 接口。它大致是这样的:

我们目前不使用 Linux C/R。我们使用 gVisor 的 runsc 来运行用户容器,它在用户空间中有效地模拟了(Linux 内核的一个子集)。这种受限的攻击面提供了对诸如最近发现的 CVE-2026-31431,即“CopyFail” 之类漏洞利用的自动防护。我们尤其感兴趣(并且参与贡献!)的是 nvproxy 子组件,它与 GPU 的内核态驱动通信。

由于应用程序只与这个模拟内核交互,因此它可以在无需宿主内核配合的情况下对应用进行检查点和恢复。 对于 runsc 来说,检查点/恢复实际上尤其简单。runsc 运行时中的容器直接就是一个状态机。也就是说,该运行时(用 Go 编写)的架构是一组具有协作式抢占的任务,就像大多数其他采用 async/await 风格并发的系统一样。系统已经在每个 await 点被中断然后继续,所以“仅仅”是把该状态序列化为检查点而已。

更准确地说,runsc checkpoint 命令会停止容器并在磁盘上生成状态,可用于通过 runsc restore 重启容器(文档在此)。默认情况下,它是一个 zip 归档,但我们生成时不压缩(还记得 gzip 瓶颈吗!)。关键文件是 pages.img,其中包含原始页数据。它至少有 100 MB,但也可能达到数 GB(不过通常不会大于系统内存)。

Diagram of the gVisor checkpoint/restore process, including nvproxy.

还有许多其他环节,但检查点恢复性能的成败取决于它能多快被载入宿主页缓存。我们使用上文描述的同一套自定义文件系统机制来传递检查点文件。

结果是加载新副本宿主侧组件的时间大约减少了 10 倍。你可以在这篇博客文章中进一步了解我们的内存快照系统。

这里有一些限制。检查点对宿主环境的细节非常敏感。例如,AWS g6.12xlarge 实例类型不支持 pclmulqdq Perform a Carry-Less Multiplication of Quadword 指令,因此它无法接受任何在支持该指令的宿主上创建的快照——该指令可能被硬编码到某个代码区域页中,执行它会导致非法指令错误(或更糟)。因此,在像 Modal 这样从多个提供商聚合容量以确保低成本和可用性的异构云平台上,单个推理服务器部署需要不止一个快照。

其次,该系统只考虑了程序的主机端状态。但进程状态中的文件描述符可能包含通过驱动程序对 GPU 的句柄,而程序状态理应包含设备上的任何状态。启动推理服务器时,大部分时间都花在这里,因此纯主机端检查点/恢复带来的收益有限。但它们为设备快照铺平了道路,接下来我们就转向这一点。

借助 GPU 内存快照,你可以快进跳过数分钟的应用设备启动过程。

现在,让我们考虑创建新推理服务器副本的最后一步:

  • 在设备上启动应用程序,使其准备好处理请求(数分钟到数十分钟)

对于当代推理工作负载,有两项不同的工作都可能耗时数分钟。首先,需要将神经网络权重从存储加载到 GPU 内存中。其次,神经网络周围的代码(即“推理引擎”)需要做一些设置工作。

如今的前沿 LLM 权重从数十亿字节到数万亿字节不等(即 GB 到 TB)。我们使用与自定义文件系统相同的基本存储能力来加载模型权重,因此模型权重的加载速度约为每秒几 GB。这意味着总延迟在几秒到几百秒之间。检查点/恢复在这里帮不上忙,因为瓶颈在于大读取的吞吐量,而不是可以通过快照轻松跳过的工作。

关于权重加载的补充说明

像我们这样跨云或跨云区域加载时,很难提升这一瓶颈。在可用区内运行权重服务器可能将速度提升 3 倍以上,通过 RoCE/InfiniBand 运行 RDMA 权重服务器可能提升 10 倍以上。这可行,但成本高昂且复杂,尤其是在扩展到众多模型和动态工作池时。我们正在努力解决!

但权重加载并不是唯一依赖设备的慢步骤。推理引擎设置涉及多个计算密集、依赖设备的步骤,这些步骤会产生难以缓存的小型内存产物。例如,vLLM 推理服务器会捕获 CUDA graphs 并运行 Torch 编译器。每个步骤耗时在数十秒到数分钟之间。CUDA graphs 由指向张量和内核的指针组成,没有原生的序列化选项。Torch 编译器可以生成可序列化的产物。但根据我们的经验,验证这些产物的缓存命中通常很慢(数秒到数十秒),限制了缓存的好处。

这些生成成本高昂的小型内存运行时产物,使推理设置成为检查点/恢复的绝佳候选。然而,基于 runsc 或 CRIU 的检查点仅作用于主机内存,而非设备内存。尽管大多数推理引擎产物位于主机端,但设置过程会创建必须被检查点和恢复的设备资源。

Nvidia 近期的驱动程序版本为这个问题提供了一个优雅的解决方案。简而言之,驱动程序将设备内存检查点保存到主机内存中,以便主机端检查点系统可以将其检查点保存到磁盘。然后,一旦主机端系统恢复了主机内存(包括设备检查点),驱动程序就会恢复设备内存。

设备检查点/恢复建立在主机检查点/恢复之上,而主机检查点/恢复又建立在底层文件系统之上。基础设施层层叠加。

结果非常显著:典型的加速比在 4-10 倍之间,将容器启动时间从几分钟缩短到几十秒。

Diagram indicating a reduction in start latency from 300s to 50s for inference applications with snapshots.

对此有几点需要注意,我们在此处做了说明。首先,多 GPU 程序的快照处理比较棘手,因为 nccl 程序并非为暂停而设计,当某个对等节点静默时经常会死锁。其次,尽管我们的经验是几乎任何应用都可以被快照,但大多数应用需要先做一些小的调整。例如,对 vLLM 或 SGLang 进行快照时,配合权重卸载效果最佳——即在检查点保存前将权重移回主机内存。此外,这些引擎通常会急切地创建一个(空的)KV 缓存,而重新创建它比从检查点恢复要快得多。

有了这些调整,LLM 推理服务器副本借助快照几乎可以快一个数量级地启动。下面,我们报告了 vLLM 或 SGLang 全新副本服务一个约 1 GiB 语言模型(Qwen 3 0.6B,见 bf16)的延迟累积分布函数。这包括在 Modal 上创建新副本的全部延迟——任何机器排队、容器启动、主机端和设备端的准备工作。在超过一万次冷启动中,我们观察到快照部署在每个分位数上都表现出更优的延迟。

平均值也有所改善。

快照关闭快照开启
vLLM 启动延迟(均值)95,679 ms13,797 ms
SGLang 启动延迟(均值)83,713 ms17,486 ms

你可以在这篇博客文章中阅读更多关于 GPU 快照的内容,包括额外的基准测试结果。

我们已在众多用例中以数千万个副本的规模运行了这套技术栈。

过去三个月(2026 年 2 月至 4 月)的使用数据如下所示。

恢复的副本数执行小时数创建的不同快照数
CPU 快照~35,000,000>5,000,000~1,000,000
CPU+GPU 快照~15,000,000>2,000,000~700,000

CPU 和 GPU 快照被数百个不同的组织用于各种用例。

CPU 快照最常用于数据管道或作业队列系统,但也经常被用于各种用例以加速初始化,尤其是 Python 导入。

GPU 快照也被用于各种领域。由于目前仅限单 GPU,它们最常用于大小在几 GB 到几十 GB 之间的模型。这包括大型语言/视觉语言模型中较小的那一端,用于结构化数据提取或认知复杂度较低的任务。我们发现 GPU 快照在音频/语音用例中也很受欢迎,既用于语音转文本/自动语音识别,也用于文本转语音/语音生成。

聚焦用例:Reducto 将文档处理无缝扩展到数千个 GPU。

Reducto 是一个文档处理平台,使用视觉语言基础模型从非结构化文档中提取结构化数据。你可能读到过他们对 JMail 项目的贡献,在该项目中他们索引了国际罪犯 Jeffrey Epstein 的通信记录。

Reducto 文档处理系统的主要约束之一是高峰均比。客户可能随时出现,请求处理比如整个企业的 Notion 文档集合。这些作业的截止期限在几十分钟的量级,只有通过横向扩展到数百或数千个 GPU 才能满足。

快速的容器启动让 Reducto 无需维持闲置容量即可满足这些截止时间——从而“真正无服务器地”运行千卡 GPU 推理工作负载。

尤其是,GPU 内存快照的加入将冷启动时间缩短了约六倍,从约 70 秒降至约 12 秒。

你可以在我们的博客上阅读更多关于 Reducto 使用无服务器 GPU 进行推理的内容。

Coda

现有的容器技术栈及基于它构建的云服务是为上一代工作负载设计的,例如托管网站和与数据库交互。它们并非为训练或推理而设计,这种阻抗不匹配对构建推理应用的团队而言是成本、效率和性能上的额外负担。

我们构建 Modal 是为了让云基础设施(字面意义上)跟上人工智能的需求。我们分享我们的做法有几个原因。

首先,我们希望你和我们的客户一样,对在这套基础设施上构建应用感到兴奋,比如 Physical Intelligence、Runway、Ramp、Zencastr、Lovable、Substack 和 Suno。你可以立即开始使用它,包括每月 30 美元的免费使用额度。

其次,我们是在许多优秀的开源或文档完善的系统之上、并参考它们构建了这套系统,从 Linux CRIU 到 AWS Lambda。我们想将这份收获传递下去。如果你从我们的工作中获得灵感,我们很想听听。

最后,我们还有很多工作要做——那些 RDMA 网络可不会自己配置!我们希望分享这些工作的样貌,能吸引更多最优秀的工程师有兴趣与我们一起做这件事。“造船不在于织帆、打钉或观天。而在于赋予对海洋的共同品味。”造船者和向往大海的人,欢迎垂询,并分享你为了节省一毫秒而工作数小时、重复一万亿次的最喜欢的故事。

作者感谢 Vikram Mailthody、Steven Gurfinkel、Stephen Jones、Radostin Stoyanov、Rodrigo Bruno 和 Jordan Sassoon 提供的意见。

来源:Modal Blog · modal.com