日本a√视频在线,久久青青亚洲国产,亚洲一区欧美二区,免费g片在线观看网站

        <style id="k3y6c"><u id="k3y6c"></u></style>
        <s id="k3y6c"></s>
        <mark id="k3y6c"></mark>
          
          

          <mark id="k3y6c"></mark>

          "); //-->

          博客專欄

          EEPW首頁 > 博客 > 模型插入 NV12 預(yù)處理節(jié)點(diǎn)精度問題排查流程

          模型插入 NV12 預(yù)處理節(jié)點(diǎn)精度問題排查流程

          發(fā)布人:地平線開發(fā)者 時間:2025-09-28 來源:工程師 發(fā)布文章
          一、引言

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

          此類問題的傳統(tǒng)排查流程耗時較長,且往往需要重新訓(xùn)練浮點(diǎn)模型,對用戶開發(fā)進(jìn)度造成顯著影響。基于此,本文提供一套標(biāo)準(zhǔn)化的快速排查方案,旨在縮短問題定位周期,降低對開發(fā)節(jié)奏的干擾。

          二、問題確定與現(xiàn)象
          2.1.1 關(guān)鍵術(shù)語定義
          • qat_nv12.bc/quantized_nv12.bc:插入 NV12 預(yù)處理節(jié)點(diǎn)的偽量化 / 定點(diǎn) BC 模型

          • qat_feat.bc/quantized_feat.bc:未插入 NV12 預(yù)處理節(jié)點(diǎn)的偽量化 / 定點(diǎn) BC 模型

          2.1.2 典型現(xiàn)象

          問題通常表現(xiàn)為:在對插入 NV12 預(yù)處理節(jié)點(diǎn)的 HBM 或 qat_nv12.bc/quantized_nv12.bc 進(jìn)行精度驗證時,出現(xiàn) quantized_feat.bc 精度正常而 quantized_nv12.bc 精度異常的特征性差異。

          2.1.3 NV12 節(jié)點(diǎn)插入規(guī)范

          在 qat.bc 中插入 NV12 預(yù)處理節(jié)點(diǎn)的標(biāo)準(zhǔn)代碼如下:

          resizer_input = ["resize"]      # 部署時數(shù)據(jù)來源于resizer的輸入節(jié)點(diǎn)名稱列表
          pyramid_input = ["pym"]         # 部署時數(shù)據(jù)來源于pyramid的輸入節(jié)點(diǎn)名稱列表
          
          # 為和歷史版本保持兼容,建議使用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])
                  # 插入前處理節(jié)點(diǎn),具體可參考下一節(jié)的說明
                  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])
                  # 插入前處理節(jié)點(diǎn),具體可參考下一節(jié)的說明
                  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 節(jié)點(diǎn)與不含 NV12 節(jié)點(diǎn)),對比輸出結(jié)果的可視化效果及數(shù)值相似度。預(yù)期異常特征為:

          • quantized_nv12.bc 與 quantized_feat.bc 推理結(jié)果差異顯著

          • qat_nv12.bc 與 quantized_nv12.bc 推理結(jié)果一致性差

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

          1. quantized_nv12.bc 已經(jīng)插入了 NV12->bgr/rgb 和歸一化節(jié)點(diǎn)了,所以其輸入為 NV12 圖像;quantized_feat.bc 的輸入需要對齊浮點(diǎn)模型,為手動做過歸一化操作的 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 驗證原理

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

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

          3.2 參考實現(xiàn)代碼

          以下為對比輸入數(shù)據(jù)加噪前后,比較浮點(diǎn) onnx 推理結(jié)果的示例代碼:

          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):
              """對比加噪前后浮點(diǎn)模型輸出差異"""
              input_data = np.load("data.npy")
              # 添加0-2像素值范圍的隨機(jī)噪聲
              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)]
              
          # 執(zhí)行驗證
          similarities = compare_noise_impact(float_model_path="float_model.onnx")
          for i, sim in enumerate(similarities):
              print(f"輸出{i}余弦相似度: {sim:.6f}")

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


          *博客內(nèi)容為網(wǎng)友個人發(fā)布,僅代表博主個人觀點(diǎn),如有侵權(quán)請聯(lián)系工作人員刪除。



          相關(guān)推薦

          技術(shù)專區(qū)

          關(guān)閉