Технології AI Написано практикуючими розробниками

Генеративні World Models: AI, який уявляє майбутнє

Оновлено: 9 хв читання 4 переглядів

Що якщо AI міг би уявити наслідки своїх дій до того, як їх виконає?


Що якщо AI міг би уявити наслідки своїх дій до того, як їх виконає?

Не просто передбачити «наступний кадр». А згенерувати повноцінну симуляцію: що станеться через секунду, хвилину, годину. В деталях. З варіантами. З можливістю «програти» сценарій заново з іншими рішеннями.

Genie від Google. Sora від OpenAI. JEPA від Yann LeCun. Це не просто «відео-генератори». Це world models нового покоління — моделі, які вчаться симулювати реальність в своїй уяві. І це змінює все: від ігор до робототехніки, від autonomous vehicles до наукових досліджень.


Від Video Prediction до Generative World Models

Стара парадигма: Video Prediction (2015-2020)

Вхід: frame_1, frame_2, frame_3
Вихід: frame_4

Проблема: автогресивні помилки накопичуються
Результат: через 10 кадрів — каша

Нова парадигма: Action-Conditioned Generation (2020+)

Вхід: frame_1 + action_1
Вихід: frame_2

Вхід: frame_2 + action_2
Вихід: frame_3

Ключове: модель вчиться динаміці світу, не просто тренду пікселів

Ще новіша парадигма: Latent World Models (2023+)

Encoder: frame → latent state z
Dynamics: z_t + action → z_{t+1}
Decoder: z → frame (тільки коли потрібно візуалізувати)

Перевага: dynamics в compact space, швидше та стабільніше

Genie (Google DeepMind, 2024)

Що це: Foundation world model для інтерактивних 2D середовищ.

Революційна особливість: Навчається БЕЗ action labels. Модель сама виводить, які дії можливі у світі.

Training data: 200,000+ годин відео з YouTube
  - platformer games
  - робототехніка
  - реальні відео

Архітектура:
  1. Video Tokenizer: frame → discrete tokens
  2. Latent Action Model: виводить implicit actions
  3. Dynamics Model: tokens + action → next tokens
  4. Decoder: tokens → frame

Як це працює:

class GenieArchitecture:
    """Спрощена архітектура Genie."""

    def __init__(self):
        # Video Tokenizer (VQ-VAE style)
        self.video_tokenizer = VQEncoder(
            codebook_size=1024,
            token_dim=256
        )

        # Latent Action Model
        # Виводить дії з пар кадрів без supervision
        self.latent_action_model = nn.TransformerEncoder(
            num_layers=6,
            d_model=512,
            nhead=8
        )
        self.action_quantizer = VectorQuantizer(num_actions=8)

        # Dynamics Model (MaskGIT-style)
        self.dynamics = MaskGITTransformer(
            num_layers=12,
            d_model=1024,
            context_length=256  # tokens per frame
        )

    def infer_action(self, frame_t, frame_t1):
        """Виводить latent action між двома кадрами."""
        # Encode обидва кадри
        z_t = self.video_tokenizer.encode(frame_t)
        z_t1 = self.video_tokenizer.encode(frame_t1)

        # Concatenate і пропустити через action model
        combined = torch.cat([z_t, z_t1], dim=-1)
        action_logits = self.latent_action_model(combined)

        # Quantize до discrete actions
        action = self.action_quantizer(action_logits)
        return action

    def generate_next_frame(self, current_tokens, action):
        """Генерує наступний кадр з action."""
        # MaskGIT-style generation
        # Починаємо з повністю masked output
        output_tokens = torch.full_like(current_tokens, MASK_TOKEN)

        # Ітеративно unmask tokens
        for step in range(num_steps):
            # Predict всі tokens
            logits = self.dynamics(current_tokens, action, output_tokens)

            # Sample найвпевненіші predictions
            confidence = logits.softmax(-1).max(-1).values
            num_to_unmask = int((step + 1) / num_steps * num_tokens)

            # Unmask top-k по confidence
            indices = confidence.topk(num_to_unmask).indices
            output_tokens[indices] = logits[indices].argmax(-1)

        return output_tokens

    def play(self, initial_frame, actions):
        """Грати в згенерований світ."""
        tokens = self.video_tokenizer.encode(initial_frame)
        frames = [initial_frame]

        for action in actions:
            tokens = self.generate_next_frame(tokens, action)
            frame = self.video_tokenizer.decode(tokens)
            frames.append(frame)

        return frames

Вражаючі можливості:

  • Zero-shot генерація ігрових світів з одного зображення
  • Можна «грати» у згенеровані світи
  • Узагальнює на стилі, яких не бачив у тренуванні

Обмеження:

  • Тільки 2D середовища
  • 1 FPS (не real-time)
  • Деякі фізичні inconsistencies

Sora (OpenAI, 2024)

Що це: Text-to-video diffusion model з «emergent physics understanding».

Архітектура (на основі публічної інформації):

Input: Text prompt + optional image
Backbone: DiT (Diffusion Transformer)
Training: Spacetime patches (video as 3D tokens)
Output: Up to 60 seconds of 1080p video

World Model чи ні?

Arguments FOR being a world model:
  - Consistent physics: падіння, тіні, відбиття
  - Object permanence: об'єкти не зникають
  - Spatial reasoning: правильна перспектива

Arguments AGAINST:
  - Не action-conditioned (не інтерактивна)
  - Галюцинації у складних сценах
  - Не можна «грати» світ

Справжня цінність: Sora показує, що великі generative models можуть вивчити щось схоже на physical intuition з відео. Це proof-of-concept для справжніх world models.


Архітектура Dreamer (State-of-the-Art для RL)

Dreamer — найуспішніша серія world models для reinforcement learning.

import torch
import torch.nn as nn
import torch.nn.functional as F
import torch.distributions as D

class RSSM(nn.Module):
    """Recurrent State-Space Model — серце Dreamer."""

    def __init__(self, obs_dim, action_dim, hidden_dim=200,
                 deter_dim=200, stoch_dim=30, discrete_dim=32):
        super().__init__()

        # Deterministic state (RNN hidden)
        self.gru = nn.GRUCell(hidden_dim, deter_dim)

        # Prior: p(z_t | h_t) — для imagination
        self.prior_net = nn.Sequential(
            nn.Linear(deter_dim, hidden_dim),
            nn.ELU(),
            nn.Linear(hidden_dim, stoch_dim * discrete_dim * 2)
        )

        # Posterior: q(z_t | h_t, o_t) — для training
        self.posterior_net = nn.Sequential(
            nn.Linear(deter_dim + obs_dim, hidden_dim),
            nn.ELU(),
            nn.Linear(hidden_dim, stoch_dim * discrete_dim * 2)
        )

        # Observation encoder
        self.obs_encoder = nn.Sequential(
            nn.Linear(obs_dim, hidden_dim),
            nn.ELU()
        )

        # Action encoder
        self.action_encoder = nn.Linear(action_dim, hidden_dim)

        self.stoch_dim = stoch_dim
        self.discrete_dim = discrete_dim
        self.deter_dim = deter_dim

    def get_dist(self, params):
        """Створює categorical distribution з параметрів."""
        logits = params.reshape(-1, self.stoch_dim, self.discrete_dim)
        return D.Independent(D.OneHotCategorical(logits=logits), 1)

    def prior(self, deter):
        """Prior distribution p(z|h)."""
        params = self.prior_net(deter)
        return self.get_dist(params)

    def posterior(self, deter, obs_embed):
        """Posterior distribution q(z|h,o)."""
        combined = torch.cat([deter, obs_embed], dim=-1)
        params = self.posterior_net(combined)
        return self.get_dist(params)

    def forward(self, obs, action, prev_state):
        """One step з observation (training mode)."""
        prev_deter, prev_stoch = prev_state

        # Encode action
        action_embed = self.action_encoder(action)

        # Combine previous stoch with action
        x = torch.cat([prev_stoch.flatten(-2), action_embed], dim=-1)

        # Deterministic state update
        deter = self.gru(x, prev_deter)

        # Posterior (using observation)
        obs_embed = self.obs_encoder(obs)
        post = self.posterior(deter, obs_embed)
        stoch = post.rsample()

        # Prior (for KL loss)
        prior = self.prior(deter)

        return (deter, stoch), prior, post

    def imagine(self, action, prev_state):
        """One step БЕЗ observation (imagination mode)."""
        prev_deter, prev_stoch = prev_state

        action_embed = self.action_encoder(action)
        x = torch.cat([prev_stoch.flatten(-2), action_embed], dim=-1)
        deter = self.gru(x, prev_deter)

        # Use prior (no observation!)
        prior = self.prior(deter)
        stoch = prior.rsample()

        return (deter, stoch), prior


class DreamerV3(nn.Module):
    """Повна архітектура DreamerV3."""

    def __init__(self, obs_shape, action_dim, config):
        super().__init__()

        # Image encoder (CNN)
        self.encoder = nn.Sequential(
            nn.Conv2d(obs_shape[0], 32, 4, stride=2),
            nn.ELU(),
            nn.Conv2d(32, 64, 4, stride=2),
            nn.ELU(),
            nn.Conv2d(64, 128, 4, stride=2),
            nn.ELU(),
            nn.Conv2d(128, 256, 4, stride=2),
            nn.ELU(),
            nn.Flatten(),
            nn.Linear(256 * 4 * 4, config.embed_dim)
        )

        # World model
        self.rssm = RSSM(
            obs_dim=config.embed_dim,
            action_dim=action_dim,
            hidden_dim=config.hidden_dim,
            deter_dim=config.deter_dim,
            stoch_dim=config.stoch_dim
        )

        # Decoders
        feature_dim = config.deter_dim + config.stoch_dim * config.discrete_dim

        self.decoder = nn.Sequential(
            nn.Linear(feature_dim, 256 * 4 * 4),
            nn.Unflatten(-1, (256, 4, 4)),
            nn.ConvTranspose2d(256, 128, 4, stride=2, padding=1),
            nn.ELU(),
            nn.ConvTranspose2d(128, 64, 4, stride=2, padding=1),
            nn.ELU(),
            nn.ConvTranspose2d(64, 32, 4, stride=2, padding=1),
            nn.ELU(),
            nn.ConvTranspose2d(32, obs_shape[0], 4, stride=2, padding=1)
        )

        self.reward_head = nn.Sequential(
            nn.Linear(feature_dim, 256),
            nn.ELU(),
            nn.Linear(256, 1)
        )

        self.continue_head = nn.Sequential(
            nn.Linear(feature_dim, 256),
            nn.ELU(),
            nn.Linear(256, 1)
        )

        # Actor-Critic
        self.actor = nn.Sequential(
            nn.Linear(feature_dim, 256),
            nn.ELU(),
            nn.Linear(256, 256),
            nn.ELU(),
            nn.Linear(256, action_dim)
        )

        self.critic = nn.Sequential(
            nn.Linear(feature_dim, 256),
            nn.ELU(),
            nn.Linear(256, 256),
            nn.ELU(),
            nn.Linear(256, 1)
        )

    def get_feature(self, state):
        """Combine deterministic and stochastic state."""
        deter, stoch = state
        return torch.cat([deter, stoch.flatten(-2)], dim=-1)

    def imagine_trajectory(self, initial_state, horizon=15):
        """Imagine future trajectory for actor-critic training."""
        state = initial_state
        features = []
        actions = []
        rewards = []

        for _ in range(horizon):
            feature = self.get_feature(state)
            features.append(feature)

            # Actor вибирає дію
            action_logits = self.actor(feature)
            action_dist = D.Categorical(logits=action_logits)
            action = action_dist.sample()
            actions.append(action)

            # Imagine next state
            action_onehot = F.one_hot(action, self.action_dim).float()
            state, _ = self.rssm.imagine(action_onehot, state)

            # Predict reward
            reward = self.reward_head(self.get_feature(state))
            rewards.append(reward)

        return {
            'features': torch.stack(features),
            'actions': torch.stack(actions),
            'rewards': torch.stack(rewards)
        }

Diffusion World Models

Новий напрямок — використання diffusion models для world model generation.

class DiffusionWorldModel(nn.Module):
    """World model на основі diffusion для кращої якості генерації."""

    def __init__(self, state_dim, action_dim, num_steps=1000):
        super().__init__()
        self.num_steps = num_steps

        # Noise schedule
        self.betas = torch.linspace(1e-4, 0.02, num_steps)
        self.alphas = 1 - self.betas
        self.alpha_cumprod = torch.cumprod(self.alphas, dim=0)

        # Denoising network
        self.denoiser = nn.Sequential(
            nn.Linear(state_dim + action_dim + 1, 512),  # +1 for timestep
            nn.SiLU(),
            nn.Linear(512, 512),
            nn.SiLU(),
            nn.Linear(512, 512),
            nn.SiLU(),
            nn.Linear(512, state_dim)
        )

    def forward_diffusion(self, x0, t):
        """Додає noise до clean state."""
        alpha_t = self.alpha_cumprod[t].view(-1, 1)
        noise = torch.randn_like(x0)
        x_t = torch.sqrt(alpha_t) * x0 + torch.sqrt(1 - alpha_t) * noise
        return x_t, noise

    def predict_noise(self, x_t, action, t):
        """Predicts noise для denoising."""
        t_embed = t.float().view(-1, 1) / self.num_steps
        x = torch.cat([x_t, action, t_embed], dim=-1)
        return self.denoiser(x)

    def training_loss(self, current_state, action, next_state):
        """Diffusion training loss."""
        batch_size = current_state.size(0)
        t = torch.randint(0, self.num_steps, (batch_size,))

        # Forward diffusion
        x_t, noise = self.forward_diffusion(next_state, t)

        # Predict noise
        # Condition on current state through concatenation
        x_t_conditioned = x_t + current_state  # Residual connection
        predicted_noise = self.predict_noise(x_t_conditioned, action, t)

        return F.mse_loss(predicted_noise, noise)

    @torch.no_grad()
    def sample_next_state(self, current_state, action):
        """Sample next state через reverse diffusion."""
        batch_size = current_state.size(0)
        x = torch.randn(batch_size, current_state.size(-1))

        for t in reversed(range(self.num_steps)):
            t_batch = torch.full((batch_size,), t, dtype=torch.long)

            # Predict noise
            x_conditioned = x + current_state
            predicted_noise = self.predict_noise(x_conditioned, action, t_batch)

            # Reverse step
            alpha_t = self.alphas[t]
            alpha_cumprod_t = self.alpha_cumprod[t]
            beta_t = self.betas[t]

            if t > 0:
                noise = torch.randn_like(x)
            else:
                noise = 0

            x = (1 / torch.sqrt(alpha_t)) * (
                x - (beta_t / torch.sqrt(1 - alpha_cumprod_t)) * predicted_noise
            ) + torch.sqrt(beta_t) * noise

        return x

Застосування Generative World Models

1. Model-Based Reinforcement Learning

Перевага: Sample efficiency 10-100x краща
Причина: вчимося в imagination, не в реальному світі
Приклад: Dreamer v3 на Atari — human-level з 200K steps
         (model-free потребує 50M+)

2. Game Development & Procedural Generation

Genie показує: можна згенерувати playable level з одного скріншоту
Застосування:
  - Rapid prototyping ігрових світів
  - Infinite content generation
  - Testing без ручного QA

3. Autonomous Vehicles

Scenario generation:
  - "Що якщо пішохід вибіжить?"
  - "Як поведуться інші машини?"
  - Safety testing через imagination

4. Scientific Discovery

Molecular dynamics:
  - Predict наслідки хімічних реакцій
  - Drug discovery через imagination
Protein folding:
  - World model of protein dynamics

Benchmarks та Evaluation

Standard RL Benchmarks:

| Benchmark | Domain | Metrics | Best Method |

|-----------|--------|---------|-------------|

| Atari 100K | Games | Human-normalized score | DreamerV3 |

| DMControl | Continuous | Episode return | TD-MPC2 |

| Meta-World | Manipulation | Success rate | Varies |

| Minecraft | Open-world | Achievement progress | DreamerV3 |

Video Prediction Benchmarks:

  • BAIR Robot Pushing: manipulation prediction
  • Kinetics-600: human action prediction
  • Cityscapes: driving scene prediction

Ідеї для дослідження

Для бакалавра:

  • Реалізувати базовий Dreamer на простому середовищі (CartPole, Pendulum)
  • Порівняти model-free (PPO) vs model-based (Dreamer) sample efficiency
  • Візуалізація imagined trajectories

Для магістра:

  • Diffusion-based world model для DMControl
  • Hierarchical world models для long-horizon tasks
  • Compression techniques для real-time inference
  • Multi-task world model (одна модель для багатьох середовищ)

Для PhD:

  • Compositional world models (object-centric representations)
  • Grounding through physics engines (hybrid learned + physics)
  • Transfer across domains (sim-to-real world models)
  • Theoretical analysis: коли world models допомагають, коли шкодять?

Generative world models — це передній край досліджень AI. Якщо вас цікавить ця тема для курсової чи дипломної роботи, команда skp-degree.com.ua допоможе з реалізацією та оформленням. Пишіть у Telegram: @kursovi_diplomy.


Де брати матеріал

Ключові роботи:

  • "Dream to Control" (Hafner et al., 2019) — Dreamer v1
  • "Mastering Atari with Discrete World Models" (2021) — Dreamer v2
  • "Mastering Diverse Domains through World Models" (2023) — Dreamer v3
  • "Genie: Generative Interactive Environments" (2024)
  • "World Models" (Ha & Schmidhuber, 2018) — класика

Код та репозиторії:

  • github.com/danijar/dreamerv3 — офіційний DreamerV3
  • github.com/google-research/genie — (якщо випустять)
  • github.com/jannerm/diffuser — diffusion for planning

Конференції:

  • NeurIPS, ICML, ICLR — топ ML конференції
  • CoRL — для робототехніки

Складність: ? Магістерський рівень

Потрібні знання:

  • Generative models (VAE, Diffusion, GAN)
  • Reinforcement Learning (MDP, policy gradient)
  • Sequence modeling (Transformers, RNN/GRU)
  • PyTorch (advanced)
  • Probability theory

GPU вимоги:

  • Atari: 1x RTX 3090 достатньо
  • DMControl: 1x RTX 3090
  • Large-scale (Genie-like): 8+ A100 GPUs

Чому це революційно

Imagination — ключова здатність інтелекту. Планувати наперед. Оцінювати ризики. Вибирати кращу дію без спроб і помилок у реальному світі.

Людина не пробує стрибнути з даху, щоб дізнатися наслідки. Вона уявляє. World models дають AI цю здатність.

Genie показав: достатньо відео з YouTube, щоб модель навчилася створювати інтерактивні світи. Sora показала: physics understanding може emerge з даних.

Наступний крок — world models для реального світу. Роботи, які можуть уявити наслідки маніпуляцій. Автопілоти, які симулюють аварійні сценарії. Наукові асистенти, які передбачають результати експериментів.

Це не просто technical advance. Це крок до AI, який думає.

Ключові слова: world models, generative AI, Dreamer, Genie, Sora, video prediction, model-based reinforcement learning, latent dynamics, imagination, planning, дипломна робота, магістерська, PhD, research.

Про автора

Команда SKP-Degree

Верифікований автор

Розробники та дослідники AI · Python, TensorFlow, PyTorch · Досвід у промисловій розробці

Команда SKP-Degree — професійні розробники з досвідом 7+ років у промисловій розробці. Виконали 1000+ проєктів для студентів з України, Польщі та країн Балтії.

Python Django Java ML/AI React C# / .NET JavaScript

Потрібна допомога з роботою?

Замовте курсову чи дипломну роботу з програмування. Оплата після демонстрації!

Без передоплати Відеодемонстрація Автономна робота 24/7
Написати в Telegram