如果把推荐系统的所有工作都交给一个模型,它应该长什么样?
传统答案是一棵“模型树”:
评分预测 → 回归模型
下一项推荐 → 序列模型
解释生成 → 文本生成器
评论理解 → 分类器
直接推荐 → 排序模型
每个任务有自己的输入格式、输出头和损失函数。团队每增加一个任务,就多维护一套数据管线。
上一篇 BERT4Rec 已经把商品当成 token,把历史当成句子。但它仍只会回答一种问题:被遮住的 Item ID 是什么?
既然语言可以描述任务,那就把评分、排序和解释全部写成文本输入—文本输出,用一个 encoder–decoder 和一种语言建模损失共同学习。
这一篇是系列的分水岭。前四篇在设计更好的推荐模型;从 P5 开始,研究者尝试设计推荐领域的通用接口。
30 秒看懂本文
- BERT4Rec 留下的问题:Item ID 虽然成了 token,不同推荐任务仍由不同架构和目标解决,知识不能自然迁移。
- P5 的答案:建立 personalized prompt collection,把五类任务都转成 文本对,以 T5 式 encoder–decoder 最小化同一个 token-level NLL。
- 最重要的证据:统一生成并未必牺牲推荐精度。原论文 Table 3 中,P5 在 Sports、Beauty、Toys 的全商品下一项推荐上达到或超过专用序列模型;未见过的 prompt 改写也能工作。
图 1:统一的不是“所有输出都变成长文章”,而是输入—目标都能表示为 token 序列。
上一篇留下了什么问题
BERT4Rec 的接口仍然很窄:
输入: [I01, I03, I05, MASK]
输出: I06
如果产品经理再问三个问题:
- 小林会给 I06 打几星?
- 为什么要向小林推荐 I06?
- 在 I06 和 I07 之间应该选哪件?
我们通常要分别准备评分标签、解释文本、候选集,再设计不同模型头。即使这些任务都在描述同一个人和同一件商品,它们学到的参数也未必共享。
P5 观察到:任务间真正不统一的是接口。如果所有任务都能写成“给定一段文本,生成另一段文本”,模型架构和训练目标就可以共享。
但“写成文本”不等于把 ID 丢掉。P5 的输入同时容纳:
user_23、item_7391这样的离散 ID;- 用户描述、商品标题与属性;
- 历史交互;
- 评分、评论和解释;
- 描述当前任务的 prompt。
它想同时保留协同信号与语言语义。
用八件商品理解 personalized prompt
继续使用小林和同一组商品:
| ID | 商品 | 在例子中的作用 |
|---|---|---|
| I01 | 网球拍 | 历史行为 |
| I02 | 吸汗带 | 候选 |
| I03 | 攀岩鞋 | 历史行为、已知高评分 |
| I04 | 粉袋 | 候选 |
| I05 | 羽毛球 | 历史行为 |
| I06 | 泳镜 | 下一项真值 |
| I07 | 瑜伽垫 | 负候选 |
| I08 | 蛋白棒 | 评论商品 |
同一份日志可以被实例化成不同训练样本。
评分预测
Input: What star rating will user_小林 give item_I03?
Target: 5
下一项推荐
Input: user_小林 has interacted with I01, I03, I05.
What item comes next?
Target: I06
解释生成
Input: Explain why item_I03 is recommended to user_小林.
Target: 攀岩鞋适合他近期增长的户外运动兴趣。
直接推荐
Input: Choose one item for user_小林 from I06 and I07.
Target: I06
图 2:模板改变任务,用户与商品事实保持一致。真实 P5 共覆盖 rating、sequential、explanation、review、direct recommendation 五个任务族。
这里有一个容易忽视的细节:prompt 不只是自然语言说明,还包含个性化字段。把 {user_id}、{item_id}、{history}、{review} 填入模板后,才能得到真正的样本。它更像一个带类型的查询语言,而不是一句装饰性的提示词。
论文还为同一任务设计多种措辞,并在预训练时留出部分模板。这让实验可以测试:模型到底学会了任务,还是只记住某一句固定问法。
模型从输入到输出发生了什么
1. 将原始数据实例化为 input–target
训练管线从评论、评分和行为序列中抽取字段,再随机选择一个 prompt 模板。需要候选集的任务会额外采样负商品。
2. 把 ID 也交给 SentencePiece
P5 没有为每个用户和商品永久增加一个独立词表 token。item_7391 可能被拆为:
item | _ | 73 | 91
这样词表不会随商品数线性膨胀。代价是不同 ID 会共享子词,数字本身未必有语义。论文因此额外加入 whole-word embedding,告诉模型这些子词属于同一个字段。
3. Encoder 读取完整 prompt
输入 token embedding、position embedding 与 whole-word embedding 相加:
再由双向 Transformer encoder 得到:
4. Decoder 逐 token 生成答案
Decoder 同时读取 encoder 表示与此前生成的 token:
评分可以是 "4",偏好可以是 "yes",商品可以是 "item_6",解释则是一串自然语言 token。
图 3:任务共享 encoder、decoder 与 NLL;greedy decoding、beam search、候选约束等推理策略仍按输出类型选择。
若 batch size 为 ,输入长度为 ,目标长度为 :
| 张量 | Shape | 含义 |
|---|---|---|
| input IDs | 实例化后的 personalized prompts | |
| encoder states | 输入上下文表示 | |
| shifted target IDs | teacher forcing 的 decoder 输入 | |
| vocabulary logits | $[B,m, | V |
注意输出词表 是语言词表,不等同于商品目录 。Item ID 被表示成一个或多个普通子词,因此“生成了语法合法的 token”不保证“生成了目录中存在的商品”。
核心公式逐项拆解
P5 的全部任务共享一个负对数似然:
- :当前 personalized prompt;
- :目标文本;
- :答案的第 个 token;
- :teacher forcing 时已知的答案前缀;
- :五类任务共同更新的模型参数。
把玩具例子代入:
x = “根据 I01, I03, I05,下一件是什么?”
y = [“I”, “06”]
训练会分别增加 "I" 和 "06" 的条件概率。对于解释任务,公式完全不变,只是 更长。
“一种损失”带来共享,也带来冲突:评分任务可能只需一个 token,解释任务可能有几十个 token。如果简单把所有 token 相加,长文本任务天然产生更多梯度;不同任务的数据量也会改变优化方向。P5 通过任务与 prompt 采样取得经验平衡,但没有从理论上消除 multi-task interference。
训练和推理分别怎么做
for each raw record:
choose a task family
sample one personalized prompt template
fill user, item, history, review, or candidates
create (input_text, target_text)
mix examples from all five task families
tokenize input and target
encode input with bidirectional Transformer
decode target with teacher forcing
update all parameters by token NLL
推理策略依任务而变:
rating / review / explanation:
greedy_decode(prompt)
sequential recommendation:
beam_search(prompt, beam_size=20)
parse generated Item IDs
direct recommendation:
either rank candidates by P("yes" | prompt)
or generate candidate Item IDs with beam search
论文的下一项推荐使用全商品设置;直接推荐实验则常用一个正样本与 99 个未交互商品组成候选池。两者不能混作同一难度。
实验究竟证明了什么
P5 在 Amazon Sports、Beauty、Toys 以及 Yelp 上测试五类任务。它最有价值的证据不是某个单点 SOTA,而是一个共享模型能同时完成异构输出。
在下一项推荐的 NDCG@5 上:
| 数据集 | 论文中强专用基线 | P5 |
|---|---|---|
| Sports | S³-Rec 0.0161 | P5-B 0.0296 |
| Beauty | SASRec 0.0249 | P5-B 0.0379 |
| Toys | SASRec 0.0306 | P5-S 0.0567 |
图 4:数值重绘自原论文 Table 3。不同数据集最好的 P5 尺寸并不一致。
这组结果支持:“统一 text-to-text 至少可以学会有竞争力的序列推荐。”它没有证明生成式接口在所有任务都稳赢。
论文自己的结果就提供了反例:
- 60.75M 参数的 P5-small 在若干任务上优于 223.28M 的 P5-base,规模并非单调收益;
- 多任务模型在评分、序列和直接推荐上常有帮助,但某些解释与评论生成任务由单任务版本表现更好;
- P5-B 在直接推荐的部分 prompt 上明显落后 P5-S;
- 对未见 prompt 的零样本测试较稳健,但跨新领域、新商品的迁移仍不一致。
因此更准确的结论是:共享语言目标建立了迁移通道,不保证每个任务都得到正迁移。
它失败在哪里
1. ID 被写成文本,不等于 ID 有语义
item_7391 拆成数字子词只是编码技巧。相邻编号没有理由代表相似商品,模型仍主要依赖训练交互记住这些组合。
2. 自由生成可能产生无效商品
语言模型能生成词表内序列,但目录只接受有限 Item ID。实际系统需要 constrained decoding、候选重排或后处理;论文并未解决百万级目录下的严格合法性与延迟。
3. 多任务共享会互相抢容量
不同任务的梯度尺度、数据量和输出长度不同。统一模型减少了模型数量,却把工程问题转移到采样比例、prompt 设计和冲突控制。
4. “零样本”有严格边界
对未见过的模板措辞零样本,不等于对新用户、新商品或新领域都零样本。若用户 ID 曾在训练域出现,迁移仍可利用已学表示。
5. 实验目录远小于工业规模
论文数据集最多约两万件商品。beam search 生成 ID 的可用性、吞吐量和错误恢复在亿级目录中仍未验证。
6. 任务统一不等于服务统一
评分、检索、CTR 和长文本生成有完全不同的延迟预算。一个模型在论文接口上能做所有事,不代表它能在一条线上请求中以同样成本完成所有事。
下一篇为什么会出现
P5 回答了“学术上能不能统一”,却留下了更硬的工业问题:
- 召回要面对百万、亿级商品;
- 排序要在几十毫秒内返回;
- 每个新任务不能复制一份 300M 参数模型;
- 模型还要部署到手机;
- 推荐之外,平台甚至希望它生成搜索词和新内容。
下一篇 M6-Rec 会把 P5 的统一思想推进到工业 foundation model:同一个预训练底座怎样覆盖召回、排序、解释、对话与创作,又怎样靠 option tuning、late interaction、蒸馏和剪枝真正上线。
论文:Geng et al., “Recommendation as Language Processing (RLP): A Unified Pretrain, Personalized Prompt & Predict Paradigm (P5),” RecSys 2022.
系列导航:二十篇论文看懂生成式推荐的前世今生