进城大之前,暑假写了两个小文章:
首先是Is SwiGLU's Open Positive Tail Necessary? Evidence from Closed-Tail Gating with MemGLU 。这篇文章是一个针对MLP激活门控的小论文:从RELU到SwiGLU,大家似乎默认了开放正尾,而该文用一个闭尾门控函数:MemGLU来检验开放正尾门控是否必要。
在我看来,这是一个工作量极小的question-perfect文章,上arxiv后第二天就收到了SELU(Scaled Exponential Linear Units)第一作者:Prof. Günter Klambauer 的一个询问(来管我要代码了)。

作为一个从忆阻神经网络转行到LLM的人来说:MemGLU这个函数在忆阻器领域真是太常见了。MemGLU不是很重要,反而是question很重要。这篇文章反而是第二篇的一个铺垫,因为如果没有Prof. Günter Klambauer 的关注,我可能第二篇文章是进行不下去的。
第二篇是Ask Self, Ask Others: Relation Is All You Need
这篇是本文的重点,本文主要记录该idea的演化思路,以及Relation家族的公式及其性质,我真的怕我开始上课之后,忘了我当时怎么推的了。做记录,以后一旦忘了,回头看看能想起来。
接下来开始吧。
一、怎么从Attention转向的Relation?
其实idea最早并不是Relation,而是Attention:Attention太贵了。
U_{ij}=\frac{q_i^{\top}k_j}{\sqrt{d_h}}
F_i=\operatorname{Softmax}(U_i)
作为LLM的Token Mixing部分,其标准Attention的计算复杂度是 O(T^2d) 。工业上大多采取稀疏注意力、线性注意力等机制去降低这个复杂度。而我在想:既然他这么贵,MHA还是一个标准的全局通信,我能不能改进一下MHA,让他少出现几次,把复杂度降下去,最好一次开头,一次结尾就行。
然后开始小规模实验,结果很明显,各种招法都上了(不等宽Attention,高维投影等),根本不work。
第二天重看公式的时候,发现了Attention一个很有意思的点:
U_{ij}=\frac{q_i^{\top}k_j}{\sqrt{d_h}}
U 将 q,k 两个输入投影做点积,去衡量交互证据。即:证据有多强?
随后
F_i=\operatorname{Softmax}(U_i)
将整行 U 归一化为一个权重分布,决定接下来的信息流如何在各 token 之间分配。
在这里, U 似乎承担的有点多,这个标量既要编码“关系”又要参与信息流分配。更准确的说: U \rightarrow F 将关系形成与信息流分配压缩到了一个步骤内。能不能把这两点拆开呢?
首先尝试在原Attention上面动刀,做了几个实验,又是不work。而且发现了不work的原因:Attention作为一个成功的组件,一旦动了一个位置,牵一发而动全身。因此,如果想把关系与信息流分配分开,只有“掀桌子”了。
二、Relation是怎么来的?
现在开始“掀桌子”,本章节重点来讲,这个架构是怎么一点点设计出来的。
1.关系应该是什么样?
如果要将关系形成与信息流分配分开,第一个问题就是:关系应该是什么样的?
以语言举例,将一段话打成Token送入模型,模型通过学习会学到各种各样的关系。一个 Token 在不同上下文里,可能与其他 Token 构成指代、修饰、动作关联等不同关系。如果真想把关系分到精细,是很难做到的。
因此,我选了两类最基本的关系角色:Self,Exchange。
- Self:自问,Ask self,自己跟自己的关系,即:衡量自己。
- Exchange:互问,Ask others,自己跟其他Token的关系,即:衡量他人。
Self 与 Exchange 是互斥的两种结构角色,可以把一个 token 的关系空间先做最简单的二分。
2.关系如何形成关系网?
有了Self跟Exchange,下一个问题自然而然:怎么把它们组织成一个真正的关系对象?
吃了考研线性代数的福,对于矩阵的理解深刻了一些。我们来看一个任意矩阵 A :
A= \begin{bmatrix} A_{11} & A_{12} & A_{13} & \cdots \\ A_{21} & A_{22} & A_{23} & \cdots \\ A_{31} & A_{32} & A_{33} & \cdots \\ \vdots & \vdots & \vdots & \ddots \end{bmatrix}
矩阵 A 天然区分对角线与非对角线:对角线对应同一位置,非对角线对应不同位置。这正好给了 Relation 一个最简单的结构划分。就有了 R 阵
R= \begin{bmatrix} S_1 & E_{12} & E_{13} & \cdots \\ E_{21} & S_2 & E_{23} & \cdots \\ E_{31} & E_{32} & S_3 & \cdots \\ \vdots & \vdots & \vdots & \ddots \end{bmatrix}
其中,对角线承担Self,非对角线为Exchange。 E_{ij} 表示第 i 个Token对第 j 个Token的关系。
3.怎么构建关系?
好, R 的结构有了,那里面这些 Self 和 Exchange 的数值到底从哪里来?
这就不得不回头提到Attention了:
Q=XW_Q,\qquad K=XW_K,\qquad U_{ij}=\frac{q_i^{\top}k_j}{\sqrt{d_h}}
Q , K 是两个由输入 X 进行投影得到的矩阵。在Attention中,被语义化为:query,key。但实际上,从数学角度看,这两个矩阵实际上仅仅是输入 X 的投影: X 仅仅经过了两个线性变换。
而Relation要构建Self,Exchange的数值,正需要“证据”。只有将”证据“拿齐,我们才能经过“分析”得到关系。
因此,Relatio中,首先构建关系证据: U_{ij }
P_1=XW_1,\qquad P_2=XW_2
U_{ij}=\frac{p_{1,i}^{\top}p_{2,j}}{\sqrt{d_h}}
收集“证据”的方式,跟Attention一模一样,这里并没有区别。而接下来的问题是:如何将证据变为Self,Exchange。
S_i=\mathcal{S}(U_{ii}),\qquad E_{ij}=\mathcal{E}(U_{ij})
证据是统一的,关系是不同的,我们需要一个算法,将证据 U 投射为两类关系: S , E 。由于要将 S , E 彻底分离,这里需要一对非线性函数。
通过大量的消融(23个),最终确定
S_i=\sigma\!\left(\frac{U_{ii}}{\tau_S}\right)
E_{ij}=\operatorname{SiLU}(U_{ij})
其中 \tau_S 是Self temperature。选这两个函数的原因一方面是数值分离,一方面是局部最优。
当时做了好多消融以及测评,统一发现:
- S,E 不能用相同函数,用了相同函数退化到不如Attention;
- E 很喜欢开放正尾,但不喜欢开放负尾。
- S 的数值需要被限制。
至于具体原因,等到后面用Relation的分解公式去解释。
4.怎么让关系指导信息流?
现在关系网阵 R 已经被精确定义,关系被显式的拿出。接下来就是:如何让 R 来指导信息流?
在Attention中, F_i=\operatorname{Softmax}(U_i) 。我们依旧采取这个方式,让关系指导信息流:
F_i=\operatorname{Softmax}(R_i)
5.信息本身怎么被搬运?
在Attention中,
V=XW_V
Y_i=\sum_{j\le i}F_{ij}V_j
而Relation仍然借鉴Attention的这个形式,在这里,我们先对 R 阵做因果掩码:
R_{ij}= \begin{cases} S_i, & j=i,\\ E_{ij}, & j<i,\\ -\infty, & j>i. \end{cases}
随后定义Relation的信息 I 及其搬运公式:
I=XW_I
Y_i=\sum_{j\le i}F_{ij}I_j
与Attention依旧相似。
6.怎么传递到下一层?
依然借鉴Attention,在Attention中:
Z_\ell=YW_O
X_{\ell+1}=X_\ell+Z_\ell
而在Relation中:
Z_\ell=YW_O
X_{\ell+1}=X_\ell+Z_\ell
没有差别。
7.当前公式有没有问题?
有问题的,当前矩阵 R :
R_{ij}= \begin{cases} S_i, & j=i,\\ E_{ij}, & j<i,\\ -\infty, & j>i. \end{cases}
则进softmax后第 i 行为:
Z_i = e^{S_i} + \sum_{j<i}e^{E_{ij}}
好了,问题出来了。Self永远只有 S_i ,而Exchange会随着 i 的增大而增大。
\underbrace{e^{S_i}}_{\text{Self: 1 term}} \qquad\text{vs.}\qquad \underbrace{\sum_{j<i}e^{E_{ij}}}_{\text{Exchange: }i-1\text{ terms}}
假设一个极端情况,如果所有 Exchange relation 都差不多:
E_{ij}\approx c
那么:
\sum_{j<i}e^{E_{ij}} \approx (i-1)e^c
取对数:
\log\sum_{j<i}e^{E_{ij}} \approx c+\log(i-1)
也就是说,哪怕单个 Exchange relation 完全没有变强,只因为候选历史 token 变多,汇聚的Exchange relation就会自然多出一个约 logi 的量。
因此,定义带 Exchange的log 修正的关系网 R 阵:
R_{ij}= \begin{cases} S_i, & j=i,\\ E_{ij}-\lambda_\ell\log i, & j<i,\\ -\infty, & j>i. \end{cases}
其中 \lambda_\ell 为逐层可学习参数。该修正相当于做一个缩放:
\sum_{j<i} e^{E_{ij}-\lambda_\ell\log i} = i^{-\lambda_\ell} \sum_{j<i}e^{E_{ij}}
8.该章结尾
到此为止,单头的Relation已经全部推导完毕。我们将基础算子命名为:Self-Exchange Relation。
其与Attention的差别在于显式的构造关系矩阵 R ,并让其指导信息流分配。
Attention:
U_{ij} \rightarrow F_i=\operatorname{Softmax}(U_i)
Relation:
U_{ij} \rightarrow (S_i,E_{ij}) \rightarrow R_{ij} \rightarrow F_i=\operatorname{Softmax}(R_i)

三、将Self-Exchange Relation推向多头
接下来,我们将单头算子推向多头。
1.直接推广
首先定义head维度:
d_h=\frac{d}{H}
随后将关系空间和信息空间拆成 H 个 head:
P_1=\operatorname{Concat}\left(P_1^{(1)},\ldots,P_1^{(H)}\right)
P_2=\operatorname{Concat}\left(P_2^{(1)},\ldots,P_2^{(H)}\right)
I=\operatorname{Concat}\left(I^{(1)},\ldots,I^{(H)}\right)
每个 head 独立构造 Relation:
U_{ij}^{(h)} = \frac{ \left(p_{1,i}^{(h)}\right)^{\top}p_{2,j}^{(h)} }{ \sqrt{d_h} }
U^{(h)} \rightarrow \left(S^{(h)},E^{(h)}\right) \rightarrow R^{(h)} \rightarrow F^{(h)}
最后每个 head 输出:
Y^{(h)} = F^{(h)}I^{(h)}
2.特殊处理
如果直接将Relation像Attention那样直接推向多头。会导致一个问题:Relation会被头截断。举个例子:
在Attention中,特征直接按head划分,不需要一个显式的“关系对象”需要跨 head 保持一致。
但在Relation中,每个 head 都拥有自己的:R^{(h)},也就是自己的关系结构。
但是如果:I ^{(h)} 也是按head直接划分,也固定绑定在对应 head:
Y^{(h)} = F^{(h)}I^{(h)}
那么每个 head 看到的信息也被限制在自己的子空间。
意味着:head 1的 relation 只能搬运 head 1的 information。
由于Relation的 R^{(h)} 是每个头独立训练的,但 I^{(h)} 是按head暴力划分的,因此:R^{(h)} 与 I^{(h)} 未必天然匹配。
因此,我们采取考研数学里面常见的正交变换Givens对 I^{(h)} 通过每对两轮的交替配对做旋转:
I=\operatorname{Concat}\left(I^{(1)},\ldots,I^{(H)}\right)
\widetilde I = G_\ell I
G_\ell = \prod_{m}G(a_m,b_m,\theta_m)
G(a,b,\theta) = \begin{bmatrix} \cos\theta & -\sin\theta\\ \sin\theta & \cos\theta \end{bmatrix}_{(a,b)}
Y^{(h)} = F^{(h)}\widetilde I^{(h)}
Givens 在 Relation 里不是一个普通正交旋转,它承担的是一个很具体的功能:解除 R^{(h)} 与 I^{(h)} 的固定绑定。
举个例子:
对于 H=8 ,两层交替配对为:
\mathcal{M}_A= \{(1,2),(3,4),(5,6),(7,8)\}
\mathcal{M}_B= \{(2,3),(4,5),(6,7),(8,1)\}
\mathcal{M}_A \rightarrow \mathcal{M}_B \rightarrow \mathcal{M}_A \rightarrow\cdots
A,B分别做相邻两个head的局部混合,随后经过多层交替,最终达到全局混合 I 的效果:
\begin{aligned}
\text{Layer }1:\quad& I^{(1)}\leftrightarrow I^{(2)},\quad I^{(3)}\leftrightarrow I^{(4)},\quad I^{(5)}\leftrightarrow I^{(6)},\quad I^{(7)}\leftrightarrow I^{(8)} \6pt]
\end{aligned}
\begin{aligned}
\text{Layer }2:\quad& I^{(2)}\leftrightarrow I^{(3)},\quad I^{(4)}\leftrightarrow I^{(5)},\quad I^{(6)}\leftrightarrow I^{(7)},\quad I^{(8)}\leftrightarrow I^{(1)} \6pt]
\end{aligned}
\begin{aligned}
\text{Layer }3:\quad& I^{(1)}\leftrightarrow I^{(2)},\quad I^{(3)}\leftrightarrow I^{(4)},\quad I^{(5)}\leftrightarrow I^{(6)},\quad I^{(7)}\leftrightarrow I^{(8)} \end{aligned} \
偶数层进行偶数编号相邻 head 混合,奇数层切换为奇数编号相邻 head 混合。由于两种 pairing 交替出现,局部交换路径逐层扩展,最终使每个 head 的信息可以访问全局 head 信息。
3.总体Multi-Head Relation
因此,Multi-Head Relation的公式为:
\begin{aligned}
P_1&=\operatorname{Concat}(P_1^{(1)},\ldots,P_1^{(H)}),\\
\end{aligned} \
\begin{aligned}
P_2&=\operatorname{Concat}(P_2^{(1)},\ldots,P_2^{(H)}),\\ I&=\operatorname{Concat}(I^{(1)},\ldots,I^{(H)}),\\ \widetilde I&=G_\ell I. \end{aligned} \
每个head:
U^{(h)} \rightarrow (S^{(h)},E^{(h)}) \rightarrow R^{(h)} \rightarrow F^{(h)}
最终:
Y^{(h)} = F^{(h)}\widetilde I^{(h)}
Y= \operatorname{Concat} (Y^{(1)},\ldots,Y^{(H)})
X_{\ell+1} = X_\ell+YW_O

四、一个显式的 R 阵,有什么意义?
1.被拼出来的关系网矩阵
R_{ij}= \begin{cases} S_i, & j=i,\\ E_{ij}-\lambda_\ell\log i, & j<i,\\ -\infty, & j>i. \end{cases}
关系网 R 阵首先有着一个与Attention注意力矩阵完全不同的特点:他是被拼出来的!
他的主对角线是Self关系,而非主对角线为Exchange与修正项。这个拼出来的特点,将会在接下来给予Relation极其有趣的工程特点。
2.在信息传输中,显化Token关系
Relation的显式 R 阵,首先揭露Token竞争关系,让我们从softmax开始推导:
F_i=\operatorname{Softmax}(R_i)
展开第 i 行:
F_{ij} = \frac{e^{R_{ij}}} {\sum_{k\le i}e^{R_{ik}}}
代入 Relation 矩阵:
R_{ii}=S_i
R_{ij}=E_{ij}-\lambda_\ell\log i,\quad j<i
则归一化的分母为:
Z_i = e^{S_i} + \sum_{j<i}e^{E_{ij}-\lambda_\ell\log i}
随后把所有 Exchange 项合并:
A_i = \log \sum_{j<i} e^{E_{ij}-\lambda_\ell\log i}
有:
Z_i=e^{S_i}+e^{A_i}
到这就很干净了,将Self与Exchange项彻底分野,随后将Self项代入 F :
F_{ii} = \frac{e^{S_i}} {e^{S_i}+e^{A_i}}
化为sigmod形式:
F_{ii} = \sigma(S_i-A_i)
此时Self 权重可以完全由 F_{ii} 来表示。对于所有非对角项,令:
g_i = \sum_{j<i}F_{ij} = \frac{ \sum_{k<i}e^{E_{ik}-\lambda_\ell\log i} }{ e^{S_i} + \sum_{k<i}e^{E_{ik}-\lambda_\ell\log i} }
由于
F_{ii}+g_i=1
因此:
g_i = \sigma(A_i-S_i)
此时,所有 Exchange 项的总权重由 g_i 表示。
随后,开始揭露Exchange 的内部分配。由于第 i 行,有:
F_{ij} = \frac{e^{R_{ij}}} {\sum_{k\le i}e^{R_{ik}}}
我们首先把 Exchange 部分单独归一化,定义:
\pi^E_{ij} = \frac{e^{E_{ij}}} {\sum_{k<i}e^{E_{ik}}}, \qquad \sum_{j<i}\pi^E_{ij}=1 .
其中 \pi^E_{ij} 表示 Exchange 内部不同 Token 的相对分配。则代回有:
\begin{aligned} F_{ij} &= \frac{e^{E_{ij}-\lambda_\ell\log i}} {e^{S_i}+\sum_{k<i}e^{E_{ik}-\lambda_\ell\log i}} \\ &= \frac{\sum_{k<i}e^{E_{ik}-\lambda_\ell\log i}} {e^{S_i}+\sum_{k<i}e^{E_{ik}-\lambda_\ell\log i}} \cdot \frac{e^{E_{ij}-\lambda_\ell\log i}} {\sum_{k<i}e^{E_{ik}-\lambda_\ell\log i}} \\ &= g_i\cdot \frac{e^{E_{ij}}} {\sum_{k<i}e^{E_{ik}}} \\ &= g_i\pi^E_{ij}, \qquad j<i . \end{aligned}
则:
F_{ij}=g_i\pi^E_{ij},\quad j<i
总公式为:
Y_i = \underbrace{F_{ii}\tilde I_i}_{\text{Self amount}} + \underbrace{ g_i \sum_{j<i} \pi^E_{ij}\tilde I_j }_{\text{Exchange mass} \times \text{Exchange allocation}}
到此为止,Relation彻底将Token的关系显化:一个Token在进入信息流后,首先发问:我到底是需要Self进行自问,还是Exchange去进行互问?随后发问:如果我去进行互问,那么我应该问谁?
最有意思的一点是,Self与Exchange这两个身份,一直持续到了信息流阶段。Attention只能做同等数学的算术切割,而Relation第一次给了语义!
这个总公式将作为Relation的分解公式,随后的Flash化根据将直接来源于此。
五、将Relation推向落地:Flash与Linear
正是因为 Relation 显式存在,揭露了一个全新的计算路径去做Flash与Linear。
1.将分解公式应用落地:FlashRelation
我们首先看FlashAttention是怎么实现的,在标准Attention中:
U_{ij} = \frac{q_i^\top k_j}{\sqrt{d_h}}, \qquad F_i=\operatorname{Softmax}(U_i), \qquad Y_i=\sum_{j\le i}F_{ij}V_j
FlashAttention 对一个分块 B 进行逐块扫描,实时更新三个变量:当前最大值 m 、归一化系数 l 、以及输出累加值 z ,这些变量用于稳定计算并分块完成注意力输出:
\begin{aligned} m' &= \max\left( m,\max_{j\in B}U_{ij} \right), \end{aligned}
\begin{aligned}
l' &= e^{m-m'}l + \sum_{j\in B}e^{U_{ij}-m'},
\end{aligned}
\begin{aligned}
z' &= e^{m-m'}z + \sum_{j\in B}e^{U_{ij}-m'}V_j . \end{aligned}
扫描完整行之后:
Y_i=\frac{z_i}{l_i}
FlashRelation 借鉴的正是这个逐块扫描思路,但 Relation 的 R 并不是一个普通矩阵,它已经被拆成 Self 与 Exchange,因此执行路径也发生了变化,由于:
Y_i = F_{ii}\widetilde I_i + g_i \sum_{j<i} \pi^E_{ij}\widetilde I_j
然后把 Exchange 内部那一项定义成一个归一化历史块:
\bar I_i^E = \sum_{j<i} \pi^E_{ij}\widetilde I_j = \frac{ \sum_{j<i}e^{E_{ij}}\widetilde I_j }{ \sum_{j<i}e^{E_{ij}} }
即:
Y_i = F_{ii}\widetilde I_i + g_i\bar I_i^E
由于:
F_{ii}+g_i=1
有了化简公式:
Y_i = (1-g_i)\widetilde I_i + g_i\bar I_i^E
于是 FlashRelation 根本没必要在线维护完整 Ri 或完整 Fi 。只需要逐块算出 Exchange 的两个东西:对数归一化常数,以及 \bar I_i^E 。最后再和 Self 合并即可。
因此,整个流程为:扫描历史 Exchange:
j<i,\qquad E_{ij}=\operatorname{SiLU}(U_{ij})
随后与FlashAttention一样,对一个分块 B 进行逐块扫描,实时更新三个变量:当前最大值 m 、归一化系数 l 、以及输出累加值 z:
\begin{aligned} m' &= \max\left( m,\max_{j\in B}E_{ij} \right),
\end{aligned}
\begin{aligned}
l' &= e^{m-m'}l + \sum_{j\in B}e^{E_{ij}-m'},
\end{aligned}
\begin{aligned}
z' &= e^{m-m'}z + \sum_{j\in B}e^{E_{ij}-m'}\widetilde I_j . \end{aligned}
扫完整个历史 Exchange 后,令:
L_i^E = m_i+\log l_i, \qquad \bar I_i^E = \frac{z_i}{l_i}
然后把修正项加回来:
A_i = L_i^E-\lambda_\ell\log i
再做 Self–Exchange 竞争,并输出:
g_i = \sigma(A_i-S_i)
Y_i = (1-g_i)\widetilde I_i + g_i\bar I_i^E
到此为止,FlashRelation结束。实验结果已经接近了PyTorch FlashAttention吞吐速度,至于能不能再优化,那是以后的事了。
2.将Relation递推进历史:Linear Relation
同样先看KIMI团队的 KDA 所采用的 gated delta-rule 思路。简化来看,其状态更新包含一个误差修正项:
先更新:
S_t^{-} = \operatorname{Diag}(\alpha_t)S_{t-1}
然后读出当前 key 在旧状态中的值:
\hat v_t = (S_t^{-})^\top k_t
再构造误差:
\Delta v_t = v_t-\hat v_t
最后用 delta 修正状态:
S_t = S_t^{-} + \beta_t k_t \left( v_t-(S_t^{-})^\top k_t \right)^\top
即,总流程为:
\text{Retain} \rightarrow \text{Read} \rightarrow \text{Compute Error} \rightarrow \text{Correct State}
而Linear Relation则不相同,先定义Self,Ask Self:
S_t = \sigma\left( \frac{p_{1,t}^{\top}p_{2,t}} {\tau_S\sqrt{d_h}} \right)
随后给定更新方向:
\hat p_{1,t} = \frac{p_{1,t}}{\lVert p_{1,t}\rVert_2}, \qquad \hat p_{2,t} = \frac{p_{2,t}}{\lVert p_{2,t}\rVert_2}
通过输入依赖的逐通道保留系数 \alpha_t ,决定历史关系状态 C_{t-1} 中哪些信息继续保留:
C_t^{-} = \operatorname{Diag}(\alpha_t)C_{t-1}
随后由Self开始进行主导,Ask Others:
E_t = S_t(C_t^{-})^\top\hat p_{1,t}
之后得 Y , Answer:
Y_t = \widetilde I_t+E_t
最后将Self自己变为历史,Become Others:
C_t = C_t^{-} + S_t\hat p_{2,t}\widetilde I_t^\top
即,总流程为:
\boxed{ \text{Ask Self} \rightarrow \text{Ask Others} \rightarrow \text{Answer} \rightarrow \text{Become Others} }
因此跟KDA对比:
\text{KDA / Delta Rule:}\qquad \text{write} \propto v_t-(S_t^-)^\top k_t
\text{Linear Relation:}\qquad \text{write} = S_t\hat p_{2,t}\widetilde I_t^\top
在Linear Relation里面,Self占据主导权:
\underbrace{ E_t = S_t(C_t^{-})^\top\hat p_{1,t} }_{\text{Self-controlled read}}
\underbrace{ C_t = C_t^{-} + S_t\hat p_{2,t}\widetilde I_t^\top }_{\text{Self-controlled write}}
这里跟KDA相比,有着三个很有意思的特点:
1、读写顺序本身就是 Relation 语义。当前公式是严格的 read-before-write。当前 Token 在读取历史 C_t^{-} 时,自己还没被写进去,所以 E_t 是严格历史信息;等回答 Y_t 形成后,当前 Token 才变成未来 Token 的 Others。
2、写进状态的是 \widetilde I_t,不是Y_t。
C_t = C_t^{-} + S_t\hat p_{2,t}\widetilde I_t^\top
正是因为当前 Token 成为未来 Others 时,应该留下的是它自己的信息 \widetilde I_t ,不是把“自己 + 刚从历史读出来的东西”重新写回历史。否则历史信息会被递归回灌。
3、Self主导读写。KDA需要额外的参数 β_t 来控制误差修正的写入强度。Linear Relation 没有再单独引入这个变量,因为 Relation 已经有了语义明确的 Self : S_t ,并直接让它控制当前 Token 的读写强度。也就是让Self自己决定要读写多少。
3.总结
到此为止,写了一堆,累死我了,可算把Flash跟Linear写完了。论文里实际上还做了Hybird跟Relation Cache。但由于没什么特点,几乎就是Attention换皮,就不写了。
4.经济账

直接用论文里面的表了,我不想再做表了。
六、写到最后
人就不能闲着。Relation从头到尾的研究,几乎都来源于每天闲的发慌。作为一条“流浪狗”,每天不干点东西难受,因此选择假期做点自己喜欢的东西玩,谁寻思“玩”出这么个东西。
至于能不能还有Relation2。我觉得还真有可能,当前Relation只是实现了Flow follows Relaiton,有没有可能出现Flow and computation follow Relation呢?当然这是后话了。小实验虽然已经有了点小趋势,但是Relation2一旦出来就真的要追SOTA,追SOTA就不是我一个人或者我们几个能hold得住的了。
七、补充
写到最后回头看发现,我有三个问题没回答:
- S,E 不能用相同函数,用了相同函数退化到不如Attention;
- E 很喜欢开放正尾,但不喜欢开放负尾。
- S 的数值需要被限制。
一个一个回答。
1.为什么 Self 和 Exchange 要用不同函数?
先把这个公式拿出来:
F_{ii} = \sigma(S_i-A_i), \qquad g_i = \sigma(A_i-S_i)
因此 S 负责的是 Self 与整个 Exchange 总权重的竞争。而 E 一方面进入:
A_i = \operatorname{LSE}_{j<i}(E_{ij}) - \lambda_\ell\log i
即总Exchange 总权重。另一方面还决定:
\pi^E_{ij} = \frac{e^{E_{ij}}} {\sum_{k<i}e^{E_{ik}}}
也就是 Exchange 内部到底找谁,因此 S,E 根本不是同一数学角色,用同一个函数就是“找死”。
2.为什么 E 喜欢开放正尾,却不喜欢开放负尾?
在Exchange内部,满足:
R_{ij}-R_{ik} = E_{ij}-E_{ik}
所以当某个历史 Token 真正特别相关时,我们希望 U_{ij}\gg 0 时,有:
\ E_{ij}\gg 0.
否则如果正尾被压住,比如 sigmoid:
E_{ij}\in(0,1),
那么真正非常强的 Exchange 也只能挤在有限区间里,强关系拉不开。
所以 Exchange 需要一个开放正尾,来保留强关系的区分能力。
但负尾不一样,如果: U_{ij}\to-\infty 也允许 E_{ij}\to-\infty。那么这个 Token 会形成极端负 relation;大量这样的项还会参与 Exchange aggregate:
A_i = \operatorname{LSE}_{j<i}(E_{ij}) - \lambda_\ell\log i.
这会让极端负 relation 进入 Exchange 的聚合结构,但它们并不能提供我们真正需要的强 Exchange 证据。
而 E 真正需要的是:有很强的历史关系时,把它突出出来;没有关系时,不需要无限惩罚。
而SiLU形状刚刚好:
x\to+\infty \quad\Longrightarrow\quad \operatorname{SiLU}(x)\sim x,
x\to-\infty \quad\Longrightarrow\quad \operatorname{SiLU}(x)\to 0^-.
这也就是为什么用SiLU。
3.为什么Self需要被限制
\ F_{ii} = \sigma(S_i-A_i)
S_i 是一个单独的 Self 信号,要和整个历史Exchange总权重竞争。如果:
S_i\to+\infty \quad\Longrightarrow\quad F_{ii}\to 1,\qquad g_i\to 0
或者:
S_i\to-\infty \quad\Longrightarrow\quad F_{ii}\to 0,\qquad g_i\to 1
即一次极大的对角线数值就能把整个历史 Exchange 关掉。或者一个极小的对角线数值就能让历史Exchange霸占整个关系。所以 Self 这个角色更适合成为一个稳定、有限的信号,sigmod正正好好。
八、更新(2026.8.27)
做Relation2的过程中,对原分解总公式做了一些新的分解,发现了一些新东西:
Y_i = F_{ii}\widetilde I_i + g_i \sum_{j<i}\pi_{ij}^E\widetilde I_j.
把 F_{ii}+g_i=1 代入得
Y_i = (1-g_i)\widetilde I_i + g_i \sum_{j<i}\pi_{ij}^E\widetilde I_j.
随后定义聚合后的Exchange信息:
\bar I_i^E = \sum_{j<i}\pi_{ij}^E\widetilde I_j.
代回原公式:
Y_i = (1-g_i)\widetilde I_i + g_i\bar I_i^E.
等价分解:
\begin{aligned} Y_i &= \widetilde I_i - g_i\widetilde I_i + g_i\bar I_i^E\\ &= \widetilde I_i + g_i \left( \bar I_i^E-\widetilde I_i \right). \end{aligned}
随后如果把这个 \Delta_i^E = \bar I_i^E-\widetilde I_i. 单独拿出来,再代回我们会发现:
\boxed{ Y_i = \widetilde I_i + g_i\Delta_i^E }
这就意味着实际上, \Delta_i^E 是从Self所在位置,走向Exchange聚合的方向,而 g_i 是走动幅度。这就很有意思了,这是竞争中的转化,从Self到Exchange的转化。动态更新的角度,准备放论文正文里面了。
另外一提,Relation2效果很好,通过再次“掀桌子”:把FFN接口干掉。相同的小参量下,已经能压MHA接近9%的PPL了。R 阵的实际情况比想象的可怕一点:他真的能指导computation。 I 方向的Givens变换则给了我“掀FFN桌子”的一个良好接口。
作者:Yuting Ge
原文:https://zhuanlan.zhihu.com/p/2074562062899061773