Perceiver 架构:用一组 latent 向量压缩输入,不管输入多长注意力开销都一样

我得先坦白一件事:第一次看到注意力机制的计算量是 O(n²) 时,我觉得这根本不是个问题。后来我用 Transformer 处理点云数据,输入十万个点,显卡直接爆显存,才明白“平方”这两个字有多重。如果是 100 万个点,让所有点两两交互,就是一万亿次注意力计算——这还没算后续的矩阵乘法,根本没法玩。

AI technology illustration

当时产业界的主流思路是给注意力“减负”:滑窗、稀疏化、哈希近邻。这些方案都在做同一件事——减少 N 个 token 之间的交互次数。但 DeepMind 在 Perceiver 论文里给了另一个答案:干脆不要让输入之间互相打招呼,而是派一小群“代理人”去阅读整个输入。更严格地说,Perceiver 的自注意力开销恒定,交叉注意力仍是线性增长,但相比 O(N²) 已经是天壤之别。

先算一笔账:为什么 O(n²) 是长输入的死亡之吻

标准 Transformer 的注意力,本质上是在让序列里的每个 token 都去关心所有其他 token。假设有 N 个 token,每个 token 都要跟另外 N 个 token 计算相关性,所以总共是 N×N 次交互。1 万 token 就是一亿次交互,勉强能跑;100 万 token 就是一万亿次,任何单一设备都扛不住。

有人会说,线性注意力不是把复杂度降到 O(N) 了吗?是的,但 Linformer、Performer 这类方案仍然是在近似 N×N 的交互矩阵,也就是它们依然预设“输入之间应当两两交互”,只是把这个交互算得更省。Perceiver 则直接把这个预设扔了。

Perceiver 的做法:派一群“问问题的向量”去读输入

Perceiver 引入了一个全新的角色:latent array。它是一组可学习的向量,数量固定,比如 512 个,每个向量的维度是 D。这个数组不是输入的一部分,而是模型自己的一组参数,相当于一群带着任务的“记者”。

每次处理输入,Perceiver 只做两件事。第一,交叉注意力:让这 L 个 latent 向量作为 Query,去输入序列的 Key/Value 里“采访”。每个 latent 会扫一遍全部输入,挑出与它关心的方向相关的信息。输入之间不直接交互,复杂度是 N×L,而不是 N²。第二,latent 自注意力:让 L 个 latent 互相交流,相当于记者们开个碰头会,交换各自采集到的信息。这一步复杂度是 L²,L 是固定常数,与输入长度无关。

这个“采访+碰头会”的过程会重复若干轮。论文里叫 iterative attention,而且所有轮次共享同一组参数,所以不会因为多迭代几轮就多出几个亿的参数量。

想看一层的伪代码吗?点这里。
# x: 输入序列 [B, N, C]
# latent: 可学习向量 [B, L, D]
for _ in range(num_iterations):
latent = cross_attention(q=latent, kv=x)
latent = self_attention(q=latent, kv=latent)

这种方式让我想到人看一幅画——你不会同时看清所有像素,而是先整体扫一眼,然后盯着几个感兴趣的区域反复看。Perceiver 的 latent 就是你的注意焦点,迭代就是你的眼球扫视。

Perceiver 不是第一个用可学习 query 的方法。Set Transformer 2018 年就用一堆 inducing points 来做集合输入,只是 Perceiver 把同样思路推广到了任意模态,并给出了一个极简统一的实现。

信息被压缩丢了吗?丢了,但这是设计,不是 bug

我最初以为 latent array 是一种自动编码器,像 VAE 那样把输入压缩成紧凑的中间表示。后来读代码才意识到,latent 不是输入的“摘要”,而是一组查询向量。它并不试图保留输入里的所有信息,只提取当前任务觉得有用的东西。

这本质上是一种刻意制造的信息瓶颈:模型被迫放弃对细节的完整保存,从而把有限的计算资源集中到高层语义上。代价也很直接——如果你要做像素级分割、高保真重建这类“每个输入位置都要一个输出”的任务,L=512 个 latent 可能连细节都装不下。

正因如此,Perceiver 的合适场景是输入规模大、模态杂,但任务只需要整体理解的数据,比如点云分类、音频事件检测、多模态检索。

和 Sparse Attention、线性注意力放在一起看,差别更明显

方案 核心思路 对百万级输入 主要代价
标准 Transformer 所有 token 两两交互 不可能 O(N²) 算力和显存
Sparse Attention 只保留局部或部分交互 可以,但需设计图结构 对不规则模态不通用
线性注意力 用核近似全局交互 可以 近似误差,表达力有限
Perceiver 用 L 个 latent 代为交互 可以,交互次数 N×L 信息瓶颈,细节容易丢

它没有成为主流,但它的思想渗入了很多地方

Perceiver 后来被扩展成了 Perceiver IO,可以输出任意结构的预测;Perceiver AR 则把它改造成自回归模型,用来处理超长序列。不过真正让我觉得厉害的是,它把“可学习 query 从输入中提取信息”这个范式留了下来。

2023 年,BLIP-2 的 Q-Former 用了类似的做法:32 个可学习 query,从冻结的图像编码器中“读出”视觉特征,再喂给语言模型。很多人觉得这是视觉语言模型的关键创新,但如果你看过 Perceiver,会觉得这套东西太眼熟了。

我的判断:Perceiver 更像是一种注意力开销的管理哲学

今天的社区更倾向于用稀疏注意力或直接扩大上下文窗口来解决问题,Perceiver 这种“先压缩再处理”的路线不是主流。但每当你遇到输入长度不可控、数据又高冗余的场景,Perceiver 的方法论就特别值钱:把不可控的 N 变成可控的 L,用 L 作为计算预算的旋钮。

它的边界也很清楚:信息瓶颈决定了它做不了细节密集型的任务,或者说,它适合回答“这篇文章讲了什么”,不适合回答“这篇文章的第 5 个词是什么颜色”。如果你要用它,先问自己:我的任务真的需要保留每个输入位置的细节吗?如果不需要,Perceiver 可以帮你把万丈红尘压缩成一只茶杯。

原创文章,作者:guanweilu,如若转载,请注明出处:https://guanweilu.cn/article/421.html

(0)
上一篇 4天前
下一篇 4天前

相关推荐