推理与性能模型架构

当你的 GPU 装不下模型时:「卸载」流派如何让单卡训练百亿参数模型

一个被低估的数字

大模型的参数太多,单张 GPU 的显存放不下。一个直观的应对思路是:把模型参数放在容量大得多的 CPU 内存里,GPU 需要哪一层就临时搬哪一层过来算,算完再搬回去。这种方法叫「卸载」(offloading)。

听起来像是在走弯路——数据多搬一次不就慢了吗?确实会慢,但关键问题是慢多少。如果只慢一点点,那这条路就值得走。先看数据。

模型规模 卸载到 CPU(MegaTrain) 全在 GPU 显存(PyTorch 原生)
7B 284 TFLOPS 285 TFLOPS
14B 264 TFLOPS OOM(显存溢出)
32B >250 TFLOPS OOM

这张表来自 MegaTrain(2026 年 4 月论文)在单张 GH200 上的实测。读法很简单:7B 模型能完全塞进 GPU 显存时,卸载和不卸载的速度几乎一样。到了 14B,不卸载的直接报内存溢出,卸载方案不仅跑起来了,吞吐量只降了 7%。到了 32B,不卸载的全部崩溃,卸载仍然以 250+ TFLOPS 稳定运行。

精度呢?卸载会不会导致模型变笨?不会。7B 规模上,MegaTrain 准确率 88.99%,PyTorch 原生 88.91%。14B 上 MegaTrain 92.52%,PyTorch 原生跑不了(OOM),但其他同规模系统的 92.41% 可以作为参考。差异在统计噪声范围内。

如果你对「offloading」的印象停留在「原理上可行但实际慢得要命」,这个印象在 2024 年之前基本是对的。V100 时代,ZeRO-Offload 只有约 30 TFLOPS,确实很慢。但硬件换了之后,整个计算变了。

关键变量是 CPU 和 GPU 之间的那条数据通道。普通服务器用 PCIe,带宽约 128 GB/s。GH200 用的是 NVLink-C2C,900 GB/s,差了 7 倍。这不是渐进式改进,是维度级别的差异。同一套卸载思路,换一条宽 7 倍的管道,就从「能用但很慢」变成了「几乎感觉不到开销」。

当然也有不那么好消息。在普通 PCIe 连接的 H200 上,卸载仍然能用,MegaTrain 能训练 72B 甚至 120B 的模型,但绝对速度低于 GH200。好硬件上的好数字不能直接平移到所有硬件上。

接下来的问题是:这个进化是怎么发生的?背后到底在做什么?限制在哪里?

问题本质:瓶颈是内存,不是算力

理解卸载之前,先理解它要解决什么问题。

训练大模型需要在内存里同时放下三类数据:模型本身的参数(几百 GB)、告诉参数该怎么调整的梯度(几百 GB)、以及记录调整历史的优化器状态(又是几百 GB)。一个 700 亿参数的模型,三类数据加起来大约需要 840 GB。目前最强的 H200 GPU,显存只有 141 GB。放不下。

GPU 算力增长很快,显存增长很慢。模型参数增长更快,从十亿到百亿到万亿。瓶颈已经从「算得有多快」变成了「能同时记住多少东西」。

最直觉的解决方案是多买 GPU,把模型拆分到多张卡上。头部实验室做预训练确实这么干。但这很贵,而且很多时候多余。微调、指令对齐这类后训练任务,计算量不大,但仍然需要加载完整模型。你不需要跑万亿 token,可能只需要几百万。算力需求温和,内存需求不温和。

卸载的思路很直接:既然 GPU 显存放不下所有数据,而服务器主板上还有几百 GB 甚至 1.5 TB 的 CPU 内存,能不能让 GPU 在需要什么数据的时候临时从 CPU 内存搬过来,用完再搬回去?

你的电脑其实一直在这么做

这个想法并不新鲜。你的操作系统每时每刻都在做类似的事。

你的电脑有 SRAM(CPU 芯片上,极快,几 MB)、L3 缓存(快,几十 MB)、内存(中等速度,几十 GB)、硬盘(慢,几 TB)。操作系统用虚拟内存机制,把不活跃的数据从内存换到硬盘,需要时再换回来。CPU 用缓存行,把即将使用的数据从 L3 提到 L2 再到 L1。每一层都比上一层慢,但容量大一个数量级。整个计算机架构的基石就是在速度和容量之间做这种权衡。

训练神经网络天然适合这种模式。模型是一层层堆叠的,第 1 层算完才能算第 2 层,第 2 层算完才能算第 3 层。任意时刻,只有当前正在计算的那一层数据是活跃的,其他几十层的数据只是在排队等。反向传播也是一样,只是顺序反过来。

那为什么要把所有层的数据都放在最贵的 GPU 显存里?能不能像操作系统管理虚拟内存一样,只把当前层放在 GPU 上,其余放在 CPU 内存里,按需搬进搬出?

问题在于搬数据的速度。GPU 显存内部带宽是 4 TB/s 级别,CPU 到 GPU 的通道在最好的情况下是 900 GB/s,普通情况下是 128 GB/s。如果搬数据的时间超过计算的时间,GPU 就会大量空转,等数据到位。整个方案就失去了意义。

所以卸载的核心工程挑战只有一个:怎么让搬数据的时间被计算时间吃掉,让 GPU 感知不到数据不在本地。

五年进化史

2020 年至今,这个方向经历了四代演进。每一代都在回答同一个问题的不同侧面。

第一代:只卸载最占内存的部分(ZeRO-Offload, 2020)

微软 DeepSpeed 团队的第一个观察很聪明。训练时需要在内存里放三类数据,但它们的「重量」不一样。模型参数占约六分之一,梯度占六分之一,优化器状态占三分之二。优化器状态之所以最大,是因为它需要为每个参数记录历史调整轨迹,而且必须用高精度存储以保证数值稳定。

既然优化器状态占了大头,那就只搬它。ZeRO-Offload 把优化器状态和梯度放在 CPU 内存上,模型参数留在 GPU 显存里(反正计算时本来就需要它们在 GPU 上)。GPU 算完梯度后,把梯度传到 CPU,CPU 用优化器算出参数该怎么更新,然后把更新后的参数传回 GPU。

直觉在于:优化器的计算很轻(每个参数做几次简单运算),但它需要读写的内存量很大。它是典型的「内存带宽受限」任务,不是「计算受限」任务。这种任务放在 CPU 上跑完全合适——CPU 的内存带宽足够,计算也够用,而且避免了把大量数据在 CPU 和 GPU 之间来回搬的代价。

这个方案把内存需求砍掉了大约三分之二。在单张 V100 上能训练约 100 亿参数的模型,吞吐量约 30 TFLOPS,接近 4 卡无卸载的水平。

局限也明显:模型参数本身仍然必须装进 GPU 显存。对于更大的模型,仅参数本身就会超限。

第二代:连参数也卸载,加一层 SSD(ZeRO-Infinity, 2021)

既然参数也要卸载,CPU 内存够不够?对于非常大的模型,CPU 内存也不够。ZeRO-Infinity 引入了三级存储:GPU 显存(最快,最小)→ CPU 内存(中等)→ NVMe SSD(最慢,最大)。

三级存储带来的核心问题是:怎么提前知道接下来需要什么数据,在 GPU 用到之前就开始搬?ZeRO-Infinity 的做法是在第一次训练时记录完整的参数访问顺序,之后每次训练都按这个记录提前预取。类似于你每天上班走同一条路,走几天之后就知道了哪里会堵车,提前变道。

对于 SSD 这一层,速度更慢(约 3.5 GB/s),但 ZeRO-Infinity 用流水线来弥补:在从 SSD 读下一块数据的同时,CPU 在计算当前块,同时把上一块写回 SSD。三条操作并行,让 SSD 的慢速度被计算时间遮盖。

这套方案在 32 张 V100 上能训练千亿参数模型,不卸载的话需要 64 张以上。但它的局限性也很突出:预取依赖固定的访问顺序,遇到动态变化的计算模式就会失效。而且那个年代 PCIe 带宽只有约 32 GB/s,根本瓶颈并没有被解决。

第三代:翻转关系,CPU 内存成为主角(MegaTrain, 2026)

前两代的思路是「GPU 为主,CPU 内存为辅」。MegaTrain 彻底翻转了这个关系:CPU 内存是所有数据的永久住所,GPU 只是一个带缓存的计算引擎。参数平时住在 CPU 内存里,需要计算哪一层就临时搬哪一层过来,算完立刻释放。

这听起来和前两代差不多,但有一个根本区别。前两代的系统仍然依赖 PyTorch 的标准训练框架,而 PyTorch 假设所有数据在整个训练过程中都住在 GPU 上。MegaTrain 干脆绕过了这个假设,自己管理数据的搬进搬出,GPU 上只保留当前层的计算逻辑和少量缓存。

实现上依赖两个技巧。第一个是双缓冲流水线:准备两块缓冲区,GPU 在用 A 缓冲区里的数据计算第 i 层时,CPU 同时在往 B 缓冲区里装第 i+1 层的数据。算完一层,交换缓冲区,继续。GPU 永远不用等数据。第二个是无状态计算模板:GPU 上不保存任何模型的持久数据,只有空的计算框架。数据流进来就绑定上去算,算完解绑,缓冲区腾出来给下一层。这样 GPU 的显存占用永远不超过一层参数的大小。

结果就是在 GH200 上,7B 模型的卸载速度和不卸载几乎一样(284 vs 285 TFLOPS),32B 模型在所有竞品都崩溃的情况下仍然稳定运行在 250+ TFLOPS。在配备 1.5 TB CPU 内存的 H200 上,单卡能训练最大 120B 参数的模型。

还有几条并行路线

2025-2026 年还有几个系统从不同角度切入同一问题。TERAIO(NeurIPS 2025)观察到任意时刻只有 1-2% 的数据是活跃的,它直接在 GPU 和 SSD 之间建立数据通道(GPUDirect Storage),绕过 CPU 这个中转站,比 ZeRO 系列快了约 1.5 倍。MemAscend 关注的是 SSD 卸载时 CPU 内存中的暂存区本身会成为瓶颈(尤其是有很多小型专家模块的 MoE 模型),它把暂存区内存占用降低了 72%。Ratel 则把所有优化维度(数据放哪里、什么时候重算、什么时候卸载)交给一个统一调度器做全局决策,能微调最大 135B 参数的模型。

DeepSpeed 团队自己也在 ASPLOS 2026 上发表了 SuperOffload,专门针对 GH200 优化。论文报告单卡约 310 TFLOPS(FP16 精度),官方博客在特定配置下报了更高的数字,但口径和论文不完全一致。不管用哪个数字,它比老版本 ZeRO-Offload 的改进是实实在在的。

另一条路:从硬件上消灭问题

上面所有系统都在解决同一个问题:CPU 内存和 GPU 显存是分开的,中间有一条窄管道。那如果它们不是分开的呢?

Apple Silicon 用的就是统一内存。CPU 和 GPU 共享同一块物理 RAM,没有数据搬运的问题。最新的 M5 Max 有 128 GB 统一内存,带宽 614 GB/s;M4 Ultra 有 192 GB,带宽 819 GB/s。Apple 的 MLX 框架直接在这个架构上做训练和推理,不需要任何卸载机制。

NVIDIA 在数据中心端走的是类似路线。GH200 通过 NVLink-C2C 把 ARM CPU 和 GPU 封装在一起,CPU 的 480 GB LPDDR5X 和 GPU 的 96 GB HBM 构成统一地址空间,互连带宽 900 GB/s。下一代 GB200 会进一步扩展。这正是前面那些好数字之所以成为可能的硬件基础。

Apple Silicon 的限制在于算力。统一内存解决了容量和带宽问题,但 GPU 核心的原始计算能力和 NVIDIA 数据中心 GPU 差距明显。Apple 自己的研究论文也承认这一点。对于推理和中小模型微调,Apple Silicon 很有竞争力。大规模训练仍然是 NVIDIA 的主场。

带宽墙:为什么不是所有情况都这么乐观

前面给了很多好数字,现在泼一点冷水。

卸载可行性的核心条件是:GPU 计算一层的时间必须大于从 CPU 搬下一层数据的时间。只有这样,搬数据的操作才能被计算遮盖。

14B 参数的模型,BF16 下参数约 28 GB。在普通 PCIe Gen4 上(有效带宽约 26 GB/s),光搬参数就要约 1 秒。GPU 算一层的速度快得多,大约 10-20 毫秒。搬数据的时间是计算时间的 50-100 倍。GPU 绝大部分时间在空等。

换成 GH200 的 NVLink-C2C(900 GB/s),同样 28 GB 只要约 31 毫秒。和 10-20 毫秒的单层计算时间处于同一量级,通过双缓冲就可以几乎完全遮盖。这就是为什么 GH200 上的数字这么好看。

模型越大,情况越有利。因为计算量随模型宽度的平方增长,传输量也随宽度平方增长,但 GPU 算力的基数远大于链路带宽的基数。大模型的单层计算时间更长,更容易把传输时间吃掉。小模型反而是带宽受限的——算得太快,数据搬不过来。

这也解释了为什么卸载系统的退化曲线是平缓的而非断崖式的。模型越大,计算时间越长,传输时间越容易被遮盖,卸载的开销占比越低。代价是:每一步训练确实更慢了,但慢得不多,而且模型越大慢得越少。

什么时候该用卸载?

最明确的场景:资源受限的硬件上做后训练。手头只有一两张 GPU,想微调一个 30-70B 的模型,卸载就是可能和不可能之间的区别。微调需要的训练步数远少于预训练,总耗时通常可以接受。

最不适合的场景:大规模预训练。预训练要处理万亿 token,吞吐量损失在数百万步中不断累积。多租几张 GPU 把模型完整放进显存,几乎总是比在更少 GPU 上做卸载更划算。头部实验室全都用多 GPU 集群加三维并行(张量并行、流水线并行、数据并行),不用 CPU 卸载。GPU 之间通过 NVLink 通信的延迟远低于 GPU 到 CPU 的 PCIe 延迟。

还有一个折中方案值得了解。很多从业者的做法是只卸载优化器状态(占总内存三分之二),参数保留在 GPU 上。当参数本身装得进显存、但加上优化器状态就超了的时候,这个方案很实用。优化器计算本来就是内存带宽受限的,放在 CPU 上跑没有额外代价。

经济账也值得算一下。一张 GPU 加卸载,如果吞吐量是两张 GPU 无卸载的 60%,你省了 50% GPU 成本,多花了 67% 时间,净节省约 25%。GPU 越贵(H200 按需约 $3.35/小时)越划算,GPU 便宜或者赶时间就不那么划算了。

走向何方

卸载流派的演进有一个清晰的方向。早期系统把 CPU 内存当作溢出缓冲区,GPU 显存才是主角。新一代系统把 CPU 内存当作主角,GPU 显存只是计算缓存。这个反转意味着:对于大模型,数据实际上住在 CPU 内存里,GPU 的角色是对其能容纳的那一小部分执行计算。

硬件趋势在支撑这个方向。NVIDIA 的 Grace Hopper/Blackwell、Apple Silicon 都在推动 CPU 和 GPU 的内存统一。CXL 标准也在向跨设备共享内存池的方向发展。

与此同时,量化和压缩方法通过另一条路径解决同一个问题:不搬数据,而是把数据压缩到能放进 GPU 显存。最好的现代系统结合了两条路径,先用量化缩小体积,再用卸载处理剩余部分。

诚实的结论是:卸载在合适的新硬件上已经是一项成熟、实用的技术。它不会替代多卡训练,也不会让你在预训练上和头部实验室竞争。但对于在有限硬件上做后训练的大多数从业者来说,它能把可行模型规模扩大一个数量级,代价是吞吐量的适度下降。系统已经足够好,瓶颈在硬件而非软件。随着 CPU-GPU 更紧密的集成成为常态,「GPU 训练」和「CPU 卸载训练」之间的界限可能最终消失。

鸭哥每日手记

日更的深度AI新闻和分析