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")
| Variante | dim | Experts | Profundidade do loop | Contexto | Saída máxima |
|---|---|---|---|---|---|
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 |
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ário | temperature | top_k | Observação |
|---|---|---|---|
| Código / Matemática | 0.3–0.5 | 10–20 | Baixa aleatoriedade |
| Escrita criativa | 0.7–0.9 | 0 (desligado) | Alta diversidade |
| Debug / validação de inferência | 0.0 (greedy) | 1 | Máxima determinismo |
Leitura adicional / Direções avançadas
Artigos-chave
| Artigo | Problema 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.