超长序列建模 —— STCA 精读笔记

文章链接:https://arxiv.org/pdf/2511.06077

机构:字节(抖音)

发布时间:2025.11

Copyright (c) Wang-Luning. All Rights Reserved.

工业中普遍采用两阶段的策略来处理长用户历史序列:先筛选出一些和目标物品类似的历史交互物品,然后再在这个筛选后的短序列上进行建模。这样虽然高效,但难以实现端到端优化,可能丢失重要信息。

实验证明在推荐系统中通常序列越长效果越好,可以看成推荐领域的scaling law,因此如果想真正实现推荐大模型的scaling的话,长序列是不可或缺的部分

为了在低训练开销和推理开销下实现10000量级的用户历史序列建模,本文主要提出了3点优化:

 

设长度为L的用户历史序列为H={(vi,ai)}i=1L,其中vj,aj分别是第j个视频的特征向量和交互行为类型。设t为要被排序的目标视频。设xjRd(vj,aj)的embedding,xtRdt的embedding(包含了ID、多模态内容信息、作者信息等)。则给定输入的embedding序列X=[x1,,xL]和目标物品的embeddingxt,任务是输出一个预测打分值y^[0,1],这里选用完播率作为预测对象。

image-20260223161638833

STCA:

在排序任务中,目标物品到各个历史行为的直接交互是最重要的,而历史行为序列中的各项之间的交互相对来说没那么重要。因此,为了避免注意力的二次复杂度,舍弃了显式的历史序列内部交互,只使用一个单query的从目标到历史的交叉注意力。

具体而言,设总共有M层block。在第一层中,分别将历史embedding序列X和目标物品的embedding xt通过一个SwiGLUFFN+LN层,分别用于为本层后续的交叉注意力产生KV张量和query向量:

X~(1)=LN(SwiGLUFFN(1)(X))RL×dq(1)=LN(SwiGLUFFN(1)(xt))Rd

进一步,通过该层的权重WK(1),WV(1)对于X~(1)做变换得到该层的K和V,然后再和由目标物品变换而来的query向量q(1)做交叉注意力,得到的QKV注意力计算结果。将每个头的注意力结果连接起来后再通过一个WO(1)矩阵得到该层的“总结”输出o(1)Rd,它代表了该层中目标物品和历史交互后的抽象结果。

在接下来的每层i中,X~(用于产生KV)都是将原始的embedding序列X输入对应层的SwiGLUFFN得到的,而q(i)则是由目标xt和之前各层总结输出o(i)连接后再通过一个可学习映射融合变换得到的(可见Q是随着层数变深会被不断更新):

X~(i)=LN(SwiGLUFFN(i)(X))RL×dq(i)=SwiGLUFFN(i)([o(1)||||o(i1)||xt]WC(i))Rd

其中||表示向量连接。然后再进行交叉注意力并得到该层总结输出o(n),并相应地更新得到下一层的q(i+1)

可见,在每一层中的query只有1个向量,这就使得注意力计算复杂度是O(L),相当于decoding阶段的计算量

最终,最后一层输出的更新后的Q向量即为最终的信息交叉结果向量z

z=SwiGLUFFN([o(1)||||o(M)||xt]WZ)Rd

将这个交叉结果向量z再和一些用户画像tokens {uk}k=1K和目标物品tokens(例如物品的多模态内容、创作者信息等){cl}l=1C组成一个序列Xmix,然后将其送入RankMixer模块获得最终预测输出:

h=RankMixer(Xmix)y^=sigmoid(wTh+b)

 

Request Level Batching(RLB):

在排序任务中通常需要给多个目标物品打分,如果一次次单独推理的话会导致长历史序列不断重复地从CPU传输到GPU,还要重复encode,造成了系统上的效率低下。

因此,可以按照用户来聚合一批样本,并复用用户侧的表征。也即,将同一个用户的历史序列X转换成各层的输入表征X~(i)后,它可以服务于多个目标物品产生的q,这样就不需要重复进行它的生成了。

 

短序列训练,长序列推理:

在Beta分布中采样训练长度,并截取数据集中最近的该长度的序列用于训练。