把注意力机制从普通的点积改成频域滤波,确实能从数学原理上提升模型对长程依赖的捕捉能力。
很多人以为把注意力机制改成频域处理就能直接套用,其实这里有个很隐蔽的坑:论文的实验设定只覆盖了双向注意力场景,也就是训练和推理时都能看到整个序列。自回归模型没法直接用这种非因果的滤波器,因为这会引入未来的信息,导致训练和推理不一致。为了解决这个限制,作者在配套的 MorletQK 论文中专门研究了因果时间域的 Morlet 变体,因为纯频域的滤波在自回归场景下很难保证严格的时间因果性。这个区别非常关键,如果你现在就想在自己的 GPT 项目里集成 FourierQK,得先想清楚你用的是 Encoder 还是 Decoder 架构,选错方案会导致训练不稳定或收敛变差。
滤波器形状到底有什么讲究
论文里测试了五个关于滤波器形状的假设:直流抑制、奈奎斯特抑制、带宽、中心频率和多尺度覆盖。最反直觉的发现是,DC 和奈奎斯特频率分量不仅没用,反而有明显的负面影响,损失值大概在 2.0 左右,效果甚至接近相位随机化。这说明单纯的低维频谱总结是不够的,必须用带通滤波器,而且这个带通结构必须是振荡性的,而不是随便切一段频谱。作者在 TinyShakespeare 数据集上做的是 6 层 GPT 的字符级语言建模,这个实验规模不大,但足够暴露出不同滤波器设计的差异。
如果你自己尝试复现,建议从最基础的 Gaussian 滤波器入手,然后再逐步替换成 Mexican Hat(Difference of Gaussians, DOG, m=2)。你会发现 Gaussian 滤波器虽然是零均值,但它在频谱两端的衰减不如 Mexican Hat 紧凑,这会导致频谱泄露,尤其是在处理长序列时,泄露的频率分量会干扰注意力权重。墨西哥帽滤波器在数学上被称为可许滤波器,这意味着它在时域和频域都是平滑的,这种性质能显著降低双边 FFT 泄露带来的噪声,从而提升模型的稳定性。
带宽和中心频率的选择对性能影响极大。论文给出的最优单尺度带宽 sigma 约为 2 个 bin,中心频率设在段落尺度,也就是大约 70 个 token。这个选择不是拍脑袋的,而是通过消融实验对比出来的。带宽太窄,模型能捕捉到的依赖范围就受限;带宽太宽,又容易混入高频噪声和低频背景信息,导致注意力分散。70 个 token 这个尺度刚好覆盖了自然语言中常见的段落级语义单元,能兼顾局部细节和全局结构。
双边 FFT 泄露和频谱覆盖的关系
频域注意力还有一个容易被忽视的问题:双边 FFT 泄露。论文里提到,双边 FFT 泄露会随着频谱覆盖的宽度单调增长。如果你选用的滤波器频谱覆盖太宽,泄露就会变得很严重,导致模型学到的是噪声而不是真正的语义依赖。作者用“频谱覆盖”这个指标来量化这个现象,给出了一个很具体的阈值:窄带滤波器如果频谱间隙大于 +4,性能就非常干净;宽带滤波器如果频谱间隙小于 +2,就会明显变差。
这意味着你在设计滤波器时,不能只看中心频率和带宽,还得控制频谱的边缘衰减速度。墨西哥帽滤波器在边缘的衰减比 Gaussian 快得多,这就是它能提供部分保护的关键原因。你可以把双边 FFT 泄露想象成频域里的“拖尾效应”,如果你在滤波时没把尾巴剪干净,这些拖尾会在 FFT 变换回时域时产生虚假的信号,干扰模型的注意力计算。在长序列上,这个问题会变得更严重,因为 FFT 的计算长度通常是 2 的幂次,拖尾的累积效应会被放大。
为什么字符级注意力效果有限
论文的实验背景是字符级语言建模,使用的是 TinyShakespeare 数据集。虽然这能很好地暴露滤波器设计的差异,但作者也指出,在字符尺度上直接使用因果时间域 Morlet 滤波器,效果还不如基线点积注意力。原因很简单:K=128 个抽头只能覆盖 50% 的上下文窗口(T=256),这意味着模型在处理字符级依赖时,能看到的信息非常有限,频域滤波的优势发挥不出来。
为了解决这个问题,作者在配套的 MorletQK 论文中建议改用词级语言建模。词级的上下文窗口更宽,K=128 的抽头能覆盖更大的比例,这样频域滤波的优势才能真正体现出来。这个观察很有意思,它提醒我们:在工程落地时,不要盲目把频域注意力从字符级迁移到词级或子词级,必须根据上下文窗口的大小调整滤波器的抽头数和中心频率。如果你的模型上下文很短,强行上频域滤波可能反而会拖累性能。
实操建议:如何在自己的项目里使用 FourierQK
如果你想在现有的 Transformer 模型里集成 FourierQK,可以参考以下几个步骤:
- 确认模型架构类型:如果是 BERT 这种 encoder 结构,可以直接使用 FourierQK;如果是 GPT 这种 decoder 结构,建议先看 MorletQK 论文,搞清楚因果变体的实现方式。
- 选择滤波器形状:优先使用墨西哥帽滤波器(Difference of Gaussians, m=2),它的零均值特性和边缘衰减能显著降低频谱泄露。
- 设置带宽和中心频率:单尺度带宽 sigma 约为 2 个 bin,中心频率设在段落尺度(~70 个 token)。如果你处理的是词级或子词级 token,这个尺度需要相应调整。
- 监控频谱覆盖指标:在训练时监控频谱间隙,确保窄带滤波器(gap > +4)的性能优于宽带滤波器(gap < +2),这能避免因频谱泄露导致的性能下降。
- 验证上下文窗口:如果是字符级模型,K=128 的抽头可能不够,建议改用词级模型或增加抽头数,否则频域滤波的优势无法发挥。
代码已经开源在 GitHub 上,地址是 https://github.com/AthanasiosZeris/energy-gated-attention。你可以直接拉下来跑 TinyShakespeare 的实验,看看 Delta = +1.15 nats 的增益是怎么来的。如果你是做工程落地,建议先在较小的数据集上验证滤波器设计的合理性,再逐步扩大规模,避免一开始就陷入频谱泄露和上下文不足的坑里。