I encountered the error shown in the picture when converting onnx to hef. The conversion code and error are as follows. Thank you very much.
Code:
import os
import numpy as np
import logging
from typing import List
from hailo_sdk_client import ClientRunner
import onnx
import onnx.checker
from mmcv import Config
from mmdet.datasets import build_dataset, build_dataloader
import torch
import tensorflow as tf
from projects.mmdet3d_plugin.datasets.nuscenes_3d_det_track_dataset import NuScenes3DDetTrackDataset
# ===================== 日志 =====================
logging.basicConfig(level=logging.INFO, format="%(asctime)s - %(levelname)s - %(message)s")
log = logging.getLogger("onnx2hef_dataloader")
# ===================== 1) 基本配置 =====================
ONNX_PATH = "/home/ubuntu/ycy/Sparse4D-3.1latest/onnx_models/backbone_neck_simplified.onnx"
INPUT_NAME = "input"
OUTPUT_NAMES = ["output_0", "output_1", "output_2", "output_3"]
B, C, H, W = 1, 18, 256, 704
OUTDIR = "/home/ubuntu/ycy/Sparse4D-3.1latest/onnx_models/hailo_outputs_bn"
NET_NAME = "backbone_neck"
HW_ARCH = "hailo8"
HAR_FLOAT = os.path.join(OUTDIR, f"{NET_NAME}_hailo_model.har")
HAR_QUANT = os.path.join(OUTDIR, f"{NET_NAME}_hailo_quantized_model.har")
HEF_PATH = os.path.join(OUTDIR, f"{NET_NAME}.hef")
CONFIG_FILE = "/home/ubuntu/ycy/Sparse4D-3.1latest/projects/configs/sparse4dv3_temporal_r50_1x8_bs6_256x704.py"
NUM_GROUPS = 126
# ===================== 2) 工具函数 =====================
def verify_onnx(path: str, input_name: str, expected_outputs: List[str] = None):
assert os.path.exists(path), f"ONNX 不存在: {path}"
m = onnx.load(path)
onnx.checker.check_model(m)
inputs = [i.name for i in m.graph.input]
outputs = [o.name for o in m.graph.output]
log.info(f"ONNX 输入名: {inputs}, 输出名: {outputs}")
if input_name not in inputs:
log.warning(f"期望输入名 '{input_name}',实际 {inputs}。")
if expected_outputs and not all(o in outputs for o in expected_outputs):
log.warning(f"期望输出名 {expected_outputs},实际 {outputs}。")
def get_calibration_data(config_file: str, num_groups: int) -> np.ndarray:
cfg = Config.fromfile(config_file)
dataset = build_dataset(cfg.data.val)
data_loader = build_dataloader(dataset, samples_per_gpu=1, workers_per_gpu=0, dist=False, shuffle=False)
calib_nchw = []
for i, data in enumerate(data_loader):
if i >= num_groups:
break
cams = []
for j in range(6):
cam_key = f'cam{j}' if f'cam{j}' in data else f'img{j}'
if cam_key not in data:
raise KeyError(f"Cannot find {cam_key} in data")
cam_data = data[cam_key].data[0]
log.info(f"Cam {j} shape: {cam_data.shape}, mean={cam_data.mean():.2f}, std={cam_data.std():.2f}")
cams.append(cam_data)
input_tensor = torch.cat(cams, dim=1)
log.info(f"Input tensor shape: {input_tensor.shape}")
calib_nchw.append(input_tensor.numpy())
calib_nchw = np.stack(calib_nchw, axis=0)
log.info(f"✅ NCHW 校准原始: shape={calib_nchw.shape}, ndim={calib_nchw.ndim}, dtype={calib_nchw.dtype}, "
f"min={calib_nchw.min():.1f}, max={calib_nchw.max():.1f}, "
f"mean={calib_nchw.mean():.1f}, std={calib_nchw.std():.1f}")
return calib_nchw
# ===================== 3) 主流程 =====================
def main():
log.info(f"TensorFlow version: {tf.__version__}")
log.info(f"GPU devices: {tf.config.list_physical_devices('GPU')}")
log.info(f"cuDNN version: {tf.sysconfig.get_build_info().get('cudnn_version', 'Not found')}")
os.makedirs(OUTDIR, exist_ok=True)
verify_onnx(ONNX_PATH, INPUT_NAME, OUTPUT_NAMES)
log.info(f"输入规范: name={INPUT_NAME}, shape={(B, C, H, W)}, RGB, ImageNet normalized")
runner = ClientRunner(hw_arch=HW_ARCH)
try:
runner.translate_onnx_model(
model=ONNX_PATH,
net_name=NET_NAME,
net_input_shapes={INPUT_NAME: (B, C, H, W)},
start_node_names=[INPUT_NAME],
)
runner.save_har(HAR_FLOAT)
log.info(f"✅ HAR(float) 已保存: {HAR_FLOAT}")
except Exception as e:
log.error(f"❌ 转换 ONNX 到 HAR 失败: {e}")
raise
script_lines = [
"model_optimization_flavor(optimization_level=1, compression_level=0)", # 恢复量化
"resources_param(max_control_utilization=0.8, max_compute_utilization=0.8, max_memory_utilization=0.8)",
]
try:
runner.load_model_script("\n".join(script_lines))
log.info("✅ model script 已加载(启用量化优化)。")
except Exception as e:
log.warning(f"⚠️ model script 加载失败(可忽略/按需调整):{e}")
calib_nchw = get_calibration_data(CONFIG_FILE, NUM_GROUPS)
if calib_nchw.ndim == 4:
log.info("calib_nchw is 4D, applying standard NHWC transpose")
calib_nhwc = np.transpose(calib_nchw, (0, 2, 3, 1)) # (num_groups, H, W, C)
else:
log.warning(f"calib_nchw has unexpected ndim={calib_nchw.ndim}, attempting original transpose logic")
try:
calib_nhwc = np.transpose(calib_nchw, (0, 1, 3, 4, 2)).reshape(NUM_GROUPS, H, W, C)
except ValueError as e:
log.error(f"Failed to transpose calib_nchw: {e}")
raise
log.info(f"✅ NHWC 校准供 optimize: shape={calib_nhwc.shape}, ndim={calib_nhwc.ndim}, dtype={calib_nhwc.dtype}, "
f"min={calib_nhwc.min():.1f}, max={calib_nhwc.max():.1f}, mean={calib_nhwc.mean():.1f}")
try:
runner.optimize(calib_nhwc)
log.info("✅ Optimize 完成(NHWC dataset)。")
except Exception as e:
log.error(f"❌ Optimize 失败: {e}")
raise
try:
runner.save_har(HAR_QUANT)
log.info(f"✅ HAR(quantized) 已保存: {HAR_QUANT}")
har_for_compile = HAR_QUANT
except Exception as e:
log.info(f"ℹ️ 保存量化 HAR 失败,使用 float HAR: {e}")
har_for_compile = HAR_FLOAT
try:
hef = runner.compile()
try:
hef.save(HEF_PATH)
except Exception:
with open(HEF_PATH, "wb") as f:
f.write(hef)
log.info(f"✅ HEF 已导出: {HEF_PATH}")
except AttributeError:
runner.save_hef(HEF_PATH)
log.info(f"✅ HEF 已导出(save_hef): {HEF_PATH}")
log.info("🎉 完成 ONNX -> HAR -> (Quant)HAR -> HEF 全流程。")
if __name__ == "__main__":
main()
error
[error] Mapping Failed (allocation time: 18m 14s)
No successful assignment for: conv50, conv51, conv53, conv54, conv56, conv28, conv14
[error] Failed to produce compiled graph
[error] BackendAllocatorException: Compilation failed: No successful assignment for: conv50, conv51, conv53, conv54, conv56, conv28, conv14