专栏算法工具链【J6】部署模型尾部conv输出type/layout/scale解读

【J6】部署模型尾部conv输出type/layout/scale解读

Jade-self2025-03-07
75
0

1. 引言

在算法模型部署阶段,大家可能会遇到这三个问题:

  1. 为了保证精度,模型尾部conv/linear需要是int32输出

  2. 为了适配后处理代码,模型尾部conv/linear输出layout有时是NCHW的,有时是NHWC的

  3. 为什么conv/linear输出的scale会是1?这符合预期吗?

本文使用pytorch框架,以conv为例,介绍如何同时满足conv int32 + NCHW/NHWC这两种情况。另外,专开一个章节介绍scale为1的原因。

2. 输出类型/layout解读

2.1 Conv int32 + NCHW

从一个基础示例看conv输出类型与layout:

进行工具链量化转换后,输出conv情况如下图:
Description

BPU conv输出默认是NHWC的,由于pytorch框架输出是NCHW的,所以工具会在模型尾部自动加一个transpose来保证layout一致。此时,模型尾部conv输出也是int32的,符合conv int32 + NCHW预期。

2.2 Conv int32 + NHWC

  • 错误示范

进行工具链量化转换后,输出conv情况如下图:
Description

尾部conv输出layout符合预期。

尾部conv输出int16,不符合预期。原因是:在模型中,只有conv与dequant直接相连,conv才会是int32。

怎么实现conv int32 + NHWC输出呢?

  • 正确示范

在dequant后面加permute即可实现conv int32 + NHWC输出。

Description

3. 什么时候scale为1

在第2节中的示例,正常走工具链搭建QAT的流程,一般情况下,都不会出现scale为1的情况,如下图示例:箭头指向的位置都是scale的数值。

Description

什么时候scale会是1呢?首先要来了解scale=1是在什么时候生成的:在prepare初始化模型的时候,scale为1,举个例子,看scale的变化

根据上述代码,沿着这个线索来分析scale为1的可能原因。

  • 没校准,直接export导出bc文件

  • 在进行模型编译时,采用prepare后加载权重的方式,若权重中的scale为1,则编译时scale也为1

  • 在进行模型编译时,采用prepare后加载权重的方式,加载权重时,部分位置的权重没加载进去,这部分scale就会是1

scale为1一定就是错的吗?其实不一定,只能说大部分是错的。判断scale=1正确与否,跑一下模型推理,看结果是否正确即可~

4. 典型问题

问题描述:qat模型精度正常,export后的qat.bc精度不正常,且在convert+compile后发现,部分conv输出scale为1,量化类型为int16。

Description

最终原因:训练qat结束保存权重时,网络某输出结构为:

为了适配板端部署layout要求,直接修改该输出结构为:

并加载了之前训练的权重,且未关注miss key/unexpected key,此时会出现部分conv输出scale为1,量化类型为int16的问题。

算法工具链
社区征文杂谈技术深度解析
评论0
0/1000