GPT-6 Astra 的循环深度:从传闻到可验证的 Transformer 实验

2026-09-10 42 预计阅读时间: 1 分钟
来源: oschina.net AI 摘要 Original link

Disclaimer: This article is an AI-assisted summary. Read it together with the original source when precision matters. The summary may omit context, version differences, or edge cases and is not official documentation.

预计阅读时间:12 分钟

Sebastian Raschka 试用 GPT-6 Astra 后,给出了相当高的评价,甚至称它可能是自己用过的最好的模型。但那篇长文更值得关注的地方,不是再次讨论模型“有多强”,而是追问一个尚未被证实的技术传闻:Astra 是否采用了循环深度(looped transformer)架构。

这个问题的价值在于,它把讨论从模型排行榜拉回到了架构设计:一个 Transformer 层,是否可以被重复执行多次?如果可以,重复计算究竟是在增加推理能力,还是只是在堆叠更多计算?而所谓“隐藏的推理链”,又是否真的等同于我们看到的思维过程?

什么是循环 Transformer

普通 Transformer 通常由多层不同参数的模块组成。以一个简化模型为例:

x -> Layer 1 -> Layer 2 -> Layer 3 -> Layer 4 -> output

每一层都有自己的注意力和前馈网络参数。循环 Transformer 则可能采用类似下面的结构:

x -> Shared Layer -> Shared Layer -> Shared Layer -> Shared Layer -> output

这里的关键不是“调用了四次”这么简单,而是这四次调用共享同一套参数。模型可以在固定的参数规模下,增加中间状态的更新次数,让表示逐步变得更精细。

用数学形式表示,普通多层结构可以写成:

h₁ = F₁(h₀)
h₂ = F₂(h₁)
h₃ = F₃(h₂)

循环结构则更接近:

h₁ = F(h₀)
h₂ = F(h₁)
h₃ = F(h₂)

其中 F 在每一步使用同一组参数。实际系统也可能加入循环次数预测、早停机制、残差连接、位置编码处理,以及不同 token 使用不同计算步数等设计。因此,“looped transformer”并不自动对应某一个唯一实现。

更准确地说,循环深度是一种计算组织方式,而不是一个已经被公开确认的 Astra 内部细节。现有讨论可以帮助我们理解这种架构为什么合理,但不能据此断言 Astra 必然采用了它。

为什么这种结构值得关注

1. 参数规模和计算深度可以分开调节

传统模型想增加网络深度,通常需要增加更多带独立参数的层。循环结构可以重复使用一个模块,在参数量增长较慢的情况下增加计算深度。

这并不意味着它能“免费”获得能力。重复执行仍然会增加推理延迟、显存访问和能耗,只是参数复用可能改善了模型规模与计算预算之间的关系。

2. 它更像是在迭代求解

一些任务并不适合一次前向传播就得到最终答案。例如,模型可能需要先形成候选解释,再检查约束,最后修正输出。循环模块提供了一种内部迭代的可能:

初始表示 -> 草拟 -> 检查 -> 修正 -> 稳定表示

这与显式输出一大段“思维链”不同。模型可以在隐藏状态中进行多次更新,最终只输出答案。所谓隐藏推理链,如果这个说法成立,更接近“多步内部计算”,而不是一段可以直接读取的自然语言草稿。

3. 计算步数可以成为一种资源分配策略

如果模型能够判断某个输入需要多少次循环,那么简单问题可以少算几步,复杂问题则获得更深的计算。这类机制通常被称为自适应计算或动态深度。

但它也带来新的工程难题:循环次数如何学习?早停信号是否可靠?不同输入之间的延迟是否会变得不可预测?当服务需要严格的延迟预算时,动态深度未必比固定深度更容易部署。

用 PyTorch 做一个最小实验

下面的代码不是 Astra 的实现,而是一个可以运行和改造的教学模型。它用同一个 Transformer block 重复处理隐藏状态,并比较不同循环次数下的输出。运行前安装 PyTorch:

python -m pip install torch

保存为 looped_transformer_demo.py

import torch
from torch import nn


class LoopedTransformer(nn.Module):
    def __init__(self, vocab_size=1000, d_model=128, nhead=4, max_steps=4):
        super().__init__()
        self.token_embedding = nn.Embedding(vocab_size, d_model)
        self.position_embedding = nn.Embedding(128, d_model)

        # 只有一个 block,后面会重复使用它
        self.block = nn.TransformerEncoderLayer(
            d_model=d_model,
            nhead=nhead,
            dim_feedforward=4 * d_model,
            batch_first=True,
            norm_first=True,
        )
        self.final_norm = nn.LayerNorm(d_model)
        self.lm_head = nn.Linear(d_model, vocab_size)
        self.max_steps = max_steps

    def forward(self, token_ids, steps=None):
        batch_size, seq_len = token_ids.shape
        if seq_len > 128:
            raise ValueError("sequence length must be <= 128")

        if steps is None:
            steps = self.max_steps
        if not 1 <= steps <= self.max_steps:
            raise ValueError("steps must be between 1 and max_steps")

        positions = torch.arange(seq_len, device=token_ids.device)
        hidden = (
            self.token_embedding(token_ids)
            + self.position_embedding(positions)[None, :, :]
        )

        for _ in range(steps):
            hidden = self.block(hidden)

        return self.lm_head(self.final_norm(hidden))


if __name__ == "__main__":
    torch.manual_seed(7)
    model = LoopedTransformer(max_steps=6)
    tokens = torch.randint(0, 1000, (2, 12))

    for steps in (1, 2, 4, 6):
        logits = model(tokens, steps=steps)
        print(f"steps={steps}, shape={tuple(logits.shape)}")

运行:

python looped_transformer_demo.py

这个实验能观察到三件事:模型参数仍然只有一个共享 block;改变 steps 不需要改变模型结构;每增加一次循环,计算量和延迟都会上升。

如果要把它变成一个更接近研究原型的版本,可以继续加入一个 halting head,让模型为每个样本预测是否继续循环:

halt_probability = torch.sigmoid(self.halt_head(hidden[:, -1]))

不过这只是接口层面的示意。真正的动态早停还需要处理批次内不同样本步数不一致的问题,也需要设计训练目标,避免模型过早停止或无意义地循环。

不要把隐藏状态等同于可验证的推理链

“隐藏的推理链”这个表述很容易造成误解。即使一个模型确实进行了多轮内部计算,也不能直接推出以下结论:

  • 模型内部存在类似人类语言的完整思维句子;
  • 循环次数越多,答案就一定越可靠;
  • 通过读取某些中间激活,就能还原模型真正的推理过程;
  • 所有复杂问题都会使用相同的内部计算路径。

隐藏状态是高维向量,包含语义、上下文、预测和控制信号的混合信息。它可以被探针、激活缓存或可解释性工具分析,但分析结果通常是近似证据,不是天然透明的“思维记录”。

对工程团队而言,更可操作的验证方式是观察外部行为:固定模型版本和提示词,比较不同任务上的准确率、延迟、token 使用量、重复调用稳定性,以及对干扰信息的敏感度。如果无法看到内部架构,就应该把循环深度当作一个待验证假设,而不是产品事实。

采用这类架构时要权衡什么

循环 Transformer 的吸引力主要在于参数复用和计算深度可调,但它并非单向优势。

可能的收益:

  • 用较少的独立参数实现更深的状态更新;
  • 为复杂样本分配更多计算;
  • 通过共享模块减少某些参数存储成本;
  • 为推理时的质量—延迟折中提供新的控制旋钮。

需要警惕的问题:

  • 重复计算会增加推理延迟;
  • 共享参数可能限制不同阶段学习完全不同的功能;
  • 深度增加不一定带来稳定的质量提升;
  • 动态早停会让延迟和容量规划更复杂;
  • 训练时的梯度传播可能更难控制,尤其是循环次数较大时。

如果团队想在自己的模型中试验,建议先做一个小型对照实验:保持词表、训练数据、优化器和总训练 token 不变,只比较独立层堆叠与共享层循环两种方案,并记录验证损失、任务准确率、峰值显存、单请求延迟和不同循环次数的收益曲线。

结语:把传闻变成可检验的问题

Astra 的讨论真正有启发性的地方,不在于我们现在就能确认它用了哪种架构,而在于它提醒工程师重新审视“深度”这件事:深度未必只等于更多不同的层,也可能意味着对同一内部状态进行更多次有目的的更新。

在没有公开架构细节之前,比较稳妥的结论是:循环 Transformer 是一种值得实验的设计,隐藏推理可以作为一种计算行为来研究,但不能直接当作已证实的内部机制。

落地时可以按这份清单推进:

  • 明确区分公开事实、作者推测和自己的实验结果;
  • 用固定预算比较独立层与共享层,而不是只看参数量;
  • 同时测质量、延迟、显存和能耗;
  • 对动态深度设置最大循环次数和超时边界;
  • 不把中间激活的可解释性宣传成完整思维链;
  • 只有在重复实验和消融结果一致时,才把架构假设纳入生产决策。

相关推荐