12. 运行环境与常见问题¶
12.1 单机运行¶
| 阶段 | 设备 | 说明 |
|---|---|---|
标定 calibrate-subject |
CPU | 每次佩戴一次 |
| 左右检查与修正、30 Hz 导出、校验页、总览页、LeRobot 转换 | CPU | |
| 补全与投影、手部融合 | 推荐 GPU | CPU 也能跑,慢很多;严格配置约为默认配置的 5 倍耗时 |
| 重新训练 | GPU |
- 推荐 Python 3.10 加一块 NVIDIA GPU。Apple Silicon 上请用
--device cpu:在部分 PyTorch 版本组合下,MPS 上的优化会发散。 - 磁盘:每条录制的处理结果(不含视频)为几十 MB,校验页的 360p 视频副本另算。
- 耗时长的任务放在
tmux、screen里或用nohup运行。所有阶段都支持跳过已完成的录制,中断后重跑即可。 - 环境方面:
- 向已经装好的环境里加包时用
pip install --no-deps,否则依赖解析可能把 torch 换掉; - 同一个环境里不要同时装
nvidia-*-cu12和nvidia-*-cu13两套包,它们写入同一批文件,安装顺序不对就会报undefined symbol: ncclCommResume; - torch 2.x 的部分算子会即时编译 triton kernel,需要 Python 头文件(
Python.h)。使用独立打包的 Python 时,把它的include/目录加进CPATH; - 多个进程共用 GPU 时,给每个进程单独设置
TRITON_CACHE_DIR和TORCHINDUCTOR_CACHE_DIR。
- 向已经装好的环境里加包时用
12.2 容易出错的地方¶
数据本身
- 各路信号的采样率永远不一致。 每个阶段都要按时间戳重采样(线性插值或 Slerp),不能按下标对齐,也不能假设固定帧率。例如脚部着地概率是 60 Hz,tracker 轨迹是原生速率,两者长度不同,按下标截断要么悄悄错位,要么直接报错。正确的写法可参考
_load_contact_probability()。 - 相对时间与绝对时间。 SMPL-X 输出的时间从 0 开始,其它信号是系统时钟,直接混用会差出十几亿秒。
- 无效的四元数。 有些帧的四元数长度为 0 却标为有效,少数录制含 NaN。每个 tracker 单独重采样,只用有效且数值有限的样本。
- 时间戳不单调。 个别文件有两帧早了几毫秒,会让 Slerp 报错,管线已经处理。
- 目录层级不统一。 一律用
rglob递归查找,固定层级的 glob 会悄悄漏掉录制。 - 手套类型看
session.json。 MANUS 和 Wuji 的骨架都是 21 个节点,不能靠节点数区分,要看glove_type。 - "恢复"类录制要单独检查,确认手腕 tracker 有数据。
处理参数
- 学习率 0.008 会发散,用 0.004。
- 躯干前倾上限设成 15° 会让弯腰类动作沉到地面以下,默认配置用 90°。
- 用错标定代价很大。 同一条录制换成别人的标定,残差能从约 60 mm 升到 80 mm 以上。每个 batch 只放同一个人、同一次佩戴的录制。
运行与排查
- 状态为 ok 不代表结果好,要按
position_residual_m筛选。 - 进程因内存不足被杀时没有报错信息。 状态为失败却没有原因时,先用
dmesg | tail查有没有oom-kill。 - 不要把结果写回采集目录,统一写到
$WORK/out。