Guía de inicio con OpenMythos: implementación open source de la arquitectura de razonamiento en bucle basada en Claude Mythos

April 26, 2026

TIP

GitHub: kyegomez/OpenMythos | PyPI: open-mythos | Licencia: MIT

Introducción al proyecto

En abril de 2026, Anthropic presentó Claude Mythos: el siguiente modelo de razonamiento de la familia Claude, con capacidades sin precedentes en tareas como ingeniería de software y ciberseguridad (especialmente el descubrimiento y explotación de vulnerabilidades de día cero). Sin embargo, Mythos todavía solo está disponible de forma limitada mediante "Project Glasswing" para algunos socios de investigación en seguridad defensiva; dista mucho de un lanzamiento integral.

OpenMythos es la respuesta open source de la comunidad a esta arquitectura cerrada: desarrolladores independientes, como Kye Gomez, reconstruyen desde primeros principios el núcleo de Mythos a partir de artículos y literatura de investigación disponibles públicamente. No es una versión oficial, no hay filtración de pesos: es una reconstrucción teórica (theoretical reconstruction), con el objetivo de que investigadores y desarrolladores puedan experimentar y validar ideas similares.

Su avance clave es Recurrent-Depth Transformer (RDT): un mismo Transformer reutiliza sus pesos hasta 16 veces (configurable) en una única pasada forward, realizando el “pensamiento” de manera iterativa en un espacio latente continuo; en lugar de apilar cientos de capas con pesos independientes como hacen los modelos tradicionales. Un modelo recurrente de 770M parámetros puede alcanzar una calidad cercana a la de un Transformer estándar de ~1.3B parámetros: las mismas capacidades con cerca de la mitad de los parámetros.


Dificultad / Duración / Qué aprendes

Dificultad para principiantes, ~30 minutos: te guía para ejecutar la primera inferencia forward de OpenMythos, entender la esencia del razonamiento en bucle, el principio de la inyección estable LTI, y cómo MoE FFN puede ampliar el “ancho” del modelo sin aumentar los parámetros de activación.


Público objetivo

Desarrolladores con conocimientos básicos de arquitectura de LLM que quieran profundizar en el mecanismo de “razonamiento en bucle” y su implementación en ingeniería (1–5 años de experiencia). Si te interesan preguntas como estas, OpenMythos es un buen punto de partida:

  • Por qué la idea de “más bucles = más razonamiento profundo” tiene respaldo teórico
  • Cómo las restricciones de dinámica LTI evitan la divergencia durante el entrenamiento en bucle
  • Cómo MoE + compartición de pesos recurrentes encuentran un nuevo equilibrio entre cantidad de parámetros y cómputo

Dependencias clave y entorno

  • Python 3.10+
  • PyTorch 2.0+ (el soporte CUDA puede acelerar la inferencia)
  • Opcional: flash-attn >= 2.8.3 (acelera la atención GQA; IO óptimo)
  • Hardware mínimo: la CPU puede ejecutar un toy demo; la GPU permite entrenar completamente
# Solo CPU
pip install open-mythos

# Con Flash Attention 2 (requiere CUDA + herramientas de compilación)
pip install "open-mythos[flash]"

Estructura completa del proyecto

open_mythos/
├── main.py              # Núcleo: clase OpenMythos, MythosConfig y todos los componentes de la arquitectura
├── moda.py              # Módulos MoE / LoRA, etc.
├── tokenizer.py         # MythosTokenizer (envoltorio de openai/gpt-oss-20b)
├── variants.py          # Escalas preconfiguradas: mythos_1b ~ mythos_1t
├── docs/
│   ├── open_mythos.md   # Referencia completa de la API
│   └── datasets.md      # Recomendaciones para elegir conjuntos de datos
training/
└── 3b_fine_web_edu.py   # Script de entrenamiento en una sola GPU / multi-GPU
examples/
├── moda_example.py          # Demostración de MoE FFN + adaptador LoRA
└── variants_example.py     # Comparativa de parámetros entre variantes de múltiples escalas
tests/
├── test_main.py             # Pruebas unitarias del módulo central
├── bench_vs_transformer.py  # Comparativa de benchmarks vs Transformer estándar
└── small_benchmark.py       # Benchmark de rendimiento a pequeña escala

Pasos guiados

Paso 1 — Instalación

pip install open-mythos

WARNING

La compilación de flash-attn requiere CUDA Toolkit y nvcc. Si falla la instalación en un entorno sin nvcc, OpenMythos se degradará automáticamente al uso de la implementación estándar de PyTorch para la atención; no afecta la corrección, solo la velocidad.

Paso 2 — Construir la configuración

Todos los hiperparámetros se pasan mediante MythosConfig. Para entender algunos campos clave:

from open_mythos.main import MythosConfig

cfg = MythosConfig(
    vocab_size=1000,        # Tamaño del vocabulario; demo con vocabulario pequeño
    dim=256,                # Dimensión del espacio latente
    n_heads=8,              # Número de cabezas de Query
    n_kv_heads=2,          # Número de cabezas KV (GQA: menos cabezas que Q ahorra memoria)
    max_seq_len=128,        # Longitud máxima de secuencia (límite de precálculo para RoPE)
    max_loop_iters=4,       # Profundidad del bucle T; ajustable al alza en inferencia
    prelude_layers=1,       # Número de capas estándar en la sección Prelude
    coda_layers=1,          # Número de capas estándar en la sección Coda
    attn_type="mla",        # "mla" o "gqa"; ver Paso 5
    n_experts=8,            # Número total de expertos en MoE
    n_shared_experts=1,     # Número de expertos residentes (se activan para cada token)
    n_experts_per_tok=2,    # Número de expertos top-K activados por token
    expert_dim=64,          # Dimensión oculta de cada experto
    lora_rank=8,            # Rango del adaptador LoRA de profundidad
)

MythosConfig incluye un constructor por defecto; llamar directamente MythosConfig() utiliza un conjunto de valores preestablecidos de tamaño medio.

Paso 3 — Inicializar el modelo y ejecutar la inferencia forward

import torch
from open_mythos.main import OpenMythos, MythosConfig

cfg = MythosConfig()
model = OpenMythos(cfg)

# Contabilizar el número total de parámetros
total = sum(p.numel() for p in model.parameters())
print(f"Parameters: {total:,}")

# Forward: input_ids con forma (B, T); logits con forma (B, T, vocab_size)
ids = torch.randint(0, cfg.vocab_size, (2, 16))   # batch=2, seq=16
logits = model(ids, n_loops=4)                    # 4 iteraciones de inferencia en bucle
print(f"Logits shape: {logits.shape}")            # torch.Size([2, 16, 32000])

n_loops controla la profundidad del bucle. El valor por defecto proviene de cfg.max_loop_iters; en inferencia puedes aumentarlo. Esta es una característica clave de RDT: extrapolación de profundidad (depth extrapolation), es decir, entrenar con N iteraciones en bucle y razonar en inferencia con N+k, para abordar problemas más complejos.

Paso 4 — Generación autoregresiva

# Genera nuevos tokens, hasta 8; profundidad del bucle = 8
out = model.generate(ids, max_new_tokens=8, n_loops=8)
print(f"Generated shape: {out.shape}")  # torch.Size([2, 24])

El método generate mantiene internamente el KV cache: la primera llamada procesa el prompt completo y, en las llamadas posteriores, decodifica solo un token por vez. temperature controla la aleatoriedad del muestreo y top_k limita el rango de muestreo:

out = model.generate(
    ids,
    max_new_tokens=64,
    n_loops=16,
    temperature=0.8,   # Menor = más determinista
    top_k=40,          # 0 = desactivar
)

Paso 5 — Elegir la atención: MLA vs GQA

# Multi-Latent Attention (predeterminado; recomendado para contextos grandes)
cfg_mla = MythosConfig(
    attn_type="mla",
    kv_lora_rank=512,      # Dimensión latente de KV cache (cuanto menor, menos memoria)
    q_lora_rank=1536,      # Dimensión de compresión de Q
    qk_rope_head_dim=64,   # Dimensión por cabeza con RoPE
    qk_nope_head_dim=128,  # Dimensión por cabeza sin RoPE
    v_head_dim=128,
)

# Grouped Query Attention (amigable con memoria; con flash-attn suele ser eficiente)
cfg_gqa = MythosConfig(
    attn_type="gqa",
    n_kv_heads=4,         # Menos que n_heads; el cache KV se reduce por (n_heads/n_kv_heads)
)

Cómo decidir: MLA comprime el KV en un caché de vectores latentes de baja dimensión, reduciendo el uso de memoria de ~10–20 veces; pero en cada paso hay que reconstruir K/V (una proyección lineal). GQA cachea directamente las cabezas KV completas y, junto con Flash Attention 2, ofrece IO óptimo. A escala de producción, MLA ahorra más memoria; en la fase de desarrollo, GQA suele ser más sencillo para depurar.

Paso 6 — Verificar la estabilidad del bucle: comprobación de radio espectral

El problema más frecuente al entrenar RDT es la divergencia del bucle: el estado oculto crece de forma exponencial en cada iteración. OpenMythos garantiza estabilidad por construcción mediante inyección estable LTI; el método de verificación es revisar el radio espectral ρ(A):

# Obtener la matriz de estado discretizada A_discrete
A = model.recurrent.injection.get_A()           # forma (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

Si en tu entrenamiento personalizado detectas rho >= 1, no intentes corregirlo ajustando manualmente parámetros. Eso indica que la parametrización de tu inyección LTI fue eludida. Revisa si asignaste incorrectamente injection.log_A o injection.log_dt directamente.

Paso 7 — Usar variantes de escala preconfiguradas

¿No quieres preparar tú mismo MythosConfig? variants.py ofrece preajustes desde 1B hasta 1T:

from open_mythos import mythos_1b, mythos_3b, mythos_10b, mythos_50b, mythos_100b

# mythos_7b() devuelve MythosConfig
cfg = mythos_3b()
model = OpenMythos(cfg)
print(f"Variante 3B: {sum(p.numel() for p in model.parameters()):,} params")
VariantedimExpertsProfundidad del bucleContextoSalida máxima
mythos_1b204864164k4k
mythos_3b307264164k4k
mythos_10b4096128248k4k
mythos_100b8192256321M128k

Paso 8 — Ejecutar el script de entrenamiento

El proyecto incluye el script de entrenamiento del modelo 3B en el dataset FineWeb-Edu:

# Una GPU
python training/3b_fine_web_edu.py

# Multi-GPU (detecta automáticamente el número de GPUs)
torchrun --nproc_per_node=$(python -c "import torch; print(torch.cuda.device_count())") \
    training/3b_fine_web_edu.py

TIP

Por defecto, el entrenamiento usa el subconjunto sample-10BT (30B tokens), ideal para validar rápidamente. Para ejecutar el subconjunto completo de 100BT, cambia el parámetro dataset_name del script a "sample-100BT".

Configuración clave del entrenamiento:

# training/3b_fine_web_edu.py (parámetros clave)
optimizer = torch.optim.AdamW(model.parameters(), lr=3e-4, weight_decay=0.1)
# Precisión: H100/A100 usan bfloat16; GPUs antiguas usan float16 + GradScaler
# Scheduler: warmup de 2000 steps → decaimiento coseno
# Tokenizer: openai/gpt-oss-20b vía MythosTokenizer

Solución de problemas (FAQ)

1. Explosión de memoria: trampa de la combinación entre número de bucles y tamaño del batch

La fase de bucle de RDT no es como en el Transformer estándar, donde las capas son independientes entre sí: en cada paso de bucle, el estado KV de todos los tokens se acumula en el cache. Con 16 bucles × secuencia de 4096 × batch 8, la presión de memoria es varias veces la de un modelo convencional.

Solución: primero usa un n_loops pequeño (p. ej., 4) para validar; tras converger, aumenta gradualmente. El batch debe escalarse linealmente, no mantenerse fijo.

2. Falta Flash Attention, pero quieres acelerar

Si falla la compilación de flash-attn (común en Windows + entornos CUDA), OpenMythos degradará automáticamente a la atención nativa de PyTorch. Ten en cuenta que esta degradación no afecta la corrección, solo la velocidad: en escenarios de lotes pequeños, la diferencia no suele ser grande.

3. Fallo en la comprobación de radio espectral: divergencia del entrenamiento

Si modificaste la parametrización de LTIInjection, o al hacer fine-tuning congelaste capas incorrectas que rompen los parámetros de injection, puede aparecer ρ(A) >= 1. No recortes (clippees) directamente los parámetros: vuelve a empezar desde la inicialización por defecto. La restricción LTI depende de la estructura parametrizada, no de correcciones “a posteriori”.

4. ACT detiene antes de tiempo: el bucle real tiene menos iteraciones

act_threshold=0.99 significa que en cada posición, cuando se acumula el 99% de la probabilidad, el modelo sale de forma anticipada. Si en algunas tareas observas que el número real de iteraciones es muy inferior a n_loops, revisa la distribución de dificultad de los tokens en tus datos: los tokens demasiado sencillos disparan el halting demasiado pronto y los tokens complejos no reciben la profundidad suficiente.

5. Colapso del routing MoE: algunos expertos nunca se activan

Las pérdidas auxiliares tipo DeepSeekMoE para balance de carga sin pérdidas dependen de un ajuste dinámico mediante router_bias. Si no llamaste a esta lógica de ajuste desde el entrenamiento desde cero, el router convergerá rápidamente a activar solo un subconjunto pequeño de expertos (normalmente los primeros 1–2). En el proyecto, MoEFFN.forward ya incluye un placeholder para el ajuste del bias, pero en scripts de entrenamiento personalizados necesitas llamar periódicamente a la lógica de actualización del bias.

6. Calidad de generación baja: cómo configurar temperature y top_k

Escenariotemperaturetop_kNotas
Código / Matemáticas0.3–0.510–20Aleatoriedad baja
Escritura creativa0.7–0.90 (desactivado)Alta diversidad
Depuración / Validación de inferencia0.0 (greedy)1Máxima determinación

Lecturas adicionales / Direcciones avanzadas

Artículos clave

ArtículoProblema que resuelve
Loop, Think & Generalize (2025)Cómo un Transformer recurrente realiza razonamiento implícito en el espacio latente
Parcae (Prairie et al., 2026)Leyes de escalado: cómo las restricciones LTI garantizan la estabilidad del bucle
DeepSeekMoE (Dai et al., 2024)Diseño de routing MoE de grano fino + expertos compartidos
DeepSeek-V2 MLA (2024)Principio de compresión KV de Multi-Latent Attention
Relaxed Recursive Transformers (Bae et al., 2024)Cómo los adaptadores LoRA mejoran la capacidad de representación del bucle sin añadir demasiados parámetros

Direcciones avanzadas

1. Crear un LoRA Adapter personalizado: el lora_rank actual es global y uniforme; puedes convertirlo en una configuración por capa para que distintas profundidades de bucle usen distintos niveles de intensidad de adaptación.

2. Barrido de umbrales ACT: el valor por defecto 0.99 es una heurística. Ejecuta una búsqueda en malla de 0.8–0.999 y verás que en algunas tareas 0.95 rinde mejor que 0.99 (el early stop evita el overthinking).

3. Experimentos de Depth Extrapolation: entrena con un n_loops fijo y luego, durante la inferencia, barre n_loops; traza una curva de “número de iteraciones de bucle → exactitud en tareas downstream”. Teóricamente deberías ver una forma de decaimiento exponencial; es una de las propiedades más importantes y demostrables de RDT.

4. Comparar contra Transformer estándar: usa el script bench_vs_transformer.py para comparar, con la misma cantidad de parámetros, las diferencias entre el modelo recurrente y el modelo estándar en tareas de generalización composicional / sistemática. Este es el escenario donde RDT muestra su ventaja más destacada.

Updated April 26, 2026