基于自动驾驶车辆的NVIDIA-TensorRT推理实时优化
Optimizing NVIDIA TensorRT Conversion for Real-time Inference on Autonomous Vehicles
自动驾驶系统使用各种神经网络模型,这些模型需要在gpu上进行非常精确和高效的计算。Zoox是一家全新开发robotaxis的初创公司,利用NVIDIA DRIVE的高性能、节能计算。最近,Zoox在旧金山发布了一个小时的完全自主的游戏,详细展示了他们的人工智能堆栈。
与TensorFlow相比,NVIDIA TensorRT提供了显著的加速(fp32为2-6倍,Zoox网络为int8中为9-19倍),支持使用CUDA流的异步和并发推理能力。Zoox vision/lidar/radar/prediction算法严重依赖于深度神经网络,这些神经网络都运行在我们的车辆上的NVIDIA GPU上,并且大多与TensorRT一起部署。
TensorRT是一个用于高性能深度学习推理的SDK,它为深度学习推理应用程序提供低延迟和高吞吐量。
可以使用各种转换管道将模型转换为TensorRT引擎。例如,使用Caffe训练的模型可以使用Caffe解析器轻松地转换为TensorRT运行时。
然而,TensorFlow模型需要使用ONNX(开放式神经网络交换)转换为TensorRT引擎。TensorFlow也可用于其他培训工具。
在为所有这些深层神经网络部署和维护TensorRT引擎的过程中,我们发现了以下痛点:
ONNX和TensorRT只支持一组有限的TensorFlow操作。
内核大小和步幅的某些组合可能会对TensorRT产生副作用。
迁移到低精度推理或TensorRT升级可能会导致性能下降。
在Zoox,我们开发了一组工具来促进TensorRT引擎的部署、验证和维护,如图2所示。在下面的部分中,将详细介绍这些模块。
TensorRT conversion checker
TensorRT转换检查器的目标是帮助您在训练网络之前识别可能的转换失败。checker是轻量级的,设计上是最小的(在本文后面的代码示例中重点介绍)。在训练前,它在所构建的网络上触发一个TensorRT转换过程。我们只有在转换成功后才开始训练。
下面的代码示例显示了TensorRT转换检查器。要使用该插件,用户只需导入包,在网络构建期间注册输入/输出节点,然后在培训开始前触发转换检查。
import trt_checker
class Lenet5():
def network(self, X):
input = tf.identity(X, name = "input")
# Registers the input in the conversion checker.
trt_checker.register_input(input)
# Network definition.
…
# Output node.
output = tf.identity(logits, name="output")
# Registers the output node in the conversion checker.
trt_checker.register_output(output)
return output
def main():
…
# Checks if the model can be converted to trt.
conversion_result = trt_checker.check_conversion()
# Only train when trt conversion is successful.
if conversion_result:
accuracy = lenet_network.train()
Output deviation inspection
此插件的目标是在运行整个特定于模型的评估之前,报告转换后的TensorRT引擎的潜在精度回归。这个插件在转换后的TensorRT引擎和原始的TensorFlow图上运行推理,输入完全相同(由用户随机生成或指定)。然后报告输出偏差的分布,给开发人员一个潜在精度回归的预警。该模块是逐层检测模块的构建模块。
Figure 3. Output deviation inspection
Layer-by-layer inspection
The following code example shows the layer-by-layer inspection:
def layer_by_layer_analysis(graph, input_layer):
median_error = []
for layer in graph.layers():
errors = convert(graph, input=input_layer, output=layer)
median_error.append(median(errors))
plot(median_error)
如果观察到精度回归,我们希望找出TensorRT引擎中的哪一层或操作对回归有显著贡献。这促使我们开发了逐层检测模块。当被调用时,模块为每个中间操作运行一个转换作业,并报告由这个特定操作生成的中间值/最大值错误(如图4所示)。本模块在研究不同版本的TensorRT中观察到的不同行为时非常有用。
Latency flame graph
Figure 4. Example regression observed in semantic segmentation when upgrading from TensorRT 5.1.5 to TensorRT 7.0.
图4显示了这种回归的一个例子,在这个例子中,我们观察到语义分段输出有轻微的回归。我们对TensorRT 5.1引擎和TensorRT 7.0引擎进行了逐层检查,然后绘制了每层的中值误差。
图5显示了为每个层生成的中值误差。我们可以看到,在这个特定网络的上采样层中有一个潜在的缺陷。基于这些信息,我们能够在一个较小的网络上复制这个回归,并将这个错误报告给NVIDIA。这个错误现在已在TensorRT 7.1中修复。
Figure 5. Layer-by-layer inspection results on the two TensorRT engines used in Figure 4. The orange line shows the median error of the TensorRT 7.0 inference outputs compared to the TensorFlow inference outputs. The blue line shows the results generated by the TensorRT 5.0 engine. There is a significant difference in the error distributions on the upsampling layers.
Latency flame graph
为了可视化推理中的瓶颈并找出可能的优化操作,我们将TensorRT profiler生成的分层计时信息绘制成火焰图。计时细节根据每个层的名称范围分组,如图6所示。这使我们能够看到网络的哪个部分比预期的时间要长。
Figure 6. Latency flame graph on Inception Net. The 1767 samples shown in this graph indicates that a forward pass on this network takes 1.767 ms.
Automated conversion pipeline
在Zoox,我们维护一个自动转换管道,跟踪每个模型使用的转换选项。当触发时,自动转换管道将所有记录的模型转换为TensorRT引擎,并将它们上载到云中进行部署。它还为新转换的TensorRT引擎运行验证作业,以验证准确性。这个管道只需一个命令就可以帮助我们将所有现有模型升级到TensorRT的更新版本。
Incompatible graph test suite
Zoox维护一个TensorFlow到TensorRT的转换测试套件。它测试从TensorFlow图形到TensorRT引擎的转换失败案例,以及报告的NVIDIA错误识别。
每个测试构建一个TensorFlow图,将其转换为TensorRT,并将输出偏差与TensorFlow图进行比较。使用这个测试套件,我们不仅可以向Zoox工程师演示哪些图形结构或操作可能无法使用TensorRT,而且还可以检测到在升级到较新版本的TensorRT时修复了哪些回归。Summary
本文介绍了Zoox-TensorRT转换管道中的几个特性。TensorRT转换检查器参与神经网络训练的早期阶段,以确保在您浪费时间和资源进行全面训练之前发现不兼容的操作。您可以在每个层调用推理精度验证,以识别不利于降低精度计算的操作。详细的分析揭示了不必要的计算,这些计算在TensorRT内部没有得到优化,但是可以通过在图构造期间进行简单的代码更改来优化这些计算。
自动转换管道帮助您验证每个TensorRT升级或模型重新转换。利用这条管道,我们成功地为在Zoox自主驾驶平台上执行各种流线型感知任务的神经网络提供了TensorRT转换支持。
手机扫一扫
移动阅读更方便
你可能感兴趣的文章