日本不卡不码高清免费观看,久久国产精品久久w女人spa,黄色aa久久,三上悠亚国产精品一区二区三区

您的位置:首頁技術(shù)文章
文章詳情頁

PyTorch模型轉(zhuǎn)TensorRT是怎么實現(xiàn)的?

瀏覽:27日期:2022-06-16 14:07:02
轉(zhuǎn)換步驟概覽 準(zhǔn)備好模型定義文件(.py文件) 準(zhǔn)備好訓(xùn)練完成的權(quán)重文件(.pth或.pth.tar) 安裝onnx和onnxruntime 將訓(xùn)練好的模型轉(zhuǎn)換為.onnx格式 安裝tensorRT環(huán)境參數(shù)

ubuntu-18.04PyTorch-1.8.1onnx-1.9.0onnxruntime-1.7.2cuda-11.1cudnn-8.2.0TensorRT-7.2.3.4PyTorch轉(zhuǎn)ONNX

Step1:安裝ONNX和ONNXRUNTIME

網(wǎng)上找到的安裝方式是通過pip

pip install onnxpip install onnxruntime

如果使用的是Anaconda環(huán)境,conda安裝也是可以的。

conda install -c conda-forge onnxconda install -c conda-forge onnxruntime

Step2:安裝netron

netron是用于可視化網(wǎng)絡(luò)結(jié)構(gòu)的,便于debug。

pip install netron

Step3 PyTorch轉(zhuǎn)ONNx

安裝完成后,可以根據(jù)下面code進行轉(zhuǎn)換。

#--*-- coding:utf-8 --*--import onnx # 注意這里導(dǎo)入onnx時必須在torch導(dǎo)入之前,否則會出現(xiàn)segmentation faultimport torchimport torchvision from model import Netmodel= Net(args).cuda()#初始化模型checkpoint = torch.load(checkpoint_path)net.load_state_dict(checkpoint[’state_dict’])#載入訓(xùn)練好的權(quán)重文件print ('Model and weights LOADED successfully')export_onnx_file = ’./net.onnx’x = torch.onnx.export(net,torch.randn(1,1,224,224,device=’cuda’), #根據(jù)輸入要求初始化一個dummy inputexport_onnx_file,verbose=False, #是否以字符串形式顯示計算圖input_names = ['inputs']+['params_%d'%i for i in range(120)],#輸入節(jié)點的名稱,這里也可以給一個list,list中名稱分別對應(yīng)每一層可學(xué)習(xí)的參數(shù),便于后續(xù)查詢output_names = ['outputs'],# 輸出節(jié)點的名稱opset_version = 10,#onnx 支持采用的operator set, 應(yīng)該和pytorch版本相關(guān)do_constant_folding = True,dynamic_axes = {'inputs':{0:'batch_size'}, 2:'h', 3:'w'}, 'outputs':{0: 'batch_size'},})net = onnx.load(’./erfnet.onnx’) #加載onnx 計算圖onnx.checker.check_model(net) # 檢查文件模型是否正確onnx.helper.printable_graph(net.graph) #輸出onnx的計算圖

dynamic_axes用于指定輸入、輸出中的可變維度。輸入輸出的batch_size在這里都設(shè)為了可變,輸入的第2和第3維也設(shè)置為了可變。

Step 4:驗證ONNX模型

下面可視化onnx模型,同時測試模型是否正確運行

import netronimport onnxruntimeimport numpy as npfrom PIL import Imageimport cv2netron.start(’./net.onnx’)test_image = np.asarray(Image.open(test_image_path).convert(’L’),dtype=’float32’) /255.test_image = cv2.resize(np.array(test_image),(224,224),interpolation = cv2.INTER_CUBIC)test_image = test_image[np.newaxis,np.newaxis,:,:]session = onnxruntime.InferenceSession(’./net.onnx’)outputs = session.run(None, {'inputs': test_image})print(len(outputs))print(outputs[0].shape)#根據(jù)需要處理一下outputs[0],并可視化一下結(jié)果,看看結(jié)果是否正常ONNX轉(zhuǎn)TensorRT

Step1:從NVIDIA下載TensorRT下載安裝包 https://developer.nvidia.com/tensorrt

根據(jù)自己的cuda版本選擇,我選擇的是TensorRT 7.2.3,下載到本地。

cd download_pathdpkg -i nv-tensorrt-repo-ubuntu1804-cuda11.1-trt7.2.3.4-ga-20210226_1-1_amd64.debsudo apt-get updatesudo apt-get install tensorrt

查了一下NVIDIA的官方安裝教程https://docs.nvidia.com/deeplearning/tensorrt/quick-start-guide/index.html#install,由于可能需要調(diào)用TensorRT Python API,我們還需要先安裝PyCUDA。這邊先插入一下PyCUDA的安裝。

pip install ’pycuda<2021.1’

遇到任何問題,請參考官方說明 https://wiki.tiker.net/PyCuda/Installation/Linux/#step-1-download-and-unpack-pycuda如果使用的是Python 3.X,再執(zhí)行一下以下安裝。

sudo apt-get install python3-libnvinfer-dev

如果需要ONNX graphsurgeon或使用Python模塊,還需要執(zhí)行以下命令。

sudo apt-get install onnx-graphsurgeon

驗證是否安裝成功。

dpkg -l | grep TensorRT

PyTorch模型轉(zhuǎn)TensorRT是怎么實現(xiàn)的?

得到類似上圖的結(jié)果就是安裝成功了。

問題:此時在python中import tensorrt,得到ModuleNotFoundError: No module named ’tensorrt’的報錯信息。

網(wǎng)上查了一下,通過dpkg安裝的tensorrt是默認(rèn)安裝在系統(tǒng)python中,而不是Anaconda環(huán)境的python里的。由于系統(tǒng)默認(rèn)的python是3.6,而Anaconda里使用的是3.8.8,通過export PYTHONPATH的方式,又會出現(xiàn)python版本不匹配的問題。

重新搜索了一下如何在anaconda環(huán)境里安裝tensorRT。

pip3 install --upgrade setuptools pippip install nvidia-pyindexpip install nvidia-tensorrt

驗證一下這是Anconda環(huán)境的python是否可以import tensorrt。

import tensorrtprint(tensorrt.__version__)#輸出8.0.0.3

Step 2:ONNX轉(zhuǎn)TensorRT

先說一下,在這一步里遇到了*** AttributeError: ‘tensorrt.tensorrt.Builder’ object has no attribute ’max_workspace_size’的報錯信息。網(wǎng)上查了一下,是8.0.0.3版本的bug,要退回到7.2.3.4。emmm…

pip unintall nvidia-tensorrt #先把8.0.0.3版本卸載掉pip install nvidia-tensorrt==7.2.* --index-url https://pypi.ngc.nvidia.com # 安裝7.2.3.4banben

轉(zhuǎn)換代碼

import pycuda.autoinit import pycuda.driver as cudaimport tensorrt as trtimport torch import time from PIL import Imageimport cv2,osimport torchvision import numpy as npfrom scipy.special import softmax### get_img_np_nchw h和postprocess_the_output函數(shù)根據(jù)需要進行修改TRT_LOGGER = trt.Logger()def get_img_np_nchw(img_path):img = Image.open(img_path).convert(’L’)img = np.asarray(img, dtype=’float32’)img = cv2.resize(np.array(img),(224, 224), interpolation = cv2.INTER_CUBIC)img = img / 255.img = img[np.newaxis, np.newaxis]return imageclass HostDeviceMem(object): def __init__(self, host_mem, device_mem):'''host_mom指代cpu內(nèi)存,device_mem指代GPU內(nèi)存'''self.host = host_memself.device = device_mem def __str__(self):return 'Host:n' + str(self.host) + 'nDevice:n' + str(self.device) def __repr__(self):return self.__str__()def allocate_buffers(engine): inputs = [] outputs = [] bindings = [] stream = cuda.Stream() for binding in engine:size = trt.volume(engine.get_binding_shape(binding)) * engine.max_batch_sizedtype = trt.nptype(engine.get_binding_dtype(binding))# Allocate host and device buffershost_mem = cuda.pagelocked_empty(size, dtype)device_mem = cuda.mem_alloc(host_mem.nbytes)# Append the device buffer to device bindings.bindings.append(int(device_mem))# Append to the appropriate list.if engine.binding_is_input(binding): inputs.append(HostDeviceMem(host_mem, device_mem))else: outputs.append(HostDeviceMem(host_mem, device_mem)) return inputs, outputs, bindings, streamdef get_engine(max_batch_size=1, onnx_file_path='', engine_file_path='',fp16_mode=False, int8_mode=False,save_engine=False): ''' params max_batch_size: 預(yù)先指定大小好分配顯存 params onnx_file_path: onnx文件路徑 params engine_file_path: 待保存的序列化的引擎文件路徑 params fp16_mode: 是否采用FP16 params int8_mode: 是否采用INT8 params save_engine: 是否保存引擎 returns: ICudaEngine ''' # 如果已經(jīng)存在序列化之后的引擎,則直接反序列化得到cudaEngine if os.path.exists(engine_file_path):print('Reading engine from file: {}'.format(engine_file_path))with open(engine_file_path, ’rb’) as f, trt.Runtime(TRT_LOGGER) as runtime: return runtime.deserialize_cuda_engine(f.read()) # 反序列化 else: # 由onnx創(chuàng)建cudaEngine# 使用logger創(chuàng)建一個builder # builder創(chuàng)建一個計算圖 INetworkDefinitionexplicit_batch = 1 << (int)(trt.NetworkDefinitionCreationFlag.EXPLICIT_BATCH)# In TensorRT 7.0, the ONNX parser only supports full-dimensions mode, meaning that your network definition must be created with the explicitBatch flag set. For more information, see Working With Dynamic Shapes.with trt.Builder(TRT_LOGGER) as builder, builder.create_network(explicit_batch) as network, trt.OnnxParser(network, TRT_LOGGER) as parser, builder.create_builder_config() as config: # 使用onnx的解析器綁定計算圖,后續(xù)將通過解析填充計算圖 profile = builder.create_optimization_profile() profile.set_shape('inputs', (1, 1, 224, 224),(1,1,224,224),(1,1,224,224)) config.add_optimization_profile(profile) config.max_workspace_size = 1<<30 # 預(yù)先分配的工作空間大小,即ICudaEngine執(zhí)行時GPU最大需要的空間 builder.max_batch_size = max_batch_size # 執(zhí)行時最大可以使用的batchsize builder.fp16_mode = fp16_mode builder.int8_mode = int8_mode if int8_mode:# To be updatedraise NotImplementedError # 解析onnx文件,填充計算圖 if not os.path.exists(onnx_file_path):quit('ONNX file {} not found!'.format(onnx_file_path)) print(’loading onnx file from path {} ...’.format(onnx_file_path)) # with open(onnx_file_path, ’rb’) as model: # 二值化的網(wǎng)絡(luò)結(jié)果和參數(shù) # print('Begining onnx file parsing') # parser.parse(model.read()) # 解析onnx文件 parser.parse_from_file(onnx_file_path) # parser還有一個從文件解析onnx的方法 print('Completed parsing of onnx file') # 填充計算圖完成后,則使用builder從計算圖中創(chuàng)建CudaEngine print('Building an engine from file{}’ this may take a while...'.format(onnx_file_path)) ################# # import pdb;pdb.set_trace() print(network.get_layer(network.num_layers-1).get_output(0).shape) # network.mark_output(network.get_layer(network.num_layers -1).get_output(0)) engine = builder.build_engine(network,config) # 注意,這里的network是INetworkDefinition類型,即填充后的計算圖 print('Completed creating Engine') if save_engine: #保存engine供以后直接反序列化使用with open(engine_file_path, ’wb’) as f: f.write(engine.serialize()) # 序列化 return enginedef do_inference(context, bindings, inputs, outputs, stream, batch_size=1): # Transfer data from CPU to the GPU. [cuda.memcpy_htod_async(inp.device, inp.host, stream) for inp in inputs] # Run inference. context.execute_async(batch_size=batch_size, bindings=bindings, stream_handle=stream.handle) # Transfer predictions back from the GPU. [cuda.memcpy_dtoh_async(out.host, out.device, stream) for out in outputs] # Synchronize the stream stream.synchronize() # Return only the host outputs. return [out.host for out in outputs]def postprocess_the_outputs(outputs, shape_of_output): outputs = outputs.reshape(*shape_of_output) out = np.argmax(softmax(outputs,axis=1)[0,...],axis=0) # import pdb;pdb.set_trace() return out# 驗證TensorRT模型是否正確onnx_model_path = ’./Net.onnx’max_batch_size = 1# These two modes are dependent on hardwaresfp16_mode = Falseint8_mode = Falsetrt_engine_path = ’./model_fp16_{}_int8_{}.trt’.format(fp16_mode, int8_mode)# Build an engineengine = get_engine(max_batch_size, onnx_model_path, trt_engine_path, fp16_mode, int8_mode , save_engine=True)# Create the context for this enginecontext = engine.create_execution_context()# Allocate buffers for input and outputinputs, outputs, bindings, stream = allocate_buffers(engine) # input, output: host # bindings# Do inferenceimg_np_nchw = get_img_np_nchw(img_path)inputs[0].host = img_np_nchw.reshape(-1)shape_of_output = (max_batch_size, 2, 224, 224)# inputs[1].host = ... for multiple inputt1 = time.time()trt_outputs = do_inference(context, bindings=bindings, inputs=inputs, outputs=outputs, stream=stream) # numpy datat2 = time.time()feat = postprocess_the_outputs(trt_outputs[0], shape_of_output)print(’TensorRT ok’)print('Inference time with the TensorRT engine: {}'.format(t2-t1))

根據(jù)https://www.jb51.net/article/187266.htm文章里的方法,轉(zhuǎn)換的時候會報下面的錯誤:

PyTorch模型轉(zhuǎn)TensorRT是怎么實現(xiàn)的?

原來我是根據(jù)鏈接里的代買進行轉(zhuǎn)換的,后來進行了修改,按我文中的轉(zhuǎn)換代碼不會有問題,

修改的地方在

with trt.Builder(TRT_LOGGER) as builder, builder.create_network(explicit_batch) as network, trt.OnnxParser(network, TRT_LOGGER) as parser, builder.create_builder_config() as config: # 使用onnx的解析器綁定計算圖,后續(xù)將通過解析填充計算圖 profile = builder.create_optimization_profile() profile.set_shape('inputs', (1, 1, 224, 224),(1,1,224,224),(1,1,224,224)) config.add_optimization_profile(profile) config.max_workspace_size = 1<<30 # 預(yù)先分配的工作空間大小,即ICudaEngine執(zhí)行時GPU最大需要的空間 engine = builder.build_engine(network,config)

將鏈接中相應(yīng)的代碼進行修改或添加,就沒有這個問題了。

到此這篇關(guān)于PyTorch模型轉(zhuǎn)TensorRT是怎么實現(xiàn)的?的文章就介紹到這了,更多相關(guān)PyTorch模型轉(zhuǎn)TensorRT內(nèi)容請搜索好吧啦網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持好吧啦網(wǎng)!

標(biāo)簽: PyTorch TensorRT
相關(guān)文章:
日本不卡不码高清免费观看,久久国产精品久久w女人spa,黄色aa久久,三上悠亚国产精品一区二区三区
国产拍在线视频| 韩国久久久久久| 国产高清视频一区二区| 国产精品人人爽人人做我的可爱| 亚洲女人av| 亚洲免费观看| 亚洲欧美日韩视频二区| 成人av动漫在线观看| 波多野结衣一区| 久久电影一区| 亚洲久久在线| 国产精品自在| 国产精品激情| 国产中文欧美日韩在线| 日韩一区二区三区免费| 1000部精品久久久久久久久| 欧美另类专区| 亚洲综合图色| 四虎精品永久免费| 国产精品最新| 成人福利视频| 午夜电影亚洲| 亚洲毛片一区| 国产精品第一国产精品| 成人在线丰满少妇av| 精品国产亚洲日本| 免费在线观看一区| 综合一区二区三区| 欧洲精品一区二区三区| 鲁大师成人一区二区三区 | 久久夜色精品| 婷婷久久一区| 国产成人精品三级高清久久91 | 国产精品国产三级在线观看| 国产精品毛片一区二区三区| 日韩av有码| 日韩精品免费一区二区夜夜嗨| 久久亚洲精品中文字幕蜜潮电影| 国产精品成人3p一区二区三区| 日本成人中文字幕在线视频| 999国产精品| 日本在线精品| 国产精品视频一区二区三区| 日韩精品一区二区三区中文在线 | 日韩中文字幕区一区有砖一区| 综合在线一区| 麻豆国产欧美日韩综合精品二区| www.九色在线| 伊人久久亚洲| 国产一区二区三区亚洲综合| 免费看日韩精品| 女人天堂亚洲aⅴ在线观看| 国产美女精品| 久久福利精品| 免费成人在线视频观看| 久久精品123| 国产精品chinese| 国产精品一站二站| 精品国产乱码| 国产v日韩v欧美v| 久久久久国产精品一区三寸| 欧美91福利在线观看| 亚洲大片在线| 天使萌一区二区三区免费观看| 青草久久视频| 精品淫伦v久久水蜜桃| 麻豆精品蜜桃| 亚洲精品欧洲| 久久99精品久久久野外观看| 日韩天堂在线| 国产 日韩 欧美 综合 一区| 国产精品视区| 五月综合激情| 日本va欧美va瓶| 精品美女久久| 久久精品国产福利| 天堂va欧美ⅴa亚洲va一国产| 久久男人天堂| 日本免费一区二区视频| 亚洲成人免费| 久久精品福利| 首页亚洲欧美制服丝腿| 亚洲欧洲美洲av| 国产精品v日韩精品v欧美精品网站 | 999国产精品| 国产精品久久久久毛片大屁完整版| 欧美在线网站| 黄毛片在线观看| 欧美国产日本| 日韩成人精品一区二区三区 | 99久久久久国产精品| 日韩综合一区二区三区| 久草免费在线视频| 日韩高清一区| 亚洲综合国产| 久久一区二区三区喷水| 精品国产99| 国产精品白丝久久av网站| 一区二区三区四区日韩| 欧美日韩国产免费观看视频| 香蕉成人av| 鲁鲁在线中文| 成人精品高清在线视频| 麻豆久久久久久| 国产精品嫩模av在线| 综合亚洲自拍| 午夜宅男久久久| 欧美/亚洲一区| 国产一区二区三区亚洲综合| 国产麻豆一区二区三区| 婷婷亚洲成人| 午夜在线视频观看日韩17c| 欧美成人综合| 久久视频精品| 免费黄色成人| 午夜久久免费观看| 极品裸体白嫩激情啪啪国产精品| 成人日韩在线| 色老板在线视频一区二区| 色婷婷色综合| 日本不良网站在线观看| 国内不卡的一区二区三区中文字幕| 国产精品成人自拍| 日韩精品免费一区二区夜夜嗨| 蜜桃久久精品一区二区| 亚洲区欧美区| 亚州精品视频| 国产精选久久| 久久精品一区二区国产| 精品亚洲a∨一区二区三区18| 国产精品久久久免费| 久久av导航| 日本一区二区高清不卡| 麻豆网站免费在线观看| 美女网站视频一区| 成人欧美一区二区三区的电影| 国产日韩视频在线| 国产精品高清一区二区| 久久国产三级精品| 开心激情综合| 91精品精品| 日本在线一区二区三区| 日韩精品91亚洲二区在线观看| 国产日韩一区二区三免费高清| 麻豆精品在线观看| 午夜久久影院| 欧美亚洲综合视频| 日韩av福利| 日韩综合小视频| 成人自拍av| 国产精品一国产精品k频道56| 国精品产品一区| 免费看日韩精品| 日韩高清在线不卡| 亚洲免费播放| 欧美日韩一区二区三区视频播放| 91精品综合| 黄色aa久久| 免费在线成人网| 国产拍在线视频| 中文在线免费视频| 激情自拍一区| 日韩va欧美va亚洲va久久| 欧美国产另类| 国产精品久久久网站| 在线一区免费观看| 日韩久久99| 欧美精品成人| 国产精品午夜av| 日韩精品1区| 亚洲一区二区三区高清不卡| 欧美视频一区| 欧美精选视频一区二区| 西西人体一区二区| 国产精品二区影院| 久久国产主播| 国产日韩欧美三级| 日韩精品一二三| 国产毛片一区| 久久亚洲不卡| 免费在线成人网| 欧美日韩国产在线观看网站| zzzwww在线看片免费| 日本h片久久| 免费美女久久99| 蜜桃免费网站一区二区三区| 欧美一区久久久| 成人精品久久| 99久久久久| 久久国产亚洲| 涩涩av在线| 亚洲免费精品| 亚洲精品激情| 国产欧美久久一区二区三区| 日本精品另类| 免费日韩成人| 久久精品高清| 一区二区日韩免费看| 蜜桃免费网站一区二区三区| 欧美一级一区|