在pycharm中的console中调用yolov8代码的bug

简述问题

最近项目在使用yolov8,我个人习惯在pycharm中的console中逐行测试代码,但在pycharm的console中执行yolov8的示例代码报了完全看不懂的错误
具体的报错信息
在这里插入图片描述
报错代码

Traceback (most recent call last):
  File "<string>", line 1, in <module>
  File "D:\python387\lib\multiprocessing\spawn.py", line 123, in spawn_main
    exitcode = _main(fd, parent_sentinel)
  File "D:\python387\lib\multiprocessing\spawn.py", line 136, in _main
    prepare(preparation_data)
  File "D:\python387\lib\multiprocessing\spawn.py", line 252, in prepare
    _fixup_main_from_path(data['init_main_from_path'])
  File "D:\python387\lib\multiprocessing\spawn.py", line 304, in _fixup_main_from_path
    main_content = runpy.run_path(main_path,
  File "D:\python387\lib\runpy.py", line 265, in run_path
    code, fname = _get_code_from_file(run_name, path_name)
  File "D:\python387\lib\runpy.py", line 234, in _get_code_from_file
    with io.open_code(decoded_path) as f:
OSError: [Errno 22] Invalid argument: 'D:\\yolo\\<input>'

从报错信息看,它是在调用multiprocessing的模块中出现问题
而奇怪的是在cmd中调用python 命令行模式下执行相同代码却没有这种报错,反而是能正常调用的
最初以为是python的版本不兼容,换成了python3.10的版本依旧出现同样的错误,然后以为是pycharm的版本兼容问题,换了低版本的pycharm,依旧没用。
查看后台发现在调用后台时主进程同时启动多个子进程去进行训练,如果是熟悉multiprocessing的应该知道,multiprocessing调用pool时,一般将代码封装到函数或者类里面然后在__main__去调用,我试了一下,将代码放到__main__中去调用,然后整个脚本去运行,果然是能出结果的,而不放到__main__中,则会出现同样的错误,就是如下,第一种写法跟第二种写法的区别。但这也不是我想要的结果,我还是想逐行调试,查看每一步的输出,以达到跟cmd调用时逐行输入调试同样的效果。

# 第一种写法,这种写法会出现报错
from ultralytics import YOLO
model = YOLO("yolov8n.yaml")  # build a new model from scratch
model = YOLO("yolov8n.pt")  # load a pretrained model (recommended for training)
model.train(data="coco128.yaml", epochs=1)
# 第二种写法,这种写法本质一样,但是不会出现报错
from ultralytics import YOLO

def main():
    model = YOLO("yolov8n.yaml")  # build a new model from scratch
    model = YOLO("yolov8n.pt")  # load a pretrained model (recommended for training)
    # Use the model
    model.train(data="coco128.yaml", epochs=3)  # train the model


if __name__ == '__main__':
    main()

没办法只能细看代码了。总结来说其实就是pycharm中的环境变量参数略有不同导致的。
具体问题出在prepare函数中的传参preparation_data,在cmd中打印这个preparation_data以及在pycharm中打印preparation_data他们的输出如下:

cmd中的python,preparation_data输出
{'log_to_stderr': False, 'authkey': b'\xb2h\xb73\xa1\xcbx\xd0\xdb\x9f20\xe2\xbfO\xc3\x0f|{\xc1\x9a\xf7\xb6G\xa1\x14d\x02\xd6\xa0\xe8\xf2', 'name': 'Process-24', 'sys_path': ['D:\\yolo', 'D:\\python387\\python38.zip', 'D:\\python387\\DLLs', 'D:\\python387\\lib', 'D:\\python387', 'D:\\python387\\lib\\site-packages'], 'sys_argv': [''], 'orig_dir': 'D:\\yolo', 'dir': 'D:\\yolo', 'start_method': 'spawn'}

pycharm console的preparation_data输出
{'log_to_stderr': False, 'authkey': b'\xa6;t~\xb3\\\x16hC=\xb4G\x8f\x81\xbaoNHqg\xb9j\xad\x0b~bq\xb2\xa7;F\xb1', 'name': 'Process-1', 'sys_path': ['D:\\Program Files\\PyCharm 2023.1.2\\plugins\\python\\helpers\\pydev', 'D:\\Program Files\\PyCharm 2023.1.2\\plugins\\python\\helpers\\third_party\\thriftpy', 'D:\\Program Files\\PyCharm 2023.1.2\\plugins\\python\\helpers\\pydev', 'D:\\yolo', 'D:\\Program Files\\PyCharm 2023.1.2\\plugins\\python\\helpers\\pycharm_display', 'D:\\python387\\python38.zip', 'D:\\python387\\DLLs', 'D:\\python387\\lib', 'D:\\python387', 'D:\\python387\\lib\\site-packages', 'D:\\Program Files\\PyCharm 2023.1.2\\plugins\\python\\helpers\\pycharm_matplotlib_backend', 'D:\\yolo'], 'sys_argv': ['D:/Program Files/PyCharm 2023.1.2/plugins/python/helpers/pydev/pydevconsole.py', '--mode=client', '--host=127.0.0.1', '--port=62180'], 'orig_dir': 'D:\\yolo', 'dir': 'D:\\yolo', 'start_method': 'spawn', 'init_main_from_path': 'D:\\yolo\\<input>'}

细看的话可以发现,pycharm中的preparation_data出现了’init_main_from_path’: ‘D:\yolo\’,跟报错信息出现的是一样的。重点就在于这个D:\yolo\,这不是个路径也不是个文件,那pycharm中定义这个东西到底有什么用?其实这个参数的作用是用于pycharm去准确定位主模块的路径位置,而代表console的输入来自输入流,而就是因为这个参数并不是指代具体的路径,导致这个参数本身并没有什么意义(就是定位主模块的路径位置,虽然另一个参数sys_path中的也会包含环境路径,但并不够具体。),而到了multiprocessing模块中就会调用这个参数的值,导致出现上述的报错。所以解决方案也很粗暴,直接把这个字典的值删掉或者修改multiprocessing的源码。
我这边直接修改multiprocessing的源码。

将:
   elif 'init_main_from_path' in data:
        _fixup_main_from_path(data['init_main_from_path'])
        改为:
    elif 'init_main_from_path' in data and '<input>' not in data['init_main_from_path']:
        _fixup_main_from_path(data['init_main_from_path'])

其实我也只是回避了这个错误,这个问题更像是pycharm跟python的multiprocessing模块本身的兼容性出现问题。因为本身运行yolov8的代码时,并不需要这个参数,这个参数更像是pycharm中特有的参数值,回避这个问题后整体的代码也能顺利执行,并且得到跟cmd调用时同样的结果了。
暂时没有发现其他项目会有冲突,希望这种方法可以帮到看到这里的你,有问题可以在下面评论留言。

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值