Nanbeige4.2-3B 在 Apple Silicon 上:修复部署 Bug 并减少 Looped Transformer 的内存开销

arXiv cs.AI 论文

摘要

本文讨论了 Nanbeige4.2-3B Looped Transformer 模型在 Apple Silicon 上的部署 bug,并引入了一种内存高效的分块预填充策略以支持 agentic 任务。

arXiv:2608.13987v1 公告类型:新 摘要: Nanbeige4.2-3B 是一个基于 Looped Transformer (LT) 构建的 3B 参数智能体模型,它通过重用一组层进行第二次前向传递,在不增加参数的情况下增加有效深度。在 Apple Silicon (MPS) 上评估时,我们识别出五个独立的 bug,这些 bug 阻止了发布的检查点通过 Hugging Face transformers 直接运行(包括一个静默清零的 RoPE 缓冲区和调用已移除的 transformers 缓存 API)。此外,我们表明,修复这些 bug 对于 agentic 任务仍然不够,因为用于实现参数效率的 LT 的层重用策略(实际上使峰值注意力内存翻倍)。因此,我们引入了一种分块预填充策略,以缓解由此产生的内存容量惩罚,在 32~GiB 共享内存上将允许的上下文宽度扩展了 $2.7 \times$。然而,即使内存开销减少,我们仍然表明需要补丁才能使 Nanbeige4.2-3B 可用;解决系统提示和 MPS 原生内存 bug 最终使得在标准 MCP 和工具调用基准测试上进行可靠评估成为可能。在 MCPMark 的一个子集上,调试后的模型完成多达 30\% 的真实 agentic 任务(从原始的 0\% 提升),而在 BFCL 上,它在单次工具调用中近乎完美(但在大多数多工具测试中失败)。我们在 https://github.com/johnhalloran321/Nanbeige4.2-3B-mps-fix 发布了补丁后的检查点、系统提示优化器和评估工具。
查看原文
查看缓存全文

缓存时间: 2026/08/17 09:59

# Nanbeige4.2-3B 在 Apple Silicon 上的部署:修复部署缺陷并降低循环 Transformer 内存开销
来源:https://arxiv.org/html/2608.13987
\setCJKmainfont FandolHei\-Regular\.otf
2026年8月14日

###### 摘要
Nanbeige4\.2\-3B (https://huggingface.co/Nanbeige/Nanbeige4.2-3B) (Nanbeige Team 2026 (https://arxiv.org/html/2608.13987#bib.bib3)) 是一个30亿参数的智能体模型,基于循环 Transformer (LT) (Bae et al\. 2026 (https://arxiv.org/html/2608.13987#bib.bib1)) 构建,该架构通过重用一组层进行第二次前向传播,在不增加参数的情况下增加了有效深度。我们在 Apple Silicon (MPS) 上对其进行了评估,发现了五个独立的缺陷,导致发布的检查点无法通过 Hugging Face transformers 开箱即用(包括一个被静默清零的 RoPE 缓冲区和调用已移除的 transformers 缓存 API)。此外,我们发现即使修复了这些缺陷,对于智能体任务仍然不够,因为 LT 的层重用策略(为了实现参数效率)实际上将峰值注意力内存翻倍。因此,我们引入了一种分块预填充策略,缓解了由此产生的内存容量惩罚,在 32 GiB 共享内存上将可允许的上下文宽度扩展了 2\.7 倍。然而,即使在降低内存开销后,我们表明仍需进行修补才能使 Nanbeige4\.2\-3B 可用;解决系统提示和 MPS 原生内存缺陷最终允许在标准 MCP 和工具调用基准测试上进行可靠评估。在 MCPMark 的一个子集上,调试后的模型完成了高达 30% 的真实智能体任务(从原始的 0% 提升),而在 BFCL 上,它在单次工具调用中接近完美(但在大多数多工具测试中失败)。我们在 github\.com/johnhalloran/Nanbeige4\.2\-3B\-mps\-fix (https://github.com/johnhalloran321/Nanbeige4.2-3B-mps-fix) 发布了修补后的检查点、系统提示优化器和评估工具。

## 1 引言
Nanbeige4\.2\-3B 最近作为一个强大的小型语言模型 (SLM) 发布,专门设计用于增强智能体任务的能力。该模型采用循环 Transformer (LT) 架构,以在无需扩大参数规模的情况下平衡解码计算。发布的模型卡片报告其在智能体和办公工作流基准测试上与更大的模型(Qwen3\.5\-4B, Qwen3\.5\-9B)具有竞争力或更好的结果 (Nanbeige Team 2026 (https://arxiv.org/html/2608.13987#bib.bib3)),这归功于其循环 Transformer 架构增加的有效深度。然而,在 MPS (Apple Silicon) 上通过 transformers 在 ReAct 风格的智能体框架中运行发布的检查点,会暴露出稳定性和正确性问题,导致模型无法开箱即用。本文中,我们识别了五个初始缺陷——例如,静默清零的 RoPE 缓冲区、调用已移除的 transformers 缓存 API 等——并给出了必要的修复方案,使发布的检查点在 MPS 上可用。然而,由于 LT 架构增加了内存需求,即使在 32 GiB 共享内存系统上以 bf16 格式运行 30亿 参数,修复后的模型对于智能体任务仍不可扩展;本质上,LT 以双倍峰值注意力内存为代价实现了参数效率(由于前向传播中层的递归循环),这禁止了智能体任务所需的长推理链。因此,我们引入了一种分块预填充策略来缓解 LT 的内存开销,将可允许的上下文宽度评估翻了一倍多。然而,修复后的模型暴露出进一步的不足:(1) 一旦调用者提供任何系统消息,Nanbeige4\.2\-3B 训练好的工具使用系统提示会被静默替换(而非合并),(2) 一个 MPS 内存不足 (OOM) 错误会永久降低服务进程的可用内存预算,仅在 MCPMark 上评估调试后的模型时出现。这一系列缺陷和模型修复——五个初始缺陷修复、一种替代预填充算法、系统提示纠正和 MPS 特定的 OOM 修复——使得在标准智能体和工具使用基准测试上对模型进行真正的可重现评估成为可能。

## 2 五个初始部署缺陷
通过 model=AutoModelForCausalLM\.from\_pretrained\(”Nanbeige/Nanbeige4\.2\-3B”, trust\_remote\_code=True, device=”mps”\) 在 Apple Silicon 上加载失败或静默错误地工作,有五个独立的原因。我们通过直接重现未修改的检查点确认了每一个缺陷。
1.  **1\. RoPE 缓冲区持久性(主导缺陷)**。模型的 `inv_freq` 旋转嵌入缓冲区在加载时被静默清零,并且在第一次前向传播前从未重新填充。因此 RoPE 对注意力贡献零位置信息:模型在不知道 token 顺序的情况下运行。这表现为看起来流畅但位置不连贯的生成,而不是崩溃,如果不直接检查加载后的缓冲区值,很容易错过。
2.  **2\. RoPE 配置分发 KeyError**。自定义建模代码中 RoPE 类型分发的一个错误,对部分原本有效的配置值引发 `KeyError`(表1 (https://arxiv.org/html/2608.13987#S2.T1))。这在模型构建期间触发,在设备放置或单次前向传播之前,并且不是 MPS 特定的(它会阻止在任何设备上加载)。
3.  **3\. 缓存 API 哨兵值不匹配**。直接使用默认 `past_key_values=None` 调用模型的 `forward()`,而不是通过 `generate()`,会调用当前 transformers 版本中已移除的 API (`DynamicCache\.from_legacy_cache(\.\.\.)`)。
4.  **4\. 位置 ID 重新截断**。自定义注意力代码中位置跟踪期间的一个错误,在 MPS 设备上特别会导致硬崩溃(在 CPU 上无法重现)。
5.  **5\. 绑定权重键格式**。不兼容的绑定权重键命名约定破坏了 `save_pretrained()`。即使成功修补、正在运行的模型也无法在没有额外修复的情况下重新序列化。
我们通过兄弟文件 monkeypatching(从不修改缓存的 transformers 包文件)在 johnhalloran/Nanbeige4\.2\-3B\-mps\-fix (https://huggingface.co/johnhalloran/Nanbeige4.2-3B-mps-fix) 检查点中修复了所有这五个缺陷。这五个缺陷都与第3节 (https://arxiv.org/html/2608.13987#S3)–4节 (https://arxiv.org/html/2608.13987#S4) 中讨论的内存或系统提示问题无关,这些问题在所有五个缺陷修复后依然存在。表1 (https://arxiv.org/html/2608.13987#S2.T1) 给出了每个缺陷的确切触发条件、未修改的 `modeling_nanbeige.py` 中的行号以及针对 transformers==5\.8\.1(本文使用的版本)的错误字符串或症状;完整的差异和重现脚本在产物仓库的 `patch/` 目录中(第6节 (https://arxiv.org/html/2608.13987#S6))。

表 1:针对 transformers==5\.8\.1,每个缺陷的确切触发条件、源代码行和错误/症状。行号指的是未修改的检查点。

## 3 循环 Transformer 的内存权衡
Nanbeige4\.2\-3B 的 LT (Bae et al\. 2026 (https://arxiv.org/html/2608.13987#bib.bib1)) 将隐藏状态通过完整的 $L$ 个物理 Transformer 层传递,然后在第二次前向传播中再次传递该传递的输出,最后产生 logits:从 $L$ 层的参数产生两次有效传递($2L$ 个有效层执行)。这实际上提高了模型质量,而无需扩大参数——例如,在固定参数预算下,LT 优于更大的非循环模型 (Bae et al\. 2026 (https://arxiv.org/html/2608.13987#bib.bib1))。然而,参数数量的保持是以额外的计算和内存需求为代价的。朴素地看,预填充期间自注意力的峰值激活内存主要由与 $\text{prompt\_len}^2$ 成正比的注意力分数张量物化主导。与非循环对应模型相比,LT 使所需的预填充内存翻倍,因为对相同提示的 $O(\text{prompt\_len}^2)$ 注意力计算在每次循环中重复一次。因此,尽管训练期间循环的权重共享节省了总参数数量,但朴素的预填充导致推理期间完整的二次注意力成本翻倍。对于在大型专用硬件(例如 H200)上的小型语言模型 (SLM),这种翻倍通常不是问题。然而,在 Apple Silicon 的统一内存上——内存由操作系统、竞争进程和模型共享,没有与 CUDA 内存管理相当的页面换出路径——对于智能体任务来说可能是灾难性的。

### 3\.1 通过分块预平衡循环内存使用
与*朴素预填充*(在单次前向传播中,每个循环迭代计算一次完整的 $(\text{prompt\_len} \times \text{prompt\_len})$ 注意力分数张量)相反,我们表明可以通过*分块预填充*显著降低 Nanbeige4\.2\-3B 的内存使用。分块预填充以固定大小的块处理提示,在块之间以与普通自回归解码相同的方式增量增长键值缓存。我们将单次调用 `model(input_ids=full_prompt, ...)` 的预填充替换为一个循环,该循环以固定大小的块(默认为 256 个 token)处理提示,在块之间增量增长 `DynamicCache`,然后将剩余部分交给 `generate()`:

```python
total_len = input_ids.shape[1]
if total_len <= chunk_size:
    return model.generate(
        input_ids=input_ids,
        max_new_tokens=max_new_tokens,
        **gen_kwargs
    )
cache = DynamicCache()
n_full_chunks = (total_len - 1) // chunk_size
with torch.no_grad():
    for i in range(n_full_chunks):
        start, end = i * chunk_size, i * chunk_size + chunk_size
        outputs = model(
            input_ids=input_ids[:, start:end],
            past_key_values=cache,
            use_cache=True,
            cache_position=torch.arange(start, end),
        )
        cache = outputs.past_key_values
return model.generate(
    input_ids=input_ids,
    past_key_values=cache,
    max_new_tokens=max_new_tokens,
    **gen_kwargs
)
```

这将每一步的峰值注意力分数张量限制在 $\text{chunk\_size} \times \text{running\-total}$,与提示长度无关,代价是将单次前向传播拆分为多个顺序子调用。已验证输出与朴素预填充逐位相同。

### 3\.2 LongBench\-Pro 结果
我们使用来自 LongBench\-Pro (Chen et al\. 2026 (https://arxiv.org/html/2608.13987#bib.bib2)) 的 50 个长样本和八种不同长度(从 1024 到 12,244 个 token)的单轮查询,展示了分块预填充 (CP) 相对于朴素预填充 (NP) 的内存优势。每个样本使用 Nanbeige4\.2\-3B 分词器进行标记化并截断到目标长度。为了测量最大内存吞吐量,我们通过将批量大小加倍直到失败来计算每种长度和预填充策略的最大批量大小,重复此过程 3 次。所有评估均在配备 32 GiB 共享内存的 Apple M2 Max 上进行。结果见表2 (https://arxiv.org/html/2608.13987#S3.T2)。

表 2:NP 与 CP 在 50 个 LongBench\-Pro 样本上的评估结果,取 3 次重复实验的平均值。"–" 表示该方法甚至无法完成批量大小=1 的情况。CP 下可能的最大长度 (11231) 显著大于 NP (4096)。然而,CP 以时间换取内存需求;在 $\text{prompt\_len}=1024$ 时,CP 允许两倍的批量并行性,同时仅比 NP 慢 22\.8%。这种权衡在 $\text{prompt\_len}=2048$ 时最为明显,此时 CP 允许 4 倍的批量并行性,同时慢 40\.9%。我们注意到,对于 CP,每个分块的子调用会产生固定成本,无论批量大小如何都需要支付 `chunk_size` 次。因此,当批量较大时,这个开销会被分摊,但当仅存在较小批量时,例如 $\text{prompt\_len}=4096$,它会成为总运行时间中更大的部分,其吞吐量低于对更长提示进行批量大小=1 的评估。我们注意到,通过内核融合将顺序的分块子调用折叠成更少的大 GPU 操作,将直接减少这个每调用开销。

## 4 系统提示回归
独立于先前讨论的内存问题,Nanbeige4\.2\-3B 的聊天模板(`chat_template\.jinja`,在 `{% if tools %}` 分支中)对 `messages[0]` 执行以下 if/else:
- • 如果调用者提供*任何*系统消息,它将按原样使用,模板会附加一个尾随 `\n\n`。
- • 否则,模板会注入一个硬编码的默认值(Nanbeige 自身训练的工具使用系统提示,以 “你是一位工具函数调用专家...” 开头\footnote{翻译:“你是一位工具函数调用专家。你将收到一个问题和一组可能的工具函数。根据问题,你需要进行一次或多次函数/工具调用来完成目标——请尽力通过工具探索解决问题。如果没有可用函数,请用自然语言直接回复用户。如果给定问题缺少函数所需的参数,请用自然语言向用户询问必要信息。如果调用结果已经足以回答用户的问题,请总结结果并用自然语言回复用户。”}),在随后的 `# Tools` 部分之前*没有*尾部分隔符。因此,任何调用者提供的系统消息都会静默丢弃模型自身的训练默认值,而不是扩展它。任何工具加用户消息的请求都会生成一个干净、正确格式化的单工具调用,但没有系统消息;如果添加了系统消息——即使像 “你是一个带有 MCP 工具的助手” 这样的消息——多工具调用输出会变成格式错误的文本。重新提供原始文本作为显式系统消息无法修复此行为。通过显式系统消息分支的逐字节相同内容仍然会中断,因为该分支自身自动附加的 `\n\n` 与零额外空格自动插入分支的输出恰好相差两个字符。发布的检查点的工具调用可靠性是基于其自身默认渲染路径产生的精确字节序列进行校准的,这与它的工具使用 SFT/RL 数据仅通过自动插入分支渲染,从未通过调用者提供的系统消息渲染相一致。
**修复**:从聊天模板中移除系统消息,以便模板采用其自身的零额外空格自动插入路径。然后在自动插入的默认值之后(永远不要通过默认模板的上述分支)将调用者的系统内容插入到渲染字符串中。这生成单工具调用输出的同时包含了调用者的系统内容。我们注意到一个密切相关的(但机制上不同的)缺陷已被独立报告于此模型:llama\.cpp PR \#26324 (https://github.com/ggml-org/llama.cpp/pull/26324) 记录了 Nanbeige4\.2\-3B 在大约 25% 的调用中输出带尾随空格而非 `\n`,破坏了该推理引擎中的标签匹配,并指出 Qwen3\-Coder 和 Qwen3\.5\-4B 也共享相同的模板结构(但未观察到触发相同的失败)。这两个缺陷位于相同的聊天模板/生成管道中,是该检查点工具调用可靠性对模板和空白敏感的独立证据。

## 5 评估
我们在 MCPMark (Wu et al\. 2025 (https://arxiv.org/html/2608.13987#bib.bib4)) 的 10 个任务子集上评估组合修复——该基准测试在多轮任务中测试 MCP 工具使用能力,同时对工具生成的响应进行评分——以及 Berkeley 函数调用排行榜 (BFCL) (Yan et al\. 2024 (https://arxiv.org/html/2608.13987#bib.bib5)) 的 150 个子集——该基准测试测试工具选择能力,不考虑工具执行输出。**MPS 内存缺陷**。运行端到端测试套件发现了一个与模型无关的缺陷:一个被捕获的 `RuntimeError: MPS back`

相似文章

Nanbeige/Nanbeige4.2-3B

Hugging Face Models Trending

Nanbeige4.2-3B 是一款紧凑型智能体模型,采用循环Transformer架构,在3B规模下展现出强大的智能体任务和推理基准性能,超越了Qwen3.5-9B和Gemma4-12B等更大规模的模型。

Nanbeige4.2-3B:在紧凑模式下释放智能体能力

arXiv cs.CL

Nanbeige4.2-3B 是一个紧凑的 3B 参数通用智能体模型,采用 Looped Transformer 从零开始预训练,在智能体和推理任务上表现出色,在多个基准测试中超越了更大的模型。该模型和代码均已开源。