基于TensorRT 3的自动驾驶快速INT8推理

Fast INT8 Inference for Autonomous Vehicles with TensorRT 3

自主驾驶需要安全性,需要一种高性能的计算解决方案来处理极其精确的传感器数据。研究人员和开发人员创建用于自动驾驶的深度神经网络(DNNs)必须优化其网络,以确保低延迟推理和能源效率。由于NVIDIA TensorRT中有了一个新的Python API,这个过程变得更加简单。

Figure 1. TensorRT optimizes trained neural network models to produce deployment-ready runtime inference engines.

TensorRT是一个高性能的深度学习推理优化器和运行时引擎,用于深度学习应用程序的生产部署。开发人员可以优化在TensorFlow或Caffe中训练的模型,以生成内存高效的运行时引擎,从而最大限度地提高推理吞吐量,使深度学习对于延迟关键的产品和服务(如自主驾驶)切实可行。。

最新的TensorRT 3版本引入了一个功能齐全的Python API,使研究人员和开发人员能够使用熟悉的Python代码优化和序列化DNN。使用TySoRRT 3,可以在Python中部署云计算服务,或者在C++中实时应用,例如在英伟达驱动PX AI汽车计算机上运行的自主驱动软件。
在本文中,将向展示如何在主机上使用TensorRT 3 Python API来缓存语义分段网络的校准结果,以便使用INT8 precision进行部署。然后,可以使用校准缓存来优化和部署在驱动PX平台上使用C++ API的网络。

城市景观数据集与全卷积网络The Cityscapes Dataset and Fully Convolutional Network

Figure 2. Sample images from the Cityscapes dataset.

城市景观数据集[Cordts等人。2016]用于城市自主驾驶场景的语义分割。图2显示了数据集中的示例图像。该数据集共有30个不同的类,分为8个不同的类别。为了评估性能,使用了19个类和7个类别,如图3所示。

Figure 3. Classes and categories used in the Cityscapes benchmark, and the IoU (Intersection-over-Union) metric.

对于评估,使用IoU(Intersection over Union)度量,提供两个平均分数,一个用于类,另一个用于类别。

Figure 4. A sample VGG16-based fully convolutional
network trained for semantic segmentation.

为了证明TensorRT的能力,设计了一种全卷积网络FCN[Long等人]。基于VGG16,如图4所示。该网络由一个基于VGG16的编码器和两个使用反卷积层实现的上采样层组成。用NVIDIA数字和Caffe在城市景观数据集上训练了[2014年]网络后端。

Figure 5. Sample FCN network output.

该网络设计为获取512×1024的输入图像并生成每像素分类结果,如图5所示。训练后的网络IoU类平均得分为48.4分,IoU类平均得分为76.9分。如果直接使用Caffe和cuDNN在其中一个驱动器PX autochauffer gpu(Pascal)上运行推断,该网络将达到大约242ms的延迟和大约4个图像/秒的吞吐量。在35英里/小时的速度下,242毫秒相当于大约12英尺的行驶距离。这种水平的表现不足以为自动驾驶做出及时的决定。让来看看如何才能做得更好。

图6. DP4A指令:四元点积累加。

作为第一步,使用TensorRT优化网络,使用FP32精度提供了良好的加速。通过使用TensorRT,实现了170毫秒的延迟和大约6个图像/秒的吞吐量。这比Caffe提高了50%,但是TensorRT可以进一步优化网络。

以下各节将演示如何使用TensorRT,在保持原FP32网络良好精度的同时,使用INT8降低的精度来提高该网络的推理性能。

INT8推理和校准

驱动器PX autochauffer中的Pascal dGPU能够执行8位整数4元向量点积(DP4A,见图6)指令,以加速深层神经网络推理。虽然这条新指令提供了更快的计算速度,但在用这种简化的INT8格式表示深度神经网络的权值和激活方面存在着重大挑战。如表1所示,与FP32或FP16相比,INT8可表示值的动态范围和粒度明显受限。
TensorRT提供了一种快速简便的方法来获取在FP32中训练过的模型,并自动转换网络以供部署,INT8的精度降低,精度损失最小。为了实现这一目标,TensorRT使用了一个校准过程,当用有限的8位整数表示逼近FP32网络时,该校准过程将信息损失最小化。有关此算法如何工作的更多信息,请参阅TensorRT GPU技术会议演示的8位推理。

在准备校准数据集时,应在典型的推断场景中捕获预期的数据分布。需要确保校准数据集涵盖所有预期场景,例如晴天、雨天、夜景等。如果正在创建自己的数据集,建议创建单独的校准数据集。校准数据集不应与训练、验证或测试数据集重叠,以避免校准模型仅在这些数据集上正常工作的情况。

让看看如何使用新的TensorRT Python API创建校准缓存。

使用Python API创建校准缓存

随着TensorRT Python API的引入,现在完全可以在Python中实现INT8校准器类。这个例子演示了如何处理图像数据并为校准器提供数据。修改这个示例以支持Python中不同类型的数据和网络应该很简单。

import pycuda.driver as cuda

import pycuda.autoinit

import numpy as np

from PIL import Image

import ctypes

import tensorrt as trt

CHANNEL = 3

HEIGHT = 512

WIDTH = 1024

class PythonEntropyCalibrator(trt.infer.EntropyCalibrator):

def init(self, input_layers, stream):

trt.infer.EntropyCalibrator.init(self)

self.input_layers = input_layers

self.stream = stream

self.d_input = cuda.mem_alloc(self.stream.calibration_data.nbytes)

stream.reset()

def get_batch_size(self):

return self.stream.batch_size

def get_batch(self, bindings, names):

batch = self.stream.next_batch()

if not batch.size:

return None

cuda.memcpy_htod(self.d_input, batch)

for i in self.input_layers[0]:

assert names[0] != i

bindings[0] = int(self.d_input)

return bindings

def read_calibration_cache(self, length):

return None

def write_calibration_cache(self, ptr, size):

cache = ctypes.c_char_p(int(ptr))

with open(‘calibration_cache.bin’, ‘wb’) as f:

f.write(cache.value)

return None

PythonEntropyCalibrator类是INT8校准器的Python实现。这个类负责分配CUDA内存并为所有输入层创建绑定。每当调用get_batch()时,会将校准输入数据上载到预先分配的CUDA内存。校准批大小定义了同时处理多少校准图像以收集计算正确比例因子所需的输入分布。校准批大小可以不同于用于推断的最大批大小参数。使用较大的校准批大小通常会加快校准过程,建议使用GPU内存中可以容纳的最大批大小。

class ImageBatchStream():
def init(self, batch_size, calibration_files, preprocessor): self.batch_size = batch_size
self.max_batches = (len(calibration_files) // batch_size) + \ (1 if (len(calibration_files) % batch_size) \ else 0)
self.files = calibration_files
self.calibration_data = np.zeros((batch_size, CHANNEL, HEIGHT, WIDTH), \
dtype=np.float32)
self.batch = 0
self.preprocessor = preprocessor @staticmethod
def read_image_chw(path):
img = Image.open(path).resize((WIDTH,HEIGHT), Image.NEAREST)
im = np.array(img, dtype=np.float32, order=‘C’)
im = im[:,:,::-1]
im = im.transpose((2,0,1))
return im
def reset(self):
self.batch = 0
def next_batch(self):
if self.batch < self.max_batches:
imgs = []
files_for_batch = self.files[self.batch_size * self.batch : \ self.batch_size * (self.batch + 1)]
for f in files_for_batch:
print("[ImageBatchStream] Processing ", f)
img = ImageBatchStream.read_image_chw(f)
img = self.preprocessor(img)
imgs.append(img)
for i in range(len(imgs)): s
elf.calibration_data[i] = imgs[i]
self.batch += 1
return np.ascontiguousarray(self.calibration_data, dtype=np.float32)
else:
return np.array([])

ImageBatchStream是一个helper类,负责处理文件I/O、图像大小的缩放、创建要处理的批处理数据、将数据布局重新排序为CHW格式,以及应用预处理器函数(例如减去图像平均值)。

校准结果可以保存到缓存文件中,因此可以创建优化的TensorRT运行时引擎,而无需在目标上重复校准过程。在本例中,生成的文件名是calibration_cache.bin,在write_calibration_cache函数中处理。

一旦准备好校准器类,剩下的过程就可以用TensorRT的新的拉氏体Python模块,旨在抽象出许多低级细节,使数据科学家更容易使用TensorRT。这个包允许添加预处理和后处理函数,并使能够利用现有的Python数据预处理例程。在下面的代码中,函数sub_mean_chw作为预处理步骤处理均值减影,函数color_map处理将输出类ID映射到颜色以可视化输出。

import glob
from random
import shuffleimport numpy as npfrom PIL
import Image
import tensorrt as trt
import labels #from cityscapes evaluation scriptimport calibrator #calibrator.py
MEAN = (71.60167789, 82.09696889, 72.30508881)
MODEL_DIR = ‘/data/fcn8s/’
CITYSCAPES_DIR = ‘/data/Cityscapes/’
TEST_IMAGE = CITYSCAPES_DIR + ‘leftImg8bit/val/lindau/lindau_000042_000019_leftImg8bit.png’
CALIBRATION_DATASET_LOC = CITYSCAPES_DIR + ‘leftImg8bit/train//.png’
CLASSES = 19
CHANNEL = 3
HEIGHT = 512
WIDTH = 1024
def sub_mean_chw(data):
data = data.transpose((1,2,0)) # CHW -> HWC
data -= np.array(MEAN) # Broadcast subtract
data = data.transpose((2,0,1)) # HWC -> CHW return
data def color_map(output):
output = output.reshape(CLASSES, HEIGHT, WIDTH)
out_col = np.zeros(shape=(HEIGHT, WIDTH), dtype=(np.uint8, 3))
for x in range (WIDTH):
for y in range (HEIGHT):
out_col[y,x] = labels.id2label[labels.trainId2label[np.argmax(output[:,y,x])].id].color
return out_col

这是将所有代码组合在一起的主要功能。这个tensorrt.lite模块提供高级函数,使用一个名为tensorrt.lite.Engine.

def create_calibration_dataset(): # Create list of calibration images (filename) # This sample code picks 100 images at random from training set
calibration_files = glob.glob(CALIBRATION_DATASET_LOC)
shuffle(calibration_files)
return calibration_files[:100]
def main():
calibration_files = create_calibration_dataset()
**# Process 5 images at a time for calibration # This batch size can be different from MaxBatchSize (1 in this example)
batchstream = calibrator.ImageBatchStream(5, calibration_files, sub_mean_chw)
int8_calibrator = calibrator.PythonEntropyCalibrator(["**data"], batchstream) # Easy to use TensorRT lite package
engine = trt.lite.Engine(framework=“c1”, deployfile=MODEL_DIR + “fcn8s.prototxt”, modelfile=MODEL_DIR + “fcn8s.caffemodel”, max_batch_size=1,
max_workspace_size=(256 << 20),
input_nodes={“data”:(CHANNEL,HEIGHT,WIDTH)},
output_nodes=[“score”],
preprocessors={“data”:sub_mean_chw},
postprocessors={“score”:color_map}, data_type=trt.infer.DataType.INT8, calibrator=int8_calibrator, logger_severity=trt.infer.LogSeverity.INFO)
test_data = calibrator.ImageBatchStream.read_image_chw(TEST_IMAGE)
out = engine.infer(test_data)[0]
test_img = Image.fromarray(out, ‘RGB’)
test_img.show()

在城市景观数据集中,有独立的训练、验证和测试集,遵循深度学习的常见做法。然而,这意味着没有单独的校准数据集。因此,可以从训练数据集中随机选择100幅图像用作校准数据集,以说明校准过程的工作情况。正如将看到的,校准算法可以达到良好的精度,只有100个随机图像!

使用包含计算能力为6.1的NVIDIA GPU的系统(例如Quadro P4000、Tesla P4或P40),可以运行INT8优化引擎来验证其准确性。建议运行整个验证数据集,以确保使用降低精度所带来的小精度损失是可接受的。通过使用所有500个验证图像运行Cityscapes评估脚本,发现校准后的INT8模型实现了48.1个平均类IoU和76.8个平均类IoU,而原始FP32精度模型分别为48.4和76.9。

Optimizing the INT8 Model on DRIVE PX

TensorRT builder实现了一种基于分析的优化,称为内核自动调整。此过程要求在目标设备上优化网络。在这个目标优化阶段,可以使用从主机生成的校准缓存文件生成INT8模型,而不需要校准数据集。需要编写一个实现readCalibrationCache函数的校准器类,以告诉TensorRT使用缓存的结果,如下代码所示。

class Int8CacheCalibrator : public IInt8EntropyCalibrator {
public:
Int8CacheCalibrator(std::string cacheFile) : mCacheFile(cacheFile) {}
virtual ~Int8CacheCalibrator() {}
int getBatchSize() const override {return 1;}
bool getBatch(void* bindings[], const char* names[], int nbBindings) override
{
return false;
}
const void* readCalibrationCache(size_t& length) override
{
mCalibrationCache.clear();
std::ifstream input(mCacheFile, std::ios::binary);
input >> std::noskipws;
if (input.good())
{
std::copy(std::istream_iterator(input), std::istream_iterator(), std::back_inserter(mCalibrationCache));
}
length = mCalibrationCache.size();
return length ? &mCalibrationCache[0] : nullptr;
}
private: std::string mCacheFile;
std::vector mCalibrationCache;

利用TensorRT的INT8推断,该模型现在可以在一个驱动器PX autochauffer的Pascal GPU上以50毫秒的延迟或20个图像/秒的速度运行。图7总结了TensorRT使用FP32和INT8推断获得的性能。

Figure 7. INT8 inference with TensorRT improves inference throughput and latency by about 5x compared to the original network running in Caffe.

可以将优化的引擎序列化到一个文件中进行部署,然后就可以在驱动器PX上部署INT8优化的网络了!

基于TensorRT 3的自动驾驶快速INT8推理相关推荐

  1. 基于Donkeycar手动实现自动驾驶

    基于Donkeycar手动实现自动驾驶 关于Donkeycar小车 本文说明 硬件选择 主板模块 小车选择 驱动模块 其他模块 驱动总结 小车组装 Jetson nano.PCA9685与L298N模 ...

  2. 地平线机器人_地平线机器人CEO余凯:基于深度学习的自动驾驶之路

    请关注公众号"汽车创新港",获取后续更多论坛实录! 加工作人员微信号:tinydanio,备注"我要入群"直接进入直播群! 今天都是大牛,下面的也是技术大牛,是 ...

  3. 【Stereo R-CNN 解读】基于立体R-CNN的自动驾驶三维目标检测

    摘要 本文充分利用立体图像中的稀疏.密集.语义和几何信息,提出了一种用于自动驾驶的三维目标检测方法.我们的方法,称为 Stereo R-CNN,扩展了 Faster R-CNN 用于立体输入,以同时检 ...

  4. 基于Matlab/simulink的自动驾驶车道保持adas辅助模型

    基于Matlab/simulink的自动驾驶车道保持adas辅助模型 需要版本Matlab2021a ID:6949665214165236乔治在柬埔寨debug

  5. 使用MATLAB/simulink与PreScan联合进行基于强化学习的自动驾驶系统设计与仿真

    使用MATLAB/simulink与PreScan联合进行基于强化学习的自动驾驶系统设计与仿真 总论 环境配置 系统搭建 总论 使用MATLAB中的强化学习工具箱作为核心算法的建立工具,在simuli ...

  6. 目标检测YOLO实战应用案例100讲-基于深度学习的自动驾驶目标检测算法研究

    目录 基于深度学习的自动驾驶目标检测算法研究 相关理论基础 2.1  卷积神经网络基本原理

  7. Talk预告 | 清华大学交叉信息研究院助理教授赵行:基于视觉感知的自动驾驶运动预测

    本期为TechBeat人工智能社区第481期线上Talk! 北京时间3月15日(周三)20:00,清华大学交叉信息研究院助理教授--赵行的Talk将准时在TechBeat人工智能社区开播! 他与大家分 ...

  8. 《整体决策的统一框架和基于时空的高速路自动驾驶轨迹规划》论文分析

    文献分析 这篇<整体决策的统一框架和基于时空的高速路自动驾驶轨迹规划>论文,针对过往前任研究的一些不足,建立了决策规划的三个模块,这三个模块针对短期(10hz,一秒运行十次),中期(1hz ...

  9. 基于改进Deeplabv3plus的自动驾驶场景分割系统 (源码&教程)

    1.研究背景 随着人工智能技术的飞速发展,车辆的自动驾驶离人们的生活越来越近.自动驾驶整个运行流程中首先需要依赖各种车载传感器收集车辆周围的各种环境数据,进而利用各种分析算法分析得到计算机可感知的环境 ...

最新文章

  1. 光标定位在文本框的末尾
  2. 精读《setState 做了什么》
  3. java uuid静态方法_Java UUID toString()方法与示例
  4. uni-app更新某个组件版本;uni-app更新插件版本;uni-app更新uni_modules插件;uni-app小程序更新某一个组件的版本库
  5. 好程序员Java分享Java案例_英汉字典
  6. python version 3_VIM设置python3支持和检测python version
  7. 学习Wireshark之二:数据包分析
  8. laravel 配置邮件发件人_Jenkins中配置自动化测试项目
  9. 蓝牙鼠标windows linux,在Deepin和Windows 10双系统中蓝牙4.0鼠标共享使用的方法
  10. GIS专业/GIS方向需要考那些证书
  11. lenovo微型计算机如何拆t410,拆解 ThinkPad T410
  12. java实现zip文件压缩和解压
  13. 十大热门编程语言入门难度排名
  14. Linux系统入门学习
  15. 使用flex实现左中右布局,中间自适应
  16. 深圳大学计算机与科学考研科目,2020深圳大学计算机专业课不考408了
  17. 怎么在CAD三维图面上添加一长段说明文字?
  18. 宁向东认为的沟通分类
  19. oracle01109,oracle解锁用户时报错ORA-01109: database not open的解决办法
  20. javaweb主页设置

热门文章

  1. 2022-2028年中国UI设计行业现状调研分析及发展趋势研究报告
  2. 2022-2028年中国LCD光刻胶行业市场深度分析及发展规模预测报告
  3. 【JavaWeb】servlet与http请求协议
  4. 面试常碰到++p/p--问题到底结果是什么?
  5. ifelse的命令空间
  6. python编程问题---第一次
  7. TensorFlow+TVM优化NMT神经机器翻译
  8. 机器学习PAI产品架构
  9. Tesla T4视频编码性能分析
  10. 使嵌入式系统调试更容易:有用的硬件和软件提示