← All writing生成式推荐 · 05

所有推荐任务都能改写成一句话吗?|生成式推荐 05:P5

P5 把评分、下一项推荐、解释、评论理解与直接推荐统一成 text-to-text:同一个模型、同一种损失,只改变 personalized prompt。

Read the English edition →

如果把推荐系统的所有工作都交给一个模型,它应该长什么样?

传统答案是一棵“模型树”:

评分预测 → 回归模型
下一项推荐 → 序列模型
解释生成 → 文本生成器
评论理解 → 分类器
直接推荐 → 排序模型

每个任务有自己的输入格式、输出头和损失函数。团队每增加一个任务,就多维护一套数据管线。

上一篇 BERT4Rec 已经把商品当成 token,把历史当成句子。但它仍只会回答一种问题:被遮住的 Item ID 是什么?

Recommendation as Language Processing (RLP): A Unified Pretrain, Personalized Prompt & Predict Paradigm (P5) 往前走了一步:

既然语言可以描述任务,那就把评分、排序和解释全部写成文本输入—文本输出,用一个 encoder–decoder 和一种语言建模损失共同学习。

这一篇是系列的分水岭。前四篇在设计更好的推荐模型;从 P5 开始,研究者尝试设计推荐领域的通用接口

30 秒看懂本文

  1. BERT4Rec 留下的问题:Item ID 虽然成了 token,不同推荐任务仍由不同架构和目标解决,知识不能自然迁移。
  2. P5 的答案:建立 personalized prompt collection,把五类任务都转成 文本对,以 T5 式 encoder–decoder 最小化同一个 token-level NLL。
  3. 最重要的证据:统一生成并未必牺牲推荐精度。原论文 Table 3 中,P5 在 Sports、Beauty、Toys 的全商品下一项推荐上达到或超过专用序列模型;未见过的 prompt 改写也能工作。

从任务专用模型到统一文本接口

图 1:统一的不是“所有输出都变成长文章”,而是输入—目标都能表示为 token 序列。

上一篇留下了什么问题

BERT4Rec 的接口仍然很窄:

输入: [I01, I03, I05, MASK]
输出: I06

如果产品经理再问三个问题:

  • 小林会给 I06 打几星?
  • 为什么要向小林推荐 I06?
  • 在 I06 和 I07 之间应该选哪件?

我们通常要分别准备评分标签、解释文本、候选集,再设计不同模型头。即使这些任务都在描述同一个人和同一件商品,它们学到的参数也未必共享。

P5 观察到:任务间真正不统一的是接口。如果所有任务都能写成“给定一段文本,生成另一段文本”,模型架构和训练目标就可以共享。

但“写成文本”不等于把 ID 丢掉。P5 的输入同时容纳:

  • user_23item_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

同一份行为数据对应的四种 personalized prompt

图 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。

P5 从 prompt 到多任务输出的数据流

图 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

P5 与专用序列模型的下一项推荐结果

图 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.

原文arXiv:2203.13366

系列导航二十篇论文看懂生成式推荐的前世今生