目录 · 10 节
1它到底在解决什么问题?2两个观察:注意力越来越集中,而且排名稳定3整体流程:一次全看,一次挑选,之后逐步截短4第 1 步为什么要把所有 beam 的意见合起来?5为什么还要每步缩小预算?6每一步为什么要单独一份 KV?7实验:快了多少,准了多少8我认为它的局限9一个推荐/搜索团队可以怎么试10结论做生成式召回、又被长序列推理延迟卡住的团队值得读。它没有发明新的稀疏注意力,而是先量清楚生成式推荐解码时注意力怎么变化,再按这个规律把挑选重要历史这件事从“每步、每条 beam 各做一次”改成“全程只做一次”。生成式推荐做 beam 解码时,每一步、每条 beam 都要对整段用户历史算一遍注意力,历史越长越慢。阿里的作者发现,解码越往后,注意力越集中在少数几条历史行为上,而且哪些行为重要,前后几步基本不变。PFA(Progressively Focused Attention)据此只在解码开头看完整历史,之后把各条 beam 的注意力按生成概率加权汇总,排出一份所有 beam 共用的重要行为排名,把这些行为的 KV cache 挪到连续内存里。之后每往后一步,保留的行为数按固定比例缩小,比如每步减半。重要的行为前几步就能找出来,后面不必每步重选。在电商广告平台的线上 A/B 中,用户历史从 128 条加长到 512 条。收入提升 3.76%,响应时间仍比直接用完整的 512 条更短。
它到底在解决什么问题?
先看一个示意场景。一个用户有 512 条历史点击,生成式召回要为他生成 100 个候选商品。每个商品用 4 个码的 SID 表示,beam search 一共走 4 步,每步保留 100 条 beam。每走一步,每条 beam 都拿自己当前的 query 去和全部 512 条历史算 attention。
| 示意 | 每步看几条历史 | 每步谁来挑 | 历史 KV 怎么读 |
|---|---|---|---|
| 完整 attention | 512 | 不挑 | 每条 beam 读全部 512 条 |
| 动态 top-k | 256 | 每条 beam 各挑一次 | 读散落在内存各处的 256 条 |
| PFA | 第 0 步 512;第 1 步给 512 条打分,只用前 256 条;第 2、3 步 128、64 | 只在第 1 步挑一次 | 读重排后连续存放的前若干条 |
完整 attention 的计算量随历史长度线性增长。论文给的实测是历史长度放大 4 倍,推理延迟变成 2.46 倍。
现有的两类办法各有毛病。第一类是解码前先把历史压短,比如 LONGER(把长历史合并成少量 token 的长序列模型)和 Q-Former 把 512 条合成更少的几个向量。压缩只做一次,和解码到哪一步无关,后面某一步需要的细节可能已经被压掉,找不回来。第二类是动态 top-k:每一步、每条 beam 用自己的 query 从完整历史里挑出最相关的 k 条再算 attention。它能跟着每一步变,但在 beam search 下很亏。100 条 beam 各挑各的,挑选本身就是开销;挑出来的 KV 在显存里东一条西一条,读取很慢。论文的消融里,动态 top-k 在工业数据集上的延迟是完整 attention 的 2.36 倍,计算量省了,时间反而更长。
两个观察:注意力越来越集中,而且排名稳定
PFA 的出发点是两张统计图,数据来自工业数据集。

第一个观察是注意力逐步集中。第 0 步还没生成任何码,query 只来自开始符,注意力铺得很开。一旦生成了第一个码,注意力就迅速收拢:从第 1 步起,排在前 10% 的历史行为就拿走了 92.98% 的 attention 权重。这和直觉一致。第一个码定下了大类,比如“运动装备”,之后的码在这个大类里细分,需要参考的历史自然越来越少。

第二个观察是排名稳定。在第 1 步按权重选出前 25% 的历史,到第 2 步和第 3 步不再重选,直接沿用,仍能保住 97.03% 和 98.62% 的权重,只比每步重选少 2.23 和 1.04 个百分点。如果偷懒只取最近的 25% 条行为,差距是 47.60 和 65.89 个百分点。这说明“最近的就是最重要的”在这里不成立,但“第 1 步重要的,后面也重要”基本成立。这批历史在第 1 步和第 2、3 步的排名,Spearman 相关系数是 0.746 和 0.713,说明排名前后基本一致,只是没有一模一样。
两个观察合起来就是 PFA 的设计:既然后面要看的历史越来越少,预算就该逐步缩小;既然排名前后稳定,挑一次就够了。
整体流程:一次全看,一次挑选,之后逐步截短

| 阶段 | 解码步 | 做什么 | 产出 |
|---|---|---|---|
| 准备 | 解码前 | encoder 编码历史,为每一步单独投影出一份 KV | 4 份历史 KV |
| 全局探索 | 第 0 步 | 开始符的 query 对全部历史做 attention | 第一个码,前 100 条 beam |
| 跨 beam 挑选 | 第 1 步 | 汇总各 beam 的 attention,排出一份共用排名,留前 k 条 | 重排后的连续 KV 缓存 |
| 逐步截短 | 第 2 步起 | 每条 beam 只看缓存最前面的 k_t 条 | 剩下的码 |
关键分工是:第 0 步和第 1 步负责“看全”,在完整历史上探索和打分,尽量保住用户的各种兴趣;第 1 步结束后负责“看准”,只在少数重要历史上算。下面拆开讲。
第 1 步为什么要把所有 beam 的意见合起来?
第 1 步时,100 条 beam 已经各自生成了不同的第一个码,代表用户不同方向的兴趣。比如一条 beam 走向“跑鞋”,另一条走向“咖啡”。每条 beam 都用自己的 query 和完整历史算一遍 attention,得到每条历史的权重。多头时把各头的权重取平均。
然后 PFA 给每条 beam 一个份量:这条 beam 的生成概率除以所有 beam 生成概率之和。每条历史的重要性分数,就是各 beam 给它的权重按这个份量加权求和:
这里 是 beam 给第 条历史的 attention 权重, 是 beam 的生成概率, 是第 条历史的综合重要性。直觉是:越可能被推荐出去的方向,说话越算数。
举个能手算的例子(示意)。只有两条 beam,生成概率 0.6 和 0.2,份量就是 0.75 和 0.25。历史 A 在两条 beam 里的权重是 0.4 和 0.0,历史 B 是 0.1 和 0.6。A 的分数是 0.75×0.4=0.30,B 是 0.75×0.1+0.25×0.6=0.225。A 排在 B 前面,但 B 因为对第二条 beam 很重要,仍有不低的分数,不会被直接扔掉。
为什么不让每条 beam 自己挑?消融里有答案。改成每条 beam 各建一份排名后,Recall@10 略高一点,延迟却从 62 涨到 118 ms/batch。共用一份排名,相当于用一点点精度换来一半的时间。
挑出前 k 条后,PFA 把后面各步要用的历史 KV 按排名重新排列,只留前 k 条,排成一块连续内存,所有 beam 共用。第 1 步本身不再重算:前面已经算好的 attention 权重,只保留这 k 条的部分,重新归一化成和为 1,再和对应的 value 加权求和得到输出。
为什么还要每步缩小预算?
挑出来的 k 条已经按重要性从高到低排好,后面每一步只需要“取前多少条”。PFA 的预算公式是:
是第 1 步留下的条数, 是每步保留的比例。默认 、,所以第 1 步给全部历史打分后只用前 256 条算输出,第 2 步和第 3 步每步减半,只看前 128 条和前 64 条。
这样设计的好处在内存上。每一步看的历史都是上一步的前缀,取前 128 条就是从连续内存的开头读 128 条,不需要按索引去各处取数据。论文把这叫零开销的前缀截断。去掉逐步缩小、每步都看 256 条时,Recall@10 几乎不变,延迟从 62 涨到 65 ms/batch。这一项的收益不大,因为 SID 只有 4 个码,能缩小的步数少。
每一步为什么要单独一份 KV?
缩小预算后,后面几步看的历史是同一批的子集。但每一步要预测的码不同:第一个码定大类,最后一个码区分具体商品,需要从同一条历史里读出的信息也不同。PFA 给每个解码步单独一组 KV 投影参数,解码前把 4 份历史 KV 都算好。这样同一条历史在不同步里呈现不同的侧面。
这是 PFA 里对精度影响最大的一项。去掉它、各步共用一组投影后,工业数据集的 Recall@10 从 0.1695 掉到 0.1602,比完整 attention 的 0.1643 还低;延迟只少了 3 ms/batch。
实验:快了多少,准了多少
先看理论计算量。按上面的默认设置估算,PFA 的 attention 乘加次数约为完整 attention 的三分之一多一点,理论上快 2.65 倍;比动态 top-k 快 1.99 倍。论文把收益归到两点:所有 beam 和后续各步共用一份排名,不再重复挑选;预算逐步缩小,看的历史越来越少。
主实验在三个数据集上比了 8 个基线:Kindle Store(电子书)、Tmall(电商点击)和一个工业广告数据集,后者有约 3500 万用户、历史长度 512。下表摘工业数据集的结果。
| 方法 | Recall@10 | NDCG@10 |
|---|---|---|
| TIGER(标准生成式推荐,看完整历史) | 0.1332 | 0.0722 |
| LONGER(解码前压缩历史) | 0.1565 | 0.0928 |
| GEMs(长序列生成式推荐,最强基线) | 0.1581 | 0.0947 |
| PFA | 0.1695 | 0.1021 |
PFA 在三个数据集、四个指标上都是第一,相对每个指标上最强的基线,Recall@10 平均高 5.75%,NDCG@10 平均高 7.18%。这说明“先看全再挑”比“解码前压短”更能保住有用的历史。
消融表把精度和延迟放在一起看更清楚(延迟单位 ms/batch,L20 GPU,每批 512 个用户)。
| 变体 | Kindle Recall@10 | Kindle 延迟 | 工业 Recall@10 | 工业延迟 |
|---|---|---|---|---|
| 完整 attention | 0.0624 | 24 | 0.1643 | 90 |
| 动态 top-k | 0.0623 | 53 | 0.1638 | 212 |
| 不跨 beam 共享 | 0.0648 | 29 | 0.1706 | 118 |
| 不逐步缩小 | 0.0637 | 20 | 0.1699 | 65 |
| 不分步投影 KV | 0.0618 | 16 | 0.1602 | 59 |
| PFA | 0.0635 | 18 | 0.1695 | 62 |
相比完整 attention,PFA 在工业数据集上快 1.45 倍,Recall@10 高 3.16%。各部件的分工也清楚:跨 beam 共享和逐步缩小主要省时间,几乎不影响精度;分步投影 KV 主要管精度。
什么时候建排名也做了对比(工业数据集,延迟单位 ms/batch):
| 在第几步建排名 | 第 0 步 | 第 1 步(默认) | 第 2 步 | 第 3 步 |
|---|---|---|---|---|
| Recall@10 | 0.1632 | 0.1695 | 0.1701 | 0.1704 |
| 延迟 | 55 | 62 | 94 | 103 |
第 0 步就建,最快但精度最低;拖到第 2、3 步,精度只再涨一点,延迟却多出一半左右。这和前面的观察对得上:第 0 步注意力太分散,选不准;第 1 步已经收拢,所以选一次就够。
预算也不能砍太狠。 降到 192 时 Recall@10 几乎不变,降到 128 才明显掉到 0.1648,延迟却只比 256 时少 10 ms/batch。这说明适度删减历史只是去掉冗余,砍得太狠就会丢掉有用的偏好,作者因此取 256 作为折中。
线上做了 7 天 A/B,对照组是线上的生成式推荐,历史截断到 128 条;实验组用 PFA,历史加长到 512 条,各占 10% 流量。广告收入提升 3.76%,CTR 提升 0.34%,GMV 提升 2.56%。PFA 的线上响应时间是 11 ms,直接把 512 条历史放进去要 15 ms。这说明加长历史带来的收益是真的,而 PFA 让这份收益不用拿延迟去换。
我认为它的局限
第一,精度提升的来源要分开看。去掉分步投影 KV 后,工业数据集 Recall@10 是 0.1602,比完整 attention 的 0.1643 还低。也就是说,分步投影是 PFA 精度上最关键的一项,但现有对照拆不开它和稀疏各自的影响。想把两者分开,要自己补一组“完整 attention 加分步投影”的对照。
第二,线上延迟只和“直接用 512 条”比。论文给的是 PFA 的 11 ms 和完整 512 条的 15 ms。上线前更要紧的是加长历史后比现在 128 条的系统慢了多少,这要自己测。
第三,收益和 SID 长度强相关。逐步缩小只在第 2 步之后起作用,4 个码的 SID 只有两步能缩,所以去掉它延迟只多 3 ms/batch。码更短的系统收益会更小。论文说码更长时优势更明显,这个结论来自理论计算量的分析,实验里的 SID 都是 4 个码。
一个推荐/搜索团队可以怎么试
- 先在现有生成式召回模型上复现那两张统计图:按解码步统计前 10% 历史拿到的 attention 权重,以及第 1 步排名和后面各步的 Spearman 相关。这一步不改模型,只看自己的数据是不是也有“越来越集中、排名稳定”的规律。
- 规律成立的话,先做最便宜的版本:不改训练,推理时在第 1 步按生成概率加权汇总 attention,排出共用排名,后面各步只看前 k 条。离线比 Recall 和延迟,判断稀疏本身损失多少精度。
- 再加分步投影 KV,这需要重新训练。和第 2 步的结果对比,就能把精度提升和稀疏的影响分开。
- 最后把省下的延迟花在加长历史上,在线上做 A/B,同时记录对照组和实验组各自的响应时间。
结论
PFA 最值得带走的一点是:生成式推荐的逐步解码让注意力越来越集中,挑选可以只做一次,挑选的成本和内存的读取方式比计算量本身更决定实际速度。
| 维度 | 评价 |
|---|---|
| 问题重要性 | 高。长历史提升效果,但 beam 解码的延迟限制了历史长度 |
| 方法创新性 | 中。共享索引在大模型推理里已有,新意在跨 beam 按概率加权和按步缩小预算 |
| 实验证据 | 中高。三个数据集加 7 天线上 A/B,但精度提升和稀疏化的贡献没有完全拆开 |
| 工程成本 | 中。推理侧改动集中,分步投影 KV 要重新训练 |
| 是否值得尝试 | 值得。先用不改训练的推理版验证规律,成本很低 |
读完这篇,你觉得
夜读鸮记下了,谢谢你的反馈。
点一下即可,无需登录;再点一次撤回。只统计匿名次数,不记录你是谁。
相关论文RELATED
Generative · 2026-10-24Coarse-to-Fine Long-term Interest Modeling for Generative Recommendation生成式推荐一个码一个码地生成下一个物品的 Semantic ID,注意力计算量随序列长度平方增长,所以这类模型通常只吃最近几十条行为,用不上长期历史。GLASS 按 Semantic ID 的层级分开用长期历史。生成第一层码之前,它给每个一级码取该类物品向量的平均当原型。再把余弦相似度区间等分成若干档,统计长期历史里和原型的相似度落在每一档的物品数,所有一级码的计数拼起来经一个小网络压成一个兴趣 token 送进编码器;第一层码生成之后,拿它当检索键,从长期历史里取出同一大类的物品,辅助生成后两层码。在 TAOBAO-MM 上,R@1 比最强基线高 21.57%;短视频平台两周 A/B 中,召回率绝对提升 3 个百分点。
Generative · 2026-10-29KL-MOPD: Discrepancy-Aware Multi-Objective On-Policy Distillation for Generative Recommendation把点击老师和价值老师一起蒸馏进生成式推荐时,每个 token 平分权重并不公平:在 TencentGR 上,学生生成第 1 个 token 时离价值老师的 KL 是离点击老师的 3.13 倍,而且难学的老师在后两个 token 换成了点击老师。浙大和阿里的 KL-MOPD 在训练前算一次学生离两个老师的距离,每个 token 上离得更远的老师拿更大的权重,训练时没有额外开销。线上 A/B 中,广告收入提升 1.63%,说明点击和价值两个目标一起涨了。
Generative · 2026-10-29PailitaoMMSearch2.0 Technical Report: Scaling Generative Retrieval to Unified End-to-End Multimodal Search淘宝拍立淘里,用户拍一件衬衫再说「找条配它的短裤」,要的是搭配而不是同款。传统做法先分意图、再分发到不同召回通道,任何一步分错后面全错。阿里这篇技术报告让一个 2B 视觉语言模型直接读原图和原话,生成商品的 Semantic ID,不需要意图标签。优秀率指前 10 个结果里被评审模型判满分的比例。「找搭配」请求的这一指标从多路召回链路的 44.2% 提到 74.3%,线上 GMV 提升 8.94%,已全量上线。
Generative · 2026-07-23TSGR: Taobao Search Generative Retrieval淘宝搜索的 TSGR 在 SID 第 3 层按点击给商品排座次,并按 query 准备多套排序,让卖得好又贴合 query 的商品更容易被生成,同一模型再接打分模块做重排。离线 HR@1000 从 0.7735 提到 0.8651,线上 GMV +1.64%;但重排抬高了前 1000 命中、压低了前 20 命中。
讨论
欢迎补充实验细节、复现经验或不同看法。需 GitHub 登录。
正在加载讨论…