哪个命令或者什么标准的加载代码是跑hbm文件的

我需要跑hbm查看导出的推理结果是否正确,请问有谁知道正确的评测流程吗,推理速度,推理结果等等

你好!针对你关于 HBM 文件推理评测 的问题,这里给出完整的评测流程和关键命令。

核心结论

HBM 模型(Horizon BPU Model)只包含 BPU 算子,板端推理需要使用 BPU SDK API 编写推理程序,或使用官方提供的工具进行快速验证。


一、快速验证流程(推荐新手)

1. 查看模型信息

在板端使用 hrt_model_exec 工具查看 HBM 模型的基本信息和性能:

# 查看模型结构、输入输出 shape
hrt_model_exec model_info --model_file your_model.hbm

# 测试推理性能(latency)
hrt_model_exec perf --model_file your_model.hbm --core_id 1 --frame_count 1000 --thread_num 1

2. 使用官方示例代码

OE 开发包中提供了完整的推理示例,路径:

ddk/samples/ai_toolchain/horizon_runtime_sample/code/00_quick_start/

关键步骤:

  1. 编译示例:在板端运行 build_j5.sh(J5 芯片)或对应芯片的编译脚本
  2. 修改模型路径:将示例中的模型文件替换为你的 HBM 文件
  3. 准备测试数据:准备与模型输入 shape 匹配的图像/数据
  4. 运行推理:执行生成的脚本,查看输出结果

二、自定义推理程序开发

如果需要更灵活的评测(如自定义后处理、批量测试等),需要编写 C++ 推理程序。核心流程如下:

关键代码步骤

// Step 1: 加载模型
hbPackedDNNHandle_t packed_dnn_handle;
hbDNNHandle_t dnn_handle;
const char* model_file = "your_model.hbm";
hbDNNInitializeFromFiles(&packed_dnn_handle, &model_file, 1);
hbDNNGetModelHandle(&dnn_handle, packed_dnn_handle, model_name_list[0]);

// Step 2: 准备输入输出张量
std::vector<hbDNNTensor> input_tensors;
std::vector<hbDNNTensor> output_tensors;
// 获取输入输出数量并分配内存
hbDNNGetInputCount(&input_count, dnn_handle);
hbDNNGetOutputCount(&output_count, dnn_handle);
// 使用 hbSysAllocCachedMem 分配带缓存的内存

// Step 3: 填充输入数据
// 将图像/数据拷贝到 input_tensors 的内存空间
// 注意数据格式对齐(NV12/NCHW 等)

// Step 4: 执行推理
hbDNNInferCtrlParam infer_ctrl_param;
HB_DNN_INITIALIZE_INFER_CTRL_PARAM(&infer_ctrl_param);
hbDNNInfer(&task_handle, &output, input_tensors.data(), dnn_handle, &infer_ctrl_param);
hbDNNWaitTaskDone(task_handle, 0);

// Step 5: 读取输出结果
// 使用 hbSysFlushMem 同步数据到缓存
// 解析 output_tensors 中的推理结果

// Step 6: 释放资源
hbDNNReleaseTask(task_handle);
hbSysFreeMem(&input_tensors[i].sysMem[0]);
hbDNNRelease(packed_dnn_handle);

三、评测指标获取

1. 推理速度

  • 使用 hrt_model_exec perf 命令获取平均延迟
  • 或在代码中使用 chrono 记录 hbDNNInferhbDNNWaitTaskDone 的时间

2. 推理结果正确性

  • 对比方法:将板端输出与 PC 端浮点模型/量化模型的输出进行对比
  • 工具:使用 hrt_bin_dump 工具导出中间层数据进行调试
  • 一致性验证:参考社区帖子 QAT 一致性对齐流程

3. 内存占用

  • 通过 hbSysAllocCachedMem 分配的内存大小累加
  • 或使用系统命令 cat /proc/meminfo 监控

四、常见问题排查

问题 排查方法
模型加载失败 检查 OE 版本与编译版本是否匹配,参考 FAQ 手册
输出 shape 不对 使用 hrt_model_exec model_info 确认模型输入输出定义
推理结果异常 检查输入数据对齐规则(NV12/NCHW),参考 对齐规则解析
速度慢 确认 core_id 设置,检查是否使用了 BPU 而非 CPU

五、推荐学习资源

  1. 官方教程模型推理快速上手 - 详细代码解读
  2. API 手册:工具链手册中的 BPU SDK API 章节
  3. 示例代码:OE 包中的 horizon_runtime_sampleai_forward_view_sample
  4. 一致性验证QAT 一致性对齐流程

下一步建议

  1. 先用 hrt_model_exec 快速验证模型能否正常加载和推理
  2. 基于官方 00_quick_start 示例修改,适配你的 HBM 模型
  3. 如需进一步帮助,请提供:
    • 芯片型号(J5/X3/S100 等)
    • OE 开发包版本
    • 模型类型(分类/检测/分割等)
    • 具体报错信息(如有)

欢迎将评测过程中遇到的问题发帖到社区,方便其他开发者参考!

能不能给出完整的推理代码,我需要看转换的模型推理出的结果对不对

好的,给你一个完整可编译运行的推理代码示例,基于官方 00_quick_start 简化,专门用于验证 HBM 模型推理结果。


一、完整推理代码

1. 主程序 infer_hbm.cpp

#include <iostream>
#include <vector>
#include <string>
#include <cstring>
#include <algorithm>
#include <chrono>
#include <fstream>

#include "hobotdnn/hbot_dnn.h"
#include "hobot_sys_mem/hobot_sys_mem.h"

// 命令行参数
std::string model_file = "";
std::string input_file = "";
int top_k = 5;

void print_usage(const char* prog) {
    std::cout << "Usage: " << prog << " --model <model.hbm> --input <input.bin/nv12> [--topk N]" << std::endl;
}

int parse_args(int argc, char** argv) {
    for (int i = 1; i < argc; i++) {
        if (strcmp(argv[i], "--model") == 0 && i + 1 < argc) {
            model_file = argv[++i];
        } else if (strcmp(argv[i], "--input") == 0 && i + 1 < argc) {
            input_file = argv[++i];
        } else if (strcmp(argv[i], "--topk") == 0 && i + 1 < argc) {
            top_k = std::stoi(argv[++i]);
        } else if (strcmp(argv[i], "--help") == 0) {
            print_usage(argv[0]);
            return -1;
        }
    }
    if (model_file.empty() || input_file.empty()) {
        print_usage(argv[0]);
        return -1;
    }
    return 0;
}

// 从文件读取原始数据到 tensor
int read_input_data(const std::string& file_path, hbDNNTensor* tensor) {
    std::ifstream file(file_path, std::ios::binary);
    if (!file.is_open()) {
        std::cerr << "Failed to open input file: " << file_path << std::endl;
        return -1;
    }
    
    // 获取文件大小
    file.seekg(0, std::ios::end);
    size_t file_size = file.tellg();
    file.seekg(0, std::ios::beg);
    
    // 获取 tensor 需要的内存大小
    size_t tensor_size = tensor->properties.alignedByteSize;
    
    if (file_size != tensor_size) {
        std::cerr << "Warning: Input file size (" << file_size 
                  << ") != tensor size (" << tensor_size << ")" << std::endl;
    }
    
    // 读取数据到 tensor 内存
    file.read(reinterpret_cast<char*>(tensor->sysMem[0].virAddr), tensor_size);
    file.close();
    
    std::cout << "Loaded " << file_size << " bytes to input tensor" << std::endl;
    return 0;
}

// 打印输出结果
void print_output_results(hbDNNTensor* output_tensor, int top_k) {
    auto* data = reinterpret_cast<float*>(output_tensor->sysMem[0].virAddr);
    auto& shape = output_tensor->properties.validShape;
    
    // 计算总元素数
    int total_elements = 1;
    for (int i = 0; i < shape.numDimensions; i++) {
        total_elements *= shape.dimensionSize[i];
    }
    
    std::cout << "\n=== Output Tensor Info ===" << std::endl;
    std::cout << "Shape: ";
    for (int i = 0; i < shape.numDimensions; i++) {
        std::cout << shape.dimensionSize[i] << (i < shape.numDimensions - 1 ? "x" : "");
    }
    std::cout << ", Total elements: " << total_elements << std::endl;
    
    // 反量化处理(如果需要)
    std::vector<std::pair<float, int>> scores;
    for (int i = 0; i < total_elements; i++) {
        float score = data[i];
        // 如果模型是量化模型,需要反量化
        if (output_tensor->properties.quantiType == HB_DNN_QUANTI_TYPE_SHIFT) {
            score = data[i] / (1 << output_tensor->properties.shift.shiftData[i]);
        } else if (output_tensor->properties.quantiType == HB_DNN_QUANTI_TYPE_SCALE) {
            score = data[i] * output_tensor->properties.scale.scaleData[i];
        }
        scores.push_back({score, i});
    }
    
    // 排序取 TopK
    std::sort(scores.begin(), scores.end(), 
              [](const auto& a, const auto& b) { return a.first > b.first; });
    
    std::cout << "\n=== Top " << top_k << " Results ===" << std::endl;
    for (int i = 0; i < std::min(top_k, (int)scores.size()); i++) {
        std::cout << "Rank " << i + 1 << ": Index=" << scores[i].second 
                  << ", Score=" << scores[i].first << std::endl;
    }
    
    // 打印前 10 个原始输出值(用于调试)
    std::cout << "\n=== First 10 Raw Output Values ===" << std::endl;
    for (int i = 0; i < std::min(10, total_elements); i++) {
        std::cout << "Output[" << i << "] = " << data[i] << std::endl;
    }
}

int main(int argc, char** argv) {
    // 解析参数
    if (parse_args(argc, argv) != 0) {
        return -1;
    }
    
    std::cout << "=== HBM Inference Test ===" << std::endl;
    std::cout << "Model: " << model_file << std::endl;
    std::cout << "Input: " << input_file << std::endl;
    
    // Step 1: 加载模型
    hbPackedDNNHandle_t packed_dnn_handle = nullptr;
    hbDNNHandle_t dnn_handle = nullptr;
    const char** model_name_list = nullptr;
    int model_count = 0;
    
    const char* model_file_cstr = model_file.c_str();
    HB_CHECK_SUCCESS(hbDNNInitializeFromFiles(&packed_dnn_handle, &model_file_cstr, 1),
                     "hbDNNInitializeFromFiles failed");
    
    HB_CHECK_SUCCESS(hbDNNGetModelNameList(&model_name_list, &model_count, packed_dnn_handle),
                     "hbDNNGetModelNameList failed");
    
    std::cout << "Model count: " << model_count << std::endl;
    for (int i = 0; i < model_count; i++) {
        std::cout << "  Model[" << i << "]: " << model_name_list[i] << std::endl;
    }
    
    HB_CHECK_SUCCESS(hbDNNGetModelHandle(&dnn_handle, packed_dnn_handle, model_name_list[0]),
                     "hbDNNGetModelHandle failed");
    
    // Step 2: 获取输入输出信息
    int input_count = 0, output_count = 0;
    HB_CHECK_SUCCESS(hbDNNGetInputCount(&input_count, dnn_handle),
                     "hbDNNGetInputCount failed");
    HB_CHECK_SUCCESS(hbDNNGetOutputCount(&output_count, dnn_handle),
                     "hbDNNGetOutputCount failed");
    
    std::cout << "Input count: " << input_count << ", Output count: " << output_count << std::endl;
    
    // Step 3: 准备输入输出 tensor
    std::vector<hbDNNTensor> input_tensors(input_count);
    std::vector<hbDNNTensor> output_tensors(output_count);
    
    for (int i = 0; i < input_count; i++) {
        HB_CHECK_SUCCESS(hbDNNGetInputTensorProperties(&input_tensors[i].properties, dnn_handle, i),
                         "hbDNNGetInputTensorProperties failed");
        
        // 设置 alignedShape = validShape(让推理库自动处理对齐)
        input_tensors[i].properties.alignedShape = input_tensors[i].properties.validShape;
        
        size_t mem_size = input_tensors[i].properties.alignedByteSize;
        HB_CHECK_SUCCESS(hbSysAllocCachedMem(&input_tensors[i].sysMem[0], mem_size),
                         "hbSysAllocCachedMem failed (input)");
        
        const char* input_name = nullptr;
        HB_CHECK_SUCCESS(hbDNNGetInputName(&input_name, dnn_handle, i),
                         "hbDNNGetInputName failed");
        std::cout << "Input[" << i << "] name: " << input_name 
                  << ", shape: " << input_tensors[i].properties.validShape.numDimensions << "D"
                  << ", size: " << mem_size << " bytes" << std::endl;
    }
    
    for (int i = 0; i < output_count; i++) {
        HB_CHECK_SUCCESS(hbDNNGetOutputTensorProperties(&output_tensors[i].properties, dnn_handle, i),
                         "hbDNNGetOutputTensorProperties failed");
        
        output_tensors[i].properties.alignedShape = output_tensors[i].properties.validShape;
        
        size_t mem_size = output_tensors[i].properties.alignedByteSize;
        HB_CHECK_SUCCESS(hbSysAllocCachedMem(&output_tensors[i].sysMem[0], mem_size),
                         "hbSysAllocCachedMem failed (output)");
        
        const char* output_name = nullptr;
        HB_CHECK_SUCCESS(hbDNNGetOutputName(&output_name, dnn_handle, i),
                         "hbDNNGetOutputName failed");
        std::cout << "Output[" << i << "] name: " << output_name 
                  << ", shape: " << output_tensors[i].properties.validShape.numDimensions << "D"
                  << ", size: " << mem_size << " bytes" << std::endl;
    }
    
    // Step 4: 读取输入数据
    if (read_input_data(input_file, &input_tensors[0]) != 0) {
        std::cerr << "Failed to read input data" << std::endl;
        return -1;
    }
    
    // 刷新输入数据到 DDR
    for (int i = 0; i < input_count; i++) {
        hbSysFlushMem(&input_tensors[i].sysMem[0], HB_SYS_MEM_CACHE_CLEAN);
    }
    
    // Step 5: 执行推理
    std::cout << "\n=== Running Inference ===" << std::endl;
    hbDNNTaskHandle_t task_handle = nullptr;
    hbDNNTensor* output_ptr = output_tensors.data();
    
    hbDNNInferCtrlParam infer_ctrl_param;
    HB_DNN_INITIALIZE_INFER_CTRL_PARAM(&infer_ctrl_param);
    // 默认使用任意 BPU 核心
    infer_ctrl_param.bpuCoreId = HB_BPU_CORE_ANY;
    
    auto start_time = std::chrono::high_resolution_clock::now();
    
    HB_CHECK_SUCCESS(hbDNNInfer(&task_handle, &output_ptr, input_tensors.data(), 
                                 dnn_handle, &infer_ctrl_param),
                     "hbDNNInfer failed");
    
    HB_CHECK_SUCCESS(hbDNNWaitTaskDone(task_handle, 0),
                     "hbDNNWaitTaskDone failed");
    
    auto end_time = std::chrono::high_resolution_clock::now();
    auto duration = std::chrono::duration_cast<std::chrono::milliseconds>(end_time - start_time);
    
    std::cout << "Inference completed in " << duration.count() << " ms" << std::endl;
    
    // Step 6: 同步输出数据并打印结果
    for (int i = 0; i < output_count; i++) {
        hbSysFlushMem(&output_tensors[i].sysMem[0], HB_SYS_MEM_CACHE_INVALIDATE);
    }
    
    print_output_results(&output_tensors[0], top_k);
    
    // Step 7: 释放资源
    std::cout << "\n=== Releasing Resources ===" << std::endl;
    hbDNNReleaseTask(task_handle);
    
    for (int i = 0; i < input_count; i++) {
        hbSysFreeMem(&input_tensors[i].sysMem[0]);
    }
    for (int i = 0; i < output_count; i++) {
        hbSysFreeMem(&output_tensors[i].sysMem[0]);
    }
    
    hbDNNRelease(packed_dnn_handle);
    
    std::cout << "Done!" << std::endl;
    return 0;
}

2. CMakeLists.txt

cmake_minimum_required(VERSION 3.10)
project(infer_hbm)

set(CMAKE_CXX_STANDARD 14)
set(CMAKE_CXX_STANDARD_REQUIRED ON)

# 地平线 SDK 路径(根据实际 OE 包路径修改)
set(HORIZON_SDK_PATH "/opt/horizon/hobotdnn")
set(HORIZON_INCLUDE_DIR "${HORIZON_SDK_PATH}/include")
set(HORIZON_LIB_DIR "${HORIZON_SDK_PATH}/lib")

include_directories(${HORIZON_INCLUDE_DIR})
link_directories(${HORIZON_LIB_DIR})

add_executable(infer_hbm infer_hbm.cpp)

target_link_libraries(infer_hbm
    hobot_dnn
    hobot_sys_mem
    pthread
)

# 设置 rpath 以便在板端运行时找到库
set_target_properties(infer_hbm PROPERTIES
    BUILD_RPATH "${HORIZON_LIB_DIR}"
    INSTALL_RPATH "${HORIZON_LIB_DIR}"
)

3. 编译脚本 build.sh

#!/bin/bash

# 创建 build 目录
mkdir -p build
cd build

# 配置 CMake(根据实际 SDK 路径修改)
cmake -DHORIZON_SDK_PATH=/opt/horizon/hobotdnn ..

# 编译
make -j4

echo "Build completed. Executable: build/infer_hbm"

二、使用说明

1. 准备输入数据

HBM 模型的输入数据需要是原始二进制格式,与模型定义的 input shape 匹配。

方法 A:使用 hrt_model_exec 查看 input shape

hrt_model_exec model_info --model_file your_model.hbm

方法 B:从图像生成输入数据(以 NV12 格式为例)

# gen_input.py
import cv2
import numpy as np
import sys

def bgr2nv12(bgr_img):
    h, w = bgr_img.shape[:2]
    yuv = cv2.cvtColor(bgr_img, cv2.COLOR_BGR2YUV_I420)
    y = yuv[:h, :w]
    uv = yuv[h:, :].reshape(-1, 2)
    nv12 = np.vstack([y.flatten(), uv.flatten()])
    return nv12.astype(np.uint8)

img = cv2.imread('test.jpg')
img = cv2.resize(img, (224, 224))  # 根据模型 input shape 调整
nv12_data = bgr2nv12(img)
nv12_data.tofile('input.bin')
print(f"Generated input.bin: {nv12_data.nbytes} bytes")

2. 在板端编译运行

# 上传代码到板端
scp -r infer_hbm_code user@board:/home/user/

# 编译
cd infer_hbm_code
chmod +x build.sh
./build.sh

# 运行推理
./build/infer_hbm --model your_model.hbm --input input.bin --topk 5

三、输出结果解读

运行后会看到类似输出:

=== HBM Inference Test ===
Model: your_model.hbm
Input: input.bin
Model count: 1
  Model[0]: model_0
Input count: 1, Output count: 1
Input[0] name: data, shape: 4D, size: 150528 bytes
Output[0] name: prob, shape: 4D, size: 4000 bytes

Loaded 150528 bytes to input tensor

=== Running Inference ===
Inference completed in 12 ms

=== Output Tensor Info ===
Shape: 1x1000, Total elements: 1000

=== Top 5 Results ===
Rank 1: Index=340, Score=0.8523
Rank 2: Index=292, Score=0.0891
Rank 3: Index=282, Score=0.0234
Rank 4: Index=83, Score=0.0156
Rank 5: Index=290, Score=0.0098

=== First 10 Raw Output Values ===
Output[0] = 0.0012
Output[1] = 0.0034
...

四、验证结果正确性

对比方法

  1. PC 端对比:在 PC 上用相同输入跑 ONNX/PyTorch 模型,对比 TopK 结果

  2. 数值对比:导出板端输出为文件,在 PC 上用 Python 计算误差

    # 板端保存输出
    # 在 print_output_results 中添加:
    # np.array([s[0] for s in scores]).tofile('output_board.bin')
    
    # PC 端对比
    import numpy as np
    board_out = np.fromfile('output_board.bin', dtype=np.float32)
    pc_out = np.fromfile('output_pc.bin', dtype=np.float32)
    diff = np.abs(board_out - pc_out).max()
    print(f"Max diff: {diff}")
    
  3. 一致性标准:通常量化模型与浮点模型的误差在 1e-2 ~ 1e-1 范围内可接受


五、常见问题

问题 解决方法
hbDNNInitializeFromFiles failed 检查 HBM 文件路径,确认 OE 版本匹配
Input file size != tensor size hrt_model_exec model_info 确认 input shape,重新生成输入数据
推理结果为 0 或异常 检查输入数据格式(NV12/NCHW),确认是否需要反量化
编译找不到头文件 修改 CMakeLists.txt 中的 HORIZON_SDK_PATH

六、下一步

运行后如果结果异常,请提供:

  1. hrt_model_exec model_info --model_file xxx.hbm 的完整输出
  2. 推理程序的完整打印信息
  3. 你的模型类型(分类/检测/分割)和输入数据类型

欢迎将验证结果发帖到社区,方便其他开发者参考!

hrt_model_exec infer
–model_file model_best_fixed.hbm
–input_file “input_y_final.npy,input_uv_final.npy”
–enable_dump=true
–output_dir ./hbm_output 这个命令对吗

结论:命令不正确 :cross_mark:

hrt_model_exec 不支持 infer 子命令,也无法直接加载 .npy 文件进行推理。


一、hrt_model_exec 的实际功能

该工具仅支持以下两个子命令:

命令 功能 示例
model_info 查看模型结构、输入输出 shape hrt_model_exec model_info --model_file xxx.hbm
perf 测试推理性能(使用内部随机数据) hrt_model_exec perf --model_file xxx.hbm --frame_count 100

限制:

  • :cross_mark: 不能加载自定义输入数据
  • :cross_mark: 不能保存推理输出
  • :cross_mark: 不支持 .npy 格式

二、正确的评测方案

要验证 HBM 模型推理结果,必须编写推理程序。我已在上文提供了完整代码 infer_hbm.cpp,以下是关键步骤:

1. 准备输入数据(转换 .npy 为二进制)

你的 .npy 文件需要转换成原始二进制格式

# convert_npy_to_bin.py
import numpy as np

# 加载 Y 和 UV 数据
y_data = np.load('input_y_final.npy')
uv_data = np.load('input_uv_final.npy')

# 拼接成 NV12 格式(Y 在前,UV 交错在后)
nv12_data = np.concatenate([y_data.flatten(), uv_data.flatten()])

# 保存为二进制文件
nv12_data.astype(np.uint8).tofile('input.bin')

print(f"Generated input.bin: {nv12_data.nbytes} bytes")
print(f"Y shape: {y_data.shape}, UV shape: {uv_data.shape}")

2. 确认模型输入 Shape

# 在板端运行
hrt_model_exec model_info --model_file model_best_fixed.hbm

查看输出中的 input 部分,确认:

  • 输入节点名称(如 data
  • 输入 shape(如 1x3x224x2241x224x224x1
  • 数据格式(NV12/NCHW 等)

3. 使用推理程序运行

编译并运行我之前提供的 infer_hbm.cpp

# 编译
cd infer_hbm_code
./build.sh

# 运行推理
./build/infer_hbm --model model_best_fixed.hbm --input input.bin --topk 5

4. 保存输出结果(用于对比)

infer_hbm.cppprint_output_results 函数中添加:

// 添加头文件
#include <fstream>

// 在函数末尾添加保存代码
std::ofstream outfile("output_board.bin", std::ios::binary);
outfile.write(reinterpret_cast<char*>(data), total_elements * sizeof(float));
outfile.close();
std::cout << "Output saved to output_board.bin" << std::endl;

三、为什么不能直接用命令?

需求 hrt_model_exec 自定义推理程序
加载自定义输入 :cross_mark: 不支持 :white_check_mark: 完全可控
保存输出结果 :cross_mark: 不支持 :white_check_mark: 可保存为文件
后处理(TopK/检测框等) :cross_mark: 不支持 :white_check_mark: 自定义逻辑
性能计时 :white_check_mark: 支持 :white_check_mark: 可自定义
调试中间层 :warning: 有限支持 :white_check_mark: 完全可控

四、快速验证流程

# 1. 查看模型信息
hrt_model_exec model_info --model_file model_best_fixed.hbm

# 2. 转换输入数据(在 PC 或板端)
python3 convert_npy_to_bin.py

# 3. 编译推理程序
cd infer_hbm_code && ./build.sh

# 4. 运行推理
./build/infer_hbm --model model_best_fixed.hbm --input input.bin --topk 5

# 5. 对比结果(将 output_board.bin 下载到 PC)
python3 compare_results.py  # 与 PC 端输出对比

五、如果坚持要用命令行工具

地平线提供了 hrt_bin_dump 工具可以导出中间层数据,但仍需要先运行推理程序。参考流程:

  1. 在推理代码中设置 enable_dump = true
  2. 推理时会自动生成 dump 文件
  3. 使用 Python 脚本分析 dump 文件

但这仍需基于自定义推理程序,无法纯命令行完成。


下一步

  1. 先用 hrt_model_exec model_info 确认模型输入 shape
  2. 转换你的 .npy 文件为二进制
  3. 使用我提供的 infer_hbm.cpp 编译运行
  4. 如果遇到问题,请提供:
    • model_info 的完整输出
    • 你的输入数据 shape 和格式
    • 编译/运行时的报错信息

需要我帮你调整代码以适配你的具体模型类型(检测/分割/分类)吗?

hrt_model_exec perf --model_file=model_best_fixed.hbm
[UCP]: log level = 3
[UCP]: UCP version = 3.13.6
[VP]: log level = 3
[DNN]: log level = 3
[HPL]: log level = 3
[UCPT]: log level = 6
hrt_model_exec perf --model_file=model_best_fixed.hbm

[Warning]: These operators have range limitations on input data:
[Acos, Acosh, Asin, Atanh, BevPoolV2, Div, Gather, GatherElements, GatherND, GridSample, ImageDecoder, IndexSelect, Log, Mod, Pow, Reciprocal, RoiAlign, ScatterElements, ScatterND, Slice, Sqrt, Tan, Tile, Topk, Upsample].
Please make sure that these operators are not in your model, when no input data is provided to the tool.
[Suggestion]: Using --input_file command to specify perf input data, which can appoint valid input data.

[BPU][[BPU_MONITOR]][281473779463456][INFO]BPULib verison(2, 2, 15)[f21ee84]!
[DNN]: 3.13.6_(4.7.5 HBRT)
Load model to DDR cost 13291.5ms.
[I][11506][08-27][00:07:49:987][tensor_util.cpp:321][hrt_model_exec][HRT_MODEL_EXEC] Input[0] stride is dynamic, but you did not specify the stride, set as (983040,1280,1,1)
[I][11506][08-27][00:07:49:987][tensor_util.cpp:321][hrt_model_exec][HRT_MODEL_EXEC] Input[1] stride is dynamic, but you did not specify the stride, set as (491520,1280,2,1)
Frame count: 200, Thread Average: 849.807190 ms, thread max latency: 855.804016 ms, thread min latency: 849.403992 ms, FPS: 1.176596

Running condition:
Thread number is: 1
Frame count is: 200
Program run time: 169982.250 ms
Perf result:
Frame totally latency is: 169961.438 ms
Average latency is: 849.807 ms
Frame rate is: 1.177 FPS
root@ubuntu:/home/sunrise/data# hrt_model_exec perf --model_file=model_cal_data_103_247.hbm
[UCP]: log level = 3
[UCP]: UCP version = 3.13.6
[VP]: log level = 3
[DNN]: log level = 3
[HPL]: log level = 3
[UCPT]: log level = 6
hrt_model_exec perf --model_file=model_cal_data_103_247.hbm

[Warning]: These operators have range limitations on input data:
[Acos, Acosh, Asin, Atanh, BevPoolV2, Div, Gather, GatherElements, GatherND, GridSample, ImageDecoder, IndexSelect, Log, Mod, Pow, Reciprocal, RoiAlign, ScatterElements, ScatterND, Slice, Sqrt, Tan, Tile, Topk, Upsample].
Please make sure that these operators are not in your model, when no input data is provided to the tool.
[Suggestion]: Using --input_file command to specify perf input data, which can appoint valid input data.

[BPU][[BPU_MONITOR]][281473594193184][INFO]BPULib verison(2, 2, 15)[f21ee84]!
[DNN]: 3.13.6_(4.7.5 HBRT)
Load model to DDR cost 7723.92ms.
[I][12168][08-27][00:11:55:243][tensor_util.cpp:321][hrt_model_exec][HRT_MODEL_EXEC] Input[0] stride is dynamic, but you did not specify the stride, set as (983040,1280,1,1)
[I][12168][08-27][00:11:55:243][tensor_util.cpp:321][hrt_model_exec][HRT_MODEL_EXEC] Input[1] stride is dynamic, but you did not specify the stride, set as (491520,1280,2,1)
Frame count: 200, Thread Average: 1117.584717 ms, thread max latency: 1118.350952 ms, thread min latency: 1117.250000 ms, FPS: 0.894717

Running condition:
Thread number is: 1
Frame count is: 200
Program run time: 223534.641 ms
Perf result:
Frame totally latency is: 223516.938 ms
Average latency is: 1117.585 ms
Frame rate is: 0.895 FPS 是不是有问题看着

结论:确实有问题 :warning:

推理延迟 850ms~1117ms/frame 明显异常,正常 BPU 推理应该在 10~50ms 级别。


一、问题分析

从你的输出来看,有几个关键异常点:

指标 你的结果 正常范围 问题
单帧延迟 850~1117 ms 10~50 ms 慢 20~80 倍
FPS 0.89~1.17 20~60+ 极低
模型加载 7723~13291 ms 100~500 ms 加载慢
输入数量 2 个输入 通常 1 个 多输入模型

二、可能原因排查

1. 模型是否在 BPU 上运行?

hrt_model_exec perf 默认使用 随机数据,如果模型包含不支持的算子,可能回退到 CPU 运行

检查方法:

# 查看模型详细信息,确认算子类型
hrt_model_exec model_info --model_file model_best_fixed.hbm

查看输出中是否有:

  • BPU 字样(表示在 BPU 上运行)
  • CPU 字样(表示回退到 CPU)

2. 多输入模型需要指定输入数据

你的模型有 2 个输入(Input[0] 和 Input[1]),但 perf 命令使用随机数据,可能导致异常。

警告信息解读:

[Warning]: These operators have range limitations on input data:
...
[Suggestion]: Using --input_file command to specify perf input data

这说明模型中包含对输入数据敏感的算子(如 SqrtDiv 等),使用随机数据可能导致计算异常变慢。

3. 版本兼容性问题

从日志看:

[DNN]: 3.13.6_(4.7.5 HBRT)
BPULib verison(2, 2, 15)

需要确认:

  • HBM 模型是用哪个 OE 版本编译的?
  • 板端 OE 版本是否与编译版本匹配?

三、解决方案

方案 1:使用真实输入数据测试(推荐)

hrt_model_exec perf 支持 --input_file 参数,但需要二进制格式

# 1. 先将你的 .npy 转换为二进制
python3 convert_npy_to_bin.py

# 2. 查看模型输入 shape
hrt_model_exec model_info --model_file model_best_fixed.hbm

# 3. 使用真实数据测试性能
hrt_model_exec perf --model_file model_best_fixed.hbm \
    --input_file input.bin \
    --frame_count 100 \
    --thread_num 1

注意: 如果有多个输入,可能需要用特定格式(如 input1.bin,input2.bin),具体参考工具链手册。

方案 2:用自定义推理程序测试(最准确)

使用我之前提供的 infer_hbm.cpp,可以:

  • 使用真实输入数据
  • 精确计时
  • 保存输出结果对比
# 编译运行
./build/infer_hbm --model model_best_fixed.hbm --input input.bin --topk 5

# 多次运行取平均
for i in {1..10}; do
    time ./build/infer_hbm --model model_best_fixed.hbm --input input.bin
done

方案 3:检查模型编译配置

如果模型确实很慢,可能是编译时配置问题:

# 重新编译模型,确认 BPU 优化开启
hb_compile --input-model xxx.onnx \
    --output-model model_best_fixed.hbm \
    --bpu-type j5 \
    --optimization-level O2  # 或 O3

四、快速诊断命令

# 1. 确认模型输入输出
hrt_model_exec model_info --model_file model_best_fixed.hbm > model_info.txt

# 2. 检查板端 OE 版本
cat /etc/horizon/version

# 3. 检查 BPU 使用情况
cat /proc/hb_bpu/status

# 4. 监控推理时的资源使用
top -d 1  # 看 CPU 占用

五、需要你提供的信息

为了进一步帮你定位,请提供:

  1. model_info 完整输出

    hrt_model_exec model_info --model_file model_best_fixed.hbm
    
  2. 模型类型

    • 分类/检测/分割/其他?
    • 输入 shape 是什么?
  3. 编译环境

    • OE 版本(如 1.1.62)
    • 芯片型号(J5/X3/S100?)
  4. 板端环境

    cat /etc/horizon/version
    

六、预期正常值参考

芯片 模型类型 正常延迟 正常 FPS
J5 分类 (224x224) 5~15 ms 60+
J5 检测 (640x640) 20~50 ms 20~50
X3 分类 (224x224) 10~30 ms 30~60
S100 大模型 50~200 ms 5~20

你的 850ms+ 明显超出正常范围,大概率是模型未在 BPU 上运行输入数据问题

先把 model_info 的输出贴出来,我帮你看看模型配置是否有问题!

hrt_model_exec perf --model_file model_best_fixed.hbm --input_file input_y_final.npy,input_uv_final.npy
[UCP]: log level = 3
[UCP]: UCP version = 3.13.6
[VP]: log level = 3
[DNN]: log level = 3
[HPL]: log level = 3
[UCPT]: log level = 6
hrt_model_exec perf --model_file model_best_fixed.hbm --input_file input_y_final.npy,input_uv_final.npy
[BPU][[BPU_MONITOR]][281473024161056][INFO]BPULib verison(2, 2, 15)[f21ee84]!
[DNN]: 3.13.6_(4.7.5 HBRT)
Load model to DDR cost 10405ms.
[I][18072][08-27][00:47:20:556][tensor_util.cpp:321][hrt_model_exec][HRT_MODEL_EXEC] Input[0] stride is dynamic, but you did not specify the stride, set as (983040,1280,1,1)
[I][18072][08-27][00:47:20:556][tensor_util.cpp:321][hrt_model_exec][HRT_MODEL_EXEC] Input[1] stride is dynamic, but you did not specify the stride, set as (491520,1280,2,1)
[I][18072][08-27][00:47:20:560][file_util.cpp:578][hrt_model_exec][HRT_MODEL_EXEC] read file input_y_final.npy length: 983040
[I][18072][08-27][00:47:20:562][file_util.cpp:578][hrt_model_exec][HRT_MODEL_EXEC] read file input_uv_final.npy length: 491520
Frame count: 200, Thread Average: 849.744934 ms, thread max latency: 850.163025 ms, thread min latency: 849.405029 ms, FPS: 1.176702

Running condition:
Thread number is: 1
Frame count is: 200
Program run time: 169966.828 ms
Perf result:
Frame totally latency is: 169948.984 ms
Average latency is: 849.745 ms
Frame rate is: 1.177 FPS
root@ubuntu:/home/sunrise/data# hrt_model_exec perf --model_file model_cal_data_103_247.hbm --input_file input_y_final.npy,input_uv_final.npy
[UCP]: log level = 3
[UCP]: UCP version = 3.13.6
[VP]: log level = 3
[DNN]: log level = 3
[HPL]: log level = 3
[UCPT]: log level = 6
hrt_model_exec perf --model_file model_cal_data_103_247.hbm --input_file input_y_final.npy,input_uv_final.npy
[BPU][[BPU_MONITOR]][281473373140256][INFO]BPULib verison(2, 2, 15)[f21ee84]!
[DNN]: 3.13.6_(4.7.5 HBRT)
Load model to DDR cost 7684.44ms.
[I][18792][08-27][00:51:49:667][tensor_util.cpp:321][hrt_model_exec][HRT_MODEL_EXEC] Input[0] stride is dynamic, but you did not specify the stride, set as (983040,1280,1,1)
[I][18792][08-27][00:51:49:667][tensor_util.cpp:321][hrt_model_exec][HRT_MODEL_EXEC] Input[1] stride is dynamic, but you did not specify the stride, set as (491520,1280,2,1)
[I][18792][08-27][00:51:49:668][file_util.cpp:578][hrt_model_exec][HRT_MODEL_EXEC] read file input_y_final.npy length: 983040
[I][18792][08-27][00:51:49:668][file_util.cpp:578][hrt_model_exec][HRT_MODEL_EXEC] read file input_uv_final.npy length: 491520

Frame count: 200, Thread Average: 1117.309448 ms, thread max latency: 1117.727051 ms, thread min latency: 1116.943970 ms, FPS: 0.894923

Running condition:
Thread number is: 1
Frame count is: 200
Program run time: 223483.250 ms
Perf result:
Frame totally latency is: 223461.891 ms
Average latency is: 1117.309 ms
Frame rate is: 0.895 FPS

hrt_model_exec model_info --model_file model_best_fixed.hbm

[UCP]: log level = 3
[UCP]: UCP version = 3.13.6
[VP]: log level = 3
[DNN]: log level = 3
[HPL]: log level = 3
[UCPT]: log level = 6
hrt_model_exec model_info --model_file model_best_fixed.hbm
[BPU][[BPU_MONITOR]][281473032877344][INFO]BPULib verison(2, 2, 15)[f21ee84]!
[DNN]: 3.13.6_(4.7.5 HBRT)
Load model to DDR cost 10757.9ms.
This model file has 1 model:
[model_best_fixed]

[model desc]: {“BUILDER_VERSION”: “3.5.11”, “HBDK_VERSION”: “4.9.7”, “HBDK_RUNTIME_VERSION”: null, “HMCT_VERSION”: “2.7.3”, “CAFFE_MODEL”: null, “PROTOTXT”: null, “ONNX_MODEL”: “/models/model_best_fixed.onnx”, “MARCH”: “nash-m”, “LAYER_OUT_DUMP”: “False”, “LOG_LEVEL”: null, “WORKING_DIR”: “/model_output”, “MODEL_PREFIX”: “model_best_fixed”, “OUTPUT_NODES”: “”, “REMOVE_NODE_TYPE”: “Quantize;Transpose;Dequantize;Cast;Reshape;Softmax”, “REMOVE_NODE_NAME”: “”, “DEBUG_MODE”: “”, “NODE_INFO”: “{}”, “INPUT_NAMES”: “data”, “INPUT_SPACE_AND_RANGE”: “regular”, “INPUT_TYPE_RT”: “nv12”, “INPUT_TYPE_TRAIN”: “bgr”, “INPUT_LAYOUT_TRAIN”: “NHWC”, “INPUT_LAYOUT_RT”: “NHWC”, “NORM_TYPE”: “no_preprocess”, “MEAN_VALUE”: “”, “SCALE_VALUE”: “”, “STD_VALUE”: “”, “INPUT_SHAPE”: “1x768x1280x3”, “INPUT_BATCH”: “”, “SEPARATE_BATCH”: “False”, “SEPARATE_NAME”: “”, “CUSTOM_OP_METHOD”: null, “CUSTOM_OP_DIR”: null, “CUSTOM_OP_REGISTER_FILES”: “”, “OPTIMIZATION”: “run_fast”, “CALI_TYPE”: “skip”, “CAL_DATA_DIR”: “”, “PER_CHANNEL”: “False”, “MAX_PERCENTILE”: “None”, “RUN_ON_CPU”: “”, “RUN_ON_BPU”: “”, “QUANT_CONFIG”: null, “ADVICE”: 0.0, “DEBUG”: “True”, “OPTIMIZE_LEVEL”: “O2”, “COMPILE_MODE”: “latency”, “CORE_NUM”: 1, “MAX_TIME_PER_FC”: 0, “BALANCE_FACTOR”: 100, “ABILITY_ENTRY”: null, “INPUT_SOURCE”: {“data”: “pyramid”}, “hbdk3_compatible_mode”: null, “cache_mode”: “disable”, “cache_path”: “”, “max_l2m_size”: 0, “CALI_EXTRA_PARAM”: {}, “EXTRA_PARAMS”: {}}
input[0]:
name: data_y
valid shape: (1,768,1280,1)
aligned byte size: -1
tensor type: HB_DNN_TENSOR_TYPE_U8
quanti type: NONE
stride: (-1,-1,1,1)

input[1]:
name: data_uv
valid shape: (1,384,640,2)
aligned byte size: -1
tensor type: HB_DNN_TENSOR_TYPE_U8
quanti type: NONE
stride: (-1,-1,2,1)

output[0]:
name: labels
valid shape: (1,1,300,1)
aligned byte size: 384
tensor type: HB_DNN_TENSOR_TYPE_S8
quanti type: SCALE
stride: (300,300,1,1)
scale data: (1)
zero_point data: (0)

output[1]:
name: scores
valid shape: (1,1,300)
aligned byte size: 640
tensor type: HB_DNN_TENSOR_TYPE_S16
quanti type: SCALE
stride: (600,600,2)
scale data: (3.05185e-05)
zero_point data: (0)

output[2]:
name: bboxes
valid shape: (1,1,300,4)
aligned byte size: 1280
tensor type: HB_DNN_TENSOR_TYPE_S8
quanti type: SCALE
stride: (1200,1200,4,1)
scale data: (0.00787402)
zero_point data: (0)


root@ubuntu:/home/sunrise/data# cat /etc/

Display all 258 possibilities? (y or n)^C
root@ubuntu:/home/sunrise/data#
root@ubuntu:/home/sunrise/data# cat /etc/horizon/version
cat: /etc/horizon/version: No such file or directory
root@ubuntu:/home/sunrise/data# cat /proc/hb_
hb_isp hb_isp_hw1 hb_perf_monitor
root@ubuntu:/home/sunrise/data# hrt_model_exec model_info --model_file model_cal_data_103_247.hbm
[UCP]: log level = 3
[UCP]: UCP version = 3.13.6
[VP]: log level = 3
[DNN]: log level = 3
[HPL]: log level = 3
[UCPT]: log level = 6
hrt_model_exec model_info --model_file model_cal_data_103_247.hbm
[BPU][[BPU_MONITOR]][281473438283040][INFO]BPULib verison(2, 2, 15)[f21ee84]!
[DNN]: 3.13.6_(4.7.5 HBRT)
Load model to DDR cost 7546.14ms.
This model file has 1 model:
[model_cal_data]

[model desc]: {“BUILDER_VERSION”: “3.5.11”, “HBDK_VERSION”: “4.9.7”, “HBDK_RUNTIME_VERSION”: null, “HMCT_VERSION”: “2.7.3”, “CAFFE_MODEL”: null, “PROTOTXT”: null, “ONNX_MODEL”: “/models/model_best_fixed_horizon.onnx”, “MARCH”: “nash-m”, “LAYER_OUT_DUMP”: “False”, “LOG_LEVEL”: null, “WORKING_DIR”: “/model_04_11_up”, “MODEL_PREFIX”: “model_cal_data”, “OUTPUT_NODES”: “”, “REMOVE_NODE_TYPE”: “”, “REMOVE_NODE_NAME”: “”, “DEBUG_MODE”: “”, “NODE_INFO”: “{}”, “INPUT_NAMES”: “data”, “INPUT_SPACE_AND_RANGE”: “regular”, “INPUT_TYPE_RT”: “nv12”, “INPUT_TYPE_TRAIN”: “rgb”, “INPUT_LAYOUT_TRAIN”: “NHWC”, “INPUT_LAYOUT_RT”: “”, “NORM_TYPE”: “data_scale”, “MEAN_VALUE”: “”, “SCALE_VALUE”: “[0.003921568627451]”, “STD_VALUE”: “”, “INPUT_SHAPE”: “1x768x1280x3”, “INPUT_BATCH”: “”, “SEPARATE_BATCH”: “False”, “SEPARATE_NAME”: “”, “CUSTOM_OP_METHOD”: null, “CUSTOM_OP_DIR”: null, “CUSTOM_OP_REGISTER_FILES”: “”, “OPTIMIZATION”: “”, “CALI_TYPE”: “max”, “CAL_DATA_DIR”: “/dataset/calibration_data/”, “PER_CHANNEL”: “False”, “MAX_PERCENTILE”: “0.999”, “RUN_ON_CPU”: “”, “RUN_ON_BPU”: “”, “QUANT_CONFIG”: null, “ADVICE”: 1.0, “DEBUG”: “False”, “OPTIMIZE_LEVEL”: “O2”, “COMPILE_MODE”: “balance”, “CORE_NUM”: 1, “MAX_TIME_PER_FC”: 0, “BALANCE_FACTOR”: 2, “ABILITY_ENTRY”: null, “INPUT_SOURCE”: {“data”: “pyramid”}, “hbdk3_compatible_mode”: null, “cache_mode”: “disable”, “cache_path”: “”, “max_l2m_size”: 0, “CALI_EXTRA_PARAM”: {}, “EXTRA_PARAMS”: {“input_no_padding”: true, “output_no_padding”: true}}
input[0]:
name: data_y
valid shape: (1,768,1280,1)
aligned byte size: -1
tensor type: HB_DNN_TENSOR_TYPE_U8
quanti type: NONE
stride: (-1,-1,1,1)

input[1]:
name: data_uv
valid shape: (1,384,640,2)
aligned byte size: -1
tensor type: HB_DNN_TENSOR_TYPE_U8
quanti type: NONE
stride: (-1,-1,2,1)

output[0]:
name: labels
valid shape: (1,300,1)
aligned byte size: 1216
tensor type: HB_DNN_TENSOR_TYPE_F32
quanti type: NONE
stride: (1200,4,4)

output[1]:
name: scores
valid shape: (1,300,1)
aligned byte size: 1216
tensor type: HB_DNN_TENSOR_TYPE_F32
quanti type: NONE
stride: (1200,4,4)

output[2]:
name: bboxes
valid shape: (1,300,4)
aligned byte size: 4864
tensor type: HB_DNN_TENSOR_TYPE_F32
quanti type: NONE
stride: (4800,16,4)

信息是这些

S100 提供 Python 推理接口:Python 接口手册 | RDK DOC

工具链手册也提供了ucp C接口

可以自行进行代码编写进行benchmark测试

结论:找到问题了!:warning:

根据你提供的 model_info 输出,我发现了3 个关键问题导致推理速度异常慢:


一、核心问题分析

问题 1:版本不匹配(最可能原因)

环境 版本
模型编译版本 HBDK 4.9.7
板端 Runtime 版本 HBRT 4.7.5

编译版本 > 板端版本,可能导致:

  • 部分算子无法在 BPU 上运行,回退到 CPU
  • 推理效率大幅下降

问题 2:输入数据格式问题

你直接用 .npy 文件作为输入:

--input_file input_y_final.npy,input_uv_final.npy

.npy 文件包含 numpy header(约 128 字节),不是纯二进制数据。虽然工具能读取,但可能导致:

  • 数据对齐异常
  • 需要额外的数据转换开销

问题 3:模型输出类型差异

模型 输出类型 延迟
model_best_fixed S8/S16 (量化) 850ms
model_cal_data F32 (浮点) 1117ms

量化模型反而更快,说明量化配置正确,但整体还是太慢。


二、解决方案

方案 1:升级板端 OE 版本(推荐)

# 检查当前 OE 版本
hrt_model_exec --version

# 升级到与编译版本匹配的 OE 包(4.9.7 或更高)
# 具体升级方法参考地平线官方文档

方案 2:转换输入数据为纯二进制

# convert_npy_to_bin.py
import numpy as np

# 加载 .npy 文件
y_data = np.load('input_y_final.npy')
uv_data = np.load('input_uv_final.npy')

# 直接保存 raw 数据(去掉 numpy header)
y_data.astype(np.uint8).tofile('input_y.bin')
uv_data.astype(np.uint8).tofile('input_uv.bin')

print(f"Y: {y_data.shape} -> {y_data.nbytes} bytes")
print(f"UV: {uv_data.shape} -> {uv_data.nbytes} bytes")

然后用二进制文件测试:

hrt_model_exec perf --model_file model_best_fixed.hbm \
    --input_file input_y.bin,input_uv.bin \
    --frame_count 100

方案 3:用自定义推理程序验证(最准确)

使用我之前提供的 infer_hbm.cpp,可以:

  • 精确控制输入数据格式
  • 准确计时
  • 保存输出结果与 PC 端对比

三、模型信息解读

你的模型是目标检测模型(类似 YOLO):

输出节点 Shape 含义
labels (1,1,300,1) 300 个检测框的类别
scores (1,1,300) 300 个检测框的置信度
bboxes (1,1,300,4) 300 个检测框的坐标 (x1,y1,x2,y2)

输入规格:

  • 分辨率:768x1280
  • 格式:NV12 分离输入(Y + UV)
  • 芯片:nash-m (S100 系列)

预期正常性能:

芯片 输入分辨率 正常延迟
S100 (nash) 768x1280 检测 50~150 ms

你的 850ms+ 确实异常,正常应该快 5-10 倍。


四、快速诊断步骤

# 1. 检查 BPU 使用情况(推理时监控)
watch -n 1 cat /proc/hb_bpu/status

# 2. 检查 CPU 占用(如果 CPU 占用高,说明回退到 CPU 了)
top -d 1

# 3. 用纯二进制输入重新测试
python3 convert_npy_to_bin.py
hrt_model_exec perf --model_file model_best_fixed.hbm \
    --input_file input_y.bin,input_uv.bin \
    --frame_count 50

# 4. 检查版本详情
hrt_model_exec --version
hb_compiler --version  # 如果在编译环境

五、需要你确认的信息

  1. 板子型号:是 RDK S100 吗?
  2. OE 包版本:运行 hrt_model_exec --version 看完整版本
  3. 编译环境:模型是在本地编译还是云端编译?
  4. 预期用途:这个检测模型是用来做什么的?(可以帮你优化后处理)

六、临时 workaround

如果暂时无法升级 OE 版本,可以:

  1. 重新用 4.7.5 版本编译模型(与板端匹配)
  2. 使用自定义推理程序infer_hbm.cpp),可能比 hrt_model_exec 更快
  3. 降低输入分辨率测试(如 384x640),看延迟是否成比例下降

先把 hrt_model_exec --version 的输出发出来,我帮你确认版本匹配问题!

方案 1:升级板端 OE 版本(推荐)如何升级啊

结论:S100 系统升级不能直接用 apt upgrade :warning:

根据社区案例,RDK S100 的系统升级需要通过「刷写官方镜像」完成,而不是简单的 apt 命令。


一、正确升级步骤

步骤 1:获取最新系统镜像

方式 A:官方文档下载

  1. 访问 RDK S 工具链开发文档
  2. 查找「系统镜像下载」章节
  3. 下载 S100 最新系统镜像(如 4.0.5-Beta)

方式 B:社区资源帖


步骤 2:准备烧录工具

宿主机(PC)上操作:

# 安装烧录工具
sudo apt install u-boot-tools

# 准备 SD 卡(至少 16GB)
# 插入 SD 卡后查看设备名(如 /dev/sdb)
lsblk

步骤 3:烧录系统镜像

# 解压下载的镜像(如果是压缩包)
tar -xvf s100_v4.0.5-beta.tar.gz

# 烧录到 SD 卡(⚠️ 确认 /dev/sdX 是你的 SD 卡设备名)
sudo dd if=s100_v4.0.5-beta.img of=/dev/sdX bs=4M conv=fsync status=progress

# 同步数据
sync

步骤 4:启动并升级

  1. 将 SD 卡插入 S100
  2. 从 SD 卡启动(可能需要设置启动跳线或按键)
  3. 按照屏幕提示完成刷写
  4. 重启后验证版本
    cat /etc/version
    # 应显示新版本号
    

二、重要注意事项

事项 说明
:warning: 备份数据 升级会清空系统盘,提前备份模型和代码
:warning: 电源稳定 烧录过程中断电会导致变砖
:warning: 镜像匹配 确认下载的是 S100/S100P 专用镜像
:white_check_mark: 升级后 建议用新版 OE 重新编译模型获取最佳性能

三、你的情况特殊建议

根据你的 model_info 输出:

  • 模型编译版本:HBDK 4.9.7
  • 板端 Runtime:HBRT 4.7.5

建议优先级:

方案 A:重新用 4.7.5 版本编译模型(最快)

如果无法立即升级系统,可以:

  1. 在编译环境安装 OE 4.7.5 版本
  2. 重新编译模型:
    hb_compile --input-model xxx.onnx \
        --output-model model_fixed.hbm \
        --bpu-type nash-m \
        --optimization-level O2
    
  3. 部署到板端测试

方案 B:升级板端系统(彻底解决)

按上述步骤升级到 4.9.x 版本系统,匹配你的编译版本。


四、快速验证命令

升级前后都可以用这些命令检查:

# 查看系统版本
cat /etc/version

# 查看 Runtime 版本
hrt_model_exec --version

# 查看 BPU 库版本
cat /proc/hb_bpu/version  # 或类似路径

五、需要帮助?

如果遇到问题,请提供:

  1. 当前系统版本:cat /etc/version
  2. 目标升级版本(从官方文档确认)
  3. 是否有官方镜像文件

建议先在社区搜索「S100 系统升级」相关帖子,或联系地平线技术支持获取最新镜像和详细教程!

我烧录的soc系统已经升级到了4.0.5.beta,还不满足吗

结论:4.0.5-beta 应该够了,但需要确认 Runtime 版本 :white_check_mark:

系统升级到 4.0.5-beta 后,关键不是系统版本号,而是 Runtime 库版本是否匹配


一、先确认升级后的实际版本

请运行以下命令,确认升级是否生效:

# 1. 查看系统版本
cat /etc/version

# 2. 查看 Runtime 版本(关键!)
hrt_model_exec --version

# 3. 查看 BPU 库版本
ls /lib/libhb_bpu*  # 或
cat /proc/hb_bpu/version

期望结果:

组件 当前 期望
系统版本 4.0.5-beta :white_check_mark: 已升级
HBRT 4.7.5 应 ≥ 4.9.x
BPULib 2.2.15 应更新

二、如果 Runtime 还是 4.7.5

说明系统升级了,但 Runtime 库没更新。解决方法:

方案 1:重新编译模型(推荐,最快)

用与板端匹配的 OE 版本重新编译:

# 在编译环境安装 OE 4.7.5 或更低版本
# 重新编译模型
hb_compile --input-model model_best_fixed.onnx \
    --output-model model_fixed_v2.hbm \
    --bpu-type nash-m \
    --optimization-level O2 \
    --compile-mode latency

方案 2:更新板端 Runtime 库

# 尝试更新地平线相关包
sudo apt update
sudo apt install horizon-runtime horizon-bpu-lib

# 或从 OE 包中拷贝 Runtime 库
# 参考 OE 包文档中的「板端部署」章节

三、同时排查输入数据问题

你之前用 .npy 文件直接作为输入,这可能有 numpy header 开销。建议:

# convert_npy_to_bin.py
import numpy as np

y_data = np.load('input_y_final.npy')
uv_data = np.load('input_uv_final.npy')

# 保存纯二进制(去掉 numpy header)
y_data.astype(np.uint8).tofile('input_y.bin')
uv_data.astype(np.uint8).tofile('input_uv.bin')

print(f"Y: {y_data.nbytes} bytes, UV: {uv_data.nbytes} bytes")

然后用二进制文件测试:

hrt_model_exec perf --model_file model_best_fixed.hbm \
    --input_file input_y.bin,input_uv.bin \
    --frame_count 50

四、预期正常性能参考

芯片 输入分辨率 模型类型 正常延迟
S100 (nash-m) 768x1280 检测 50~150 ms

如果升级后还是 850ms+,大概率是:

  1. Runtime 库未更新
  2. 模型编译版本过高
  3. 输入数据格式问题

五、请提供以下信息

# 1. 升级后的版本信息
cat /etc/version
hrt_model_exec --version

# 2. 重新测试性能
hrt_model_exec perf --model_file model_best_fixed.hbm \
    --input_file input_y.bin,input_uv.bin \
    --frame_count 50

把输出贴出来,我帮你判断是 版本问题 还是 其他原因


六、如果还是慢的临时方案

  1. 降低输入分辨率测试(如 384x640),看延迟是否成比例下降
  2. 用自定义推理程序infer_hbm.cpp),可能比 hrt_model_exec 更快
  3. 联系地平线技术支持,确认 4.0.5-beta 对应的 OE 版本