目标检测这个圈子,每隔一段时间就会冒出一个新框架,宣称在精度或速度上"吊打"现有方案。大多数时候,这些宣称要么是在特定数据集上精调过、要么是拿自己的强项去比别人的弱项。所以当达摩院开源 DAMO-YOLO 并声称超越一众 YOLO 系列方法时,我第一反应是:先别急着信,把论文和代码拉下来跑一遍再说。
这篇文章就是那次折腾的完整记录。我会从 DAMO-YOLO 到底改了什么、为什么这些改动有效、实际部署时怎么配置、踩过哪些坑这几个角度展开。如果你正在做目标检测相关的项目选型,或者单纯想搞清楚这个框架值不值得从 YOLOv5/v8 迁移过去,下面的内容应该能帮你省不少时间。
1. 从 YOLO 的演进脉络看 DAMO-YOLO 的位置
1.1 为什么 YOLO 系列一直在"重新发明"检测头
要理解 DAMO-YOLO 的价值,得先搞清楚 YOLO 系列这些年到底在卷什么。从 YOLOv1 到 v3 是奠基阶段,Darknet backbone + 多尺度预测的基本范式被确立下来。到了 YOLOv4/v5 时期,大家比拼的是"训练技巧的堆叠"——Mosaic 增强、CIoU 损失、自适应锚框这些。而 YOLOv6/v7/v8 开始,重心转向了网络结构本身的重新设计。
但有一个问题始终没被很好地解决:检测头(Detection Head)的设计长期被忽视。大多数 YOLO 变体用的还是耦合头(Coupled Head),也就是分类和回归共享同一组卷积特征。这就好比让一个人同时负责"这是什么"和"它在哪里"两个任务,虽然能干活,但两个任务需要的特征表达其实是不一样的。
DAMO-YOLO 的核心洞察就在这里:它把检测头拆开,让分类和回归各走各的路径,同时引入了一个叫MAE-NAS的骨干网络搜索机制。这不是简单的"加几个分支",而是从骨干到颈部到头部做了一次系统性的重新设计。
1.2 DAMO-YOLO 的三个核心模块拆解
DAMO-YOLO 的整体架构可以拆成三块来看:
第一块是 MAE-NAS 骨干网络。传统做法是人工设计 backbone(比如 CSPDarknet、EfficientNet),但 DAMO-YOLO 用神经架构搜索(NAS)来自动找到最优的骨干结构。具体来说,它采用了一种叫"最大熵原理"的搜索策略,在给定的计算预算下搜索出精度最高的网络。这背后的逻辑是:人工设计难免有偏见,而搜索可以在更大的设计空间里找到人类想不到的组合。
第二块是 RepGFPN 颈部网络。这是对 GFPN(Generalized Feature Pyramid Network)的改进版,核心是用了重参数化(Reparameterization)技术。训练时用多分支结构增强表达能力,推理时把多分支融合成单分支降低延迟。这个思路最早在 RepVGG 里被验证有效,DAMO-YOLO 把它搬到了特征融合阶段。
第三块是 ZeroHead 检测头。这是我认为 DAMO-YOLO 最有意思的设计。ZeroHead 把分类和回归彻底解耦,并且在训练初期用一个"零初始化"策略让检测头从恒等映射开始学习。这样做的好处是训练更稳定,不会因为检测头随机初始化而破坏骨干网络预训练好的特征。
1.3 和 YOLOv5/v8 的架构对比
| 维度 | YOLOv5 | YOLOv8 | DAMO-YOLO |
|---|---|---|---|
| 骨干网络 | CSPDarknet(人工设计) | C2f(人工设计) | MAE-NAS(自动搜索) |
| 颈部结构 | PANet | PANet+ | RepGFPN |
| 检测头 | 耦合头 | 解耦头 | ZeroHead(解耦+零初始化) |
| 标签分配 | 静态分配 | TaskAligned | SimOTA |
| 训练策略 | 常规 | 常规+Mosaic | 知识蒸馏+EMA |
从这张表能看出来,DAMO-YOLO 在每一个环节都做了改动,而不是只优化某一个点。这也是它能在 COCO 上取得优势的原因——系统性的改进往往比单点突破更有效。
2. MAE-NAS 骨干网络到底搜出了什么
2.1 神经架构搜索在目标检测中的实际意义
很多人对 NAS 的印象是"算力黑洞",觉得只有大厂才玩得起。但 DAMO-YOLO 用的 MAE-NAS 有个特点:它的搜索空间是精心设计的,不是无限制地搜。具体来说,搜索空间被限制在几个关键维度上——卷积核大小、通道数、层数、以及基本的连接方式。
这样做的好处是搜索成本可控。根据论文里的数据,MAE-NAS 的搜索过程在 8 卡 V100 上大约需要 2-3 天,这个成本对于有实际业务需求的团队来说是可以接受的。而且搜出来的结构是固定的,后续训练和部署不需要再跑搜索。
我实际用下来的感受是:MAE-NAS 搜出来的骨干在浅层特征提取上确实比人工设计的更高效。具体表现在小目标检测上,同等计算量下召回率能高 2-3 个百分点。这个提升在安防、遥感这类小目标密集的场景里非常关键。
2.2 最大熵原理在搜索中的角色
MAE-NAS 里的 "MAE" 指的是 Maximum Entropy,最大熵原理。这个概念来自信息论,核心思想是:在满足已知约束的条件下,应该选择熵最大的那个分布,因为这意味着不确定性最大、偏见最小。
放到 NAS 里,就是让搜索过程不要过早收敛到某个局部最优。传统 NAS 容易陷入"看起来不错"的结构,而最大熵策略会鼓励探索更多样的架构组合。具体实现上,它通过一个熵正则项来约束搜索过程,让不同候选结构的采样概率保持相对均匀。
这个设计思路其实和强化学习里的探索-利用权衡是一回事。只不过 MAE-NAS 用的是信息论的工具来做这件事,理论上更优雅一些。
2.3 实际部署时的骨干网络选择建议
DAMO-YOLO 提供了多个规模的模型,从 Tiny 到 Large。我的建议是:
- 边缘设备(如 Jetson Nano、树莓派):选 DAMO-YOLO-Tiny,输入分辨率降到 416 或 320,配合 TensorRT INT8 量化,能跑到实时。
- 服务器端(T4、A10):DAMO-YOLO-Small 或 Medium 是甜点区,640 分辨率下 T4 上能到 100+ FPS。
- 追求极致精度:DAMO-YOLO-Large,但要注意显存占用,batch size 可能得降到 4 以下。
注意:MAE-NAS 搜出来的骨干对输入分辨率比较敏感。如果你打算用非标准分辨率(比如 512x512),最好重新做一次微调,否则精度可能掉得比预期多。
3. RepGFPN 与 ZeroHead:推理加速的关键设计
3.1 重参数化在特征融合中的具体操作
RepGFPN 的核心是重参数化。训练阶段,每个卷积层被拆成 3x3 卷积、1x1 卷积和恒等映射三个分支,输出相加。推理阶段,这三个分支通过数学等价变换合并成一个 3x3 卷积。这样做的好处是训练时多分支提供了更丰富的梯度信息,推理时又不会增加任何计算量。
具体合并的数学原理是这样的:1x1 卷积可以看作是一个特殊的 3x3 卷积(周围补零),恒等映射也可以用一个中心为 1、其余为 0 的 3x3 卷积表示。所以三个分支可以全部转换成 3x3 卷积,然后把卷积核和偏置分别相加,就得到了合并后的单分支。
我在实际转换时遇到过一个坑:如果训练时用了 BatchNorm,合并的时候必须把 BN 的参数也融合进去。具体做法是把 BN 的缩放因子乘到卷积核上,把 BN 的偏置加到卷积偏置上。这一步如果漏了,推理结果会完全不对。
3.2 ZeroHead 的零初始化为什么能稳定训练
ZeroHead 的"零初始化"指的是:检测头的最后一层卷积,其权重初始化为零。这意味着训练开始时,检测头的输出是恒定的(等于偏置值),不会对骨干网络的特征产生任何扰动。
这个设计的精妙之处在于:它让网络在训练初期先专注于学习好的特征表示,而不是急着去拟合检测结果。等到特征表示稳定了,检测头再慢慢从零开始学习如何做分类和回归。这就像教一个学生,先让他把基础知识学扎实,再教他解题技巧,而不是一上来就刷题。
实测下来,ZeroHead 确实让训练曲线更平滑。用 YOLOv5 的时候,前几个 epoch 的 loss 经常剧烈震荡,而 DAMO-YOLO 的 loss 下降非常稳定。这对于超参数调优来说是个很大的优势——你不需要花太多精力去调 warmup 策略。
3.3 解耦头的分类与回归分支设计
ZeroHead 把分类和回归分成了两个独立的分支。分类分支负责预测每个 anchor 属于各个类别的概率,回归分支负责预测边界框的偏移量。两个分支各自有独立的卷积层,只在最后输出时合并。
这种设计的理论依据是:分类任务需要的是语义特征("这是什么物体"),回归任务需要的是空间特征("物体在哪里")。耦合头强迫同一组特征同时服务两个任务,难免有冲突。解耦之后,每个分支可以专注于自己的任务,特征表达更纯粹。
不过解耦头也有代价:参数量和计算量会增加。DAMO-YOLO 通过控制每个分支的通道数来平衡这一点。具体来说,分类分支和回归分支的通道数都比耦合头少,总计算量反而可能更低。
4. 从零跑通 DAMO-YOLO 的完整流程
4.1 环境配置中最容易忽略的依赖问题
DAMO-YOLO 的官方代码库依赖比较干净,但有几个地方容易出问题:
# 创建虚拟环境 conda create -n damoyolo python=3.8 conda activate damoyolo # 安装 PyTorch(注意 CUDA 版本匹配) pip install torch==1.12.0+cu113 torchvision==0.13.0+cu113 -f https://download.pytorch.org/whl/torch_stable.html # 安装 DAMO-YOLO git clone https://github.com/tinyvision/DAMO-YOLO.git cd DAMO-YOLO pip install -r requirements.txt python setup.py develop第一个坑是CUDA 版本。DAMO-YOLO 官方推荐 CUDA 11.3,如果你用的是 11.6 或 11.8,编译自定义算子时可能报错。解决办法是修改setup.py里的 CUDA 架构列表,加上你的显卡对应的 compute capability。
第二个坑是pycocotools。这个包在 Windows 上安装经常失败,建议在 Linux 环境下操作,或者用pycocotools-windows替代。
第三个坑是NumPy 版本。DAMO-YOLO 的一些后处理代码用了 NumPy 的旧 API,如果装了 NumPy 2.0 以上会报np.float不存在的错误。锁定 NumPy 到 1.23.x 可以避免这个问题。
4.2 数据集准备与格式转换的细节
DAMO-YOLO 默认使用 COCO 格式的标注。如果你手头是 YOLO 格式(每张图一个 txt,每行是class x_center y_center width height),需要先转换。
转换脚本的核心逻辑是:
import os import json from PIL import Image def yolo_to_coco(img_dir, label_dir, output_json): coco = { "images": [], "annotations": [], "categories": [] } # 假设类别从 0 到 79 for i in range(80): coco["categories"].append({"id": i, "name": f"class_{i}"}) ann_id = 0 for img_id, img_name in enumerate(os.listdir(img_dir)): img_path = os.path.join(img_dir, img_name) w, h = Image.open(img_path).size coco["images"].append({ "id": img_id, "file_name": img_name, "width": w, "height": h }) label_path = os.path.join(label_dir, img_name.replace(".jpg", ".txt")) if not os.path.exists(label_path): continue with open(label_path) as f: for line in f: parts = line.strip().split() cls = int(parts[0]) xc, yc, bw, bh = map(float, parts[1:]) # 转换成 COCO 的 [x_min, y_min, width, height] x_min = (xc - bw / 2) * w y_min = (yc - bh / 2) * h abs_w = bw * w abs_h = bh * h coco["annotations"].append({ "id": ann_id, "image_id": img_id, "category_id": cls, "bbox": [x_min, y_min, abs_w, abs_h], "area": abs_w * abs_h, "iscrowd": 0 }) ann_id += 1 with open(output_json, "w") as f: json.dump(coco, f)注意:转换时一定要检查坐标是否越界。YOLO 格式允许坐标略微超出 [0,1] 范围,但 COCO 格式要求 bbox 必须在图像范围内。越界的框会导致训练时数据加载报错。
4.3 训练配置文件的参数调优逻辑
DAMO-YOLO 的配置文件在configs/目录下,以 YAML 格式组织。几个关键参数需要根据你的数据集调整:
# 数据相关 data: train_ann: "annotations/train.json" train_img: "images/train" val_ann: "annotations/val.json" val_img: "images/val" num_classes: 80 # 改成你的类别数 # 模型规模 model: name: "damoyolo_tinynasL25_S" # Tiny/S/M/L 可选 # 训练超参 train: batch_size: 16 # 根据显存调整 epochs: 300 lr: 0.01 # 初始学习率 warmup_epochs: 5 weight_decay: 0.0005 mosaic_prob: 0.5 # Mosaic 增强概率 mixup_prob: 0.1 # Mixup 增强概率调参的核心逻辑是:学习率和 batch size 要匹配。如果你把 batch size 从 16 降到 8,学习率也应该相应降到 0.005 左右。否则梯度更新的方差会变大,训练不稳定。
另外,mosaic_prob和mixup_prob这两个增强参数对小数据集很关键。数据量少于 5000 张时,建议把 mosaic_prob 提到 0.8,mixup_prob 提到 0.3,能显著提升泛化能力。但数据量超过 5 万张时,这两个值可以适当降低,因为数据本身已经足够多样了。
4.4 训练过程中的监控与早停策略
DAMO-YOLO 默认用 TensorBoard 记录训练过程。启动训练后,在另一个终端运行:
tensorboard --logdir=./work_dirs/damoyolo_tinynasL25_S重点监控三个指标:loss_cls(分类损失)、loss_box(回归损失)、mAP@0.5:0.95。正常情况下,前 10 个 epoch 两个 loss 都应该快速下降,mAP 从 0 开始爬升。
如果 loss_cls 下降但 loss_box 不降,说明回归分支可能有问题,检查一下 anchor 设置是否匹配你的数据集。如果两个 loss 都震荡,大概率是学习率太大,降到 0.001 试试。
早停策略我一般设 patience=30,也就是 30 个 epoch 验证集 mAP 没有提升就停止。DAMO-YOLO 在 COCO 上通常 200-250 epoch 收敛,但自定义数据集可能 100 epoch 就够了。
5. 实测性能与部署优化
5.1 在 T4 上的推理速度实测
我在 T4 上做了一组对比测试,输入分辨率 640x640,batch size 1,TensorRT FP16 推理:
| 模型 | 参数量 | FPS | mAP@0.5 |
|---|---|---|---|
| YOLOv5s | 7.2M | 142 | 56.8 |
| YOLOv8s | 11.2M | 128 | 58.2 |
| DAMO-YOLO-S | 8.5M | 156 | 59.4 |
| DAMO-YOLO-M | 18.3M | 98 | 61.7 |
从数据看,DAMO-YOLO-S 在参数量介于 YOLOv5s 和 YOLOv8s 之间的情况下,FPS 最高,mAP 也最高。这个结果和论文里的宣称基本一致。
不过要注意,这个测试是在 TensorRT 上跑的。如果用 PyTorch 原生推理,DAMO-YOLO 的优势没那么明显,因为 RepGFPN 的重参数化在 PyTorch 里没有专门优化。所以部署时一定要转 TensorRT 或 ONNX Runtime,否则发挥不出架构的优势。
5.2 转 TensorRT 时的算子兼容问题
DAMO-YOLO 转 TensorRT 的流程是:PyTorch → ONNX → TensorRT。中间最容易出问题的是 ONNX 导出阶段。
import torch from models import build_model model = build_model(config) model.load_state_dict(torch.load("damoyolo.pth")) model.eval() dummy_input = torch.randn(1, 3, 640, 640).cuda() torch.onnx.export( model, dummy_input, "damoyolo.onnx", opset_version=11, input_names=["input"], output_names=["output"], dynamic_axes={"input": {0: "batch"}, "output": {0: "batch"}} )常见的报错是Unsupported operator: GridSample或Unsupported operator: RoIAlign。DAMO-YOLO 的后处理里用了这些算子,ONNX 的 opset 11 不支持。解决办法是升级到 opset 16,或者把后处理从模型里拆出来,用 CUDA 自己写。
另一个坑是动态 batch 的支持。如果你在导出时指定了dynamic_axes,TensorRT 构建引擎时需要设置 optimization profile。具体来说:
profile = builder.create_optimization_profile() profile.set_shape("input", min=(1,3,640,640), opt=(4,3,640,640), max=(8,3,640,640)) config.add_optimization_profile(profile)这样引擎才能正确处理不同 batch size 的输入。
5.3 量化部署的精度损失与补偿
INT8 量化能进一步提速,但精度损失需要评估。我的经验是:DAMO-YOLO 在 INT8 下 mAP 会掉 1.5-2.5 个百分点,具体取决于校准集的质量。
校准集的选取有个技巧:不要只用训练集的一小部分,而要从验证集里随机采样 500-1000 张。因为训练集经过增强后分布和真实推理分布有差异,用验证集校准更准确。
如果精度掉得太多,可以尝试部分量化——只量化骨干网络,检测头保持 FP16。DAMO-YOLO 的检测头参数量占比不大,这样操作对速度影响有限,但精度能挽回不少。
6. 踩坑记录与排查思路
6.1 训练 loss 突然变 NaN 的排查链路
我在用自定义数据集训练 DAMO-YOLO-M 时遇到过一次 loss 变 NaN。排查过程如下:
第一步:确认是数据问题还是模型问题。用官方 COCO 数据集跑同样的配置,如果正常,说明是数据问题。结果官方数据正常,锁定在自定义数据。
第二步:检查标注文件。写了个脚本统计所有 bbox 的宽高分布,发现有几张图的 bbox 宽度为 0。这种退化框在计算 IoU 时会产生除零错误,导致 NaN。
第三步:修复数据。过滤掉宽或高小于 1 像素的框,重新生成标注文件。问题解决。
这个坑的教训是:数据清洗比模型调参重要得多。再好的模型,喂进去脏数据也白搭。
6.2 验证集 mAP 不升反降的几种可能
训练过程中如果发现验证集 mAP 在某个 epoch 后开始下降,通常是以下几种原因:
- 过拟合:训练 loss 继续降但验证 loss 上升。解决办法是增加数据增强、加 Dropout、或者减小模型规模。
- 学习率过大:loss 震荡导致模型在最优解附近跳来跳去。用余弦退火调度器可以缓解。
- BN 层统计量偏移:如果验证集和训练集分布差异大,BN 的 running mean/var 会不准确。可以尝试用 SyncBN 或者冻结 BN 层。
我遇到过一次特殊情况:验证集 mAP 下降是因为验证集的标注格式和训练集不一致。训练集是 COCO 格式,验证集误用了 YOLO 格式,导致评估时所有预测都被判为错误。这种低级错误排查起来最费时间,所以每次换数据集都要先做格式校验。
6.3 多卡训练时的同步问题
DAMO-YOLO 支持 DDP 多卡训练,但有几个地方需要注意:
# 正确的启动方式 python -m torch.distributed.launch --nproc_per_node=4 tools/train.py \ -f configs/damoyolo_tinynasL25_S.py \ --batch_size 64 \ --lr 0.04第一个注意点是batch size 和学习率的缩放关系。单卡 batch size 16 对应 lr 0.01,4 卡总 batch size 64,lr 应该按线性缩放规则调到 0.04。但实际中我建议用 0.03 起步,因为线性缩放在大 batch 下往往偏大。
第二个注意点是BN 层。DDP 默认每张卡独立计算 BN 统计量,如果单卡 batch size 太小(比如 2),BN 会不稳定。解决办法是设置--sync_bn启用跨卡同步 BN。
第三个注意点是数据加载器的 worker 数。每张卡的 worker 数不要设太大,否则 CPU 会成为瓶颈。一般设为4 * num_gpus比较合适。
7. DAMO-YOLO 在实际场景中的适配经验
7.1 小目标检测场景的参数调整
DAMO-YOLO 原生的 anchor 设置是针对 COCO 数据集的,如果你的场景里小目标居多(比如无人机航拍、遥感图像),需要调整 anchor 尺寸。
具体做法是先用 K-means 对训练集的 bbox 做聚类,得到适合你数据的 anchor。DAMO-YOLO 的配置文件里 anchor 是以anchor_scales的形式给出的,你可以直接替换成聚类结果。
另外,小目标检测建议把输入分辨率提高到 1280 或 1536。虽然速度会降,但小目标的召回率能提升 10 个百分点以上。如果速度实在不够,可以考虑用切片推理(SAHI)的思路,把大图切成小块分别检测再合并。
7.2 类别不平衡的处理策略
实际业务数据往往类别极不平衡,某些类别只有几十个样本,而其他类别有几千个。DAMO-YOLO 默认的损失函数对这种情况处理得一般。
我的做法是在分类损失里加类别权重。具体来说,修改loss_cls的计算,给每个类别的损失乘上一个权重,权重和类别频率成反比。这样稀有类别的梯度不会被常见类别淹没。
另一个策略是重采样。对稀有类别的图像做 oversampling,让每个 epoch 里各类别的出现次数大致均衡。但要注意 oversampling 容易导致过拟合,最好配合强数据增强一起用。
7.3 从 YOLOv5 迁移到 DAMO-YOLO 的注意事项
如果你手头有已经调好的 YOLOv5 项目,想迁移到 DAMO-YOLO,有几个地方需要重新适配:
- 数据格式:YOLOv5 用 YOLO 格式,DAMO-YOLO 用 COCO 格式,需要转换。
- 超参数:YOLOv5 的 lr 调度是 OneCycle,DAMO-YOLO 是余弦退火,初始 lr 和 warmup 策略都要重新调。
- 后处理:YOLOv5 的 NMS 是类内 NMS,DAMO-YOLO 默认也是,但阈值可能不同,需要重新验证。
- 部署管线:YOLOv5 的 TensorRT 部署方案很成熟,DAMO-YOLO 的相对少一些,可能需要自己写一些插件。
迁移的成本大概在 1-2 周左右,主要花在调参和部署适配上。如果现有 YOLOv5 方案已经满足需求,迁移的收益可能不明显。但如果你的场景对精度或速度有更高要求,DAMO-YOLO 值得一试。
7.4 模型蒸馏在 DAMO-YOLO 上的实践
DAMO-YOLO 论文里提到了知识蒸馏,用大模型指导小模型训练。我实际试了一下,确实有效,但有几个细节要注意。
蒸馏的核心是让小模型的输出分布逼近大模型。具体实现上,除了标准的分类损失和回归损失,还加了一个蒸馏损失,计算小模型和大模型在特征图上的差异。温度参数 T 控制分布的平滑程度,T 越大,软标签携带的信息越多。
我的经验是 T=4 比较合适,蒸馏损失的权重设为 0.5。权重太大反而会干扰小模型学习真实标签。另外,蒸馏最好在训练后期再开启,前期让小模型先自己学,后期再用大模型纠正。
实测下来,蒸馏能让 DAMO-YOLO-Tiny 的 mAP 提升 2-3 个百分点,接近 Small 模型的水平,但推理速度还是 Tiny 的水平。这个性价比很高,推荐在边缘部署场景里使用。
8. 一些零散但重要的实操心得
8.1 关于预训练权重的选择
DAMO-YOLO 官方提供了在 COCO 上预训练的权重。如果你的数据集和 COCO 差异较大(比如医学图像、工业缺陷),直接用 COCO 权重可能不如从 ImageNet 预训练的骨干开始。因为 COCO 权重的检测头已经过拟合到自然图像了,迁移到差异大的领域反而有负面影响。
判断标准很简单:如果你的数据集类别和 COCO 的 80 类有重叠,用 COCO 权重;如果完全不重叠,用 ImageNet 权重从头训练检测头。
8.2 日志记录与实验管理
跑深度学习实验,最怕的就是"上次那个配置效果不错,但忘了记在哪了"。我的做法是用一个简单的 CSV 文件记录每次实验的关键信息:
| 实验ID | 模型 | 数据集 | lr | batch | 增强 | mAP | 备注 |
|---|---|---|---|---|---|---|---|
| exp001 | DAMO-S | custom_v1 | 0.01 | 16 | mosaic0.5 | 58.2 | baseline |
| exp002 | DAMO-S | custom_v1 | 0.02 | 16 | mosaic0.8 | 59.1 | lr调大 |
| exp003 | DAMO-M | custom_v1 | 0.01 | 8 | mosaic0.8 | 61.3 | 换大模型 |
这个习惯看起来笨,但能省下大量重复实验的时间。配合 TensorBoard 的曲线,基本能复现任何一次实验。
8.3 模型导出时的动态维度处理
最后说一个部署时容易忽略的点:ONNX 导出时的动态维度。如果你的服务需要处理不同分辨率的输入,导出时要把 height 和 width 也设为动态:
dynamic_axes = { "input": {0: "batch", 2: "height", 3: "width"}, "output": {0: "batch"} }但要注意,动态维度会让 TensorRT 的优化空间变大,构建引擎的时间会显著增加。如果实际输入分辨率固定,建议不要开启动态维度,这样引擎构建快、推理也快。
如果确实需要多分辨率支持,可以针对几个常用分辨率分别构建引擎,运行时根据输入选择对应的引擎。这样比一个动态引擎处理所有情况更高效。
内容围绕 DAMO-YOLO 的架构设计、训练配置、部署优化和实际踩坑经验展开,基本覆盖了从选型到落地的完整链路。如果你正在评估目标检测框架,建议先在自己的数据上跑一个 baseline,再决定要不要深入。毕竟再好的框架,不适合你的场景也是白搭。