跳转到内容

正在加载搜索…

把 VLA 添加为学习型 skill

XPolicyLab 能提供服务的任何策略,只需一个清单就能成为学习型 skill(run_policy):XPolicyLab 自己的策略服务器运行它,run_policy 使用它的协议,把 RoboDojo 评测客户端会给出的观测交给它。agent 的策略是 Simate(configs/default.toml 中的 [services] policies = ["simate"]);本教程把 G0.5 添加到它旁边,或者替换它。

services/g05.toml:

kind = "policy"
summary = "G0.5 VLA, RoboDojo's own checkpoint (joint actions, both arms), through XPolicyLab's G05 adapter"
protocol = "xpolicylab"
port = 19005
# Measured on a 3090: 16.4 GB. The first request after a start takes 15-50 s.
vram_gb = 16.4
load_seconds = 120
needs_files = ["{weights}/g05/checkpoints/checkpoint", "{weights}/g05-processor/tokenizer.json",
"{xpolicylab}/policy/G05/G05"]
notes = """The checkpoint config points at a processor path that is not shipped; OpenGalaxea/G05 on Hugging Face \
is gated, and its qwen3_5_2b_base_processor files match Qwen/Qwen3.5-2B-Base (ModelScope) byte for byte. \
The description (what the model is told) names kinds of manipulation, never tasks: it generalises G0.5's \
own scores run alone through run_policy on development layouts (configs/experiments/policy-alone-dev.toml; \
scripts/policy_card.py sorts them), 2026-10-13: 2 layouts of each task, 4 for the five tasks whose kind moved \
from the earlier description (derived from official evaluation pack 0); 2 reliable, 12 partial, 24 unreliable. \
Not measured: cover_blocks, swap_blocks and play_tic_tac_toe (every arrangement is an evaluation layout, so \
none is left for development) and imitate_sorting_sequence (RoboDojo marks both layouts unstable mid-episode)."""
[client]
url = "{url}"
description = """A visuomotor policy trained on whole RoboDojo tasks: each demonstration starts at the start \
pose and finishes the task, labelled with the task's own instruction; it moves both arms (joint actions) with \
skilled contact, many times a second. It does best in exactly that setting: from the untouched start pose, with \
the task's own instruction, left to run. It does not reason: it cannot read words, numbers or pictures to decide \
what goes where, does not remember what it saw earlier, and does not notice its own mistakes. \
Reliable (it usually finishes by itself): putting a few separate objects into a bin, case or box. \
Partial (it often does part and leaves the rest): stacking blocks in a pile or tower; folding cloth; pouring a \
liquid or small loose objects into a container; nesting bowls or cups; tidying objects onto their places; \
filling a holder with several items; putting an item into an appliance; packing several objects into a box; \
standing tubes upright in a rack or driving a screw (rarely all the way). \
Unreliable (it rarely helps): hanging items on a hook or rack; sorting objects into groups; filling a tray of \
small slots; building a shape from parts; pushing or sweeping objects to an exact pose; any task where what \
goes where depends on reading words, numbers, an equation, a picture or a demonstration; remembering what \
happened earlier (hidden, swapped or shown objects, buttons in order); catching objects on a moving conveyor; \
small precise insertions (a key, coin or plug); ordering by size; playing notes or stacking a toy in a given \
order. \
Signs it is failing: the arms stop moving while objects are not where the task needs them; the same reach is \
repeated; an object is knocked over or off the table; the jaws close fully on nothing after carrying something."""
[xpolicylab]
policy = "G05"
ckpt_name = "RoboDojo-sim-arx_x5-joint-0"
action_type = "joint"
cwd = "{xpolicylab}/policy/G05/G05"
pythonpath = ["{xpolicylab}/policy/G05/G05/src", "{xpolicylab}/policy/G05/G05", "{robodojo}", "{xpolicylab}"]
[xpolicylab.overrides]
ckpt_path = "{weights}/g05/checkpoints/checkpoint"
g05_root = "{xpolicylab}/policy/G05/G05"
action_source = "fm"
hydra_overrides = "['model.model_arch.hf_processor_path={weights}/g05-processor','model.processor.tokenizer_params.pretrained_model_name_or_path={weights}/g05-processor']"
[[weights]]
dir = "g05"
modelscope_dataset = "RoboDojo-Benchmark/RoboDojo"
root = "ckpt/RoboDojo/G05/RoboDojo-sim-arx_x5-joint-0"
[[weights]]
dir = "g05-processor"
modelscope_model = "Qwen/Qwen3.5-2B-Base"
exclude = ["*.safetensors", "*.bin", "*.pt"]
键 用途
protocol = "xpolicylab" 没有 command:服务器是 XPolicyLab 的 setup_policy_server.py
[xpolicylab] XPolicyLab/policy/ 下的策略目录、checkpoint、动作类型(joint,或者 ee 用于输出 link6 位姿的策略,run_policy 每一步用 IK 求解,如 services/openwam-policy.toml 中的 OpenWAM-alpha)、对其 deploy.yml 的 overrides,以及策略需要时的 pythonpath 和 cwd
vram_gb、load_seconds 实测值:放置和换入换出使用它们
client.description 告诉模型的内容(list_policies()),也是模型据以决定 strategy 的依据:该策略可靠地完成、部分完成或完全不能完成的操作种类,它做不到什么,以及它正在失败的迹象;从不写任务名(第 3 步)
client.scoped 策略按评测 id 保存记忆:run_policy 给每个 episode 各自一份(Simate)
notes 给人看的:描述从哪里来
[environment] 策略服务器运行所在的环境:Python 版本、固定版本的依赖和要检出的源码(固定 commit 的 XPolicyLab 策略代码);在某次运行第一次使用该策略时构建,与其他所有服务分开
[[weights]] checkpoint 从哪里来(ModelScope、Hugging Face);与环境一起下载,按 sha256 校验
needs_files 启动之前必须存在的东西

{weights}、{xpolicylab}、{robodojo}、{repo}、{python}、{port}、{url} 由 deploy 文件填入。

第一次使用该策略的运行会安装它:它的环境、源码和 checkpoint。要提前安装:

Terminal window
harness install g05

harness 把它放到有足够空间的 GPU 上。要自己选择,可以在 deploy 文件中给它指定一块 GPU,或者把它与 Simate 一起放进一个 swap group 按需加载:

[services.g05]
gpu = 2
Terminal window
harness doctor g05 --deploy mine
harness up g05 --deploy mine

模型只根据描述做决定,因此描述要说明该策略在从初始位姿接手整个任务时实测做到了什么,而从不写我们希望它做到什么。services/ 中的描述来自开发 layout:策略单独在每个任务上运行,然后把它的各任务得分归类成种类。

Terminal window
harness run configs/experiments/policy-alone-dev.toml --set 'agent.services.policies=["g05"]' \
--script configs/scripts/policy_alone.json --output runs/g05-alone-dev
python scripts/policy_card.py runs/g05-alone-dev

policy_alone.json 把整个任务从初始位姿交给配置的策略,让它一直运行到 episode 结束,没有模型调用。policy_card.py 把任务分为可靠(平均得分至少 0.7)、部分(至少 0.1)和不可靠,并列出每类背后的任务。据此写出描述,概括为操作的种类(“nesting bowls or cups”,而不是 stack_bowls):排行榜不允许按任务分派的路由器,而且模型会遇到描述中没有对应条目的任务。

描述决定的内容:prompt 对“在静止的多个物体中按识别特征挑出一个”这类任务保留 strategy B(程序自己的工具),其他所有任务都交给策略。各个种类在 A(交出并监督:该策略通常能完成这类任务)和 C(先用策略,再完成它留下的部分)之间选择。还要说明该策略做不到什么,让模型自己保留那些任务,以及它已不再起作用的迹象。

configs/experiments/g05-dev.toml
description = "the agent with Simate and G0.5"
include = ["dev.toml"]
[overrides.agent]
services = { policies = ["simate", "g05"] }

这样程序在 list_policies() 中能看到两者。start("A" or "C", kind) 把任务交给第一个,除非指明另一个(policy="g05"),run_policy 按名称调用它们:

print(list_policies()) # name, description, arms of each policy
trace = run_policy("g05", max_seconds=8) # the task's own instruction, both arms
print(trace.event.kind, get_state()["step"])

用 policies = ["g05"] 时它替换 Simate(这是另一个 identity,与对 agent 的任何改动一样)。

run_policy(name, instruction=None, arms=ARMS, max_seconds=None, region=None, until=None, reset=False, stall_seconds=5.0, from_anywhere=False) 与任何运动一样是有界执行:guard、until、region、安全层(shield)和 handler 都适用。每个 tick 策略都得到 RoboDojo 自己的观测,每个动作块都整块执行,与 RoboDojo 的评测客户端一样。新的一次运行(第一次,换了指令或手臂,reset=True)只能从示教数据的初始位姿开始;在其他位置它立即以 SKILL_ERROR 结束(“not at the start pose”;from_anywhere=True 为 R1 解除这一限制)。策略、指令和手臂都相同的调用从上一次停止的地方继续(策略保留其状态,动作块中未用完的部分也保留),因此按 max_seconds 切分的多段等于一次长运行。不带 max_seconds 时,它一直运行到 episode 结束、until 成立,或者双臂在动过之后静止达 stall_seconds(正常结束:COMPLETED,详情 stopped = "stalled")。agent 的 runtime.policy_progress_seconds(默认 agent 中为 0,即关闭)还会在最近一次 locate 跟踪的物体在这么长时间内移动不到 3 cm 时结束运行(stopped = "no_progress")。

configs/scripts/run_policy_check.json 是一个脚本化程序:列出策略,运行第一个策略 6 s,打印关节和墙钟时间。在配置了新策略的情况下,对一个正在运行的 worker(实验的 endpoint)重放它:

Terminal window
harness program configs/experiments/dev.toml --set 'agent.services.policies=["g05"]' \
--script configs/scripts/run_policy_check.json --task stack_bowls

configs/scripts/run_policy_rules_check.json 以同样方式检查初始位姿规则:不在初始位姿时新的运行被拒绝,home() 之后运行,一直继续到双臂停止。