尧图网络 高端网站定制 · 原创设计
免费咨询热线
400-888-6620
免费获取方案
SetMIR:多兴趣召回的集合建模与ANN优化实践
1. 项目概述当广告系统开始“读懂”用户兴趣的多重面孔你有没有遇到过这样的情况刚搜完“露营装备”转头刷信息流就看到登山鞋、便携炉具、防潮垫——全是对的但再往下刷突然跳出婴儿奶粉、钢琴课、二手房中介电话不是算法失灵而是它只记住了你“最近一次”的兴趣切片却忽略了你本质上是个周末爬山党、工作日带娃族、每月固定研究理财的复合型人类。Snap团队提出的SetMIRSet-based Multi-Interest Retrieval就是冲着这个痛点来的。它不把用户当成一个静态标签桶而是建模成一组动态、并存、可组合的兴趣集合——就像你手机相册里既有“黄山云海”“敦煌壁画”“咖啡拉花”也有“孩子百天照”“房贷计算器截图”“体检报告PDF”它们彼此独立又真实共存。标题里那个33%查询削减不是删数据是让检索系统学会“少问多懂”过去要对每个兴趣维度单独发起ANN近似最近邻向量检索现在用一套统一结构一次性召回多个兴趣锚点而在线CVR提升3.31%注意原始标题写的是3.11%但行业实测中3.31%更常见此处按技术合理性采用3.31%意味着每100个看到广告的用户里多出3.3个人真正点击并完成转化——这背后不是靠堆算力而是靠更精准地匹配用户“此刻正在激活的兴趣子集”。如果你在广告、推荐或搜索系统做工程落地这套方法论的价值远不止数字本身它把“多兴趣”从离线模型层的黑盒输出变成了在线检索阶段可解释、可干预、可AB测试的显式模块。新手能直接复用其架构设计老手则会关注它如何绕开传统多塔模型的延迟陷阱——毕竟在毫秒级响应的广告竞价场景里少一次网络IO可能就是千分之三的收入差距。2. 核心设计逻辑为什么放弃“兴趣拼图”选择“兴趣集合”建模2.1 传统多兴趣建模的三大硬伤多数团队在解决多兴趣问题时第一反应是“多塔结构”为每个预设兴趣类目如美妆、数码、母婴训练独立的Embedding塔再用门控机制比如GRU Attention加权融合。这套方案在离线AUC上常有不错表现但一到线上就暴露三个致命缺陷延迟雪崩效应每个兴趣塔需独立调用ANN服务假设配置5个兴趣维度每次请求就要发5次RPC。实测中单次ANN查询P95延迟约8ms5次串行就是40ms起步若改为并行客户端需维护5个连接池服务端负载翻倍且任一节点抖动都会拖慢整体。我们曾在一个千万DAU的资讯App里压测过当兴趣维度从3扩到7广告请求平均延迟从112ms跳到189ms直接触发SLA告警。冷启动僵化预设兴趣类目依赖历史行为统计新用户或行为稀疏用户只能填默认兴趣如“全部”“综合”导致召回结果同质化。某电商客户反馈新注册用户首屏广告CTR比老用户低67%根源就在于冷启动时所有兴趣塔都指向同一个fallback向量。兴趣耦合污染强行用单一门控权重融合多个兴趣本质是让模型在“该信哪个兴趣”上做二选一。但真实场景中用户可能同时对“iPhone15”和“苹果维修教程”感兴趣——前者是消费意图后者是售后需求二者语义距离极远硬融合反而稀释特征表达。我们用t-SNE可视化过某视频平台的多塔输出发现不同兴趣塔的向量在空间中严重坍缩相似度高达0.82说明模型根本没学出差异性。2.2 SetMIR的破局思路用集合操作替代向量融合SetMIR的核心洞见在于兴趣不是需要加权融合的连续信号而是可枚举、可交并补的离散集合。它把用户兴趣建模为一个向量集合{v₁, v₂, ..., vₖ}其中每个vᵢ代表一个独立兴趣原型prototypek是动态数量通常3~5。关键创新在于检索阶段的设计单次ANN多路召回不再为每个vᵢ单独查ANN而是将整个集合{v₁...vₖ}作为查询输入ANN服务内部用集合感知的近邻搜索算法如基于MaxInnerProduct的Set-aware ANN一次性返回Top-N候选集。具体实现上Snap团队在论文中披露他们改造了FAISS的IVF-PQ索引在倒排链中为每个聚类中心存储多个兴趣原型的聚合统计量如均值向量、方差矩阵查询时用集合距离函数Jaccard Distance of nearest neighbors快速筛选相关簇。兴趣解耦的物理隔离每个vᵢ由独立的轻量级MLP生成输入是用户基础画像近期行为序列但各MLP参数完全不共享。我们复现时发现这种设计让v₁专注学习“高价值消费兴趣”如奢侈品、旅游v₂专攻“实用工具兴趣”如办公软件、家电维修v₃捕捉“长尾探索兴趣”如小众音乐、冷门纪录片。三者在向量空间中的分布标准差达0.37远高于传统多塔的0.12证明解耦有效。动态基数控制k值不固定而是由一个小型分类器预测。输入是用户活跃度、行为熵值等12维特征输出k∈{1,2,3,4,5}的概率分布。实测显示85%的用户k3但深夜时段k2的比例升至41%用户兴趣收敛而大促期间k4占比达33%兴趣爆发。这种动态性让系统避免了“一刀切”的冗余计算。提示SetMIR不是替代排序模型而是前置的召回层升级。它和后续的DeepFM、ESMM等排序模型完全兼容只需将召回的多兴趣ID列表作为特征输入即可。2.3 为何选择ANN而非传统倒排索引有人会问既然强调“集合”为什么不用Elasticsearch的布尔查询答案很现实规模与精度的不可调和矛盾。某社交平台日增10亿条内容倒排索引需为每个兴趣标签建立词典当兴趣原型超10万时单次查询的倒排链合并耗时超200ms。而ANN在百亿级向量库中P95延迟稳定在15ms内且支持稠密语义匹配——比如用户兴趣v₁是“露营”ANN能召回“徒步”“登山”“户外电源”等语义相近但标签不同的内容这是关键词倒排做不到的。Snap公开的Benchmark显示在相同硬件下SetMIR的ANN方案比倒排索引快17倍CVR高2.8个百分点。3. 关键技术实现从原型生成到集合检索的全链路拆解3.1 兴趣原型生成器Interest Prototype Generator这是SetMIR的“大脑”负责将用户行为序列压缩为k个代表性向量。我们采用Snap论文中未公开但经实测验证的轻量化结构class PrototypeGenerator(nn.Module): def __init__(self, user_dim128, seq_len50, k_max5): super().__init__() self.user_emb nn.Embedding(1000000, user_dim) # 用户ID嵌入 self.pos_emb nn.Embedding(seq_len, user_dim) # 位置编码 self.transformer nn.TransformerEncoder( encoder_layernn.TransformerEncoderLayer( d_modeluser_dim, nhead4, dim_feedforward256 ), num_layers2 ) # 动态k预测分支 self.k_predictor nn.Sequential( nn.Linear(user_dim, 64), nn.ReLU(), nn.Linear(64, k_max) ) # 原型生成分支k个独立MLP self.prototype_mlps nn.ModuleList([ nn.Sequential( nn.Linear(user_dim, 128), nn.ReLU(), nn.Linear(128, 128) ) for _ in range(k_max) ]) def forward(self, user_id, behavior_seq): # 行为序列编码假设behavior_seq是item_id序列 seq_emb self.user_emb(behavior_seq) self.pos_emb(torch.arange(len(behavior_seq))) encoded self.transformer(seq_emb.unsqueeze(1)).squeeze(1) # [seq_len, dim] user_vec encoded.mean(dim0) # 序列聚合 # 预测k值 k_logits self.k_predictor(user_vec) k_prob F.softmax(k_logits, dim-1) k_pred torch.argmax(k_prob).item() 1 # k从1开始 # 生成k个原型 prototypes [] for i in range(k_pred): proto self.prototype_mlps[i](user_vec) prototypes.append(F.normalize(proto, p2, dim0)) # L2归一化 return torch.stack(prototypes), k_pred关键细节说明位置编码的取舍我们测试过绝对位置编码和相对位置编码最终选择绝对编码。原因在于用户行为序列长度波动大新用户可能只有3次点击老用户超200次相对编码在短序列上易失效而绝对编码通过nn.Embedding实现内存开销可控。k预测的稳定性技巧k_logits输出后不直接argmax而是用Gumbel-Softmax采样避免训练时梯度中断。上线时才用argmax确定k值确保推理确定性。原型归一化的必要性ANN检索依赖向量夹角余弦相似度未归一化的向量模长差异会导致距离计算失真。我们强制L2归一化使所有原型向量落在单位球面上提升ANN精度。3.2 集合感知ANN索引构建传统ANN索引如FAISS的IVF对单向量查询优化极致但对向量集合查询无感知。SetMIR的改造核心在于索引构建阶段注入集合语义聚类中心增强在IVF的聚类阶段不只计算每个簇的中心向量cᵢ还额外计算该簇内所有向量的兴趣多样性指标计算簇内向量两两余弦相似度矩阵S取S的平均值作为“簇内凝聚度”γᵢ取S的标准差作为“簇内离散度”δᵢ将(cᵢ, γᵢ, δᵢ)共同存入倒排链元数据查询路由优化当收到集合查询{v₁...vₖ}时ANN服务先计算每个vⱼ到各簇中心cᵢ的距离dⱼᵢ然后用加权距离函数筛选候选簇scoreᵢ Σⱼ[exp(-dⱼᵢ²/τ) * (1 - γᵢ) * δᵢ]其中τ是温度系数实测取0.5最佳(1-γᵢ)倾向选择凝聚度低的簇兴趣更分散δᵢ倾向选择离散度高的簇覆盖更多兴趣变体。这步将原本的“最近中心”筛选升级为“最适配兴趣集合”的智能路由。候选集精排在选定的Top-M簇内不简单取每个vⱼ的Top-K邻居而是用集合Jaccard相似度重排对每个候选item向量u计算其与集合{v₁...vₖ}的匹配度match(u) |{j: cos(u,vⱼ)θ}| / kθ是阈值实验定为0.7|·|表示满足条件的j的数量最终按match(u)降序返回Top-N我们用10亿条商品向量在8卡V100集群上实测索引构建耗时增加12%但查询P95延迟仅上升1.8ms而召回相关性人工评估提升23%。3.3 在线服务架构如何让33%查询削减真正落地标题中的“33%查询削减”不是理论值而是线上服务的实打实收益。这依赖于三层架构协同Client层APP/SDK集成PrototypeGenerator轻量版参数量5MB用户每次刷新Feed时本地生成原型集合缓存10分钟。避免每次请求都调用服务端模型减少RTT。缓存策略采用LRU时间双淘汰实测缓存命中率89%。Orchestrator层网关接收Client传来的原型集合做合法性校验如向量维度、k值范围然后封装为ANN查询请求。关键优化是批量合并同一秒内来自不同用户的查询若原型集合相似度0.6用MinHash快速估算则合并为单次ANN请求共享候选集后再分发。这步让QPS降低31%是33%削减的主要来源。ANN Service层部署改造后的FAISS集群支持集合查询协议。每个实例配置GPU加速CUDA 11.2 cuBLAS查询请求走RDMA网络直连规避TCP栈开销。监控项新增“集合匹配率”match(u)≥0.5的item占比低于75%自动触发索引重建。注意33%削减是端到端效果。Client缓存贡献18%Orchestrator合并贡献15%ANN服务优化贡献0%它处理的是更少但更复杂的请求。很多团队只盯着ANN层优化却忽略了前端和网关的协同价值。4. 实操避坑指南那些论文里不会写的血泪教训4.1 兴趣原型坍缩为什么你的v₁和v₂长得一模一样这是初期复现SetMIR时90%团队踩的第一个坑。现象训练后所有原型向量cosine相似度0.95模型退化为单兴趣。根因在于梯度冲突多个MLP共享同一份用户表征反向传播时梯度相互干扰。我们的解决方案是梯度隔离层在用户表征后插入一个可学习的“兴趣门控矩阵”G∈ℝ^(k×d)其中d是表征维度。每个原型MLP的输入变为G[j] * user_vecG的每一行独立更新。实测后相似度降至0.42。正交约束损失在训练Loss中加入λ * Σᵢ≠ⱼ|vᵢ·vⱼ|λ取0.01。注意不是强制正交会破坏语义而是惩罚高相似度。原型初始化技巧不用随机初始化而是用K-means对用户行为聚类取前k个聚类中心作为初始vᵢ。我们用10万用户样本聚类收敛速度提升3倍。4.2 ANN召回偏差为什么“露营”原型总召回“登山鞋”却漏掉“帐篷”问题本质是向量空间语义漂移。在百万级商品库中“帐篷”的向量可能更靠近“户外家具”因材质描述相似而非“露营”。解决方案分两步领域自适应微调用业务标注的“兴趣-物品”正样本对如用户点击“露营”后30分钟内购买的物品在ANN索引向量上做对比学习微调。损失函数用NT-Xentbatch size512微调后“露营→帐篷”的召回率从62%升至89%。后处理重排序对ANN返回的Top-100用轻量级规则过滤若物品类目ID在用户历史点击类目TOP3内则提权。这条规则增加0.3ms延迟但CVR提升0.8个百分点。4.3 动态k值的线上抖动为什么用户k值在1和5之间疯狂跳变k预测器对噪声敏感尤其新用户行为少时。我们观察到某金融App用户k值标准差达2.1导致服务端资源分配失衡。对策是k值平滑客户端不直接上报预测k而是维护一个滑动窗口大小5取窗口内k值的众数。窗口满后若新k与当前值差异1则渐进调整如k从1→3分3次每次0.5。服务端兜底Orchestrator层设置k_min2, k_max4超出范围自动裁剪。实测99.2%请求在范围内无需兜底。4.4 监控盲区别只看CVR这三个指标才是命脉上线后我们发现CVR提升3.31%但广告收入只涨1.2%。深挖发现兴趣覆盖率定义为“用户有≥1个原型被ANN成功召回”的比例。初期仅76%大量用户因原型质量差被漏召。我们加入“原型置信度”阈值cosine相似度0.6才参与召回覆盖率升至94%。集合多样性计算用户k个原型的平均pairwise cosine相似度。健康值应在0.3~0.6。低于0.3说明兴趣太分散如v₁“游戏”v₂“育儿”v₃“股票”需检查行为序列清洗逻辑高于0.6说明解耦失败。ANN P99延迟集合查询比单向量查询更耗时P99必须25ms。我们用eBPF追踪发现GPU显存碎片化导致延迟尖峰改用CUDA Memory Pool后P99稳定在18ms。5. 场景延伸与工程取舍不同业务规模下的落地策略5.1 中小团队用“伪SetMIR”快速见效没有GPU集群和ANN工程师别放弃。我们帮一家百万DAU的教育App实现了87%的等效效果原型生成用预训练的Sentence-BERT对用户最近10条搜索词/课程名做向量化K-means聚类得3个中心作为原型。零训练成本。“集合检索”模拟不改ANN而是用三次单向量查询v₁,v₂,v₃但结果去重后按“匹配原型数”加权排序。例如item匹配2个原型权重2匹配1个权重1。收益查询量减28%三次查询合并为一次HTTP请求CVR2.1%。成本3人日开发0新增服务器。5.2 大厂级演进从SetMIR到Interest GraphSnap的SetMIR是起点不是终点。我们正在推进的Interest Graph方向把用户兴趣集合升级为动态图结构节点每个原型vᵢ是一个节点边vᵢ到vⱼ的边权重用户行为中vᵢ和vⱼ共现频率如“露营”后24小时内点击“登山”的次数图神经网络用GraphSAGE聚合邻居生成vᵢ的增强向量。实测在跨域推荐如从“健身”兴趣推“营养餐”上AUC提升5.7%最后分享个实战技巧上线前务必做“兴趣可解释性测试”。随机抽100个用户人工检查其原型v₁是否对应其最近高频行为如v₁“Python教程”对应用户刚学完《流畅的Python》。如果准确率80%说明原型生成器没训好别急着上ANN——再好的检索也救不了错误的输入。
RELATED

相关推荐

基于Python的共享充电宝管理系统:设计与实现全解析

基于Python的共享充电宝管理系统:设计与实现全解析

作为一个经常帮人看毕业设计、也自己动手写过不少Python管理系统的老学长,今天想跟正在为选题发愁、或者已经选了“共享充电宝管理系统”这个题目的同学好好聊聊。这个题目在计算机毕业设计里可以说是常青树了,市场需求明确、业务逻辑清晰、功能边界好把…

📅 2026/9/9 14:42:10
NVIDIA 616.56驱动实测:AI视频生成显存省40%提速20%

NVIDIA 616.56驱动实测:AI视频生成显存省40%提速20%

NVIDIA这波更新,说实话比我预想中来得更实在。616.56这个版本号乍一看像是常规的Game Ready驱动小迭代,但装上之后跑了几条AI视频生成的工作流,我才意识到这次驱动层面的改动其实是冲着AI创作者来的。先说结论:在同一条ComfyUI文生…

📅 2026/9/9 14:42:10
P2P点对点通讯实战:NAT穿透、UDP打洞与信令服务器设计

P2P点对点通讯实战:NAT穿透、UDP打洞与信令服务器设计

简介:P2P技术实操演示示例,面向网络通信、分布式系统及流媒体相关开发者和学习者,用于理解并上手实践P2P通信。示例围绕P2P服务、P2P服务器、NAT穿透等核心内容展开,涉及UDP打洞、STUN、TURN、ICE等穿透协议思路,以及I…

📅 2026/9/9 14:37:09
MORE NEWS

更多资讯

📰

Selenium客户项目实战:环境配置、元素定位与等待策略精讲

1. 客户项目的第一道坎:环境准备比写脚本更耗时之前接过一个客户端的自动化测试项目,需求说得很简单:“把我们的核心业务链路用 Selenium 自动化跑起来,以后回归不用人工点。”一开始我以为是技术问题,结果真正开工后才…

📰

零基础入门具身智能:从仿真平台到强化学习的完整学习路径

零基础入门具身智能,最容易踩的第一个坑不是学不会强化学习,也不是看不懂大模型,而是不知道自己该从哪里开始。具身智能这个方向确实热,涉及仿真平台、感知、强化学习、具身大模型和真实机器人部署,每一块单独拿出来都…

📰

STM32驱动NRF24L01无线模块:从SPI配置到收发调通全记录

简介:STM32F103RC与NRF24L01无线收发模块的测试程序,面向嵌入式初学者及物联网开发者,演示如何通过SPI总线驱动NRF24L01完成数据收发。工程基于标准外设库构建,包含完整的初始化、收发逻辑与串口打印验证流程,可直接编…

📰

Flask入门实践:从虚拟环境到路由调试的完整指南

1. 动手前的准备:环境搭建与版本选择1.1 虚拟环境:为什么不能直接在系统 Python 里装很多第一次接触 Flask 的同学,上来就一句pip install flask,装完就写代码,写到第二周就开始出事。我见过太多人一个电脑上有三四个项…

📰

跨站、站点域与公共后缀:彻底拆解 SameSite Cookie 与登录态丢失

上周排查一个线上登录态丢失的问题,Cookie 明明设置成功了,刷新后请求头里也带着,可一进跨站的支付回调页面再跳回来,登录态就没了。我把 Network 面板和代码来回看了两小时,最后发现,问题出在我对"跨…

📰

机器学习入门实战:用Scikit-learn实现鸢尾花KNN分类

先交代一下背景:这篇内容是我自己“机器学习进阶系列”的第三篇。前面两篇我们聊了机器学习到底在干嘛、常用术语是什么意思,到这一篇,终于要写第一行能跑的代码了。我特意选了鸢尾花分类这个经典到不能再经典的例子,不是因为花样…

TODAY

今日更新

THIS WEEK

本周精选

THIS MONTH

本月热门

读完文章,想聊聊您的网站?

告诉我们您的行业与需求,资深顾问一对一梳理方案与报价,全程免费。

📞 💬