AI 基建
0%
第九部分 · 基础设施与算力 · 第 65 章

编排与数据基础设施

作者Changkun Ou
阅读时长约 22 分钟

一个分布式训练程序,只有在运维系统能启动它、识别它的状态、恢复它,并证明它消费过什么时,才算得上一次真正的运行。控制平面保存期望运行状态,并让它与观测到的运行状态保持一致。数据平面按照明确的顺序与混合契约供给身份确定的训练样本。检查点把二者连在一起:它在同一个逻辑边界提交模型状态与数据进度,避免恢复时拼接出两段互不相容的历史。实际需要回答的问题包括多久保存一次、如何定义数据顺序与覆盖范围、哪些状态能跨过重启,以及操作员如何区分一次缓慢的训练步骤和一次已经受损的运行。

这些机制源自不同的技术脉络。早在加速器训练出现以前,Young 就于 1974 年推导出了检查点间隔的一阶近似 (Young 1974)。后来,Borg、Omega 与 Kubernetes 等集群管理器把期望状态调谐确立为控制平面的标准模式 (Burns et al. 2016)。再后来,tf.data 等机器学习输入运行时开始把加载、变换、并行、缓冲与迭代器恢复视为同一个数据流问题 (Murray et al. 2021)。现代训练基础设施把这些思想组合起来,但每次运行仍须各自声明语义与故障预算。

本章说明检查点、数据平面与可观测性如何组成一套编排协议,并为它规定明确身份、状态转换、提交规则与恢复目标。受这套系统控制的并行算法来自 第 10 章;加速器与互连见 第 62 章;编译器与内核产物见 第 64 章;数据源选择与混合设计则始于 第 6 章

运行是由控制器持续调谐的状态机

编排的持久输入应当是不可变运行规格,而不是某个调度器进程记住的一条 shell 命令。它至少需要绑定以下内容:

契约范围 必须确定的身份或策略
程序 源码修订版本、容器摘要、入口点、依赖与编译器版本
训练 模型配置、优化器与调度计划、精度策略、随机种子、全局批次与停止规则
数据 数据集清单、分词器版本、混合策略、变换、打包策略与访问策略
资源 加速器类型与数量、固定全局规模或弹性范围、角色、拓扑与放置约束
恢复 检查点模式、保存频率、保留策略、重试类别、恢复点目标与恢复时间目标
输出 产物命名空间、评估策略、发布门禁、负责人、预算与取消权限

控制平面在这份规格旁维护一份持久运行记录。记录包含当前运行代次、状态、准入决定、工作进程成员关系、最近一次进度心跳、最新提交的检查点、数据游标、故障历史与最终结果。控制器反复比较期望运行与观测到的运行,并尝试调谐二者的差异。只有当控制器产生的副作用是幂等,或由唯一操作标识符保护时,重试才是安全的。

图 65.1 展示了这台状态机。“运行中”并不只是没有报错,而是指当前代次的成员关系、健康状态与进度不变量都成立。

spec 不可变运行规格 期望状态 record 持久运行记录 观测状态 + 代次 spec->record 创建 pending 等待中 record->pending 调谐 starting 启动中 准入 + 预检 + 会合 pending->starting 获得容量 cancelled 已取消 pending->cancelled running 运行中 starting->running 健康 failed 失败 starting->failed 重试耗尽 starting->cancelled checkpointing 保存检查点 running->checkpointing 保存 recovering 恢复中 隔离 + 替换 + 恢复 running->recovering 可重试故障 succeeded 成功 running->succeeded 满足停止规则 running->cancelled checkpointing->running 提交 recovering->starting 新代次
图 65.1. 控制平面持久保存期望状态与观测状态,再通过准入、执行、恢复与终止状态,持续调谐一个受隔离令牌保护的运行代次。

只有租约,没有隔离令牌还不够

一个工作进程可能暂停、失去租约,等替代进程已经启动后又恢复运行。停止心跳并不会终止进程。因此,凡是能修改共享状态的副作用,都必须携带一个单调递增的隔离令牌,通常就是运行代次。只有当令牌等于持久运行记录中的代次时,系统才接受检查点发布、进度更新与最终产物写入。过期工作进程仍可计算,但写入会被拒绝。

取消操作也遵循同一规则。控制器先记录已取消的终止状态,并推进或撤销当前代次,然后才要求工作进程停止。由于输出按代次划分,而且垃圾回收不会删除已经提交的产物,所以清理操作可以安全重试。

调度与工作进程成员关系是两份独立契约

同步训练通常适合使用成组调度:调度器一次性准入整个工作进程组所需的资源,避免部分资源获批后闲置等待其余资源。成组调度是一项准入策略,不是集合通信的属性。工作进程启动后,集合通信之所以会阻塞,是因为进程组中的每个成员都必须发出相互兼容的操作。拓扑感知放置还会增加一项约束:集群可能总体上有足够的空闲设备,却没有一种有效放置方式满足所需的本地域或纵向扩展域 (Gu et al. 2019; Kubernetes SIG Scheduling 2026)。

运行规格必须选择一种成员关系契约:

  • 固定全局规模把任何成员丢失都视为整个组的故障。控制器中止通信、替换资源或重新排队、重建相同规模的进程组,再恢复检查点。
  • 弹性范围允许成员发生变化,但前提是模型切分、优化器状态、全局批次语义、数据分配与调度计划都支持新的规模。
  • 针对特定角色或局部范围的修复属于另一项系统能力。系统必须明确哪些通信器和状态可以重建,而不必重启其余部分。

以 TorchElastic 为例,某个工作进程失效或成员关系改变后,它会停止所有尚存的工作进程并重新组建进程组,而不是把一个新 rank 热替换进仍在运行的集合通信。系统必须重启整个工作进程组,重新会合并恢复已提交的状态。rank 在重新会合前后并不是稳定身份;弹性改变全局规模时,rank 编号和 world size 都可能重新分配 (PyTorch Contributors 2026)。因此,稳定的样本所有权、检查点键与输出身份必须使用逻辑标识符,而不能只用 rank 编号。

检查点是一笔分布式提交

参数文件适合推理,却未必是训练检查点。一个可恢复的检查点必须捕获所有会改变后续更新的状态变量:

状态类别 示例
数值状态 模型参数,以及使用时的主权重或指数移动平均权重、优化器状态与计数器
调度状态 全局步骤、已消费词元数、学习率与权重衰减调度位置
精度状态 梯度缩放器、FP8 缩放历史、跳过更新的计数器
随机状态 Python、宿主框架与每个设备的随机数生成器状态
数据状态 数据集 ID、已提交的数据游标、打乱与混合状态、打包器残余、各数据源计数器
分布状态 逻辑张量名、形状、dtype、切分元数据、并行方式与支持的重新切分模式
来源信息 运行代次、代码与配置摘要、分词器与数据清单、检查点格式版本

最干净的快照边界位于全局优化器步骤完成提交之后、下一步消费数据之前。在这个步骤边界,系统里没有尚未完成的梯度累积。如果系统在步骤中途保存,还必须持久化累积梯度、微批次游标、流水线状态,以及任何尚未完成的集合通信语义。

切分改变的是字节所在的位置,不是一致性规则。每个 rank 或存储工作进程可以只写一部分状态,但所有部分必须描述同一个检查点代次与同一个逻辑步骤。例如,PyTorch Distributed Checkpoint 会协调分布式状态,并能把受支持的切分张量加载到另一种布局;自定义状态仍需自行提供兼容的保存与恢复契约 (PyTorch Contributors 2026)。

最后发布清单

图 65.2 给出了一套不依赖具体存储系统的提交协议。这里的“原子”描述的是检查点可见性:读者只会看到上一个完整代次或新的完整代次,绝不会看到二者的混合。

boundary 优化器步骤边界 代次 g,步骤 k stage 暂存不可变本地状态 boundary->stage write 写入每个临时分片 字节 + 校验和 stage->write verify 验证所有预期分片 键 + 大小 + 校验和 write->verify partial 不完整检查点 忽略,稍后回收 write->partial 失败 commit 最后发布清单 + 提交记录 以隔离令牌为条件 verify->commit verify->partial 缺失 / 无效 restore 可用于恢复 commit->restore
图 65.2. 只有在所有必需的临时分片都通过验证,并且受隔离令牌保护的清单提交记录最后发布之后,分布式检查点才可以用于恢复。

一套具体协议可以这样设计:

  1. 在当前隔离令牌下分配一个新的检查点代次。
  2. 在同一个步骤边界,暂存一份不可变的本地状态副本。训练程序不得再修改正在持久化的字节。
  3. 写入每个临时分片,并附上逻辑键、字节数与校验和。
  4. 验证所有预期分片与全局键覆盖。校验和能发现存储或传输损坏,却无法证明张量在计算校验和之前数值就是正确的。
  5. 最后发布一份不可变清单和提交记录。只有记录已经持久化且隔离令牌仍为当前令牌时,才能更新“最新”指针。
  6. 只恢复已经提交的清单。所有不完整检查点都只是暂存残留,应由有界垃圾回收清除。

清单才是事务边界。目录列表、某个 rank 的文件或时间戳,都不能证明检查点已经完整。全局状态一致性问题早于机器学习而存在。Chandy 与 Lamport 关于分布式快照的工作形式化地说明了,局部看来合理的碎片不会自动组成一个有效的全局状态 (Chandy and Lamport 1985)。

保存频率是一套带假设的模型

Young 的一阶模型在检查点的显性成本与预期重算成本之间取平衡 (Young 1974)。如果把检测与恢复加入模型,并把它们视为不改变一阶最优解的项,那么预期浪费比例为

W(T)=CT+T2M+R+DM,W(T)=\frac{C}{T}+\frac{T}{2M}+\frac{R+D}{M},

使其最小的间隔为

TYoung=2CM.T_{\text{Young}}=\sqrt{2CM}.

其中:

  • W(T)W(T) 是总运行时间中损失在检查点暴露时间、重放、检测与恢复上的预期比例;
  • TT 是两次完成的检查点之间用于有效计算的时间,单位为秒;
  • CC 是一次阻塞式检查点实测的暴露成本,单位为秒;
  • MM 是同步作业两次中断之间的平均时间,单位为秒;
  • RR 是每次中断后的会合、恢复与验证时间,单位为秒;
  • DD 是每次中断后的检测、隔离与重新排队延迟,单位为秒;
  • TYoungT_{\text{Young}} 是一阶模型给出的最优间隔。

这套模型假设作业运行时间很长,故障彼此独立,中断时间服从指数分布,各项成本恒定,重启能够成功,而且故障在每个间隔内均匀分布。它还假设检查点会阻塞训练、CTMC\ll T\ll M,并且保存检查点时不会发生故障。Daly 推导的是更高阶的泊松模型,而不是把这个近似当成普遍规律 (Daly 2006)。当软件故障、抢占、存储事故或相关故障破坏独立性假设时,应当使用作业层面实测的中断率,而不是把各部件故障率简单相加。

下面的可运行示例只使用 Python 标准库。若检查点的暴露成本为 30 秒,作业 MTBF 为 6 小时,一阶模型给出的间隔约为 19 分钟。

from math import sqrt

checkpoint_cost_s = 30.0
job_mtbf_s = 6 * 60 * 60
detect_and_restore_s = 180.0

young_s = sqrt(2 * checkpoint_cost_s * job_mtbf_s)
print(f"Young interval: {young_s / 60:.2f} minutes")

for interval_min in (5, 10, 20, 40, 80):
    interval_s = interval_min * 60
    waste = (
        checkpoint_cost_s / interval_s
        + interval_s / (2 * job_mtbf_s)
        + detect_and_restore_s / job_mtbf_s
    )
    print(f"{interval_min:>2} min -> expected waste {100 * waste:5.2f}%")

异步检查点改变的是成本测量方式,不是持久化义务。系统先把不可变状态暂存起来,通常放在主机内存,再在后台把它写入持久存储。暂存造成的停顿与训练干扰应计入 CC;后台写入耗时则会造成耐久性滞后,也就是已暂存步骤与最新可恢复步骤之间的差距。主机内存、网络与存储流量仍是真实成本。系统还必须设置有界的写入积压:如果新快照到达的速度超过旧快照的排空速度,就应按声明的策略延迟或跳过新快照,而不是无限分配缓冲区。CheckFreq 在其评估条件下展示了一套两阶段、可恢复的设计,并不意味着写入没有成本 (Mohan et al. 2021)。

切分检查点能减少单个写入者处理的字节数,并利用并行存储带宽,但总耐久字节数仍等于完整逻辑状态。当存储带宽、元数据处理、网络争用或协调器成为瓶颈时,扩展就会停止。因此,保存频率不仅取决于硬件 MTBF,还要考虑状态大小、步骤时长、暂存内存、持续与突发带宽、检查点失败、写入滞后和保留策略。

存储层级落实恢复目标

只有相对于它要防护的故障域,存储层级才有意义。本地内存也许能承受工作进程崩溃,却承受不了主机丢失;对等副本也许能承受一台主机丢失,却承受不了整个机架故障;远程持久存储也许能防护集群级故障,但仍可能与训练集群共享地域、凭据、元数据服务或控制平面故障。

层级 常见优势 常见局限
设备内存或本地内存 暂存与恢复延迟低 随设备或主机一同丢失,并占用训练内存
主机本地存储 顺序持久化与重新加载速度快 若不复制,仍与主机或机架处于同一故障域
对等复制的内存或存储 能防护声明范围内的成员故障 消耗网络与副本容量,仍可能相关丢失
远程持久存储 保留时间长,故障隔离范围更广 延迟更高,存在突发与元数据争用,并依赖外部系统

策略要从两个目标出发:

  • **恢复点目标(RPO):**当前已提交训练步骤与最新可恢复步骤之间允许的最大差距。
  • **恢复时间目标(RTO):**从运行中断到恢复并验证训练继续推进所允许的最长时间。

复制、保留与保存频率必须让已命名的故障域满足 RPO;准入、诊断、替换、加载带宽与验证则必须满足 RTO。近期的多层系统探索了不同取舍,其中包括内存副本 (Wang et al. 2023),但这里并不存在非此即彼的二选一。在预期故障域下进行恢复演练,比一次成功的写入基准测试更能证明系统具备恢复能力。

恢复始于故障分类

检查点与重启只有在故障原因已被移除或绕过时,才能修复丢失的进程状态。不同故障需要不同处置:

故障类别 证据 安全响应
失效即停的进程、节点或抢占 进程退出、心跳丢失、明确的驱逐事件 中止通信、隔离当前代次、替换或重新排队,再恢复
挂起或遗漏 进程仍存活,但进度停止 收集诊断信息、等待超时、让进程组静止、隔离并重启
掉队进程 某个 rank 的阶段耗时持续处于长尾 诊断数据、温度、链路、主机或内核原因,必要时隔离
确定性的代码、配置、OOM 或坏数据 完整替换后仍重复出现同一故障特征 停止有界重试,让运行失败并进入修复流程
存储或传输损坏 字节缺失或校验和不一致 拒绝该代次、尝试另一副本,或恢复更早的已提交代次
静默数据损坏 独立重算、不变量或硬件测试给出不同结果 隔离可疑硬件,回滚到已知正确的检查点
相关的机架、存储或控制平面事故 多个副本或作业出现同源故障 从独立故障域恢复,或等待服务恢复后重新排队

静默数据损坏(SDC),也就是不崩溃却悄悄写出错误数字的静默数据损坏,会让运行在没有显式故障的情况下继续;它也可能引起非有限值尖峰、改变优化轨迹或导致持续发散 (Ma et al. 2025)。普通检查点既不能检测也不能修复静默数据损坏,反而可能如实保存已经损坏的状态。只有当独立检测在回滚窗口内发现问题,而且系统仍保留一份已知正确的检查点时,恢复才有可能。校验和只能保证字节完整性;语义或数值层面的静默损坏需要端到端完整性检查,例如重复计算、不变量检查、主动硬件诊断或经过评估的小规模试验步骤。

固定成员关系通常按以下顺序恢复:

  1. 检测并分类进度停滞或无效状态。
  2. 中止通信器、停止工作进程组,并隔离它的运行代次。
  3. 收集诊断信息,隔离可疑节点、镜像、数据分片或存储代次。
  4. 分配并预检替代资源,或者采用有界退避重新排队。备用容量是一项可选的成本策略,不是调度器不变量。
  5. 重新会合,重建角色与 rank 映射,并在回滚窗口内选择最新的、已提交且验证通过的检查点。
  6. 恢复每一类状态,必要时按受支持的方式重新切分;恢复数据游标,再验证一个或多个步骤,之后才能把运行标记为健康。

数据平面始于不可变身份

corpus/latest 这样的路径是位置,不是数据集身份。运行启动前,系统必须把可变别名解析成一份不可变数据集清单。清单应记录:

  • 数据集与模式版本;
  • 每个对象的不可变版本或摘要、字节大小、记录数与逻辑范围;
  • 稳定的样本标识符或推导规则;
  • 格式、压缩、数据划分、过滤、去重与来源;
  • 分词器版本、词表摘要、变换与打包策略;
  • 混合策略、是否放回抽样,以及数据源耗尽时的行为;
  • 读取数据时采用的访问策略与授权范围。

数据集 ID 可以取规范化清单的摘要。缓存键应使用内容身份,而不是可变 URI;缓存填充完成后,也应先验证摘要再发布。通用来源模型会显式表示产物、执行与派生关系。这条数据血缘让后续检查点能够准确指出自己消费过哪份数据与哪张变换图 (Moreau and Missier 2013)。

逻辑样本分配与物理交付是两件事。逻辑平面把全局位置映射为样本、变换、打包序列与数据并行副本。张量、序列、上下文与流水线并行的多个 rank 可能协作处理同一个逻辑样本。物理平面则决定对象放置、远程读取、节点缓存、并行解码与预取。缓存命中与工作进程完成顺序可以改变延迟,但不应暗中改变声明的逻辑序列。

映射式与流式是访问接口,不是内存大小标签。只要能够按键或索引寻址,即使字节位于远程存储,仍然可以是映射式数据集;无法随机访问或随机访问代价过高时,迭代式数据集更合适。顺序归档格式是一种实用的流式设计 (Aizman et al. 2020);tf.data 则展示了如何把交错读取、并行映射、缓存与预取组成可组合的输入数据流 (Murray et al. 2021)。

吞吐量是一份有界队列契约

要让输入流水线不暴露在训练关键路径上,所需的最低平均供给速率为

Rreq=NtokTstep,R_{\text{req}}=\frac{N_{\text{tok}}}{T_{\text{step}}},

其中:

  • RreqR_{\text{req}} 是每秒交付的、参与损失计算的词元吞吐量;
  • NtokN_{\text{tok}} 是一个全局优化器步骤消费的参与损失计算的词元数;
  • TstepT_{\text{step}} 是目标优化器步骤时长,单位为秒。

平均值达标并不足以应对长尾服务时间。系统还应跟踪取批延迟分位数、输入等待、读取与解码吞吐量、队列深度与队列年龄、缓存命中率、重试次数和预取提前量。每个队列都需要内存上限与背压策略。生产者只能在达到高水位线后,按照明确规则阻塞或丢弃任务;无界预取只会把输入停顿变成内存压力和更大的重放窗口。Plumber 对输入流水线的分析说明,瓶颈会在 I/O、CPU 变换、内存与并行度之间移动,并不存在一个固定不变的“数据带宽”答案 (Kuchnik et al. 2022)。

打乱与混合都是有版本的算法

一句“把数据打乱”并没有定义可复现的分布。完整均匀排列、带种子的分片排列与有界打乱缓冲区,在随机性、局部性、内存占用与恢复状态上都不同。一种确定性的有限数据设计可以这样实现:

  1. 从数据集 ID、轮次与运行种子推导稳定样本 ID 上带版本的伪随机排列;
  2. 把全局批次 kk 定义为这个固定的逻辑排列区间;
  3. 在数据并行副本之间切分全局批次,同时让相互协作的张量或流水线并行 rank 共享样本;
  4. 通过序列号并行发起物理读取,再经有界重排缓冲区按逻辑顺序输出;
  5. 从稳定的样本上下文推导随机变换所需的随机数,而不是让它取决于工作进程到达顺序。

真正的数据流也可以使用带种子的分片顺序和有界打乱缓冲区。但这种设计不是均匀的全局排列,不能把它称为全局均匀排列。

混合数据也需要同样精确的契约。若各数据源独立抽样,则

ItCategorical(w1,,wm),E[Ni(H)]=Hwi,I_t\sim\operatorname{Categorical}(w_1,\ldots,w_m), \qquad \mathbb{E}[N_i(H)]=Hw_i,

其中:

  • ItI_t 是第 tt 次逻辑抽样选中的数据源;
  • mm 是数据源数量;
  • wi0w_i\geq0 是数据源 ii 的目标概率,且 i=1mwi=1\sum_{i=1}^{m}w_i=1
  • Ni(H)N_i(H) 是包含 HH 次抽样的窗口内,数据源 ii 实际被抽中的次数;
  • HH 是声明的测量窗口;
  • E\mathbb{E} 表示对采样器随机抽样取期望。

权重给出的是期望比例,不是精确计数。如果每个批次或窗口都要求精确配额,就要按明确的舍入规则分配整数配额、携带舍入债务,并以确定性顺序交错各来源。策略还必须说明计量单位是文档、样本、打包序列、原始词元或参与损失计算的词元;也要说明数据源耗尽后是停止、重复、重新归一化,还是报错。采样权重与损失权重是两种不同的控制量。检查点既要保存目标策略,也要保存各数据源的实际计数。

必须明确恢复语义

“可复现”可能指四种不同承诺:

恢复契约 承诺 额外要求
精确重放 从已提交游标之后开始,逻辑样本、打包张量、掩码与批次边界完全相同 数据集与算法身份、采样器与打包器状态、兼容的分区方式
轨迹精确重放 在精确重放之外,随机抽样与数值更新也完全相同 所有随机数生成器状态、确定性内核与库、兼容拓扑
覆盖等价恢复 覆盖同一份不可变数据,并满足声明的来源计数,但允许改变顺序或批次 稳定 ID、已提交计数与游标、明确的重复与跳过策略
分布一致恢复 继续从同一份声明的分布中抽样,不保证样本级连续 带版本的混合策略与有界统计检查

最后一行是分布一致恢复契约,只有当训练结论允许这么弱的保证时才适用。改变全局规模时,可以在改变 rank 局部顺序的同时保持覆盖等价;有些采样器还能推导一条与物理工作进程数量无关的精确全局序列。选定的契约必须写入运行规格与检查点模式。

持久游标只在消费这些样本的优化器步骤提交后推进。生产者也许已经获取并变换了后续样本,但这些预取的样本尚未提交。发生故障后,除非队列本身也属于检查点,否则它们会被丢弃,或从已提交游标重新构造。物理字节可能被读取两次,目标则是让恢复后的训练状态按照声明的重复与跳过样本策略,正确反映每一个逻辑位置。

图 65.3 把模型提交与数据提交连接起来。回滚模型却不回滚游标会造成跳过;游标比模型回滚得更远会造成重复贡献。

manifest 数据集清单 + 采样器 逻辑序列 fetch 并行获取 / 解码 有界预取 manifest->fetch batch 游标 c 处的全局批次 fetch->batch ahead 预取 c' 及之后的数据 临时状态 fetch->ahead 提前读取 step 优化器步骤 k batch->step commit 提交检查点 模型 k + 下一游标 c' step->commit failure 故障 commit->failure ahead->failure restore 恢复模型 k + 游标 c' 丢弃临时样本 failure->restore restore->fetch 重新构造
图 65.3. 模型状态与已提交的数据游标一同推进。预取工作仍是临时状态,回滚后应丢弃或重新构造。

如果顺序完全由数据集 ID、算法版本、种子、轮次与游标决定,采样器状态可以很小。有状态的打乱缓冲区、自适应混合、随机变换与序列打包器则需要保存更多内容。特别是,当尚未填满的打包序列、边界掩码或残余文档会影响下一个批次时,只保存文档游标远远不够。

可观测性验证每一份契约

只看损失无法定位运维故障,平滑的损失曲线也不能证明数据连续或硬件正确。遥测必须保留运行 ID、代次、全局步骤、数据身份、拓扑与软件版本,以便跨系统关联证据。

问题 信号
进程组是否仍在推进? 每个 rank 的心跳与步骤、步骤耗时分布、阶段时间线、超时与重启次数
设备路径是否健康? 集合通信等待、链路与重传计数器、硬件错误与限速事件、主动诊断结果
输入是否就绪? 输入等待、队列深度与年龄、缓存命中率、读取与解码吞吐量、重试与校验和失败
检查点保护是否仍然及时? 已暂存步骤与已持久化步骤、检查点队列与写入积压、年龄、字节数、清单结果与恢复验证
训练数值是否合理? 损失、裁剪前后的梯度范数、非有限张量、跳过更新、定期评估与独立检查
数据契约是否成立? 已提交游标、重复和跳过的 ID、按参与损失计算的词元统计的实际混合比例、数据集与分词器摘要

每个 rank 的分布比集群平均值更重要,因为单个掉队进程可能藏在正常均值里,却决定整个集合通信的速度。跟踪记录应把准入、输入、计算、集合通信、检查点与恢复跨度连接起来。每条告警都需要负责人、阈值或不变量、严重等级与操作手册。“没有告警”只说明没有已配置的检测器被触发,并不能证明静默损坏不可能发生。

衡量运维效率时应把故障也计入,而不是只报告稳态下每秒处理的词元数。一项实用指标是

ETTR=TproductiveTallocated,\operatorname{ETTR}=\frac{T_{\text{productive}}}{T_{\text{allocated}}},

其中,TproductiveT_{\text{productive}} 是用于已接受优化器步骤的时间,TallocatedT_{\text{allocated}} 则包括有效训练时间,以及检查点暴露时间、重放、恢复、停顿和已分配但闲置的容量。有效吞吐量应当用参与损失计算且已接受的词元数除以端到端运行时间。每个已接受词元的成本还应计入重放、可选备用容量、存储、网络与控制平面资源。

运行全生命周期

长时间运行在获得完整资源分配之前,应先在小规模环境里通过同一套恢复契约:

  1. **冻结规格。**确定代码、镜像、模型与优化器状态、数据与分词器清单、拓扑、恢复语义、RPO/RTO、预算、重试类别与取消权限。
  2. **预检路径。**在目标拓扑上验证设备与链路健康、软件兼容性、集合通信、存储凭据、检查点带宽、数据访问、缓存完整性与遥测。
  3. **运行小规模试验。**覆盖有代表性的形状、输入变换、打包、混合计数、检查点暂存与提交、评估和输出发布。
  4. **注入故障。**在计算和保存检查点时终止一个工作进程;制造挂起、掉队、存储超时、分片截断、陈旧工作进程、缺失的数据对象与受支持的拓扑变化。验证隔离、有界重试、隔离故障对象、回退与游标连续性。
  5. **执行恢复演练。**把最新代次和较旧代次恢复到所有受支持的布局;拒绝不完整或已损坏的清单,并测量 RPO 与 RTO。
  6. **为持续执行设置门禁。**针对进度、各 rank 长尾、输入等待、检查点滞后、混合比例偏差、损坏证据、预算消耗与重复故障特征设置告警。确定性故障重复出现时应升级处理,避免制造重试风暴。
  7. **演练取消与完成。**隔离过期写入者、停止工作进程、保留已提交证据、释放资源,并对临时分片与缓存执行有界垃圾回收。
  8. **发布运行后清单。**绑定终止状态、已接受的模型产物、完整来源信息、数据与词元计数、评估、事故、成本,以及保留的恢复产物。

下层约束

运维平面无法凭空创造训练程序没有暴露的状态。如果框架遗漏梯度缩放器、随机数流、打包器残余或逻辑张量身份,检查点就无法重建它。如果并行方案不能重新切分,调度器就不能安全宣称支持弹性。如果存储、主机内存或互连无法在不干扰集合通信的情况下吸收暂存流量与数据流量,异步工作仍会降低训练有效吞吐量。这些限制来自 第 10 章第 62 章;本章所做的是把它们转化为可测量的准入、提交与恢复规则。

下一章 第 66 章 会沿着同一个系统继续向下、向前追问:未来运行中,哪些带宽、封装与互连结构约束正在成为新的瓶颈。

争议所在

有些选择仍然取决于具体工作负载与系统。固定成员关系让恢复语义更简单;弹性可以提高容量利用率,却要求模型、优化器与数据状态都能重新切分。精确重放提供更强的取证证据;覆盖等价或分布一致的恢复则允许更大范围的物理重排与拓扑变化。本地层级与对等层级能缩短恢复时间,远程持久层级则防护不同的故障域。完整工作进程组重启已得到广泛支持,而角色局部修复与热替换需要更严格的通信器与状态隔离保证。

真正该问的不是哪一种机制普遍最好,而是一份有明确名称的运行契约,能否在它声称可承受的故障下,达到实测的恢复点目标、恢复时间目标、数据连续性承诺、数值检查、有效吞吐量与成本要求。

延伸阅读

  • Young, “A First Order Approximation to the Optimum Checkpoint Interval,” 1974. doi.org
    Young 在简单的独立故障模型下,根据检查点成本和平均故障间隔推导了一阶检查点间隔。
  • Daly, “A Higher Order Estimate of the Optimum Checkpoint Interval for Restart Dumps,” 2006. doi.org
    Daly 推导了泊松故障条件下更高阶的检查点间隔,并指出一阶近似会在哪些情况下失准。
  • Gu et al., “Tiresias: A GPU Cluster Manager for Distributed Deep Learning,” 2019. usenix.org
    Tiresias 研究了具有全有或全无资源需求的分布式深度学习任务应如何准入、放置和调度。
  • Chandy & Lamport, “Distributed Snapshots: Determining Global States of Distributed Systems,” 1985. doi.org
    Chandy 和 Lamport 说明了如何在不中断分布式计算的情况下记录一致的全局状态。
  • Mohan et al., “CheckFreq: Frequent, Fine-Grained DNN Checkpointing” (频繁的异步检查点), 2021. usenix.org
    CheckFreq 分析检查点开销,调整保存频率,并将检查点工作流水线化,同时保持所评估的数据加载器不变量。
  • Wang et al., “Gemini: Fast Failure Recovery in Distributed Training with In-Memory Checkpoints,” 2023. doi.org
    Gemini 把检查点副本保存在主机内存中,并调度传输流量以缩短恢复时间,而不假设单一存储层能覆盖所有故障域。
  • Ma et al., “Understanding Silent Data Corruption in LLM Training,” 2025. aclanthology.org
    存在静默数据损坏的生产节点可能造成轻微数值扰动、损失突增,甚至训练出不同权重。
  • Murray et al., “tf.data: A Machine Learning Data Processing Framework,” 2021. vldb.org
    tf.data 把输入加载表示为可组合的数据流,其并行、缓存、预取和确定性选择都会影响端到端训练。
  • Kuchnik et al., “Plumber: Diagnosing and Removing Performance Bottlenecks in Machine Learning Data Pipelines,” 2022. proceedings.mlsys.org
    Plumber 通过感知资源的流水线分析定位输入瓶颈,并调节并行度、预取和缓存。

评论

登录后评论