先纠正一个流传很广的说法
搜「Microduck 量化部署」,中文结果里大量文章写着「主控是 ESP32-S3」「状态空间 31 维」「STM32 做 PD 控制」。
官方一手材料写的完全是另一回事:整机主控是 Rockchip RK3566,运行时是一组 Rust 守护进程,以 50 Hz 控制回路驱动 15 个舵机;训练仓基于 mjlab 与 PPO,所有策略共享 61 维观测、14 维动作,导出器把观测归一化烘焙进 ONNX 图,发布前会校验图是 61 进 14 出。官方产品页也明确写了 50 Hz 板载策略循环与 7 个已发布可重训的出厂策略。
那 ESP32-S3 从哪来的?它是玩家把训练好的行走策略从 fp32 量化到 int8、压到极小的体积后塞进微控制器的降本复刻路线,社区报道里写的是「模型参数从 32 位浮点量化到 int8,压缩到 2K 就塞进了 ESP32-S3」。这是复刻者的选择,不是官方硬件规格,也没有统一仓库与版本。两类文章混着读,最危险的后果是拿 31 维状态向量去拼官方 61 维策略的输入:形状都对不上,还可能被当成「量化精度损失」调上半天。
从训练产物到板载推理的七步
步骤按官方训练仓的导出与复演路径组织,量化部分标了哪些属于社区口径。每一步都写了预期结果,不通过就停在原地。
-
只用官方导出脚本产出 ONNX。命令是
uv run scripts/export.py Mjlab-Velocity-Flat-MicroDuck --wandb-run-path 你的训练记录。预期结果:得到一个 ONNX 文件。不要手工把.ptcheckpoint 转成 ONNX 就部署——官方导出器会把观测归一化烘焙进图,手转的版本在真机运行时没有外部训练器替你补这一步,运行时会看到未归一化的观测。 -
校验图形状与输出有效性。预期结果:输入 1×61、输出 1×14,跑一组合理输入无 NaN、非常量输出。官方
uv run publish会做这类校验并拒绝坏图,可以借它当检查点。形状不对就回第 1 步,别往上机走。 -
做 CPU 复演并比对数值。用
uv run scripts/infer_policy.py --walking output.onnx在 CPU 的 MuJoCo 里用键盘驱动策略,有条件再拿 PyTorch 输出对一次数值。预期结果:仿真里能走、数值量级一致。导出或归一化有问题,通常在这一步就会暴露,而不是等到真机倒地。 - 决定精度,不要默认必须量化。见下表。预期结果:能说清自己为什么选 fp32、fp16 或 int8,以及推理耗时相对控制周期有没有余量。社区实测里既有方案最终选了 fp32,因为小 MLP 在 ESP32-S3 上单次推理约 0.8 毫秒,远低于 20 毫秒控制周期;也有方案量化后把控制频率从 20Hz 提到 50Hz。两组数字来自不同网络规模与不同平台,不能互相套用。
- 若确实走 int8,先做代表性校准。用真机回传或仿真采集的观测样本做训练后量化校准,再对比 fp32、fp16、int8 三种精度下的策略输出差异;精度掉得明显就考虑量化感知训练。预期结果:姿态控制相关输出没有不可接受的偏移。注意社区文章里「PTQ 掉 4.2%、QAT 掉 0.8%」是语音唤醒任务的数据,只能当方法参考,不能当步态策略的精度承诺。
- 板载集成时对齐状态向量。固定大小输入输出缓冲、推理前做一次 warm-up 避免首次调用延迟落在控制周期里、明确维度顺序约定;把 IMU 姿态、关节角度、上一帧动作、命令块按训练时的顺序与单位拼接。预期结果:实物一帧与仿真一帧逐项量级、符号一致。这里最常犯的错是单位——仿真用弧度,真机读的是编码器位置,直接灌进去就是站起来一秒就往前栽。
- 分级上机:卸力预览 → 固定中位做开环测试 → 软地面或系一根安全绳 → 小范围行走。预期结果:每一级都稳定才放开下一级。第一次上电务必留一只手扶着,别在桌边测试。
三种精度怎么选
| 精度 | 适用判断 | 代价与风险 |
|---|---|---|
| fp32 | 网络规模小、主控推理耗时相对 20ms 周期有余量时优先 | 体积与功耗较高,但在多数复刻平台上根本不构成瓶颈 |
| fp16 | 需要减体积又不想做校准的折中 | 仍需确认板载推理库支持,策略输出偏移要用真机样本比对 |
| int8 | 只有微控制器可用、必须把模型压到极小体积时才选 | 需要代表性校准集;精度损失可能让姿态控制偏移;策略冻结后更难跟随官方更新 |
这里没有任何「必须量化到 int8」的结论。官方原版跑的是 ONNX 策略,量不量化是复刻平台算力与体积约束下的工程选择,把它写进「官方流程」是二手文章的另一个常见偏差。
量化导出的固有局限
| 局限 | 具体表现 | 可做的补救 |
|---|---|---|
| 策略冻结 | 复刻鸭的动作停在量化导出当天,原版社区持续发布的新动作无法在复刻机上复现 | 想要新动作就按官方训练流程重训、重新导出并重新验证 |
| 版本对齐 | 社区集成仓库明确标注官方策略取自不可变策略集的 SHA-256 校验产物,随附仿真资产仍是历史基线 | 记录策略集版本与校验值,别把不同版本策略与仿真资产混用 |
| 仿真到真机落差 | 打印误差、脚底摩擦、电池电压、装配重量都会改变结果;仿真能走不等于真机可立即上力 | 按第 7 步分级上机,保留随时卸力的手段 |
| 许可证边界 | 训练仓代码 Apache-2.0,但 3D 网格文件为 CC BY-NC-SA 4.0;社区模型还有各自的许可口径 | 再分发或商用前逐仓核对许可证与 NOTICE |
上机前的验证清单
| 检查项 | 通过标志 | 用到的工具或命令 |
|---|---|---|
| ONNX 来源 | 由官方导出脚本产出,不是手转 checkpoint | scripts/export.py |
| 图契约 | 61 进 14 出,无 NaN 与常量输出 | publish 的校验或等价自检 |
| CPU 复演 | 仿真里能驱动,数值与训练侧量级一致 | scripts/infer_policy.py --walking |
| 状态对齐 | 实物与仿真一帧逐项量级、符号、单位一致 | 状态打印与 make imu 一类姿态工具 |
| 推理时延 | 单次推理耗时明显小于控制周期 | 板载计时日志 |
| 安全兜底 | 随时可卸力,测试面平整且无跌落风险 | Inference only、Torque off、安全绳 |
边界与下一步
本页的官方命令与契约来自官方训练仓和产品页,量化耗时、「2K」「0.8 毫秒」等数字来自社区报道与玩家自述,只作背景与方法参考,本站未做真机实测,也不承诺任何模型体积、推理耗时或控制频率。想系统走训练到发布,继续看《Microduck 强化学习训练与真机部署》;想只换现成策略,看《Microduck 玩法扩展与社区资源》;换模型后行为异常,按《Microduck 常见问题与故障排查》的「策略异常」反查,并把旧 ONNX 留一份在目录外做对照。