使用TensorRT加速GPU上的TensorFlow推理(翻译)

本文翻译于博客Speed up TensorFlow Inference on GPUs with TensorRT,这篇博客介绍了如何使用TensorRT加速TensorFlow模型的推理速度,作者为:

  • Siddharth Sharma — Technical Product Marketing Manager, NVidia
  • Sami Kama — Deep Learning Developer Technologist, NVidia
  • Julie Bernauer — Pursuit Engineering Solution Architect, NVidia
  • Laurence Moroney — Developer Advocate, Google

概述

TensorFlow是当今最受欢迎的深度学习框架,在全球有着数十万名用户。NVIDIA®TensorRT™是一个深度学习平台,用于优化神经网络模型,加快数据中心,嵌入式芯片和汽车设备中运行的GPU加速平台的推理速度。我们对TensorFlow与TensorRT的集成感到兴奋,这似乎很自然,特别是NVIDIA提供的平台非常适合用于加速TensorFlow。这使得TensorFlow用户在使用TensorRT时具有极高的推理性能和近乎透明的工作流程。


图1 tensor通过优化训练好的神经网络模型来生成部署就绪的推理引擎

TensorRT对神经网络图执行几项重要的转换和优化(图2)。首先,消除具有未使用的输出层以避免不必要的计算。接下来,在可能的情况下,对卷积,偏置和ReLU层进行融合以形成单个层。另一种转换是水平层融合或层聚合,以及聚合层到它们各自输出的划分。水平层融合通过对使用相同源tensor的层进行组合,并应用具有相似参数的相同操作来提高性能。请注意,这些图优化操作不会更改计算图中的基础计算:相反,它们会对计算图进行重新构建,使其可以更快,更有效地进行推理

图2 (a)一个具有多个卷积层和激活层的卷积神经网络。(b)TensorRT通过融合垂直和水平层以及层消除操作简化了GoogLeNet Inception模块图,减少了计算和内存开销。

如果您已经将TensorRT与TensorFlow模型一起使用,那么您应该知道,在过去的版本中,使用TensorRT优化需要导出训练好的TensorFlow计算图。您还需要手动导入某些不受支持的TensorFlow图层,然后在TensorRT中运行完整图形。在大多数情况下,您再也不用这样做了。在新的工作流中,您可以通过使用简单的API在TensorFlow中应用TensorRT强大的FP16和INT8优化。现有的TensorFlow程序只需要几行新代码就可以使用这些优化。

在ResNet-50的基准测试钟,TensorRT将TensorFlow推断速度提高了8倍。这些性能改进仅需几行额外代码,并可与TensorFlow 1.7及更高版本一起使用。在本文中,我们将介绍新的工作流程和API,以帮助您开始使用它。

在TensorFlow graphs中应用tensorRT优化

如图3所示,在TensorFlow推理工作流中加入tensorRT优化需要一个额外操作,在这个额外操作(使用绿色进行高亮)中,TensorRT根据frozen TensorFlow graph构建优化后的推理图。


图3 在TensorFlow中使用TensorRT时的工作流程图

为了完成优化操作,TensorRT对frozen TensorFlow graph进行解析,选出图中可以进行优化的子图。之后,TensorRT对子图进行优化,并且在原TensorFlow graph中将需要优化的子图替换为TensorRT节点,图中其余部分保持不变。在推理过程中,TensorFlow将调用TensorRT来执行优化后的TensorRT节点。通过这种方法,开发人员可以继续使用灵活的TensorFlow功能集和TensorRT优化。

举个栗子🌰,假设有个计算图由A,B,C三个子图组成,TensorRT对子图B进行了优化,之后将子图B替换为TensorRT节点。在推理过程中,TensorFlow执行了子图A,之后调用TensorFlow执行了子图B,最后使用TensorFlow执行了子图C。

TensorRT优化了TensorFlow图中可能的最大子图。子图中的计算越多,从TensorRT获得的收益越大。您希望对大部分计算图进行优化,并使用最少数量的TensorRT节点替换,以获得最佳性能。根据计算图中的操作,优化后的计算图可能包含多个TensorRT节点。使用TensorFlow API,您可以指定子图中节点的最小数量,以便将其转换为TensorRT节点。任何小于指定设定节点数的子图都不会转换为TensorRT引擎,即使其与TensorRT兼容。这对于包含由不兼容节点分隔的小兼容子图的模型非常有用,从而导致微小的TensorRT引擎。

让我们看看如何更详细地实现工作流。

使用新的 TensorFlow APIs

新的TensorFlow API支持使用几行新代码直接实现TensorRT优化。首先,指定分配给TensorFlow的GPU内存比例,剩余内存将用于TensorRT引擎。这可以通过使用GPUOptions函数的新参数per_process_gpu_memory_fraction来完成。需要在TensorFlow-TensorRT进程第一次启动时设置此参数。例如,将per_process_gpu_memory_fraction设置为0.67会为TensorFlow分配67%的GPU内存,为TensorRT引擎分配剩余三分之一的GPU内存。

gpu_options = tf.GPUOptions(per_process_gpu_memory_fraction = 
                0 < memory_for_TensorFlow < 1)

下一步是使用tensorRT对TensorFlow计算图进行分析,进行优化,并将需要优化的子图替换为tensotRT节点。您可以使用新函数create_inference_graph来对frozen TensorFlow graph进行tensorRT优化,这个函数的输入为frozen TensorFlow graph,返回含有tensorRT节点的优化图,如下面的代码片段所示:

trt_graph = trt.create_inference_graph(
   input_graph_def = frozen_graph_def,
   outputs = output_node_name,
   max_batch_size=batch_size,
   max_workspace_size_bytes=workspace_size,
   precision_mode=precision,
   minimum_segment_size=3)

让我们看看这个函数的参数:

  • input_graph_def:frozen TensorFlow graph
  • outputs:输出节点的tensor name,例如:[“resnet_v1_50/predictions/Reshape_1”]
  • max_batch_size:整数,输入batch的大小,例如:16
  • max_workspace_size_bytes:整数,tensorRT可用的最大内存
  • precision_mode:string,可选值为:“FP32”, “FP16” 或者 “INT8”
  • minimum_segment_size:整数(默认为3),控制要创建的TensorRT引擎的子图中的最小节点数,如果子图中的节点数小于这个值,那么这个子图将不会被替换为tensorRT节点

per_process_gpu_memory_fractionper_process_gpu_memory_fraction两个参数应该被一起使用,对TensorFlow和TensorRT的内存分配进行控制,进而获得应用程序的最佳性能。为了最大化推理性能,您可以分配给tensorRT多一点内存,将剩余的内存分配给TensorFlow。例如:在一块内存为12G的GPU中,如果您将per_process_gpu_memory_fraction设置为( 12–4 ) / 12 = 0.67,那么参数max_workspace_size_bytes应设置为4000000000,为TensorRT引擎收集大约4G的内存。同样,最佳的内存分割方案是依赖于应用程序的,可能需要一些迭代来寻找最佳划分。

使用TensorBoard对优化后的计算图进行可视化

在对 ResNet-50进行TensorRT优化之后,TensorBoard可以使我们清楚地看到ResNet-50计算图中的变化。如图4所示,TensorRT几乎优化了整张计算图,并使用名称为“my_trt_op0”(使用红色进行高亮)的单个节点进行替换。根据模型中的层和操作,由于优化操作,TensorRT节点替换掉了图中的一部分。命名为“ conv1”的操作其实不是真正的卷积层,只是将feature map的格式由NHWC转换为NCHW(注:NCHW分别对应batch_size, channel, height, width)。

图4 (a)经过TensorBoard可视化之后的ResNet-50 (b)经过TensorRT优化之后的ResNet-50,其中的子图被替换为TensorRT节点

在Volta GPU上使用Tensor Cores

与FP32或FP64相比,使用半精度(也被称为FP16)可以降低神经网络的内存使用。FP16支持部署更大的网络,同时比FP32或FP64花费更少的时间。NVIDIA的Volta架构硬件采用了称为Tensor Cores的矩阵数学加速器。Tensor Cores提供4x4x4矩阵处理阵列,用于执行操作D = A * B + C,其中A, B, C and D为4×4的矩阵。图5展示了工作过程。矩阵乘法输入A和B是FP16矩阵,而累加矩阵C和D可以是FP16或FP32矩阵。


图5 Tensor Cores上的矩阵处理操作

当使用FP16 math检测到推理时,TensorRT会自动使用硬件Tensor Cores。 Tensor Cores在NVIDIA Tesla V100上的峰值性能比双精度(FP64)快一个数量级,而吞吐量比单精度(FP32)提高了4倍。可以在函数create_inference_graph中,将precision_mode设置为“ FP16”启用半精度计算,如下所示。getNetwork()用于从protobuf文件中读出frozen network,返回数据结构为tf.GraphDef()的神经网络。

trt_graph = trt.create_inference_graph(
                getNetwork(network_file_name), 
                outputs,
                max_batch_size=batch_size, 
                max_workspace_size_bytes=workspace_size, 
                precision_mode=”FP16")

图6所示,在相同的硬件环境,小于7ms延时的情况下,应用基于NVIDIA Volta Tensor Cores的TensorFlow-TensorRT集成后的ResNet-50比仅使用TensorFlow的推理速度快8倍。


图6 ResNet-50推理吞吐量性能

使用INT8的精度进行推理

使用INT8精度执行推理进一步提高了计算速度并降低了对带宽的要求。减小的动态范围给表示神经网络的权重和激活带来挑战。

各个数据类型的动态范围

TensorRT可以将以单精度(FP32)或者半精度(FP16)训练的模型转化为以INT8量化部署的模型,同时可以最小化准确率损失。使用TensorRT优化对模型进行INT8量化之前需要对精度为FP32的模型进行校验。在创建TensorRT优化推理图之前,工作流程将包含校准步骤(Create Calibration Graph and Calibrate),如图7所示:
图7 包含INT8推理的工作流程

首先使用create_inference_graph函数,将参数precision_mode设置为INT8来校准模型,此功能的输出是一个frozen TensorFlow graph,可以进行校准。

trt_graph = trt.create_inference_graph(
                getNetwork(network_file_name), 
                outputs,
                max_batch_size=batch_size,
                max_workspace_size_bytes=workspace_size, 
                precision_mode=”INT8")

现在使用校准数据运行校准图。 TensorRT使用节点数据的分布来量化节点的权重。您必须使用与实际问题数据集分布相同或者类似的校准数据。我们建议在首次使用INT8校准的模型时,检查推理过程中的误差累积。minimum_segment_size可以帮助调整优化来最小化量化误差。通过使用minimum_segment_size,您可以更改优化的INT8引擎中的最小节点数,进而更改最终优化计算图以微调结果准确性。

在校验数据上执行完计算图之后,使用函数calib_graph_to_infer_graph对检验之后的计算图应用TensorRT优化,这个函数同样会将TensorFlow中的子图替换为INT8优化后的TensorRT节点。函数的输出为可以用于推理的frozen TensorFlow graph。

trt_graph=trt.calib_graph_to_infer_graph(calibGraph)

在使用这两个命令之后,就可以以INT8的精度对您的模型进行推理了。

如果您想查看此处显示的示例,请查看运行这些示例所需的代码:
https://developer.download.nvidia.com/devblogs/tftrt_sample.tar.xz

可用性

我们希望通过将TensorRT与TensorFlow集成,进而在使用NVIDIA GPU时可以获得最高性能,同时保持TensorFlow的易用性和灵活性。 NVIDIA将继续与Google TensorFlow团队密切合作,进一步增强这些集成功能。随着TensorRT支持更多网络,开发人员将自动受益于更新,而无需更改现有代码。

查找有关今天如何开始的说明:
https://www.tensorflow.org/install/install_linux

在不久的将来,我们希望标准的pip安装过程也能正常运行。敬请关注!

我们相信,在使用GPU时,您会看到将TensorRT与TensorFlow集成的实质性好处。您可以在以下位置找到有关TensorFlow的更多信息:https://www.tensorflow.org/.

有关TensorRT的更多信息,请访问NVIDIA的TensorRT页面https://developer.nvidia.com/tensorrt.

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 194,457评论 5 459
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 81,837评论 2 371
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 141,696评论 0 319
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 52,183评论 1 263
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 61,057评论 4 355
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 46,105评论 1 272
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 36,520评论 3 381
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 35,211评论 0 253
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 39,482评论 1 290
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 34,574评论 2 309
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 36,353评论 1 326
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 32,213评论 3 312
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 37,576评论 3 298
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 28,897评论 0 17
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 30,174评论 1 250
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 41,489评论 2 341
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 40,683评论 2 335

推荐阅读更多精彩内容