TensorRT Python中cuMemcpyHtoDAsync报错invalid argument求助
解决TensorRT中
cuMemcpyHtoDAsync failed: invalid argument错误及相关问题 一、核心错误分析与修复
1. CUDA内存拷贝参数顺序错误
你的do_inference函数中cuda.memcpy_htod_async的参数顺序完全颠倒,这是触发错误的直接原因。该API要求第一个参数是设备内存地址,第二个是主机内存地址,你当前的调用把两者搞反了。
修复后的代码:
def do_inference(context, bindings, inputs, outputs, stream): # 修正参数顺序:设备内存在前,主机内存在后 [cuda.memcpy_htod_async(i, inp, stream) for i, inp in zip(bindings[:len(inputs)], inputs)] context.execute_async(bindings=bindings, stream_handle=stream.handle) [cuda.memcpy_dtoh_async(out, o, stream) for out, o in zip(outputs, bindings[len(inputs):])] stream.synchronize()
2. CUDA上下文重复初始化与资源泄漏
allocate_buffers函数中每次都执行cuda.init()和device.make_context(),会重复初始化CUDA并创建新的设备上下文,导致资源冲突。应将这些操作移到全局代码中,避免重复执行:
修改全局初始化部分:
# 全局初始化CUDA,仅执行一次 cuda.init() device = cuda.Device(0) ctx = device.make_context() # 加载引擎 engine = trt.Runtime(trt.Logger(trt.Logger.WARNING)).deserialize_cuda_engine(open("Modelle/best.engine", "rb").read()) context = engine.create_execution_context() # 如果是动态batch引擎,必须设置输入形状(根据你的模型调整) # context.set_binding_shape(0, (1, 3, 640, 640))
同时修改allocate_buffers函数,移除重复的CUDA初始化代码,并改用实际batch size分配内存:
def allocate_buffers(engine, batch_size=1): inputs = [] outputs = [] bindings = [] stream = cuda.Stream() for binding in engine: # 用实际batch size代替max_batch_size,避免内存分配不匹配 size = trt.volume(engine.get_binding_shape(binding)) * 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_mem) else: outputs.append(host_mem) return inputs, outputs, bindings, stream
调用时传入实际batch size:
inputs, outputs, bindings, stream = allocate_buffers(engine, batch_size=1)
3. 输入数据赋值错误
你直接用inputs[0] = np.ascontiguousarray(...)替换了页锁定内存对象,导致实际拷贝的不是预先分配的页锁定内存。正确做法是将数据拷贝到已分配的页锁定内存中:
# 预处理图像 image = cv2.resize(image, (640, 640)) image = cv2.cvtColor(image, cv2.COLOR_BGR2RGB) # 若模型用RGB输入,需添加此转换 image = np.transpose(image, (2, 0, 1)) image = np.expand_dims(image, axis=0) # 准备输入数据并拷贝到页锁定内存 input_data = np.ascontiguousarray(image, dtype=np.float32) / 255.0 np.copyto(inputs[0], input_data.flatten()) # 展平后拷贝到页锁定内存
二、引擎加载的注意事项
你的引擎加载代码本身无根本性错误,但需注意:
- 确保当前TensorRT、CUDA、cuDNN版本与导出引擎时的环境完全一致,版本不兼容会导致反序列化失败或运行时错误。
- 若引擎是动态shape类型,必须在创建context后调用
context.set_binding_shape设置输入形状,否则推理时会触发错误。 - 可通过
print(engine.get_binding_shape(0))检查引擎输入形状,确认与预处理后的图像形状(如(1,3,640,640))匹配。
三、其他图像目标检测标注方法
常用标注工具
- LabelImg:轻量级桌面工具,支持PASCAL VOC和YOLO格式,适合单类别/少量类别的矩形标注。
- LabelMe:支持多边形、关键点、线段等复杂标注,导出JSON格式,可转换为其他格式。
- CVAT:开源大规模数据集标注平台,支持多人协作、自动标注辅助,适合工业级项目。
- VGG Image Annotator (VIA):浏览器端工具,无需安装,支持自定义标注类型。
- MakeSense.AI:在线工具,简单易用,支持批量标注和多种导出格式。
主流标注格式
- YOLO格式:每个图像对应一个TXT文件,每行包含类别ID、归一化后的x_center、y_center、width、height。
- PASCAL VOC格式:XML文件,包含图像信息、边界框坐标、类别等。
- COCO格式:JSON文件,适合大规模数据集,支持目标检测、分割、关键点等多种标注类型。
内容的提问来源于stack exchange,提问作者Peter T.
相关产品推荐
相关产品推荐

