系统韧性与可观测性¶
大模型系统的可靠性目标不是“进程还能运行”,而是持续产生可验证的训练进度或满足 SLO 的推理结果。一个 rank 卡住、网络降速、GPU 产生不可纠正错误、checkpoint 部分完成,都可能让进程表面存活却不再产生有效 goodput。
韧性设计应从故障模型、状态边界和恢复目标开始,再决定 heartbeat、重试、弹性或冗余。
先定义服务目标¶
训练系统可使用有效 token goodput:
推理系统则以满足全部 TTFT、TPOT、端到端延迟和质量约束的请求计数:
可用性和正确性不能相互替代。自动重试可能提高完成率,却也可能造成重复训练 step、重复计费、重复流式 token 或不一致的工具副作用。
恢复目标至少包括:
- RPO:允许丢失多少已完成进度;
- RTO:故障后多久恢复有效工作;
- 数据一致性:是否允许重样本、跳样本或近似 resume;
- 服务语义:请求是 at-most-once、at-least-once 还是幂等重放;
- 降级边界:允许牺牲哪些质量、长度或吞吐。
故障分类¶
| 层次 | 典型故障 | 需要的证据 |
|---|---|---|
| GPU | ECC、Xid、温度、降频、kernel hang | 设备健康、错误事件、时钟与功耗 |
| 进程 | crash、OOM、死锁、异常退出 | exit code、stack、allocator 与 trace |
| Collective | rank mismatch、超时、链路降速 | 各 rank 调用序列、count、dtype、网络计数 |
| 主机 | 内存、NUMA、磁盘、重启 | OS 与资源 telemetry |
| 网络 | packet loss、拥塞、NIC / switch 故障 | link、RDMA、重传、端到端带宽 |
| 存储 | 超时、部分写入、损坏 | manifest、checksum、提交标记 |
| 数据 | 坏样本、游标漂移、重复或跳样本 | sample ID、token cursor、版本 |
| 模型 | NaN、梯度爆炸、质量漂移 | loss、gradient、scale、固定探针 |
| 服务控制面 | 错路由、stale version、容量失配 | request / model / cache schema |
故障检测要区分 fail-stop、slowdown、Byzantine-like corruption 和控制面不一致。只对 crash 做重启不能处理静默数值损坏或 straggler。
Collective 的正确性先于超时¶
NCCL collective 语义要求各 rank 的 collective 调用匹配 count、datatype 与顺序。违反契约可能表现为 hang、crash 或静默数据损坏。
因此 timeout 只能说明“在时间窗内没有完成”,不能单独证明网络故障。排查顺序应包括:
- 每个 rank 是否进入同一个逻辑 step;
- process group 与 collective 顺序是否一致;
- tensor count、dtype、device 和 stream 是否匹配;
- 是否存在提前异常或 OOM 的 rank;
- 最后再判断链路、拥塞和硬件。
watchdog 若在一个 rank 仍使用通信 buffer 时直接重启其他 rank,可能扩大故障。需要先终止或隔离同一一致性组,再进行恢复。
Straggler 是可靠性问题¶
同步训练由最慢 rank 决定 step time。可定义尾部比:
还应按 phase 分解 compute、collective、input 和 checkpoint。一个 rank 的 step 慢可能来自:
- GPU 降频或错误恢复;
- NUMA / CPU 数据线程;
- 特定 NIC、交换链路或拥塞;
- allocator / page fault;
- 数据 shape 偏斜;
- expert 或 sequence 负载不平衡;
- 异步 checkpoint staging 抢占 CPU / 网络。
只看平均 GPU utilization 会把这些原因混在一起。NVIDIA DCGM profiling 与诊断工具可提供设备级证据,但仍需与模型 phase 和分布式 trace 对齐。
状态机与故障域¶
把训练作业表示为
每个状态应定义允许的外部动作和持久化边界。恢复不能简单地“从最近目录读取”,而应读取最近一个经过原子提交、checksum 和兼容性检查的 checkpoint。
故障域决定一致性组:
- 一个 DP replica 失败是否需要重启整个 world;
- pipeline 某 stage 能否由备用副本接管;
- serving worker 失败是否只丢失本地 KV;
- router 和 KV store 是否持有可恢复的全局状态;
- 网络分区时哪一侧允许继续接受写入。
弹性缩放改变 world size 时,还会改变 shard、batch 和数据游标语义,必须与检查点与容错的跨拓扑恢复共同设计。
重试、弹性与冗余¶
TorchElastic agent 提供 worker group 的失败检测和重启语义;它不会自动证明数据游标、optimizer 或自定义外部状态的一致性。
TorchFT 探索训练中的容错与副本协调;NVIDIA Resiliency Extension 提供 fault detection、straggler detection 与进程管理等能力。采用这些机制前仍需回答:
- 哪些状态被复制;
- 复制在何时达到一致;
- 故障切换会丢失多少 step;
- 外部数据和 checkpoint 如何去重;
- 网络带宽和显存开销是否进入容量模型。
冗余并不总是最优。若 checkpoint 恢复很快、故障率低,备用 GPU 的持续成本可能大于收益;若模型 step 很长或集群 MTBF 随规模快速下降,局部恢复与冗余更有价值。
可观测性数据模型¶
指标应围绕状态与因果关系组织,而不是堆积 dashboard。
训练¶
- global step、有效 token、数据游标;
- step、forward、backward、optimizer、collective 分位;
- MFU / HFU 与 HBM / network throughput;
- 各 rank tail ratio;
- loss、gradient norm、overflow、scale;
- checkpoint staging、写入、提交和恢复时间;
- restart、lost work、重复或跳过样本;
- GPU Xid、ECC、温度、功耗与时钟。
推理¶
- queue time、TTFT、TPOT、E2E 和 goodput;
- active / waiting / preempted / cancelled 请求;
- KV pool、fragmentation、prefix hit 与 eviction;
- prefill、decode、transfer 与 sampler 时间;
- model / adapter / cache schema version;
- OOM、timeout、stream disconnect、retry 与重复输出;
- compile、graph miss 和 fallback 比例。
高基数字段如 request ID、rank、model version 用于 trace 或结构化 log;不要把 prompt、生成文本或 token 内容默认放入 telemetry。指标 label 无界增长会反过来破坏观测系统。
Trace 与关联¶
一次训练 step 或推理请求应具有稳定关联 ID,使以下事件可拼接:
时钟不同步会破坏跨节点 trace 顺序;需要记录单调时钟 duration,并对 wall-clock 做同步质量监测。采样 trace 时应保留错误、尾延迟和版本切换事件,不能只随机保留平均请求。
健康检查¶
- liveness:进程或服务循环仍能推进;
- readiness:当前实例能够安全接收新工作;
- progress:有效 step、token 或请求确实增长;
- correctness probe:固定输入仍满足数值或协议不变量。
只检测端口或 heartbeat 不能证明 collective、GPU 或模型可用。反过来,短时没有新请求也不是服务失败。健康检查应结合当前状态和工作负载。
正确性契约¶
- 同一训练一致性组只认可一个 active generation / epoch。
- restart count、checkpoint ID、data cursor 和 model version 单调。
- committed checkpoint 不可在后台修改。
- 请求重放必须有 idempotency key 或明确的重复语义。
- streaming token 的序号单调,finish 只发生一次。
- readiness 在模型、adapter、KV schema 未加载完成时保持 false。
- 旧 worker drain 后不得接收新版本请求。
- 观测事件携带版本和状态,但默认不携带敏感内容。
- alert 必须引用可操作证据,并区分症状与根因。
自动恢复何时会伤害系统¶
- collective mismatch 尚未修复,重试只会重复 hang;
- checkpoint 未原子提交,自动回退可能读到部分状态;
- OOM 来自确定性 shape,原配置重启必然再次失败;
- NaN 来自数据或模型错误,跳过并继续会掩盖质量损坏;
- 非幂等外部副作用可能被重复;
- 网络分区中双方都继续写入,产生 split brain;
- stale model / KV schema 被重新加入流量;
- retry storm 占满控制面、存储或网络。
自动化应有速率上限、熔断、隔离和人工升级边界。无法证明安全重放时,应停止而不是追求表面可用。
故障注入与验证¶
验证矩阵至少覆盖:
- 单 worker 正常退出、强制退出和无响应;
- collective 前后某 rank 失败;
- NIC 降速、丢包、网络分区和节点内链路退化;
- GPU OOM、Xid、降频和长 kernel;
- 数据读取超时、坏样本和游标不一致;
- checkpoint shard 缺失、损坏、重复和 partial manifest;
- 恢复时改变 DP / TP / PP / EP 拓扑;
- serving worker 带活跃 KV 退出;
- model、adapter 或 cache schema 灰度切换;
- telemetry 后端不可用,确认业务不会被观测链路拖垮。
每次实验记录 detection time、quiesce time、lost work、restore time、重复工作和最终数值 / SLO。故障注入的通过标准不是“自动重启成功”,而是状态不变量仍成立、错误可定位且恢复成本符合目标。
何时采用更简单的方案¶
单机短作业、可快速重跑的实验不一定需要复杂弹性框架;小规模服务也可能用进程隔离、健康检查和无状态重启即可。复杂恢复机制只有在以下条件下才值得:
- 故障频率和 lost-work 成本已量化;
- 状态边界清楚且可测试;
- 恢复时间确实优于全量重启;
- 引入的副本、网络和控制面成本可接受;
- 团队能维护故障注入和升级兼容矩阵。
可靠性的成熟度应以恢复演练和长期 goodput 证明,而不是以配置项数量衡量。collective、全局归一化与 checkpoint 提交的不变量可结合手撕:分布式与容错逐项验证。