OpenMythos 入门:基于 Claude Mythos 循环推理架构的开源实现

2026年4月26日

TIP

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

项目简介

2026 年 4 月,Anthropic 推出了 Claude Mythos——Claude 系列的下一代推理模型,在软件工程、网络安全(尤其是零日漏洞发现与利用)等任务上展现出前所未有的能力。不过 Mythos 目前仅通过 "Project Glasswing" 有限开放给部分防御性安全研究合作伙伴,远未全面发布。

OpenMythos 就是社区对这一封闭架构的开源回应:由独立开发者 Kye Gomez 基于公开论文和研究文献,从第一性原理重建了 Mythos 的核心架构。它不是官方版本,不是权重泄露,而是一个理论重建(theoretical reconstruction)——目的是让研究者和开发者能够实验验证类似想法。

它的核心突破是 Recurrent-Depth Transformer(RDT):同一个 Transformer 权重在单次前向传播中循环执行最多 16 次(可配置),以迭代方式在连续隐空间中完成"思考",而非像传统模型那样堆叠数百层独立权重。770M 参数的循环模型可以达到约 1.3B 标准 Transformer 的质量——同样的能力,少了一半的参数。


难度 / 时长 / 收获

入门级难度,约 30 分钟,带你跑通第一个 OpenMythos 前向传播,理解循环推理的本质、LTI 稳定注入的原理,以及 MoE FFN 如何在不增加激活参数的前提下扩展模型宽度。


目标读者

对 LLM 架构有基础了解,想深入理解"循环推理"机制及其工程实现的 1-5 年经验开发者。如果你对以下问题感兴趣,OpenMythos 是个好起点:

  • 为什么"更多循环 = 更深推理"这件事本身是有理论支撑的
  • LTI 动力学约束如何保证循环训练不发散
  • MoE + 循环权重共享如何在参数量和计算量之间找到新平衡点

核心依赖与环境

  • Python 3.10+
  • PyTorch 2.0+(CUDA 支持可加速推理)
  • 可选:flash-attn >= 2.8.3(加速 GQA 注意力,IO 最优)
  • 最低硬件:CPU 可跑toy demo,GPU 可完整训练
# CPU only
pip install open-mythos

# with Flash Attention 2 (requires 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 模型单卡 / 多卡训练脚本
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 会自动降级到标准 PyTorch 注意力实现,不影响正确性,只影响速度。

步骤 2 — 构建配置

所有超参数通过 MythosConfig 传入。来理解几个关键字段:

from open_mythos.main import MythosConfig

cfg = MythosConfig(
    vocab_size=1000,        # 词表大小,demo 用小词表
    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,       # Prelude 段的标准 Transformer 层数
    coda_layers=1,          # Coda 段的标准 Transformer 层数
    attn_type="mla",        # "mla" 或 "gqa",见步骤 5
    n_experts=8,            # MoE 路由专家总数
    n_shared_experts=1,     # 常驻专家数(每个 token 都激活)
    n_experts_per_tok=2,    # 每个 token 激活的 top-K 专家数
    expert_dim=64,          # 每个专家的隐藏维度
    lora_rank=8,            # 深度 LoRA adapter 的秩
)

MythosConfig 有一个默认构造函数,直接 MythosConfig() 会使用一套中等规模的预设值。

步骤 3 — 初始化模型并运行前向传播

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:,}")

# 前向传播:input_ids shape (B, T),logits 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 次循环推理
print(f"Logits shape: {logits.shape}")            # torch.Size([2, 16, 32000])

n_loops 控制循环深度。默认值来自 cfg.max_loop_iters,推理时可以调高——这是 RDT 的关键特性:深度外推(depth extrapolation),即模型在训练时用 N 次循环,在推理时可以用 N+k 次,处理更复杂的问题。

步骤 4 — 自回归生成

# 生成新 token,最多 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,后续每次只解码一个 token。temperature 控制采样随机性,top_k 限制采样范围:

out = model.generate(
    ids,
    max_new_tokens=64,
    n_loops=16,
    temperature=0.8,   # 越低越确定性
    top_k=40,          # 0 = 关闭
)

步骤 5 — 选择注意力机制:MLA vs GQA

# Multi-Latent Attention(默认,推荐用于大上下文)
cfg_mla = MythosConfig(
    attn_type="mla",
    kv_lora_rank=512,      # 缓存的 KV 潜在维度(越小越省显存)
    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 压缩成低秩潜在向量缓存,显存减少约 10–20 倍,但每次需要重建 K/V(一个线性投影);GQA 直接缓存完整 KV 头,配合 Flash Attention 2 时 IO 最优。生产规模下 MLA 更省显存,开发阶段 GQA 调试更简单。

步骤 6 — 验证循环稳定性:谱半径检查

RDT 训练最容易出的问题是循环发散——hidden state 在每次循环中指数级放大。OpenMythos 通过 LTI 稳定注入 从构造上保证了稳定性,验证方法是检查谱半径 ρ(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.log_Ainjection.log_dt

步骤 7 — 使用预置规模变体

不想手配 MythosConfigvariants.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")
变体dimExperts循环深度上下文最大输出
mythos_1b204864164k4k
mythos_3b307264164k4k
mythos_10b4096128248k4k
mythos_100b8192256321M128k

步骤 8 — 运行训练脚本

项目内置了 FineWeb-Edu 数据集上的 3B 模型训练脚本:

# 单 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 token),适合快速验证。要跑完整 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 via MythosTokenizer

常见问题排查

1. 显存爆炸:循环次数 × 批次大小的组合陷阱

RDT 的循环阶段不像标准 Transformer 那样层间独立——每个循环步骤都会把所有 token 的 KV 状态累积到 cache。循环 16 次 × 序列 4096 × 批次 8,显存压力是普通模型的数倍。

解法:先用小 n_loops(如 4)验证,收敛后再逐步增加;批次按线性缩放而非固定。

2. Flash Attention 缺失但想加速

安装 flash-attn 编译失败时(常见于 Windows + CUDA 环境),OpenMythos 会自动降级到 PyTorch 原生注意力。注意这个降级不影响正确性,只影响速度——原生实现在小批量场景下差距不大。

3. 谱半径检查失败:训练发散

如果你自己改了 LTIInjection 的参数化,或在微调时 freeze 了错误的层导致 injection 参数被破坏,会出现 ρ(A) >= 1不要直接 clip 参数——回到默认初始化重新开始。LTI 约束靠的是参数化结构,不是事后修正。

4. ACT 提前停导致循环实际次数不足

act_threshold=0.99 意味着每个位置累积到 99% 概率后就会提前退出。如果你在某些任务上发现实际循环次数远低于 n_loops,检查数据中的 token 难度分布——太简单的 token 会过早触发 halting,导致复杂 token 得不到足够深度。

5. MoE 路由崩溃:某些专家永远不激活

DeepSeekMoE 风格的辅助损失-free 负载均衡依赖 router_bias 的动态调整。如果你从头训练没有调用这个调整逻辑,路由器会快速收敛到只激活少数专家(通常是前 1-2 个)。项目中 MoEFFN.forward 已内置了 bias 调整的占位,但在自定义训练脚本中需要定期调用 bias 更新逻辑。

6. 生成质量差:温度和 top_k 怎么配

场景temperaturetop_k备注
代码 / 数学0.3–0.510–20低随机性
创意写作0.7–0.90(关闭)高多样性
调试 / 推理验证0.0(贪心)1最确定性

扩展阅读 / 进阶方向

核心论文

论文解决的问题
Loop, Think & Generalize (2025)循环 Transformer 如何在隐空间做隐式推理
Parcae (Prairie et al., 2026)LTI 约束保证循环稳定性的 Scaling Law
DeepSeekMoE (Dai et al., 2024)细粒度 MoE + 共享专家的路由设计
DeepSeek-V2 MLA (2024)Multi-Latent Attention 的 KV 压缩原理
Relaxed Recursive Transformers (Bae et al., 2024)LoRA adapter 如何在不增加太多参数的前提下提升循环表达力

进阶方向

1. 自定义 LoRA Adapter:当前 lora_rank 是全局统一的,可以改成逐层配置,让不同循环深度使用不同的适配强度。

2. ACT 阈值扫描:默认 0.99 是一个经验值。跑一个 0.8–0.999 的网格搜索,你会发现在某些任务上 0.95 比 0.99 更好(早停避免了 overthinking)。

3. Depth Extrapolation 实验:用固定 n_loops 训练,然后在推理时 sweep n_loops,画一条"循环次数 → 下游任务准确率"的曲线。理论上应该看到指数衰减形状——这是 RDT 最重要的可证性质之一。

4. 对比标准 Transformer:用 bench_vs_transformer.py 脚本,在相同参数量下对比循环模型和标准模型在 compositional / systematic generalization 任务上的差距。这是 RDT 最显著的优势场景。

Updated 2026年4月26日