10 KiB
Wall-X 重新训练后部署到 Turtle2:完整迁移流程
本流程对应 /home/xiehaolv/huanghuagui/zhanyifeng/wall-x 的当前 serving 与 TCP/WebSocket 桥接代码。当前已验收的目标 checkpoint 是 /home/xiehaolv/huanghuagui/wall-x-model/finetuned/1。实际启动命令见 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 计算合并系数。若使用逐层不同缩放,当前加载器会拒绝,需实现并测试后才能部署。 |
二、训练前检查数据和配置
- 保留一份原始 LeRobot v3 数据。当前训练配置指向 LeRobot v2.1 数据目录;继续使用同一训练环境时,先生成其可读取的 v2.1 训练副本,不要把 v3 目录直接写成 v2.1 路径。
- 核对每条 episode 的三路视频能解码、帧数与
observation.state/action对齐,并剔除明显不合格的示教。当前物理映射是 camera1 左臂固定视角、camera2 面部视角、camera3 右臂视角。 - 当前训练 key mapping 为:
observation.images.faceImg → face_view,observation.images.leftImg → left_wrist_view,observation.images.rightImg → right_wrist_view,observation.state → state,action → action。换数据集后按新数据的真实字段更新;字段名相同并不能证明镜头位置相同。 - 确认机器人状态和示教动作的坐标系、单位、夹爪开合方向相同。当前模型训练右臂,训练数据原始状态/动作为 7D;当前配置在训练加载时把欧拉角转换为 6D,并把动作转为相对当前末端的表示,最终形成“位置 3+旋转 6+夹爪 1+填充 16”的 26D 布局。
- 在训练服务器上更新
data.lerobot_config.root、repo_id、data.norm_stats_path、data.key_mappings.camera、图像分辨率、task.action_horizon和task.action_horizon_flow。如果只改优化超参数,仍核对保存出的config.yml这些字段未意外变化。 norm_stats.json与 normalizer 必须由这次训练所用的数据和配置生成。当前 6D 配置部署时优先读取 checkpoint 内的normalizer_action.pth与normalizer_propri.pth;不要沿用上一模型的两个.pth。- 保存训练实际使用的 LoRA JSON,记录
lora_r、lora_alpha、use_rslora和目标模块。不要只保存配置文件的绝对路径,训练服务器路径到部署服务器通常不可达。
三、把 checkpoint 导出到部署服务器
为每次训练创建独立目录,例如 /home/xiehaolv/huanghuagui/wall-x-model/finetuned/<新版本>。不要覆盖正在部署的 checkpoint。至少保留:
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 不在手,不要把示例配置当作训练凭据。
四、部署前静态核对
在部署服务器进入仓库目录:
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 中将 --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 仍需要现场与训练产物确认。