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

PyTorch版YOLOv5与YOLOv7多进程推理模型加载路径错误咨询

多进程加载YOLOv5与YOLOv7推理的路径冲突及相关问题解答

我需要在同一项目中通过多进程(支持CPU或GPU)分别加载PyTorch版YOLOv5与YOLOv7进行推理,但出现模型加载路径错误。报错显示加载YOLOv5时,torch.load从YOLOv7的models.common模块中找不到'C3'属性。

项目结构

project_root/
├── yolov5/
│   ├── models/
│   │   ├── common.py
│   │   └── yolo.py
│   └── utils/
├── yolov7/
│   ├── models/
│   │   ├── common.py
│   │   └── yolo.py
│   └── utils/
└── inference.py

核心代码(inference.py)

import torch
import multiprocessing as mp
import sys
import os

def load_yolov5():
    # 设置路径
    sys.path.insert(0, './yolov5')
    from models.common import C3  # 确保能找到YOLOv5的C3
    model = torch.load('./yolov5/yolov5s.pt', map_location='cpu')
    print("YOLOv5加载成功")
    # 推理逻辑...

def load_yolov7():
    # 设置路径
    sys.path.insert(0, './yolov7')
    from models.common import Conv  # 确保能找到YOLOv7的模块
    model = torch.load('./yolov7/yolov7.pt', map_location='cpu')
    print("YOLOv7加载成功")
    # 推理逻辑...

if __name__ == '__main__':
    # 设置环境变量尝试解决路径问题
    os.environ['PYTHONPATH'] = './yolov5:./yolov7'
    p1 = mp.Process(target=load_yolov5)
    p2 = mp.Process(target=load_yolov7)
    p1.start()
    p2.start()
    p1.join()
    p2.join()

完整报错栈

Traceback (most recent call last):
  File "<string>", line 1, in <module>
  File "/usr/lib/python3.8/multiprocessing/spawn.py", line 116, in spawn_main
    exitcode = _main(fd, parent_sentinel)
  File "/usr/lib/python3.8/multiprocessing/spawn.py", line 125, in _main
    prepare(preparation_data)
  File "/usr/lib/python3.8/multiprocessing/spawn.py", line 236, in prepare
    _fixup_main_from_path(data['init_main_from_path'])
  File "/usr/lib/python3.8/multiprocessing/spawn.py", line 287, in _fixup_main_from_path
    main_content = runpy.run_path(main_path,
  File "/usr/lib/python3.8/runpy.py", line 265, in run_path
    return _run_module_code(code, init_globals, run_name,
  File "/usr/lib/python3.8/runpy.py", line 94, in _run_module_code
    _run_code(code, mod_globals, init_globals,
  File "/home/user/project/inference.py", line 10, in <module>
    load_yolov5()
  File "/home/user/project/inference.py", line 8, in load_yolov5
    model = torch.load('./yolov5/yolov5s.pt', map_location='cpu')
  File "/home/user/.local/lib/python3.8/site-packages/torch/serialization.py", line 713, in load
    return _load(opened_zipfile, map_location, pickle_module, **pickle_load_args)
  File "/home/user/.local/lib/python3.8/site-packages/torch/serialization.py", line 1049, in _load
    result = unpickler.load()
AttributeError: Can't get attribute 'C3' on <module 'models.common' from '/home/user/project/yolov7/models/common.py'>

问题解答

1. 为何torch.serialization的load函数设置断点后无法调试?

  • torch.load底层依赖Python的pickle模块反序列化模型,pickle加载时直接执行类/函数的导入逻辑,且多进程spawn模式下,子进程是重新启动解释器加载主模块,断点无法被子进程继承。
  • 反序列化过程中大量操作由C扩展实现,Python调试器无法跟踪C层代码,导致断点无法触发。

2. 为何设置环境变量仍无法找到正确路径获取'C3'属性?

  • 环境变量PYTHONPATH优先级低于sys.path.insert(0, ...),且多进程spawn模式下,子进程会重新执行主模块代码,两个进程的sys.path会互相干扰:比如YOLOv7进程先将./yolov7插入sys.path头部,导致YOLOv5进程加载时,Python优先从YOLOv7的models.common导入,而该模块没有C3类(YOLOv7用的是命名不同的同类结构模块)。
  • torch.load反序列化时,会根据模型保存时的模块路径查找类,当两个YOLO版本的模块同名时,必然出现路径混淆。

3. 如何实现两模型多进程(单GPU环境下亦可)推理?

  • 方案1:重命名模块目录避免冲突
    将yolov5的models目录改为yolov5_models,yolov7的改为yolov7_models,修改各自代码中的导入路径,确保模块名唯一,从根源避免路径混淆。
  • 方案2:子进程内严格隔离sys.path
    在每个子进程函数中,先清空sys.path,再仅添加当前YOLO版本的路径,彻底隔离两个版本的导入环境:
    def load_yolov5():
        sys.path = []  # 清空原有路径
        sys.path.insert(0, './yolov5')
        sys.path.insert(0, os.path.dirname(os.path.abspath(__file__)))  # 确保能加载自身模块
        from models.common import C3
        model = torch.load('./yolov5/yolov5s.pt', map_location='cpu')
        # 推理逻辑
    
  • 方案3:单GPU下用线程+锁控制推理
    单GPU环境下可改用线程代替进程,提前加载好两个模型,推理时加锁避免GPU资源冲突:
    import threading
    lock = threading.Lock()
    
    def infer_yolov5(img):
        with lock:
            results = model_v5(img)
        return results
    
    def infer_yolov7(img):
        with lock:
            results = model_v7(img)
        return results
    
  • 方案4:用torch.hub加载官方预训练模型
    直接调用官方实现的torch.hub.load加载模型,官方已处理好模块隔离:
    model_v5 = torch.hub.load('ultralytics/yolov5', 'yolov5s', pretrained=True)
    model_v7 = torch.hub.load('WongKinYiu/yolov7', 'yolov7', pretrained=True)
    

4. 同一项目能否混用不同版本的YOLO?

完全可以,但必须解决模块命名冲突和路径隔离问题:

  • 要确保不同YOLO版本的核心模块(如models.common)不会被Python解释器混淆,要么重命名模块目录,要么在加载时严格隔离sys.path。
  • 不同YOLO版本的依赖库可能存在版本差异,建议用虚拟环境隔离,或确保项目依赖同时兼容两个版本的YOLO(比如PyTorch版本满足两者要求)。

内容的提问来源于stack exchange,提问作者season

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.22 03:39:33