bc 与 hbm 一致性比对
01 引言 使用地平线 征程 6 算法工具链时,算法侧在验证 quantized.bc 精度符合预期后,软件侧反馈 hbm 精度不符合预期,此时应该怎么做呢?(“打一架!”) 对于熟悉地平线算法工具链的用户而言,可能会立刻想到,使用 hb_verifier 工具比对 bc 与 hbm 的一致性即可,so easy! 但对于不太熟悉的同学,可能会遇到如下问题: hb_verifier 工具怎
01 引言
使用地平线 征程 6 算法工具链时,算法侧在验证 quantized.bc 精度符合预期后,软件侧反馈 hbm 精度不符合预期,此时应该怎么做呢?(“打一架!”)
对于熟悉地平线算法工具链的用户而言,可能会立刻想到,使用 hb_verifier 工具比对 bc 与 hbm 的一致性即可,so easy!
但对于不太熟悉的同学,可能会遇到如下问题:
-
hb_verifier 工具怎么用?
-
输入数据怎么准备?准备几个输入?准备什么 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 代码如下:
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")
更多推荐
所有评论(0)