meituan / YOLOv6

YOLOv6: a single-stage object detection framework dedicated to industrial applications.
GNU General Public License v3.0
5.72k stars 1.03k forks source link

一旦脱离了yolov6的repo,torch.load('path/to/yolov6s.pt')将失效报错 #278

Closed Bin-ze closed 2 years ago

Bin-ze commented 2 years ago

yolov6.pt中似乎保存了整个模型的结构,一旦在load的时候找不到对应的文件,将引发报错,我认为这是一种很不好用的写法,也可能因为我太无知了吧,总之,很奇怪,我认为的权重就是应该超脱于模型而存在,而不是存在上述的这种耦合。感谢您做出的贡献,但是是不是可能存在更好的写法去保存模型以支持rep-model呢? 如有叨扰,实属得罪

mtjhl commented 2 years ago

PyTorch 保存的权重都得在项目文件夹进行 load,如果您想在任何地方运行模型,可以转成 onnx 模型,用 onnx-runtime 运行 onnx 模型;或者转成 TRT 模型,使用 TensorRT 运行;

Bin-ze commented 2 years ago

PyTorch 保存的权重都得在项目文件夹进行 load吗?他应该不依赖于项目文件吧,那这样的话我自己复现了网络架构,难道不可以使用官方的checkpoints吗,那些backbone预训练权重也不能加载了,因为他不在原来的那个项目文件夹下。我想知他必须依赖项目文件夹的原因是不是rep操作本身,您的回答让我更加困惑了

hiyyg commented 2 years ago

@Bin-ze 这是因为他们用的yolov5那套写法(代码质量一言难尽),存了module而不是state_dict, 如果要任何地方都能load,需要存state_dict,例如https://github.com/Megvii-BaseDetection/YOLOX/blob/48fd2a95837a92e0583492210b5ebeb02a4e7d7d/yolox/core/trainer.py#L359

Bin-ze commented 2 years ago

如果这样写的话,那么将不支持rep操作,因为模型的fuse依赖于这样的权重保存方式,通过直接读到整个moudle,去遍历层并融合参数,我想要知道的是如果只保存state_dict,那么推理加速时的fuse操作应该是怎样的?

zhiqwang commented 2 years ago

这个跟rep 没关系吧,而且也有办法hack的

https://github.com/zhiqwang/yolov5-rt-stack/blob/c6482cfce9b779d88511071c98e7dbd0ac901576/yolort/v5/helper.py#L15-L29

或者把这个封装成一个装饰器也可以

Bin-ze commented 2 years ago

这个跟rep 没关系吧,而且也有办法hack的

https://github.com/zhiqwang/yolov5-rt-stack/blob/c6482cfce9b779d88511071c98e7dbd0ac901576/yolort/v5/helper.py#L15-L29

或者把这个封装成一个装饰器也可以

非常感谢你的回复,hack方法是通过一个上下文管理器吗,请问可以具体一点吗(我很菜),我还是没有理解怎样通过上下文管理器实现load,而且我查看了源码https://github.com/meituan/YOLOv6/blob/f8f9627b1471c39571409684cbb8614873198aac/yolov6/utils/torch_utils.py#L85, 这样的写法应该是为这样的模型保存方式服务的吧?(如果说错了,请纠正我),我的目的是使用hook+runner+register重新复现yolov6,但是在模型保存以及推理rep部分,我不清楚怎样实现(如果完全照搬yolov6,似乎是不可行的),请问您有什么好的建议吗,或者一些具体的建议,如果可以抽出时间帮我解答,我不胜感激!

zhiqwang commented 2 years ago

如果你自己去复现v6,那就无所谓了呀,随便用自己觉着舒服的方式呗

CchenDdong commented 2 years ago

手动添加yolov6路径,在yolov6/core/inferer.py添加以下代码可暂时解决该问题 import sys import os sys.path.append(os.path.join(os.path.dirname(os.path.abspath(__file__)), "../../"))

Qiang-Feng98 commented 2 years ago

这种方式必须在相同工程路径下才行,我在工程A中加载YOLOV6的预训练权重,最简单的方法就是把源码中的yolov6文件夹直接复制到A工程中,在其他工程中sys.path的方法并不好用。还有可以重新load后再保存下来,但是这种方式我不会。最简单的就是直接复制过去,当一个文件夹。如有更好的方法请指教我一下下。