fix(actpred): 定位 HEF 输入不敏感根因,补齐归一化预训练链路
根因:预训练全零图像占位使 BN running_var 停在初始小值,推理时 特征放大至 ±1e6,DFC 在 token merge 点按最大幅度分配共享量化 scale,pred_token/act_tokens 全部被压成 0,HEF 输出对任何输入 恒定(详见 docs/reports/actpred_hef_insensitivity_rootcause_20260813.md) - export_deploy.py:新增 check_token_ranges 导出前 token 量级检查 (|img|>100 中止导出并提示微调;act/img 比例过大警告;归一化 模型在 z 空间采样,避免零方差列爆炸) - pretrain_mt.py:新增 --random-images(ImageNet 归一化噪声占位, 恢复 BN 统计)、--init-from(微调起点,含动作空间一致性警告)、 --normalize-actions 完整支持(训练集 stats 计算与保存、验证集复用) - gen_calibration.py:归一化模型的校准集自动 z-score 动作历史 - _onnx_validate.py / _npu_test.py:归一化模型适配(torch 参考 z-score、HailoPredictor 传 stats_path) - README:预训练章节补充新参数与 NPU 部署警告 - 单测 76/76 通过;冒烟验证:1 epoch 噪声微调后 |img| 2.46e5→8, 归一化后 |act| 694→2.9
This commit is contained in:
1 parent
8c58770280
commit
52c0ade3c4
8 files changed
+394
-27
No files matched your search
@@ -22,6 +22,7 @@
|
||||
"""
|
||||
|
||||
import argparse
|
||||
import os
|
||||
|
||||
import numpy as np
|
||||
|
||||
@@ -77,6 +78,27 @@ def build_deploy_set(args):
|
||||
history = build_action_history_samples(
|
||||
args.mt_dir, args.samples, cfg.history_len, cfg.action_dim, rng)
|
||||
history = history[:, None, :, :] # (N, 1, H_len, D)
|
||||
if cfg.normalize_actions:
|
||||
# 归一化模型的 HEF 输入是 z-score 历史(hailo_infer --stats 同语义),
|
||||
# 校准数据必须走同一变换,否则量化范围与推理分布不匹配
|
||||
stats_path = cfg.action_stats_path
|
||||
if not stats_path:
|
||||
stats_path = os.path.join(
|
||||
os.path.dirname(os.path.abspath(args.model)),
|
||||
"action_stats.npy")
|
||||
elif not os.path.isabs(stats_path):
|
||||
stats_path = os.path.join(
|
||||
os.path.dirname(os.path.abspath(args.model)), stats_path)
|
||||
if not os.path.exists(stats_path):
|
||||
raise FileNotFoundError(
|
||||
f"模型训练时启用了动作归一化,但未找到统计文件: {stats_path}")
|
||||
stats = np.load(stats_path)
|
||||
if stats.shape != (2, cfg.action_dim):
|
||||
raise ValueError(
|
||||
f"action stats 形状应为 (2, {cfg.action_dim}),"
|
||||
f"实际为 {stats.shape}: {stats_path}")
|
||||
history = (history - stats[0]) / stats[1]
|
||||
print(f" action_history: 已 z-score 归一化({stats_path})")
|
||||
|
||||
model = ActionPredictor(parse_checkpoint_config(ckpt["config"]).model,
|
||||
cfg, pretrained=False)
|
||||
|
||||
Reference in new issue
Block a user