TensorRt与模型量化

部署运行你感兴趣的模型镜像

1) TensorRT 是什么,它解决什么问题?

TensorRT 是 NVIDIA 的深度学习推理 SDK,用来把训练好的模型优化并生成高性能的 GPU 推理引擎(Builder→Engine→ExecutionContext),主要目标是降低延迟与提高吞吐。

  1. Builder 是 TensorRT 中负责 构建(compile/optimize)推理网络 的对象。

主要工作

  • 解析网络结构(ONNX / API 定义)

  • 算子融合、层合并、内存复用优化

  • 精度选择(FP32 / FP16 / INT8)

  • tactic 选择(选择每个算子最优的实现 kernel,比如 cuDNN/cublas/cuTensor)

  • 创建 optimization profiles(动态 shape 的 min/opt/max 范围)

  1. Engine

ICudaEngine 对象,代表了一个 优化过的推理模型。
是一个“可执行的模型程序(类似一个二进制可执行文件)”。

它包含了:

  • 网络的拓扑结构

  • 内存分配(workspace / weights layout)

  • 选择好的算子实现(tactics)

  • 优化 profile(如果有动态输入)

特点

  • 不可修改(Engine 是优化后冻结的,不能再改算子/结构)

  • 可以 序列化 / 反序列化:

  • 序列化 → 保存为 .plan 文件

  • 反序列化 → 加载回来直接用,不用重新 build

  1. ExecutionContext

一个 Engine 可以创建多个 ExecutionContext → 支持多线程 / 并发推理

  1. ONNX 导出不通过怎么办?
  1. torch 和 onnx 版本
  2. 动态 shape / dynamic_axes 设置问题 -1(动态
  3. opset

3)如果量化(INT8)精度下降明显,你会怎么办?

  1. 混合精度(Fallback )
    不是所有层都必须 INT8,可以 只量化计算密集的层(卷积/全连接),其余保持 FP16/FP32。

  2. per-channel scale
    让每个通道都充分利用 INT8 的数值范围,避免某些通道的数值被压扁。

4)怎么评估量化效果?
精度层面:在验证集跑任务指标(分类 Top-1/Top-5,检测 mAP),量化前后对比精度下降幅度。

数值层面:计算输出张量的 MSE / Max Error / Cosine similarity,判断量化误差大小。

您可能感兴趣的与本文相关的镜像

TensorRT-v8.6

TensorRT-v8.6

TensorRT

TensorRT 是NVIDIA 推出的用于深度学习推理加速的高性能推理引擎。它可以将深度学习模型优化并部署到NVIDIA GPU 上,实现低延迟、高吞吐量的推理过程。

### 使用 TensorRT 对 YOLO 模型进行 INT8 量化 TensorRT 是 NVIDIA 提供的一个高性能深度学习推理库,支持模型的优化和部署。INT8 量化是一种降低模型精度的技术,通过将浮点数(FP32 或 FP16)转换为整数(INT8),可以显著减少模型的大小并提高推理速度,同时尽量保持模型的精度[^2]。 以下是一个使用 TensorRT 对 YOLO 模型进行 INT8 量化的教程: #### 1. 准备环境 确保安装了以下依赖项: - NVIDIA TensorRT - CUDA 和 cuDNN - Python 和相关库(如 NumPy、ONNX) ```bash pip install nvidia-pyindex pip install tensorrt ``` #### 2. 将 YOLO 模型导出为 ONNX 格式 TensorRT 支持 ONNX 格式的模型导入。如果原始模型是 PyTorch 格式,可以使用以下代码将其导出为 ONNX: ```python import torch import torch.onnx # 加载 PyTorch 模型 model = torch.load("yolo_model.pth") model.eval() # 导出为 ONNX 格式 dummy_input = torch.randn(1, 3, 640, 640) # 输入张量形状 torch.onnx.export(model, dummy_input, "yolo_model.onnx", opset_version=11) ``` #### 3. 使用 TensorRT 构建 INT8 引擎 以下是构建 INT8 引擎的步骤: ```python import tensorrt as trt def build_int8_engine(onnx_file_path, calibration_cache_path): TRT_LOGGER = trt.Logger(trt.Logger.WARNING) with trt.Builder(TRT_LOGGER) as builder, \ builder.create_network(1 << int(trt.NetworkDefinitionCreationFlag.EXPLICIT_BATCH)) as network, \ trt.OnnxParser(network, TRT_LOGGER) as parser: builder.max_workspace_size = 1 << 30 # 1GB builder.precision_mode = trt.PrecisionMode.INT8 # 配置校准器 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_size dtype = trt.nptype(engine.get_binding_dtype(binding)) host_mem = cuda.pagelocked_empty(size, dtype) device_mem = cuda.mem_alloc(host_mem.nbytes) bindings.append(int(device_mem)) if engine.binding_is_input(binding): inputs.append({'host': host_mem, 'device': device_mem}) else: outputs.append({'host': host_mem, 'device': device_mem}) return inputs, outputs, bindings, stream # 解析 ONNX 文件 with open(onnx_file_path, 'rb') as model: if not parser.parse(model.read()): print('Failed to parse the ONNX file.') for error in range(parser.num_errors): print(parser.get_error(error)) return None # 设置 INT8 校准器 class Int8EntropyCalibrator(trt.IInt8EntropyCalibrator2): def __init__(self, data_loader, cache_file): trt.IInt8EntropyCalibrator2.__init__(self) self.data_loader = data_loader self.cache_file = cache_file self.input_blob_name = "input_0" # 替换为实际输入名称 self.device_input = cuda.mem_alloc(self.data_loader.calibration_data[0].nbytes) def get_batch_size(self): return self.data_loader.batch_size def get_batch(self, names): try: batch = next(self.data_loader) cuda.memcpy_htod(self.device_input, batch) return [int(self.device_input)] except StopIteration: return None def read_calibration_cache(self): if os.path.exists(self.cache_file): with open(self.cache_file, "rb") as f: return f.read() def write_calibration_cache(self, cache): with open(self.cache_file, "wb") as f: f.write(cache) calib = Int8EntropyCalibrator(data_loader, calibration_cache_path) builder.int8_calibrator = calib # 构建引擎 engine = builder.build_cuda_engine(network) return engine ``` #### 4. 运行推理 构建好 INT8 引擎后,可以使用以下代码运行推理: ```python def infer(engine, input_data): inputs, outputs, bindings, stream = allocate_buffers(engine) with engine.create_execution_context() as context: inputs[0]['host'] = input_data [cuda.memcpy_htod_async(inp['device'], inp['host'], stream) for inp in inputs] context.execute_async_v2(bindings=bindings, stream_handle=stream.handle) [cuda.memcpy_dtoh_async(out['host'], out['device'], stream) for out in outputs] stream.synchronize() return [out['host'] for out in outputs] ``` #### 5. 校准数据集 为了生成校准缓存文件,需要准备一个小型校准数据集。该数据集应包含模型输入张量的样本。 ```python class DataLoader: def __init__(self, dataset_path, batch_size): self.dataset_path = dataset_path self.batch_size = batch_size self.calibration_data = self.load_data() def load_data(self): # 加载数据集并预处理 pass def __iter__(self): for i in range(0, len(self.calibration_data), self.batch_size): yield self.calibration_data[i:i+self.batch_size] ``` --- ### 注意事项 - INT8 量化可能会导致模型精度下降,因此需要仔细选择校准数据集以最小化精度损失。 - 校准过程是离线完成的,不会影响推理时的性能[^2]。 - 如果模型定义复杂,可能需要参考 PyTorch 的静态量化教程以更好地理解量化过程[^3]。 --- ###
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值