作者​:昇腾实战派
知识地图​:https://blog.csdn.net/Lumos_Lovegood/article/details/161601003

1.背景

InsightFace是一个开源的、基于深度学习的2D和3D人脸分析工具箱,广泛应用于人脸识别、人脸检测和人脸对齐等任务。该工具箱以其高效的算法实现和在公开基准测试中的优异表现而著称。在实际部署中,常需要将基于ONNX格式的人脸识别模型迁移至NPU平台进行推理加速。本文记录了在迁移过程中遇到的精度问题及其定位与解决过程,涉及ResNet50@WebFace600K和ResNet100@Glint360K两个模型。

2.问题描述

首先使用LFW数据集对两个原生ONNX模型在CPU上进行精度测试,正确率均在98%以上。然而,将ResNet50@WebFace600K模型迁移至NPU后,正确率骤降至50%左右,无法对齐CPU精度。经过排查,该问题得到解决。但采用相同迁移方法处理ResNet100@Glint360K模型时,正确率仅为40%左右。

3.定位流程

ResNet50@WebFace600K

由于正确率接近随机猜测,直接选取一个badcase进行分析。使用以下代码读取同一人的两张人脸图片(Abel_Pacheco_0001和Abel_Pacheco_0004),计算人脸embedding并求取余弦相似度。CPU上相似度为0.74,NPU上仅为0.1左右。

def cosine_similarity(feat1, feat2):
    feat1 = feat1 / np.linalg.norm(feat1)
    feat2 = feat2 / np.linalg.norm(feat2)
    return np.dot(feat1, feat2)

if __name__ == '__main__':
    parser = argparse.ArgumentParser(description='FaceAnalysis')
    parser.add_argument('--device', default=0)
    parser.add_argument('--p1')
    parser.add_argument('--p2')
    args = parser.parse_args()

    path1 = args.p1
    path2 = args.p2
    device = int(args.device)
    app = FaceAnalysis(name='antelopev2', device=device)
    app.prepare(ctx_id=0, det_size=(640, 640))
    img1 = cv2.imread(path1)
    img2 = cv2.imread(path2)
    faces1 = app.get(img1)
    faces2 = app.get(img2)

    emb1 = faces1[0].embedding
    emb2 = faces2[0].embedding

    sim = cosine_similarity(emb1, emb2)
    print(sim)

使用mist debug compare工具对ONNX模型和OM模型各算子的输出进行精度对比(工具使用方法见链接)。对比结果显示,第一个存在精度问题的算子在CPU和NPU上的输出余弦相似度为0.748。进一步排查发现,模型转换时默认将所有算子转换为fp16格式,怀疑是精度降级导致的问题。由于目标平台(Atlas 800I A2)支持fp32格式,将模型转换为fp32后,精度恢复正常。

在这里插入图片描述

ResNet100@Glint360K

参考上一个模型的经验,将该模型也转换为fp32格式执行,但发现人脸相似度为NaN,且embedding值中出现正无穷和负无穷。查看dump数据,发现CPU和NPU上第一个有精度问题的算子输出的相似度为0(如下图所示)。分析认为,fp32格式在该模型中存在数值溢出问题。将模型转换为fp16格式后,精度恢复正常。

在这里插入图片描述

4.解决方案

ResNet50@WebFace600K

精度问题源于归一化算子在fp16格式下的精度损失。解决方案是在atc模型转换命令中添加参数--precision_mode=must_keep_origin_dtype,保持模型原有的fp32格式。

ResNet100@Glint360K

该模型在fp32格式下存在数值溢出问题,因此atc命令中不加--precision_mode=must_keep_origin_dtype参数,将模型转换为fp16格式即可解决。

Logo

鲲鹏昇腾开发者社区是面向全社会开放的“联接全球计算开发者,聚合华为+生态”的社区,内容涵盖鲲鹏、昇腾资源,帮助开发者快速获取所需的知识、经验、软件、工具、算力,支撑开发者易学、好用、成功,成为核心开发者。

更多推荐