2024 年 4 月 9 日 — 作者:Alan Kelly,软件工程师我们很高兴地宣布,XNNPack 的全连接和二维卷积运算符现在支持动态范围量化。XNNPack 是 TensorFlow Lite 的 CPU 后端,CPU 为 ML 推理提供了最广泛的覆盖范围,并且仍然是 TensorFlow Lite 的默认目标。因此,提高 CPU 推理性能是重中之重。我们**将**TensorFlow Lite 的 XNNPack 后端的推理性能**提高了四倍**,…
我们很高兴地宣布,XNNPack 的全连接和二维卷积运算符现在支持动态范围量化。XNNPack 是 TensorFlow Lite 的 CPU 后端,CPU 为 ML 推理提供了最广泛的覆盖范围,并且仍然是 TensorFlow Lite 的默认目标。因此,提高 CPU 推理性能是重中之重。通过为全连接和卷积运算符添加对动态范围量化的支持,我们**将**TensorFlow Lite 的 XNNPack 后端的推理性能**提高了四倍**,与单精度基线相比。这意味着更多由 AI 提供支持的功能可以部署到旧的和低端设备上。
以前,XNNPack 为用户提供了两种选择:全整数量化,其中权重和激活存储为带符号的 8 位整数,或者半精度(fp16)或单精度(fp32)浮点推理。在本文中,我们将展示动态范围量化的优势。
与全量化模型类似,动态量化模型在模型转换期间将全连接和卷积运算符的权重量化为 8 位整数。所有其他张量都没有量化,它们保持为 float32 张量。在模型推理期间,浮点层激活在传递到全连接和卷积运算符之前被转换为 8 位整数。每个激活张量行的量化参数(零点和比例)是根据观察到的激活范围动态计算的。由于激活充分利用了 8 个量化位,因此最大程度地提高了量化过程的准确性。在全量化模型中,这些参数在模型转换期间是固定的,基于使用代表性数据集观察到的激活值的范围。全量化和动态范围量化之间的第二个区别是,全连接和卷积运算符的输出是 32 位浮点格式,而不是全量化运算符的 8 位整数。使用动态范围量化,我们获得了全量化的大部分性能提升,但整体精度更高。
传统上,此类模型的推理是使用 TensorFlow Lite 的原生运算符完成的。现在,动态量化模型可以从 XNNPack 对全连接和二维卷积运算符的高度优化的每个架构实现中受益。这些运算符针对 XNNPack 支持的所有架构进行了优化(ARM、ARM64、x86 SSE/AVX/AVX512 和 WebAssembly),包括最新的 ArmV9 处理器,例如 Pixel 8 的 Tensor G3 CPU 或 OnePlus 11 的 SnapDragon 8 Gen 2 CPU。
使用动态范围量化需要两个步骤。首先,必须从 TensorFlow 转换模型,使其支持动态范围量化。已经使用动态范围量化转换的现有模型无需重新转换。通过启用 converter.optimizations = [tf.lite.Optimize.DEFAULT]
转换器标志,可以在模型转换期间启用动态范围量化。与全整数量化不同,不需要代表性数据集,不支持的运算符也不会阻止转换成功。因此,对于非专家用户而言,动态范围量化比全整数量化更易于访问。
从 TensorFlow 2.17 开始,动态量化的 XNNPack 推理将在预构建二进制文件中默认启用。如果您想尽快使用它,可以使用夜间 TensorFlow 构建。
在我们之前的文章中,我们介绍了使用半精度推理获得的令人印象深刻的性能提升。现在可以在 XNNPack 中结合使用半精度和动态范围量化,以在具有硬件 fp16 支持的设备上获得最佳的设备上 CPU 推理性能(如今出售的大多数手机都具有这种支持)。全连接和二维卷积运算符可以输出 fp16 数据而不是 fp32。于 2018 年发布的 Pixel 3 是第一款支持 fp16 的 Pixel 机型。与 fp32 相比,fp16 使用的一半位来存储浮点值,这意味着由于尾数明显较短(10 位对 23 位),每个值的相对精度会降低。并非所有模型都支持 fp16 推理,但是如果模型支持它,由于 CPU 可以每条指令处理两倍的数据,因此向量化浮点运算符的计算成本可以减半。具有计算密集型浮点运算符(例如批矩阵乘法和 Softmax)的动态量化模型也可以从 fp16 推理中受益。
下面,我们展示了对四个公开模型的基准测试,这些模型涵盖了常见的计算机视觉任务
每种模型都尽可能地转换了三次:全浮点、全 8 位有符号整数量化和动态范围量化。由于不支持的运算符,Stable Diffusion 的扩散模型无法使用全整数量化进行转换。下面显示了与使用 TFLite 内核的原始 float32 模型相比的加速情况。
下面显示了与 TFLite 的动态量化的全连接和卷积运算符相比的加速情况。只需使用最新版本的 TensorFlow Lite,您就可以从这些加速中受益。
我们可以清楚地看到,动态范围量化与全整数量化的性能相当,在某些情况下甚至可以超过全整数量化的性能。Stable Diffusion 的扩散模型运行速度比原始 float32 模型快 6.2 倍!这对设备上性能来说是一个巨大的变化。
我们预计全整数量化应该比动态范围量化更快,因为所有运算都是使用整数运算计算的。此外,动态范围量化还需要额外的开销,即将浮点激活转换为量化的 8 位整数。令人惊讶的是,在测试的三个模型中的两个模型中,情况并非如此。使用TFLite 的分析器分析模型,解开了谜团。这些模型运行速度较慢是由于量化伪影的组合造成的,当输入和输出比例的比率落在某个范围内时,量化算术效率更高,以及 XNNPack 中缺少的操作支持。这些量化参数在模型转换期间根据提供的代表性数据集确定。由于比例比率超出了最佳范围,因此必须采用次优路径,导致性能下降。
最后,我们证明了使用混合精度推理时模型精度基本保持不变,我们将使用 fp32 激活的动态量化的 Stable Diffusion 模型生成的图像与使用 fp16 激活生成的图像进行比较,随机数生成器使用相同的数字进行播种,以验证将 fp16 激活用于扩散模型不会影响生成的图像的质量。
使用 fp16 推理生成的图像(左)和 fp32 推理生成的图像(右) |
两种生成的图像都是可爱的猫,与给定的提示相符。这些图像无法区分,这强烈表明扩散模型适合使用 fp16 推理。当然,对于所有神经网络而言,任何量化策略都应该使用大型验证数据集进行验证,而不仅仅是一个单一的测试。
全整数量化很困难,转换模型很困难,容易出错,而且无法保证精度。代表性数据集必须真正具有代表性,才能最大限度地减少量化误差。动态范围量化在全整数量化和 fp32 推理之间提供了一种折衷方案:模型的大小与全量化模型相似,性能提升通常也相似,有时甚至超过了全量化模型。使用 Stable Diffusion,我们展示了动态范围量化和 fp16 推理可以结合使用,从而带来重大的性能改进。XNNPack 的动态范围量化现在为Gemini、Google Meet 和 Chrome OS 音频降噪提供支持,并将在今年的许多其他产品中推出。现在,我们开源用户可以使用相同的技术,因此您可以使用上面链接的模型并按照“如何使用它”部分中的说明进行尝试!
我们要感谢 Frank Barchard 和 Quentin Khan 对 TensorFlow Lite 和 XNNPack 中的动态范围量化推理做出的贡献。
2024 年 4 月 9 日 — 作者:Alan Kelly,软件工程师我们很高兴地宣布,XNNPack 的全连接和二维卷积运算符现在支持动态范围量化。XNNPack 是 TensorFlow Lite 的 CPU 后端,CPU 提供了最广泛的 ML 推理覆盖范围,并且仍然是 TensorFlow Lite 的默认目标。因此,提高 CPU 推理性能是重中之重。我们将推理速度提升了四倍…