650 万参数的机械臂模型,代码是 Claude 写的:我在这台 Windows 笔记本上复现了它

做机器人、或者说做具身智能的这两年,最难受的不是模型跑不通,是跑通了也不知道它到底学没学到东西。

官方演示里机械臂稳稳抓起积木,论文里成功率写着 94%,然后你发现那个场景是作者自己挑的,指令是作者自己写的那句,连相机角度都只有一个。你想自己验一遍,代码在 GitHub 上,权重在 Hugging Face 上------然后卡在第一步:这东西到底怎么跑?

这篇不讲原理。我把这个项目的官方成绩在本机复现了一遍,顺手算了几个官方没写的数。

一、这是什么东西

AMP Tadpole ,一家叫 Adaptive Machine Patterns 的英国小公司做的,650 万参数的视觉-语言-动作(VLA)模型:机械臂有 6 个关节,看三路固定相机(顶视 / 侧视 / 等轴),听一句「把那个青柠色的星星捡起来」这样的指令,然后去抓。

它配套了一个基准叫 AMP Toy Robotics Benchmark,还有一套能在浏览器里直接跑的演示。

最让我停了一下的是作者自己写的一段话------他说这个项目的数据集生成器,最开始是手写的,「看看我还能不能算三维三角函数(不能)」,后来交给本地跑的 Qwen3.8 27B,最后用 Claude Opus 5.5 收尾。模型卡的 Credits 里还多了一个 OpenAI ChatGPT。

也就是说:这个模型的代码,本身就是 AI 写的。

我看到这句的时候第一反应是「那它的成绩可信吗」。所以才有这篇。

二、官方到底给了几个数(先把原始数据摊开)

这是这篇最需要先讲清楚的,因为官方在不同地方给了三个不同的成功率,直接看很容易懵:

口径 数值 出处
作者原帖口述 「约 95%」 Open Robotics Discourse 原帖(抓取与搬运,不含未见场景)
模型卡标准测试 93.7%(898 条指令) HF 模型卡,基准 v0.2.0
基准升到 v0.3.0 后,同一组权重 94.2% GitHub README
200 个从未参与选模的场景 93.1%(608 条) HF 模型卡

teacher 基线(脚本控制器,天花板)也有同样的版本差:99.4%(v0.2.0)/ 100.0%(v0.3.0)。

这三个数不矛盾,是基准版本变了:模型卡跑的是 0.2.0 基准,README 跑的是 0.3.0 基准,同一组权重在不同基准上量出来就是不一样。后面我会说我们本机跑出来是 94.0%,正好卡在 93.7% 和 94.2% 中间------那不是巧合,那是我们在 0.3.0 基准上跑的。

三、我们怎么在本机跑的

先说环境,因为这里有个意外的好消息:

  • Windows / Python 3.12.4 / torch 2.14.1+cpu
  • 用 python -m venv --system-site-packages .venv 建独立环境,依赖零下载------numpy、pillow、torch、safetensors 全局已有
  • 仓库 115 KB,模型包 51.9 MB(权重 26.0 + onnx 28.2 + 词表 149 KB)
  • 装完只多了一个 amp-toy-robotics 包,pip uninstall 就能完全清除

更关键的一点:这个基准不需要下载任何数据集。 训练场景是拿整数种子现场生成的,所以同一个种子在任何机器上生成的场景、物体、指令逐位相同。这意味着复现这件事不需要「申请数据权限」「等作者上传」,也不存在「我拿到的数据和作者不是同一份」这种扯皮。

teacher 基线 300 个场景,我们本机从 22:16 跑到 22:45,29 分钟(官方说约 40 分钟,CPU 上跑)。

四、三组数字

第一组,teacher 基线 100.0% ,和官方 0.3.0 基准的那个数对得上。这条本身不稀奇,但它证明我们的评测环境跟官方是对齐的------不然后面所有数字都没意义。

第二组,Tadpole 完整评测 94.0%(898 条指令)。

子任务 pick move midpoint open close home 全部
成功率 94% 94% 76% 100% 100% 100% 94.0%

对比官方模型卡(0.2.0 基准):93% / 94% / 75% / 100% / 100% / 100% / 93.7%。

我们的 94.0% 落在官方两个口径(93.7% / 94.2%)之间,而且落在 0.3.0 基准那一侧------这就把「95% 是怎么来的」这个疑问关掉了:那个 95% 是口述的近似值,标准测试口径是 93.7%,换了新基准是 94.2%,没有哪个是编的。

第三组,也是我最看重的一组:5 项 grounding test,逐位相同。

这五项是作者专门设计的防作弊测试。因为大型 VLA 经常根本不看你给的画面、不看你给的指令,就靠猜。

测试 改了什么 官方 我们
named object 不变,看它是否奔向被点名的物体 0.98 0.98
other objects 同上,但看它是否奔向没被点名的物体 0.31 0.31
image swap 两个物体互换位置,只有像素变 1.00 1.00
instruction swap 换指令,只有词变 1.00 1.00
blank instruction 指令留空 0.95 0.95

这五个数怎么读 :image swap = 1.00 说明它真的在看像素(位置变了它的行为就跟着变);blank instruction = 0.95 说明空指令会让它停手而不是瞎动;other objects = 0.31 说明它对「没被点名的物体」有明显的抑制倾向,不是无差别乱抓。

这五项逐位一模一样,意味着我们的评测环境和官方用的是同一套------不是「跑了个寂寞」,也不是「环境太糙导致分数虚高」。

另外两个辅助指标也对上了:步数比 teacher 1.12× (官方 1.13×),路径比直线 1.96×(官方 1.96×,逐位相同)。

五、我们自己算出了官方没写的那部分

README 里有一句话:

The word table was cut to the 32 tokens the instructions use. This changes no output, and takes the model from 19.2M to 6.5M parameters.

「19.2M → 6.5M」这个说法我没找到对应的脚本,于是自己把权重逐项统计了一遍:

模块 参数量 占比
transformer 主体(6 层 / 宽 256 / 8 头) 4,738,560 72.8%
共享卷积(三路相机共用) 1,669,440 25.7%
位置 / 视角 / query 参量 76,544 1.2%
词嵌入 + 词位置嵌入 20,480 0.3%
动作输出头 2,311 0.0%
合计 6,507,335 100%

统计本身没什么难的,难的是把「19.2M」这个数的来历还原出来:

python 复制代码
weights = load_file(str(PKG / "weights.safetensors"))
total = sum(v.numel() for v in weights.values())

groups = {}
for k, v in sorted(weights.items()):
    g = ("cnn" if k.startswith("cnn") else
         "word" if k.startswith("word") else
         "fuse" if k.startswith("fuse") else
         "head" if k.startswith("head") else "other")
    groups[g] = groups.get(g, 0) + v.numel()

# 词表裁剪的账:SmolVLM2 分词器 49152 → 指令实际用到的 32
used_vocab = len(json.loads((PKG / "instructions.json").read_text())["vocab"])
old_emb, new_emb = 49_152 * 256, used_vocab * 256
saved = old_emb - new_emb
untrimmed = total - new_emb + old_emb      # 反推未裁剪的体量
  • 原词表 = SmolVLM2-500M-Video-Instruct 分词器的 49,152 个 token(tokenizer_config.json 里 vocab_size: 49152)
  • 裁剪后只保留指令真正用到的 32 个(规范指令共 1,644 条)
  • 词嵌入:49,152×256 = 12,582,912 → 32×256 = 8,192 ,省下 12,574,720
  • 未裁剪总参数 = 6,507,335 − 8,192 + 12,582,912 = 19,082,055 = 19.08M

判定:6.5M 这个数和实测对得上(实测 6,507,335 = 6.51M);官方说的 19.2M,实际是 19.08M,是往大了取整的说法。

但真正让我停下来的是这件事的反面:

这次「瘦身」省下的 1,257 万参数,全部来自词表 ------占原模型的 65.9%。可裁完之后,词嵌入总共只剩 2 万参数,占整个模型的 0.3%,可以忽略不计。

也就是说,决定这个模型体量的是 transformer 主体和 CNN,跟词表一点关系都没有了。 「小模型」这件事在词嵌入这个维度上已经做完了,剩下的空间在视觉编码和主干网络------这跟大多数人的直觉是反的。

顺带把它的结构常量也读出来了,这几个数字解释了「650 万参数」到底是怎么用的:

ini 复制代码
GRID = 16            # 每路相机 16×16 = 256 个 token
CHUNK = 8            # 一次输出 8 步动作
STATE_DIM = 7        # 6 个关节角 + 夹爪开合
TOKEN_LEN = 48       # 指令槽位
STATE_FEATURES = 31  # 状态经 sin/cos 展开

token 总数 = 3×16×16(图像)+ 48(指令)+ 1(状态)+ 8(动作)= 825。

一次前向,825 个 token 进去,8 步动作出来,没有采样、没有自回归。 这也是为什么它能在纯 CPU 上 29 分钟跑完 300 个场景------每步的成本比扩散策略或者自回归 VLA 便宜得多。模型小不是侥幸,是结构上就这么设计的。

六、浏览器里跑的那个,跟本地跑的是同一个模型吗

官方演示是个 Hugging Face Space,浏览器里用 Pyodide 跑 Python,不用装环境、不用 GPU、不用 API key,第一次访问会下载约 61 MB。

那它跑的是 ONNX 导出版,跟我们本地跑的 PyTorch 版,是同一个模型吗?我用同一个观测(场景 9000007,指令「Pick up the lime star」)走了两条推理路径对比:

指标 值
最大绝对差 2.384e-07
余弦相似度 1.000000000

浮点误差在 1e-7 量级------是同一个模型。

然后我又自己写了个驱动脚本,把官方导出的 amp-tadpole.onnx 当后端,接进基准的闭环里自己驱动机械臂:

项 值
指令 Pick up the lime star
总步数 34
ONNX 调用次数 5 次(每次输出 8 步动作),总共 1.5 秒
单次推理 平均 299 ms(含三路 512×512 图像渲染)
是否抓住 是,抓住了 lime star
是否触步数上限 否

注:抓取判定由 benchmark 的物理逻辑给出(指尖与物体距离 ≤ 容差且在闭合瞬间),不是我目测。

这条是我最想给读者看的东西 :不是「模型声称能抓」,是我把它的浏览器后端拆下来自己接进闭环,它真的把那个青柠色的星星抓起来了。

七、浏览器里到底能干什么

顺手把那个 Space 逐个点了一遍,功能比想象中多:

  • 四个视角(Free 3D / Top / Side / Iso),可拖拽旋转
  • 点选式指令输入 :积木式拼装,INSTRUCTIONS(pick up / move to / open the gripper / close the gripper / return home)+ OBJECTS(lime square / coral triangle / teal star...)+ 连接词
  • 语音输入(Listen)和朗读(Read)
  • Model Viewer :把模型的每一层画成建筑的一层------底部是相机画面,中间是主干的每一层,顶上是机械臂下一步动作,用一次真实运行点亮。这个可视化我觉得比论文里的架构图好懂
  • New scene 会随机一个模型训练时从没见过的新场景

⚠️ 有一个付费 Pro 版,官方页面明列。免费版只有 Demo 面板;加载自己的 PyTorch 模型、从 HF 拉 LeRobot 模型、两次运行并排对比、保存图片视频轨迹、在无限 benchmark 数据上训练微调,这些都在 Pro 里。

八、边界(这些必须一起说)

这个模型的能力边界,模型卡自己写得很清楚,我照搬:

  • 只认固定句式。自由文本会先被基准改写成规范句式,模型本身不处理自然语言变体
  • 只见过这一个模拟世界 :一台机械臂、三路固定相机、8 种颜色、5 种形状,没见过真实相机
  • 「midpoint」(移到两物体中点)是最弱项,75% 。原因是两物体中间是空地,画面里没有可瞄准的目标,而它只占 10% 的训练指令,训练结束时误差还在下降
  • 所有结果来自一次训练,没有换随机种子复现
  • 官方自己的免责段,我觉得该原样留着:teacher 是确定性的、无限的、相机是固定的------这就是为什么 650 万参数能在这里表现好。这不是对更大 VLA 在人类演示基准上的反面证据。

还有一条商用上必须注意的:

对象 协议 能商用吗
数据生成器 + 基准代码 Apache-2.0 ✅ 可以
AMP Tadpole 模型权重 CC BY-NC 4.0 ❌ 不行,商用要单独联系作者

文章里所有配图都是我们本机用 Apache-2.0 的基准代码渲染生成的,不是转载官方截图。渲染结果不含权重。

九、所以这说明了什么

它证明的:在「一台机械臂 + 固定相机 + 固定句式」这种高度受控的环境里,650 万参数能到 94%,而且这个 94% 经得起 5 项防作弊测试的检验(图像一换它就跟着换、指令一空它就停手)。

它没证明的:650 万参数能干活。VLA 这条路真正难的是泛化到没见过的场景、真实的相机、真实的指令分布------而这个模型恰好在训练结束时误差还在下降的那一类任务上最弱。

作者自己给了一句我觉得挺诚实的话:These numbers are a line in the sand, not a ceiling.(是给后来者立的一根线,等着被超越。)

我唯一想补的一句是 :这根线是用 AI 写的代码立起来的。一个 6.5M 参数的模型,配一套 AI 写的 1,644 条规范指令和训练场景生成器,能被独立复现到逐位一致------这件事本身可能比 94% 这个数字更有意思。

如果你也想跑一遍:代码在 GitHub 的 Adaptive-Machine-Patterns/amp-toy-robotics(Apache-2.0,开源 ),权重在 Hugging Face 的 Adaptive-Machine-Patterns/amp-tadpole(CC BY-NC,不可商用 ),浏览器演示是 Adaptive-Machine-Patterns/amp-embodied-ai-workbench-demo。不需要申请数据权限,不需要 GPU,一个整数种子就能开始。

资料检索与信息核对由 AI 辅助完成,判断与取舍由我负责。

相关推荐
蒲公英内测分发2 小时前
智能家居厂商有多个产品线,包装上的 App 下载入口该共用还是分开?
android·人工智能·数码相机·机器人·智能家居·智能硬件
爱研究的小梁2 小时前
从无人车配送走向集群联动作业,通信如何扛住协同压力?
网络·网络协议·机器人·信息与通信
QY_Research_3 小时前
全球钥匙联锁系统 市场规模及CAGR5.2%深度分析
大数据·人工智能·物联网·安全·机器人
阿尔法工场研究院3 小时前
物理AI的GPT时刻快到了?
人工智能·机器人
视睿4 小时前
人形机器人2026年现状
机器人
GlobalInfo4 小时前
全球防爆轮式巡检机器人行业研究:安全生产需求、产品升级与智能运维趋势
人工智能·安全·机器人
Rock Chin6974 小时前
LangBot 群机器人:三个 AI 角色分工迎新人、答群规、管广告
人工智能·机器人·开源·自动化
Light Gao12 小时前
LeRobot 全链路原理:用一个“1+1=2“的例子讲透机械臂与模型如何接入
机器人·具身智能·vla·模仿学习·lerobot
GlobalInfo17 小时前
全球及中国风电叶片检测机器人行业研究报告(2026版):市场现状、行业前景与占有率分析
运维·网络·人工智能·机器人