前言

本文以最常见的模型 Bi-LSTM-CRF 为例,总结了在实践工作中能有用提高在 CPU/GPU 上的推理速度的若干方法,包含优化模型结构优化超参数,运用 onnx 结构等。当然如果你有充足的 GPU ,结合以上方法提高推理速度的作用将更加震撼。

数据

本文运用的数据便是常见的 NER 数据,我这儿运用的是 BMEO 标示方法,如下列举一个样本作为说明:

华B_ORG 东M_ORG 师M_ORG 范M_ORG 大M_ORG 学E_ORG 位O 于O 上B_LOC 海E_LOC。

详细的标示方法标示规则可以依据自己的实践事务中的实体类型进行定义,这儿不做深入探讨,但是有个基本原则便是标示的实体是符合实践事务意义的内容。

优化模型结构

关于 Bi-LSTM-CRF 这一模型的详细细节,我这儿默认都是知道的,所以不再赘述。咱们平时在运用模型的时分有个误区觉得 LSTM 层堆叠的越多作用越好,其实不然,如果是关于入门级的 NER 使命,只需求一个 Bi-LSTM 就足够可以把实体识别出来,完全没有必要堆叠多个 Bi-LSTM ,这样有点杀鸡用牛刀了,而且多层的模型参数量会激增,这也会拖垮终究的练习和推理速度。

多种战略提高线上 tensorflow 模型推理速度

关于其他的模型来说,也是同样的道理,优化模型结构,砍掉过量的层和参数,可能会取到意想不到的推理作用和速度。

优化超参数

在我看来三个最重要的超参数便是 batch_sizehidden_sizeembedding_dim ,这三个别离表明批处理样本数,隐层状态维度,嵌入纬度。这儿的常见误区和模型参数量相同,会以为越大作用越好。其实不然,太大的超参数也会拖垮终究的练习和推理速度。正常在模型推理过程中,耗时基本是和这三个参数呈正相关关系。常见的参数设置可以按照以下的推荐值来进行即可:

batch_size:32、64
hidden_size:128、256
embedding_dim:128、256

关于简略的 NER 使命来说,这些超参数的设置现已足够运用了,如果是比较复杂的使命,那就需求恰当调大 hidden_sizeembedding_dim,最好以 2 的 N 次方为值。batch_size 如果没有特别事务要求,按照推荐值即可。

另外,如果你运用的是 tensorflow2.x 结构,可以运用 Keras Tuner 说到的 API ,不只可以选择最优的模型超参数,还能选择最优的算法超参数。

onnx

ONNX(Open Neural Network Exchange)是一个用于表明深度学习模型的开放式标准。ONNX 的规划方针是使得在不同结构中练习的模型可以轻松地在其他结构中布置和运转。ONNX 支持在不同的布置环境中(例如移动设备、边缘计算、云端服务器)更加灵敏地运用深度学习模型。

多种战略提高线上 tensorflow 模型推理速度

ONNX 在模型布置的时分会对模型做许多优化战略,如图结构优化、节点通讯优化、量化、硬件加快、多线程和并行计算等。onnxruntime 是一个对 ONNX 模型提供推理加快的 python 库,支持 CPU 和 GPU 加快,GPU 加快版别为onnxruntime-gpu,默认版别为 CPU 加快。装置也很简略,直接运用 pip 装置即可。另外装置 tf2onnx 需求将 tensorflow2.x 模型转换为 onnx 模型

下面以本文中运用的模型来进行转化,需求注意的有两点,第一是要有现已练习并保存好的 h5 模型,第二是明确指定模型的输入结构,代码中的是 (None, config['max_len']) ,意思是输入的 batch_size 可所以任意数量,输入的序列长度config['max_len'] , 详细代码如下:

def tensorflow2onnx():
    model = NerModel()
    model.build((None, config['max_len']))
    model.load_weights(best.h5)
    input_signature = (tf.TensorSpec((None, config['max_len']), tf.int32, name="input"),)
    onnx_model, _ = tf2onnx.convert.from_keras(model, input_signature=input_signature,)
    onnx.save(onnx_model, 'best.onnx')

保存好 onnx 模型之后,咱们运用 onnx 模型进行 CPU 推理。只需求简略的几步即可完成推理使命, results_ort 便是推理成果 logits ,详细代码如下:

def inference():
    x_train, y_train, x_test, y_test = getData()
    sess = ort.InferenceSession(config['onnxPath'], providers=['CPUExecutionProvider'])   
    results_ort = sess.run(["output_1"], {'input': x_train})[0]

作用比照

在归纳运用以上的三种,将之前的模型结构进行减小到一层的 Bi-LSTM ,并且将超参数进行恰当的削减到都为 256 ,然后运用 onnx 加快推理,在 CPU 上面终究从推理速度 278 ms ,下降到 29 ms ,提高了 9 倍的推理速度。

多种战略提高线上 tensorflow 模型推理速度

多种战略提高线上 tensorflow 模型推理速度

如果有 GPU ,咱们可以装置 onnxruntime-gpu (如果装置时分和 onnxruntime 有冲突,可以先卸载 onnxruntime ),然后将上面的代码改为如下即可,终究的推理时刻进一步削减了一半:

sess = ort.InferenceSession(config['onnxPath'], providers=['CUDAExecutionProvider'])

多种战略提高线上 tensorflow 模型推理速度

定论

终究咱们从 278 ms 下降到 15 ms ,完成了 18 倍的推理提速,综上可以看出本文介绍的几种战略的归纳运用确实可以加快推理速度,也说明了工业上进行模型布置优化是很有必要的。

参考