一句话定义:GPU ECC(Error Correcting Code,纠错码)是显卡显存上的一套硬件校验机制,能在数据位发生翻转时自动纠正小错,并对纠正不了的错误明确报警——而不是把错数据悄悄交出去。
显存为什么会自己出错?DRAM 靠电容里的电荷表示 0 和 1,宇宙射线中的中子撞一下、封装材料里的微量放射性杂质衰变一下、电压或温度抖一下,都可能让某个比特翻转。这类问题叫软错误(soft error):芯片本身没坏,重写一遍就好,但它发生的那一刻没有任何人知道。单次概率极低,可一张卡动辄几十上百 GB 显存、带宽以 TB/s 计、训练任务一跑几周,这就是纯粹的规模概率问题。真正要命的不是“坏了”,而是“错了但看起来一切正常”,也就是静默数据损坏(silent data corruption,SDC)——一个浮点数从 1.0003 变成 1.0004,loss 曲线照样平滑,日志里什么都不报。
ECC 的做法不复杂:每段数据额外配几位校验码。最常见的是 SECDED 方案——单比特错误当场自动纠正,双比特错误纠正不了,但会举手报错,让驱动和监控工具记下来。代价是实打实的:一部分显存要拿去存校验位,读写时也要多花带宽和少许延迟,开销通常是百分之几的量级,具体比例随显存类型和厂商实现而不同,以官方规格文档为准。
打个比方:显存像一本巨大的账本,每页数字后面附一个“对账码”。抄错一位,对账码能把它推回原样;错两位,账本会停下来告诉你“这页不可信”。没有 ECC,就相当于没有对账码的账本——抄错了,账照样往下算。
它和几个容易混淆的东西不是一回事:
| 机制 | 能做什么 | 生效时机 | 代价 |
|---|---|---|---|
| ECC | 纠正单比特错,报告多比特错 | 硬件级、实时 | 少量容量与带宽 |
| 奇偶校验(parity) | 只能发现,不能纠正 | 实时 | 较小 |
| Checkpoint | 保存/恢复整个训练状态 | 周期性 | 出错要回滚,丢几个小时 |
| 应用层异常检测(NaN、梯度范数) | 捕捉明显异常 | 事后 | 抓不到“看着正常”的错值 |
训练和推理的取舍完全不同。训练时,一次错误的梯度更新可能悄悄污染权重,而你往往几周后在验证集上才发现不对,最后只能回滚重跑——那点容量损失和三周的机时比几乎不算钱,所以训练集群基本默认开 ECC。推理时,一个 token 算歪了用户多半看不出来,对显存和吞吐极度敏感的场景(比如想在单卡上多塞 KV cache)就有人考虑关掉。但两点要留心:一是长上下文、大批量、长链条推理会把单次错误放大;二是很多平台根本不给你这个开关,消费级显卡通常不提供 ECC,数据中心卡则常常强制开启。
落到日常:看到可用显存比标称少一点、带宽比理论值低一点,先别怀疑买亏了;另外多数数据中心卡的管理工具会给出可纠正/不可纠正错误计数,这个数字值得盯着——可纠正错误忽然变多,往往意味着这颗显存快要不行的前兆。
