From 456056347f9b5e4d6f89d9904e1c89f02197baa9 Mon Sep 17 00:00:00 2001 From: gouhanke <12219217+gouhanke@user.noreply.gitee.com> Date: Fri, 6 Feb 2026 21:31:19 +0800 Subject: [PATCH] =?UTF-8?q?debug:=20=E5=9B=BA=E5=AE=9A=E9=AA=8C=E8=AF=81?= =?UTF-8?q?=E9=9B=86=E4=B8=8A=E7=9A=84=E9=9A=8F=E6=9C=BA=E5=99=AA=E5=A3=B0?= =?UTF-8?q?=EF=BC=8C=E4=BF=AE=E5=A4=8Dresnet=E5=9C=A8=E8=AE=AD=E7=BB=83?= =?UTF-8?q?=E6=97=B6bn=E5=B1=82=E4=BC=9A=E5=88=87=E6=8D=A2=E5=88=B0train?= =?UTF-8?q?=E7=9A=84=E9=97=AE=E9=A2=98?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- README.md | 134 ------------------------- roboimi/demos/vla_scripts/train_vla.py | 7 ++ roboimi/vla/conf/eval/eval.yaml | 2 +- roboimi/vla/models/backbones/resnet.py | 10 ++ 4 files changed, 18 insertions(+), 135 deletions(-) delete mode 100644 README.md diff --git a/README.md b/README.md deleted file mode 100644 index d6ce487..0000000 --- a/README.md +++ /dev/null @@ -1,134 +0,0 @@ -# VLA Framework: Vision-Language-Action Policy Framework - -**VLA Framewrok** 是 `roboimi` 生态系统中的下一代具身智能策略框架。它采用**完全解耦**与**基于组合**的架构设计,支持视觉语言模型(VLM)、投影层(Projector)与动作生成头(Action Head)的灵活搭配。 - -本框架基于 [Hydra](https://hydra.cc/) 进行配置管理,并采用 HDF5 作为标准数据格式。 - ---- - -## 🏗 架构概览 (Directory Structure) - -我们采用“接口与实现分离”以及“代码与配置镜像映射”的设计原则。 - -```text -roboimi/vla/ -├── agent.py # [Core] VLAAgent 组装类,负责串联各个模块 -├── conf/ # [Config] Hydra 配置文件 (单一真值源) -│ ├── config.yaml # 主入口配置 -│ ├── agent/ # Agent 结构定义 (定义模块间的连接与插值) -│ ├── backbone/ # 视觉骨干配置 (e.g., SigLIP, CLIP) -│ ├── projector/ # 投影层配置 (e.g., MLP, Perceiver) -│ ├── head/ # 动作头配置 (e.g., Diffusion, ACT) -│ └── data/ # 数据流配置 -├── core/ # [Interface] 抽象基类 -│ ├── base_vlm.py # VLMBackbone (ABC) -│ └── base_policy.py # ActionHead (ABC) -├── models/ # [Implementation] 具体模型实现 -│ ├── backbones/ # 视觉模型 (Sub-package) -│ ├── projectors/ # 投影层 (Sub-package) -│ └── heads/ # 策略头 (Sub-package) -├── data/ # [Data Pipeline] Dataset 与 DataLoader -├── modules/ # [Building Blocks] 通用组件 (Encoders, Fusion) -└── scripts/ # [Utilities] 数据转换与维护脚本 -``` - ---- - -## 🚀 快速开始 (Quick Start) - -### 1. 环境依赖 -请确保安装以下核心库: -```bash -pip install hydra-core h5py zarr diffusers transformers -``` - -### 2. 启动训练 (Training) -训练入口脚本通常位于 `demos/vla_scripts/train_vla.py`。 -由于使用了 Hydra,您可以在命令行动态组合模型架构: - -```bash -# 1. 默认训练 (SigLIP + MLP + Diffusion) -python demos/vla_scripts/train_vla.py - -# 2. 切换视觉骨干为 CLIP -python demos/vla_scripts/train_vla.py agent/backbone=clip - -# 3. 切换投影层为 Perceiver Resampler -python demos/vla_scripts/train_vla.py agent/projector=perceiver - -# 4. 修改超参数 (例如 batch size) -python demos/vla_scripts/train_vla.py train.batch_size=32 - -# 5. 调试模式 (使用 Tiny 模型快速跑通流程) -python demos/vla_scripts/train_vla.py agent=tiny -``` - ---- - -## 🛠 开发指南 (Developer Guide) - -### 1. 添加新的视觉骨干 (New Backbone) -1. **代码**: 在 `models/backbones/` 下新建文件 (如 `my_model.py`),继承 `VLMBackbone`。 -2. **导出**: 在 `models/backbones/__init__.py` 中添加导出。 -3. **配置**: 在 `conf/backbone/` 下新建 `my_model.yaml`。 - * *注意*: 必须定义 `output_dim`,供 Projector 引用。 - -### 2. 添加新的投影层 (New Projector) -Projector 负责将 VLM 特征维度对齐到 Agent 的 Embedding 维度。 -1. **代码**: 在 `models/projectors/` 下实现 `nn.Module`。 -2. **配置**: 在 `conf/projector/` 下新建 YAML 文件。 - * *关键*: 设置 `input_dim: ???` 和 `output_dim: ???`,让 Hydra 在 `agent/default.yaml` 中自动插值填充。 - -### 3. 添加新的动作头 (New Action Head) -1. **代码**: 在 `models/heads/` 下新建文件,继承 `ActionHead`。 - * 必须实现 `compute_loss(context, actions)` 和 `predict_action(context)`。 -2. **配置**: 在 `conf/head/` 下新建 YAML 文件。 - * 同样建议设置 `input_dim: ???` 以保持动态性。 - ---- - -## 📊 数据流水线 (Data Pipeline) - -本框架强制使用 **HDF5** 格式以优化 IO 性能。 - -### 1. 数据结构标准 -数据集必须遵循 [Robomimic](https://robomimic.github.io/) 的层级结构: -```text -episode_0.hdf5 -├── action: Dataset, shape=(700, 16), dtype=float32 -└── observations: Group - ├── images: Group - │ ├── angle: Dataset, shape=(700, 480, 640, 3), dtype=uint8 - │ ├── r_vis: Dataset, shape=(700, 480, 640, 3), dtype=uint8 - │ └── top: Dataset, shape=(700, 480, 640, 3), dtype=uint8 - └── qpos: Dataset, shape=(700, 16), dtype=float32 -``` - -### 2. 数据转换工具 -使用内置脚本将您的原始数据转换为标准 HDF5: - -```bash -# 在项目根目录下运行 -python -m roboimi.vla.scripts.convert_to_hdf5 \ - --input_dir /path/to/raw/images \ - --output_path ./data/demo.hdf5 -``` - -### 3. 调试数据 -如果不确定数据是否正确,使用可视化工具检查: -```bash -python -m roboimi.vla.scripts.visualize_data --dataset ./data/demo.hdf5 -``` - ---- - -## ⚠️ 最佳实践 (Best Practices) - -1. **绝对导入**: 禁止使用 `from . import xxx`。请始终使用全路径 `from roboimi.vla.models.backbones import SigLIPBackbone`。 -2. **Hydra 插值**: 在 `agent/default.yaml` 中,我们使用了 `${..embed_dim}` 语法来确保所有子模块的维度一致。**不要在子配置中硬编码维度数值。** -3. **HDF5 IO**: 在 `Dataset` 类中,**必须在 `__getitem__` 内部打开 HDF5 文件**。如果在 `__init__` 中打开,多进程 DataLoader 会因无法序列化文件句柄而报错。 -4. **接口导出**:每当在 `models/xxx/` 下添加新文件时,务必在对应的 `__init__.py` 中更新 `__all__`,以保持引用整洁。 - ---- - -*Maintainer: VLA Framework Team* \ No newline at end of file diff --git a/roboimi/demos/vla_scripts/train_vla.py b/roboimi/demos/vla_scripts/train_vla.py index 32115fb..7df889b 100644 --- a/roboimi/demos/vla_scripts/train_vla.py +++ b/roboimi/demos/vla_scripts/train_vla.py @@ -200,6 +200,13 @@ def main(cfg: DictConfig): if val_loader is None: return None agent.eval() + + # 🔧 FIX: Set deterministic seed for validation to get reproducible loss + # This ensures validation loss is comparable across different steps + torch.manual_seed(42) + if torch.cuda.is_available(): + torch.cuda.manual_seed(42) + total_loss = 0.0 num_batches = 0 with torch.no_grad(): diff --git a/roboimi/vla/conf/eval/eval.yaml b/roboimi/vla/conf/eval/eval.yaml index 10456f2..6e9d251 100644 --- a/roboimi/vla/conf/eval/eval.yaml +++ b/roboimi/vla/conf/eval/eval.yaml @@ -7,7 +7,7 @@ device: ${train.device} # 与训练保持一致 task_name: "sim_transfer" # Task name for environment creation # Policy execution — 从 agent 配置中引用,保持一致性 -num_queries: ${agent.pred_horizon} # 每次预测 pred_horizon 步后重新查询 +num_queries: 4 # 每次预测 pred_horizon 步后重新查询 obs_horizon: ${agent.obs_horizon} # Camera names — 从 data 配置中引用,保持一致性 diff --git a/roboimi/vla/models/backbones/resnet.py b/roboimi/vla/models/backbones/resnet.py index dca2fa1..6d9320c 100644 --- a/roboimi/vla/models/backbones/resnet.py +++ b/roboimi/vla/models/backbones/resnet.py @@ -27,6 +27,16 @@ class ResNetBackbone(VLABackbone): param.requires_grad = False self.model.eval() + def train(self, mode=True): + """ + Override train() to keep frozen ResNet in eval mode. + This ensures BatchNorm layers use running statistics consistently. + """ + super().train(mode) + if hasattr(self, 'model'): + self.model.eval() # Always keep ResNet in eval mode + return self + def forward_single_image(self, image): B, T, C, H, W = image.shape image = image.view(B * T, C, H, W)