假设有人已经有「拿起杯子放下杯子」的数据并训好了模型。 要把它用到我们的机器上,具体怎么做、要检查什么、 什么才算微调成功,以及拿到结果之后往哪走。
lerobot/smolvla_base。
三项里有一项对不上,就不能拿他的权重当起点,只能借他的配方(超参数、集数、时长)。
| 项 | 我们的值 | 怎么查对方的 | 不一致会怎样 |
|---|---|---|---|
| 动作维度 | 17 维(双臂 12 + 头 2 + 底盘 3) | 他的 meta/info.json 里 features.action.shape |
致命 —— 动作头的输出层形状都不一样,权重装不进去 |
| 相机路数 | 3 路(左腕/右腕/头部) | 同一个文件里 observation.images.* 有几个 |
致命 —— 视觉输入数量变了,模型直接不可用 |
| 机器人型号 | XLeRobot(SO-101 双臂 + LeKiwi 底盘) | info.json 的 robot_type |
同型号最好;不同型号即使维度凑巧一样,关节零点也不同 |
| 帧率 | 30 fps | fps | 可容忍,但动作分块的时间尺度会偏 |
# 查对方数据集的这三项(不用下载整个数据集)
python - <<'PY'
from huggingface_hub import hf_hub_download
import json
f = hf_hub_download("对方的/数据集名", "meta/info.json", repo_type="dataset")
j = json.load(open(f))
print("robot_type :", j.get("robot_type"), " fps:", j.get("fps"))
print("action dim :", j["features"]["action"]["shape"])
for k, v in j["features"].items():
if "image" in k: print(" camera :", k, v["shape"])
PY
用他的 checkpoint 当起点,在我们自己的数据上微调。
--policy.path 从 lerobot/smolvla_base 换成他的仓库名即可,其余不动。
好处:他的模型已经见过「杯子」「抓」「放」这些概念在同一种机器人上的样子, 起点比通用底座近得多,理论上更少的数据就能收敛。
只借配方,不借权重。把他的超参数、每集时长、集数、
指令写法原样抄过来当起点,数据还是自己的,起点仍是 lerobot/smolvla_base。
这条路收益也很实在 —— 调参的边际收益远低于把数据录干净, 而抄一个已经跑通的配方能省掉整轮试错。
跑上面那段脚本。三项全对才走 A 路。结果记下来 —— 后面出问题时这是第一个要回头看的地方。
微调用的是我们的数据,不是他的。不要用 U 盘或网盘拷 —— 容易漏文件、版本对不上。
在推之前先过一遍面板的「训练交接自检」: 数据集、基座模型、训练配置、语言指令、相机路数五样齐了没有。
autodl.com 开一台 RTX 4090。
本机跑不了 —— 官方配方是 batch_size=64,Jetson 只装得下 batch=2,
换算下来要一百多小时。
lerobot-train \
--policy.path=<A路:对方仓库名 / B路:lerobot/smolvla_base> \
--dataset.repo_id=Suyang99/<我们的数据集> \
--batch_size=64 \ # ★ 官方推荐值 ★ 我们之前用的是 2
--steps=20000 \
--dataset.eval_split=0 \ # ★ 部署用的模型要吃全部数据 ★
--policy.device=cuda \
--output_dir=outputs/train/ft --job_name=ft
推回 Hub 再拉下来。然后点面板「训练交接自检」的「② 训练回来后」—— 它会核对 checkpoint 的相机路数和数据集对不对得上,并读训练日志。
「实机试跑」卡 →「空跑 1 次」(手臂不动,验观测/推理/安全层)→ 没问题再实跑。 手放急停上。
| # | 判据 | 怎么量 | 及格线(建议) |
|---|---|---|---|
| 1 | 训练过的杯位成功率 | 杯子放在数据最多的位置,跑 10 次 | ≥ 7/10。达不到说明连「见过的情况」都没学会,别谈泛化 |
| 2 | 没训过的杯位成功率 | 放在数据最少或完全没录过的位置,跑 10 次 | ≥ 4/10。这一条才是「学到技能」而不是「背下轨迹」的证据 |
| 3 | 比基线好多少 | 同样的数据、同样的步数,从 smolvla_base 再训一次做对照 |
A 路的价值全在这里:如果不比基线好,那就没必要用他的权重 |
| 4 | 样本效率 | 用一半数据训,看成功率掉多少 | 掉得少 = 起点真的更好。这是 A 路最有说服力的证据 |
| 结果 | 说明什么 | 下一步 |
|---|---|---|
| 训练位 ≥7、没训位 ≥4 | 成了 | 固化这套配置,往下做「抓起→平移→放下」 |
| 训练位高、没训位低 | 在背轨迹,没学到技能 | 补数据的多样性:更多杯位、打乱顺序录。不是加步数 |
| 两个都低,但比基线好 | 起点确实更好,只是数据还不够 | 补数据到单臂 80–100 集,再训一轮 |
| 两个都低,且不比基线好 | 他的权重没帮上忙 | 放弃 A 路,回 smolvla_base,把精力全放在数据质量上 |
| 某个杯位系统性失败 | 覆盖失衡(我们正在踩这个坑) | 面板「数据可用性」→「覆盖体检」,补最薄弱的那个位置 |
| 动作幅度整体偏移 | 标定或几何变了,不是策略问题 | 做重放对照实验:--replay-episode 0,不加载模型直接重放录制动作。
重放也失败 = 硬件;重放成功 = 策略 |
| 项 | 官方推荐 | 我们 | |
|---|---|---|---|
| 基座 | lerobot/smolvla_base | 同 | ✅ |
| batch_size | 64 | 2 | ❌ 小 32 倍。20000 步只过了 2.06 遍数据,官方配方是 66 遍 |
| steps | 20000 | 20000 | ✅ 但步数离开 batch 没有意义 |
| eval_split | — | 0.2(按集号顺序切) | ❌ 切走的正好是右侧整块工作空间,最右杯位只剩 2 集进训练 |
| 训练时长 | 单张 A100 约 4 小时 | Jetson 5.5 小时(batch=2) | ❌ 换算到 batch=64 约需 176 小时 —— 租卡不是优化,是必要条件 |