对于在hailo NPU上运行一般的图像AI算法,建议将归一化放到hailo内部去做。具体做法为:在转模型时,脚本中加上一句:
normalization1 = normalization([0.0, 0.0, 0.0], [255.0, 255.0, 255.0])
这是因为hailo本身是做量化的NPU加速器,归一化放在hailo芯片里可以避免host资源损耗,提高运行效率。
但是当输入的tensor不是图像数据而是特征图或激光雷达数据时,输入tensor本身就是浮点型,无法在hailo内部做归一化,必须使用hailort而非hailo硬件做归一化。
使用hailort做归一化意味着输入到hailort API的数据为float32数据类型,hailort会在API内部基于host资源和转换模型得到的量化参数,使用CPU进行量化计算,然后将量化后的数据传输给hailo硬件。
如果希望使用DSP而不是CPU进行量化,可以通过以下步骤实现:
- 将input vstream的输入格式由float32修改为UINT8:
auto input_params = network_group.value()->make_input_vstream_params({}, HAILO_FORMAT_TYPE_UINT8, HAILO_DEFAULT_VSTREAM_TIMEOUT_MS, HAILO_DEFAULT_VSTREAM_QUEUE_SIZE);
- 通过模型文件hef获取输入tensor的量化参数:
auto input_vstreams = pipeline.get_input_vstreams();
std::vector quant;
for (const auto &input_vstream : input_vstreams) {
quant = input_vstream.get().get_quant_infos();
assert(quant.size() == 1);
const auto input_name = input_vstream.get().name();
std::cout << "input_name:" << input_name << " zp: " << quant[0].qp_zp
<< " scale: " << quant[0].qp_scale << " frame size: " << input_vstream.get().get_frame_size() << std::endl;
}
- 采用自定义的量化方式,这里示例中采用CPU量化:
#ifdef QUANT_EXT
//TODO: you could do the quant in other ways or in other HW.
Quantization::quantize_input_buffer<float32_t, uint8_t>((float32_t*)file_data.data(), (uint8_t*)input_buffer.data(),
input_vstream.get().get_frame_size(), quant[0]);
#else
std::copy(file_data.begin(), file_data.end(), input_buffer.begin());
#endif
请根据量化信息自行选择合适的量化方式,例如使用DSP进行量化。
发表回复