← Back to list
SONA

Sona Technical Report

生成式推荐 Yandex
Abstract 9 │ Reading 9 │ Rating —
2026-08-11
Sona Team
Yandex
SONA 是 Yandex Music 的单模型生成式推荐器,也是 Gryphon → Gryphon-v2 路线的系统级总报告:共享 encoder(8192 事件历史 + History Compression,深度只花在最近 2048 事件)一次编码后同时供 SID decoder 做约束 beam search(3×32k 码本,item 表征来自冻结 Qwen2.5-Omni + 协同精炼)与 item 级 Ranking Module 打分,后者唯一监督是从训练期专用、免特征、吃整年日志的 0.6B Teacher Ranker 蒸馏来的分数,候选同时取自当前 decoder 的 on-policy rollout 与 logged impressions;配 10 分钟权重同步、45 分钟端到端延迟的在线训练闭环,线上 A/B 用单模型整体替换 15+ 召回器 + 粗排 + 精排,活跃用户 +4.53%、总收听时长 +6.30%、点赞 +11.42%,为 Argus 增量的 2.35 倍。
评分原因
摘要评分:Yandex Music 用单一生成式模型整体替换掉 15+ 召回源加粗排精排的成熟级联,线上 A/B 活跃用户 +4.53%、时长 +6.30%、点赞 +11.42%,且增量是此前最强模型 Argus 的 2.35 倍,是「端到端生成式推荐取代多级级联」最有分量的工业证据之一。
精读评分:工业证据极强:单个模型(共享 encoder + SID decoder + 蒸馏 Ranking Module,无任何手工特征)在 Yandex Music 智能音箱 My Vibe 上整体替换 15+ 召回器 + 粗排 + 精排,活跃用户 +4.53%、时长 +6.30%、点赞 +11.42%,为此前最强模型 Argus 增量的 2.35×;配套给出 tokenizer / 容量 / 数据量 / teacher 设计 / 统一模型五组消融与完整在线训练闭环(45 分钟端到端延迟、10 分钟权重同步、41% 推理 MFU),是 2026 年该路线证据链最完整的报告。扣分点在于新颖性偏配方式(Gryphon-v2 配方 + 8k History Compression + 新 tokenizer 的组合)、Exp5 相对 Exp4 的 +1.41%→+4.53% 无法归因到单一组件、所有消融均为无显著性检验的点估计、离线主指标 TeacherRecall 与提供目标的 teacher 循环、student 上限被 teacher 锁死(叠加 teacher 重排可再翻倍),且码本固化 + beam 召回上界的扩展性隐患仍在。
semantic-id knowledge-distillation transformer multi-task sequence-compression inference-serving industrial

SONA 技术报告:为 Yandex Music 打造的单模型生成式推荐器

Sona Team(Yandex,贡献者含 Daria Tikhonovich、Oleg Sorokin、Vladislav Dodonov、Mariia Ulianova、Ilya Murzin、Anna Lipkina、Viktor Yanush、Denis Burshtein、Nikolai Savushkin、Artem Matveev、Kirill Golovko 等 34 人),arXiv 2608.11015v1,2026-08-11。场景:Yandex Music 智能音箱上的 My Vibe 无限个性化音乐流。

研究动机与背景

工业推荐的标准形态是多阶段级联。Yandex Music 的生产级联包含 15 个以上候选生成器,加上消费数百个特征的粗排与精排模型,而这些特征本身还来自 Argus 这类大型 transformer 与 target-attention 打分器。SONA 要回答的是:能不能用一个端到端训练、端到端服务的模型把整条链路替掉,并且更好。

音乐域与短视频、电商的三点差异塑造了 SONA 的设计:消费是被动的(流持续播放而注意力在别处,反馈以 play / skip / 偶发 like 到达);重复收听是常态(回到熟悉曲目常常正是用户想要的,重复是要建模的信号而非要过滤的冗余);二者叠加成核心张力——熟悉曲目稳定支撑时长,新 favorite 的发现要更长周期才兑现。测试面是智能音箱上的 My Vibe:播放开始时用户不指定艺人、流派、心情或任何偏好,是纯推荐设置,也是按收听时长计最大的界面之一。

论文在 §2.1 把设计哲学拆成六条:一个模型同时做生成与排序;一份用户表征跨任务共享——encoder 代价每请求只付一次,作者写道"我们因此采用 Gryphon [28] 这一统一 generate-and-rank 设计作为 SONA 的架构";不使用任何手工特征(SONA 与 teacher 都只吃 logged event 字段与学出来的 SID);排序需要稠密监督(NTP 每个位置都产生目标而显式反馈稀疏,无手工特征的 ranker 必须从数据里把这些结构学回来);把一年历史压进 teacher、再稠密蒸馏进 student——请求级 NTP 数据集每条样本都要重编码整段历史只为监督少数新目标、无法覆盖数月跨度,解法是让大 ranking 模型在整年日志上自回归训练把历史压进权重,再蒸馏进只用数周窗口训练的 Ranking Module;用 Rollout Distillation 对齐生成与排序——蒸馏候选来自当前 decoder 的 rollout,信号跟随模型当下的候选分布,又因两模块共享 encoder,同时塑造它们共同条件化的表征。

Figure 1(原文首页柱状图):My Vibe 智能音箱上历代 transformer 部署的增量 A/B 提升(%),收益逐代叠加:

部署 Active Users Total Listening Time Likes
V0 +0.56 +1.81 0.00
V1 +0.73 +1.23 +2.71
V2 +0.84 +1.46 0.00
Argus +1.93 +3.69 +10.76
SONA +4.53 +6.30 +11.42

与 Gryphon / Gryphon-v2 的系统谱系关系

本文标题极其泛化,必须先厘清它在 Yandex Music 生成式推荐谱系里的位置。结论是:SONA 是同一支团队 Gryphon → Gryphon-v2 路线的直接后继与系统级总报告,证据三条:

  1. 架构继承是明写的:§2.1 说 "We therefore adopt Gryphon [28], a unified generation-and-ranking design, as the architecture of SONA",§3.5 又说 Ranking Module "following the unified generation-and-ranking design of Gryphon [28]";引用 [28] 即 arXiv 2606.08604(Gryphon v1)。
  2. 术语继承自 v2:"Rollout Distillation" 是 Gryphon-v2 标题里的自造术语,SONA 全文用了 3 次却没有引用 2608.06213(v2 比本文早 5 天挂出)——同一团队复用自家术语的典型痕迹。
  3. 决定性的数值证据:SONA 的 Experiment 4(distilled model 单独替掉整条级联)报 TLT +1.62%、Likes +7.12%、"Repeat" +15.25%、Active Users +1.41%,与 Gryphon-v2 Table 2 的线上 A/B 逐项完全一致——Gryphon-v2 报告的那次 A/B 就是 SONA 的 Experiment 4。

SONA 相对 v2 的增量因此很清晰:(a) 历史从 2,048 扩到 8,192 事件并引入 History Compression(Exp 5 相对 Exp 4 的主要差异,AU 从 +1.41% 跃到 +4.53%);(b) tokenizer 的 item 表征从 CLMR 音频嵌入换成 Qwen2.5-Omni 音频 + 元数据再协同精炼;(c)(d)(e) 补上 Teacher Ranker 设计消融、在线训练闭环工程细节、容量与数据量 scaling 曲线。v2 是"把 teacher 蒸馏进服务模型"这一个方法点的论文,SONA 则是把 tokenizer、架构、teacher、蒸馏、基础设施、五组 A/B 串成完整流水线的系统技术报告。

核心方法:SONA 架构

Figure 2.1. SONA architecture and data flow.

服务时 encoder 把时序事件历史编码一次,产出 decoder 与 Ranking Module 共享的表征;decoder 自回归产出一束短 SID 元组,目录索引把元组映射到一个或多个曲目,Ranking Module 用同一份 encoder 状态给展开后的候选打分排序。训练时 tokenizer 把每个目标 item 转成 SID 序列提供 NTP 目标,冻结 Teacher Ranker 给 decoder 生成的候选打分提供蒸馏目标,两个损失都回传进共享 encoder。最终配置下 tokenizer 与 teacher 只在训练期存在,服务侧只有 encoder + decoder + 确定性 SID→item 映射 + Ranking Module。各组件的消费/产出/生命周期见原文 Table 2.1:

Table 2.1. Final SONA serving components and training-only supervision.

语义 tokenizer

Figure 3.1. Tokenization pipeline. The frozen Qwen2.5-Omni runs in prefill-only mode — no decoding.

tokenizer 给每首曲目分配固定的 3 个 Semantic ID(3 个各 32,000 条目的码本),离线分三阶段构建。(1) 内容特征:冻结的 Qwen2.5-Omni 对前 90 秒音频的 mel 频谱图 + 携带标题/艺人/标签的文本 prompt 做仅 prefill、不解码的前向,取最后一层状态。(2) 协同精炼:内容特征会让"可替代性"隐而不显——听众视为可互换的曲目在内容空间未必相邻,因此一个 4 层 4 头、维度 512 的精炼 transformer(QARM 风格)在协同相关曲目对上训练,mean-pool 成 256 维 item 嵌入 $z$,损失为:

$$\mathcal{L} = \mathcal{L}_{\text{InfoNCE}} + \lambda_{\text{align}} \mathcal{L}_{\text{align}} \tag{1}$$

一个 batch 含 $m$ 个协同对,产出 $2m$ 个精炼 item 嵌入 $z_a$;每个各当一次 anchor,其配对 $z_{a^+}$ 为正样本,其余 $2m-2$ 个为负样本:

$$\mathcal{L}_{\text{InfoNCE}} = -\frac{1}{2m}\sum_{a=1}^{2m} \log \frac{\exp\!\big(\mathrm{sim}(z_a, z_{a^+})/\tau\big)}{\sum_{b \neq a}\exp\!\big(\mathrm{sim}(z_a, z_b)/\tau\big)} \tag{2}$$

对齐项把 item 嵌入拉近同一曲目内容特征的均值 $\bar h_a$:

$$\mathcal{L}_{\text{align}} = \frac{1}{2m}\sum_{a=1}^{2m}\big\| z_a - \bar h_a \big\|^2, \qquad \lambda_{\text{align}} = 0.1 \tag{3}$$

协同对来自两条互斥的流:target-wise 流收集生产推荐器的共同曝光 item 集合——因为生产推荐器不在同一次响应里放同艺人曲目,这些共现按构造是跨艺人的;NPMI 流用归一化点互信息给共听打分:

$$\mathrm{NPMI}(i,j) = \frac{1}{-\log p(i,j)} \log \frac{p(i,j)}{p(i)\,p(j)} \tag{4}$$

$p(i,j)$ 是三个月窗口内两曲目在同一用户日志里共现的概率;只保留同艺人的高 NPMI 对,故两条流不相交。

Table 3.2:tokenizer InfoNCE 目标的协同对来源

对来源 挖掘窗口 对数
Target-wise(共同曝光,跨艺人) 3 周 220–240M
NPMI(共听,同艺人) 3 个月 20M

(3) 残差量化:精炼后的 $z$ 用残差 K-means 映射为 SID 元组——3 层各 32,000 质心、k-means++ 初始化、欧氏距离分配,每层量化上一层残差,元组是穿过码本的粗到细路径。

用户历史表示

一次请求的历史是时序序列 $u = (e_1, \dots, e_T)$,$T \le T_{\max}$,训练与服务用同一套选择规则。每个事件被三个 embedder 编码:

Table 3.3:历史事件特征与三个输入 embedder 的变换

Embedder 源信号 构造方式
Item track ID、artist ID、track duration track ID 哈希 3 次、artist ID 哈希 2 次进同一张共享嵌入表;track duration 分桶后嵌入
Context 智能音箱标志、organic-feed 标志 直接嵌入两个请求面标志
Feedback like 标志、played time 嵌入 like 标志;played time 除以时长得完播率,分桶后嵌入

两个连续量都分桶后嵌入而非当作裸标量,完播率为:

$$\rho_t = \frac{p_t}{\max(d_t, \epsilon)} \tag{5}$$

item embedder 把 5 个哈希身份特征与时长嵌入拼接后投影到 $\mathbb{R}^d$,另两个 embedder 在宽度 $d$ 上直接嵌入并求和;事件 token 是三者之和:

$$x_t = \mathrm{ItemEmb}(e_t) + \mathrm{ContextEmb}(e_t) + \mathrm{FeedbackEmb}(e_t) \tag{6}$$

再前置一个可学 CLS token 作为全局汇总位:

$$X = [\,x_{\mathrm{CLS}}, x_1, \dots, x_T\,] \tag{7}$$

Encoder 与 History Compression

完整 encoder 的输出为

$$H = \mathrm{Enc}_\theta(X), \qquad H \in \mathbb{R}^{(T+1)\times d} \tag{8}$$

decoder 与 Ranking Module 消费的是每请求只算一次的共享 encoder memory $K$:完整 encoder 下 $K = H$,而 History Compression 不构造全深度的 $H$。

Figure 3.2. History Compression, read bottom-up. Dark: the long-term block O (no events); light: the recent block R (nr events).

注意力代价随历史长度二次增长,长历史在服务延迟预算下的可负担性是工业用户模型的老问题。SONA 因此不均匀地花深度:把至多 $N$ 个事件切成最近 $n_r$ 个的 recent block $R$ 与前面 $n_o = N - n_r$ 个的 long-term block $O$,分四步:(1) 交叉注意力——两个单层 cross-attention 块让两块互读,得到 $\tilde O$、$\tilde R$;(2) 全历史 pass——一层 self-attention 跑在 $[\tilde O; \tilde R]$ 上得到 $X_O$、$X_R$,这是唯一一处跨整段历史混合信息的阶段;(3) 深栈只跑 recent block——7 层 self-attention(承载绝大部分容量)只在 $n_r$ 个近期事件上精炼 $X_R$ 得 $H_R$;(4) 拼接读出:

$$K = \big[\, X_O \,;\, H_R \,\big] \tag{9}$$

于是全部 $N$ 个位置下游都可见,但只有近期 $n_r$ 个携带深度编码。完整 $L$ 层 encoder 的注意力代价是 $\Theta(L N^2 d)$,而这里只在 recent block 上付深度代价:

$$\Theta\big((L\,n_r^2 + N^2 + 2\,n_o n_r)\,d\big) \tag{10}$$

作者强调节省来自容量花在哪里,而非丢弃历史。取 $N = 8192$、$n_r = 2048$,约一半推理成本保住了完整 transformer 的大部分下游表现。所有 block 用 RMSNorm 前置归一化、SwiGLU FFN、RoPE。

Decoder

tokenizer 把每首曲目映射为 $L = 3$ 级 SID 元组 $s(v) = (s_1(v), \dots, s_L(v))$。decoder 是码本词表上的浅层自回归 transformer(2 层),从 BOS 出发逐级生成:

$$p_\theta(s_1, \dots, s_L \mid u) = \prod_{\ell=1}^{L} p_\theta\big(s_\ell \mid s_{<\ell}, K\big) \tag{11}$$

服务时用 tokenizer trie 约束的 beam search 屏蔽非法前缀,保证每个完成的元组至少映射到一首曲目。码本不是无碰撞的(一个典型元组被少量曲目共享,这是 Semantic ID 形式化的内禀性质),因此每个元组被展开成整个碰撞类交由 Ranking Module 排序。

Ranking Module

Figure 3.3. Unified generation-and-ranking architecture: the decoder and the Ranking Module attend to the same encoded user history.

Ranking Module 用 decoder 所 attend 的同一份 $K$ 给每个候选打分,不引入第二次 encoder 前向。候选由三类特征表示:item ID、独立看待的各级 SID 码 $c_1, \dots, c_L$、及其前缀 $n$-gram;按 Coleman 等人的 unified-embedding 方案,每个特征经若干独立哈希映射进与 encoder 共享的嵌入表,取出的行拼接后投影成稠密向量 $e_i$。打分沿用 decoder 架构的前置归一化 cross-attention 栈:

$$\tilde e_i = \mathrm{CrossAttnBlocks}(e_i, K) \tag{12}$$

$$s_i = \mathrm{Head}(\tilde e_i) \in \mathbb{R}^n \tag{13}$$

每个 head 对应 Teacher Ranker 的一个 head。服务时一个固定权重组合器把 $n$ 个 head 分数塌缩成标量,展开后的候选按它排序产出最终列表。

训练框架

数据集设计

数据集是请求级的:一条样本 = 一次被服务的推荐请求,携带请求前的时序历史与该请求的 impressions(带时间戳与后续反馈)。监督:tokenizer 把每个 impression 映射成 SID 元组,正样本构成 NTP 的打包目标集 $C^+(u)$(一次 encoder 前向、多个目标);完整 impression 列表是蒸馏的一个候选源,beam-search rollout 是另一个;不在 tokenizer 目录快照里的 impression 被 mask 出损失。时序组织:初始训练把请求切成日级表由旧到新消费,在线阶段按事件序消费请求流;两阶段都沿时间向前扫,每条样本只条件于其请求之前的事件。

联合目标与 Rollout Distillation

Figure 4.1. Joint training of the decoder (LNTP) and the Ranking Module (LDistillation, regression toward the frozen Teacher Ranker) on the shared encoder.

decoder 由 NTP 监督、只在每次请求的正 impression 上;encoder 每请求跑一次,每个正样本作为独立的 teacher-forcing 序列 cross-attend 共享表征。Ranking Module 由冻结 teacher 蒸馏监督:teacher 每候选暴露 $n$ 个互动分数,Ranking Module 用逐元素 MAE 回归。两个目标都回传进共享 encoder。

蒸馏对来自两个互补源:当前 decoder 的 rollout 与 logged impressions。beam search 用当前 decoder 生成 $B$ 个 SID 元组,能解析成目录 item 的构成 $\mathcal{B}$(解析失败的排除出损失),再用该请求的 logged impressions $\mathcal{I}$ 把监督拓宽到生产流量真实曝光过的 item。记 $r^h_c$、$\hat r^h_c$ 分别为 teacher 与 Ranking Module 对候选 $c$ 的第 $h$ 个 head 分数:

$$\mathcal{L}_{\text{rollout}} = \sum_{h=1}^{n} \frac{1}{|\mathcal{B}|}\sum_{c \in \mathcal{B}} \big| \hat r^h_c - r^h_c \big| \tag{14}$$

$$\mathcal{L}_{\text{impression}} = \sum_{h=1}^{n} \frac{1}{|\mathcal{I}|}\sum_{c \in \mathcal{I}} \big| \hat r^h_c - r^h_c \big| \tag{15}$$

$$\mathcal{L} = \mathcal{L}_{\text{NTP}} + \mathcal{L}_{\text{rollout}} + \mathcal{L}_{\text{impression}} \tag{16}$$

三项等权(1:1:1)。服务时的组合分数只用于重排 beam 候选,不进入任何训练损失。初始训练从随机初始化开始、按日级 chunk 时序消费(日间有序、日内打乱),走线性 warmup + decay;在线训练随后以恒定学习率消费到达的请求。FSDP 分片可训练参数,冻结 teacher 以 bfloat16 在每个 rank 上复制,不产生 all-gather 开销。

Teacher Ranker

Figure 5.1. Teacher Ranker architecture: a history encoder over the typed event sequence (left) and a candidate scorer that cross-attends to its hidden states (right).

Teacher Ranker 是一个无手工特征的大型 ranker,只作为 Ranking Module 的蒸馏教师;摆脱服务侧预算后它更大且 attend 完整历史,并在线上实验中胜过生产 ranker。结构是"深度用户历史 encoder + 候选打分器"。与服务侧那一对有两点差异:encoder 是因果的(每个位置携带该点的用户状态,解锁自回归训练与时间线打包监督);不用 History Compression,深栈每层都 attend 完整历史。若干互动 head 各是收窄到标量的 MLP:一个提供主排序信号,其余是辅助反馈 head,经学到的逐 head scale 与 bias 还原成校准 logit。

数据集是时间线级的:单元是一段用户事件时间线,携带与 Table 3.3 相同的属性;预训练样本只含时间线本身、每个事件都是一个 next-item 目标,微调样本额外携带沿时间线服务出去的 impressions 与分级反馈。自回归消费:因果 encoder 在每个位置提供该点用户状态,打分器通过自定义 mask 只读到各自锚点之前的历史,一次 encoder 前向即监督整条时间线的全部目标。正是这种打包决定了可负担窗口:teacher 吃整整一年的目标事件,联合训练只消费数周。

预训练沿用 Argus 的自回归配方:每个位置从因果用户状态预测下一个互动事件,损失为 InfoNCE(in-batch 负样本混合均匀采样的尾部负样本池 + LogQ 校正),保留 encoder、丢弃预测 head。微调热启动 encoder、随机初始化挂上打分器,主目标是 pairwise:impression 映射到分级互动尺度 like > play > skip > dislike,用 logistic 损失排序时序相邻、等级不同的 impression。设 $P$ 为 $i$ 等级更高的有序相邻对集合:

$$\mathcal{L}_{\text{pair}} = -\frac{1}{|P|}\sum_{(i,j)\in P} \log \sigma\big(\mathrm{score}_{\text{pair}}(i) - \mathrm{score}_{\text{pair}}(j)\big) \tag{17}$$

对可在同一请求内构成、也可跨相邻两请求的边界,且只有推荐请求里服务出去的 impression 有资格。辅助目标是 pointwise,每个剩余 head 用 BCE 拟合一个二元反馈目标:

$$\mathcal{L}_{\text{teacher}} = \mathcal{L}_{\text{pair}} + \sum_k \mathcal{L}^k_{\text{BCE}} \tag{18}$$

自定义 cross-attention mask 用专门的 Triton kernel 实现;微调把 attend 的历史拉长到预训练长度之外(2k → 8k)。持续刷新:微调后 teacher 滚动到当下并每日在新日志会话上刷新,目标对收窄到它所监督的推荐界面以专门化信号。

训练与推理基础设施

训练优化:联合训练生成与排序、并在生成候选上评估冻结 teacher,三份计算共置在同一组 GPU worker 上。数据路径保持在关键路径之外(异步输入流水线预取、预处理、算 item 哈希);bfloat16 + FSDP + FlashAttention + torch.compile;数值稳定性靠 QK normalization、梯度裁剪与精调过的 warmup/decay。

Figure 6.1. Online-training infrastructure for the final SONA configuration.

在线训练闭环:用户行为流进实时事件处理系统、按用户聚合成会话,与推理时上下文 join 后作为训练样本发出;GPU trainer 从消息队列消费并用 §4.2 的联合目标更新模型;模型每 10 分钟同步回服务,Teacher Ranker 每 24 小时刷新进 trainer。从事件发出到基于它训练的更新抵达服务,端到端中位 45 分钟、P99 60 分钟。几个工程要点:

  • 会话聚合与流量过滤:会话由几分钟空闲 gap 与 15 分钟最小归因窗口关闭,该窗口同时充当正确性缓冲让 inference log 追上触发它的事件;发出的会话再过反欺诈、历史长度门控与模型黑名单(丢弃探针/评估模型的流量,否则与训练数据形成反馈闭环)。多个模型可同时注册各自的会话定义,一遍事件上并行跑多路在线更新。
  • 用户画像双存储:批式重建的 KV 存储持长历史(尾部滞后),实时画像由事件流直写、持最近 72 小时且每用户上限 1000 条事件,读取时按时间戳合并去重——有界尾巴使流处理器不必持有完整 8192 事件历史。
  • 历史 join 经由推理服务:训练样本只有在"展示给模型的历史 = 推理时看到的历史"时才有意义。推理服务在服务那一刻按请求 ID 写一条带截断时间戳的 inference log,聚合器按 session 标识 join 并打戳;历史本身不经事件流传播——聚合后的会话回投给推理服务,由它用与服务相同的计算重建样本。

推理优化:生成与 item 级排序由同一个 GPU worker 执行并共享编码后的用户状态,推理期 MFU 达 41%。三条路径(初始训练/在线训练/推理)共用同一套特征存储处理;Triton 的异步 CPU batcher 把变长历史补成固定形状,从而能把完整模型路径捕获成 CUDA graph;beam 1024 × 每级 32,000 logit 使 top-k 成为实质解码成本,改用 FlashInfer 的 radix 选择器;大 beam 解码产生大量"KV 长度至多 3"的单 token query,与默认 FlashAttention tile 不匹配,故用专门调过 tile 的 decoder attention kernel。

模型卡(附录 B)要点:Teacher Ranker——因果 encoder 10 层 + 打分器 6 层、隐维 1024、16 头、最大位置 8193、总参数 0.6B(嵌入表主导)、预训练 2k / 微调 8k、NIP in-batch 负样本 $2^{13}$。Ranking Module——4 层 cross-attention、FFN 4096、输出 2 个 teacher head 分数、每 prompt 32 rollout、损失权重 1:1:1。Encoder——7 层 recent + 1 层全历史 + 每方向 1 bridge、隐维 1024、16 头、FFN 2816、8192 总历史 / 2048 近期(+1 CLS)、共享哈希桶嵌入表 $2^{19}\times256$。Decoder——2 层、SID 词表 3×32,000、3 个不共享的 $\mathrm{Linear}(1024\to32000)$ 头。优化——AdamW、weight decay 0.1、裁剪 1.0、$10^{-5}\to3\times10^{-4}\to7\times10^{-5}$(3000 warmup 步)、有效 batch size 16,384。

实验设置:评估协议与指标

论文评估四个问题(Table 7.1 给出问题→被测模型→证据的映射):tokenizer/容量/数据量如何影响候选生成(仅 NTP 的 encoder–decoder);预训练/历史长度/打分器深度如何影响 Teacher Ranker(报 WPA);哪些选择让统一模型同时保住检索与 teacher 排序;最终配置线上是否提升互动。三个离线指标(均越高越好):

目标曲目 Recall@k——设 $n_i$ 为请求 $i$ 的目标曲目数、$m_i(k)$ 为前 $k$ 个解析出的预测中命中的目标数,指标是 $\min\{m_i(k), k\}/\min\{n_i, k\}$ 在留出请求上的宏平均;容量扫描改报匹配曝光下的训练 NTP 损失(越低越好)。

Teacher Recall@k(条件于候选生成的排序保真度)——对留出请求 $r$,decoder 产出候选池 $C_r$,Ranking Module 与 teacher 排同一个池:

$$\mathrm{TeacherRecall@}k = \frac{1}{|R|}\sum_{r \in R} \frac{1}{k}\Big| \mathrm{Top}_k\big(s^{(r)}_{\mathrm{RM}}; C_r\big) \cap \mathrm{Top}_k\big(s^{(r)}_{\mathrm{teacher}}; C_r\big) \Big| \tag{19}$$

无 Ranking Module 时由 decoder 似然提供顺序。

Weighted pair accuracy (WPA)——在时序相邻、目标权重不同的留出 impression 对上衡量互动排序,$t_i$ 为预定义目标权重、$P$ 含 $t_i > t_j$ 的对:

$$\mathrm{WPA} = \frac{\sum_{(i,j)\in P}(t_i - t_j)\,\mathbb{1}\{\mathrm{score}_{\text{pair}}(i) > \mathrm{score}_{\text{pair}}(j)\}}{\sum_{(i,j)\in P}(t_i - t_j)} \tag{20}$$

权重差越大的对贡献越大。

主要实验结果

候选生成(§7.2)

这组实验用只有 NTP 的 encoder–decoder,无 Ranking Module 也无 teacher;CLMR(对比训练的音频 encoder)提供纯音频基线。

Table 7.2:语义 tokenizer 消融(每个子表只变一个组件,共用同一留出集)

(a) 码本大小(固定 CLMR 嵌入)

Codebook size Recall@1000
3 × 8,192 0.8036
3 × 32,000 0.8111

(b) item 表征(固定三层 32,000 码本)

Item representation Recall@10 Recall@100 Recall@1000
CLMR audio embedding 0.1848 0.4712 0.8111
CLMR + collaborative projection 0.2005 0.4873 0.8139
Qwen2.5-Omni + collaborative refinement 0.2171 0.5362 0.8524

分析:两条轴都指向"更大码本 + 更强的多模态 + 协同精炼",但收益分布很不均匀——从 CLMR 到 Qwen2.5-Omni + 精炼,Recall@1000 只涨 5.1%,Recall@10 却涨 17.5%:tokenizer 质量主要改善 beam 头部的精度而非召回上界。只加协同 InfoNCE 残差投影提升很小,说明换掉内容特征来源比在旧特征上做协同后处理更关键。

Figure 7.1. Train NTP loss of the Small, Medium, and 2× Medium configurations at matched cumulative packed-target exposure.

模型规模:固定层分配、数据窗口、目标与 8192 事件历史,Small / Medium / 2× Medium 的核心参数为 20M / 130M / 260M(含嵌入与输出头则为 264M / 485M / 659M)。在 0.5–2.25 billion 累计打包目标的曝光区间内,增大容量一致地降低训练 NTP 损失,三条曲线未交汇。

Table 7.3:固定 Medium 骨干与 2k 历史,训练数据窗口变化时的训练损失与召回(每次运行在自己的窗口上做一遍时序单 pass)

Training window Train loss Recall@10 Recall@100 Recall@1000
1 week 2.2735 0.1798 0.4979 0.8333
2 weeks 2.1061 0.2126 0.5576 0.8640
4 weeks 2.0800 0.2388 0.5993 0.8849
8 weeks 2.0427 0.2519 0.6178 0.8947

分析:点估计随窗口增大单调改善,含 4 周到 8 周这一段。与分离的容量曲线合起来,作者称"测量范围内没有平台期",也解释了 §8 为何把 MoE、稀疏/线性注意力、跨请求持久 KV cache 列为下一步。需注意每个窗口只跑一遍,"数据量"与"优化步数"混在一起、贡献无法拆开。

Teacher Ranker 设计消融(§7.3)

Table 7.4:预训练消融(固定 8k 事件历史与六层候选打分器,第一行只移除 next-item-prediction 预训练阶段)

Configuration Weighted pair accuracy
Teacher, no pre-training 0.6153
Teacher, two-stage initial recipe (selected) 0.6215

Table 7.5:打分器深度与 attend 历史长度变化时的 teacher WPA 点估计(同一留出互动标签集)

History Scorer depth Weighted pair accuracy
2k 1 0.6080
2k 2 0.6105
2k 4 0.6124
2k 6 0.6134
2k 8 0.6138
8k 1 0.6159
8k 2 0.6189
8k 4 0.6207
8k 6(selected) 0.6215
8k 8 0.6219

分析:历史长度的边际收益系统性大于打分器深度——深度 1 上从 2k 换到 8k 带来 +0.0079,而 2k 上把深度从 1 加到 8 只带来 +0.0058;深度 6 层后基本饱和(6→8 仅 +0.0004),是明确的性价比拐点。预训练那 +0.0062 看着不大,但对照全表动态范围(跨度仅 0.0139)就知道:单独一个 NIP 预训练阶段贡献了整张消融表跨度的 45%——这正是作者称之为 load-bearing stage 的依据,也是无手工特征 transformer 得以替代生产 ranker 的关键。

统一生成与排序(§7.4)

固定 teacher 后,这组离线实验评估 NTP + 蒸馏联合训练的 encoder、decoder 与 Ranking Module(teacher 只提供蒸馏目标与参考分)。所有变体用 §3 的组件与 2 周训练窗口,评估 beam 固定 $B_{\text{eval}} = 1024$。

Table 7.6:围绕共享参考配置的单因子消融(参考:MAE、rollout + impressions、训练 rollout beam 32、2k 事件历史、$E=7, D=2, R=1$;† 标记的三行是同一次参考运行)

Configuration Target-track Recall@1000 Teacher Recall@10 Teacher Recall@100 WPA
Distillation loss
MAE† 0.8615 0.5654 0.7344 0.5892
MSE 0.8671 0.5748 0.7329 0.5915
Huber 0.8679 0.5568 0.7220 0.5894
KL 0.8662 0.5452 0.7151 0.5860
Distillation candidate source
Rollouts + impressions† 0.8615 0.5654 0.7344 0.5892
Rollouts only 0.8610 0.5618 0.7288 0.5730
Impressions only 0.8663 0.2983 0.5281 0.5872
Training rollout beam size
32† 0.8615 0.5654 0.7344 0.5892
64 0.8565 0.5661 0.7359 0.5901
128 0.8616 0.5762 0.7427 0.5905

分析:(a) 损失函数无一在三方面同时占优,故保留 MAE——实质是说"蒸馏损失的具体形式不重要"。(b) 候选来源是全表最有信息量的一组:impressions-only 检索点估计最高但 Teacher Recall@10 只有 0.2983、不到含 rollout 配置的一半;rollout-only 保住保真度却 WPA 最低(0.5730);混合方案在两个单来源各自擅长的指标上都不劣。机制清楚:logged impressions 从不包含 decoder 会生成但生产从未曝光的候选,student 因此在自己服务时的候选分布上没见过世面;纯 on-policy 候选又缺真实曝光锚定。换候选来源的影响比换损失函数大一个数量级。(c) 训练 beam 32→128 给出最高保真度点估计,但要打分的 rollout 候选数翻两番,故保留 32。

Table 7.7:Ranking Module 深度,随后是历史长度与历史编码的消融(E/D/R 分别为 encoder/decoder/Ranking Module 层数;R = – 表示无 Ranking Module、由 decoder 似然排序)

History encoding History length E D R Target-track Recall@1000 Teacher Recall@10 Teacher Recall@100 WPA
Full attention 2k 7 2 – 0.8656 0.0381 0.1936 0.5478
Full attention 2k 7 2 1 0.8615 0.5654 0.7344 0.5892
Full attention 2k 7 2 4 0.8656 0.6005 0.7501 0.5937
Full attention 8k 7 2 4 0.8722 0.6586 0.7997 0.6029
History Compression 8k 7 2 4 0.8709 0.6474 0.7893 0.6033

分析:第一行是机制基准——没有 Ranking Module 时 decoder 似然与 teacher 的 top-10 几乎不相交(0.0381),而检索本身(0.8656)却是全表最好之一,这把"生成"与"排序"彻底解耦:beam 似然是好的提议器、却是几乎无效的 item 级排序器。加一层打分器把 Teacher Recall@10 拉到 0.5654(一个数量级以上),4 层到 0.6005,历史扩到 8k 到 0.6586。最后一行是最关键的工程取舍:History Compression 的 Teacher Recall 比全注意力 8k 低 1.7%、Target-track Recall 几乎持平,WPA 反而最高(0.6033),而推理成本约为一半。WPA 反超值得玩味:深度容量集中在近期事件上,可能更贴合 WPA 评估的"时序相邻 impression 对"这一近端目标。

线上 A/B 实验(§7.5)

五组受控 A/B 在 My Vibe 智能音箱流量上评估服务配置;除标 † 外所有 delta 在 $p < 0.01$ 下显著。Active Users 是主指标,每项都是相对同实验生产对照臂的百分比变化。

Table 7.8:实验 1——teacher 排序分中 likes-score 权重的影响(NTP-only encoder–decoder 生成候选、teacher 排序;每组 5% 用户;teacher attend 8k、enc–dec attend 2k)

Metric Pairwise only (0) + α Likes score + 2α Likes score
Total Listening Time +2.05% +2.45% +2.28%
Likes −1.03%† +6.56% +11.93%
"Repeat" Commands +7.43% +12.89% +12.57%
Active Users +1.51% +1.83% +1.53%
Deeply Engaged Users +2.61% +2.87% +2.80%

分析:纯 pairwise 的 Likes 是 −1.03%(不显著),加入 likes 分后 Likes 单调上升,但 Active Users 在 $\alpha$ 处达峰(+1.83%)后回落到 +1.53%——典型的多目标权衡曲线,过度加权点赞会挤压总体活跃度,故保留非零但适中的 likes 分。

Table 7.9:实验 2——Teacher Ranker 的 SID 候选特征(唯一差异是 teacher 候选特征是否含 SID;各组 4% 用户)

Metric Teacher without SID features Teacher with SID features
Total Listening Time +2.60% +3.18%
Likes +11.13% +19.86%
"Repeat" Commands +15.88% +20.52%
Active Users +1.98% +2.23%
Deeply Engaged Users +2.95% +3.80%

分析:干净的单变量线上消融——加 SID 特征后五个指标全面上行,Likes 从 +11.13% 提到 +19.86%。机制上 SID 让候选侧获得"共享前缀 = 语义/协同相近"的泛化能力,尤其惠及曝光稀疏的曲目;这也解释了 Ranking Module 为何同样保留各级 SID 码与前缀 $n$-gram。

Table 7.10:实验 3——teacher 搭配两条候选生成路径(都只用 pairwise 分以匹配打分目标;每组 3% 用户)

Metric Teacher Ranker Enc–dec + Teacher Ranker
Total Listening Time +1.64% +3.63%
Likes +1.48%† −0.54%†
"Repeat" Commands +4.68%† +5.02%†
Active Users +1.22% +2.72%
Deeply Engaged Users +1.83% +4.06%

分析:左列只替换生产 ranker就拿到 Active Users +1.22%,是"免特征 transformer 可取代吃数百特征的生产 ranker"的直接线上证据。右列连候选生成也换掉后 Active Users 翻倍到 +2.72%——即替换候选生成的增量比替换 ranker 更大。Likes 在两列都不显著(右列为负),提示纯 pairwise 目标不覆盖显式点赞,正与实验 1 互补。

Table 7.11:实验 4——蒸馏后的单模型,单独使用与再叠加 teacher 重排(都用 §4.2 联合目标训练、2k 历史、含 likes 分;各组 8% 用户)

Metric Distilled model Distilled + Teacher Ranker
Total Listening Time +1.62% +4.32%
Likes +7.12% +11.81%
"Repeat" Commands +15.25% +14.93%
Active Users +1.41% +2.81%
Deeply Engaged Users +2.78% +5.11%

分析:左列即 Gryphon-v2 论文报告的那次 A/B(数值逐项一致),证明"不服务 teacher 也能替掉生产级联"。右列同时暴露了蒸馏的代价上限:把 8k 上下文的 teacher 挂回服务路径,Active Users 从 +1.41% 翻到 +2.81%——蒸馏只收回约一半 teacher 增益。作者的应对不是把 teacher 上线(成本不允许),而是把 student 自己的上下文从 2k 扩到 8k,这正是实验 5 的主变更。

Table 7.12:实验 5——SONA 单模型替换整条推荐栈(两臂各 15% 随机用户、7 天,保留限制生产输出的硬业务规则)

Metric Relative change vs control
Total Listening Time +6.30%
Likes +11.42%
"Repeat" Commands +17.99%
Active Users +4.53%
Deeply Engaged Users +7.37%

分析:五个指标全面显著提升,主指标 Active Users +4.53%,是此前该界面最强模型 Argus 增量(+1.93%)的 2.35 倍。与实验 4 的关键差异是可用上下文(2k → History Compression 下的 8192 事件);但作者主动声明两次实验分开进行、其差值不能隔离历史长度的因果贡献——中间还夹着 tokenizer 更换、Ranking Module 从 1 层到 4 层等多处变化。

核心贡献总结

  1. 一次罕见的整链路替换 A/B,且是正向大幅提升:单模型替掉 15+ 候选生成器 + 粗排 + 精排,Active Users +4.53%、TLT +6.30%、Likes +11.42%,且是叠加在历代部署保留收益之上的增量。
  2. 把"训练期专用大教师"这个角色定型:teacher 不是奖励模型(无需 RL)、不是线上 ranker(无需服务),而是纯粹的偏好函数供给方;其 featureless 设计是隐藏枢纽——正因只依赖历史即可给任意 user–item 对打分,那些从未曝光、无日志特征的 rollout 候选才可能被监督。
  3. "一年历史压进 teacher、稠密蒸馏进 student"绕开了数据经济学约束:时间线级打包让 teacher 一次前向监督整条时间线的所有目标,而请求级 NTP 数据集连数月都覆盖不了。
  4. History Compression 是"长历史 vs 延迟"的实用解:深度只花在近期 2048 事件、一层跨全 8192 事件混合,约一半推理成本拿到与全注意力 8k 相当的指标。
  5. 完整披露了在线训练闭环(45 分钟中位延迟、10 分钟权重同步、双存储画像、经推理服务重建历史消除训练-服务偏移、模型黑名单切断反馈闭环),这类细节在同类报告里罕见。

与已归档相关工作的对比

OneRec OneRec Technical Report(快手,2025-06-16)

关系:显式引用([18],仅在"single-model generative recommenders carried this recipe into production"处一笔带过,无方法/指标层对比)· 已加载对方精读

  • 共同关注的问题:root cause 一致——多阶段级联把优化目标与算力都碎片化。OneRec 量化了同一件事:serving 阶段 >50% 资源用于通信与存储,排序模型训练/推理 MFU 仅 4.6% / 11.2%;SONA 把推理 MFU 做到了 41%。
  • 相近的技术骨架:几乎逐组件对应——多模态 LLM 抽内容特征(miniCPM-V-8B / Qwen2.5-Omni)→ 协同对齐 → RQ-Kmeans 三层量化 → encoder-decoder + SID 自回归生成 → 用一个额外信号源把服务级偏好注入生成模型。
  • 本文的差异与推进:最后一跳是分水岭。OneRec 走 RL 后训练(P-Score 奖励模型 + ECPO + format reward);SONA 走监督蒸馏(teacher 给连续分数、逐 head MAE 回归,没有梯度穿过 beam search),§8 明确表态"只在受控对比证明贡献后才采用某训练阶段,而 RL 我们还没建立这个证据"。SONA 还保留显式的 item 级 Ranking Module,因而能区分 SID 碰撞类内部的 item。
  • 可比的方法/实验差异:OneRec 报 App Stay Time +0.54%/+1.24%、OPEX 降至级联的 10.6%;SONA 报 Active Users +4.53%、延迟持平。历史处理也分道扬镳:OneRec 用四条通路(终身路径先层次 K-means 压缩再 QFormer),SONA 用单一时序序列 + History Compression。

UniPinRec UniPinRec: Unifying Generative Retrieval and Ranking at Pinterest Scale(Pinterest,2026-05-29)

关系:显式引用([13],在"一份用户表征跨任务共享"的设计哲学处与 [14] 并列一句带过,无方法/指标层对比)· 已加载对方精读

  • 共同关注的问题:问题陈述可以互换——检索与排序都在用大 transformer 编码同一段用户历史,重复编码是低效的首要来源;统一后用户只编码一次、表征共享、信号互相正则化。UniPinRec 称之为"全栈统一",SONA 称之为"一份用户表征跨任务共享"。
  • 相近的技术骨架:核心机制惊人一致——"历史编码一次($O(n^2)$),给 $k$ 个候选打分只付 $O(nk)$"。UniPinRec 靠跨进程 KV-cache 共享(预分配 GPU 显存池 + CUDA IPC handle);SONA 靠同一 GPU worker 内共享 encoder memory $K$。两者都强调统一模型必须比分开部署更便宜才值得切换。
  • 本文的差异与推进:(a) UniPinRec 保留 ANN(Faiss),SONA 用 SID 约束 beam search,因此 SONA 能替掉整个漏斗而 UniPinRec 明确选择不替(理由是会丧失与既有候选源的可组合性与逐阶段运维控制)。(b) UniPinRec 用 Masked Action Modeling 拟合真实动作标签,SONA 只回归 teacher 分数:前者上限是日志标签能表达的偏好,后者上限被 teacher 锁死但能吸收整年数据。(c) UniPinRec 是 drop-in 增量替换,SONA 是一次性整栈替换。
  • 可比的方法/实验差异:UniPinRec 报排序 Hit@3 相对生产 ranker +14.8%、线上 saves +0.95% / push opens +0.91%、延迟 −11.1%、QPS +63.6%;SONA 报 Active Users +4.53%、延迟持平、MFU 41%。UniPinRec 线上增益更小,但它自陈原因是离线提升被未改动的下游 ranker/blender 衰减——这恰好从反面支持 SONA"必须整栈替换才能拿到全部增益"的选择。

UniSGR UniSGR: Unified Framework for Semantic ID Generation and Ranking(阿里 AIDC / Lazada,2026-07-05)

关系:独立并发(本文未引用 UniSGR,两者殊途同归)· 已加载对方精读

  • 共同关注的问题:同一 root cause——生成式检索能选出语义相关候选,却缺少工业排序所需的细粒度多目标判别力;在生成器后简单外挂判别式 ranker 又会重新引入"生成器优化候选可信度、ranker 在被截断候选集上优化最终收益"的目标错位。
  • 相近的技术骨架:都是在同一个 SID encoder-decoder 内挂多目标排序模块,复用生成侧表示,服务时不再调用独立的 item-ID 排序模型;都用多模态 LLM(Qwen3-VL / Qwen2.5-Omni)抽 item 表征后协同对齐、再残差量化成三层 SID。
  • 本文的差异与推进:监督来源仍是分水岭——UniSGR 用真实 click/atc/pay 标签的 BCE 并用 VA-PMTP 把业务价值回灌进生成目标,SONA 只回归 teacher 分数。SONA 独有的推进是候选分布:显式混合 on-policy rollout 与 logged impressions,并量化了只用 impressions 的代价(0.2983 vs 0.5654);UniSGR 独有的则是把业务价值回灌进生成(SONA 生成侧只有朴素 NTP)与多场景预训练 + 场景对齐的两阶段范式。
  • 可比的方法/实验差异:UniSGR 额外攻解码效率(STARK 树注意力,QPS 119→219、延迟 30.9→14.1ms),线上 Lazada 首页 GMV +5.68%;SONA 不优化解码本身,而是靠蒸馏把 teacher 的推理 pass 整个从服务路径删掉。两者是这条路线上标签驱动派与教师蒸馏派的对照。

被剔除的近似候选:GBLA(2606.07317,同为 Yandex,问题是长历史注意力成本、与 History Compression 动机重合,但解法是替换注意力算子而非统一系统);UniGD(2608.03150,快手搜广,同样在一个 backbone 内统一 SID 生成与判别式打分,但核心是用 CAGE 解两目标梯度冲突、场景带 query,无教师蒸馏与级联替换);UniFormer(2606.27058,统一的是"特征空间 × 任务空间"的协同 scaling,不涉及生成式候选替换级联)。

讨论与局限性

值得借鉴的设计。 (1) "把容量花在哪里"这个视角贯穿全文:History Compression 不丢历史而是不均匀分配深度,teacher 不上线而是把一年历史压进权重,Ranking Module 不重编码历史而是 cross-attend 已有 memory。(2) 候选分布对齐比损失函数选择重要一个数量级。(3) Table 7.7 第一行干净地钉死了"beam 似然是好提议器、坏排序器";(4) teacher 侧"长历史 > 深打分器"的对比为容量分配提供了可迁移先验。

局限与争议。

  • 实验 5 与实验 4 的差值不可归因:中间同时变了历史长度、Ranking Module 深度、tokenizer 表征等多项,唯一线上证据是整体 treatment,全文最亮眼的数字拆不到组件。
  • 离线主指标 Teacher Recall 存在循环性:它衡量 student 复现提供蒸馏目标的同一个 teacher 的程度,从 0.0381 提到 0.6586 在定义上就是"蒸馏成功"的同义反复;WPA 则在现有级联曝光策略下的 impression 上评估,不衡量 SONA 自己会浮现的那批 item。
  • student 上限被 teacher 锁死:实验 4 已量化 gap(+1.41% vs +2.81%,蒸馏只收回约一半 teacher 增益);SONA 的应对是给 student 加上下文而非改蒸馏机制,这个 gap 是否随 student 变强而收敛并无证据。
  • 所有消融都是点估计,无显著性检验、无多种子:Table 7.5 里 6 层与 8 层差 0.0004、Table 7.6 里 beam 64 与 32 差 0.0007,而 Gryphon-v2 曾提到 R@1000 运行间标准差约 0.003。
  • 未全量部署,且目录覆盖率已知下降:作者明写覆盖率低于生产栈且待调查——对"把 15+ 异构召回器压成单一 beam"的系统这恰是最该担心的方向(异构召回器的隐含功能之一就是保证多样性与探索)。他们同时又称"未注意到内容探索退化",两句话存在张力。
  • 只验证了一个界面:My Vibe 是纯推荐、无 query、被动消费——恰是对生成式单模型最友好的设置;带搜索与编辑运营上下文的界面能否复现留待未来。
  • 方法论可扩展性隐忧仍在:SID 码本(3×32,000)在联合训练前固化,扩参时"如何表征历史"与"如何建模序列"两条路径都受这个离散接口约束;beam 仍是召回上界;训练 rollout beam(32)与服务 beam(1024)有 32 倍分布缺口。tokenizer 三层组件都冻结/离线拟合,无法与下游联合优化。
  • 新颖性主要在配方而非机制:多模态 tokenizer、统一 generate-and-rank、大教师蒸馏、on-policy 蒸馏都已有先例,SONA 的贡献是把它们组装成一条真能替掉级联并显著赢的流水线。

定位。 在 2026 年"用一个模型替掉推荐级联"的密集竞赛里,SONA 是证据链最完整的一份——五组按概念顺序排列的线上 A/B(teacher 能替 ranker → enc-dec 能替候选生成 → 蒸馏能去掉 teacher → 长上下文再翻一倍)。这种"逐级替换 + 逐级验证"的叙事对工业团队比单点方法创新更有参考价值,代价是它整体上是配方级而非机制级的贡献。