首页 > 其他分享 >bc 与 hbm 一致性比对

bc 与 hbm 一致性比对

时间:2024-12-15 16:42:26浏览次数:7  
标签:hbm quantized bc np 一致性 nv12 data

01 引言

使用地平线 征程 6 算法工具链时,算法侧在验证 quantized.bc 精度符合预期后,软件侧反馈 hbm 精度不符合预期,此时应该怎么做呢?(“打一架!”)

对于熟悉地平线算法工具链的用户而言,可能会立刻想到,使用 hb_verifier 工具比对 bc 与 hbm 的一致性即可,so easy!

但对于不太熟悉的同学,可能会遇到如下问题:

  1. hb_verifier 工具怎么用?
  2. 输入数据怎么准备?准备几个输入?准备什么 shape?什么 type?

为了结合用户的疑问详细介绍该过程,本文会举个非常详细的例子来介绍。有没有比 hb_verifier 更“优雅”的比对方式?当然是有的,欢迎往下看。

02 模型定义

quantized.bc 与 hbm 可以分为以下几类:

  • convert 后什么都不做的:quantized_stage1.bc,对应 quantized_stage1.hbm

  • 在 stage1 的基础上,插入前处理 nv12 节点的:quantized_nv12_stage2.bc,对应 quantized_nv12_stage2.hbm

  • 在 stage2 的基础上,删除尾部反量化节点的:quantized_nv12_remove_stage3.bc,对应 quantized_nv12_remove_stage3.hbm

理论上,大家直接比对 stage3.bc 与 stage3.hbm 的一致性即可,而这一步,也是最复杂的。

03 hb_verifier 简介

hb_verifier 比对 bc 与 hbm 一致性时,需要关注的信息如下:

bc 与 hbm 一致性比对时,输出信息如下:

本文的例子中,命令如下:

hb_verifier -m quantized_nv12_remove_stage3.bc,quantized_nv12_remove_stage3.hbm -i y_data.npy,uv_data.npy

04 输入数据准备

在地平线 docker 中,可以使用 hb_model_info 查看 bc 以及 hbm 的输入信息,或在 docker/开发板上使用 hrt_model_exec 工具查看模型输入信息,然后根据终端打印的模型输入数量、输入类型来准备输入数据,以 quantized_nv12_remove_stage3.bc/quantized_nv12_remove_stage3.hbm 为例,来准备输入数据。

hb_model_info quantized_nv12_remove_stage3.bc
hb_model_info quantized_nv12_remove_stage3.hbm

输入数据准备的代码如下:

from PIL import Image
import numpy as np

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

if __name__ == "__main__":
    # Create a random image with the shape (1, 512, 960, 3)
    # Generate random RGB values in the range 0-255
    image_data = np.random.randint(0, 256, (512, 960, 3), dtype=np.uint8)

    # Convert the numpy array to a PIL image
    img = Image.fromarray(image_data)
    y, uv = generate_nv12(img)

述代码只介绍了 NV12 输入时,如何准备输入数据,对于 int8、int16、bool 等类型如何准备输入数据呢?

import numpy as np
# 定义所有输入数据的形状和数据类型
data_dict = {
    'A_input': {'shape': (1, 32, 16), 'dtype': np.int8},
    'B_input': {'shape': (1, 1, 320, 4), 'dtype': np.int16},
    'C_input': {'shape': (32, 10, 10), 'dtype': np.bool_},
}

# 生成数据并保存为 .npy 文件
for idx, (name, info) in enumerate(data_dict.items()):
    shape = info['shape']
    dtype = info['dtype']
    # 生成随机数据
    data = np.random.randint(0, 100, size=shape, dtype=dtype) if dtype == np.int16 else np.random.choice([True, False], size=shape)
    # 保存为 .npy 文件,文件名前加上编号
    np.save(f"{idx}_{name}.npy", data)
    print(f"Saved {idx}_{name}.npy")

05 hb_verfier 比对 bc 与 hbm 一致性

此时有模型:quantized_nv12_remove_stage3.bc,quantized_nv12_remove_stage3.hbm,有输入数据:y_data.npy,uv_data.npy。

在地平线征程 6 工具链提供的 docker 中,运行如下命令:

hb_verifier -m quantized_nv12_remove_stage3.bc,quantized_nv12_remove_stage3.hbm -i y_data.npy,uv_data.npy

结果如下:

可以发现,二者输出一致。

06 优雅的方案

使用一套数据,在 docker 中推理 bc 与 hbm,并比对一致性的 python 代码如下:

from hbdk4.compiler import load, Hbm
import numpy as np
from PIL import Image

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

def compare_arrays(array1, array2, decimal_places=2):
    """
    Compare two arrays for consistency up to a specified number of decimal places.

    Parameters:
    - array1: First numpy array.
    - array2: Second numpy array.
    - decimal_places: Number of decimal places to consider for alignment.

    Returns:
    - are_equal: True if arrays are consistent up to the specified decimal places, False otherwise.
    - max_difference: Maximum difference (absolute value) if arrays are not consistent, else 0.
    """
    # Round the arrays to the specified decimal places
    rounded1 = np.round(array1, decimals=decimal_places)
    rounded2 = np.round(array2, decimals=decimal_places)
    
    # Check equality
    are_equal = np.array_equal(rounded1, rounded2)
    
    # Calculate maximum difference if not equal
    max_difference = 0
    if not are_equal:
        max_difference = np.max(np.abs(array1 - array2))
    
    return are_equal, max_difference

hbir = load("./quantized_nv12_remove_stage3.bc")
hbm = Hbm("./quantized_nv12_remove_stage3.hbm")

# Create a random image with the shape (1, 512, 960, 3)
# Generate random RGB values in the range 0-255
image_data = np.random.randint(0, 256, (512, 960, 3), dtype=np.uint8)
# Convert the numpy array to a PIL image
img = Image.fromarray(image_data)
y, uv = generate_nv12(img)

inputs = {"input_0_y": y, "input_0_uv": uv}

# 分别进行hbir和Hbm推理
hbir_outputs = hbir[0].feed(inputs)
# print("hbir_outputs:", hbir_outputs)
hbm_x86_outputs = hbm[0].feed(inputs)
# print("hbm_x86_outputs:", hbm_x86_outputs)

# 比较Hbir和hbm输出
for idx, v in enumerate(hbir[0].outputs):
    hbir_data = hbir_outputs[v.name]
    hbm_x86_data = hbm_x86_outputs[v.name]

    # Compare arrays
    are_equal, max_difference = compare_arrays(hbir_data, hbm_arrch64_data, decimal_places=4)
    if not are_equal:
        print("Maximum difference:", max_difference)
    else:
        print(f"outputs[{idx}] is equal!")

标签:hbm,quantized,bc,np,一致性,nv12,data
From: https://www.cnblogs.com/horizondeveloper/p/18608133

相关文章

  • 多线程交替打印ABC
    开启3个线程,依次交替打印ABC,打印5轮一、使用Lock+Condition来实现publicclassThreadABC{privatevolatileintnumber=1;privateLocklock=newReentrantLock();privateConditionc1=lock.newCondition();privateConditionc2=lock.newCondi......
  • ABC 384 F
    ABC384Fabc经典EF出式子题。问题陈述对于正整数\(x\),定义\(f(x)\)如下:"当\(x\)是偶数时,继续除以\(2\)。经过这些除法后,\(x\)的最终值为\(f(x)\)"。例如,\(f(4)=f(2)=f(1)=1\)和\(f(12)=f(6)=f(3)=3\)。已知长度为\(N\)的整数序列\(A=(A_1,A_2,\ldots,A......
  • AT_kupc2019_g ABCのG問題题解
    这题的难度不怎么好说,不过我认为还是挺简单的。我们可以把答案看成由多个子图构成的图,这样我们只需要手打一个小子图,从中推出完整的答案。-把小于子图范围的地方填上子图的字母-如果这个点的横坐标或纵坐标小于子图范围就填上$T_{i,0}$或$T_{0,j}$详见注释intmain(){......
  • React 与 Stylelint:提升CSS质量,保持代码风格一致性的指南
    前言在前端开发中,维护一致且高质量的CSS代码对于项目的长期可维护性和团队协作至关重要。Stylelint作为一款强大的CSS代码检查工具,在确保代码质量方面发挥了重要作用。本教程将详细介绍如何在React项目中集成和使用Stylelint,通过这一过程,我们将能够提升代码的一致......
  • 2、多线程-三个线程分别打印 A,B,C,要求这三个线程一起运行,打印 n 次,输出形如“ABCABCABC
    题目三个线程分别打印A,B,C,要求这三个线程一起运行,打印n次,输出形如“ABCABCABC....”的字符串代码示例publicclassZeroEvenOdd{ privateintn; privateAutoResetEventaEvent=newAutoResetEvent(true);//一开始A可以运行 privateAutoResetEventbEvent=new......
  • 读数据保护:工作负载的可恢复性13一致性模型
    1. 一致性模型1.1. 数据库与其他东西相比,还有一个很重要的区别就在于,它们需要通过某种机制来确保数据一致,对于运行在多个节点上的数据库来说,这尤其重要1.1.1. 一致性模型(consistencymodel)1.2. 立即一致性1.2.1. 立即一致性(immediateconsistency)也叫强一致性(s......
  • DDCA —— 内存一致性
    1.同步(Synchronization)1.1构造锁(Locks)原子(atomic)执行:应用程序的某些部分必须独占执行(原子性),这意味着在这些部分执行期间,其他并行进程无法访问或修改相关数据。比如一个账户转账操作,需要保证资金不会被同时修改,避免出现不一致的状态。锁的作用:锁(Lock)用于保护数据或代码块,确保......
  • MySQL语句学习第四篇_数据库:通过intellij IDE连接MySQL数据库使用JDBC实现增删查改
    MySQL语句学习第四篇_数据库通过intellijIDE连接MySQL数据库使用JDBC来实现增删查改专栏记录MySQL的学习,感谢大家观看。本章的专栏......
  • 蓝易云 - sharding-jdbc分库连接数优化教程
    在使用Sharding-JDBC进行分库分表时,优化连接数是一个重要的考虑因素。下面是一个关于如何优化Sharding-JDBC分库连接数的简单教程。配置连接池参数:在Sharding-JDBC的数据源配置中,我们可以设置连接池相关的参数来优化连接数。以下是一些常见的连接池参数:minPoolSize:连接池中......
  • [HBCPC2024] Points on the Number Axis A
    [HBCPC2024]PointsontheNumberAxisA题目描述Aliceisplayingasingle-playergameonthenumberaxis.Thereare\(n\)pointsonthenumberaxis.Eachtime,theplayerselectstwopoints.Thetwopointswillberemoved,andtheirmidpointwillbeadded.......