LLM може написати есе про гравітацію. Але чи розуміє він, що м'яч падає вниз?
Спойлер: ні. GPT-4 провалює прості фізичні задачі, які трирічна дитина вирішує інтуїтивно. «Що буде, якщо штовхнути чашку з краю столу?» — LLM почне галюцинувати про різні можливості, замість того щоб просто сказати: «Впаде і розіб'ється».
World Models — це інший підхід. Системи, які не просто читали про фізику, а навчились її симулювати внутрішньо. І ця битва — LLM vs World Models — визначить майбутнє embodied AI, робототехніки та автономних систем.
Що таке World Model
World Model — це нейронна мережа, яка вчиться передбачати наступний стан світу на основі поточного стану та дій. По суті, це симулятор реальності в голові AI.
Формально:
s_{t+1} = f(s_t, a_t)
де:
s_t — поточний стан середовища
a_t — дія агента
s_{t+1} — передбачений наступний стан
f — learned world model (нейронна мережа)
Ширше визначення включає:
World Model = {
Dynamics model: s_{t+1} = f(s_t, a_t)
Reward model: r_t = g(s_t, a_t)
Observation model: o_t = h(s_t) # як спостерігаємо стан
}
Чому це потужно?
Замість того щоб взаємодіяти з реальним світом (дорого, повільно, небезпечно), агент може:
- Уявити дію
- Симулювати результат у World Model
- Оцінити наслідки
- Прийняти рішення БЕЗ реальної спроби
Це як шахіст, який думає на кілька ходів вперед — він не рухає фігури фізично, а симулює гру в голові.
Чому LLM не справляються з фізикою
LLM навчені на тексті. Текст — це символи. Символи описують реальність, але не є реальністю. Коли GPT читає «м'яч падає», він вчить статистичний зв'язок між словами, а не фізику гравітації.
Приклад 1: Простий фізичний reasoning
Питання: «Куля на столі. Стіл нахилили. Куля...»
LLM: «...може покотитися» (правильно!)
Питання: «Куля на столі. Стіл перевернули догори ногами. Куля...»
LLM: «...залишилась на столі» (НЕПРАВИЛЬНО!)
LLM вивчив кореляцію «нахил → котиться», але не розуміє концепцію гравітації.
Приклад 2: Контрфактуальне reasoning
Питання: «Якби не було тертя, що сталося б з ковзаном?»
LLM: Може дати будь-яку відповідь, бо в training data
мало прикладів світів без тертя
Приклад 3: Просторовий reasoning
Питання: «Три книги стоять на полиці: А, Б, В зліва направо.
Я перемістив Б ліворуч від А. Який порядок?»
LLM: Часто плутає, особливо з довшими ланцюжками операцій
Чому так відбувається?
# LLM по суті робить це:
def llm_reasoning(question):
# Pattern matching в embedding space
similar_examples = find_similar_in_training_data(question)
# Статистичне продовження
answer = sample_next_tokens(similar_examples)
return answer
# World Model робить це:
def world_model_reasoning(state, action):
# Фактична симуляція
next_state = physics_simulation(state, action)
return next_state
Архітектури World Models
Підхід 1: Video Prediction Models
Вчимося передбачати наступні кадри відео. Якщо модель може точно передбачити, як падає м'яч — вона «розуміє» гравітацію.
import torch
import torch.nn as nn
class VideoPredictor(nn.Module):
"""Простий video prediction model."""
def __init__(self, channels=3, hidden_dim=256):
super().__init__()
# Encoder: image -> latent
self.encoder = nn.Sequential(
nn.Conv2d(channels, 64, 4, stride=2, padding=1),
nn.ReLU(),
nn.Conv2d(64, 128, 4, stride=2, padding=1),
nn.ReLU(),
nn.Conv2d(128, 256, 4, stride=2, padding=1),
nn.ReLU(),
nn.Flatten(),
nn.Linear(256 * 8 * 8, hidden_dim)
)
# Dynamics: latent + action -> next latent
self.dynamics = nn.Sequential(
nn.Linear(hidden_dim + 4, hidden_dim), # +4 for action
nn.ReLU(),
nn.Linear(hidden_dim, hidden_dim),
nn.ReLU(),
nn.Linear(hidden_dim, hidden_dim)
)
# Decoder: latent -> image
self.decoder = nn.Sequential(
nn.Linear(hidden_dim, 256 * 8 * 8),
nn.ReLU(),
nn.Unflatten(1, (256, 8, 8)),
nn.ConvTranspose2d(256, 128, 4, stride=2, padding=1),
nn.ReLU(),
nn.ConvTranspose2d(128, 64, 4, stride=2, padding=1),
nn.ReLU(),
nn.ConvTranspose2d(64, channels, 4, stride=2, padding=1),
nn.Sigmoid()
)
def forward(self, frame, action):
"""Передбачає наступний кадр."""
z = self.encoder(frame)
z_action = torch.cat([z, action], dim=-1)
z_next = self.dynamics(z_action)
next_frame = self.decoder(z_next)
return next_frame
def rollout(self, initial_frame, actions):
"""Симулює послідовність кадрів."""
frames = [initial_frame]
frame = initial_frame
for action in actions:
frame = self.forward(frame, action)
frames.append(frame)
return torch.stack(frames)
Підхід 2: Latent Dynamics Models (Dreamer)
Замість працювати з пікселями, кодуємо стан у компактний latent space і вчимо dynamics там. Набагато ефективніше.
class DreamerWorldModel(nn.Module):
"""Dreamer-style world model з RSSM."""
def __init__(self, obs_dim, action_dim, hidden_dim=200,
state_dim=30, latent_dim=30):
super().__init__()
# Encoder: observation -> features
self.encoder = nn.Sequential(
nn.Linear(obs_dim, hidden_dim),
nn.ReLU(),
nn.Linear(hidden_dim, hidden_dim)
)
# RSSM components
# Deterministic state transition
self.rnn = nn.GRUCell(hidden_dim, hidden_dim)
# Prior: p(z_t | h_t)
self.prior = nn.Sequential(
nn.Linear(hidden_dim, hidden_dim),
nn.ReLU(),
nn.Linear(hidden_dim, 2 * latent_dim) # mean, logvar
)
# Posterior: q(z_t | h_t, o_t)
self.posterior = nn.Sequential(
nn.Linear(hidden_dim + hidden_dim, hidden_dim),
nn.ReLU(),
nn.Linear(hidden_dim, 2 * latent_dim) # mean, logvar
)
# Decoder: h_t, z_t -> o_t
self.decoder = nn.Sequential(
nn.Linear(hidden_dim + latent_dim, hidden_dim),
nn.ReLU(),
nn.Linear(hidden_dim, obs_dim)
)
# Reward predictor
self.reward_head = nn.Sequential(
nn.Linear(hidden_dim + latent_dim, hidden_dim),
nn.ReLU(),
nn.Linear(hidden_dim, 1)
)
self.hidden_dim = hidden_dim
self.latent_dim = latent_dim
def reparameterize(self, mean, logvar):
"""Reparameterization trick."""
std = torch.exp(0.5 * logvar)
eps = torch.randn_like(std)
return mean + eps * std
def forward(self, obs, action, h_prev):
"""Один крок world model з observation."""
# Encode observation
obs_feat = self.encoder(obs)
# Deterministic transition
h = self.rnn(torch.cat([obs_feat, action], dim=-1), h_prev)
# Posterior (training)
post_input = torch.cat([h, obs_feat], dim=-1)
post_params = self.posterior(post_input)
post_mean, post_logvar = post_params.chunk(2, dim=-1)
z = self.reparameterize(post_mean, post_logvar)
# Prior (для KL loss)
prior_params = self.prior(h)
prior_mean, prior_logvar = prior_params.chunk(2, dim=-1)
# Decode
state = torch.cat([h, z], dim=-1)
obs_pred = self.decoder(state)
reward_pred = self.reward_head(state)
return {
'h': h,
'z': z,
'obs_pred': obs_pred,
'reward_pred': reward_pred,
'prior': (prior_mean, prior_logvar),
'posterior': (post_mean, post_logvar)
}
def imagine(self, h, action):
"""Imagination без observation (для planning)."""
# Deterministic transition
# В imagination використовуємо prior, не posterior
h_next = self.rnn(action, h)
prior_params = self.prior(h_next)
prior_mean, prior_logvar = prior_params.chunk(2, dim=-1)
z = self.reparameterize(prior_mean, prior_logvar)
state = torch.cat([h_next, z], dim=-1)
reward_pred = self.reward_head(state)
return h_next, z, reward_pred
def imagine_trajectory(self, h_init, policy, horizon=15):
"""Уявляємо траєкторію на horizon кроків."""
h = h_init
states, rewards = [], []
for _ in range(horizon):
# Policy вибирає дію
state = torch.cat([h, torch.zeros(h.size(0), self.latent_dim)], dim=-1)
action = policy(state)
# Imagine next state
h, z, reward = self.imagine(h, action)
states.append(torch.cat([h, z], dim=-1))
rewards.append(reward)
return torch.stack(states), torch.stack(rewards)
Підхід 3: Physics-Informed Neural Networks (PINN)
Вбудовуємо фізичні закони прямо в архітектуру або loss function.
class HamiltonianNN(nn.Module):
"""Hamiltonian Neural Network — зберігає енергію."""
def __init__(self, input_dim, hidden_dim=200):
super().__init__()
# Network that predicts Hamiltonian H(q, p)
self.hamiltonian_net = nn.Sequential(
nn.Linear(input_dim, hidden_dim),
nn.Tanh(),
nn.Linear(hidden_dim, hidden_dim),
nn.Tanh(),
nn.Linear(hidden_dim, 1) # Scalar energy
)
def forward(self, x):
"""Returns Hamiltonian energy."""
return self.hamiltonian_net(x)
def time_derivative(self, x):
"""
Обчислює dq/dt, dp/dt з Hamilton's equations:
dq/dt = ∂H/∂p
dp/dt = -∂H/∂q
"""
x = x.requires_grad_(True)
H = self.forward(x)
# Gradient of H w.r.t. x
dH = torch.autograd.grad(
H.sum(), x, create_graph=True
)[0]
# Split into q and p components
dim = x.shape[-1] // 2
dH_dq = dH[..., :dim]
dH_dp = dH[..., dim:]
# Hamilton's equations
dq_dt = dH_dp
dp_dt = -dH_dq
return torch.cat([dq_dt, dp_dt], dim=-1)
class NeuralODE(nn.Module):
"""Neural ODE для фізичної динаміки."""
def __init__(self, dynamics_net):
super().__init__()
self.dynamics = dynamics_net
def forward(self, x0, t):
"""Інтегрує від x0 до часу t."""
from torchdiffeq import odeint
def dynamics_fn(t, x):
return self.dynamics.time_derivative(x)
trajectory = odeint(dynamics_fn, x0, t, method='dopri5')
return trajectory
Гібридний підхід: LLM + World Model
Найперспективніший напрямок — комбінація сильних сторін обох підходів.
class HybridAgent:
"""LLM для high-level planning, World Model для low-level control."""
def __init__(self, llm, world_model, low_level_policy):
self.llm = llm # Для symbolic reasoning та planning
self.world_model = world_model # Для фізичної симуляції
self.policy = low_level_policy # Для виконання дій
def solve_task(self, task_description, current_state):
"""Вирішує задачу використовуючи обидві системи."""
# 1. LLM генерує high-level план
plan_prompt = f"""
Current situation: {self._describe_state(current_state)}
Task: {task_description}
Generate a step-by-step plan as a list of subgoals.
Each subgoal should be a concrete physical objective.
"""
high_level_plan = self.llm.generate(plan_prompt)
subgoals = self._parse_plan(high_level_plan)
# 2. Для кожного subgoal використовуємо World Model
for subgoal in subgoals:
# Перевіряємо feasibility у World Model
if not self._check_feasibility(current_state, subgoal):
# Запитуємо LLM альтернативу
alternative = self._ask_llm_alternative(subgoal)
subgoal = alternative
# Виконуємо через low-level policy з World Model planning
current_state = self._execute_subgoal(current_state, subgoal)
return current_state
def _check_feasibility(self, state, subgoal):
"""Перевіряє, чи досяжний subgoal у World Model."""
# Imagine trajectory до subgoal
imagined_states = []
current = state
for _ in range(100): # Max steps
action = self.policy(current, subgoal)
current, reward = self.world_model.imagine(current, action)
imagined_states.append(current)
if self._goal_reached(current, subgoal):
return True
return False
def _execute_subgoal(self, state, subgoal):
"""Виконує subgoal з Model Predictive Control."""
while not self._goal_reached(state, subgoal):
# Plan у World Model
best_action = self._mpc_planning(state, subgoal)
# Execute в реальному світі
state = self.env.step(best_action)
return state
def _mpc_planning(self, state, goal, horizon=10, n_samples=100):
"""Model Predictive Control з World Model."""
best_reward = float('-inf')
best_action = None
for _ in range(n_samples):
# Sample random action sequence
actions = torch.randn(horizon, self.action_dim)
# Evaluate in World Model
total_reward = 0
current = state
for action in actions:
current, reward = self.world_model.imagine(current, action)
total_reward += reward
# Bonus for reaching goal
total_reward += self._goal_reward(current, goal)
if total_reward > best_reward:
best_reward = total_reward
best_action = actions[0] # MPC: execute only first action
return best_action
Benchmark: LLM vs World Model на фізичних задачах
import numpy as np
from dataclasses import dataclass
@dataclass
class PhysicsTask:
description: str
initial_state: dict
correct_answer: str
category: str # 'gravity', 'collision', 'fluid', etc.
class PhysicsBenchmark:
"""Benchmark для порівняння LLM і World Models."""
def __init__(self):
self.tasks = self._load_tasks()
def _load_tasks(self):
return [
PhysicsTask(
description="A ball is placed on a tilted ramp. What happens?",
initial_state={'ball': {'pos': [0, 1], 'vel': [0, 0]},
'ramp': {'angle': 30}},
correct_answer="rolls_down",
category="gravity"
),
PhysicsTask(
description="Two balls collide head-on with equal mass and speed. What happens?",
initial_state={'ball1': {'pos': [-1, 0], 'vel': [1, 0], 'mass': 1},
'ball2': {'pos': [1, 0], 'vel': [-1, 0], 'mass': 1}},
correct_answer="both_reverse",
category="collision"
),
PhysicsTask(
description="A pendulum is released from horizontal position. Where is it fastest?",
initial_state={'pendulum': {'angle': 90, 'length': 1}},
correct_answer="at_bottom",
category="energy"
),
# ... more tasks
]
def evaluate_llm(self, llm, verbose=False):
"""Оцінює LLM на фізичних задачах."""
results = {'correct': 0, 'total': 0, 'by_category': {}}
for task in self.tasks:
prompt = f"""
Physical scenario: {task.description}
Initial state: {task.initial_state}
What will happen? Give a brief answer.
"""
response = llm.generate(prompt)
is_correct = self._check_answer(response, task.correct_answer)
results['total'] += 1
if is_correct:
results['correct'] += 1
# Track by category
cat = task.category
if cat not in results['by_category']:
results['by_category'][cat] = {'correct': 0, 'total': 0}
results['by_category'][cat]['total'] += 1
if is_correct:
results['by_category'][cat]['correct'] += 1
if verbose:
print(f"Task: {task.description}")
print(f"LLM answer: {response}")
print(f"Correct: {is_correct}\n")
results['accuracy'] = results['correct'] / results['total']
return results
def evaluate_world_model(self, world_model, verbose=False):
"""Оцінює World Model через симуляцію."""
results = {'correct': 0, 'total': 0, 'by_category': {}}
for task in self.tasks:
# Convert to simulation state
state = self._task_to_state(task)
# Simulate
trajectory = world_model.simulate(state, steps=100)
# Extract answer from final state
answer = self._extract_answer(trajectory, task)
is_correct = answer == task.correct_answer
results['total'] += 1
if is_correct:
results['correct'] += 1
# Track by category
cat = task.category
if cat not in results['by_category']:
results['by_category'][cat] = {'correct': 0, 'total': 0}
results['by_category'][cat]['total'] += 1
if is_correct:
results['by_category'][cat]['correct'] += 1
results['accuracy'] = results['correct'] / results['total']
return results
# Типові результати на такому benchmark:
# LLM (GPT-4): ~60-70% accuracy (добре на простих, погано на контрфактуальних)
# World Model: ~85-95% accuracy (стабільно, якщо навчений на схожій фізиці)
Порівняльна таблиця
| Критерій | LLM | World Models |
|----------|-----|--------------|
| Reasoning про текст | ⭐⭐⭐⭐⭐ | ⭐⭐ |
| Просторове reasoning | ⭐⭐ | ⭐⭐⭐⭐⭐ |
| Фізична інтуїція | ⭐ | ⭐⭐⭐⭐ |
| Генералізація на нові домени | ⭐⭐⭐⭐ | ⭐⭐⭐ |
| Sample efficiency | ⭐⭐⭐⭐⭐ (pre-trained) | ⭐⭐ (потребує даних) |
| Обчислювальна вартість inference | ⭐⭐⭐ | ⭐⭐⭐⭐ |
| Interpretability | ⭐⭐ | ⭐⭐⭐⭐ |
| Causal reasoning | ⭐⭐ | ⭐⭐⭐⭐ |
| Counterfactual reasoning | ⭐ | ⭐⭐⭐⭐⭐ |
Ключові роботи та системи
World Models:
- "World Models" (Ha & Schmidhuber, 2018) — класична робота, яка визначила напрямок
- "Dreamer" series (Hafner et al., 2019-2023) — state-of-the-art для RL
- "Genie" (Google DeepMind, 2024) — generative world model з відео
- "Sora" (OpenAI, 2024) — video generation як world simulation
- "JEPA" (Yann LeCun) — joint embedding predictive architecture
LLM for physical reasoning:
- "Language Models as World Models" (Hao et al., 2023)
- "Physics of Language Models" series (MIT)
- "Embodied Understanding through LLMs" (various, 2023-2024)
Гібридні підходи:
- "PaLM-E" (Google, 2023) — embodied multimodal LLM
- "RT-2" (Google DeepMind) — vision-language-action model
- "SayCan" (Google) — LLM planning + robot skills
Ідеї для дослідження
Для бакалавра:
- Порівняння GPT-4V vs простого world model на PHYRE benchmark
- Реалізація базового Dreamer-lite для 2D середовища
- Аналіз типів помилок LLM у фізичному reasoning
Для магістра:
- LLM-guided world model: LLM генерує hypothesis, World Model верифікує
- Transfer learning між world models різних фізичних доменів
- Оптимізація world model для edge devices (мобільна робототехніка)
- Multimodal world models: vision + proprioception + touch
Для PhD:
- Теоретичне дослідження: що необхідно і достатньо для «розуміння» фізики?
- Нейронаукова перспектива: як біологічний мозок будує world models?
- Unified architecture для symbolic + spatial reasoning
- Формальні гарантії для world model predictions
Дослідження World Models — це шлях до embodied AI та робототехніки нового покоління. Якщо вас цікавить ця тема для академічної роботи, команда skp-degree.com.ua допоможе з вибором напрямку, оглядом літератури та реалізацією. Пишіть у Telegram: @kursovi_diplomy.
Benchmark датасети
Для фізичного reasoning:
- PHYRE: 2D physics puzzles (Facebook Research)
- IntPhys: physical intuition benchmark (DeepMind)
- CLEVRER: causal reasoning з відео
- PIGLeT: physical interaction grounding
Для world models:
- DMControl: MuJoCo environments для continuous control
- Habitat: 3D indoor navigation
- CARLA: autonomous driving simulation
- RoboSuite: robotic manipulation
Для evaluation:
- PTB (Physical Reasoning Test): набір задач на фізичну інтуїцію
- CRAFT: counterfactual reasoning about physical dynamics
Практична реалізація
Мінімальний експеримент для порівняння:
# Крок 1: Встановлення
# pip install phyre torch transformers dm_control
# Крок 2: Тест LLM на PHYRE
def test_llm_phyre(llm_client, n_tasks=100):
import phyre
# Завантажуємо задачі
eval_setup = phyre.create_evaluation_setup('ball_cross_template')
task_ids = eval_setup.task_ids[:n_tasks]
correct = 0
for task_id in task_ids:
# Отримуємо опис задачі
task = phyre.TaskFactory.get_task(task_id)
description = task_to_text(task) # Конвертуємо в текст
# Питаємо LLM
prompt = f"Physical puzzle: {description}\nWhat action solves this?"
response = llm_client.generate(prompt)
# Перевіряємо відповідь
action = parse_action(response)
result = task.simulate(action)
if result.is_solved:
correct += 1
return correct / n_tasks
# Крок 3: Тест World Model
def test_world_model_phyre(world_model, n_tasks=100):
import phyre
eval_setup = phyre.create_evaluation_setup('ball_cross_template')
task_ids = eval_setup.task_ids[:n_tasks]
correct = 0
for task_id in task_ids:
task = phyre.TaskFactory.get_task(task_id)
# World Model планує через simulation
best_action = None
best_score = float('-inf')
for _ in range(100): # Random shooting
action = sample_action()
# Симулюємо у world model
predicted_outcome = world_model.simulate(task.initial_state, action)
score = evaluate_outcome(predicted_outcome, task.goal)
if score > best_score:
best_score = score
best_action = action
# Перевіряємо в реальній симуляції
result = task.simulate(best_action)
if result.is_solved:
correct += 1
return correct / n_tasks
Фреймворки:
- stable-baselines3: RL algorithms
- dm_control: physics environments
- Hugging Face transformers: LLMs
- phyre: physics puzzles
- pytorch3d: 3D operations
Складність: ? Магістерський рівень
Потрібні знання:
- Deep Learning (CNN, Transformer, VAE)
- Reinforcement Learning basics (MDP, policy gradient)
- Physics simulation (бажано, але не обов'язково)
- PyTorch
- Probability theory (для latent models)
Для входу:
- Курс Deep Learning (Andrew Ng або аналог)
- Базовий RL (David Silver lectures)
- Dreamer paper reading group
Чому це визначить майбутнє AI
Embodied AI — наступний великий фронтир. Роботи, автономні авто, AR/VR, домашні асистенти — всюди потрібне розуміння фізичного світу.
LLM — це мозок без тіла. Він може розмірковувати про фізику, але не відчуває її.
World Models — це тіло без абстрактного мислення. Вони симулюють реальність, але не можуть узагальнювати на рівні концепцій.
Хто їх правильно поєднає — створить справжній embodied intelligence. Систему, яка:
- Розуміє мовні інструкції (LLM)
- Планує на високому рівні (LLM)
- Передбачає фізичні наслідки (World Model)
- Діє надійно в реальному світі (World Model + Control)
Це майбутнє AI. І воно вже будується.
Ключові слова: world models, LLM, embodied AI, physical reasoning, Dreamer, RSSM, video prediction, Hamiltonian neural networks, робототехніка, автономні системи, model-based RL, simulation, дипломна робота, магістерська, PhD, дослідження.