面向GPU内存比特翻转的软件实现容错系统SAVE 个人笔记
引言当前在边缘加速器上保护模型推理免受比特翻转的方法可分为两类具体取决于它们是否修改模型结构。第一类通过修改模型结构来增强模型鲁棒性包括专门的激活函数、压缩和量化。然而这些方法通常会损害精度并且在不同模型之间缺乏通用性。第二类保留模型结构通过冗余实现保护例如三模冗余 (TMR)和 ECC 。尽管这些方法可以保留精度和通用性但它们要么会产生显著的开销TMR 为 2 倍要么提供的纠错能力有限ECC。SAVE属于第二类而且无需重新训练模型或牺牲精度的前提下观察到的现象第一硬件上“并非所有比特都生而平等”。现代边缘AI加速器如NVIDIA Orin提供了少量但完全无比特翻转的“安全岛”内存同时部分GPU内存比特本身由于制造工艺等因素在实际中也不易翻转可被视为可靠内存。第二软件层面“并非所有比特翻转都是致命或静默的”。由于模型计算中的非线性激活函数等特性比特翻转对推理结果的影响程度不同。部分比特是鲁棒比特Robust Bits其翻转对最终精度几乎没有影响与通用计算不同模型计算的非线性使得某些比特翻转对模型精度的影响很小。部分比特是范围比特Ranging Bits其错误可以通过简单的输出范围检查被检测到可能导致NaN并将模型精度降低至0剩余的是脆弱比特Vulnerable Bits它们会静默地破坏模型输出且难以察觉。导致精度逐渐下降eg 尾数最后几位对结果影响甚微因此可直接指定为鲁棒比特基于以上背景与洞察本研究的目标是提出一种不修改模型结构、不牺牲精度、且性能开销低的软件实现的容错系统SAVE基本思想洞察在判单 某一个数值 的 某一个比特 属于哪一种比特的时候通过测试所有比特位来寻找所有鲁棒比特和范围比特是不切实际的因为比特位的数量庞大1亿参数每个参数32bit。每翻转一个比特理论上都需要执行一次完整的模型推理过程以评估其对最终结果如分类准确率的影响。一个复杂的深度学习模型推理可能涉及数千甚至数万次浮点运算。穷举法是离线、动态测试实际运行推理SAVE是离线、静态分析 同时单个比特位的鲁棒性不能直接推广到多个比特位多个比特同时翻转正因为这种复杂性SAVE 并没有试图穷举多比特翻转而是将比特分为了三种类型Robust BitsRanging BitsVulnerable Bits穷举370天SAVE10sRobust Bits不用通过反转一个然后执行一次完整的推理过程分析最终结果来验证。只需要分析GPU核函数的数学性质即可确定一些鲁棒比特and 尾数最后几位直接指定为鲁棒比特。Ranging Bits见下“选择阶段”SAVE系统的工作流程SAVE系统的工作流程包含四个阶段选择、分配、验证和编辑。整个系统构建在PyTorch框架之上。PS第一步首先通过离线 静态 分析识别出模型中“每一个”数值包括输入、输出激活值和中间值不包括模型参数第二步会被故意放到不可靠内存KV Cache的三种比特类型。第二步模型运行时在执行每一个GPU核函数时将输入矩阵一般就是指激活值模型权重都放到不可靠内存分块。SAVE优先将包含更多“类型-2”数值即包含脆弱比特的数值的分块分配到可靠内存剩余的分块分配到不可靠内存。 需要注意的是在第二步中为了最大限度的利用可靠内存SAVE采用“就地计算”的方法。“类型-2”数值的定义§3.2是包含脆弱比特的数值。而“类型-1”数值是全部由鲁棒比特和范围比特构成的数值。决策的直接单元是“类型-2”数值而非直接统计脆弱比特本身第三步的验证内容是动态的。首先对所有涉及的计算块异步验证其模型权重通过与CPU端的完整的模型参数是否一致来检验。然后对于“输入存放在不可靠内存中”的那些计算块额外启动 范围比特 的GPU核函数验证并对脆弱比特部分发起异步的“混合精度 重计算”验证。第四步恢复阶段若在第三步中检测出来了至少有一个比特除错则从中断的模型层开始重新启动推理计算第一阶段选择阶段此阶段为一次性离线静态分析旨在识别模型中每个数值的三种比特类型鲁棒比特、范围比特、脆弱比特。范围分析离线的SAVE将模型视为一个有向无环计算图从已知的输入数据范围例如图像像素值范围0-1开始推导出模型中每一个中间值张量中每个元素的合法输出值范围。对于输入输出关系非单调或输出范围过宽的操作符SAVE会将其输出范围划分为多个区间进行更精细的分析。比特属性分析利用计算出的值范围SAVE识别两种非脆弱比特。回到论文了解细节参数是按照IEEE754的格式范围比特的识别对于一个给定 值范围SAVE找出在该范围内所有可能取值都必须相同的那些比特通常是符号位和部分受范围边界约束的指数位。这些比特即为范围比特它们的正确性可以通过检查计算值是否落在预定范围内来快速验证。鲁棒比特的识别SAVE识别两类鲁棒比特。一是基于数值的鲁棒比特对于一个值范围的上下界如果翻转其尾数部分的某个比特所引起的数值变化小于一个保守的阈值论文选用10^-5则该比特被认为是鲁棒的。取上下界鲁棒比特的交集作为该值范围的鲁棒比特集。二是基于操作符的鲁棒比特某些操作符特别是激活函数会引入额外的鲁棒性。例如对于ReLU函数只要输入为负无论其具体负值是多少输出恒为0。因此对于负输入除符号位外的其它比特都可被视为鲁棒比特。分析结果被存储在一个比特属性缓存中供运行时快速查询以加速验证过程。第二阶段分配阶段此阶段负责运行时GPU内存的管理与数据放置策略。由于现有计算接口不支持比特级内存管理SAVE采用矩阵分块的策略。分区与评估在执行GPU核函数时SAVE将输入矩阵分区为若干子矩阵块。评估每个子矩阵块中所含脆弱比特的比例。优先级分配分配策略的核心是优先将脆弱比特比例更高的计算子矩阵块放置在可靠内存中模型参数权重矩阵则被有意地始终放置在不可靠内存中因为CPU端保存有它们的完好副本就地计算与内存管理为了优化有限可靠内存的使用SAVE采用就地计算技术eg在矩阵乘法中用输出结果覆盖输入张量。同时它需要仔细管理输出内存的放置。根据输入和输出所在的内存类型可靠/不可靠存在四种计算场景。SAVE确保在CPU端已安全存储副本后才进行内存的原地修改并同步更新验证状态。**鲁棒比特计数Robust Bit Count图例从深橙色到浅橙色再到白色表示矩阵块中鲁棒比特Robust Bit**的数量从“多More”到“少Less”。绿色边框 (Case 1)表示输入和输出都存储在可靠内存中。蓝色边框 (Case 2)表示输入存储在可靠内存输出存储在不可靠内存中。灰色边框 (Case 3)表示输入存储在不可靠内存输出存储在可靠内存中。黄色边框 (Case 4)表示输入和输出都存储在不可靠内存中。第三阶段验证阶段此阶段负责高效检测发生在不可靠内存计算中的错误。在大模型运行时显存、内存中读存放哪些数据显存核心计算区推理阶段模型参数也称“权重矩阵”权重、偏置KV Cache激活值也称“中间值、特征图”计算后立即释放临时缓冲区矩阵乘法临时空间等训练阶段模型参数KV Cache完整激活值梯度优化器状态临时缓冲区内存数据与调度中枢模型参数模型过大时内存存储完整权重显存按需交换训练数据批次优化器状态系统与框架开销异步权重验证对于模型参数权重SAVE在每层计算后利用GPU的DMA引擎异步地将其从GPU不可靠内存拷贝回CPU从GPU拷贝回CPU干什么由CPU线程与原始副本进行一致性比对。此过程与下一层的GPU计算重叠几乎不引入额外延迟。没看懂对于“模型参数”而言模型参数都被完整的存放在了CPU端的内存中即显存中的模型参数在CPU端都有副本可以用这个副本来检验GPU中的“模型参数 数据”是否出错对于存储在不可靠内存中的中间值验证 范围比特SAVE利用选择阶段推导出的合法范围来验证其范围比特。它启动一个轻量级的GPU核函数快速检查每个值是否落在预定的区间内并将结果标记矩阵传回CPU进行最终确认检查是否全部为零。该核函数可与原计算核函数融合以减少开销。混合精度 重计算验证 脆弱比特对于涉及脆弱比特的计算结果需要进行重计算来验证正确性。为了最小化CPU重计算的负担SAVE采用混合精度整数计算进行轻量级验证。由于范围比特已通过范围检查鲁棒比特可被忽略真正需要验证的比特数已减半。结果的符号位通过对x和y的符号位行异或运算得到。结果的指数位通过对x和y的指数部分进行加法或减法运算得到。确定了新的指数位重新估计鲁棒位并移除鲁棒位以进行进一步的低精度验证。结果的尾数通过将x和y的尾数不包括鲁棒位转换为16位或8位整数低精度和混合精度然后执行乘法或除法来计算SAVE将剩余的尾数比特转换为16位或8位整数利用CPU的SIMD指令并行执行整数乘法或除法详见论文并与从GPU结果中提取的符号位、指数位组合生成一个低精度的验证结果进行比对。对于加法和减法等轻量操作则直接进行重算。第四阶段恢复阶段当在验证阶段检测到错误比特翻转时SAVE执行错误恢复。其策略是简单地从中断的模型层开始重新启动推理计算利用可靠内存和已验证的正确数据确保最终得到正确结果。