YAML Metadata Warning:empty or missing yaml metadata in repo card

Check out the documentation for more information.

G1_23 Dex1 取瓶 / 放瓶模型发布包(2026-09-26)

Unitree G1_23(5 自由度手臂)+ Dex1 夹爪真机数据上训练的三个模型,每个带最新两个 checkpoint、推理所需的全部配置,以及从 GitHub 仓库开始推理所需的代码补丁。

模型 任务 checkpoint 训练数据
openpi π0.5 place:把瓶子放到红色 X 处 16000、19999(最终) place-at-red-x-g1-23:99 episode / 22,091 帧
ImageWAM (FLUX.2-klein-4B) pick:拿起最左边的瓶子 step_009000、step_010000(最终) pick-leftmost-g1-23:181 episode / 50,699 帧
ImageWAM (FLUX.2-klein-4B) place:把瓶子放到红色 X 处 step_005000、step_006000(最终) place-at-red-x-g1-23:99 episode / 22,091 帧

openpi 的 pick 模型仍在训练中,不在本包内。

1. 目录结构

g1_23_release_20260926/
├── README.md
├── SHA256SUMS                               所有文件的校验和(sha256sum -c SHA256SUMS)
├── patches/
│   ├── openpi-fintune_g1_23.patch           打在 leihao100/openpi-fintune 上
│   └── imagewam_g1_23.patch                 打在 yuyangalin/ImageWAM 上
├── openpi/pi05_g1_23_place_red_x/
│   ├── 16000/  {params/, assets/, _CHECKPOINT_METADATA}
│   └── 19999/  {params/, assets/, _CHECKPOINT_METADATA}
└── imagewam/
    ├── configs/                             训练/推理用的 hydra 配置(补丁里也有,这里单独放一份方便查看)
    │   ├── data/g1_23_dex1_joint.yaml
    │   └── task/g1_23_{pick_leftmost,place_red_x}_flux2_klein_4b.yaml
    ├── g1_23_pick_leftmost_flux2_klein_4b/
    │   ├── step_009000.pt  step_010000.pt   完整权重(LoRA 已合并),各 17 GB
    │   ├── dataset_stats.json               该 run 的归一化统计,推理必须用这份
    │   ├── config.yaml                      该 run 的完整训练配置(存档)
    │   └── g1_23_pick_leftmost_prompt_embeds.npz   3 条指令的 Qwen3 文本嵌入
    └── g1_23_place_red_x_flux2_klein_4b/
        └── (同上:step_005000.pt、step_006000.pt、dataset_stats.json、config.yaml、*_prompt_embeds.npz)

openpi checkpoint 只包含推理需要的 params 和 assets(归一化统计在 assets/place-at-red-x-g1-23/norm_stats.json)。用于续训的 train_state(优化器状态,每个 13 GB)没有复制,原件在 nnmc65:/shared/user64/workspace/yuhao/pi/openpi-fintune/checkpoints/pi05_g1_23_place_red_x/v1/。

2. 模型接口(三个模型相同)

状态 / 动作:12 维关节空间。手臂单位是弧度,夹爪是 Dex1 原始读数(约 5.35 为张开,约 2.8–4.3 为夹住):

维度 含义
0–4 左臂 ShoulderPitch, ShoulderRoll, ShoulderYaw, Elbow, WristRoll
5–9 右臂(顺序同上)
10 左夹爪
11 右夹爪

两个任务都只用左臂,右臂和右夹爪基本不动。输出的动作是绝对关节位置,不是增量。

相机:3 路 RGB,训练分辨率 480×640,30 fps。

位置 数据集里的 key
头部 observation.images.cam_left_high
左腕 observation.images.cam_left_wrist
右腕 observation.images.cam_right_wrist

指令:必须与训练时逐字一致。

  • pick:Pick up the leftmost {cola / hand soap / water} bottle in the designated target area.
  • place:Pick up the {cola / hand soap / water} bottle and place it at the red X-marked target position.

每次推理的输出:

  • openpi:(32, 12) 的动作块,对应 32 步 × 1/30 s。
  • ImageWAM:(16, 12) 的动作块,对应 16 步。

3. openpi 推理

3.1 准备代码

补丁基于 feat/b601-pick-red-cube 分支的 084dc0f,端到端验证也在这个版本上做的。补丁也能直接打在 main 上,但那种组合没有做过推理验证。

git clone https://github.com/leihao100/openpi-fintune.git
cd openpi-fintune
git checkout 084dc0f          # 即 origin/feat/b601-pick-red-cube
git apply <本包>/patches/openpi-fintune_g1_23.patch
GIT_LFS_SKIP_SMUDGE=1 uv sync

补丁改动了以下内容:

  • src/openpi/policies/unitree_policy.py:UnitreeG1Outputs 新增 action_dim 参数,默认 16,G1_23 用 12。
  • src/openpi/training/config.py:
    • LeRobotUnitreeG1DataConfig 新增 action_dim;
    • 新增 pi05_g1_23_pick_leftmost 和 pi05_g1_23_place_red_x 两个 TrainConfig。
  • src/openpi/transforms.py(及其测试):Normalize 会把归一化后的值裁剪到 ±10。训练时开着这个裁剪,所以推理也必须带上,否则右夹爪这类几乎不动的维度,读数稍有偏差就会被放大成极大的输入。
  • scripts/convert_g1_23_v30_to_v21.py:把 G1_23 采集下来的 LeRobot v3.0 数据转换成 v2.1。重新训练时才用得到,推理不需要。
  • scripts/infer_g1_23_offline.py:离线推理检查脚本(见 3.3)。

3.2 起推理服务

uv run scripts/serve_policy.py policy:checkpoint \
  --policy.config=pi05_g1_23_place_red_x \
  --policy.dir=<本包>/openpi/pi05_g1_23_place_red_x/19999

单张 GPU 即可(验证时用的是一张 L40S 46 GB)。归一化统计会从 checkpoint 的 assets/ 自动读取。

客户端(openpi_client 的 WebSocket 协议)每次发送以下字段:

{
  "observation/image":             head_rgb,        # uint8 HxWx3,头部相机
  "observation/left_wrist_image":  left_wrist_rgb,  # uint8 HxWx3
  "observation/right_wrist_image": right_wrist_rgb, # uint8 HxWx3
  "observation/state":             state_12,        # float32 (12,),顺序见第 2 节
  "prompt":                        "Pick up the cola bottle and place it at the red X-marked target position.",
}

返回 {"actions": (32, 12)},即原始单位的绝对关节目标。

3.3 离线检查(可选,不需要接机器人)

uv run scripts/infer_g1_23_offline.py pi05_g1_23_place_red_x \
  <本包>/openpi/pi05_g1_23_place_red_x/19999 <place-at-red-x-g1-23 数据集目录>

脚本会从数据集取 5 帧真实观测做推理,并打印预测动作与数据集动作的误差。

4. ImageWAM 推理

4.1 准备代码

补丁基于官方 main,在 5d4a341 上验证通过;它同样能打在 70bc471 上。

git clone https://github.com/yuyangalin/ImageWAM.git
cd ImageWAM
git apply <本包>/patches/imagewam_g1_23.patch

# FLUX.2 官方源码(被 .gitignore 忽略,需要单独 clone,钉在这个提交)
git clone https://github.com/black-forest-labs/flux2 third_party/flux2
git -C third_party/flux2 checkout 50fe5162777813d869182b139e83b10743caef15

# 机器人侧客户端:服务端要从这里导入 msgpack 协议编解码
git clone https://github.com/leihao100/g1-client.git ../g1-client

补丁共 49 个文件,是官方仓库之外的全部 G1 工作:

  • G1 的数据处理、夹爪关键帧 loss 加权、推理加速模块(src/imagewam/...);
  • scripts/g1/ 下的服务端、控制面板、基准脚本;
  • 本次新增的内容:
    • ConcatScatter:把 12 维映射到 RoboTwin 基座的 14 维槽位。左臂 → 0–4,右臂 → 7–11,左夹爪 → 6,右夹爪 → 13,槽位 5 和 12 为填充。
    • G1_23 的 data / task 配置。
    • scripts/g1/infer_g1_23.py:离线推理脚本。
    • scripts/g1/run_train_g1_23.sh:训练脚本。
    • 对 serve_imagewam_g1.py 的修复:原来写死了 16 维,而且推理时没有走 merger。修复后按 shape_meta 取维度,并与训练保持一致(先归一化再 merger,输出反向)。已对照验证:原有 16 维 G1_29 任务的预测结果在修改前后完全一致。

4.2 环境

照 ImageWAM 仓库的安装方式来。以下是 nnmc64/65 上实际能用的组合:

uv venv --python 3.11 .venv
uv pip install --python .venv/bin/python torch==2.7.1 torchvision==0.22.1 torchcodec==0.5 \
  --index-url https://download.pytorch.org/whl/cu128
uv pip install --python .venv/bin/python -e ".[shared]"
uv pip install --python .venv/bin/python transformers==4.56.1 gradio==5.50.0 websockets==15.0.1 msgpack==1.2.1
uv pip install --python .venv/bin/python nvidia-npp-cu12==12.4.1.87 peft==0.19.1

注意两点:

  • transformers 必须是 4.56.1,并且要在 .[shared] 之后装。
  • torchcodec 0.5 需要 FFmpeg 7(libavutil.so.59)。系统里没有的话,可以用 conda create -n ff7 -c conda-forge ffmpeg=7,再把它加进 LD_LIBRARY_PATH。

基座权重:推理时要用来构建模型结构。

文件 来源
flux-2-klein-base-4b.safetensors HF black-forest-labs/FLUX.2-klein-base-4B
ae.safetensors HF black-forest-labs/FLUX.2-dev,需在 HF 上接受许可

Qwen3 不需要:文本嵌入已经预先导出在 *_prompt_embeds.npz 里。

在仓库根目录建 .env.local,scripts/common.sh 会自动加载它。离线推理要手动 source:

REPO_ROOT=<ImageWAM 路径>
FLUX2_SRC=<ImageWAM 路径>/third_party/flux2
FLUX2_MODEL_PATH=<路径>/flux-2-klein-base-4b.safetensors
FLUX2_AE_MODEL_PATH=<路径>/ae.safetensors
LD_LIBRARY_PATH=<ff7 环境>/lib:<ImageWAM>/.venv/lib/python3.11/site-packages/nvidia/npp/lib${LD_LIBRARY_PATH:+:${LD_LIBRARY_PATH}}

4.3 离线推理(不需要接机器人)

cd ImageWAM && set -a && source .env.local && set +a
export PYTHONPATH=$PWD/src:$FLUX2_SRC/src:$FLUX2_SRC
cd scripts/g1
D=<本包>/imagewam/g1_23_pick_leftmost_flux2_klein_4b
CUDA_VISIBLE_DEVICES=0 ../../.venv/bin/python infer_g1_23.py \
  --task-config   g1_23_pick_leftmost_flux2_klein_4b \
  --ckpt          $D/step_010000.pt \
  --dataset-stats $D/dataset_stats.json \
  --prompt-embeds $D/g1_23_pick_leftmost_prompt_embeds.npz \
  --dataset-root  <pick-leftmost-g1-23 数据集目录> \
  --episode 0 --num-calls 5

place 模型的用法相同:把 pick_leftmost 换成 place_red_x,数据集换成 place-at-red-x-g1-23。

4.4 起推理服务

cd ImageWAM && set -a && source .env.local && set +a
export PYTHONPATH=$PWD/src:$FLUX2_SRC/src:$FLUX2_SRC
D=<本包>/imagewam/g1_23_place_red_x_flux2_klein_4b
CUDA_VISIBLE_DEVICES=0 .venv/bin/python scripts/g1/serve_imagewam_g1.py \
  --task-config   g1_23_place_red_x_flux2_klein_4b \
  --ckpt          $D/step_006000.pt \
  --dataset-stats $D/dataset_stats.json \
  --prompt-embeds $D/g1_23_place_red_x_prompt_embeds.npz \
  --g1-client-path ../g1-client \
  --port 8000

协议与 g1-client 的 PolicyClient 相同(msgpack over WebSocket)。三路图像按"头部、左腕、右腕"的顺序发送,state 为 12 维,返回 (16, 12) 的动作块。

ckpt、dataset_stats.json、prompt_embeds.npz 必须来自同一个任务目录,不能混用。

5. 已做的验证(2026-09-26,nnmc65)

模型 代码 结果(与数据集真实动作的平均绝对误差)
openpi place 19999 GitHub 084dc0f + 本补丁(干净 worktree) 5 帧:输出 (32, 12);手臂 0.0055 rad(约 0.3°);左夹爪 0.008
ImageWAM pick step_010000 官方 5d4a341 + 本补丁(干净 worktree) ep0 5 帧:输出 (16, 12);左臂 0.0126 rad;左夹爪 0.013;单次 0.24 s
ImageWAM place step_006000 同上 ep40 3 帧:输出 (16, 12);左臂 0.0086 rad;左夹爪 0.0095
原有 16 维 G1_29 模型(回归测试) 修改前后的 serve_imagewam_g1.py 预测输出逐值一致

三次推理用的 checkpoint、dataset_stats、prompt_embeds 都直接取自本目录。这些都是离线验证,还没有上真机闭环测试。

6. 注意事项

  1. ImageWAM place 后期有过拟合迹象:

    step val_loss action_l1
    2000 0.224 0.033
    6000 0.343 0.056

    验证集只有 1 个 episode(16 个样本),数字噪声较大。本包按要求放的是最新两个 checkpoint;如果真机效果不好,建议试 step_002000/step_003000,原件在 nnmc65:/shared/user64/workspace/yuhao/imagewam/ImageWAM/runs/g1_23_place_red_x_flux2_klein_4b/2026-09-26_09-25-59/checkpoints/weights/。

  2. ImageWAM pick 没有过拟合:action_l1 从 0.024 一直降到 0.013,最终的 step_010000 就是最好的。

  3. 机器人侧需要适配 G1_23:现有的 g1-client 是按 16 维 G1_29(7 自由度手臂)写的,需要按第 2 节的 12 维顺序组装 state,并把返回的 12 维动作下发给 5 自由度手臂。服务端这边不需要改。

  4. 数据格式:训练数据来自 pick_leftmost_g1_23_dex1_lerobot_only_20260922 和 place_at_red_x_g1_23_dex1_lerobot_only_20260923,经 convert_g1_23_v30_to_v21.py 转成了 v2.1(视频为 H.264,头部相机的 key 由 cam_high 改为 cam_left_high)。pick 数据剔除了 handsoap_094922Z 的 ep28(右臂下垂)。

  5. nnmc65 上用 JAX 多卡训练 openpi 不稳定:10 次 4 卡训练中有 8 次出现 NaN 或 loss 异常(GPU 0–3 和 4–7 上都出现过),原因未查明;单卡训练与推理都正常。这不影响推理。本包里的 openpi place 属于正常的那 2 次之一(在 GPU 4–7 上训练),loss 曲线全程平稳下降(0.117 → 0.0011)。

Downloads last month

-

Downloads are not tracked for this model. How to track
Inference Providers NEW
This model isn't deployed by any Inference Provider. 🙋 Ask for provider support