体系结构论文(五十):Maintaining Sanity: Algorithm-based Comprehensive Fault Tolerance for CNNs 【DAC‘24】

Maintaining Sanity: Algorithm-based Comprehensive Fault Tolerance for CNNs 

这篇文章旨在为CNN提供高效、全面的容错能力。它的目标是在CNN应用于安全关键的场景(例如自动驾驶、医疗诊断等)时,即使硬件出现故障,也能保证网络的可靠性。

一、背景介绍

1. 背景

由于CNN越来越多地被用于安全关键的应用(如自动驾驶、气候分析、疾病诊断等),因此保证它们在硬件故障时依然能稳定运行变得尤为重要。硬件中的软错误(例如由宇宙射线或热中子引起的意外比特翻转)可能导致神经网络误分类,比如可能把卡车识别为鸟。这类错误在安全关键应用中可能引发灾难性后果。

2. 现有问题

现有的许多保护方案存在三个主要缺点:

  • 高开销问题: 一些方案如模块冗余(比如三模冗余)虽然可以有效检测和纠正错误,但由于需要复制整个模型,因此计算和内存开销非常大。
  • 覆盖不足: 有些方法虽然能有效地保护部分网络,但其他部分仍然暴露在故障的风险之中。
  • 额外要求: 某些解决方案需要额外的训练或组件,比如基于机器学习的容错技术,往往要求重新训练一个新的模型来检测故障。

3. Maintaining Sanity 

为了应对上述问题,本文提出了 Maintaining Sanity 技术。它主要基于算法容错(ABFT)技术,通过汉明码(即在原始数据中插入校验位,形成一个可以自我检查的编码结构)来生成冗余信息,用于检测和修正 CNN 中的故障。

  • 模型参数冗余: 该方法通过校验和机制来保护卷积层和全连接层中的权重、偏置和输出。每当网络进行前向传播时,会计算检查和校验和,如果检测到问题,可以通过回退到上一个检查点来纠正错误。

  • 输入冗余: 为了处理网络各层的输入故障,Maintaining Sanity 通过复制输入并使用检查点算法来纠正输入层的错误。通过这种方式,它仅需复制原始输入,而不需要为每一层单独生成冗余。

 模型参数冗余: 基于ABFT,添加冗余来保护神经网络的模型参数(包括权重、偏置和输出)。通过生成检查和校验和来检测错误。如果出现错误,可以通过检查和总校验和的值来恢复出错的参数。

层输入冗余: 除了保护模型参数外,Maintaining Sanity 还通过输入冗余来保护每一层的输入。它通过复制原始输入并采用“检查点回滚”策略,在检测到输入故障时回滚到前一个层的输出,从而有效恢复错误。

4. 贡献

通过在四种流行的 CNN 模型(包括 AlexNet、LeNet5、ResNet18 和 VGG16)上进行实验,Maintaining Sanity 能纠正超过 99.6% 的关键故障。与其他容错技术相比,Maintaining Sanity 的故障覆盖率几乎完美,同时计算开销仅为三模冗余(TMR)的约 72%。

  • 全面可靠性: Maintaning Sanity 能够检测并修复神经网络中任何时刻、任何位置的故障。
  • 高效性: 它的开销仅增加约 135%,但相比传统的三模冗余,效率大大提升。
  • 易于应用: 该技术没有特殊的前提条件,适合应用在资源受限的环境中。

二、相关工作

2.1 神经网络的可靠性

  1. 双模冗余和三模冗余

    • 这些方法通过在硬件或软件层面上复制或三重复制模块来保障单一组件的完整性。DMR 可以检测错误,而 TMR 则可以纠正错误。TMR 通过将模块执行的三次结果进行多数投票,来纠正可能出现的错误。
    • 尽管 TMR 和 DMR 在传统计算系统中被广泛采用,但它们对空间和时间资源要求非常高。而对于神经网络来说,已经需要大量的计算资源,因此这些冗余技术的高开销使其难以直接应用于神经网络。
  2. 基于范围限制的轻量化容错方法

    • 这种方法假设会显著改变最终分类结果的关键错误会引起较大的值偏差。因此,限制激活函数的输出范围可以减少错误带来的影响。
    • 但是,由于现代的量化技术(如 INT8)已经充分利用了数据的范围,这种基于范围限制的方法在高度量化的网络中无法提供足够的故障覆盖。
  3. 基于训练的容错方法

    • 一些研究尝试通过神经网络训练的改进来应对故障。例如,将网络暴露在故障环境中进行训练,以增强其对故障的耐受性。
    • 另一种策略是训练一个小型神经网络,专门用来检测原始网络的特征图中的故障。虽然这种方法可以提供有效保护,但它依赖于神经网络的“黑箱”特性,缺乏解释性,并且需要额外的训练数据和足够的故障注入实验。

2.2 Sanity-Check

Sanity-Check 是与本文工作最密切相关的一项研究工作。它基于 ABFT(算法容错)原理,提出了一种检测深度神经网络推理过程中错误的机制。Sanity-Check 通过空间校验和的概念来保护神经网络的权重、偏置和输出。

空间校验和:是指在一个特定时间点,对多个数据元素或输出进行计算,生成一个校验和。譬如如果在某一层的计算中,输出的某些值出现错误,空间校验和的计算结果就会与预期不符,从而能够检测到错误的发生。

  1. 在全连接层中的应用

    • Sanity-Check 在全连接层中引入两个冗余神经元:sanity neuron(“完整性”神经元)和 check neuron(“检查”神经元)。Sanity neuron 的权重和偏置设置为,使得在没有故障时,该神经元的值等于其他所有输出神经元的负和。Check neuron 则计算所有输出神经元(包括 sanity neuron)的校验和。
    • 如果校验和不为零,则表明层的权重、偏置或输出存在故障。
  2. 在卷积层中的应用:类似的过程也应用于卷积层,Sanity-Check 增加了额外的校验滤波器和偏置来检测卷积层中的参数错误。

  3. 空间校验和的不足:仅使用空间校验和不足以检测层输入中的故障。因此,Sanity-Check 还引入了时间校验和,通过在输入批次中添加“sanity inputs”来进行输入故障检测。这些 sanity inputs 被计算为所有其他输入的负和,使得空间校验和的值等于批次大小与相应层的偏置向量/矩阵的乘积。如果输出校验和与预期不符,则可以识别输入层存在故障。

  4. Sanity-Check 的局限性:无法扩展到激活函数或池化层。它还需要批处理推理来计算时间校验和,导致引入额外的延迟和内存开销。

时间校验和:用于保护不同批次输入或层输入的正确性,通过对多个时间点的数据生成校验和,保证中间层输入输出没有在传递过程中出错。

这一部分介绍了 Maintaining Sanity 技术在全连接层和卷积层中的容错方法。让我为你详细解析这一段内容,结合图2中的示例:

三、 Maintaining Sanity

3.1 模型参数冗余

Maintaining Sanity 目标是确保卷积层和全连接层的容错性。

1. 基本原理:

在全连接层或卷积层中,Maintaining Sanity 通过增加冗余神经元,生成一个总校验(Total Sanity)。Sanity neurons 确保原始输出的总和加上 sanity neurons 的总和为 0。

例如:对于一个有 n 个输出的全连接层,假设输出分别是 O1∼On,Maintaining Sanity 会生成一个额外的输出 OS​ 作为 sanity output,满足:

O1+O2+⋯+On+OS=0

如果发生错误,这个公式将无法成立,从而可以检测到错误。

2. 故障检测和恢复:

  • 故障检测:通过检查总校验和是否为 0 来判断网络是否出错。如果校验和不为 0,则表明某个输出存在错误。

左侧部分展示了原始神经元和 sanity neurons 的权重连接关系。每个 sanity neuron 都通过计算一部分输出的总和来生成校验值。

右侧部分展示了错误检测和错误定位的过程。通过检查校验和 P0、P1、P2 的值能精确定位哪个输出出现错误。

最下方展示了如何通过公式恢复出错的输出 O6O_6O6​,以及如何通过 sanity neuron 恢复错误的权重和偏置。

工作流程总览:

1. Sanity Neurons 和 部分校验和 的计算:

在图2中,全连接层有7个输出神经元 O1,O2,…,O7。Maintaining Sanity 为这些输出神经元增加了 sanity neurons,其中包含:

  • 部分 sanity neurons:S0,S1,S2,用于计算部分校验和。

  • 总 sanity neuron:S,用于计算总校验和。

部分 sanity neurons 是如何工作的?

  • S0:负责监控输出 O1,O3,O5,O7,也就是那些索引的二进制形式的第0位是1的输出。

  • S1:负责监控输出 O2,O3,O6,O7,即那些二进制索引的第1位是1的输出。

  • S2:负责监控输出 O4,O5,O6,O7,即二进制索引的第2位是1的输出。

2. 校验和的检查和错误定位:

每个部分 sanity neuron Si的计算值与它负责的输出神经元的部分校验和 Pi​ 相加,应当为零。如果某个输出神经元 Ok 出现错误,则某些部分校验和 Pi​ 的值会不为零。

通过检查哪些部分校验和 P0,P1,P2 出现异常(即不为零),我们可以确定是哪一个输出神经元发生了错误。以下是确定错误的过程:

错误定位过程:

  1. 错误发生时的部分校验和值:

    • 每个部分校验和 Pi 对应某些输出神经元,如果校验和 Pi​ 不为零,表示这些输出神经元中某个发生了错误。

  2. 定位错误:

    • 比如,假设 P0 对应输出 O1,O3,O5,O7;如果 P0≠0,说明这些输出中有一个发生了错误。

    • 通过结合所有部分校验和 P0,P1,P2 的状态,可以唯一确定哪个输出神经元发生了错误。

示例:

假设输出 O6 发生了错误:

  • P0=0,因为 O6​ 不在 P0负责的范围内。

  • P1≠0,因为 O6​ 在 P1 负责的范围内。

  • P2≠0,因为 O6 也在 P2 负责的范围内。

通过查看 P1​ 和 P2​ 的状态,知道它们都不为零,而 P0=0,可以推断出索引为 110(即二进制形式)的输出神经元 O6​ 出现了错误。

  • 故障定位:如果检测到错误,Maintaining Sanity 会使用部分校验和来定位出错的具体输出。

    • 每个部分校验和会监控一部分输出。例如,图2中的部分校验和 P2 负责监控输出 O4、O5、O6、O7,而 P1 监控 O2、O3、O6、O7。
    • 如果某个部分校验和不为 0,意味着监控的这部分输出中有错误。
    • 图2中的示例显示了输出 O6​ 出现错误的情况。根据部分校验和 P2≠0和 P1≠0,可以定位到 O6是有问题的输出。

3. 错误修复:

  • 定位出错输出后,Maintaining Sanity 可以通过其他部分输出和 sanity output 来恢复这个出错的输出。
    • 例如,假设 O6​ 出错了,可以通过以下公式恢复: O6=−(O1+O2+O3+O4+O5+O7+S)
  • 除了输出恢复外,Maintaining Sanity 还可以通过检查 sanity neuron 的权重和偏置,来修复错误的权重和偏置。

Maintaining Sanity 的思路不仅适用于全连接层,还可以应用于卷积层。在卷积层中,通过增加 sanity filters 和 sanity biases,生成与原始特征图相加为零的 sanity feature maps 和校验和。

  • 和全连接层一样,Maintaining Sanity 可以检测卷积层中的权重、偏置和输出错误,并通过部分校验和定位并修复这些错误。

3.2 层输入冗余

在神经网络中,输入数据经过层与层之间的中间计算才能生成最终的输出。在这种情况下,中间层输入的独特性决定了它们与模型参数不同,因此不能采用模型参数的冗余保护方法。

  • ABFT 方法的一个局限性是它需要在输入中生成校验和,这在单输入环境中无法很好地应用。另外,通过扩展输入维度来增加冗余也不切实际,因为这会改变网络架构。

解决方案: 为了解决这些问题,Maintaining Sanity 使用了双模冗余(DMR)检查点与回滚机制来从输入故障中恢复。

1. 原始输入和复制输入:

  • 左侧部分展示了一个典型的 CNN 模型,其中包含卷积层、激活函数和池化层。原始输入经过这些层的处理,生成最终的输出。在此过程中,如果输入或中间层发生错误,将会导致模型输出错误。

  • 右侧部分是包含 Maintaing Sanity 技术的 CNN 模型。

2. 生成检查点和错误检测:

  • 生成初始检查点: 输入复制后,在进入第一个卷积层之前生成一个检查点。这个检查点保存中间输出数据,方便后续进行错误检测和回滚。

  • 卷积层和全连接层中的恢复机制: 每当卷积层或全连接层完成计算后,Maintaining Sanity 会生成另一个检查点,并对输出进行冗余检查。通过比较冗余输入和输出,可以检测到是否发生了故障。

  • 故障检测: 在每一层处理完后,Maintaining Sanity 会通过对比冗余输出,检测中间层的输入是否发生错误。如果发现错误,系统会回滚到前一个检查点并重新计算,确保最终输出的正确性。

3. 回滚机制:

  • 回滚机制: 当检测到错误时,Maintaining Sanity 可以回滚到上一个检查点,重新执行卷积或全连接层的计算,避免错误继续传播到后续层。

4. 双重冗余和检查点机制的优化:

  • 避免每层重复输入冗余: 在图中我们可以看到,Maintaining Sanity 采用了一种优化策略,即它只复制初始输入,而不是在每一层都生成新的冗余输入。这减少了系统的计算开销,同时仍然能够检测到故障。

  • 减少内存和计算开销: Maintaining Sanity 不仅在卷积层和全连接层中应用了冗余机制,还应用于其他层(如激活函数和池化层)

  • 简化输出检测: 通过与 3.1 节中的模型参数冗余结合,Maintaining Sanity 可以通过比较卷积层或全连接层的总校验和来简化冗余输出的对比。

实现细节:
  • 复制原始输入: Maintaining Sanity 仅复制了原始输入,而不是为每一层生成新的冗余输入(换句话说,只复制原始矩阵,然后用这两份数据一路检测下去)。

  • 输入冗余覆盖所有层: 在激活函数层和池化层中也保持输入冗余。

  • 输出对比的优化: 在卷积层或全连接层中,通过利用模型参数冗余的总校验和进行优化(因为对比俩矩阵太慢了),比较两个冗余输出的校验和来检测故障,而不是直接对比输出张量。

单点故障(系统中的某个地方错误,这个错误影响到后续运作)的消除:

这里的关键点是保存输入副本,然后在出错时可以回滚

保存输入副本:在进行计算之前,Maintaining Sanity 会先把这层的输入保存下来。

你可以把这看成是“保存进度”,就像玩游戏时存档一样。如果后面出现了错误,我们可以回到这个存档重新开始。

错误检测:计算完之后,系统会对输出进行检测,看看有没有出错。如果没有错误,一切正常,继续下一步。

重新执行:如果发现错误,系统不会直接用错的数据继续计算,而是会回滚到之前保存的“存档”,重新计算。这保证了即使某个地方出错了,也不会影响后面的计算

这个图是图4的宏观图,在这里不再详述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

D了一天bug忘了编译

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值