简介
张量分解通过分解卷积核的张量,将一个卷积转化成两个小卷积的堆叠来降低推理开销,如用户模型中存在大量卷积,且卷积核shape普遍大于(64, 64, 3, 3)时推荐使用张量分解。目前仅支持满足如下条件的卷积进行分解:
- group=1,dilation=(1,1),stride<3
- kernel_h>2,kernel_w>2
卷积是否分解由昇腾模型压缩工具自动判断,即便满足上述条件,也不一定会分解;例如,用户使用的PyTorch原始模型中存在torch.nn.Conv2d层,且该层满足上述条件,才有可能将相应的Conv2d层分解成两个Conv2d层。
通常情况下,分解后模型的精度会比原始模型有所下降,因此在分解之后,需通过finetune(微调)来提高精度。最后使用昇腾模型压缩工具将分解后的模型转换成可以在昇腾AI处理器部署的量化模型,以便在模型推理时获得更好的性能。
该场景为可选操作,用户自行决定是否进行原始模型的分解。
分解约束
如果torch.nn.Conv2d层的权重shape过大,会造成分解时间过长或分解异常中止,为防止出现该情况,执行分解动作前,请先参见如下约束或参考数据:
- 分解工具性能参考数据:
- CPU: Intel(R) Xeon(R) CPU E5-2699 v4 @ 2.20GHz
- 内存: 512G
分解单层卷积:
- shape(512, 512, 5, 5),大约耗时7秒。
- shape(1024, 1024, 3, 3),大约耗时12秒。
- shape(1024, 1024, 5, 5),大约耗时52秒。
- shape(2048, 2048, 3, 3),大约耗时89秒。
- shape(2048, 2048, 5, 5),大约耗时374秒。
- 内存超限风险提醒:
分解大卷积核存在内存超限风险参考数值:分解shape为(2048, 2048, 5, 5)的卷积核约需9G内存。
分解方式
张量分解有两种使用方式,在线张量分解和离线张量分解,用户可以根据实际情况选择其中一个方式进行分解。详细说明如下:
- 在线张量分解
即直接分解原始网络模型并进行finetune:在训练代码中引入张量分解接口,对已包含预训练权重的模型进行分解,然后进行finetune。
该流程在张量分解时直接修改模型结构并更新权重,分解后的模型可直接使用,其优点是使用方便,仅需一步操作;而缺点是每次调用脚本都要重新进行分解计算,需要耗费一定时间。
- 离线张量分解
即先分解原始网络模型,然后再进行finetune:首先将含有预训练权重的模型调用张量分解接口进行分解,保存分解信息文件和分解后的权重;后续使用时,在训练脚本中引入张量分解接口,读取保存的分解信息文件对模型结构进行分解,然后加载保存的分解后的权重,再进行finetune。
该流程先将分解信息和分解后的权重保存下来,然后在finetune时快速加载使用,其优点是可以一次分解,多次使用,使用时加载几乎不耗费时间;而缺点是需要两步操作,且需保存分解后的权重并在使用时加载