| # SceneSmith 完整技术文档 |
|
|
| > 语言:中文 |
| > 对应代码:[nepfaff/scenesmith](https://github.com/nepfaff/scenesmith) |
| > 论文:[arXiv 2602.09153](https://arxiv.org/abs/2602.09153) |
| > 本次运行环境:NVIDIA L40S GPU,SLURM 集群 |
|
|
| --- |
|
|
| ## 目录 |
|
|
| 1. [系统总览](#1-系统总览) |
| 2. [输入输出格式](#2-输入输出格式) |
| 3. [核心流程详解](#3-核心流程详解) |
| 4. [代码结构解析](#4-代码结构解析) |
| 5. [Robot Eval 模块](#5-robot-eval-模块) |
| 6. [SceneSmith 能做什么 / 不能做什么](#6-scenesmith-能做什么--不能做什么) |
| 7. [本次运行结果](#7-本次运行结果) |
| 8. [Demo采集说明](#8-demo采集说明) |
| 9. [常见问题与局限性](#9-常见问题与局限性) |
| 10. [复现指南](#10-复现指南) |
|
|
| --- |
|
|
| ## 1. 系统总览 |
|
|
| SceneSmith 是一个**全自动、文本驱动的室内场景生成系统**,专为机器人仿真设计。 |
|
|
| 给一段自然语言描述(如"一个有书桌、床和衣柜的卧室"),SceneSmith 会输出一个**物理上可用的完整室内场景**,包含: |
| - 精确的 6D 物体位姿 |
| - 每个物体的碰撞几何体(SDF 格式) |
| - 物理属性(质量、摩擦系数、惯性矩阵) |
| - 可以直接导入 Drake / MuJoCo / Isaac Sim 的格式 |
|
|
| 系统的核心是用**多个 LLM Agent 协作**代替人工设计:每个 Agent 负责场景生成的一个阶段,用视觉反馈迭代优化,直到满足质量标准。 |
|
|
| ``` |
| 文字描述 |
| │ |
| ▼ |
| ┌─────────────────────────────────────────────────────────┐ |
| │ SceneSmith Pipeline │ |
| │ │ |
| │ Floor Plan Agent → Furniture Agent → Wall Agent │ |
| │ ↓ ↓ ↓ │ |
| │ 生成平面图 摆放大件家具 墙面装饰 │ |
| │ ↓ ↓ │ |
| │ Ceiling Agent → Manipuland Agent │ |
| │ ↓ ↓ │ |
| │ 天花板灯具 小件可操作物体 │ |
| │ │ |
| │ 每个阶段:LLM 规划 → 3D资产生成 → 物理验证 → 视觉评分 │ |
| └─────────────────────────────────────────────────────────┘ |
| │ |
| ▼ |
| house.blend (Blender 渲染) + house.dmd.yaml (Drake 仿真) + house_state.json |
| ``` |
|
|
| --- |
|
|
| ## 2. 输入输出格式 |
|
|
| ### 输入 |
|
|
| | 输入项 | 格式 | 说明 | |
| |--------|------|------| |
| | 场景描述 | 自然语言字符串 | 例:`"A cozy bedroom with a queen bed..."` | |
| | CSV 提示文件(可选) | `prompts.csv` | 批量生成多个场景时使用 | |
| | 配置文件 | Hydra YAML | 控制使用的模型、后端、参数 | |
|
|
| **`prompts.csv` 格式**: |
| ```csv |
| scene_index,prompt |
| 0,"A modern kitchen with..." |
| 1,"A cozy living room with..." |
| ``` |
|
|
| **关键配置参数**: |
| ```yaml |
| openai: |
| model: "gpt-5.2" # LLM 模型名 |
| experiment: |
| num_scenes: 5 # 生成场景数量 |
| scene_prompt: "..." # 单场景描述 |
| furniture_agent: |
| asset_manager: |
| backend: "hunyuan3d" # 3D资产生成后端: sam3d | hunyuan3d | hssd |
| ``` |
|
|
| ### 输出 |
|
|
| 每次运行生成如下目录结构: |
|
|
| ``` |
| outputs/YYYY-MM-DD/HH-MM-SS/ |
| └── scene_000/ |
| ├── combined_house/ |
| │ ├── house.blend ← Blender 完整场景 (~200MB) |
| │ ├── house.dmd.yaml ← Drake Directives(仿真可用) |
| │ ├── house_furniture_welded.dmd.yaml ← 家具焊接版(稳定性更好) |
| │ ├── house_state.json ← 所有物体的位姿+元数据 |
| │ └── sceneeval_state.json ← 场景评分数据 |
| ├── room_bedroom/ |
| │ ├── generated_assets/ ← 每个物体的 SDF + 纹理 |
| │ │ ├── desk_0/ |
| │ │ │ ├── model.sdf |
| │ │ │ ├── model.obj |
| │ │ │ └── texture.png |
| │ │ └── ... |
| │ ├── scene_states/ ← 各阶段保存的中间状态 |
| │ │ ├── scene_after_furniture/scene.blend |
| │ │ ├── scene_after_wall_objects/scene.blend |
| │ │ ├── scene_after_ceiling_objects/scene.blend |
| │ │ └── final_scene/ |
| │ │ ├── scene.blend |
| │ │ └── scene_state.json |
| │ └── scene_renders/ ← 各阶段的渲染图像 (PNG) |
| └── floor_plans/ |
| └── final_floor_plan/ |
| ├── floor_plan.blend |
| └── floor_plan.dmd.yaml |
| ``` |
|
|
| **`house_state.json` 结构**(关键字段): |
| ```json |
| { |
| "rooms": { |
| "bedroom": { |
| "objects": { |
| "desk_0": { |
| "object_type": "furniture", |
| "name": "desk", |
| "description": "A modern wooden desk", |
| "sdf_path": "generated_assets/desk_0/model.sdf", |
| "transform": { |
| "translation": [0.79, 1.58, 0.0], |
| "rotation_wxyz": [1.0, 0.0, 0.0, 0.0] |
| }, |
| "bbox_min": [-0.6, -0.3, 0.0], |
| "bbox_max": [0.6, 0.3, 0.75], |
| "mass": 15.0, |
| "mu_static": 0.6 |
| } |
| } |
| } |
| } |
| } |
| ``` |
| |
| **`house.dmd.yaml` 格式**(Drake Directives): |
| ```yaml |
| directives: |
| - add_model: |
| name: bedroom_desk_0 |
| file: package://scene/room_bedroom/generated_assets/desk_0/model.sdf |
| - add_weld: |
| parent: world |
| child: bedroom_desk_0::base_link |
| X_PC: |
| translation: [0.79, 1.58, 0.0] |
| rotation: !Rpy { deg: [0, 0, 0] } |
| ``` |
| |
| --- |
| |
| ## 3. 核心流程详解 |
| |
| ### Stage 1:Floor Plan Agent(平面图规划) |
| |
| **输入**:场景描述文字 |
| **输出**:房间尺寸、门窗位置、墙体布局(`floor_plan.dmd.yaml`) |
| |
| 工作方式: |
| 1. LLM 解析场景描述,确定所需房间类型(卧室、厨房等) |
| 2. 生成候选平面图(房间长宽、门的位置) |
| 3. 用 Blender 渲染俯视图,LLM 评分(0-1分) |
| 4. 迭代优化,选择得分最高的方案 |
| |
| 评分标准:空间合理性、比例、门窗位置是否符合常识。 |
| |
| --- |
| |
| ### Stage 2:Furniture Agent(家具摆放) |
| |
| **输入**:平面图、场景描述 |
| **输出**:家具的精确 6D 位姿 + 每件家具的 SDF 模型 |
| |
| 这是最复杂的阶段,分三个子步骤: |
| |
| #### 2a. 家具规划 |
| LLM 决定放什么家具、大概的位置,生成一个结构化的家具列表。 |
| |
| #### 2b. 3D 资产生成 |
| 对每件家具,走以下路由(Asset Router): |
| |
| ``` |
| 家具描述文字 |
| │ |
| ▼ |
| Asset Router (LLM决策) |
| ├── "generated" → Hunyuan3D-2 / SAM3D |
| │ ├── 生成参考图 (GPT-Image-2) |
| │ └── 图片 → 3D mesh (扩散模型) |
| │ ↓ |
| │ 纹理烘焙 + SDF生成 |
| │ |
| ├── "artvip" → 从ArtVIP库检索关节物体(开门的衣柜等) |
| │ |
| └── "hssd" → 从HSSD数据集检索(更快,质量稳定) |
| ``` |
| |
| #### 2c. 迭代摆放 |
| 1. 放置家具到初始位置 |
| 2. Drake 物理仿真:检测碰撞、检查是否可站立 |
| 3. Blender 渲染多视角图 |
| 4. LLM 用视觉反馈打分(美观度、布局合理性、可达性) |
| 5. 如果分数不满足阈值,调整位置重试(最多 N 轮) |
| |
| --- |
| |
| ### Stage 3:Wall Agent(墙面装饰) |
| |
| **输入**:已摆好家具的场景 |
| **输出**:墙面装饰物(画、镜子、时钟、架子等)的位姿 |
| |
| 同样走 asset router → 3D 生成 → Drake 验证 → 视觉评分的流程,但专注于墙面的高度、朝向、装饰品间距。 |
| |
| --- |
| |
| ### Stage 4:Ceiling Agent(天花板) |
| |
| **输入**:已完成墙面的场景 |
| **输出**:天花板灯具、风扇等物体 |
| |
| 主要验证灯具位置是否在房间中央、是否与墙面冲突。 |
| |
| --- |
| |
| ### Stage 5:Manipuland Agent(可操作小物件) |
| |
| **输入**:已完成天花板的场景、每件家具的支撑面信息 |
| **输出**:桌面上的书、杯子、水果等小物件 |
| |
| 特点: |
| - 自动分析每件家具的"支撑面"(桌面、架子面) |
| - 在支撑面上随机采样放置位置,Drake 验证不碰撞 |
| - 可生成组合(stack/pile/filled_container):叠起来的书、装苹果的碗等 |
| |
| --- |
| |
| ### Stage 6:物理投影 + 最终导出 |
| |
| 所有物体放好后: |
| 1. Drake 运行物理仿真,让物体自然落下(消除浮空、轻微穿插) |
| 2. 输出最终 `house.dmd.yaml`(固定位姿,weld 到 world) |
| 3. Blender 渲染最终场景,保存 `house.blend` |
| |
| --- |
| |
| ## 4. 代码结构解析 |
| |
| ``` |
| scenesmith/ |
| ├── main.py ← 入口,Hydra 配置,调度各 Agent |
| │ |
| ├── scenesmith/ |
| │ ├── experiments/ |
| │ │ └── indoor_scene_generation.py ← 主实验类,串联所有 Agent |
| │ │ |
| │ ├── floor_plan_agents/ |
| │ │ ├── stateful_floor_plan_agent.py ← Floor Plan Agent 实现 |
| │ │ └── tools/ ← 平面图相关工具 |
| │ │ |
| │ ├── furniture_agents/ |
| │ │ ├── stateful_furniture_agent.py ← Furniture Agent 主类 |
| │ │ └── tools/ |
| │ │ ├── furniture_tools.py ← 家具放置、物理检查工具 |
| │ │ ├── vision_tools.py ← Blender 渲染观察工具 |
| │ │ └── scene_tools.py ← 场景状态查询 |
| │ │ |
| │ ├── wall_agents/ ← Wall Agent(同结构) |
| │ ├── ceiling_agents/ ← Ceiling Agent(同结构) |
| │ ├── manipuland_agents/ ← Manipuland Agent(同结构) |
| │ │ |
| │ ├── agent_utils/ |
| │ │ ├── asset_manager.py ← 资产获取总入口 |
| │ │ ├── asset_router/ ← LLM决策走哪个资产后端 |
| │ │ ├── geometry_generation_server/ ← 3D生成服务(Hunyuan3D工作进程) |
| │ │ │ ├── server_manager.py |
| │ │ │ ├── worker_pool.py ← GPU工作进程池 |
| │ │ │ └── gpu_worker.py ← 单个GPU的3D生成进程 |
| │ │ ├── drake_utils.py ← Drake 仿真工具 |
| │ │ ├── rendering.py ← 场景渲染工具 |
| │ │ ├── physics_validation.py ← 物理碰撞检测 |
| │ │ ├── reachability.py ← 机器人可达性分析 |
| │ │ ├── image_generation.py ← 参考图生成(GPT-Image-2) |
| │ │ ├── vlm_service.py ← VLM评分服务 |
| │ │ └── blender/ ← Blender 进程通信 |
| │ │ ├── server_manager.py ← Blender 服务器管理 |
| │ │ └── renderer.py ← 渲染接口 |
| │ │ |
| │ └── robot_eval/ |
| │ ├── dmd_scene.py ← Drake 场景加载 |
| │ ├── policy_interface/ |
| │ │ ├── policy_agent.py ← 任务 → 物体绑定 Agent |
| │ │ └── predicate_resolver.py ← 绑定 → 精确位姿 |
| │ ├── success_validation/ |
| │ │ └── validator_agent.py ← 任务成功验证 Agent |
| │ └── task_generation/ |
| │ └── scene_prompt_generator.py ← 任务 → 场景描述 |
| │ |
| └── scripts/ |
| ├── robot_eval/ |
| │ ├── generate_prompts.py ← Stage 1: task → prompts |
| │ ├── policy_interface.py ← Stage 3: scene + task → robot poses |
| │ └── validate.py ← Stage 4: 验证任务完成 |
| ├── collect_demo.py ← Demo采集与可视化(本次添加) |
| ├── render_flythrough.py ← 生成场景飞行视频 |
| └── export_scene_to_mujoco.py ← 导出到 MuJoCo |
| ``` |
| |
| --- |
| |
| ### 关键类说明 |
| |
| #### `StatefulFurnitureAgent` |
| 继承自 `BaseStatefulAgent`,用 `openai-agents` SDK 运行 LLM agent loop。 |
| |
| Agent 的 tools 包括: |
| - `place_furniture(obj_id, x, y, yaw)` — 放置家具 |
| - `observe_scene()` — 渲染当前场景,返回多视角图给 LLM 看 |
| - `get_physics_check()` — 运行 Drake 碰撞检测 |
| - `generate_furniture_assets(descriptions)` — 批量生成 3D 资产 |
| - `score_scene()` — VLM 打分 |
| |
| 每轮 LLM 调用 tools → 观察反馈 → 调整 → 直到评分达标或超过最大轮数。 |
| |
| #### `AssetManager` |
| 统一的资产获取接口,内部调用 `AssetRouter` 决策: |
| ```python |
| asset = await asset_manager.get_asset( |
| description="A wooden desk with drawers", |
| object_type="furniture", |
| strategy="generated" # or "hssd", "artvip" |
| ) |
| # 返回 Asset(sdf_path, obj_path, texture_path, dimensions, ...) |
| ``` |
| |
| #### `DMDScene` + `PredicateResolver` |
| 用于 robot eval: |
| ```python |
| scene = load_scene_for_validation( |
| scene_state_path=Path("house_state.json"), |
| dmd_path=Path("house.dmd.yaml"), |
| ) |
| scene.finalize() # 建立 Drake plant,同步位姿 |
| |
| resolver = PredicateResolver(scene=scene, cfg=cfg) |
| result = resolver.resolve("Pick the apple and place it on the plate") |
| # result.poses[0].target_position → [x, y, z] 目标位姿 |
| # result.poses[0].placement_bounds_min/max → 有效放置区域 AABB |
| ``` |
| |
| --- |
| |
| ## 5. Robot Eval 模块 |
| |
| 这是 SceneSmith 的机器人评测框架,共 4 个阶段: |
| |
| ### 阶段 1:生成场景提示词 |
| ```bash |
| python scripts/robot_eval/generate_prompts.py \ |
| --task "Pick a fruit from the bowl and place it on the plate" \ |
| --output-dir outputs/eval_run \ |
| --num-prompts 5 |
| ``` |
| LLM 分析 task,提取: |
| - 必须存在的物体(水果、碗、盘子) |
| - 初始状态约束(水果不能已经在盘子上) |
| - 可变的风格维度(厨房风格、其他装饰物) |
| |
| 输出 `prompts.csv` 供 `main.py` 生成多个不同风格的场景。 |
| |
| ### 阶段 2:生成场景 |
| ```bash |
| python main.py +name=eval experiment.csv_path=outputs/eval_run/prompts.csv |
| ``` |
| |
| ### 阶段 3:Policy Interface(任务 → 机器人位姿) |
| ```bash |
| python scripts/robot_eval/policy_interface.py \ |
| --scene-state outputs/.../house_state.json \ |
| --dmd outputs/.../house.dmd.yaml \ |
| --task "Pick a fruit from the bowl and place it on the plate" \ |
| --output-json robot_commands.json |
| ``` |
| |
| 输出格式: |
| ```json |
| { |
| "task": "Pick a fruit...", |
| "robot_start_xy": [1.2, -0.5], |
| "world_bounds": {"min": [-3, -3, 0], "max": [3, 3, 2.7]}, |
| "commands": [{ |
| "action": "pick_and_place", |
| "rank": 1, |
| "confidence": 0.92, |
| "drake_model_name": "bedroom_apple_0", |
| "target_position": [0.5, 0.3, 0.85], |
| "placement_bounds_min": [0.2, 0.1, 0.85], |
| "placement_bounds_max": [0.8, 0.5, 1.0], |
| "reasoning": "Apple found on nightstand (precondition met), plate on desk is valid goal" |
| }] |
| } |
| ``` |
| |
| **注意**:SceneSmith 不包含 robot URDF 和 policy。`placement_bounds_min/max` 是给你的 policy 用的采样区域。 |
| |
| ### 阶段 4:验证 |
| Robot 执行完任务后,将修改过的 `house.dmd.yaml`(更新了物体位姿)传入验证器: |
| ```bash |
| python scripts/robot_eval/validate.py \ |
| --scene-state outputs/.../house_state.json \ |
| --dmd outputs/.../modified_house.dmd.yaml \ |
| --task "Pick a fruit from the bowl and place it on the plate" |
| ``` |
| |
| 验证器用 Drake 物理查询(签名距离、接触检测)+ VLM 视觉判断,输出每个子要求的得分。 |
| |
| --- |
| |
| ## 6. SceneSmith 能做什么 / 不能做什么 |
| |
| ### ✅ 能做的 |
| |
| | 场景类型 | 说明 | |
| |---------|------| |
| | 卧室 | 床、衣柜、书桌、台灯、挂画、小件(书、闹钟等) | |
| | 厨房 | 橱柜、餐桌、厨具、水果、杯子等 | |
| | 办公室 | 桌子、椅子、电脑、文具等 | |
| | 客厅 | 沙发、茶几、书架、摆件等 | |
| | 关节物体 | 可开关的柜子、抽屉(来自 ArtVIP 数据集) | |
| | 桌面操作场景 | 通过 manipuland agent 生成多个小物件,支持 pick-and-place | |
| | 组合物体 | 叠起来的书(stack)、装了东西的碗(filled_container)、散乱的一堆(pile) | |
| |
| ### ❌ 不能做的 |
| |
| | 类别 | 原因 | |
| |------|------| |
| | **柔性物体**(布料、毛绒玩具) | SceneSmith 只生成刚体 SDF。柔性物体需要 FEM/粒子仿真,Drake 支持有限,SceneSmith 不建模 | |
| | **流体**(倒水、液体) | 同上,流体需要 SPH/粒子系统,不在 SceneSmith 范围内。`house.dmd.yaml` 是刚体 Directives | |
| | **人体/角色动画** | 无 URDF/骨骼,无动画系统 | |
| | **室外场景** | 专为室内设计,无地形、植被等 | |
| | **Robot URDF** | SceneSmith 只生成环境,不包含机器人本体 | |
| | **Policy / Controller** | 不包含任何 policy,只提供场景 + eval harness | |
| |
| ### 关于柔性物体和流体的正确路径 |
| |
| 如果需要: |
| - **布料**:用 MuJoCo 的 `composite` 元素或 Isaac Sim 的 FEM,把 SceneSmith 生成的刚体场景作为背景 |
| - **流体**:FluidLab、Taichi,SceneSmith 生成杯子/瓶子的 SDF 作为容器几何体 |
| - 可以用 `scripts/export_scene_to_mujoco.py` 先把 SceneSmith 场景转成 MuJoCo XML,再在 MuJoCo 里加入柔性/流体模拟 |
| |
| --- |
| |
| ## 7. 本次运行结果 |
| |
| ### 场景 1:卧室(Bedroom) |
| |
| **提示词**: |
| > A cozy bedroom with a queen bed against the wall, two nightstands with lamps, a wardrobe in the corner, and a small desk with a chair near the window. |
| |
| **运行时间**:约 1 小时 57 分钟(L40S GPU) |
| |
| **生成物体**: |
| | 物体 | 类型 | 位置 (x, y, z) | |
| |------|------|---------------| |
| | desk_0 | furniture | (0.79, 1.58, 0.0) | |
| | nightstand_0 | furniture | (-0.55, -1.73, 0.0) | |
| | nightstand_1 | furniture | (0.62, -1.73, 0.0) | |
| | rug_0 | furniture | (-0.01, -0.39, 0.0) | |
| | wardrobe_0 | furniture | (2.06, -1.53, 0.0) | |
| |
| **注意**:本次运行中 Hunyuan3D worker 因 CUDA fork 问题未能生成 manipuland(小件物体),house_state.json 只有家具级别的物体。 |
| |
| **输出文件**: |
| - `combined_house/house.blend` — 201MB Blender 场景 |
| - `combined_house/flythrough.mp4` — 120帧 1280×720 飞行视频 |
| - `combined_house/house.dmd.yaml` — Drake 仿真文件 |
| |
| --- |
| |
| ## 8. Demo采集说明 |
| |
| ### 什么是 Demo |
| |
| 在这里,"demo" 是指一个 **pick-and-place 任务的完整轨迹**,包含: |
| - 初始场景状态(物体位姿) |
| - 末端执行器的完整轨迹(6D位姿序列) |
| - 夹爪宽度序列 |
| - 任务成功与否 |
| |
| ### 本次 Demo 类型 |
| |
| 由于 SceneSmith 不含真实 robot,我们采用 **scripted demo**(脚本化轨迹),按照标准 pick-and-place 轨迹规划: |
| |
| ``` |
| Home → Approach(接近物体上方)→ Pre-grasp(下降)→ Grasp(夹爪闭合) |
| → Lift(提升)→ Transport(平移)→ Place(放下)→ Release(张开夹爪) |
| ``` |
| |
| ### 与真实采集的区别 |
| |
| | 项目 | 本次(脚本化) | 真实采集 | |
| |------|--------------|---------| |
| | 轨迹来源 | 几何规划 | robot controller / teleop | |
| | 物理真实性 | 运动学插值 | 力矩控制 | |
| | 碰撞避免 | 简单直线轨迹 | 运动规划(RRT等) | |
| | 接触建模 | 无 | Drake/MuJoCo 物理仿真 | |
| | 用途 | 演示、可视化 | 训练 policy | |
| |
| ### Demo JSON 格式 |
| |
| ```json |
| { |
| "task": "Pick an object from the nightstand and place it on the desk", |
| "scene_id": "bedroom_nightstand_to_desk", |
| "target_object": "bedroom_nightstand_0", |
| "initial_pos": [-0.55, -1.73, 0.5], |
| "goal_pos": [0.79, 1.58, 0.85], |
| "goal_reference": "bedroom_desk_0", |
| "success": true, |
| "total_duration_s": 7.5, |
| "num_steps": 150, |
| "trajectory": [ |
| { |
| "step_id": 0, |
| "phase": "approach", |
| "end_effector_pos": [0.0, 0.0, 0.8], |
| "end_effector_quat_wxyz": [1, 0, 0, 0], |
| "gripper_width": 1.0, |
| "target_object_pos": [-0.55, -1.73, 0.5], |
| "timestamp": 0.0 |
| }, |
| ... |
| ] |
| } |
| ``` |
| |
| ### 可视化说明 |
| |
| `demo_*_trajectory.png` 包含 4 个子图: |
| 1. **3D 轨迹图**:不同颜色表示不同阶段(接近/抓取/搬运/放置) |
| 2. **俯视图**(XY平面):路径规划可视化 |
| 3. **高度-时间曲线**:末端执行器与物体的 Z 轴变化 |
| 4. **夹爪宽度-时间曲线**:抓取动作可视化 |
| |
| --- |
| |
| ## 9. 常见问题与局限性 |
| |
| ### Q: Hunyuan3D-2 生成质量很差怎么办? |
| **A**: 换 SAM3D 后端(需要 A100/H100,无 gated 访问限制)。Hunyuan3D 官方说明仅作 proof-of-concept,质量明显劣于 SAM3D。 |
| |
| ### Q: manipuland 物体没有生成? |
| **A**: Hunyuan3D worker 在 fork 后 CUDA 重初始化失败。症状:`Worker shutting down. Stats: 279 total, 0 completed, 279 failed`。解决:换用 `strategy: "hssd"` 检索模式,不依赖 CUDA generation。 |
| |
| ### Q: LLM 返回 `rs_*` 错误? |
| **A**: LiteLLM 代理是无状态的,不支持 server-side reasoning 续接。需要设置 `reasoning_effort: none` 并使用自定义 `NvidiaInferenceProvider`(已在本次配置中修复)。 |
| |
| ### Q: 一次运行需要多久? |
| **A**: 单房间约 1-2 小时(L40S, Hunyuan3D)。SAM3D 质量更好但更慢。多 GPU 可以并行生成多个房间。 |
| |
| ### Q: 能生成多房间场景吗? |
| **A**: 可以,在 `scene_prompt` 中描述多个房间,`experiment.num_scenes` 控制变体数量。 |
| |
| ### Q: 如何接入自己的 robot? |
| **A**: |
| 1. 加载 `house.dmd.yaml` 到 Drake/MuJoCo |
| 2. 用 `policy_interface.py` 获取 task 的目标位姿 |
| 3. 用你自己的 robot controller 执行 |
| 4. 将结果写回修改后的 `.dmd.yaml` |
| 5. 用 `validate.py` 验证成功率 |
| |
| --- |
| |
| ## 10. 复现指南 |
| |
| ### 环境要求 |
| |
| - Python 3.11 |
| - CUDA 12.4(编译 custom_rasterizer) |
| - Blender 5.1(headless,EEVEE 渲染) |
| - SLURM 集群,L40S GPU(48GB) |
| |
| ### 安装步骤 |
| |
| ```bash |
| # 1. 克隆仓库 |
| git clone https://github.com/nepfaff/scenesmith.git |
| cd scenesmith |
| git submodule update --init --recursive |
| |
| # 2. 创建虚拟环境 |
| uv sync --no-dev |
| |
| # 3. 安装 Hunyuan3D-2 |
| bash scripts/install_hunyuan3d.sh |
| |
| # 4. 下载 ArtVIP 数据 |
| huggingface-cli download nepfaff/scenesmith-preprocessed-data \ |
| artvip/artvip_vhacd.tar.gz --repo-type dataset --local-dir . |
| mkdir -p data/artvip_sdf |
| tar xzf artvip/artvip_vhacd.tar.gz -C data/artvip_sdf |
| |
| # 5. 下载材质 |
| python scripts/download_ambientcg.py --output data/materials |
| # 下载材质嵌入(从 HF) |
| |
| # 6. 编译 CUDA 扩展(需要 CUDA toolkit) |
| # 见 cuda_home/ 目录的说明 |
| ``` |
| |
| ### 运行 |
| |
| ```bash |
| # 设置环境变量 |
| export OPENAI_API_KEY=<your_key> |
| export OPENAI_BASE_URL=https://inference-api.nvidia.com/v1 |
| export HF_TOKEN=<your_hf_token> |
| |
| # 生成场景 |
| python main.py \ |
| "+name=my_scene" \ |
| "experiment.scene_prompt=A cozy bedroom with a bed and desk" \ |
| "openai.model=azure/openai/gpt-5.2" \ |
| "furniture_agent.asset_manager.backend=hunyuan3d" \ |
| "furniture_agent.reasoning_effort.generation=none" |
| |
| # 渲染视频 |
| python scripts/render_flythrough.py \ |
| --blend outputs/.../combined_house/house.blend \ |
| --output flythrough.mp4 \ |
| --blender /path/to/blender |
| |
| # 采集 Demo |
| python scripts/collect_demo.py \ |
| --scene-state outputs/.../house_state.json \ |
| --dmd outputs/.../house.dmd.yaml \ |
| --task "Pick the book and place it on the desk" \ |
| --output-dir demos/ |
| ``` |
| |
| ### 本次运行的关键 Patch |
| |
| 本次在 NVIDIA 内部集群运行时,在原始代码基础上做了以下修改: |
| |
| 1. **`nvidia_inference_provider.py`**(新增):绕过 `openai-agents` SDK 对 `azure/openai/gpt-5.2` 的前缀解析,直接路由到 `inference-api.nvidia.com` |
| 2. **`base_stateful_agent.py`**:注入自定义 Provider |
| 3. **所有 YAML 配置**:`reasoning_effort: none`,防止 stateful reasoning items |
| 4. **`worker_pool.py`**:限制 CUDA re-init 重试次数(max 3次) |
| 5. **`render_flythrough.py`**(新增):适配 Blender 5.1 新 API(`action.layers[].strips[].channelbags[].fcurves`) |
| |