模型插入 NV12 預處理節點精度問題排查流程
發布人:
時間:2025-09-28
來源:工程師
一、引言
二、問題確定與現象
2.1.1 關鍵術語定義
qat_nv12.bc/quantized_nv12.bc:插入 NV12 預處理節點的偽量化 / 定點 BC 模型
qat_feat.bc/quantized_feat.bc:未插入 NV12 預處理節點的偽量化 / 定點 BC 模型
2.1.2 典型現象
2.1.3 NV12 節點插入規范
resizer_input = ["resize"] # 部署時數據來源于resizer的輸入節點名稱列表
pyramid_input = ["pym"] # 部署時數據來源于pyramid的輸入節點名稱列表
# 為和歷史版本保持兼容,建議使用flatten_inputs將輸入展開,如下代碼同時兼容新舊版本模型:
for input in func.flatten_inputs[::-1]:
if input.name in pyramid_input:
# pyramid&resizer 只支持 NHWC 的 input layout,若原始輸入layout為NHWC,則無需插入transpose
node = input.insert_transpose(permutes=[0, 3, 1, 2])
# 插入前處理節點,具體可參考下一節的說明
node = node.insert_image_preprocess(mode=None, divisor=1, mean=[128, 128, 128], std=[128, 128, 128])
node.insert_image_convert("nv12")
for input in func.flatten_inputs[::-1]:
if input.name in resizer_input:
# pyramid&resizer 只支持 NHWC 的 input layout,若原始輸入layout為NHWC,則無需插入transpose
node = input.insert_transpose(permutes=[0, 3, 1, 2])
# 插入前處理節點,具體可參考下一節的說明
node = node.insert_image_preprocess(mode=None, divisor=1, mean=[128, 128, 128], std=[128, 128, 128])
node.insert_roi_resize("nv12")2.2 核心驗證思路
quantized_nv12.bc 與 quantized_feat.bc 推理結果差異顯著
qat_nv12.bc 與 quantized_nv12.bc 推理結果一致性差
def generate_nv12(img):
w,h = img.size
# Convert images to YUV format
yuv_img = img.convert('YCbCr')
y_data, u_data, v_data = yuv_img.split()
# Convert Y, U, and V channel data to byte streams
y_data_bytes = y_data.tobytes()
u_data_bytes = u_data.resize((u_data.width // 2, u_data.height // 2)).tobytes()
v_data_bytes = v_data.resize((v_data.width // 2, v_data.height // 2)).tobytes()
# Arrange the UV data in the form of UVUVUVUV...
uvuvuv_data = bytearray()
for u_byte, v_byte in zip(u_data_bytes, v_data_bytes):
uvuvuv_data.extend([u_byte, v_byte])
# Input for the hbir model
y = np.frombuffer(y_data_bytes, dtype=np.uint8).reshape(1, h, w, 1).astype(np.uint8)
# np.save("y_data.npy", y)
uv = np.frombuffer(uvuvuv_data, dtype=np.uint8).reshape(1, h//2, w//2, 2).astype(np.uint8)
# np.save("uv_data.npy", uv)
return y, uv三、原因驗證與示例
3.1 驗證原理
3.2 參考實現代碼
from hbdk4.compiler import load,compile,hbm_perf,visualize,save,convert
import numpy as np
from horizon_tc_ui.hb_runtime import HBRuntime
def cosine_similarity(vec1, vec2):
"""計算兩向量余弦相似度"""
vec1_flat = vec1.flatten()
vec2_flat = vec2.flatten()
dot_product = np.dot(vec1_flat, vec2_flat)
norm_vec1 = np.linalg.norm(vec1_flat)
norm_vec2 = np.linalg.norm(vec2_flat)
return dot_product / (norm_vec1 * norm_vec2) if (norm_vec1 * norm_vec2) != 0 else 0
def compare_noise_impact(float_model_path):
"""對比加噪前后浮點模型輸出差異"""
input_data = np.load("data.npy")
# 添加0-2像素值范圍的隨機噪聲
noise = np.random.uniform(0, 2, size=input_data.shape).astype(np.float32)
input_data_noise = input_data + noise
sess = HBRuntime(float_model_path)
input_names = sess.input_names
output_names = sess.output_names
# 原始輸入推理
input_dict = {input_names[0]: input_data}
outputs_original = sess.run(output_names, input_dict)
# 加噪輸入推理
input_dict_noise = {input_names[0]: input_data_noise}
outputs_noise = sess.run(output_names, input_dict_noise)
# 計算相似度
return [cosine_similarity(orig, noise) for orig, noise in zip(outputs_original, outputs_noise)]
# 執行驗證
similarities = compare_noise_impact(float_model_path="float_model.onnx")
for i, sim in enumerate(similarities):
print(f"輸出{i}余弦相似度: {sim:.6f}")*博客內容為網友個人發布,僅代表博主個人觀點,如有侵權請聯系工作人員刪除。
相關推薦
-
| 2007-12-28
-
| 2018-05-31
-
| 2020-06-12
-
| 2009-09-03
-
-
| 2020-03-16
-
| 2010-01-20
-
| 2004-07-26
-
| 2007-02-16
-
| 2007-02-16
-
| 2020-03-16
-
| 2019-11-08
-
-
-
| 2011-06-27
-
| 2007-02-16
-
-
-
-
-
-
| 2012-09-07
-
| 2003-06-06
-
| 2011-05-11
-
| 2004-08-06
-
| 2007-02-16
-
| 2002-05-17
-
| 2004-08-04

