TIP
GitHub: kyegomez/OpenMythos | PyPI: open-mythos | License: MIT
Обзор проекта
В апреле 2026 года Anthropic представила Claude Mythos — модель следующего поколения семейства Claude, демонстрирующую поразительные способности в задачах из области разработки ПО, кибербезопасности (особенно поиска и эксплуатации zero-day уязвимостей). Однако Mythos сейчас доступен лишь в ограниченном виде через «Project Glasswing» для части партнеров по защитным исследованиям — до полноценного релиза ещё далеко.
OpenMythos — это ответ сообщества на эту закрытую архитектуру в виде открытого кода: независимый разработчик Kye Gomez на основе опубликованных статей и исследовательской литературы восстановил ключевую архитектуру Mythos, применив подход от первых принципов. Это не официальная версия, не утечка весов — это теоретическая реконструкция (theoretical reconstruction): цель — чтобы исследователи и разработчики могли экспериментально проверить идеи, похожие на заложенные.
Ключевой прорыв — Recurrent-Depth Transformer (RDT): те же веса Transformer выполняются в одном проходе вперёд до 16 раз (настраиваемо). Так реализуется «мышление» итеративно в непрерывном скрытом пространстве, а не путём наращивания сотен слоёв с независимыми весами, как у традиционных моделей. Рекуррентная модель на 770M параметров достигает качества примерно уровня стандартного Transformer на ~1.3B — при тех же возможностях, но с меньшей вдвое численностью параметров.
Сложность / длительность / польза
Уровень для начинающих, около 30 минут: вы сможете прогнать первый forward-проход OpenMythos, понять суть циклического вывода, принцип LTI-стабильного внедрения, а также то, как MoE FFN расширяет ширину модели, не увеличивая активируемые параметры.
Целевая аудитория
Разработчики, у которых есть базовое понимание LLM-архитектуры и которые хотят углубиться в «механизм циклического вывода» и инженерную реализацию, имея опыт 1–5 лет. Если вас интересуют вопросы ниже, OpenMythos — хороший старт:
- Почему сама идея «больше циклов = глубже рассуждение» имеет теоретическое обоснование
- Как динамические ограничения LTI помогают избежать расходимости при циклическом обучении
- Как связка MoE + совместное использование рекуррентных весов находит новую точку равновесия между числом параметров и объёмом вычислений
Ключевые зависимости и окружение
- Python 3.10+
- PyTorch 2.0+ (поддержка CUDA ускоряет инференс)
- Опционально:
flash-attn >= 2.8.3(ускоряет GQA attention, IO оптимально) - Минимальное железо: CPU достаточно для toy demo, GPU нужен для полноценного обучения
# только CPU
pip install open-mythos
# с Flash Attention 2 (требует CUDA + build tools)
pip install "open-mythos[flash]"
Полная структура проекта
open_mythos/
├── main.py # ядро: класс OpenMythos, MythosConfig и все компоненты архитектуры
├── moda.py # модули MoE / LoRA и т.п.
├── tokenizer.py # MythosTokenizer (обёртка над openai/gpt-oss-20b)
├── variants.py # предустановленные масштабы: mythos_1b ~ mythos_1t
├── docs/
│ ├── open_mythos.md # полный справочник API
│ └── datasets.md # рекомендации по выбору обучающих датасетов
training/
└── 3b_fine_web_edu.py # скрипт обучения для 3B: single-card / multi-card
examples/
├── moda_example.py # демонстрация MoE FFN + LoRA adapter
└── variants_example.py # сравнение параметров для разных масштабов
tests/
├── test_main.py # модульные тесты ядра
├── bench_vs_transformer.py # бенчмарк против стандартного Transformer
└── small_benchmark.py # бенчмарк производительности малого масштаба
Пошагово
Шаг 1 — Установка
pip install open-mythos
WARNING
Компиляция flash-attn требует CUDA Toolkit и nvcc. Если установка в среде без nvcc завершается ошибкой, OpenMythos автоматически откатится к стандартной реализации attention в PyTorch — корректность не пострадает, только скорость.
Шаг 2 — Сборка конфигурации
Все гиперпараметры передаются через MythosConfig. Чтобы понять несколько ключевых полей:
from open_mythos.main import MythosConfig
cfg = MythosConfig(
vocab_size=1000, # размер словаря; demo использует маленький vocab
dim=256, # размерность скрытого слоя
n_heads=8, # число Query-голов
n_kv_heads=2, # число KV-голов (GQA: меньше Q-голов — меньше расход памяти)
max_seq_len=128, # максимальная длина последовательности (предел предвычислений RoPE)
max_loop_iters=4, # глубина цикла T; при инференсе можно увеличить
prelude_layers=1, # число слоёв стандартного Transformer в секции Prelude
coda_layers=1, # число слоёв стандартного Transformer в секции Coda
attn_type="mla", # "mla" или "gqa"; см. шаг 5
n_experts=8, # общее число экспертов MoE
n_shared_experts=1, # число «постоянных» экспертов (активны на каждом токене)
n_experts_per_tok=2, # сколько top-K экспертов активируется для каждого токена
expert_dim=64, # скрытая размерность каждого эксперта
lora_rank=8, # ранг глубинного LoRA adapter
)
MythosConfig имеет конструктор по умолчанию: просто MythosConfig() будет использовать набор значений среднего масштаба.
Шаг 3 — Инициализация модели и запуск forward-прохода
import torch
from open_mythos.main import OpenMythos, MythosConfig
cfg = MythosConfig()
model = OpenMythos(cfg)
# подсчёт числа параметров
total = sum(p.numel() for p in model.parameters())
print(f"Parameters: {total:,}")
# forward: shape input_ids (B, T), shape logits (B, T, vocab_size)
ids = torch.randint(0, cfg.vocab_size, (2, 16)) # batch=2, seq=16
logits = model(ids, n_loops=4) # 4 цикла inference
print(f"Logits shape: {logits.shape}") # torch.Size([2, 16, 32000])
n_loops задаёт глубину рекурсии. По умолчанию значение берётся из cfg.max_loop_iters; при инференсе можно увеличить — это ключевая особенность RDT: экстраполяция глубины (depth extrapolation), то есть модель тренируется с N циклами, а при инференсе может использовать N+k, чтобы решать более сложные задачи.
Шаг 4 — Автарегрессионная генерация
# генерация новых токенов: максимум 8, глубина цикла 8
out = model.generate(ids, max_new_tokens=8, n_loops=8)
print(f"Generated shape: {out.shape}") # torch.Size([2, 24])
Метод generate внутри поддерживает KV cache: первый вызов обрабатывает полный prompt, а дальше при каждом следующем вызове декодируется только один токен. temperature задаёт случайность семплирования, top_k ограничивает диапазон семплирования:
out = model.generate(
ids,
max_new_tokens=64,
n_loops=16,
temperature=0.8, # чем ниже — тем детерминированнее
top_k=40, # 0 = выключено
)
Шаг 5 — Выбор механизма attention: MLA vs GQA
# Multi-Latent Attention (по умолчанию, рекомендовано для длинного контекста)
cfg_mla = MythosConfig(
attn_type="mla",
kv_lora_rank=512, # потенциальная размерность K/V в кеше (меньше — меньше расход памяти)
q_lora_rank=1536, # компрессия размерности Q
qk_rope_head_dim=64, # размерность на голову с RoPE
qk_nope_head_dim=128, # размерность на голову без RoPE
v_head_dim=128,
)
# Grouped Query Attention (дружелюбно к памяти; с flash-attn обычно эффективно)
cfg_gqa = MythosConfig(
attn_type="gqa",
n_kv_heads=4, # меньше, чем n_heads; KV-кэш в n_heads/n_kv_heads раз меньше
)
Компромисс: MLA сжимает KV в low-rank потенциальные векторы для кэширования, уменьшая расход памяти примерно в 10–20 раз, но при этом при каждом шаге нужно перестраивать K/V (одна линейная проекция). GQA кэширует полный KV head напрямую, и в паре с Flash Attention 2 получается оптимальный IO. В продакшене MLA экономит память сильнее, а на этапе разработки GQA проще отлаживать.
Шаг 6 — Проверка стабильности рекурсии: контроль спектрального радиуса
Самая частая проблема при обучении RDT — расходимость цикла: скрытое состояние может экспоненциально возрастать на каждой итерации. OpenMythos обеспечивает стабильность по построению через LTI-stable injection. Проверка выполняется через спектральный радиус ρ(A).
# получение дискретизированной матрицы состояний A_discrete
A = model.recurrent.injection.get_A() # shape (dim,)
rho = torch.linalg.eigvals(A).abs().max().item()
print(f"Spectral radius ρ(A) = {rho:.4f}")
assert rho < 1.0, f"Unstable: ρ(A) = {rho:.4f} >= 1"
WARNING
Если при собственном обучении вы обнаружили rho >= 1, не пытайтесь вручную «подкрутить» параметры — это означает, что параметризация LTI injection была обойдена. Проверьте, не было ли ошибочно присвоено значение напрямую injection.log_A или injection.log_dt.
Шаг 7 — Использование вариаций предустановленного масштаба
Не хочется вручную собирать MythosConfig? В variants.py подготовлены предустановки от 1B до 1T:
from open_mythos import mythos_1b, mythos_3b, mythos_10b, mythos_50b, mythos_100b
# mythos_7b() возвращает MythosConfig
cfg = mythos_3b()
model = OpenMythos(cfg)
print(f"Variant 3B: {sum(p.numel() for p in model.parameters()):,} params")
| Вариант | dim | Experts | глубина цикла | контекст | максимальный вывод |
|---|---|---|---|---|---|
mythos_1b | 2048 | 64 | 16 | 4k | 4k |
mythos_3b | 3072 | 64 | 16 | 4k | 4k |
mythos_10b | 4096 | 128 | 24 | 8k | 4k |
mythos_100b | 8192 | 256 | 32 | 1M | 128k |
Шаг 8 — Запуск обучающих скриптов
В проекте есть встроенный скрипт обучения 3B на FineWeb-Edu:
# одна GPU
python training/3b_fine_web_edu.py
# несколько GPU (автоматическое определение количества GPU)
torchrun --nproc_per_node=$(python -c "import torch; print(torch.cuda.device_count())") \
training/3b_fine_web_edu.py
TIP
По умолчанию обучение использует сабсет sample-10BT (30B токенов) — подходит для быстрой проверки. Чтобы прогнать полный датасет 100BT, в скрипте поменяйте параметр dataset_name на "sample-100BT".
Ключевая настройка обучения:
# training/3b_fine_web_edu.py (ключевые параметры)
optimizer = torch.optim.AdamW(model.parameters(), lr=3e-4, weight_decay=0.1)
# точность: H100/A100 — bfloat16, старые карты — float16 + GradScaler
# планировщик: 2000 шагов warmup → далее косинусное затухание
# Tokenizer: openai/gpt-oss-20b через MythosTokenizer
Частые проблемы и их устранение
1. Взрыв по памяти: ловушка «количество циклов × размер батча»
Рекуррентная стадия RDT отличается от стандартного Transformer: между слоями независимости меньше — каждый шаг цикла накапливает KV-состояния всех токенов в кэш. Циклы 16 раз × последовательность 4096 × батч 8 создают нагрузку на память в несколько раз выше, чем у обычной модели.
Решение: сначала проверьте с меньшим n_loops (например, 4). После сходимости постепенно увеличивайте; батч масштабируйте линейно, а не фиксированно.
2. Нет Flash Attention, но хочется ускорить
Если компиляция flash-attn не проходит (часто встречается на Windows + CUDA-средах), OpenMythos автоматически откатится к нативной attention в PyTorch. Важно: такой даунгрейд не влияет на корректность, только на скорость — в сценариях с маленькими батчами разница обычно невелика.
3. Не проходит проверка спектрального радиуса: обучение расходится
Если вы изменили параметризацию LTIInjection или при fine-tuning заморозили неправильные слои, из-за чего параметризация injection окажется нарушенной, появится ρ(A) >= 1. Не делайте обрезку (clip) параметров напрямую — вернитесь к настройкам инициализации по умолчанию и начните заново. Стабилизация LTI опирается на структурную параметризацию, а не на постфактум-коррекцию.
4. ACT приводит к раннему завершению: фактическое число циклов меньше, чем n_loops
act_threshold=0.99 означает, что на каждой позиции выход из цикла происходит после накопления 99% вероятности. Если на некоторых задачах вы видите, что фактическое число циклов существенно ниже n_loops, проверьте распределение сложности токенов в данных: слишком «простые» токены будут слишком рано инициировать halting, и для сложных токенов не будет хватать глубины.
5. Крах MoE-роутинга: некоторые эксперты никогда не активируются
Вспомогательная loss для балансировки нагрузки в стиле DeepSeekMoE без loss-знака опирается на динамическую настройку router_bias. Если вы обучаете с нуля и не вызываете логику этого обновления, роутер быстро сойдётся к активации лишь небольшой части экспертов (обычно первых 1–2). В проекте MoEFFN.forward уже содержит место под bias-адаптацию, но в пользовательских обучающих скриптах нужно регулярно вызывать логику обновления bias.
6. Плохое качество генерации: как подбирать temperature и top_k
| Сценарий | temperature | top_k | Примечание |
|---|---|---|---|
| Код / математика | 0.3–0.5 | 10–20 | низкая случайность |
| Творческое письмо | 0.7–0.9 | 0 (выкл.) | высокая вариативность |
| Отладка / проверка инференса | 0.0 (greedy) | 1 | максимум детерминизма |
Дополнительное чтение / направления развития
Ключевые статьи
| Статья | Что решает |
|---|---|
| Loop, Think & Generalize (2025) | Как рекуррентный Transformer делает неявный вывод в скрытом пространстве |
| Parcae (Prairie et al., 2026) | Scaling Law: как LTI-ограничения обеспечивают стабильность рекурсии |
| DeepSeekMoE (Dai et al., 2024) | Дизайн роутинга для fine-grained MoE + shared experts |
| DeepSeek-V2 MLA (2024) | Принцип сжатия KV в Multi-Latent Attention |
| Relaxed Recursive Transformers (Bae et al., 2024) | Как LoRA adapter повышает рекуррентную выразительность, не увеличивая слишком много параметров |
Направления развития
1. Собственный LoRA Adapter: текущий lora_rank одинаковый для всего пайплайна; его можно сделать послойной настройкой, чтобы разные глубины рекурсии использовали разную силу адаптации.
2. Сканирование порога ACT: дефолт 0.99 — эмпирическое значение. Сделайте grid search по 0.8–0.999, и вы обнаружите, что для некоторых задач 0.95 лучше, чем 0.99 (раннее завершение помогает избежать overthinking).
3. Эксперименты с Depth Extrapolation: тренируйте на фиксированном n_loops, а при инференсе делайте sweep n_loops и нарисуйте кривую «число циклов → точность на downstream-задаче». Теоретически должна проявиться форма экспоненциального затухания — это одно из самых важных доказуемых свойств RDT.
4. Сравнение со стандартным Transformer: с помощью скрипта bench_vs_transformer.py сравните рекуррентную модель и стандартную на задачах compositional / systematic generalization при одинаковом количестве параметров. Это наиболее яркий сценарий преимуществ RDT.