自适应并行推理:高效推理扩展的下一个范例

The Berkeley Artificial Intelligence Research Blog Adaptive Parallel Reasoning: The Next Paradigm in Efficient Inference Scaling The BAIR Blog [!quote...
自适应并行推理:高效推理扩展的下一个范例
自适应并行推理:高效推理扩展的下一个范例
The Berkeley Artificial Intelligence Research Blog

Adaptive Parallel Reasoning: The Next Paradigm in Efficient Inference Scaling

The BAIR Blog

image

[!quote]+ 自适应并行推理系统

推理时,我们实际上是要求模型执行映射-还原操作:

  • 将问题分叉为子任务/线程,并发处理它们

  • 将它们合并为最终答案

图 5:叉连接推理设计

具体来说,模型会遇到一个子任务列表。然后,它将预填充每个子任务,并将其作为独立请求发送给推理引擎处理。然后,这些线程会同时进行解码,直到遇到结束标记或超过最大长度。这一过程会阻塞,直到所有线程完成解码,然后汇总结果。这在各种自适应并行推理方法中都很常见。但是,在聚合过程中会出现一个问题:分支中生成的内容无法在 KV 缓存级别上轻松聚合。这是因为独立线程中的标记从相同的位置 ID 开始,导致编码重叠,并在将 KV 缓存合并时产生非标准行为。同样,由于独立线程之间互不关注,因此它们合并后的 KV 缓存会产生非因果关注模式,而基础模型在训练过程中并没有看到这种模式。

为了解决这个问题,在如何执行聚合过程的问题上,该领域分成了两派,分别以修改推理引擎还是绕过推理引擎来定义。

**Multiverse 修改了推理引擎,以便在连接过程中重复使用 KV 缓存。**在深入了解 Multiverse(Yang 等人,2025 年)的内存管理之前,我们先来了解一下 KV 缓存在 "连接 "阶段之前是如何处理的。请注意每个独立线程是如何共享前缀序列(即子任务列表)的。如果不进行优化,每个线程都需要为前缀序列预填充和重新计算 KV 缓存。然而,SGLang 的 RadixAttention(Sheng 等人,2023 年)可以避免这种冗余,它将多个请求组织成一棵词缀树,一棵由不同长度的元素序列而不是单个元素组成的三角形(词缀树)。这样一来,新的 KV 缓存条目只能是独立线程生成的条目。

图 6:RadixAttention 的 KV 缓存管理策略

现在,如果一切顺利,所有独立线程都已从推理引擎返回。我们现在的目标是找出如何将它们合成为一个单一的序列,以便为下一步继续解码。事实证明,我们可以在合成阶段重复使用这些独立线程的 KV 缓存。具体来说,Multiverse(Yang 等人,2025 年)、Parallel-R1(Zheng 等人,2025 年)和 NPR(Wu 等人,2025 年)修改了推理引擎,将每个线程生成的 KV 缓存复制过来,并编辑页表,以便将非连续的内存块拼接成单个 KV 缓存序列。这避免了第二次预填充的冗余计算,并尽可能地重复使用现有的 KV 缓存。然而,这也有几个主要的局限性。

首先,这种方法需要修改推理引擎来执行非标准的内存处理,这可能会导致意想不到的行为。具体来说,由于合成请求会引用之前请求的 KV 缓存,因此会造成系统的脆弱性,并可能出现坏指针。在合成请求完成之前,另一个请求可能会进来并驱逐所引用的 KV 缓存,这就要求合成请求停止,并触发前一个线程请求的重新填充。这个问题导致 Multiverse 研究人员(Yang 等人,2025 年)限制了推理引擎可以处理的批量大小,从而限制了吞吐量。

图 7:多重宇宙推理过程中的 KV 缓存 "缝合

其次,这种方法改变了模型看待序列的方式,从而产生了分布上的变化,而模型并没有经过预训练,因此需要更广泛的训练来调整行为。具体来说,当我们以这种方式拼接 KV 缓存时,我们会创建一个具有非标准位置编码的序列。在独立线程生成过程中,所有线程都从相同的位置索引开始,并关注之前的子任务,而不是彼此。因此,当线程重新合并时,生成的 KV 缓存具有非标准位置编码,并且不使用因果注意。因此,这种方法需要大量的训练才能使模型与这种新行为保持一致。为了解决这个问题,Multiverse(Yang 等人,2025 年)和相关研究在训练过程中应用了改进的注意力掩码,以防止独立线程相互关注,从而使训练和推理行为保持一致。

图 8:多重宇宙的注意力掩码

面对非标准 KV 缓存管理所带来的这些问题,我们能否尝试一种不修改引擎的方法?

**ThreadWeaver 保持推理引擎不变,将协调工作转移到客户端。**ThreadWeaver(Lian 等人,2025 年)将并行推理纯粹视为客户端问题。分叉 "过程与 Multiverse 的几乎完全相同,但连接阶段对内存的处理方式却截然不同,因为它并不修改引擎内部结构。相反,客户端会将来自独立分支的所有文本输出连接成一个连续的序列。然后,引擎执行第二次预填充,为结论生成步骤生成 KV 缓存。虽然这引入了 Multiverse 竭力避免的计算冗余,但预填的成本明显低于解码。此外,由于第二次预填充使用的是因果注意力(线程之间会相互看到),因此在推理过程中不需要特殊的注意力处理,这使得顺序自回归模型更容易适应这项任务。

图 9:ThreadWeaver 的预填充和解码策略

我们应该如何训练模型来学习这种行为呢?简单地说,对于每个并行轨迹,我们可以按照推理模式将其分解为多个连续的部分。例如,我们可以训练模型输出给定提示的子任务、给定提示+子任务分配的单个线程,以及给定提示+子任务+对应线程的结论。然而,这似乎是多余的,而且计算效率不高。我们能做得更好吗?事实证明,可以。就像在 ThreadWeaver(Lian 等人,2025 年)中一样,我们可以将并行轨迹组织成前缀树(trie),将其扁平化为单个序列,并在训练(而非推理!)过程中应用只关注祖先的掩码。

图 10:构建前缀树并将其扁平化为单个训练序列

具体来说,我们使用掩码和位置 ID 来模拟推理行为,这样每个线程就只受提示+子任务的制约,而无需关注同级线程或最终结论。

与引擎无关的设计让采用变得容易,因为你不需要另外想办法托管,还可以利用现有的硬件基础设施。随着现有推理引擎的改进,它也会变得更好。更重要的是,有了引擎无关的方法,我们就能提供一种混合模型,在顺序和并行思维模式之间轻松切换。

1 个帖子 - 1 位参与者

阅读完整话题

来源: LinuxDo 最新话题查看原文