PaddlePaddle / Paddle-Lite

PaddlePaddle High Performance Deep Learning Inference Engine for Mobile and Edge (飞桨高性能深度学习端侧推理引擎)
https://www.paddlepaddle.org.cn/lite
Apache License 2.0
6.89k stars 1.6k forks source link

paddle静态图推理正常,转nb格式后输出不稳定 #10479

Closed zeroameli closed 3 months ago

zeroameli commented 3 months ago

为使您的问题得到快速解决,在建立 Issue 前,请您先通过如下方式搜索是否有相似问题: 历史 issue, FAQ 文档, 官方文档

建立 issue 时,为快速解决问题,请您根据使用情况给出如下信息:

def pd_i_infer(img): path_prefix = './inference_model/model' paddle.enable_static() exe = paddle.static.Executor(paddle.CPUPlace()) [inference_program, feed_target_names, fetch_targets] = ( paddle.static.load_inference_model(path_prefix, exe)) results = exe.run(inference_program, feed={feed_target_names[0]: img}, fetch_list=fetch_targets) return results

def pd_infer(img):

使用paddle-lite从inference_model转换成nb格式

model_dir = './mb_face_x86.nb'
config = MobileConfig()
config.set_model_from_file(model_dir)
predictor = create_paddle_predictor(config)
input_tensor = predictor.get_input(0)
input_tensor.from_numpy(img)
predictor.run()
output_tensor = predictor.get_output(0)
output_data = output_tensor.numpy()
return output_data

112*112的人脸图片

f_im = './face.png' image = cv2.imread(f_im, cv2.IMREADUNCHANGED) , encoded_image = cv2.imencode('.jpg', image) jpeg_image = cv2.imdecode(encoded_image, -1) jpeg_image = np.array(jpeg_image) img = jpeg_image.transpose((2, 0, 1)) img = (img - 127.5) / 127.5 imgs = np.array([img], dtype='float32')

静态图推理

rs = pd_i_infer(imgs) kpts1 = rs[0][0] rs = pd_i_infer(imgs) kpts2 = rs[0][0] np_pts1 = np.array(kpts1) np_pts2 = np.array(kpts2) print('=========check===============') if np.array_equal(np_pts1, np_pts2): print('same') else: print('diff')

预期输出:same,实际输出:same

paddle-lite推理

rs = pd_infer(imgs) kpts1 = rs[0] rs = pd_infer(imgs) kpts2 = rs[0] np_pts1 = np.array(kpts1) np_pts2 = np.array(kpts2) print('=========check===============') if np.array_equal(np_pts1, np_pts2): print('same') else: print('diff')

预期输出:same,实际可能输出:diff


- 问题描述:
   - nb转换命令:paddle_lite_opt --model_dir=./inference_model  --optimize_out=mb_fece_x86 --optimize_out_type=naive_buffer --valid_targets=x86
   - 为什么使用paddle静态图推理能得到稳定输出,而转成nb格式后,输出会变得不稳定。
csy0225 commented 3 months ago

你好,请帮忙回答下下面的问题哈。输出变得不稳定是如何理解的?是静态图推理每次推理结果都一样,但是paddlelite每次推理结果不一样么?还是说是paddlelite的推理结果和静态图推理结果不一样?如果不一样,paddlelite的检测结果是对的么?

zeroameli commented 3 months ago

你好,请帮忙回答下下面的问题哈。输出变得不稳定是如何理解的?是静态图推理每次推理结果都一样,但是paddlelite每次推理结果不一样么?还是说是paddlelite的推理结果和静态图推理结果不一样?如果不一样,paddlelite的检测结果是对的么?

不稳定是指:对于相同的输入,是静态图推理每次推理结果都一样,但是paddlelite每次推理结果可能不一样,并且paddle-lite的结果有可能对,也有可能错

另外,我调整测试脚本发现,重复单次推理相同的图片才会得到稳定正确的输出,代码如下:

import cv2
import numpy as np
import paddle
from paddlelite.lite import *

def pd_i_infer(img):
    path_prefix = './inference_model/model'
    paddle.enable_static()
    exe = paddle.static.Executor(paddle.CPUPlace())
    [inference_program, feed_target_names, fetch_targets] = (
        paddle.static.load_inference_model(path_prefix, exe))
    results = exe.run(inference_program,
                      feed={feed_target_names[0]: img},
                      fetch_list=fetch_targets)
    return results

def pd_infer(img):
    # 使用paddle-lite从inference_model转换成nb格式
    model_dir = './mb_face_x86.nb'
    config = MobileConfig()
    config.set_model_from_file(model_dir)
    predictor = create_paddle_predictor(config)
    input_tensor = predictor.get_input(0)
    input_tensor.from_numpy(img)
    predictor.run()
    output_tensor = predictor.get_output(0)
    output_data = output_tensor.numpy()
    return output_data

# 112*112的人脸图片
f_im = './face.png'
image = cv2.imread(f_im, cv2.IMREAD_UNCHANGED)
_, encoded_image = cv2.imencode('.jpg', image)
jpeg_image = cv2.imdecode(encoded_image, -1)
jpeg_image = np.array(jpeg_image)
img = jpeg_image.transpose((2, 0, 1))
img = (img - 127.5) / 127.5
imgs = np.array([img], dtype='float32')
# paddle-lite推理
rs = pd_infer(imgs)
kpts1 = rs[0]
# 保存结果
with open('debug_nb.txt', 'a') as f:
    f.write("{}\n".format(json.dumps(kpts1.tolist())))

上述代码只做单次推理并保存结果到文件,重复执行该代码推理得到多个结果,然后对比结果是一致的,是不是paddle-lite重复实例化predictor会影响推理效果。

csy0225 commented 3 months ago

这个看着像是demo 程序变量生命周期的问题,您可以尝试在外面创建一个 predictor,然后每次读取数据多次run。或者尝试使用 output_tensor.numpy().copy() 方法,应该都可以解决这个问题。

zeroameli commented 3 months ago

@csy0225 使用output_tensor.numpy().copy()后正常了,感觉解答:)