04. 深度数据工程:合成数据与自动标注 (The Data Bible)
"Data is the new Code." 本章将数据工程提升到战略高度,详细拆解如何构建一个"自生长"的数据闭环。
4.1 数据管线全景图 (Data Pipeline Overview)
从 UE 引擎到 WebDataset 分片,我们需要经过三个核心阶段:采集 (Recording) -> 标注 (Re-captioning) -> 打包 (Sharding)。
flowchart TD
subgraph UE5 [Phase 1: 虚拟仿真]
Engine[Unreal Engine 5]
Agent[RL Agent / Script]
Engine -->|Raw Video + Action| RawData[Raw MP4 + JSON]
end
subgraph VLM [Phase 2: 语义增强 Crucial]
RawData -->|Sample Frames| Frames[Key Frames]
Frames -->|Prompt: Describe this scene| GPT4V[VLM - GPT4o / Gemini]
GPT4V -->|Dense Caption| Caption[Detailed Text Description]
end
subgraph ETL [Phase 3: 清洗与分片]
RawData -->|Merge| Caption
Caption -->|Filter| CleanData
CleanData -->|WebDataset| Shards[Tar Shards 000.tar]
end
4.2 核心策略 1:VLM 自动标注 (Re-captioning)
OpenAI Sora 的核心秘密在于训练数据使用了极高质量的 Machine-Generated Captions。我们必须复刻这一过程。
为什么需要?
UE 导出的 JSON 只有 Jump, Run 等离散动作,缺乏语义(如 "A cyberpunk city in
rain")。没有文本语义,模型就无法响应 Text Prompt。
自动标注脚本 (Auto-Labeling Pipeline)
# auto_caption.py
def generate_dense_caption(video_path):
"""
使用 VLM 生成 Sora 级别的详细描述。
"""
frames = sample_frames(video_path, num=5) # 抽5帧
prompt = """
Describe this video clip in extreme detail. Focus on:
1. The environment (lighting, textures, weather).
2. The main character (apparel, movement).
3. The camera movement (pan, tilt, zoom).
4. The physics interactions (fluids, particles).
Output format: A single dense paragraph.
"""
# 模拟调用 Gemini Vision / GPT-4V
caption = call_vlm_api(frames, prompt)
return caption
# 示例输出:
# "A first-person view navigating a dimly lit cavern. The walls are covered in
# bio-luminescent moss emitting a faint blue glow. The camera shakes violently
# as the character sprints forward, jumping over a chasm..."
4.3 核心策略 2:WebDataset 高性能分片
痛点: 100 万个 MP4 文件会导致文件系统索引崩溃(Inode Exhaustion)。
解法: 使用
WebDataset 将数据打包成
1GB 左右的 .tar 包。
目录结构规范
dataset_optimized/
├── shard_00000.tar # 包含 1000 个视频 (video_0.mp4, video_0.json, video_0.txt)
├── shard_00001.tar
└── ...
JSON Schema (Metadata)
每个视频伴随的 .json 文件必须严格定义:
{
"clip_id": "ue_level3_run05_001",
"duration": 5.0,
"fps": 24,
"resolution": [1280, 720],
"camera": {
"fov": 90,
"intrinsics": [ [500, 0, 640], [0, 500, 360], [0, 0, 1] ]
},
"controls": {
"input_type": "keyboard_mouse",
"action_sequence": [
{"frame": 0, "keys": ["W"], "mouse_delta": [0, 0]},
{"frame": 1, "keys": ["W", "Space"], "mouse_delta": [10, -5]}
]
},
"caption": "A detailed description generated by VLM...",
"quality_score": 0.95
}
4.4 核心策略 3:基于状态机的样本平衡 (Balancing)
在 UE 采集端,不要随机乱跑。编写一个 State Machine Bot 来保证样本多样性。
建议分布:
- Exploration (50%): 走路、跑步、看风景。这是构建世界观的基础。
- Interaction (30%): 开门、捡东西、破坏物体。学习物理规律。
- Idle (10%): 站立不动,观察环境动态(云的飘动、水的流动)。
- Combat/Extreme (10%): 剧烈运动、特效爆炸。防止模型在动态场景崩坏。
4.5 核心代码逻辑:C++ Recorder 插件更新
// URecorderComponent.cpp (Enhanced)
void URecorderComponent::TickComponent(...) {
// ... [RGB & Depth Capture 代码同上] ...
// 获取当前 Bot 状态 (用于数据集平衡分析)
FString CurrentState = BotAIController->GetStateName(); // e.g., "Combat"
// 序列化,增加语义标签
FString MetaJson = FString::Printf(TEXT(
"{\"t\": %.3f, \"state\": \"%s\", \"action\": ...}"
), Timestamp, *CurrentState);
// 只有当画面变化幅度 > 阈值 OR 处于关键交互时才保存
// 避免存储大量无意义的静止画面 (Dedup)
if (IsSignificantFrame(RGB_Data)) {
DiskWriter->Write(RGB_Data, MetaJson);
}
}
4.6 避坑指南 (Best Practices)
- VLM 成本控制: 跑一遍 1200 小时视频的 VLM 标注非常贵。建议:关键帧标注 (每 2 秒抽 1 帧做 VLM),中间帧沿用上一关键帧的 Caption (插值)。
- Gamma 校正陷阱: UE RenderTarget 默认是 Linear Space。导出 JPG/PNG 时务必手动做 Gamma 2.2 Correction,否则视频会惨白。
- FOV 锁定: 训练时尽量固定 FOV (e.g., 90度)。如果 FOV 乱变,模型很难学得会空间透视。
4.7 最新增量:用“游戏 Glitch”做物理常识反例数据(PhysGame)
如果你想让模型具备更强的物理常识(哪里违反物理、哪些现象不合理),传统数据要么标注贵、要么仿真不真实。Order from Chaos (arXiv:2601.16471) 提出了一条很实用的“数据工程”路线:利用 gameplay videos 里的glitch(物理/渲染异常)作为可规模化监督源,构建 PhysGame QA 数据集。
- PhysGame:140,057 条 glitch-centric QA,覆盖 5 个物理域、16 个细分类别。[来源]
- GameBench:880 条专家标注评测视频,用于验证“是否真的更会找物理不合理”。[来源]
- Meta-guided prompting:利用标题/描述等 metadata 指导 QA 生成,降低自动生成的物理胡编概率。[来源]
flowchart TD
A[Gameplay Videos] --> B[Glitch 片段挖掘/筛选]
A --> M[Metadata: title/description]
B --> P[Meta-guided Prompting]
M --> P
P --> Q[自动生成 QA 对]
Q --> T[Instruction Tuning: MLLM/VLM]
T --> E[评测: GameBench/PhysBench/MVBench]
这条路线的“工程含金量”在于把物理常识训练从“正例描述”转向“反例诊断”:glitch 让“违反物理”变成可见信号。但一定要把 domain gap 当成一等公民:游戏 glitch 的分布可能过度集中在渲染/碰撞实现细节,迁移到真实世界需要明确的失效分析与再采样策略。
严正警告: 不要用 Screen Capture!因为录屏会录到 Windows 弹窗、鼠标光标、Steam 帧数显示,这些都是"污染"。一定要用 Unreal Engine 的
USceneCaptureComponent2D进行纯净的 Off-screen Rendering。