QAT训练OP融合

1.芯片型号:J5

2.天工开物开发包OpenExplorer版本:J5_OE_1.1.49b

3.问题定位:QAT中算子融合

4.问题具体描述

地平线官网手册,和torch相关手册都看了一遍,感觉云里雾里。

问题1、QAT训练过程中,需要自定义:def fuse_model(self)和def set_qconfig(self):感觉太麻烦,有没有更简单点的方法,比如类似于PTQ一样,能够自动融合OP,不需要手动掌控每层融合策略?如果有,编写范式能够指导下吗?我这边只需求常规融合策略(例如:常见的conv bn relu之间的两两融合)?

问题2:比如在网络各个模块的成员如何调用 convert_fx、fuse_fx,实现实现fuse_model, set_qconfig函数类似功能,为了快速走通QAT流程,实现自动融合OP

你好,关于问题1,在49版本中有一个示例ddk/samples/ai_toolchain/horizon_model_train_sample/plugin_basic/,里面有fx和eager两种模式的简单使用,可以只关注fx模式的,这种模式不需要手动进行算子融合,关于两者的区别可见:https://developer.horizon.ai/forumDetail/118364000835765840。

关于问题2,我们已经在开始写关于这块的基础示例教程了,也有一些社区用户反馈他们也在尝试梳理这块那内容,等出来后会第一时间更新到这里:https://developer.horizon.ai/forumDetail/146176821770230117,欢迎持续关注。

在yolov3中,例如配置文件对应为:ai_toolchain/horizon_model_train_sample/scripts/configs/detection/yolov3/pascalvoc_mobilenetv1.py

网络定义了如下模块,为什么只有backbone中插入了量化、反量化节点,neck、head中也有conv等操作,却没有插入量化节点。

model = dict(-
type=“YOLOV3”,-
backbone=dict(-
type=“MobileNetV1”,-
alpha=1.0,-
bn_kwargs=bn_kwargs,-
num_classes=num_classes,-
include_top=False,-
),-
neck=dict(-
type=“YOLOV3Neck”,-
backbone_idx=[-1, -2, -3],-
in_channels_list=[1024, 512, 256],-
out_channels_list=[512, 256, 128],-
bn_kwargs=bn_kwargs,-
),-
head=dict(-
type=“YOLOV3Head”,-
feature_idx=[-3, -2, -1],-
in_channels_list=[1024, 512, 256],-
num_classes=num_classes,-
anchors=anchors,-
bn_kwargs=bn_kwargs,-
),-
loss=dict(-
type=“YOLOV3Loss”,-
num_classes=num_classes,-
anchors=anchors,-
strides=[8, 16, 32],-
ignore_thresh=0.5,-
loss_xy=dict(type=torch.nn.BCELoss, reduce=False),-
loss_wh=dict(type=torch.nn.L1Loss, reduce=False),-
loss_conf=dict(type=torch.nn.BCELoss, reduction=“sum”),-
loss_cls=dict(type=torch.nn.BCELoss, reduction=“sum”),-
lambda_loss=[2.0, 2.0, 1.0, 1.0],-
),-
postprocess=dict(-
type=“YOLOV3PostProcess”,-
anchors=anchors,-
strides=[8, 16, 32],-
num_classes=num_classes,-
score_thresh=0.01,-
nms_thresh=0.45,-
topK=200,-
),-
)

您好,QAT使用的首要流程就是在model输入端插入量化节点,输出端插入反量化节点,在yolov3/pascalvoc_mobilenetv1.py示例中,输入端是backbone(mobilenetv1),输出端是YOLOV3Head,所以在hat/model/backbones/mobilenetv1.py路径下的forward函数中插入了量化节点,这里config文件中设置了include_top=False:-

在YOLOV3Head的forward函数中hat/models/task_modules/yolo/head.py路径下的forward函数中插入了反量化节点:-

解决了,6666,顺便问下:ConvModule2d 这个模块如何init,有接口吗?

您好,我们在hat中提供了初始化方式,导入方式为from hat.models.weight_init import kaiming_init,normal_init