『GPU』降低预测过程计算成本,这些NLP模型压缩方法要知道


『GPU』降低预测过程计算成本,这些NLP模型压缩方法要知道
本文插图
『GPU』降低预测过程计算成本,这些NLP模型压缩方法要知道
本文插图
编译 | 凯隐
出品 | AI科技大本营(ID:rgznai100)
近年来 , 基于谷歌Transformer的语言模型在神经机器翻译 , 自然语言推理和其他自然语言理解任务上取得了长足进展 。
通过多种语言模型的平均损失进行自我监督预训练 , 使得在大范围的语料库上训练的模型可以在许多任务中提高下游性能 。 然而 , 大量的参数和计算量仍然是阻碍BERT和其衍生模型部署的难点 。
值得庆幸的是 , 在过去的两年里 , 我们已经看到了各种各样的技术 , 可以缩短模型在进行实际预测时消耗的时间 。 因此 , 这篇文章主要着眼于在基本模型预训练后可以用于降低预测过程计算成本的方法 , 主要包含以下方法:

  • 数值精度约简:通过降低计算过程中使用的浮点数精度(浮点约简)和量化 , 来加速计算 。
  • 计算融合:在计算图中选择节点并进行合并的技巧 。
  • 网络修剪: 识别和删除网络中不重要的部分 。
  • 知识提炼: 训练更小的 , 效率更高的模型来模仿表现力更强 , 同时计算成本更高的大模型 。
  • 模块替换:通过替换部分模块来降低模型的深度和复杂度 。

『GPU』降低预测过程计算成本,这些NLP模型压缩方法要知道
本文插图
数值精度约简
数值精度约简可能是为模型带来预测加速最通用的方法 。 在过去几年GPU对16位浮点操作的支持性很差 , 这意味着降低权重和激活值的精度往往不会带来加速 , 甚至造成减速 。 英伟达(Nvidia)Volta和图灵张量核架构的引入在一定程度上解决了这个问题 , 让GPU能够更好的实现高效的16位浮点精度运算 。
1、浮点数的表示
浮点类型数据主要存储三种类型的数值信息:符号 , 指数 , 分数 。 传统的32位浮点表示法分别用8位和23位来表示指数和分数(剩下一位应该表示正负) , 而传统的16位表示法(用于NVIDIA硬件的格式)将32位表示法中的指数和分数部分大致减半 。 相对于GPU而言 , TPU(张量处理单元)则使用一种称为bfloat16的变体 , 它可以选择将一些位从分数移动到指数 , 即牺牲一定的精度来换取表示更大范围的值的能力 。
『GPU』降低预测过程计算成本,这些NLP模型压缩方法要知道
本文插图
三种不同的浮点数表示方法
Transformer网络的大部分结构都可以直接转换为16位浮点数的权重和激活值 , 且不会带来计算准确率的下降 。 而网络的一小部分 , 特别是softmax操作部分必须保留为32位浮点精度 。 这是因为大量的小数值(我们的logits)累积起来就可能成为错误的来源 。 由于这样做同时使用了16位和32位精度的浮点数值 , 因此这种方法通常称为“混合精度” 。
低精度的数值表示主要可以从两方面实现加速:
(1)机器自带的半精度指令(速度更快)
(2)更大的batch size(得益于更紧凑的表示)
NVIDIA已经发布了一套相当广泛的与浮点精度降低相关的基准测试——实际上 , 这种方法可以使速度提高3倍 。
链接:https://github.com/NVIDIA/DeepLearningExamples
2、整型量化
32位浮点到8位整数型值的量化也能实现加速 , 但需要更细节的实现 。 特别的 , 为了确保8位整型的计算结果与32位浮点计算结果尽可能相同 , 还需要在训练后对输入进行校准 。
如果已经知道网络激活值可能所占用的范围 , 可以将该范围划分为256个离散块 , 并将每个块分配给一个整数 。 只要存储了比例因子和占用的范围 , 就可以使用整数近似来进行矩阵乘法 , 并将乘法输出恢复为浮点值 。


推荐阅读