欧美激情综合一区二区三区,青柠影院免费观看电视剧高清8,无码人妻精品一区二区蜜桃老年人,亚洲最大成人网站,亚洲中文字幕无码一区在线

博客專欄

EEPW首頁 > > 模型插入 NV12 預處理節點精度問題排查流程

模型插入 NV12 預處理節點精度問題排查流程

發布人: 時間:2025-09-28 來源:工程師
一、引言

在近期工具鏈實踐過程中,頻繁出現 BC 模型在插入 NV12 預處理節點后精度崩潰的現象。經分析,此類問題可分為兩類:其一為用戶側 BGR/RGB 轉 NV12 的代碼實現缺陷;其二為 BGR/RGB 與 NV12 格式轉換過程中固有的不可逆誤差所致。后者的根本原因在于模型訓練階段存在嚴重過擬合現象,導致模型泛化能力薄弱,無法容忍格式轉換帶來的微小數據偏差。

此類問題的傳統排查流程耗時較長,且往往需要重新訓練浮點模型,對用戶開發進度造成顯著影響。基于此,本文提供一套標準化的快速排查方案,旨在縮短問題定位周期,降低對開發節奏的干擾。

二、問題確定與現象
2.1.1 關鍵術語定義
  • qat_nv12.bc/quantized_nv12.bc:插入 NV12 預處理節點的偽量化 / 定點 BC 模型

  • qat_feat.bc/quantized_feat.bc:未插入 NV12 預處理節點的偽量化 / 定點 BC 模型

2.1.2 典型現象

問題通常表現為:在對插入 NV12 預處理節點的 HBM 或 qat_nv12.bc/quantized_nv12.bc 進行精度驗證時,出現 quantized_feat.bc 精度正常而 quantized_nv12.bc 精度異常的特征性差異。

2.1.3 NV12 節點插入規范

在 qat.bc 中插入 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 核心驗證思路

通過單幀圖像分別推理兩類模型(含 NV12 節點與不含 NV12 節點),對比輸出結果的可視化效果及數值相似度。預期異常特征為:

  • quantized_nv12.bc 與 quantized_feat.bc 推理結果差異顯著

  • qat_nv12.bc 與 quantized_nv12.bc 推理結果一致性差

推理時需要注意兩個問題:

  1. quantized_nv12.bc 已經插入了 NV12->bgr/rgb 和歸一化節點了,所以其輸入為 NV12 圖像;quantized_feat.bc 的輸入需要對齊浮點模型,為手動做過歸一化操作的 bgr/rgb 圖像;

  2. bgr/rgb->NV12 圖像的方式有多種,推薦使用以下方式;

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 驗證原理

當確定是插入 NV12 預處理節點導致的 bc/hbm 精度下降后,且確定輸入數據處理過程完全正確,為了進一步確定原因,可以通過以下方式來證明:在輸入數據中加入 2-3 個像素值的隨機噪聲推理浮點模型。

rgb->NV12 的過程是有損的,所以我們可以在輸入圖像中加小幅的隨機噪聲(2-3 個像素值即可),然后輸入到浮點模型或者原始浮點 onnx,如果加小噪聲前后的模型輸出相差很大(可以觀察 cos 相似度、L1 等),證明確實為浮點模型過擬合導致。

3.2 參考實現代碼

以下為對比輸入數據加噪前后,比較浮點 onnx 推理結果的示例代碼:

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}")

一般來說,若輸出余弦相似度低于 99.9%,則可判定為浮點模型過擬合。此時建議在模型訓練階段增加 BGR/RGB→NV12→YUV444 的預處理流程,使模型在訓練過程中學習并適應 NV12 轉換帶來的固有誤差,從而提升部署時的精度穩定性。


*博客內容為網友個人發布,僅代表博主個人觀點,如有侵權請聯系工作人員刪除。


相關推薦

技術專區

關閉