近年来,基于Transformer 架构的模型一直是推动NLP在研究和工业上取得突破的动力。BERT、XLNET、GPT或XLM是一些改进了技术水平的模型,它们达到了GLUE等流行基准的顶级水平。

这些进步带来了高昂的计算成本,大多数基于Transformer的模型都是庞大的,用于训练的参数数量和数据都在不断增加。最初的BERT模型已经有1.1亿个参数,而最后的GPT-3有1750亿个参数,这是在两年的研究中惊人的增长了1700倍。

这些庞大的模型通常需要数百个GPU进行数天的训练才能发挥作用,幸运的是,多亏了迁移学习,我们可以下载预训练的模型,并在我们自己的更小的数据集上快速地以低成本调整它们。

也就是说,一旦训练完成,我们手中有一个庞大的模型,如果想要将其部署到生产中与其他模型相比,推理需要相对较长的时间,而且它可能太慢,无法达到需要的吞吐量。

虽然您可以投资更快的硬件或使用更多的服务器来完成工作,但有还有其他的方法来减少模型的推理时间:

模型修剪:减少层数,嵌入的尺寸或隐藏层中的单位数。

量化:不使用32位浮点数(FP32)进行加权,而是使用半精度(FP16)甚至8位整数。

将模型从本机Pytorch / Tensorflow导出到适当的格式或推理引擎(Torchscript / ONNX / TensorRT ...)

第一种和第二种方法通常意味着对模型进行重新训练,而后两种方法则是在训练后完成的,本质上与您的特定任务无关。

如果推理速度对用例极为重要,那么很可能需要尝试所有这些方法以生成可靠且快速的模型。但是,在大多数情况下,将模型导出为适当的格式/框架并进行批量预测将为您提供更快的结果,而所需的工作量却最少。在这里,我们将重点介绍这种方法,以了解其对模型吞吐量的影响。

我们将通过一些实验探讨更改模型格式和批处理的影响:

  1. 使用常规的Pytorch CPU / GPU的基准
  2. 将Pytorch模型导出到Torchscript CPU / GPU
  3. 将Pytorch模型转换为ONNX CPU / GPU

所有实验均以1/2/4/8/16/32/64批次运行

截至本文发布时,由于缺乏Pytorch嵌入所使用的int64的支持,因此尚无法将Transformer模型直接从Pytorch导出到TensorRT,因此我们暂时将其跳过。

我们将对Roberta的法语变体camemBERT(〜100M参数)执行句子分类。由于绝大多数计算是在Transformer模型内部完成的,因此无论您执行什么任务,都应得到相似的结果。

首先,我们将快速了解如何将Pytorch模型导出为相关的格式/框架,如果您不想阅读代码,则可以跳至结果部分。

如何导出模型
常规pytorch

尽管有不同的处理方法,但在Pytorch中保存和加载模型非常简单。为了进行推理,官方文档建议保存模型的“ state_dict”,这是一个包含模型可学习参数的python字典。这比保存整个模型进行更轻巧。