共计 2146 个字符,预计需要花费 6 分钟才能阅读完成。
背景与动机
传统多头注意力 (MHA) 在处理长度为 $n$ 的序列时,由于需要计算所有 query-key 对的相似度,其时间和空间复杂度均为 $O(n^2)$。当序列长度达到 2048 甚至更长时(如文档级 NLP 任务或高分辨率图像处理),显存消耗会呈现平方级增长,导致训练过程难以进行。

滑动窗口多头自注意力(s)w-msa 通过将序列划分为固定大小的窗口(通常 128-256 个 token),仅在窗口内部计算注意力,将复杂度降低到 $O(n)$。这种设计既保留了局部上下文的建模能力,又通过窗口滑动机制(shifted window)实现了跨窗口的信息交互。
技术方案对比
| 方法类型 | 计算复杂度 | 内存占用 | 适用场景 |
|---|---|---|---|
| 全局 MHA | O(n²) | 极高 | 短序列任务 |
| 稀疏 Attention | O(n√n) | 高 | 特定模式的长序列 |
| (s)w-msa | O(n) | 中等 | 通用长序列任务 |
测试环境:A100-40GB GPU,batch_size=32
| 序列长度 | 全局 MHA 显存 | (s)w-msa 显存(窗口 =128) |
|---|---|---|
| 512 | 12.1GB | 5.3GB |
| 1024 | OOM | 8.7GB |
| 2048 | OOM | 14.2GB |
核心实现细节
1. 窗口划分与重组
import einops
def window_partition(x, window_size):
"""
Args:
x: (B, L, C)
window_size: int
Returns:
windows: (num_windows*B, window_size, C)
"""
B, L, C = x.shape
x = einops.rearrange(
x,
'b (nw ws) c -> (b nw) ws c',
ws=window_size
)
return x
window_reverse = lambda windows, window_size, L: einops.rearrange(
windows,
'(b nw) ws c -> b (nw ws) c',
ws=window_size
)
2. 相对位置偏置
每个注意力头引入可学习的相对位置偏置矩阵 $B \in \mathbb{R}^{(2M-1)×(2M-1)}$(M 为窗口大小):
$$Attention = Softmax(\frac{QK^T}{\sqrt{d_k}} + B)V$$
# 初始化偏置矩阵
self.relative_position_bias_table = nn.Parameter(torch.zeros((2*window_size-1)**2, num_heads)
)
# 计算相对位置索引
coords = torch.stack(torch.meshgrid([torch.arange(window_size)]*2
))
relative_coords = coords[:, None, :] - coords[:, :, None] # 2, M, M
relative_coords += window_size - 1 # 转换为非负
3. 滑动窗口机制
通过周期性向左上方移动窗口,使得相邻层的窗口布局不同,实现跨窗口信息流动:
def shifted_window_attention(x, window_size, shift_size):
if shift_size > 0:
# 周期性位移
x = torch.roll(x, shifts=(-shift_size, -shift_size), dims=(1, 2))
# 常规窗口注意力计算
attn_mask = create_mask(window_size, shift_size)
...
if shift_size > 0:
# 位移还原
x = torch.roll(x, shifts=(shift_size, shift_size), dims=(1, 2))
return x
性能优化策略
窗口大小选择
在 WMT14 英德翻译任务上的测试结果:
| 窗口大小 | BLEU | 训练速度(tokens/sec) |
|---|---|---|
| 64 | 26.3 | 5800 |
| 128 | 27.1 | 4200 |
| 256 | 27.4 | 2100 |
建议:在显存允许的情况下选择较大窗口(128-256),当显存不足时可配合梯度检查点技术
计算热点分析
使用 Nsight Systems 分析显示:
- 注意力矩阵计算占比 45%
- 窗口划分 / 重组占比 18%
- 层归一化占比 12%
优化方向:
– 使用 FlashAttention 加速注意力计算
– 预计算相对位置偏置
实践注意事项
- 显存管理:
- 窗口大小与最大序列长度需满足
L % window_size == 0 -
混合精度训练时需对偏置矩阵做
float32强制转换 -
多 GPU 训练:
- 避免在 DataParallel 模式下直接使用
torch.roll -
推荐使用 DistributedDataParallel 配合
all_gather -
数值稳定性:
- 相对位置编码需要适当的初始化缩放
- 建议对偏置矩阵使用
xavier_uniform_初始化
扩展应用
- 轴向注意力组合:
- 在 2D 数据(如图像)中可分离行列方向的计算
-
进一步将复杂度从 $O(M^2)$ 降到 $O(2M)$
-
视觉 Transformer 适配:
- Swin Transformer 的成功已验证其有效性
- 在视频处理中可扩展到时域窗口
总结
(s)w-msa 通过局部注意力与跨窗口交互的平衡,在保持模型性能的同时显著降低了长序列处理的计算开销。实际部署时需根据硬件条件和任务需求调整窗口大小,并注意分布式训练中的实现细节。该方法为 Transformer 在基因组学、高分辨率图像等领域的应用提供了可能性。
