Introdução ao OpenMythos: implementação open-source de uma arquitetura de raciocínio em loop baseada no ciclo Claude Mythos

April 26, 2026

TIP

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

Visão geral do projeto

Em abril de 2026, a Anthropic lançou o Claude Mythos — o próximo modelo de raciocínio da família Claude — demonstrando capacidades sem precedentes em tarefas como engenharia de software e cibersegurança (especialmente descoberta e exploração de vulnerabilidades zero-day). No entanto, o Mythos ainda está apenas disponibilizado de forma limitada por meio do "Project Glasswing" para alguns parceiros de pesquisa de segurança defensiva, estando muito longe de um lançamento completo.

O OpenMythos é a resposta open-source da comunidade a essa arquitetura fechada: desenvolvido por um autor independente, Kye Gomez, que reconstruíu a arquitetura central do Mythos a partir de primeiros princípios com base em papers e literatura de pesquisa publicamente disponíveis. Não é uma versão oficial, nem vazamento de pesos; é uma reconstrução teórica (theoretical reconstruction) — com o objetivo de permitir que pesquisadores e desenvolvedores experimentem e validem ideias semelhantes.

Sua grande descoberta é o Recurrent-Depth Transformer (RDT): as mesmas pesos do Transformer são reutilizadas e executadas em loop até 16 vezes (configurável) em uma única passada forward; assim, o "pensamento" é feito de forma iterativa em um espaço latente contínuo — em vez de empilhar centenas de camadas com pesos independentes como nos modelos tradicionais. Um modelo em loop de 770M parâmetros pode atingir cerca de a qualidade de um Transformer padrão de ~1.3B parâmetros — com a mesma capacidade, mas com metade dos parâmetros.


Dificuldade / Duração / O que você ganha

Dificuldade para iniciantes, cerca de 30 minutos: te ajuda a rodar a sua primeira passada forward do OpenMythos, entendendo a essência do raciocínio em loop, o princípio da injeção estável via LTI e como o MoE FFN consegue ampliar a largura do modelo sem aumentar o número de parâmetros de ativação.


Público-alvo

Desenvolvedores com conhecimento básico de arquitetura de LLMs e que querem aprofundar na compreensão do mecanismo de "raciocínio em loop" e sua implementação em engenharia, com 1 a 5 anos de experiência. Se você se interessa por perguntas como estas, o OpenMythos é um bom ponto de partida:

  • Por que a ideia de "mais loops = mais profundidade de raciocínio" tem suporte teórico em si
  • Como as restrições dinâmicas da LTI garantem que o treino em loop não divirja
  • Como MoE + compartilhamento de pesos em loop encontram um novo equilíbrio entre número de parâmetros e custo computacional

Dependências principais e ambiente

  • Python 3.10+
  • PyTorch 2.0+ (suporte a CUDA para acelerar a inferência)
  • Opcional: flash-attn >= 2.8.3 (acelera a atenção GQA, IO ótimo)
  • Hardware mínimo: CPU consegue rodar um toy demo; GPU consegue fazer o treino completo
# apenas CPU
pip install open-mythos

# com Flash Attention 2 (requer CUDA + ferramentas de build)
pip install "open-mythos[flash]"

Estrutura completa do projeto

open_mythos/
├── main.py              # Núcleo: classe OpenMythos, MythosConfig e todos os componentes da arquitetura
├── moda.py              # Módulos como MoE / LoRA
├── tokenizer.py         # MythosTokenizer (wrapper de openai/gpt-oss-20b)
├── variants.py          # Escalas predefinidas: mythos_1b ~ mythos_1t
├── docs/
│   ├── open_mythos.md   # Referência completa da API
│   └── datasets.md      # Recomendações para seleção de datasets de treino
training/
└── 3b_fine_web_edu.py   # Script de treino single card / multi card para modelo 3B
examples/
├── moda_example.py          # Demonstração de MoE FFN + LoRA Adapter
└── variants_example.py     # Comparação de parâmetros entre variantes de múltiplas escalas
tests/
├── test_main.py             # Testes unitários do módulo principal
├── bench_vs_transformer.py  # Comparação de baseline com Transformer padrão
└── small_benchmark.py       # Benchmark de performance em pequena escala

Passo a passo

Passo 1 — Instalação

pip install open-mythos

WARNING

A compilação do flash-attn exige CUDA Toolkit e nvcc. Se a instalação falhar em um ambiente sem nvcc, o OpenMythos fará automaticamente downgrade para a implementação padrão de atenção do PyTorch; isso não afeta a correção, apenas a velocidade.

Passo 2 — Construir a configuração

Todos os hiperparâmetros são passados via MythosConfig. Para entender alguns campos-chave:

from open_mythos.main import MythosConfig

cfg = MythosConfig(
    vocab_size=1000,        # Tamanho do vocabulário; demo usa um vocabulário pequeno
    dim=256,                # Dimensão do espaço latente
    n_heads=8,              # Número de heads de Query
    n_kv_heads=2,          # Número de heads de KV (GQA: menos heads que Q economiza memória de GPU)
    max_seq_len=128,        # Comprimento máximo da sequência (limite para pré-cálculo do RoPE)
    max_loop_iters=4,       # Profundidade do loop T; pode ajustar para mais alto na inferência
    prelude_layers=1,       # Número de camadas Transformer padrão na seção Prelude
    coda_layers=1,          # Número de camadas Transformer padrão na seção Coda
    attn_type="mla",        # "mla" ou "gqa"; veja o Passo 5
    n_experts=8,            # Total de especialistas no MoE
    n_shared_experts=1,     # Número de especialistas que ficam sempre ativos (ativados por token)
    n_experts_per_tok=2,    # Top-K de especialistas ativados por token
    expert_dim=64,          # Dimensão oculta de cada especialista
    lora_rank=8,            # Rank do adapter LoRA de profundidade
)

O MythosConfig tem um construtor padrão; chamar diretamente MythosConfig() usa um conjunto de valores predefinidos em escala média.

Passo 3 — Inicializar o modelo e executar a passada forward

import torch
from open_mythos.main import OpenMythos, MythosConfig

cfg = MythosConfig()
model = OpenMythos(cfg)

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

# forward: input_ids com shape (B, T), logits com shape (B, T, vocab_size)
ids = torch.randint(0, cfg.vocab_size, (2, 16))   # batch=2, seq=16
logits = model(ids, n_loops=4)                    # 4 iterações de inferência em loop
print(f"Logits shape: {logits.shape}")            # torch.Size([2, 16, 32000])

n_loops controla a profundidade do loop. O valor padrão vem de cfg.max_loop_iters; na inferência, você pode aumentar — este é um recurso-chave do RDT: extrapolação de profundidade (depth extrapolation), isto é, treinar com N loops e, na inferência, usar N+k para lidar com problemas mais complexos.

Passo 4 — Geração autoregressiva

# gera novos tokens (máximo 8); profundidade do loop 8
out = model.generate(ids, max_new_tokens=8, n_loops=8)
print(f"Generated shape: {out.shape}")  # torch.Size([2, 24])

O método generate mantém internamente o KV cache: a primeira chamada processa o prompt completo; nas chamadas seguintes, cada iteração decodifica apenas um token. temperature controla a aleatoriedade da amostragem e top_k limita o intervalo de amostragem:

out = model.generate(
    ids,
    max_new_tokens=64,
    n_loops=16,
    temperature=0.8,   # quanto menor, mais determinístico
    top_k=40,          # 0 desliga
)

Passo 5 — Escolher mecanismo de atenção: MLA vs GQA

# Multi-Latent Attention (padrão, recomendado para contextos grandes)
cfg_mla = MythosConfig(
    attn_type="mla",
    kv_lora_rank=512,      # dimensão latente do KV cache (quanto menor, mais economiza memória)
    q_lora_rank=1536,      # dimensão comprimida de Q
    qk_rope_head_dim=64,   # dimensão por head com RoPE
    qk_nope_head_dim=128,  # dimensão por head sem RoPE
    v_head_dim=128,
)

# Grouped Query Attention (amigável à memória; com flash-attn fica muito eficiente)
cfg_gqa = MythosConfig(
    attn_type="gqa",
    n_kv_heads=4,         # menor que n_heads; KV cache reduzido em n_heads/n_kv_heads
)

Trade-offs: o MLA comprime o KV em vetores latentes de baixa ordem para cache, reduzindo a memória de GPU em cerca de 10–20 vezes; porém, a cada passo é necessário reconstruir K/V (uma projeção linear). O GQA faz cache diretamente dos heads de KV completos; com Flash Attention 2, o IO fica ótimo. Em escala de produção, o MLA economiza mais memória; na fase de desenvolvimento, o GQA é mais fácil para depuração.

Passo 6 — Verificar estabilidade do loop: checagem do raio espectral

O problema mais fácil de ocorrer no treino do RDT é a divergência do loop — o estado oculto é amplificado exponencialmente em cada iteração. O OpenMythos garante a estabilidade por construção via injeção estável por LTI (LTI stable injection); o método de validação é checar o raio espectral ρ(A):

# obter matriz de estados discreta 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

Se você encontrar rho >= 1 no seu treino customizado, não tente ajustar manualmente os parâmetros — isso indica que a parametrização da sua injeção LTI está sendo contornada. Verifique se você não atribuiu equivocadamente diretamente injection.log_A ou injection.log_dt.

Passo 7 — Usar variantes de escala predefinidas

Não quer montar manualmente MythosConfig? O variants.py fornece predefinições de 1B até 1T:

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

# mythos_7b() retorna MythosConfig
cfg = mythos_3b()
model = OpenMythos(cfg)
print(f"Variant 3B: {sum(p.numel() for p in model.parameters()):,} params")
VariantedimExpertsProfundidade do loopContextoSaída máxima
mythos_1b204864164k4k
mythos_3b307264164k4k
mythos_10b4096128248k4k
mythos_100b8192256321M128k

Passo 8 — Rodar scripts de treino

O projeto inclui um script de treino do modelo 3B no dataset FineWeb-Edu:

# uma GPU
python training/3b_fine_web_edu.py

# múltiplas GPUs (detecta automaticamente a quantidade de GPUs)
torchrun --nproc_per_node=$(python -c "import torch; print(torch.cuda.device_count())") \
    training/3b_fine_web_edu.py

TIP

Por padrão, o treino usa o subconjunto sample-10BT (30B tokens), adequado para validar rapidamente. Para rodar o subconjunto completo de 100BT, altere o parâmetro dataset_name no script para "sample-100BT".

Configurações-chave do treino:

# training/3b_fine_web_edu.py (parâmetros chave)
optimizer = torch.optim.AdamW(model.parameters(), lr=3e-4, weight_decay=0.1)
# Precisão: H100/A100 usam bfloat16; placas mais antigas usam float16 + GradScaler
# Scheduler: warmup de 2000 passos → decaimento cosseno
# Tokenizer: openai/gpt-oss-20b via MythosTokenizer

Solução de problemas comuns

1. Explosão de memória de GPU: armadilha na combinação entre número de loops e tamanho de batch

A fase de loop do RDT não é independente entre camadas como no Transformer padrão — em cada passo de loop, o estado KV de todos os tokens é acumulado no cache. Fazer 16 loops × sequência 4096 × batch 8 gera uma pressão de memória várias vezes maior do que em um modelo comum.

Solução: use um n_loops pequeno (por exemplo 4) para validar primeiro; após convergir, aumente gradualmente; ajuste o batch com escala linear, não com valor fixo.

2. Falta de Flash Attention, mas quer acelerar

Se a compilação do flash-attn falhar (comum em Windows + ambiente CUDA), o OpenMythos faz downgrade automático para a atenção nativa do PyTorch. Esse downgrade não afeta a correção, apenas a velocidade — em cenários de batch pequeno, a diferença para a implementação nativa não costuma ser grande.

3. Checagem do raio espectral falha: divergência no treino

Se você alterou a parametrização do LTIInjection, ou se durante o fine-tuning congelou uma camada errada que acabou corrompendo os parâmetros da injeção, aparecerá ρ(A) >= 1. Não faça clip diretamente nos parâmetros — volte à inicialização padrão e recomece. A restrição LTI depende da estrutura parametrizada, não de uma correção posterior.

4. Parada prematura do ACT: o número real de loops fica abaixo do esperado

act_threshold=0.99 significa que cada posição sai assim que acumula 99% de probabilidade. Se em algumas tarefas você perceber que o número real de loops é bem menor que n_loops, verifique a distribuição de dificuldade dos tokens nos dados — tokens fáceis demais acionam halting cedo, e tokens complexos não recebem profundidade suficiente.

5. Roteamento do MoE falha: alguns especialistas nunca são ativados

O balanceamento de carga auxiliar no estilo DeepSeekMoE, sem loss adicional, depende de um ajuste dinâmico do router_bias. Se você treinou do zero sem chamar essa lógica de ajuste, o roteador converge rapidamente para ativar apenas poucos especialistas (tipicamente os 1–2 primeiros). No projeto, MoEFFN.forward já inclui um placeholder para o ajuste de bias, mas em scripts de treino customizados você precisa chamar periodicamente a lógica de atualização de bias.

6. Qualidade de geração ruim: como configurar temperature e top_k

Cenáriotemperaturetop_kObservação
Código / Matemática0.3–0.510–20Baixa aleatoriedade
Escrita criativa0.7–0.90 (desligado)Alta diversidade
Debug / validação de inferência0.0 (greedy)1Máxima determinismo

Leitura adicional / Direções avançadas

Artigos-chave

ArtigoProblema que resolve
Loop, Think & Generalize (2025)Como o Transformer em loop faz raciocínio implícito no espaço latente
Parcae (Prairie et al., 2026)Lei de Escala: restrições LTI garantem estabilidade do loop
DeepSeekMoE (Dai et al., 2024)Design de roteamento para MoE em granularidade fina + especialistas compartilhados
DeepSeek-V2 MLA (2024)Princípio de compressão do KV no Multi-Latent Attention
Relaxed Recursive Transformers (Bae et al., 2024)Como LoRA adapter melhora a capacidade de expressão em loop sem adicionar muitos parâmetros

Direções avançadas

1. Customizar LoRA Adapter: atualmente lora_rank é global e unificado; você pode mudar para configuração por camada, permitindo que diferentes profundidades de loop usem intensidades de adaptação distintas.

2. Scan do limiar do ACT: o valor padrão 0.99 é um chute baseado em experiência. Ao rodar uma busca em grade de 0.8–0.999, você vai perceber que em algumas tarefas 0.95 é melhor do que 0.99 (para evitar overthinking com parada precoce).

3. Experimentos de Depth Extrapolation: treine com n_loops fixo e, na inferência, varie o n_loops (sweep) e faça um gráfico da curva "número de loops → acurácia em tarefas downstream". Em teoria, deve aparecer um formato de decaimento exponencial — uma das propriedades mais importantes e verificáveis do RDT.

4. Comparar com Transformer padrão: use o script bench_vs_transformer.py para comparar o modelo em loop e o modelo padrão com a mesma quantidade de parâmetros em tarefas de compositional / systematic generalization. Este é o cenário em que o RDT mais se destaca.

Updated April 26, 2026