fix(actpred): 修复 HEF 帧归一化误判与部署图数值不等价,补齐 P3 审计项
- hailo_infer: 帧归一化判定改为量化网格 dequant(0)(旧启发式把归一化 帧当原始像素喂入,图像路径饱和破坏;实机 max_diff 2.55→0.37, img 敏感性 1.44→22.26) - export_deploy: pool kernel 由卷积真实输出尺寸探测(H//16 在 1080 高度下静默丢弃末行);mobilenet backbone 给出明确报错 - mt_parser: @Action 为文件末位块时解析成功,不再静默丢数据 - config: checkpoint train 段未知键/非 dict 校验;init-from 兼容性 警告助手(normalize/action_dim),train 与 pretrain 共用 - dataset: stats 文件形状校验;predict: 移除误导性 --action-dim - dfc_compile: --frame-count 参数化(原硬编码 3 帧) - gen_calibration: 旧模式校准图像改分块 memmap 生成(1080p 原一次性 分配 ~600MB) - _npu_test: torch 参考反归一化对齐后再与 HEF 比较 - 单测 81→90 全过;README 与测速报告更新为验证轮次数据
This commit is contained in:
1 parent
316758d80e
commit
823e91a30e
14 files changed
+381
-62
No files matched your search
+16
-6
@@ -34,8 +34,12 @@ import tempfile
|
||||
|
||||
|
||||
NET_NAME = "actpred_deploy"
|
||||
START_NODES = ["frame0", "frame1", "frame2", "action_history", "pred_token"]
|
||||
INPUT_FORMATS = ["NHWC", "NHWC", "NHWC", "NHWC", "NHWC"]
|
||||
|
||||
|
||||
def start_nodes(frame_count: int) -> list:
|
||||
"""export_deploy.py 的输入命名约定:frame{i} × frame_count + action_history + pred_token"""
|
||||
return ([f"frame{i}" for i in range(frame_count)]
|
||||
+ ["action_history", "pred_token"])
|
||||
|
||||
|
||||
def hailo(*args, venv_bin: str):
|
||||
@@ -111,6 +115,9 @@ def main():
|
||||
parser.add_argument("--hw-arch", default="hailo10h",
|
||||
choices=["hailo15h", "hailo15m", "hailo15l",
|
||||
"hailo10h", "hailo10p"])
|
||||
parser.add_argument("--frame-count", type=int, default=3,
|
||||
help="帧输入个数(与导出 ONNX 的 frame_len 一致,"
|
||||
"默认 3)")
|
||||
parser.add_argument("--venv-bin", default="venv_dfc/bin",
|
||||
help="安装了 hailo-sdk 的 venv bin 目录")
|
||||
args = parser.parse_args()
|
||||
@@ -119,6 +126,9 @@ def main():
|
||||
if not os.path.exists(os.path.join(venv_bin, "hailo")):
|
||||
sys.exit(f"错误: {venv_bin}/hailo 不存在,请先安装 hailo-sdk")
|
||||
|
||||
nodes = start_nodes(args.frame_count)
|
||||
input_formats = ["NHWC"] * len(nodes)
|
||||
|
||||
workdir = tempfile.mkdtemp(prefix="dfc_")
|
||||
har_raw = os.path.join(workdir, "parsed.har")
|
||||
har_opt = os.path.join(workdir, "optimized.har")
|
||||
@@ -129,16 +139,16 @@ def main():
|
||||
print("[1/3] parser: ONNX → HAR")
|
||||
hailo("parser", "onnx", args.onnx, "--hw-arch", args.hw_arch, "-y",
|
||||
"--har-path", har_raw,
|
||||
"--start-node-names", *START_NODES,
|
||||
"--start-node-names", *nodes,
|
||||
"--end-node-names", "predicted_action",
|
||||
"--input-format",
|
||||
*[f"{n}={f}" for n, f in zip(START_NODES, INPUT_FORMATS)],
|
||||
*[f"{n}={f}" for n, f in zip(nodes, input_formats)],
|
||||
"--disable-onnx-simplifier", venv_bin=venv_bin)
|
||||
|
||||
# 校验未被推荐机制截断:输出层应来自预测头(conv 而非 ew_add)
|
||||
names = har_input_layer_names(har_raw)
|
||||
if len(names) != len(START_NODES):
|
||||
sys.exit(f"错误: HAR 输入层数 {len(names)} != {len(START_NODES)},解析可能被截断")
|
||||
if len(names) != len(nodes):
|
||||
sys.exit(f"错误: HAR 输入层数 {len(names)} != {len(nodes)},解析可能被截断")
|
||||
check_input_connectivity(har_raw, names)
|
||||
|
||||
print("[2/3] optimize: 量化校准")
|
||||
|
||||
Reference in new issue
Block a user