小模型在昇腾NPU上的推理部署:【InsightFace人脸识别模型迁移精度对齐案例】
作者昇腾实战派知识地图https://blog.csdn.net/Lumos_Lovegood/article/details/1616010031.背景InsightFace是一个开源的、基于深度学习的2D和3D人脸分析工具箱广泛应用于人脸识别、人脸检测和人脸对齐等任务。该工具箱以其高效的算法实现和在公开基准测试中的优异表现而著称。在实际部署中常需要将基于ONNX格式的人脸识别模型迁移至NPU平台进行推理加速。本文记录了在迁移过程中遇到的精度问题及其定位与解决过程涉及ResNet50WebFace600K和ResNet100Glint360K两个模型。2.问题描述首先使用LFW数据集对两个原生ONNX模型在CPU上进行精度测试正确率均在98%以上。然而将ResNet50WebFace600K模型迁移至NPU后正确率骤降至50%左右无法对齐CPU精度。经过排查该问题得到解决。但采用相同迁移方法处理ResNet100Glint360K模型时正确率仅为40%左右。3.定位流程ResNet50WebFace600K由于正确率接近随机猜测直接选取一个badcase进行分析。使用以下代码读取同一人的两张人脸图片Abel_Pacheco_0001和Abel_Pacheco_0004计算人脸embedding并求取余弦相似度。CPU上相似度为0.74NPU上仅为0.1左右。defcosine_similarity(feat1,feat2):feat1feat1/np.linalg.norm(feat1)feat2feat2/np.linalg.norm(feat2)returnnp.dot(feat1,feat2)if__name____main__:parserargparse.ArgumentParser(descriptionFaceAnalysis)parser.add_argument(--device,default0)parser.add_argument(--p1)parser.add_argument(--p2)argsparser.parse_args()path1args.p1 path2args.p2 deviceint(args.device)appFaceAnalysis(nameantelopev2,devicedevice)app.prepare(ctx_id0,det_size(640,640))img1cv2.imread(path1)img2cv2.imread(path2)faces1app.get(img1)faces2app.get(img2)emb1faces1[0].embedding emb2faces2[0].embedding simcosine_similarity(emb1,emb2)print(sim)使用mist debug compare工具对ONNX模型和OM模型各算子的输出进行精度对比工具使用方法见链接。对比结果显示第一个存在精度问题的算子在CPU和NPU上的输出余弦相似度为0.748。进一步排查发现模型转换时默认将所有算子转换为fp16格式怀疑是精度降级导致的问题。由于目标平台Atlas 800I A2支持fp32格式将模型转换为fp32后精度恢复正常。ResNet100Glint360K参考上一个模型的经验将该模型也转换为fp32格式执行但发现人脸相似度为NaN且embedding值中出现正无穷和负无穷。查看dump数据发现CPU和NPU上第一个有精度问题的算子输出的相似度为0如下图所示。分析认为fp32格式在该模型中存在数值溢出问题。将模型转换为fp16格式后精度恢复正常。4.解决方案ResNet50WebFace600K精度问题源于归一化算子在fp16格式下的精度损失。解决方案是在atc模型转换命令中添加参数--precision_modemust_keep_origin_dtype保持模型原有的fp32格式。ResNet100Glint360K该模型在fp32格式下存在数值溢出问题因此atc命令中不加--precision_modemust_keep_origin_dtype参数将模型转换为fp16格式即可解决。