Files
VLA/TURTLE2_RETRAIN_DEPLOYMENT.md
2026-09-23 21:04:17 +08:00

85 lines
10 KiB
Markdown
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# Wall-X 重新训练后部署到 Turtle2:完整迁移流程
本流程对应 `/home/xiehaolv/huanghuagui/zhanyifeng/wall-x` 的当前 serving 与 TCP/WebSocket 桥接代码。当前已验收的目标 checkpoint 是 `/home/xiehaolv/huanghuagui/wall-x-model/finetuned/1`。实际启动命令见 [TURTLE2_STARTUP.md](TURTLE2_STARTUP.md)。训练侧的 `config.yml` 是训练快照,部署时保留原件;推理参数改在启动命令或部署代码中。
## 一、先判断这次究竟改变了什么
| 训练变化 | 部署时必须核对或修改 |
| --- | --- |
| 只改学习率、batch size、epoch、随机种子,数据格式和动作定义不变 | 更换 checkpoint 路径及其同目录 `config.yml`;核对 LoRA 参数、归一化文件和实际推理结果。桥接接口通常不变。 |
| 换数据集,但仍为三路相机、右臂 7D 原始状态/动作 | 更新训练配置中的数据根目录、`repo_id`、`norm_stats_path`、任务文本及相机 key mapping;部署使用新 checkpoint 自带的 normalizer,并更新 serving 的 `norm-key` 与任务文本。 |
| 相机数量、名称、顺序或实际安装位置变化 | 更新训练数据的相机映射与 serving `cam-names`;核对机器人发图顺序及桥接 `camera_left`/`camera_front`/`camera_right` 的物理对应。先做逐路图像检查,不要直接执行动作。 |
| `action_horizon_flow` 变化 | serving 和桥接两处 `--action-horizon` 都改为新值;重新计算动作裁剪与插值后的包长,并运行协议检查。启动脚本现会拒绝与训练配置不一致的 serving 长度。 |
| 绝对/相对动作、欧拉角/6D 旋转、左右臂、关节/末端、夹爪范围变化 | 训练配置、归一化、serving 的动作重建、桥接的 7D `follow{1,2}_pos` 协议都要重新验收。不能只替换权重路径。 |
| LoRA 的 rank、alpha、`use_rslora` 或目标模块变化 | 从训练服务器导出实际使用的 LoRA JSON 为 checkpoint 内的 `lora_config.json`;加载器依据 rank 和 alpha 计算合并系数。若使用逐层不同缩放,当前加载器会拒绝,需实现并测试后才能部署。 |
## 二、训练前检查数据和配置
1. 保留一份原始 LeRobot v3 数据。当前训练配置指向 LeRobot v2.1 数据目录;继续使用同一训练环境时,先生成其可读取的 v2.1 训练副本,不要把 v3 目录直接写成 v2.1 路径。
2. 核对每条 episode 的三路视频能解码、帧数与 `observation.state`/`action` 对齐,并剔除明显不合格的示教。当前物理映射是 camera1 左臂固定视角、camera2 面部视角、camera3 右臂视角。
3. 当前训练 key mapping 为:`observation.images.faceImg → face_view`,`observation.images.leftImg → left_wrist_view`,`observation.images.rightImg → right_wrist_view`,`observation.state → state`,`action → action`。换数据集后按**新数据的真实字段**更新;字段名相同并不能证明镜头位置相同。
4. 确认机器人状态和示教动作的坐标系、单位、夹爪开合方向相同。当前模型训练右臂,训练数据原始状态/动作为 7D;当前配置在训练加载时把欧拉角转换为 6D,并把动作转为相对当前末端的表示,最终形成“位置 3+旋转 6+夹爪 1+填充 16”的 26D 布局。
5. 在训练服务器上更新 `data.lerobot_config.root`、`repo_id`、`data.norm_stats_path`、`data.key_mappings.camera`、图像分辨率、`task.action_horizon` 和 `task.action_horizon_flow`。如果只改优化超参数,仍核对保存出的 `config.yml` 这些字段未意外变化。
6. `norm_stats.json` 与 normalizer 必须由**这次训练所用的数据和配置**生成。当前 6D 配置部署时优先读取 checkpoint 内的 `normalizer_action.pth` 与 `normalizer_propri.pth`;不要沿用上一模型的两个 `.pth`。
7. 保存训练实际使用的 LoRA JSON,记录 `lora_r`、`lora_alpha`、`use_rslora` 和目标模块。不要只保存配置文件的绝对路径,训练服务器路径到部署服务器通常不可达。
## 三、把 checkpoint 导出到部署服务器
为每次训练创建独立目录,例如 `/home/xiehaolv/huanghuagui/wall-x-model/finetuned/<新版本>`。不要覆盖正在部署的 checkpoint。至少保留:
```text
model.safetensors # 或受加载器支持的 pytorch_model_fsdp.bin
config.yml # 对应这次训练的原始配置
config.json # 模型结构
preprocessor_config.json
tokenizer.json
tokenizer_config.json
vocab.json # 若本次 tokenizer 导出包含该文件
normalizer_action.pth
normalizer_propri.pth
lora_config.json # 从这次训练实际使用的 LoRA JSON 原样复制
```
`norm_stats.json`、`global_step.pth` 可一并保留,便于审计。`optimizer.pt`、`scheduler.pt`、`rng_state.pt` 不参与推理加载,可以不传到部署服务器。若训练保存的是仅含 LoRA adapter 的轻量文件,而不是该项目预期的完整 checkpoint,当前 `run_serving.sh` 不能直接当完整模型加载;先按训练代码的导出流程补齐基础权重。
当前 checkpoint `1` 具有完整 `model.safetensors`、配置、processor 和 normalizer,但**缺少训练原始 `lora_config.json`**。部署代码会兼容旧模型,警告后暂按 `alpha/r=2` 合并。其 LoRA 权重 rank 为 16;只有核对训练原始 JSON 的 alpha 为 32 且 `use_rslora=false`,才能确认这个系数。若原始 JSON 不在手,不要把示例配置当作训练凭据。
## 四、部署前静态核对
在部署服务器进入仓库目录:
```bash
cd /home/xiehaolv/huanghuagui/zhanyifeng/wall-x
export WALLX_TEST_CHECKPOINT=/home/xiehaolv/huanghuagui/wall-x-model/finetuned/1
export WALLX_TEST_PYTHON=/home/xiehaolv/huanghuagui/conda-envs/wallox_0.5/bin/python
PYTHONDONTWRITEBYTECODE=1 "$WALLX_TEST_PYTHON" -m pytest -q \
tests/test_lora_scale.py \
tests/test_tcp_ws_bridge.py \
tests/test_run_serving_contract.py \
tests/test_turtle2_inference_input.py
```
这些测试当前以 checkpoint `1` 的 32 步、三相机布局为基准;换成动作长度、相机数或特征布局不同的 checkpoint 时,应先更新相应测试的期望值,再运行。即使测试通过,也要继续做一次不发送动作的真实模型推理,因为测试不会证明新权重本身能完成抓取任务。
核对 `config.yml` 的 `task.dof_config`、`task.agent_pos_config`、`task.action_horizon_flow`、`data.key_mappings.camera` 和 `data.lerobot_config.repo_id`。将 serving 的 `--model-config.norm-key` 设置为 checkpoint 内 normalizer 的数据集键。当前键为 `pick_paper_lerobot_v21_3cam`;如果新 checkpoint 的键变了,要同步修改启动命令。
## 五、更新启动命令与不发送动作的推理
在 [TURTLE2_STARTUP.md](TURTLE2_STARTUP.md) 中将 `--checkpoint-path` 与 `--train-config-path` 都指向新目录;将服务端、桥接端的 `--action-horizon` 设为训练的 `task.action_horizon_flow`;相机名称、`norm-key`、任务指令同步为新训练实际值。保持 `--serialize-actions`。桥接端只接受序列化的 `follow2_pos`;它会拒绝缺少该字段的原始 `predict_action`,避免按旧布局误读填充维。
先启动 serving,观察 LoRA 合并日志和 `load_state_dict result: <All keys matched successfully>`。当前模型可能打印“词嵌入表被裁剪”和“checkpoint 内的 normalizer 参数未直接用作模型权重”:它们分别来自当前流式动作 tokenizer 与单独加载的 normalizer;需要关注是否还有其他非预期未匹配权重。若 LoRA scale 出现缺少 metadata 的警告,先核对上一步的训练 JSON。
然后启动**不带** `--allow-send` 的桥接端,在 `arm-pc` 以单包模式发送真实相机和状态。核对三路画面朝向、日志中的 `recv state`、serving 返回行数、桥接的 `predicted follow2 T=<插值后长度>`、右臂首尾目标及夹爪范围。对于当前 32 步、`action-end-ratio=0.2`、插值倍数 32,桥接预期返回 192 点。模型推理可用不等于动作方向正确,现场仍须验证坐标与夹爪符号。
## 六、单包真机与连续执行
单包时停止 dry-run 桥接进程,按启动页相同命令增加 `--allow-send`,保留 `--max-action-cycles 1`、`--require-right-feedback`、`--clip-action-delta` 和当前小幅位置/旋转限制。现场人员确认机器人周围无障碍、右臂控制器已使能、升降柱目标高度合适,能即时急停。观察 `/follow2_pos_back` 与 `/joint_information2`,并核对夹爪开合方向与物体接触情况。
单包结果符合预期后,才把 `--max-action-cycles` 改为 `0` 进入连续推理;`0` 意味着不限动作包数。当前桥接的反馈检查只验证右臂末端是否发生运动,**不提供可靠的物品滑脱检测或有限次数自动重抓**。如果任务需要这些能力,应单独设计感知判定和执行状态机,而不能把 `max-action-cycles` 当作重抓次数。
停止顺序:机器人端先退出,再停止桥接端和 serving。保留上一版 checkpoint 与其匹配的启动命令作为回退入口;回退必须同时恢复权重、训练配置、动作长度、相机和 normalizer 参数,不能只切换 `model.safetensors`。
## 七、当前验证范围
在部署服务器 GPU 1 上,checkpoint `1` 已完成载入,日志显示 72 组 LoRA 合并和 `<All keys matched successfully>`。三路 448×448 合成图像已通过完整回环:TCP 状态/图像输入 → WebSocket serving → Turtle 动作序列化 → TCP 动作回传;返回包含 `follow1_pos`、`follow2_pos`、`head_pos`、`lift`、`car_pose`,右臂轨迹为 192 点,左臂 192 点均保持输入位姿。另有 12 项回归测试通过。三路 448×448 图像此前触发的 1024 token 截断已修复为推理时保留完整图像 token。回环只把动作发给本机合成客户端,没有连接或驱动机器人。真实相机内容、抓取效果、右臂执行方向、夹爪范围和训练原始 LoRA alpha 仍需要现场与训练产物确认。