# 论文 vs 代码一致性核查:PLUM(仅第三方复现) ## 核查对象与方法(含命令) - 论文:PLUM: Adapting Pre-trained Language Models for Industrial-scale Generative Recommendations,arXiv:2510.07784v1(WWW 2026 投稿版本,Google/YouTube)。官方**未开源**(论文与 arXiv 页面均无代码链接)。 - 核查对象: - 复现1:`github.com/nikonhovzunov/plum-ml1m-repro`(4★) - 复现2:`github.com/vishsangale/plum`(2★) - 命令: ```bash git clone --depth 1 https://github.com/nikonhovzunov/plum-ml1m-repro "…/workdir/p4-plum-repro1" git clone --depth 1 https://github.com/vishsangale/plum "…/workdir/p4-plum-repro2" curl -sL -m 60 https://arxiv.org/pdf/2510.07784 -o /tmp/p4.pdf # 论文文本用 pymupdf(fitz) 提取,全文 11 页(含附录) ``` - 运行环境:macOS,Python 3.13.13;系统无 torch/pandas。复现1在仓库内建 venv(`pip install -e ".[dev]"`)后跑轻量检查;复现2只做 `compileall` + 配置类导入(其 requirements 锁定 torch 2.9.1+CUDA,未安装)。 ## 论文关键声明清单 1. **SID-v2 语义 ID 生成(§2.1)**:在 TIGER RQ-VAE 基础上,多模态内容嵌入融合(每模态一个 encoder,concat+project,§2.1.1);多分辨率码本 `2048/2^(l-1)`(§2.1.2);渐进掩码 `m_l = 1[l has title (en): \")做下一 token 预训练,1M 步、约 260B token;SFT——decoder-only 模型自回归生成下一物品 SID,奖励加权 MLE(式3),推理用 beam search 解码多条 SID,幻觉率 <5%。 3. **工业级规模(§3)**:YouTube 内部数据(数十亿视频、每天 2.5 亿样本);Gemini-1.5 MoE 家族(900M 激活 / ~4.2B 总参,扩展至 110M–3B 激活);1024 张 v6e TPU;输入序列 1536 token。 4. **评测指标(§3)**:Video Recall@10(SID 消融 12.3%→14.4%,SID 唯一性 94.0%→96.7%);CPT 消融 R1/R2/CR1/CR2 Recall@10 = 0.19/0.23/0.27/0.28;生产指标 CTR/WT/WF、有效词表规模与线上 A/B。 ## 复现1(nikonhovzunov/plum-ml1m-repro)证据对照表 定位:作者自述为「PLUM-style adaptation on MovieLens-1M」(README.md:1-5),非 SOTA 声明。数据:MovieLens-1M(6040 测试用户);模型:Qwen3-0.6B/4B(QLoRA/LoRA/全参);SID 嵌入:Qwen3-Embedding-4B(2560d)。 | 论文声明 | 代码证据(文件:行号) | 判定 | |---|---|---| | 多模态内容融合(§2.1.1) | `src/plum_ml1m/legacy/sid/rqvae.py:87-102`(每模态 FeatureBranch)、`:160-186`(branches+fusion MLP)、`:189-200`(每模态 decoder) | 实现(meta 文本 + 剧情简介两模态;MovieLens 无音视频,属合理替代) | | RQ-VAE 残差量化 | `rqvae.py:104-157`(ResidualQuantizer 逐级最近邻+残差) | 实现 | | 多分辨率码本 2048/2^(l-1)(§2.1.2) | `src/plum_ml1m/protocol.py:33-37`、`configs/rqvae_sid.yaml`:`[512,256,128,64]` | 部分实现:递减多分辨率思想一致,但尺度缩小(4 层 512 起而非 2048 起),适配小数据 | | 渐进掩码 m_l=1[l has title: …" / "The genres in movie \ are:…" 等元数据模板,与论文表1同风格);`configs/cpt.yaml`:`behavior_ratio: 0.5`;基座 `Qwen/Qwen3-4B-Base` + QLoRA | 实现(规模远小于论文的 260B token/1M 步) | | SFT:自回归生成下一物品 SID、目标 token 专属损失(式3) | `configs/sft.yaml`:`target: next_watched_item`、`target_only_loss: true`、`beam_size: 20, top_k: 10`;`notebooks/sft/21_…qwen3_4b_qlora32….ipynb`(AutoModelForCausalLM+QLoRA32) | 实现(无奖励加权 r(user,v_click)——MovieLens 无用户反馈信号,属不可复现部分) | | 推理:beam search 解码多条 SID、控制幻觉(§2.3) | `src/plum_ml1m/trie.py:9-52`(SID 字典树);`legacy/sft/decoding.py:95-144`(`num_beams=20` + `prefix_allowed_tokens_fn` 约束 beam search);`src/plum_ml1m/decoding.py:27-50` | 实现(trie 约束解码可保证只生成有效 SID) | | SID 到物品映射与碰撞处理(§3 评测细节) | `src/plum_ml1m/sid.py:68-164`(sid_to_items、collision expand、seen 过滤) | 实现 | | 评测:Recall@K/NDCG/MRR/Coverage(物品级) | `src/plum_ml1m/metrics.py:9-47`;`src/plum_ml1m/eval/runner.py`;`docs/EVALUATION.md` | 实现 | | 复现结果报告 | `README.md:42-103`、`docs/RESULTS.md`(验证集 Recall@10:SFT-only 0.1747 vs CPT+SFT 0.2707,即 CPT 消融;测试集 Qwen3-4B QLoRA32 Recall@10=0.2550;SID 深度消融;SASRec/BERT4Rec 基线);图表 `docs/assets/*.png` | 有,且诚实报告「PLUM 风格未超过 SASRec/BERT4Rec 基线」(README.md:91) | | 可运行性 | 本机验证:`pip install -e ".[dev]"` 成功;`pytest -m "not gpu and not slow"` **44 passed**;`validate-config` 通过;`smoke-test` 端到端输出指标 JSON | 通过(重训需自备大模型权重与数据产物,见 `docs/KNOWN_LIMITATIONS.md`;重训命令为 plan-only,需 `--execute`,`src/plum_ml1m/cli.py:32,157-161`) | **判定:部分实现(忠实改编/高质量学术复现)**。三阶段管线(SID-v2 RQ-VAE→CPT→SFT+约束 beam search)齐全且与论文机制一一对应,含 CPT 消融与 SID 深度消融、诚实的结果报告。非完整复现之处:规模(ML-1M vs 工业数据)、码本尺度、默认渐进掩码课程表、无奖励加权 SFT。 ## 复现2(vishsangale/plum)证据对照表 定位:README 自称「PyTorch implementation of the PLUM framework」。数据:MovieLens-1M/10M/25M;嵌入:sentence-transformers all-MiniLM-L6-v2(384d,仅标题+类型文本);LLM:distilgpt2(约 82M)。 | 论文声明 | 代码证据(文件:行号) | 判定 | |---|---|---| | 多模态融合(§2.1.1) | `plum/sid_model.py:5-53`(MultiModalEncoder:各模态 encoder+concat+project) | 框架实现,但实际只喂单模态(`plum/config.py:75` `input_dims=[384]`),融合结构退化为单分支 | | RQ-VAE + 多分辨率码本(§2.1.2) | `sid_model.py:55-233`(RQVAE,码本尺寸可配) | 实现(ML-1M 用 `[64,64,64]` 等宽码本,`config.py:133`,未按论文公式) | | 渐进掩码 r 随机(§2.1.2) | `sid_model.py:164-168`(每 batch 采样 r∈[1,L],只累加前 r 级) | 实现 | | 共现对比损失(§2.1.3) | `sid_model.py:269-304`(ContrastiveLoss/InfoNCE);共现对来自序列相邻物品 `plum/data.py`(PLUMSIDDataset 中 `(seq[i], seq[i+1])`);训练循环 `plum/train_sid.py:124-162`(recon+commit+contrast 加权求和) | 实现(简化版共现定义) | | CPT:词表扩展+领域语料预训练(§2.2) | `plum/llm_model.py:27-55`(向 GPT-2 词表添加 `` token);`plum/prepare_llm_data.py:137-185`("SID grounding tasks":SID↔标题双向语料混入训练数据) | 部分实现:**无独立 CPT 阶段**,grounding 语料与行为序列混成单一训练集 | | SFT:自回归生成下一物品 SID + 奖励加权(式3,§2.3) | `plum/train_llm.py:92-165`(单一阶段 next-token 训练,`labels=input_ids`,对整条序列全部 token 求 loss) | 部分实现:有自回归 SID 生成训练,但无独立 SFT 阶段、无目标 token 专属 loss、无奖励加权/降采样 | | 推理:beam search 解码多条 SID(§2.3) | `plum/inference.py:84-96`(`num_beams=5` 或采样);SID 从生成文本中正则解析 `:104-143` | 部分实现:无 trie/前缀约束,幻觉不受控(作者自记推断时全部影片坍缩到同一 SID「30-17-13」,`plum/README.md:225`) | | SID→物品映射、碰撞处理 | `plum/inference.py:135-143`(`sid_to_movies.get` 返回列表) | 最小实现 | | 评测指标(Recall@10 等系统性评测) | 仅 `plum/inference.py:254-386` 对少数随机样本计算演示性 Recall@5;**无全量留出集评测脚本、无基线对比、无结果报告** | 缺失 | | 复现结果报告 | 无 LLM 检索结果;只有 SID 训练过程记录(唯一性 14.32%→36.54%,`plum/README.md:103,143-153`) | 部分(SID 阶段有记录,检索阶段无) | | 可运行性 | 本机验证:`python3 -m compileall plum/` 通过;`PLUMConfig()` 可实例化(ML-1M 码本 `[64,64,64]`、LLM=distilgpt2)。但 `plum/test_rqvae.py:19-20` 仍按旧签名 `RQVAE(dim, n_levels, base)` 调用,与现行 `RQVAE(input_dim, codebook_sizes, kmeans_init)`(`sid_model.py:61`)不匹配;`config.py:58-59` LLMConfig 中 `epochs` 字段重复定义 | 部分可运行(未装 torch 未实跑训练;测试代码已过期) | **判定:部分实现(偏原型/框架级)**。SID-v2 的 RQ-VAE 组件(多分辨率码本、渐进掩码、共现对比损失、K-means 初始化、dead-code revival)实现较完整且真实训练过;但 LLM 侧只有单阶段 distilgpt2 微调、无 CPT/SFT 划分、无约束解码、无系统评测与结果——生成式检索部分仅到「能跑出演示」的程度。 ## 运行尝试记录 - 复现1:venv 安装轻量包成功(约 1 分钟);`pytest -m "not gpu and not slow"` 44/44 通过(覆盖 SID schema、trie 解码、指标、端到端评测报告、CLI smoke);`validate-config` 对 9 个 YAML 全部通过;`smoke-test` 输出含 recall/ndcg/mrr/coverage 的 JSON。未运行训练(需下载 Qwen3 权重与 ML-1M 数据产物,超出 10 分钟限时;README 明示重训产物不入 git)。 - 复现2:未安装其 requirements(锁定 torch 2.9.1+CUDA 与 CUDA 依赖包,本机无 GPU 且超时);`compileall` 语法检查通过;无 torch 无法导入 `sid_model.py` 做 smoke;`config.py` 纯 dataclass 可实例化验证。发现 `test_rqvae.py` 与现行 API 不符(旧签名),说明测试未随重构更新。 - 两个仓库均未下载任何大模型权重。 ## 结论 - **复现1(nikonhovzunov/plum-ml1m-repro):部分实现,方向忠实、工程化程度高。** 忠实覆盖论文三阶段管线(SID-v2 多模态 RQ-VAE+多分辨率码本+渐进掩码+共现对比损失;独立 CPT 阶段(50/50 混合、词表扩展、QLoRA);SFT 生成式检索+目标 token loss+trie 约束 beam search),含 CPT 消融、SID 深度消融、5 个基线对比与完整指标(Recall/NDCG/MRR/Coverage),并有 44 个通过的单元测试与 CI。距论文差距:数据(ML-1M ~1M 交互 vs 工业数十亿视频/日 2.5 亿样本)、模型(0.6B–4B 稠密 vs 900M 激活 MoE≈4.2B 总参)、码本尺度(512 起 vs 2048 起)、无奖励加权 SFT(依赖论文未公开的用户反馈信号)。其报告也诚实指出:PLUM 风格方法在 ML-1M 上未超过 SASRec/BERT4Rec。 - **复现2(vishsangale/plum):部分实现(偏原型)。** SID 量化侧较完整(与论文 §2.1 机制对应且真实训练),但生成式检索侧严重简化:无 CPT/SFT 两阶段、无约束解码(作者自记推断坍缩到单一 SID)、无系统评测与结果报告、测试代码过期。距论文工业设置差距更大。 - **官方代码缺失的影响**:论文数据(YouTube 内部)、SID 多模态嵌入源、CPT 语料模板细节、奖励加权与降采样策略、Gemini 基座权重均不可得,任何第三方只能做小数据「机制忠实」复现,无法验证表 2–6 的数字。两复现的共同结论(CPT 有益、SID-v2 优于 SID-v1 的结构思想)与论文方向一致,但绝对数值不可比。 ## 局限 - 仅浅克隆(`--depth 1`),未核查两仓库完整历史与 issue;复现1的 Qwen3 训练在 notebooks 中,未逐 cell 审查其与 configs 的一致性。 - 未实跑重训练(GPU/大模型/数据产物均不可得),复现1 的重训路径只验证到 CLI plan/校验与 smoke test 层。 - 论文为 v1 版本(arXiv:2510.07784v1,2025-10-09),若 WWW 2026 camera-ready 有修改,结论可能需微调;官方代码未公开(截至核查日无法验证其是否存在)。 - 复现2 因无 torch 环境仅做静态核查+配置实例化,其训练脚本的运行期正确性(如 AMP、DataLoader)未经实测。