MERCURY: Accelerating DNN Training By Exploiting Input Similarity
动机与创新点
这篇论文的主要动机在于应对深度神经网络(DNN)训练过程中计算量过大的问题。DNN训练中包含大量的多维点积运算,尤其是当输入数据存在相似性时,这种计算可以优化。MERCURY提出了一种利用输入相似性的硬件加速方案,通过使用随机投影和量化(RPQ)生成输入向量的签名,存储在MCACHE中。当新的输入向量的签名与已存在的签名匹配时,可直接复用已有计算结果,从而减少重复运算。这一方法可以大幅减少计算时间,实验结果表明MERCURY在训练时平均提升了1.97倍的速度,同时保持与基线系统相似的准确性。
MERCURY的创新点在于首次在硬件中利用RPQ检测输入相似性,解决了传统方法在训练过程中难以实现相似性检测和数据复用的问题。该方法通过在硬件上执行RPQ,使签名生成过程与卷积操作的计算模式相同,允许系统在不改变数据流的情况下实现计算复用。此外,MERCURY引入MCACHE缓存和Hitmap位图结构,使数据流保持连续性,确保计算过程不间断。此外,MERCURY还动态调整签名长度和相似性检测,以平衡性能和准确性,适应模型训练的不同阶段。这种设计为DNN训练中的输入相似性检测提供了一种可扩展的硬件实现,有效提升了训练效率。
如何实现输入相似性判断?
在MERCURY系统中,实现新输入向量与已存在向量的匹配是通过“随机投影与量化”(Random Projection with Quantization, RPQ)技术进行的。具体来说,该方法将输入向量转换为称为“签名”(Signature)的比特序列,随后在硬件加速器中进行高效匹配。以下是实现过程的关键步骤:
- 签名生成:每个输入向量通过RPQ转换成一个唯一的签名。RPQ通过将输入向量与一个随机投影矩阵相乘,生成一个低维向量。然后,对该低维向量进行量化操作,通常采用基于符号位的量化方式。如果低维向量的元素为正则量化为1,否则为0,最终得到一个比特序列,作为该输入向量的签名。
- 签名缓存(MCACHE):生成的签名存储在一个名为MCACHE的缓存中,并与相应的计算结果关联。如果一个新输入向量生成的签名与MCACHE中已存在的签名匹配,则意味着这两个向量在输入空间中具有高度相似性,MERCURY系统可以直接复用已有的计算结果,而无需重新计算点积。
- 位图(Hitmap)和匹配检测:MERCURY通过位图(Hitmap)快速检测签名是否在MCACHE中存在匹配。若新签名在MCACHE中有匹配条目,则命中位图中的相应位置(即“命中”);若无匹配,则标记为“未命中”,并执行完整计算后将结果存储在MCACHE中,供后续相似向量复用。
- 动态调整签名长度:随着训练的进展,模型对输入相似性的敏感度可能变化。MERCURY系统会根据计算复用的有效性动态调整签名的长度,以保持在不同训练阶段的精确性和效率平衡。
如何理解位图匹配检测
在MERCURY系统中,位图(Hitmap)用于高效检测新输入向量与已存在向量之间的相似性匹配。具体来说,位图的作用是跟踪缓存中哪些签名已经有对应的计算结果,以便在新的输入签名到达时快速判断是否可以复用计算结果。以下是理解位图匹配检测的关键点:
- 位图结构:位图是一个简单的二进制数组,每一位(bit)对应MCACHE缓存中的一个签名条目。位图中的每个位可以表示为“命中”(hit)或“未命中”(miss),表明是否存在一个匹配的签名和计算结果。
- 检测过程:当新的输入向量生成一个签名时,系统会先在位图中查看是否存在对应的“命中”标记。具体操作为:系统将新签名映射到MCACHE中的一个位置(通过哈希或索引计算),并查找位图中对应的位置位是否为“1”(命中)还是“0”(未命中)。
o 如果对应位置的位图值为“1”(命中),则表示MCACHE中已有相似的签名和计算结果。系统可以直接复用已存储的计算结果,而不需要再次执行该输入的计算。
o 如果位图中的值为“0”(未命中),说明MCACHE中没有相同的签名。此时,系统会继续进行计算,并将新计算结果和签名存储在MCACHE中,同时更新位图的对应位置为“1”。 - 缓存更新与数据流保持:在训练过程中,输入数据的流动和位图的更新是动态进行的。系统会在MCACHE中增加新的签名,并在位图中进行同步标记。这样,即使出现计算复用情况,系统的数据流依然保持连续性。
- 减少计算开销:位图的设计是为了在硬件上实现高效的匹配检测,使得签名复用过程简单且迅速。通过这种方式,MERCURY能够在保持计算效率的同时,最大限度地减少冗余计算,提高系统性能。
案例说明
输入向量生成签名:
假设我们有一个输入向量 V1,通过RPQ(随机投影和量化)算法,生成一个签名 S1。
这个签名 S1 是一串比特,比如 10101,并表示了 V1 的特征。
MCACHE 和位图设置:
现在,S1 被存入 MCACHE 的第一个位置,同时位图的第一个位置被标记为“1”(命中),表示已经在缓存中有这个签名和对应的计算结果。
假设 MCACHE 和位图的结构如下:
arduino
复制代码
MCACHE: [ S1, - , - , ... ] // 初始状态只有 S1
位图: [ 1 , 0 , 0 , ... ] // 第一个位置为1,表示 S1 已存入
新输入的到来:
过了一段时间,又来了一个输入向量 V2,我们对 V2 生成签名,得到 S2。
假设 S2 恰好和 S1 一样(即 S2 = 10101),那么 V2 和 V1 具有相似性,可以复用计算结果。
位图检测:
系统会查看位图中第一个位置,因为 S2 映射到与 S1 相同的位置。
位图中的第一个位置为“1”,这表示 S1 的计算结果已经在缓存中存在。
因此,系统会从 MCACHE 中读取 S1 的计算结果,将其直接应用于 V2,无需重新计算。
结果复用:
MERCURY 利用位图的命中标记,跳过了 V2 的计算步骤,直接复用了 S1 的结果。
这大大减少了计算量,提高了效率。
另一个示例(未命中情况):
假设有另一个输入向量 V3,生成的签名为 S3 = 11011。S3 没有对应的位图位置值为“1”的条目(即未命中)。此时:
系统会继续对 V3 进行完整的计算,并将 S3 及其结果存入 MCACHE 中。
同时,位图中 S3 对应的位置会更新为“1”。