FantasyWorld:几何一致的世界建模
1. 背景与动机
当前视频生成模型面临的核心问题是几何不一致:生成的长视频中,物体会出现诡异的形变、消失或位置漂移。这源于:
- 缺乏显式 3D 表示:纯 2D 生成缺乏空间理解
- 时序一致性差:每帧独立生成,忽视 3D 结构
- 物理规律缺失:不遵循基本的几何和物理约束
FantasyWorld1 由斯坦福大学李飞飞团队提出,首次实现几何一致的世界建模,在 WorldScore Leaderboard 上取得第一名的成绩。
2. 核心思想
2.1 问题定义
FantasyWorld 追求的是几何一致的 3D 世界建模:
给定初始条件,生成在几何、物理和视觉上保持一致的时空序列
关键要求:
- 空间一致性:物体形状和位置在时间上保持稳定
- 透视一致性:相机运动和物体相对位置正确
- 遮挡一致性:物体间的前后关系正确维护
2.2 核心洞察
FantasyWorld 的核心洞察是:视频 + 深度 + 点云 + 相机轨迹的联合建模比单独建模更有效。
传统方法要么只生成视频,要么分别生成各模态。FantasyWorld 在单一框架中同时输出:
- 视频帧序列
- 深度图序列
- 3D 点云序列
- 相机轨迹参数
3. 技术架构
3.1 整体架构
输入条件 (文本/图像/动作)
↓
┌─────────────────────────────────────┐
│ 冻结视频骨干 (Wan2.1) │
│ │
│ ┌─────────┐ 交叉注意力 ┌─────┐ │
│ │ 视频分支 │ ←───────────→ │几何分支│ │
│ └────┬────┘ 融合信息 └──┬──┘ │
│ ↓ ↓ │
│ 视频输出 几何输出 │
└─────────────────────────────────────┘
↓
┌─────────────────────────────────────┐
│ 几何约束解码器 │
│ - 深度估计头 │
│ - 点云生成头 │
│ - 相机轨迹头 │
└─────────────────────────────────────┘
3.2 视频分支 (Video Branch)
使用冻结的视频扩散模型作为骨干:
class VideoBranch(nn.Module):
"""视频生成分支 - 冻结预训练模型"""
def __init__(self, model_path):
super().__init__()
# 加载预训练视频扩散模型 (Wan2.1)
self.model = load_pretrained_video_diffusion(model_path)
# 冻结参数
for param in self.model.parameters():
param.requires_grad = False
def forward(self, condition, latent_video):
"""
Args:
condition: 文本/图像条件
latent_video: 初始噪声
Returns:
video_features: 视频特征用于后续融合
"""
features = self.model.extract_features(latent_video, condition)
return features为什么冻结?
- 避免灾难性遗忘:保留预训练的视频质量
- 减少训练成本
- 专注于几何一致性学习
3.3 几何分支 (Geometry Branch)
几何分支是可训练的,负责任务:
class GeometryBranch(nn.Module):
"""几何建模分支"""
def __init__(self, feature_dim=1024):
super().__init__()
# 深度估计头
self.depth_head = nn.Sequential(
nn.Linear(feature_dim, 256),
nn.ReLU(),
nn.Linear(256, 1) # 深度值
)
# 点云生成头
self.pointcloud_head = nn.Sequential(
nn.Linear(feature_dim, feature_dim),
nn.ReLU(),
nn.Linear(feature_dim, 3072) # 1024 points × 3 coords
)
# 相机轨迹头
self.camera_head = nn.Sequential(
nn.Linear(feature_dim, 256),
nn.ReLU(),
nn.Linear(256, 7) # [tx, ty, tz, rx, ry, rz, f]
)
def forward(self, fused_features):
depth = self.depth_head(fused_features)
pointcloud = self.pointcloud_head(fused_features)
camera = self.camera_head(fused_features)
return {
'depth': depth,
'pointcloud': pointcloud,
'camera': camera
}3.4 交叉注意力融合
视频分支和几何分支通过交叉注意力机制交互:
class CrossAttentionFusion(nn.Module):
"""交叉注意力融合模块"""
def __init__(self, video_dim, geo_dim, num_heads=8):
super().__init__()
self.video_proj = nn.Linear(video_dim, geo_dim)
self.geo_proj = nn.Linear(geo_dim, geo_dim)
self.cross_attn = nn.MultiheadAttention(geo_dim, num_heads)
self.norm = nn.LayerNorm(geo_dim)
def forward(self, video_features, geo_features):
"""
双向交叉注意力:视频特征 → 几何特征 → 视频特征
"""
# 投影到统一维度
V = self.video_proj(video_features) # [T, B, D]
G = self.geo_proj(geo_features) # [T, B, D]
# 视频 → 几何:帮助几何理解语义内容
G_attended, _ = self.cross_attn(G, V, V)
G_fused = self.norm(G + G_attended)
# 几何 → 视频:注入几何约束
V_attended, _ = self.cross_attn(V, G_fused, G_fused)
V_fused = self.norm(V + V_attended)
return V_fused, G_fused3.5 几何约束损失
FantasyWorld 的训练损失包含多个几何约束项:
深度一致性损失
最后两项是深度图的平滑正则。
点云几何损失
其中 是 Chamfer 距离。
相机轨迹损失
其中 是相机运动增量。
总损失
4. 技术细节
4.1 相机参数编码
FantasyWorld 使用 Plücker 坐标 编码相机射线:
def plucker_coordinates(camera_pose, pixel_coords):
"""
生成 Plücker 坐标
Args:
camera_pose: [tx, ty, tz, rx, ry, rz] 相机位姿
pixel_coords: [u, v] 像素坐标
Returns:
plucker: [6] Plücker 坐标
"""
# 相机内参
K = torch.tensor([[fx, 0, cx], [0, fy, cy], [0, 0, 1]])
# 射线方向
ray_dir = K.inverse() @ [u, v, 1]
ray_dir = ray_dir / (ray_dir.norm() + 1e-8)
# 相机中心
center = camera_pose[:3]
# Plücker: (d, d × c)
plucker = torch.cat([ray_dir, torch.cross(ray_dir, center)])
return plucker4.2 3D 点生成
def depth_to_pointcloud(depth_map, camera_intrinsics, camera_extrinsics):
"""
从深度图生成点云
Args:
depth_map: [H, W] 深度图
camera_intrinsics: 相机内参矩阵
camera_extrinsics: 相机外参矩阵
Returns:
points: [N, 3] 3D 点坐标
"""
H, W = depth_map.shape
u, v = torch.meshgrid(torch.arange(W), torch.arange(H))
# 反投影到相机坐标系
x = (u - camera_intrinsics[0, 2]) * depth_map / camera_intrinsics[0, 0]
y = (v - camera_intrinsics[1, 2]) * depth_map / camera_intrinsics[1, 1]
z = depth_map
points_cam = torch.stack([x, y, z], dim=-1) # [H, W, 3]
points_cam = points_cam.reshape(-1, 3)
# 变换到世界坐标系
R, t = camera_extrinsics[:3, :3], camera_extrinsics[:3, 3]
points_world = points_cam @ R.T + t
return points_world4.3 时序一致性建模
为保证长视频的几何一致性,FantasyWorld 使用时序几何 Transformer:
class TemporalGeometryTransformer(nn.Module):
"""时序几何一致性模块"""
def __init__(self, dim, num_frames=16, num_layers=4):
super().__init__()
self.layers = nn.ModuleList([
TemporalGeometryLayer(dim) for _ in range(num_layers)
])
def forward(self, geometry_features, frame_offsets):
"""
Args:
geometry_features: [T, B, D] 各帧的几何特征
frame_offsets: [T] 时间偏移
"""
for layer in self.layers:
geometry_features = layer(
geometry_features,
frame_offsets
)
return geometry_features
class TemporalGeometryLayer(nn.Module):
"""时序几何层"""
def __init__(self, dim):
super().__init__()
self.temporal_attn = nn.MultiheadAttention(dim, num_heads=8)
self.geo_mlp = nn.Sequential(
nn.Linear(dim, dim * 4),
nn.GELU(),
nn.Linear(dim * 4, dim)
)
self.norm = nn.LayerNorm(dim)
def forward(self, features, offsets):
# 时间偏移编码
offset_emb = self.get_offset_embedding(offsets)
features = features + offset_emb
# 时序注意力
out, _ = self.temporal_attn(features, features, features)
features = self.norm(features + out)
# 几何 MLP
features = self.norm(features + self.geo_mlp(features))
return features5. 实验结果
5.1 WorldScore Leaderboard
| 方法 | WorldScore ↑ | 视频质量 | 3D 一致性 | 物理合理性 |
|---|---|---|---|---|
| WorldDreamer | 72.3 | 85.1 | 58.2 | 73.6 |
| DreamWorld | 75.8 | 84.3 | 67.5 | 75.6 |
| OpenWorld | 74.1 | 82.5 | 65.8 | 74.0 |
| FantasyWorld | 81.2 | 86.7 | 78.4 | 78.5 |
5.2 几何一致性评估
| 方法 | Depth Error ↓ | PC Chamfer ↓ | 相机轨迹 Error ↓ |
|---|---|---|---|
| Wan2.1 (baseline) | 0.182 | 0.245 | 0.089 |
| DreamWorld | 0.145 | 0.198 | 0.072 |
| FantasyWorld | 0.098 | 0.134 | 0.041 |
5.3 消融实验
| 配置 | WorldScore ↑ |
|---|---|
| 完整模型 | 81.2 |
| - 几何分支 | 74.5 (-6.7) |
| - 交叉注意力 | 77.8 (-3.4) |
| - 相机轨迹头 | 79.1 (-2.1) |
| - 时序几何 Transformer | 76.3 (-4.9) |
6. 与 DreamWorld 的对比
| 维度 | DreamWorld | FantasyWorld |
|---|---|---|
| 核心目标 | 语义/运动/物理知识统一 | 几何一致性 |
| 输出 | 视频 + 世界知识 | 视频 + 深度 + 点云 + 相机轨迹 |
| 方法 | 三分支自适应融合 | 双分支交叉注意力 |
| 侧重点 | 知识表示 | 空间结构 |
| 评估 | 物理合理性 | 3D 几何精度 |
| 训练策略 | 三阶段渐进训练 | 冻结骨干 + 几何分支训练 |
互补性:两者可以结合使用,DreamWorld 提供语义理解,FantasyWorld 提供几何约束。
7. 应用场景
7.1 机器人仿真数据生成
- 生成几何精确的室内/室外场景
- 提供相机轨迹用于定位训练
7.2 自动驾驶仿真
- 生成多视角一致的街景视频
- 提供深度和点云用于感知训练
7.3 增强现实内容创作
- 从文本描述生成 3D 一致的场景
- 直接用于 AR 场景构建
8. 局限性
8.1 当前局限
- 计算成本较高(双分支推理)
- 依赖冻结骨干的视频质量
- 对极端几何结构的处理有待提升
8.2 未来方向
- 端到端联合训练
- 动态物体建模
- 物理约束的显式注入
9. 总结
FantasyWorld 通过视频分支和几何分支的交叉注意力融合,首次实现了:
- 几何一致的世界建模
- 单次前向的多模态输出(视频+深度+点云+相机)
- 冻结骨干的稳定训练策略
这一工作为构建更精确的世界模型提供了新的技术路径。
参考资料
- FantasyWorld: Geometry-Consistent World Modeling via Unified Video and 3D Prediction (ICLR 2026)
- WorldScore Leaderboard: https://worldscore.stanford.edu/
Footnotes
-
FantasyWorld: Geometry-Consistent World Modeling via Unified Video and 3D Prediction (ICLR 2026) ↩