EvoWorld:全景世界生成与3D记忆

1. 背景与动机

人类拥有惊人的空间记忆能力:可以回忆并”重放”曾经访问过的 3D 环境。这种能力对于构建真正理解物理世界的 AI 系统至关重要。

现有视频生成模型:

  • 缺乏空间理解:只生成 2D 帧序列
  • 缺乏持久性:无法”记住”已生成的空间结构
  • 缺乏探索能力:无法主动”环顾”场景

EvoWorld1 首次实现全景世界生成,通过显式 3D 记忆机制,让 AI 模型能够:

  • 生成 360 度全景视频
  • 在空间中进行”导航”
  • 保持跨视角的空间一致性

2. 核心思想

2.1 3D 记忆机制

EvoWorld 的核心创新是显式 3D 记忆

class Explicit3DMemory:
    """显式 3D 记忆模块"""
    
    def __init__(self, memory_size=(100, 100, 50)):
        super().__init__()
        # 3D 特征网格
        self.memory_grid = nn.Parameter(
            torch.randn(*memory_size, feature_dim)
        )
        
        # 可见性掩码
        self.visibility = torch.zeros(*memory_size, dtype=torch.bool)
        
        # 更新机制
        self.memory_update = MemoryUpdateBlock()
    
    def observe(self, features, depth, camera_pose):
        """
        将新的观察融入记忆
        
        Args:
            features: 2D 特征图
            depth: 深度图
            camera_pose: 相机位姿 [tx, ty, tz, rx, ry, rz]
        """
        # 反投影到 3D
        points_3d = self.backproject(features, depth, camera_pose)
        
        # 3D 卷积更新
        updated = self.memory_update(self.memory_grid, points_3d, features)
        
        # 更新可见性
        self.update_visibility(points_3d)
        
        return updated
    
    def query(self, camera_pose):
        """
        从指定视角查询记忆
        
        Args:
            camera_pose: 目标相机位姿
        Returns:
            features: 渲染的特征
        """
        # 射线投射查询
        rays = self.create_rays(camera_pose)
        
        # 体积渲染
        features = self.volume_render(self.memory_grid, rays)
        
        return features

2.2 全景表示

EvoWorld 使用等距圆柱投影 (Equirectangular Projection) 表示 360 度内容:

传统相机:     全景相机:
┌─────────┐    ┌─────────┐
│  90°    │    │ 360°    │
│ ┌─────┐ │    │         │
│ │ 45° │ │    │   全    │
│ └─────┘ │    │   景    │
│  -45°   │    │   图    │
└─────────┘    └─────────┘

3. 技术架构

3.1 整体架构

文本/图像输入
        ↓
┌─────────────────────────────────────┐
│         3D 记忆编码器                │
│  ┌────────────────────────────────┐ │
│  │ 记忆查询 (从已有记忆中检索)      │ │
│  │ 记忆更新 (融入新观察)            │ │
│  │ 记忆生成 (生成新空间)            │ │
│  └────────────────────────────────┘ │
└────────────────┬────────────────────┘
                 ↓
┌─────────────────────────────────────┐
│      全景视频扩散 (Panorama DiT)     │
│  - 360 度空间注意力                 │
│  - 深度感知生成                     │
└────────────────┬────────────────────┘
                 ↓
         全景视频输出

3.2 3D 记忆模块

class MemoryBlock3D(nn.Module):
    """3D 记忆块"""
    
    def __init__(self, grid_size, feature_dim):
        super().__init__()
        
        # 3D 卷积 backbone
        self.conv3d = nn.Sequential(
            nn.Conv3d(feature_dim, feature_dim*2, 3, padding=1),
            nn.GroupNorm(8, feature_dim*2),
            nn.GELU(),
            nn.Conv3d(feature_dim*2, feature_dim, 3, padding=1),
        )
        
        # 记忆门控
        self.gate = nn.Sequential(
            nn.Linear(feature_dim, feature_dim),
            nn.Sigmoid()
        )
    
    def forward(self, memory, observation, mask):
        """
        Args:
            memory: [B, D, H, W, L] 当前记忆
            observation: [B, D, H, W] 新观察
            mask: [B, H, W] 可见性掩码
        """
        # 扩展观察以匹配记忆维度
        obs_expanded = observation.unsqueeze(-1).expand(-1, -1, -1, -1, memory.shape[4])
        
        # 选择性更新
        gate_value = self.gate(observation.mean(dim=(1,2), keepdim=True))
        memory_update = self.conv3d(torch.cat([memory, obs_expanded], dim=1))
        
        # 门控更新
        memory = memory + gate_value * memory_update * mask.unsqueeze(1).unsqueeze(-1)
        
        return memory

3.3 全景注意力

全景视频的特殊几何需要特殊的注意力机制:

class PanoramicAttention(nn.Module):
    """全景注意力 - 考虑球面几何"""
    
    def __init__(self, dim, num_heads=8):
        super().__init__()
        self.num_heads = num_heads
        self.head_dim = dim // num_heads
        
        # 球面位置编码
        self.spherical_pos_emb = SphericalPositionalEncoding()
        
        # 标准注意力
        self.qkv = nn.Linear(dim, dim * 3)
        self.proj = nn.Linear(dim, dim)
    
    def forward(self, x, coords_3d):
        """
        Args:
            x: [B, T, H, W, C] 全景特征
            coords_3d: [B, T, H, W, 3] 3D 坐标
        """
        B, T, H, W, C = x.shape
        
        # 生成球面位置编码
        sphere_pos = self.spherical_pos_emb(coords_3d)  # [B, T, H, W, C]
        
        # 添加位置信息
        x = x + sphere_pos
        
        # Reshape for attention
        x = x.view(B*T, H*W, C)
        
        # QKV 投影
        qkv = self.qkv(x).reshape(B*T, H*W, 3, self.num_heads, self.head_dim)
        q, k, v = qkv.unbind(2)
        
        # 注意力计算
        attn = (q @ k.transpose(-2, -1)) * (self.head_dim ** -0.5)
        attn = attn.softmax(dim=-1)
        
        # 输出
        out = (attn @ v).reshape(B*T, H*W, C)
        out = self.proj(out).view(B, T, H, W, C)
        
        return out
 
 
class SphericalPositionalEncoding(nn.Module):
    """球面位置编码"""
    
    def __init__(self, num_frequencies=16):
        super().__init__()
        self.num_frequencies = num_frequencies
        
        # 球面调和基
        self.freq_bases = nn.Parameter(
            torch.tensor([2 ** i for i in range(num_frequencies)])
        )
    
    def forward(self, coords_3d):
        """
        Args:
            coords_3d: [B, T, H, W, 3] 归一化的 3D 坐标
        Returns:
            encoding: [B, T, H, W, D] 球面位置编码
        """
        # 转换为球面坐标
        x, y, z = coords_3d[..., 0], coords_3d[..., 1], coords_3d[..., 2]
        
        # θ: 方位角, φ: 俯仰角
        theta = torch.atan2(y, x)  # [-π, π]
        phi = torch.asin(z / torch.norm(coords_3d, dim=-1))  # [-π/2, π/2]
        
        # 频率编码
        theta_enc = torch.cat([
            torch.sin(theta * f) for f in self.freq_bases
        ] + [
            torch.cos(theta * f) for f in self.freq_bases
        ], dim=-1)
        
        phi_enc = torch.cat([
            torch.sin(phi * f) for f in self.freq_bases
        ] + [
            torch.cos(phi * f) for f in self.freq_bases
        ], dim=-1)
        
        # 组合
        encoding = torch.cat([theta_enc, phi_enc], dim=-1)
        
        return encoding

4. 训练策略

4.1 3D 记忆重建损失

确保记忆准确表示 3D 空间:

4.2 全景一致性损失

保证 360 度视角的一致性:

def panoramic_consistency_loss(generated_frames, memory):
    """
    全景一致性损失
    
    检查生成的全景帧是否与 3D 记忆一致
    """
    loss = 0
    
    for frame, camera_pose in zip(generated_frames, camera_poses):
        # 从记忆渲染该视角
        rendered = memory.query(camera_pose)
        
        # 计算一致性
        loss += F.mse_loss(rendered, frame)
    
    return loss

5. 实验结果

5.1 全景生成质量

方法360° FID ↓空间一致性 ↑深度准确性 ↑
2D 视频模型45.20.320.28
+ Equirectangular38.50.410.35
+ EquiConvolutions32.10.520.48
EvoWorld24.80.780.72

5.2 空间导航能力

能力准确率
视角切换一致性91.2%
物体位置保持87.5%
空间探索完整性82.3%

6. 应用场景

6.1 虚拟现实内容创作

  • 从文本生成沉浸式 VR 场景
  • 支持用户 360 度探索

6.2 机器人导航训练

  • 生成室内/室外全景环境
  • 支持不同视角的导航策略学习

6.3 文化遗产数字化

  • 360 度重建历史场景
  • 可交互的虚拟博物馆

7. 与其他方法的对比

特性2D 视频生成World ModelEvoWorld
视角范围固定固定360°
空间记忆部分✅ 完整
导航能力有限✅ 完全
全景一致性

8. 总结

EvoWorld 通过显式 3D 记忆机制实现了:

  1. 全景世界生成:360 度空间一致性
  2. 主动探索:支持空间导航
  3. 持久记忆:跨时间的空间一致性

这一工作为构建真正理解 3D 物理世界的 AI 系统奠定了基础。


参考资料

  • EvoWorld: Evolving Panoramic World Generation with Explicit 3D Memory (ICLR 2026)

Footnotes

  1. EvoWorld: Evolving Panoramic World Generation with Explicit 3D Memory (ICLR 2026)