新增用户yolov5s支持
This commit is contained in:
parent
55a7c2f78d
commit
0521f9d2cc
|
|
@ -0,0 +1,239 @@
|
|||
# YOLOv5s 模型导入失败分析报告
|
||||
|
||||
## 问题概述
|
||||
|
||||
用户提供的 YOLOv5s ONNX 模型无法通过 Netrans/Acuity 工具链导入。
|
||||
|
||||
---
|
||||
|
||||
## 1. 问题复现
|
||||
|
||||
### 1.1 用户操作
|
||||
|
||||
用户使用以下方式导出 YOLOv5s ONNX 模型:
|
||||
- 导出工具:YOLOv5 官方 `export.py`(通过 `torch.hub` 自动下载)
|
||||
- PyTorch 版本:2.10.0
|
||||
- 导出命令:
|
||||
```bash
|
||||
python export.py --weights yolov5s.pt --include onnx --opset 11 --img 640
|
||||
```
|
||||
|
||||
### 1.2 导入失败现象
|
||||
|
||||
使用 Netrans 工具链导入时失败:
|
||||
|
||||
```bash
|
||||
netrans load yolov5s
|
||||
```
|
||||
|
||||
**报错信息**:
|
||||
```
|
||||
TypeError: unsupported operand type(s) for *: 'int' and 'shape_struct'
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 2. 问题排查过程
|
||||
|
||||
### 2.1 检查模型 Opset 版本
|
||||
|
||||
使用 `check_opset.py` 检查用户提供的 ONNX 模型:
|
||||
|
||||
```bash
|
||||
python3 check_opset.py yolov5s.onnx
|
||||
```
|
||||
|
||||
**检查结果**:
|
||||
```
|
||||
Opset 版本: 18
|
||||
```
|
||||
|
||||
**发现**:用户模型实际为 **opset 18**,但 Netrans 工具链需要 **opset 11**。
|
||||
|
||||
### 2.2 复现用户导出过程
|
||||
|
||||
为验证问题,使用与用户相同的环境复现导出过程。
|
||||
|
||||
**环境信息**:
|
||||
| 组件 | 版本 |
|
||||
|------|------|
|
||||
| Python | 3.10.19 |
|
||||
| PyTorch | 2.10.0+cu128 |
|
||||
| ONNX | 1.20.1 |
|
||||
|
||||
**使用的导出工具**:
|
||||
| 项目 | 说明 |
|
||||
|------|------|
|
||||
| 工具来源 | YOLOv5 官方仓库 (ultralytics/yolov5) |
|
||||
| 工具路径 | `~/.cache/torch/hub/ultralytics_yolov5_master/export.py` |
|
||||
| 文件大小 | 68,529 字节 |
|
||||
| 许可证 | AGPL-3.0 |
|
||||
|
||||
**复现命令**:
|
||||
```bash
|
||||
cd ~/.cache/torch/hub/ultralytics_yolov5_master
|
||||
|
||||
python export.py \
|
||||
--weights yolov5s.pt \
|
||||
--include onnx \
|
||||
--opset 11 \
|
||||
--img 640 \
|
||||
--device cpu
|
||||
```
|
||||
|
||||
### 2.3 发现 PyTorch 2.10 的 Opset 限制
|
||||
|
||||
**关键发现**:PyTorch 2.10 导出时**强制使用 opset 18**,即使显式指定 `--opset 11` 也被忽略。
|
||||
|
||||
**警告信息**:
|
||||
```
|
||||
W0305 11:06:09.976000 .../exporter/_compat.py:125]
|
||||
Setting ONNX exporter to use operator set version 18 because the requested
|
||||
opset_version 11 is a lower version than we have implementations for.
|
||||
```
|
||||
|
||||
**版本转换失败错误**:
|
||||
```
|
||||
Failed to convert the model to the target version 11 using the ONNX C API.
|
||||
The model was not modified
|
||||
|
||||
RuntimeError: .../BaseConverter.h:65: adapter_lookup:
|
||||
Assertion `false' failed: No Adapter To Version $17 for Resize
|
||||
```
|
||||
|
||||
**结论**:
|
||||
- PyTorch 2.10 使用了新的 Dynamo ONNX 导出器,不再支持 opset 降级
|
||||
- ONNX Resize 操作在 opset 17+ 和 opset 11 之间有格式差异
|
||||
- 版本转换器无法将 Resize 从 opset 17+ 降级到 opset 11
|
||||
- 最终导出模型为 **opset 18**,与 Netrans 不兼容
|
||||
|
||||
### 2.4 验证 Netrans 导入失败
|
||||
|
||||
使用 Netrans 导入 opset 18 的模型,复现用户遇到的错误:
|
||||
|
||||
```
|
||||
TypeError: unsupported operand type(s) for *: 'int' and 'shape_struct'
|
||||
```
|
||||
|
||||
**原因** Netrans 对高版本 opset 的 Resize 操作支持不完善,shape inference 失败。
|
||||
|
||||
### 2.5 尝试使用低版本 PyTorch 导出
|
||||
|
||||
为解决问题,创建 Python 3.8 + PyTorch 2.4.1 环境进行测试:
|
||||
|
||||
```bash
|
||||
# 创建新环境
|
||||
conda create -n v5s python=3.8 -y
|
||||
conda activate v5s
|
||||
pip install torch==2.4.1 onnx==1.14.0 pandas tqdm pyyaml
|
||||
```
|
||||
|
||||
**环境信息**:
|
||||
| 组件 | 版本 |
|
||||
|------|------|
|
||||
| Python | 3.8.x |
|
||||
| PyTorch | 2.4.1 |
|
||||
| ONNX | 1.14.0 |
|
||||
|
||||
**导出命令**:
|
||||
```bash
|
||||
cd yolov5_official # 项目目录下的官方代码
|
||||
|
||||
/home/xj/app/miniforge3/envs/v5s/bin/python export.py \
|
||||
--weights yolov5s.pt \
|
||||
--include onnx \
|
||||
--opset 11 \
|
||||
--img 640 \
|
||||
--device cpu
|
||||
```
|
||||
|
||||
**验证结果**:
|
||||
```bash
|
||||
python3 check_opset.py yolov5s.onnx
|
||||
# 输出: Opset 版本: 11
|
||||
```
|
||||
|
||||
**Netrans 导入验证**:
|
||||
```bash
|
||||
netrans load yolov5s
|
||||
# 导入成功,生成 yolov5s.json 和 yolov5s.data
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 3. 解决方案
|
||||
|
||||
### 3.1 根本原因
|
||||
|
||||
| 问题环节 | 具体原因 |
|
||||
|----------|----------|
|
||||
| PyTorch 2.10 限制 | 强制使用 opset 18,不支持降级到 opset 11 |
|
||||
| ONNX Resize 差异 | opset 17+ 和 opset 11 格式不兼容,无法自动转换 |
|
||||
| Netrans 兼容性 | 对 opset 18 的 Resize 操作支持不完善 |
|
||||
|
||||
### 3.2 解决步骤
|
||||
|
||||
**创建 Python 3.8 + PyTorch 2.4.1 环境**
|
||||
|
||||
```bash
|
||||
conda create -n v5s python=3.8 -y
|
||||
conda activate v5s
|
||||
pip install torch==2.4.1 onnx==1.14.0 pandas tqdm pyyaml
|
||||
```
|
||||
|
||||
**导出 ONNX 模型(opset 11)**
|
||||
|
||||
```bash
|
||||
|
||||
python export.py \
|
||||
--weights /path/to/yolov5s.pt \
|
||||
--include onnx \
|
||||
--opset 11 \
|
||||
--img 640 \
|
||||
--device cpu
|
||||
```
|
||||
|
||||
**验证并导入**
|
||||
|
||||
```bash
|
||||
# 验证 opset 版本
|
||||
python3 check_opset.py yolov5s.onnx # 应输出: Opset 版本: 11
|
||||
|
||||
# 导入
|
||||
netrans load yolov5s
|
||||
```
|
||||
|
||||
### 3.3 关键注意事项
|
||||
|
||||
⚠️ **PyTorch 版本限制**:
|
||||
- PyTorch 2.10+ 无法导出 opset 11 模型
|
||||
- 必须使用 **PyTorch <= 2.4.1**
|
||||
|
||||
### 3.4 模型对比
|
||||
|
||||
| 特性 | 用户原模型 | 修复后模型 |
|
||||
|------|-----------|-----------|
|
||||
| PyTorch 版本 | 2.10 | 2.4.1 |
|
||||
| ONNX Opset | 18 | 11 |
|
||||
| IR 版本 | 10 | 6 |
|
||||
| Resize 格式 | opset 18(不兼容) | opset 11(兼容) |
|
||||
|
||||
---
|
||||
|
||||
## 4. 相关文件
|
||||
|
||||
| 文件/目录 | 说明 |
|
||||
|-----------|------|
|
||||
| `yolov5_official/` | YOLOv5 官方代码(从 torch hub 缓存复制) |
|
||||
| `yolov5_official/export.py` | YOLOv5 官方导出脚本 |
|
||||
| `check_opset.py` | 检查 ONNX 模型 opset 版本 |
|
||||
| `user_data/yolov5s.onnx` | 使用 PyTorch 2.4.1 导出的 ONNX 模型(opset 11) |
|
||||
|
||||
---
|
||||
|
||||
## 5. 总结
|
||||
|
||||
1. **问题**:用户使用 PyTorch 2.10 导出的 ONNX 模型为 opset 18,与 Acuity 不兼容
|
||||
2. **根因**:PyTorch 2.10 强制使用 opset 18,无法降级到 opset 11
|
||||
3. **解决**:使用 PyTorch 2.4.1 重新导出 opset 11 的模型
|
||||
4. **建议**:导出 ONNX 模型时,确认 PyTorch 版本 <= 2.4.1,并验证 opset 版本
|
||||
|
|
@ -0,0 +1,10 @@
|
|||
#!/usr/bin/env python3
|
||||
import onnx
|
||||
import sys
|
||||
|
||||
if len(sys.argv) != 2:
|
||||
print(f"Usage: {sys.argv[0]} <onnx_file>")
|
||||
sys.exit(1)
|
||||
|
||||
model = onnx.load(sys.argv[1])
|
||||
print(f"Opset 版本: {model.opset_import[0].version}")
|
||||
Binary file not shown.
Binary file not shown.
Loading…
Reference in New Issue