Attention 的复杂度与为什么需要位置编码
副标题 / 摘要 Self-attention 的 O(n^2) 复杂度是 Transformer 的主要瓶颈;位置编码则让模型区分顺序与相对位置。本文用 ACERS 框架解释复杂度来源与位置编码必要性,并提供最小示例。 预计阅读时长:14~18 分钟 标签:attention、positional-encoding、complexity SEO 关键词:Attention, 位置编码, 复杂度, Transformer 元描述:说明注意力复杂度与位置编码必要性,附可运行示例。 目标读者 想理解 Transformer 性能瓶颈的入门读者 需要处理长序列的工程实践者 关注注意力优化方案的开发者 背景 / 动机 Transformer 的性能瓶颈主要来自注意力矩阵的二次复杂度。 此外,注意力本身对顺序不敏感,必须引入位置编码。 理解这两点,才能合理设计模型与优化策略。 核心概念 注意力矩阵:n x n 的相似度矩阵。 时间/空间复杂度:自注意力随序列长度二次增长。 位置编码:赋予序列位置信息,避免“顺序不分”。 A — Algorithm(题目与算法) 用通俗语言说明主题内容 注意力需要比较每个 token 与所有 token → 复杂度是 O(n^2)。 不加位置编码,模型无法区分“我爱你”和“你爱我”。 基础示例(1) 序列长度从 128 到 1024,注意力矩阵大小从 16K 到 1M。 基础示例(2) 句子顺序交换,位置编码缺失时模型输出相同。 实践指南 / 步骤 估算序列长度与注意力矩阵大小。 需要长序列时考虑稀疏/线性注意力。 选择位置编码方案(绝对/相对/旋转)。 可运行示例(复杂度与位置编码) import torch # 注意力矩阵规模示例 for n in [128, 256, 512, 1024]: mat = n * n print(n, "->", mat, "elements") # 位置编码示例(绝对位置) seq = torch.randn(1, 4, 8) pos = torch.arange(4).unsqueeze(0) pe = torch.sin(pos.float().unsqueeze(-1) / 10000) seq_with_pos = seq + pe print(seq_with_pos.shape) 解释与原理 QK^T 产生 n x n 矩阵,这是 O(n^2) 来源。 没有位置编码,注意力对序列顺序“置换不变”。 C — Concepts(核心思想) 方法类型 复杂度分析属于算法复杂度范畴,位置编码属于序列建模补偿机制。 ...