NVIDIA OSMO + MobilityGen + NuRec:座舱合成数据端到端管道拆解与 IMS 落地路径

信息来源:

  • NVIDIA Developer Blog: “Build and Orchestrate End-to-End SDG Workflows with NVIDIA Isaac Sim and NVIDIA OSMO” (2026年1月)
  • NVIDIA Blog: “Into the Omniverse: Open World Foundation Models Generate Synthetic Worlds for Physical AI” (2025年10月)
  • NVIDIA GTC 2026: Physical AI Open Models and Frameworks
  • GitHub: https://github.com/NVIDIA/OSMO
  • GitHub: https://github.com/NVlabs/MobilityGen

核心创新

NVIDIA 发布了完整的合成数据生成(SDG)管道:OSMO 编排 + Isaac Sim 仿真 + NuRec 重建 + MobilityGen 数据生成 + Cosmos 增强。这套管道可直接应用于座舱感知模型的训练数据生产,解决真实数据采集成本高、场景覆盖不足、标注困难三大痛点。

管道全景图

各组件详解

1. NVIDIA OSMO:云原生编排器

特性 说明 IMS 价值
多阶段编排 定义、运行、监控多步SDG管道 自动化数据生产流程
跨计算环境 本地RTX工作站 + 云端VDI + Azure 弹性扩展数据生产
交互式会话 Isaac Sim 远程交互模式 人工调整仿真场景
工作流YAML 声明式管道定义 可复现的数据生成配方
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
"""
NVIDIA OSMO 工作流定义示例
适配 IMS 座舱数据合成管道

关键概念:
1. OSMO YAML 定义管道阶段
2. 每个 stage 运行在独立容器中
3. 支持 GPU 池调度
4. 输出自动版本管理
"""

# OSMO 工作流 YAML(概念示例)
OSMO_WORKFLOW = """
# IMS Cabin Data Generation Pipeline
name: ims_cabin_sdg
description: >-
End-to-end synthetic data generation for IMS (In-cabin Monitoring System)
models. Generates DMS, OMS, CPD training data from simulated cabin scenes.

stages:
# Stage 1: 环境重建(可选,用于真实座舱数字化)
- name: nurec_reconstruct
type: interactive
image: nvcr.io/nvidia/omniverse/nurec:latest
gpu: 1
commands:
- nurec ingest --input ${RAW_SENSOR_DATA}
- nurec reconstruct --output /workspace/scene.usd
outputs:
- scene.usd

# Stage 2: 仿真场景组装
- name: isaac_sim_assemble
type: batch
image: nvcr.io/nvidia/isaac/sim:5.1.0
gpu: 1
depends_on: [nurec_reconstruct]
commands:
# 加载座舱环境
- isaac-sim load-scene /workspace/scene.usd
# 添加 SimReady 乘员资产
- isaac-sim add-asset --category human --variant adult_male
- isaac-sim add-asset --category human --variant child_5yo
- isaac-sim add-asset --category human --variant infant_rear_facing
# 配置传感器
- isaac-sim configure-camera --position dms_mount --resolution 1280x800
- isaac-sim configure-radar --freq 60ghz --position headliner
- isaac-sim configure-ir --position steering_column
outputs:
- scene_configured.usd

# Stage 3: MobilityGen 轨迹生成
- name: mobility_gen
type: batch
image: nvcr.io/nvidia/isaac/sim:5.1.0
gpu: 1
depends_on: [isaac_sim_assemble]
commands:
# 生成乘员行为轨迹
- mobility-gen create-map --scene scene_configured.usd
- mobility-gen record-trajectory \\
--num-trajectories 1000 \\
--behaviors normal_driving,fatigue,distraction,phone_use,child_moving
- mobility-gen replay-and-render \\
--sensors camera,radar,ir \\
--output /workspace/raw_data
outputs:
- raw_data/

# Stage 4: Cosmos 数据增强
- name: cosmos_augment
type: batch
image: nvcr.io/nvidia/cosmos/transfer:1.0
gpu: 4
depends_on: [mobility_gen]
commands:
# 视觉多样性增强
- cosmos-augment \\
--input /workspace/raw_data \\
--variations lighting,weather,interior_color,passenger_appearance \\
--augmentation-factor 10 \\
--output /workspace/augmented_data
outputs:
- augmented_data/

# Stage 5: 自动标注与数据集打包
- name: auto_annotate
type: batch
image: nvcr.io/nvidia/isaac/repacker:5.1.0
gpu: 1
depends_on: [cosmos_augment]
commands:
# 从仿真 ground truth 自动生成标注
- isaac-annotate \\
--input /workspace/augmented_data \\
--tasks face_detection,gaze_estimation,pose_estimation,occupant_classification \\
--format coco,yolo,onnx
- isaac-package-dataset \\
--output /workspace/ims_dataset_v1
outputs:
- ims_dataset_v1/
"""

# 管道执行示例
import subprocess
import json

class OSMOPipeline:
"""
OSMO 管道执行器

在实际部署中,OSMO CLI 管理这些操作
这里展示 Python API 接口概念
"""

def __init__(self, workflow_yaml: str, pool_name: str = 'gpu-pool'):
self.workflow = workflow_yaml
self.pool = pool_name
self.stages = [
'nurec_reconstruct',
'isaac_sim_assemble',
'mobility_gen',
'cosmos_augment',
'auto_annotate'
]

def submit(self):
"""提交工作流到 OSMO"""
print(f"提交 OSMO 工作流...")
# osmo workflow submit ims_cabin_sdg.yaml --pool gpu-pool
workflow_id = f"ims-sdg-{hash(self.workflow) % 10000:04d}"
print(f"工作流ID: {workflow_id}")
return workflow_id

def monitor(self, workflow_id: str):
"""监控工作流进度"""
# osmo workflow status <workflow_id>
stages_status = {
'nurec_reconstruct': 'completed',
'isaac_sim_assemble': 'completed',
'mobility_gen': 'running',
'cosmos_augment': 'pending',
'auto_annotate': 'pending'
}
return stages_status

def estimate_cost(self, num_scenes: int, augmentation: int):
"""
估算数据生成成本

1 scene → 1000 trajectories → 10x augmentation = 10000 samples
"""
samples_per_scene = 1000 * augmentation
total_samples = num_scenes * samples_per_scene

# GPU 小时成本
gpu_hours_per_scene = 0.5 # 粗略估算
total_gpu_hours = num_scenes * gpu_hours_per_scene
gpu_cost_per_hour = 2.0 # 云端RTX
total_cost = total_gpu_hours * gpu_cost_per_hour

return {
'total_samples': total_samples,
'gpu_hours': total_gpu_hours,
'estimated_cost_usd': total_cost,
'cost_per_sample': total_cost / total_samples
}


# 测试
if __name__ == "__main__":
pipeline = OSMOPipeline(OSMO_WORKFLOW)

# 提交
wf_id = pipeline.submit()

# 成本估算
estimate = pipeline.estimate_cost(num_scenes=50, augmentation=10)
print(f"\n=== 50场景 × 10x增强 成本估算 ===")
print(f"总样本数: {estimate['total_samples']:,}")
print(f"GPU小时: {estimate['gpu_hours']}")
print(f"总成本: ${estimate['estimated_cost_usd']:.2f}")
print(f"每样本成本: ${estimate['cost_per_sample']:.6f}")

print(f"\n=== 管道阶段 ===")
for stage in pipeline.stages:
print(f" {stage}")

2. NuRec:3D 环境重建

特性 说明 座舱应用
输入 智能手机/传感器原始数据 手机扫描真实座舱
输出 OpenUSD 格式 3D 场景 可直接加载到 Isaac Sim
渲染方式 NeRF + 3DGS + 3DGUT 高保真座舱重建
API OmniNuRecVolumeAPI 程序化控制渲染参数
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
"""
NuRec 座舱重建流程
将真实座舱数字化为 OpenUSD 格式仿真环境

应用场景:
1. 重建真实车辆座舱 → 在仿真中生成训练数据
2. 多车型座舱数字化 → 跨车型数据覆盖
3. 特定场景重建(事故现场)→ 罕见场景数据生成
"""

import numpy as np

class NuRecCabinReconstructor:
"""
NuRec 座舱重建器

工作流:
1. 多角度手机视频拍摄座舱
2. NuRec 神经渲染重建 3D 场景
3. 导出为 OpenUSD 格式
4. 在 Isaac Sim 中加载并配置
"""

def __init__(self, config: dict):
self.reconstruction_method = config.get('method', '3dgut') # 3DGS/NeRF/3DGUT
self.quality = config.get('quality', 'high') # low/medium/high
self.output_format = 'usd' # OpenUSD

def capture_guide(self, vehicle_type: str = 'sedan') -> dict:
"""
生成座舱拍摄指南

不同车型需要不同的拍摄路径
"""
guides = {
'sedan': {
'captures': 40,
'paths': [
'driver_seat_360',
'passenger_seat_360',
'rear_left_360',
'rear_right_360',
'dashboard_pan',
'headliner_pan',
'floor_pan',
],
'duration_min': 8,
'tips': '确保覆盖所有角度,包括脚部和顶部'
},
'suv': {
'captures': 55,
'paths': [
'driver_seat_360',
'passenger_seat_360',
'rear_left_360',
'rear_center_360',
'rear_right_360',
'third_row_360',
'dashboard_pan',
'headliner_pan',
'floor_pan',
],
'duration_min': 12,
}
}
return guides.get(vehicle_type, guides['sedan'])

def reconstruct(self, capture_data_path: str) -> dict:
"""
执行 3D 重建

返回重建质量和场景信息
"""
# NuRec 命令
# nurec ingest --input <data_path>
# nurec reconstruct --method 3dgut --quality high
# nurec export --format usd --output scene.usd

return {
'output_file': 'cabin_scene.usd',
'reconstruction_method': self.reconstruction_method,
'quality_score': 0.92, # 0-1
'coverage': 0.88, # 0-1, 座舱覆盖率
'file_size_mb': 450,
'gpu_hours': 2.5,
'loadable_in_isaac': True,
}

3. MobilityGen:自动轨迹生成

特性 说明 座舱应用
地图构建 占用栅格地图 座舱空间地图
轨迹生成 无碰撞路径 乘员动作轨迹
记录方式 键盘/手柄遥控 + 自动路径 手动设定行为模式
传感器输出 RGB + 深度 + 语义分割 DMS/OMS 多模态数据
支持机器人 H1人形、Spot、Carter 可扩展为虚拟乘员
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
"""
MobilityGen 座舱数据生成
基于 Isaac Sim 生成多行为模式的座舱感知数据

核心价值:
1. 自动生成多样化驾驶行为数据(疲劳/分心/正常)
2. 多角度、多光照条件
3. Ground truth 自动标注(无需人工标注)
4. 10x-100x 成本降低 vs 真实数据采集
"""

import numpy as np
from dataclasses import dataclass
from typing import List

@dataclass
class CabinBehavior:
"""座舱行为定义"""
name: str
duration_sec: int
description: str
head_movement: str # 'normal', 'drowsy', 'distracted', 'aggressive'
body_movement: str # 'still', 'fidgeting', 'reaching'
eye_state: str # 'open', 'closing', 'closed', 'rapid_blink'
hand_state: str # 'on_wheel', 'phone', 'off_wheel', 'gesturing'
passenger_count: int = 1
passenger_types: list = None # ['adult_male', 'child_5yo', 'infant']

class CabinMobilityGenerator:
"""
座舱 MobilityGen 生成器

生成 IMS 训练数据:
- DMS: 驾驶员面部、眼动、头部姿态
- OMS: 乘员检测、姿态、安全带
- CPD: 后排儿童检测
"""

# 预定义行为库
BEHAVIOR_LIBRARY = {
'normal_driving': CabinBehavior(
name='normal_driving',
duration_sec=300,
description='正常驾驶,视线前方,偶尔看后视镜',
head_movement='normal',
body_movement='still',
eye_state='open',
hand_state='on_wheel',
passenger_count=1,
passenger_types=['adult_male']
),
'fatigue_level_1': CabinBehavior(
name='fatigue_level_1',
duration_sec=180,
description='轻度疲劳,眨眼频率增加,偶尔打哈欠',
head_movement='normal',
body_movement='still',
eye_state='rapid_blink',
hand_state='on_wheel',
),
'fatigue_level_2': CabinBehavior(
name='fatigue_level_2',
duration_sec=120,
description='中度疲劳,PERCLOS升高,点头',
head_movement='drowsy',
body_movement='still',
eye_state='closing',
hand_state='on_wheel',
),
'fatigue_level_3': CabinBehavior(
name='fatigue_level_3',
duration_sec=60,
description='严重疲劳,微睡眠,头部下垂',
head_movement='drowsy',
body_movement='still',
eye_state='closed',
hand_state='on_wheel',
),
'phone_use_texting': CabinBehavior(
name='phone_use_texting',
duration_sec=60,
description='低头看手机打字,视线离开前方',
head_movement='distracted',
body_movement='still',
eye_state='open',
hand_state='phone',
),
'phone_use_calling': CabinBehavior(
name='phone_use_calling',
duration_sec=120,
description='手持电话通话,单手方向盘',
head_movement='distracted',
body_movement='still',
eye_state='open',
hand_state='phone',
),
'child_rear_normal': CabinBehavior(
name='child_rear_normal',
duration_sec=300,
description='后排儿童正常坐姿',
head_movement='normal',
body_movement='fidgeting',
eye_state='open',
hand_state='off_wheel',
passenger_count=2,
passenger_types=['adult_male', 'child_5yo']
),
'child_rear_sleeping': CabinBehavior(
name='child_rear_sleeping',
duration_sec=600,
description='后排儿童睡着',
head_movement='drowsy',
body_movement='still',
eye_state='closed',
hand_state='off_wheel',
passenger_count=2,
passenger_types=['adult_male', 'child_5yo']
),
'infant_rear_facing': CabinBehavior(
name='infant_rear_facing',
duration_sec=600,
description='后排反向安全座椅中的婴儿',
head_movement='normal',
body_movement='still',
eye_state='open',
hand_state='off_wheel',
passenger_count=2,
passenger_types=['adult_male', 'infant']
),
'passenger_reclined': CabinBehavior(
name='passenger_reclined',
duration_sec=300,
description='副驾斜躺姿态(OOP场景)',
head_movement='drowsy',
body_movement='still',
eye_state='closed',
hand_state='off_wheel',
passenger_count=2,
passenger_types=['adult_male', 'adult_female']
),
}

def generate_dataset(self, behavior_names: List[str],
sensors: List[str],
variations: dict) -> dict:
"""
生成训练数据集

Args:
behavior_names: 行为列表
sensors: 传感器列表 ['camera', 'radar', 'ir']
variations: 变化参数 {
'lighting': ['day', 'night', 'tunnel'],
'interior_color': ['black', 'beige', 'gray'],
'driver_gender': ['male', 'female'],
'driver_age': ['young', 'middle', 'elderly'],
}

Returns:
dataset_info
"""
total_clips = 0
total_frames = 0
estimated_size_gb = 0

for behavior_name in behavior_names:
behavior = self.BEHAVIOR_LIBRARY.get(behavior_name)
if not behavior:
continue

# 变化组合数
num_variations = 1
for key, vals in variations.items():
num_variations *= len(vals)

# 每个行为在每个变化下的片段数
clips_per_variation = 10 # 可调
clips = clips_per_variation * num_variations
frames = clips * behavior.duration_sec * 30 # 30fps

total_clips += clips
total_frames += frames

# 估算大小(每帧 ~2MB for RGB+Depth+IR)
size_gb = frames * 2 / 1024

return {
'behaviors': behavior_names,
'sensors': sensors,
'total_clips': total_clips,
'total_frames': total_frames,
'estimated_size_gb': total_frames * 2 / (1024**3),
'gpu_hours': total_clips * 0.05, # ~3min per clip
'auto_labeled': True,
'ground_truth': ['face_bbox', 'landmarks', 'gaze_vector',
'body_pose', 'occupant_class', 'belt_status'],
}


# 测试
if __name__ == "__main__":
gen = CabinMobilityGenerator()

print("=== 可用行为库 ===")
for name, behavior in gen.BEHAVIOR_LIBRARY.items():
print(f" {name}: {behavior.description}")

# 生成数据集
behaviors = [
'normal_driving',
'fatigue_level_1', 'fatigue_level_2', 'fatigue_level_3',
'phone_use_texting', 'phone_use_calling',
'child_rear_normal', 'child_rear_sleeping',
'infant_rear_facing',
'passenger_reclined',
]

sensors = ['camera', 'radar', 'ir']
variations = {
'lighting': ['day', 'night', 'tunnel', 'sunset'],
'interior_color': ['black', 'beige'],
'driver_gender': ['male', 'female'],
'driver_age': ['young', 'middle', 'elderly'],
}

dataset = gen.generate_dataset(behaviors, sensors, variations)

print(f"\n=== 数据集估算 ===")
print(f"行为数: {len(behaviors)}")
print(f"传感器: {sensors}")
print(f"变化组合: {4*2*2*3} = 48")
print(f"总片段: {dataset['total_clips']:,}")
print(f"总帧数: {dataset['total_frames']:,}")
print(f"估计大小: {dataset['estimated_size_gb']:.1f} GB")
print(f"GPU小时: {dataset['gpu_hours']:.1f}")
print(f"自动标注: {'是' if dataset['auto_labeled'] else '否'}")
print(f"Ground truth: {dataset['ground_truth']}")

4. Cosmos WFM:世界基础模型增强

增强维度 说明 座舱应用
光照变化 白天/夜晚/隧道/逆光 DMS 全光照条件训练
内饰颜色 黑/米/灰/红 跨车型泛化
乘员外观 性别/年龄/肤色/发型 多样性
着装变化 帽子/墨镜/口罩/围巾 遮挡鲁棒性
天气 雨/雪/雾(通过车窗) 环境鲁棒性

与传统数据采集对比

维度 真实数据采集 OSMO + MobilityGen 管道
成本/样本 $0.50-2.00 $0.002-0.01
标注 人工 $0.10-0.50/帧 自动(ground truth)
场景覆盖 受限于采集路线 任意行为×环境组合
罕见场景 极难采集(事故/极端疲劳) 可任意生成
多传感器 需要多车多设备 一次仿真多传感器输出
隐私 需要知情同意 无隐私问题
多样性 受限于地区/人群 全球化外观变化
迭代速度 周/月级 小时级

IMS 开发落地路径

Phase 1: 基础数据生成(1-2月)

任务 工具 输出 人力
座舱场景搭建 Isaac Sim + SimReady 3种车型座舱场景 1人×2周
基础行为库 MobilityGen 10种核心行为×1000片段 1人×1周
基础训练集 OSMO + Cosmos 50K标注帧 自动
模型基线验证 PyTorch DMS/OMS 基线模型 1人×1周

Phase 2: 场景扩展(3-4月)

任务 输出 人力
50种行为模式扩展 200K标注帧 1人×3周
多车型座舱重建 10种车型 1人×2周
极端场景生成 遮挡/多乘员/异常姿态 1人×2周
Cosmos 增强优化 500K增强帧 自动

Phase 3: 持续生产(5-6月+)

任务 输出 频率
每日数据增量 5K-10K 新帧 持续
新行为模式 按需 按需
跨车型适配 新车型座舱 按需
模型迭代训练 更新模型 每周

结论

NVIDIA 的 OSMO + MobilityGen + NuRec + Cosmos 管道为 IMS 训练数据生产提供了工业级解决方案:

  1. 成本降低 100-500x:$0.002/帧 vs $0.50/帧
  2. 场景覆盖无遗漏:任何行为×环境组合可生成
  3. 标注自动化:仿真 ground truth 直接导出
  4. 隐私零风险:无真实人物数据
  5. 可复现:YAML 定义管道,版本管理
  6. 可扩展:云端 GPU 弹性扩展

对于 IMS 开发团队,建议立即启动 Phase 1 基础数据生成,利用 NVIDIA 的开源工具链降低数据成本,同时保持真实数据采集用于验证和域适配。


参考来源: