TensorRT Model Optimizer量化和模型导出

ref

Accelerate Generative AI Inference Performance with NVIDIA TensorRT Model Optimizer, Now Publicly Available | NVIDIA Technical Blog

https://github.com/NVIDIA/TensorRT-Model-Optimizer

https://nvidia.github.io/TensorRT-Model-Optimizer/index.html

安装

pip install "nvidia-modelopt[all]" --extra-index-url https://pypi.nvidia.com

resnet50实验

先用resnet简单实验跑通int8量化导出onnx模型和转TensorRT 

from transformers import AutoImageProcessor, ResNetForImageClassification
import torch
from diffusers.utils import load_image
import modelopt.torch.quantization as mtq

# https://huggingface.co/microsoft/resnet-50
processor = AutoImageProcessor.from_pretrained("resnet_50")
model = ResNetForImageClassification.from_pretrained("resnet_50")

img_url = "cat1.jpg"

image = load_image(img_url).resize((512, 512))
inputs = processor(image, return_tensors="pt")

pixel_values = inputs["pixel_values"]
data_loader=[pixel_values]

def forward_loop(model):
    for batch in data_loader:
        model(batch)

# mtq.INT8_SMOOTHQUANT_CFG
# Quantize the model and perform calibration (PTQ)
model = mtq.quantize(model, mtq.INT8_DEFAULT_CFG, forward_loop)

torch.onnx.export(model,  # model being run
                  (pixel_values),  # model input (or a tuple for multiple inputs)
                  "resnet50_quant.onnx",   # where to save the model (can be a file or file-like object)
                  export_params=True,        # store the trained parameter weights inside the model file
                  opset_version=15,          # the ONNX version to export the model to
                  do_constant_folding=True,  # whether to execute constant folding for optimization
                  input_names=['pixel_values'],   # the model's input names
                  output_names=['output'],  # the model's output names
                  dynamic_axes={'pixel_values': {0: 'batch'}},
                  )

可见核心流程为定义一个根据校准数据推理的校准函数,设置一个量化配置,然后用这两个作为quantize的输入进行量化插入量化节点。最后导出插入量化节点的onnx模型,并且使用tensorrt trtexec转换该onnx模型。

使用trtexec转模型,查看里面的性能评估。还可以用trt-engine-explorer查看trt模型结构和算子性能。

v100测试上述int8模型

Latency: min = 1.51245 ms, max = 1.69751 ms, mean = 1.54279 ms

fp16模型

Latency: min = 0.972412 ms, max = 1.14563 ms, mean = 0.993796 ms

为啥这里int8反而比fp16更慢呢?实际上我看通过上述导出的onnx模型中,batch norm并没有fuse到conv里面,插入了量化反量化算子进一步阻值了该融合。而fp16的模型batch norm进行了融合从而性能更好。如下图是量化的onnx模型中可以看到bn没有融合到conv。而实际上trt-engine-explorer中显示的算子实际上int8 conv更好,但是bn耗时也挺大。

可以考虑直接对onnx进行融合conv+bn后再进行量化

TensorRT-Model-Optimizer/onnx_ptq/README.md at main · NVIDIA/TensorRT-Model-Optimizer · GitHub

量化配置

关闭某些层量化

stable diffusion量化

Ref

TensorRT-Model-Optimizer/diffusers/quantization at main · NVIDIA/TensorRT-Model-Optimizer · GitHub

  • 3
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
注:本文将以 YOLOv5 为例,介绍如何使用 LibTorch 和 Torch TensorRT 对 TorchScript 模型进行加速推理。本文默认读者已经熟悉 YOLOv5 和 TorchScript 的相关知识。 1. 准备工作 在开始之前,需要先安装以下工具: - PyTorch - LibTorch - Torch TensorRT 其中,PyTorch 是用于训练 YOLOv5 模型的框架,而 LibTorch 和 Torch TensorRT 则是用于加速推理的工具。在安装完这些工具之后,需要将训练好的 YOLOv5 模型转换为 TorchScript 格式。 2. 将 YOLOv5 模型转换为 TorchScript 格式 将训练好的 YOLOv5 模型转换为 TorchScript 格式的方法有很多种,这里给出一种比较简单的方法: ```python import torch from models.experimental import attempt_load from utils.general import set_logging from torch.utils.mobile_optimizer import optimize_for_mobile def export_torchscript(weights, img_size, device='cpu'): set_logging() model = attempt_load(weights, map_location=device) img = torch.zeros((1, 3, img_size, img_size), device=device) model.eval() traced_script_module = torch.jit.trace(model, img) traced_script_module_optimized = optimize_for_mobile(traced_script_module) traced_script_module_optimized.save("yolov5s.torchscript.pt") export_torchscript(weights='yolov5s.pt', img_size=640, device='cpu') ``` 在这个函数中,我们首先加载训练好的 YOLOv5 模型,然后使用 torch.jit.trace 将模型转换为 TorchScript 格式。接着,我们使用 torch.utils.mobile_optimizer.optimize_for_mobile 对模型进行优化,最后将优化后的模型保存到磁盘上。 3. 加载 TorchScript 模型 在 C++ 中加载 TorchScript 模型需要使用 LibTorch,下面是加载模型的代码: ```cpp #include <torch/script.h> // One-stop header. int main(int argc, const char* argv[]) { // Load the model. torch::jit::script::Module module; try { // Deserialize the ScriptModule from a file using torch::jit::load(). module = torch::jit::load("yolov5s.torchscript.pt"); } catch (const c10::Error& e) { std::cerr << "error loading the model\n"; return -1; } return 0; } ``` 在这个代码中,我们使用 torch::jit::load 函数加载 TorchScript 模型。如果加载失败,将输出错误信息并返回 -1,否则返回 0。 4. 使用 Torch TensorRT 进行推理 为了加速 TorchScript 模型的推理,我们可以使用 Torch TensorRT。下面是使用 Torch TensorRT 进行推理的代码: ```cpp #include <torch/script.h> // One-stop header. #include <iostream> #include <memory> #include <vector> #include <chrono> #include <NvInferRuntime.h> int main(int argc, const char* argv[]) { // Load the model. torch::jit::script::Module module; try { // Deserialize the ScriptModule from a file using torch::jit::load(). module = torch::jit::load("yolov5s.torchscript.pt"); } catch (const c10::Error& e) { std::cerr << "error loading the model\n"; return -1; } // Create a TensorRT engine from the TorchScript module. nvinfer1::IRuntime* runtime = nvinfer1::createInferRuntime(gLogger); nvinfer1::ICudaEngine* engine = createCudaEngine(module, runtime, batchSize, kINPUT_BLOB_NAME, kOUTPUT_BLOB_NAME, maxWorkspaceSize); if (!engine) { std::cerr << "error creating the engine\n"; return -1; } // Create a TensorRT execution context. nvinfer1::IExecutionContext* context = engine->createExecutionContext(); if (!context) { std::cerr << "error creating the context\n"; return -1; } // Prepare inputs and outputs. std::vector<float> inputData(batchSize * inputSize * inputSize * 3); std::vector<float> outputData(batchSize * outputSize * outputSize * (5 + numClasses)); void* buffers[] = {inputData.data(), outputData.data()}; // Run inference. auto start = std::chrono::high_resolution_clock::now(); context->execute(batchSize, buffers); auto end = std::chrono::high_resolution_clock::now(); std::chrono::duration<double, std::milli> elapsed = end - start; std::cout << "elapsed time: " << elapsed.count() << " ms\n"; // Release resources. context->destroy(); engine->destroy(); runtime->destroy(); return 0; } ``` 在这个代码中,我们首先使用 createCudaEngine 函数将 TorchScript 模型转换为 TensorRT engine。接着,我们创建 TensorRT execution context,准备输入和输出数据,并调用 context->execute 进行推理。最后,我们释放资源。 5. 总结 本文介绍了如何使用 LibTorch 和 Torch TensorRT 对 TorchScript 模型进行加速推理。在实际应用中,我们可以根据自己的需求对代码进行修改和优化,以达到更好的性能和效果。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Luchang-Li

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值