概述
目录
- TensorRT中的pytorch
- Developer Guide中的pytorch
- network_api_pytorch示例demo
- demo介绍
- demo流程
- demo总结
- TensorRT中的ONNX
- Developer Guide中的onnx
- “Hello World” For TensorRT From ONNX”
- Importing An ONNX Model Using The C++ Parser API实例
- Importing From ONNX Using Python
- Introduction To Importing Caffe, TensorFlow And ONNX Models Into TensorRT Using Python
- Object Detection With The ONNX TensorRT Backend In Python
- ONNX Parser API的研究
- 问题
TensorRT中的pytorch
Developer Guide中的pytorch
在开发者手册中搜索了一下torch,主要在下面三个部分提到:
- 3.2.1 “Hello World” For TensorRT Using PyTorch And Python “中提到了一下,对应的就是示例network_api_pytorch_mnist
- 3.2.6 Importing From PyTorch And Other Frameworks 中提到想要在pytorch上使用TensorRT要用TensorRT API复刻网络结构,然后从pytorch中复制权重。
- 8. Working With Deep Learning Frameworks中提到 Python API下,使用TensorFlow,Caffe或ONNX兼容框架构建的现有模型可用于使用提供的解析器构建TensorRT引擎(也就是这几个亲儿子有解析器)。 Python API还支持以NumPy兼容格式存储图层权重的框架,例如PyTorch( supports frameworks that store layer weights in a NumPy compatible format的是后儿子,也是儿子,不过只能重构模型)。
- 8.2 和 3.2.6介绍的一样
由此看来,从开发者手册上来看,想要使用pytorch就只能replicate the network architecture。
network_api_pytorch示例demo
demo介绍
这个demo是在线训练了mnist的网络,然后直接用torch的nn.Module.state_dict()方法把weights取出来,填充给builder创建的trt格式的network,然后利用这个被填充完weights的network创建engine,进行推断。
这个demo没有涉及到pytorch从文件中读取weights的问题。
demo流程
# 只是返回了/mnist目录的绝对路径
data_path, _ = common.find_sample_data(description="Runs an MNIST network using a PyTorch model", subfolder="mnist")
# Train the PyTorch model
mnist_model = model.MnistModel()
mnist_model.learn()
# weights调用了nn.Module.state_dict()方法
weights = mnist_model.get_weights()
# Do inference with TensorRT.
with build_engine(weights) as engine:
# Build an engine, allocate buffers and create a stream.
# For more information on buffer allocation, refer to the introductory samples.
inputs, outputs, bindings, stream = common.allocate_buffers(engine)
with engine.create_execution_context() as context:
case_num = load_random_test_case(mnist_model, pagelocked_buffer=inputs[0].host)
# For more information on performing inference, refer to the introductory samples.
# The common.do_inference function will return a list of outputs - we only have one in this case.
[output] = common.do_inference(context, bindings=bindings, inputs=inputs, outputs=outputs, stream=stream)
pred = np.argmax(output)
print("Test Case: " + str(case_num))
print("Prediction: " + str(pred))
- 如介绍所提,weights是通过在线训练完的
mnist_model
的参数,利用nn.Module.state_dict()
方法创建的。 - 同样的流程,
build_engine()
方法,封装了builder
和trt格式的network
的创建过程以及利用weights填充networks的过程,最后在build_engine()
方法中调用builder.build_cuda_engine(network)
来实现engine的创建。 - common.allocate_buffers()方法是为host端和device端分配内存的过程。
- load_random_test_case()方法是在取用来test的img
- do_inference主要将allocate_buffers()分配并填充好的数据放到GPU中,然后执行推理,然后再从GPU中取回output,就是结果。
demo总结
看demo的代码发现,确实如开发者手册3.2.6所说的,pytorch在这个demo上的实现,就是用”tensorRT语法“重新把网络结构写了一遍,也就是方法populate_network()的实现。
input_tensor = network.add_input(name=ModelData.INPUT_NAME, dtype=ModelData.DTYPE, shape=ModelData.INPUT_SHAPE)
conv1_w = weights['conv1.weight'].numpy()
conv1_b = weights['conv1.bias'].numpy()
conv1 = network.add_convolution(input=input_tensor, num_output_maps=20, kernel_shape=(5, 5), kernel=conv1_w, bias=conv1_b)
conv1.stride = (1, 1)
pool1 = network.add_pooling(input=conv1.get_output(0), type=trt.PoolingType.MAX, window_size=(2, 2))
pool1.stride = (2, 2)
conv2_w = weights['conv2.weight'].numpy()
conv2_b = weights['conv2.bias'].numpy()
conv2 = network.add_convolution(pool1.get_output(0), 50, (5, 5), conv2_w, conv2_b)
conv2.stride = (1, 1)
pool2 = network.add_pooling(conv2.get_output(0), trt.PoolingType.MAX, (2, 2))
pool2.stride = (2, 2)
fc1_w = weights['fc1.weight'].numpy()
fc1_b = weights['fc1.bias'].numpy()
fc1 = network.add_fully_connected(input=pool2.get_output(0), num_outputs=500, kernel=fc1_w, bias=fc1_b)
relu1 = network.add_activation(input=fc1.get_output(0), type=trt.ActivationType.RELU)
fc2_w = weights['fc2.weight'].numpy()
fc2_b = weights['fc2.bias'].numpy()
fc2 = network.add_fully_connected(relu1.get_output(0), ModelData.OUTPUT_SIZE, fc2_w, fc2_b)
# ModelData是上面自定义的一个数据结构
fc2.get_output(0).name = ModelData.OUTPUT_NAME
network.mark_output(tensor=fc2.get_output(0))
传入的network是TensorRT由builder创建的network,add_xxx()方法都是network的内置函数,看c++版本的别的demo,看到network是INetworkDefinition类型的指针。
INetworkDefinition* network = builder->createNetwork();
然后去Nvinfer.h中去找INetworkDefinition,发现这类下面果然有很多add_xxx()方法:
class INetworkDefinition
{
public:
virtual ITensor* addInput(const char* name, DataType type, Dims dimensions) = 0;
virtual void markOutput(ITensor& tensor) = 0;
virtual IConvolutionLayer* addConvolution(ITensor& input, int nbOutputMaps, DimsHW kernelSize, Weights kernelWeights, Weights biasWeights) = 0;
virtual IFullyConnectedLayer* addFullyConnected(ITensor& input, int nbOutputs, Weights kernelWeights, Weights biasWeights) = 0;
...
所以,其实这个demo就是利用tensorRT自带的构建网络的功能重建了torch构建的网络,没有读任何网络结构。所以还是想要用pytorch转onnx,再使用tensorRT。
TensorRT中的ONNX
Developer Guide中的onnx
由上面的结论,想用onnx格式进行尝试。
同样在Developer Guide中搜索一下onnx,发现有75处提到了,这里简略记录:
- 1.4 中提出ONNX parser在c++和python都有接口,但是要注意版本
The ONNX Parser shipped with TensorRT 5.1.x supports ONNX IR (Intermediate Representation) version 0.0.3, opset version 9.
- 2.2 介绍了demo实例,“Hello World” For TensorRT From ONNX" ->对应2.25节(C++)
- 2.2.5 中 Importing An ONNX Model Using The C++ Parser API实例 ->对应2.25节 (C++)
- 3.2 中Importing From ONNX Using Python->对应3.2.5节(Python)
- 3.2.2 中最后介绍了ONNXParserAPI也是->对应3.2.5节(还给了一个ONNX Parser API的链接)(Python)
- 3.2.5 中介绍的Python+TensorRT+ONNX的sample,主要是介绍了“ Introduction To Importing Caffe, TensorFlow And ONNX Models Into TensorRT Using Python”的sample和“ Object Detection With The ONNX TensorRT Backend In Python”的sample(Python)
- 7.2. Deploying To An Embedded System
Export the trained network to a format such as UFF or ONNX which can be imported into TensorRT (see Working With Deep Learning Frameworks for more details).
- 10.3中提示onnx的问题,如果常量输入用于不支持常量输入的层,就会message error,考虑用tensor Input代替。
- A.3. Command Line Program中在calib和int8参数后面提到,如今版本的tensorRT是不支持onnx的int8的。
“Hello World” For TensorRT From ONNX”
.
这个sample将在mnixt数据集上训练好的model转化成onnx(Open Neural Network Exchange)格式。
C++代码除了多了个报错机制,基本和读取caffe模型一样
if (!onnxToTRTModel("mnist.onnx", 1, trtModelStream))
gLogger.reportFail(sampleTest);
gLogger.reportFail的作用是查看有关网络的其他信息(包括图层信息和单个图层维度)。
Importing An ONNX Model Using The C++ Parser API实例
.
这个部分提到ONNX是有严格的版本限制的,TensorRT5.1.x支持的是ONNX IR 0.03,opset 9。
一般来说,ONNX解析器是具备向后兼容性的,因此之前版本的ONNXmodel一般不会遇到问题,但是不后兼容的功能可能会有例外,这时就需要把ONNX的模型文件转到支持的版本。
可能,有些人的model是通过更高版本的opsets生成的,这时可以看一下Github上TensorRT的ONNX模块是不是更新了,查看适合的版本。具体的位置是onnx_trt_backend.cpp的BACK+OPSET_VERSION变量的值。如果需要的话要下载最新版本的解析器,README写了build的过程
之后就又链接到了“Hello World” For TensorRT From ONNX”这个sample。
Importing From ONNX Using Python
Python接口的onnx使用,这里涉及两个sample。
Introduction To Importing Caffe, TensorFlow And ONNX Models Into TensorRT Using Python
第一个sample只是介绍python中创建engine和执行inference的过程。[Introduction To Importing ONNX Models Into TensorRT Using Python](Introduction To Importing Caffe, TensorFlow And ONNX Models Into TensorRT Using Python).
Object Detection With The ONNX TensorRT Backend In Python
基于yolov3-608的目标检测sample,不支持Ubuntu14.04及以下,不支持Python3.
第二个sample包含了yolov3转onnx,onnx转TensorRT的过程。Object Detection With The ONNX TensorRT Backend In Python.
ONNX Parser API的研究
问题
- pycharm运行缺少.so文件问题
示例:
ImportError: libnvinfer.so.5: cannot open shared object file: Nosuch file or directory
缺少什么文件就去/TensorRT5.x.x.x/targets/x86_64-linux-gnu/lib/目录下找对应的文件,复制到usr/lib
sudo cp /TensorRT5.x.x.x/targets/x86_64-linux-gnu/lib/libnvinfer.so.5 /usr/lib/
如果发现这个目录下没有报错的.so文件,就是误删了或者安装的不是TensorRT5.x,TensorRT4.x就会出现这个问题缺少libnvonnxparser.so.
问题出现原因是python加载动态库方面是默认从系统lib库上查找库文件,所以把需要的.so复制上去就行了。
- onnx出现的message error
研发者手册里提示,出现这个问题可能是因为在不支持常量输入的层以常量作为了输入,考虑用tensor Input代替即可。 - 在自己复写pytorch代码的时候,出了个小python问题。
引用Variable()方法的时候,报错
File "/media/boyun/6a2d0d8c-27e4-4ad2-975c-b24087659438/pycharm/self_pytoch_tensorRT/test.py", line 54, in <module>
batch_x, batch_y = Variable(batch_x.cuda(), volatile=True), Variable(batch_y.cuda(), volatile=True)
TypeError: 'module' object is not callable
查了之后告诉我,采用import...方式导入模块后,调用模块中的方法应该是模块名.方法(),如果忘记写模块名就会这样报错
,后来检查了,确实Variable方法应该是用from导入
即From torch.autograd import Variable
我的导入方法出了错误。
最后
以上就是自信大叔为你收集整理的TensorRT 5.1.5.0入门 Pytorch & ONNXTensorRT中的pytorchnetwork_api_pytorch示例demoTensorRT中的ONNX问题的全部内容,希望文章能够帮你解决TensorRT 5.1.5.0入门 Pytorch & ONNXTensorRT中的pytorchnetwork_api_pytorch示例demoTensorRT中的ONNX问题所遇到的程序开发问题。
如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。
发表评论 取消回复