You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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.

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.31 17:15:34