PCP-Decoding: Training-Free Personalized Category-Relative Popularity Calibration for Generative Retrieval
Zhejiang University × JD.com
提出“前缀等价类坍缩”(prefix equivalence-class collapse)这一概念:Semantic ID 前缀约束解码时,共享前缀的分数被热门后代撑高,冷门兄弟节点在早期层就被剪掉,后面再也救不回来。PCP-Decoding 不重训模型,在每一步对合法子节点的 logit 减去 α(u)·Δ(子前缀与父前缀的类目内相对热度对数差),α(u) 由用户近 30 天点击的冷门偏好推断、上界为 γ,从而在束搜索内部重分配 beam 预算。
核心思路
Semantic ID 生成式检索在前缀树(trie)约束下做束搜索。一个前缀代表了它下面所有的后代 item,前缀分数实际反映的是这些后代的聚合点击质量,而不是某个具体 item 的相关性。于是一个特别热门的后代会把它所在的共享前缀整体抬高,同层其他冷门兄弟前缀就在早期被挤出 beam;目标前缀一旦被剪掉,后面层的模型再准也救不回来。作者把这种树结构放大的流行度偏差叫做前缀等价类坍缩(prefix equivalence-class collapse)。
PCP-Decoding(Personalized Category-relative Popularity)的做法是:不重新训练,在每一步解码时,对当前前缀的合法子节点 logit 做一次热度校准——比父前缀更冷的子节点加分、更热的减分,校准强度 α(u) 依用户历史对冷门商品的偏好自适应,上界是系统参数 γ。γ=0 时严格退化为原解码器。
与已有工作的区分:训练期去偏要重新优化模型;事后校准(如 Steck 2018)作用在最终列表上,救不回早已在 trie 中被剪掉的候选;RIPOR/PAG 类前缀搜索方法优化的是相关性。PCP 针对的是合法子节点之间由热度驱动的竞争。
整体实现思路
三步流水线(对应论文 Figure 1):
- 离线:按二级类目做 item 热度归一化,再沿 trie 用幂平均把热度聚合到每个前缀节点,得到 C(p)。
- 请求时:用用户近 30 天点击历史算冷门偏好得分 S_niche(u),映射为有界强度 α(u)∈[0,γ]。
- 解码时:GR 主干给出下一 token 的原始 logit z_v,PCP 按子/父前缀热度对数差修正 logit,然后在合法子节点上做 masked log-softmax,累加到 beam 分数,照常走约束束搜索。
整个方法只引入一个需要调的系统旋钮 γ,其余超参(ρ=2、β=4、δ=1.1、λ=5、μ=0.5、τ=30 天)论文中全部固定。
子模块实现(可复现细节)
1. 类目内相对热度与前缀聚合
- pop(s):item s 的点击数;c(s):其二级类目。
- 归一化:
p̂op(s) = clip( log(1+pop(s)) / log(1+q0.99[c(s)]), 0, 1 ),其中 q0.99[c] 是该类目点击数的 99 分位。稀疏类目改用全局 99 分位。目的是让热度在类目内部可比,而不是跨类目比(大类目天然点击量大)。 - 前缀聚合:
C(p) = ( (1/|D(p)|) · Σ_{s∈D(p)} p̂op(s)^ρ )^(1/ρ),D(p) 为前缀 p 的全部后代 item,ρ=2。幂平均介于算术平均和最大值之间,能突出热门后代,又不只依赖最大值。 - 热度统计只用评测日之前的日志,避免穿越。
2. 个性化校准强度 α(u)
- 对用户近 30 天点击的每个 item s_i:冷门度
x_i = 1 − p̂op(s_i),时间衰减权重w_i = exp(−Δt_i / τ),τ=30 天。 - 平滑后的冷门偏好:
S_niche(u) = (λμ + Σ w_i x_i) / (λ + Σ w_i),λ=5、μ=0.5,相当于给稀疏历史加一个均值 0.5、强度 5 的先验。 - 映射:
α(u) = (γ/2) · (1 + tanh(β (S_niche(u) − 1/2))),β=4。因此 α(u)∈[0,γ];冷启动用户 S_niche=μ=0.5,得到 α=γ/2。 - 语义:γ 是系统级最大强度,α(u) 让偏好冷门的用户被校准得更多,偏好爆款的用户被校准得更少。
3. 校准后的约束解码
对当前前缀 p_t 的每个合法子节点 v,记 p_t^v = p_t ⊕ v,GR 主干给出的原始 logit 为 z_v:
Δ_t(v) = log(C(p_t^v) + δ) − log(C(p_t) + δ) # δ = 1.1
z̃_v = z_v − α(u) · Δ_t(v)
ℓ_t(v) = z̃_v − log Σ_{v'∈Child(p_t)} exp(z̃_v') # 只在合法子节点上归一化
B(p_t^v) = B(p_t) + ℓ_t(v) # beam 累计分
- Δ_t(v)<0(子节点比父前缀冷)→ 加分;Δ_t(v)>0(更热)→ 减分。
- 作者说明:未归一化的增量沿路径可解释为“热度势函数”的差分(逐层相加会望远镜式抵消为叶子与根的热度差),但由于每层是在合法子节点上 masked 归一化,最终并不是精确的叶子级校正。
- 每层 beam 最多保留 128 个前缀。GR 主干结构、SID 层数和码本大小论文未披露。
实验设置与结果
协议:京东工业流量,连续三天共 6,912 个 held-out session,候选约 110 万 item,用户历史取前 30 天。尾部目标为预计算节点热度最低 20%。Captured eCPM@k 为每个 session 召回到的 held-out 出价均值;Gini 基于节点级曝光次数计算。只扫 γ,其余超参固定。对比对象只有 Base(γ=0,即原解码器)和 Static PCP(α 固定为 0.25=γ/2,γ=0.5)。
主结果(表 1)
| 方法 | Leaf R@10 | Leaf R@1k | Node R@64 | Node R@256 | eCPM@100 | eCPM@1k | Tail Node R@64 | Tail Node R@256 | Gini ↓ |
|---|---|---|---|---|---|---|---|---|---|
| Base (γ=0) | .0804 | .5360 | .4110 | .5770 | .6280 | .9320 | .1140 | .1430 | .6190 |
| Static PCP (α=.25) | .0818 | .5395 | .4096 | .5773 | .6319 | .9329 | .1143 | .1714 | .5960 |
| Pers. PCP (γ=.5) | .0819 | .5401 | .4142 | .5788 | .6333 | .9391 | .1143 | .2286 | .5793 |
| Pers. PCP (γ=1.0) | .0775 | .5270 | .3990 | .5570 | .6230 | .9370 | .1430 | .2570 | .5370 |
| Pers. PCP (γ=1.5) | .0696 | .4870 | .3580 | .5100 | .5840 | .8870 | .1430 | .3430 | .4910 |
| Pers. PCP (γ=2.0) | .0621 | .4340 | .3070 | .4490 | .5440 | .8160 | .2000 | .3140 | .4480 |
要点:
- γ=0.5 时个性化 PCP 在全部准确率和 eCPM 指标上都略优于 Base 和静态对照,同时 Gini 从 .619 降到 .5793(静态为 .5960)。
- γ 继续加大,Gini 单调下降到 .448,但 Leaf R@1k 从 .5401 掉到 .4340、Node R@64 掉到 .3070。γ 本质上是 accuracy–exposure 曲线上的工作点,需在 held-out 流量上按业务约束选。
- Tail Node R 只有 35 个尾部目标,作者自己提示要谨慎解读。
前缀存活分析(表 2,L2 层,γ=0.5)
| 目标分组 | Base | PCP | Δ (pp) |
|---|---|---|---|
| All(6,912 session) | .5009 | .5065 | +0.56 |
| Q1(最冷) | .3586 | .3972 | +3.86 |
| Q2 | .4220 | .4525 | +3.05 |
| Q3 | .4751 | .4907 | +1.56 |
| Q4 | .5542 | .5401 | −1.41 |
| Q5(最热) | .7363 | .6909 | −4.53 |
分位基于 6,732 个可映射到 trie 的目标。整体 +0.56 pp 的 paired bootstrap(2,000 次)95% 置信区间为 [+0.10, +1.00] pp。增益集中在冷门目标,热门目标存活下降,说明 PCP 是在固定 beam 预算下把名额从热门前缀让给冷门前缀,与“早层剪枝”这一机制假设一致。
无线上 A/B 实验,作者将更大范围验证与线上部署列为未来工作。
思考与可参考价值
最值得拿走的是诊断方法而不是公式本身。 在电商 SID 生成式召回里,冷门商品召不回常被归因为模型或 SID 质量,但很可能只是 L1/L2 被热门子树挤出了 beam。按目标热度分位统计每层 ground-truth 前缀存活率(表 2 的做法)成本很低,能直接判断瓶颈是不是在解码剪枝。
PCP 是一个便宜的旋钮。 离线算 C(p)、请求时算 α(u)、解码时每个子节点加一项,不改模型、不改训练,γ=0 可一键回退。推断:同样的框架可以把 C(p) 换成其他前缀级统计(新品比例、扶持店铺占比、广告出价),变成通用的解码期业务调控手段。
需要警惕的地方:
- 收益很小且证据有限:γ=0.5 时 Leaf R@1k 只 +0.41 pt,整体存活 +0.56 pp(CI 下界 +0.10 pp),样本只有 6,912 个 session,尾部召回只有 35 个目标。
- 基线太弱:没有和扩大 beam、事后热度重排、训练期去偏、logit adjustment 比。落地前至少应对比“beam 从 128 加大到 256 + 重排”,确认收益真的来自早层保留。
- 安全区间窄:γ≥1 召回大幅下滑;Q5 热门目标存活 −4.53 pp,要评估对头部 GMV 的影响。
- 没有任何超参消融(ρ、β、δ、λ、τ、类目内归一化、幂平均),静态对照也只取了一个点,个性化相对静态的优势只在单点成立。
- 若自家 SID 不是按类目聚簇构建,类目内归一化与 trie 结构可能不对齐,C(p) 在同层兄弟之间的区分度需要先检查。
- 逐层 masked 归一化使校正不精确,SID 层数较多时偏差如何累积论文没有分析。
结论:一篇问题定义清楚、方法极简的短文(3 页,RecSys 2026),适合作为 SID 召回长尾问题的第一步排查和低成本实验;效果上限和相对其他去偏手段的优劣还需自己验证。