04. 深度数据工程:合成数据与自动标注 (The Data Bible)

"Data is the new Code." 本章将数据工程提升到战略高度,详细拆解如何构建一个"自生长"的数据闭环。
最后更新时间: 2026-02-02 | 本页内容将每日更新「视频-动作数据的采集/合成/标注与数据 Infra 方案」。

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 来保证样本多样性。

建议分布:

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)

  1. VLM 成本控制: 跑一遍 1200 小时视频的 VLM 标注非常贵。建议:关键帧标注 (每 2 秒抽 1 帧做 VLM),中间帧沿用上一关键帧的 Caption (插值)。
  2. Gamma 校正陷阱: UE RenderTarget 默认是 Linear Space。导出 JPG/PNG 时务必手动做 Gamma 2.2 Correction,否则视频会惨白
  3. FOV 锁定: 训练时尽量固定 FOV (e.g., 90度)。如果 FOV 乱变,模型很难学得会空间透视。
🧠 AntiGravity's Commentary

严正警告: 不要用 Screen Capture!因为录屏会录到 Windows 弹窗、鼠标光标、Steam 帧数显示,这些都是"污染"。一定要用 Unreal Engine 的 USceneCaptureComponent2D 进行纯净的 Off-screen Rendering。

4.7 最新增量:用“游戏 Glitch”做物理常识反例数据(PhysGame)

如果你想让模型具备更强的物理常识(哪里违反物理、哪些现象不合理),传统数据要么标注贵、要么仿真不真实。Order from Chaos (arXiv:2601.16471) 提出了一条很实用的“数据工程”路线:利用 gameplay videos 里的glitch(物理/渲染异常)作为可规模化监督源,构建 PhysGame 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]
            
🧠 AntiGravity's Commentary

这条路线的“工程含金量”在于把物理常识训练从“正例描述”转向“反例诊断”:glitch 让“违反物理”变成可见信号。但一定要把 domain gap 当成一等公民:游戏 glitch 的分布可能过度集中在渲染/碰撞实现细节,迁移到真实世界需要明确的失效分析与再采样策略。