召回模型怎么搭建?
推荐系统召回流程:特征工程、负采样、向量索引构建
原题:请描述推荐系统中召回模型的搭建流程和核心设计逻辑,包括特征工程、模型选型、负采样策略、向量索引构建等关键环节。
向量检索 · 字节真题
回答与解析
整体架构:双塔模型(DSSM)
推荐召回的核心是向量检索,主流方案是双塔结构:User塔和Item塔分别编码,点积计算相似度,线上通过ANN快速检索。
关键环节设计
1. 特征工程
| 塔 | 核心特征 | 设计要点 |
|---|---|---|
| User塔 | 用户ID、画像标签、历史行为序列 | 行为序列用Pooling或Transformer压缩,避免长序列直接输入 |
| Item塔 | 物品ID、类目、标签、文本/视觉内容 | 内容特征需预训练(如BERT、CLIP),保持与User塔维度一致 |
关键权衡:ID特征记忆性强但泛化差,需配合属性特征缓解长尾问题。
2. 模型选型
- 基础版:MLP双塔,结构简单、推理快
- 进阶版:User侧加Transformer建模行为序列,Item侧保持轻量(物料更新频繁,需快速推理)
- 损失函数:Sampled Softmax或Cosine + Margin Loss,配合温度系数τ调节分布锐度
3. 负采样策略
1. Batch内负采样:实现简单,但分布有偏(热门item过度采样)
2. 全局负采样:从全库采样,需配合logQ修正
3. Hard Negative Mining:线上召回TopK但未点击的样本加入训练
4. 混合策略:1:1:1的easy:batch:hard比例,平衡收敛速度与区分度
4. 向量索引构建
| 方案 | 适用场景 | 注意点 |
|---|---|---|
| HNSW | 百万级、精度要求高 | 内存占用大,需控制ef参数 |
| IVF-PQ | 十亿级、内存受限 | 聚类中心数与量化比特数 trade-off |
| 实时增量 | 新物料秒级入库 | 需支持HNSW的动态增删或定期重建 |
工程实践:Item向量离线预计算,User向量实时推理;索引按类目/热度分片,降低检索空间。
链路解耦
- 离线:全量Item编码 → 构建Faiss/Milvus索引 → 推送至KV/Redis
- 在线:User实时特征 → 塔模型推理 → ANN检索TopK → 粗排过滤
学习建议
建议系统学习该知识点
口语版讲法(约4分钟)
- 一句话定位:召回的本质是向量检索,双塔是主流
- 特征工程:ID和属性配合,行为序列压缩
- 负采样:batch内、全局、hard negative混合,注意分布偏差
- 向量索引:HNSW和IVF-PQ的选择,实时更新风险
- 工程落地:离线预计算、在线实时推理、分片策略,可延伸点延伸
面试官你好,这道题问的是召回模型的搭建流程和核心设计逻辑,我觉得它本质上是问:在推荐系统里,怎么从海量物料中快速找到用户可能感兴趣的候选集,并且把精度和效率平衡好。主流的方案是双塔模型,也就是User塔和Item塔各自编码,然后点积算相似度,线上通过ANN做快速检索。
先说特征工程。User塔这边,核心是用户ID、画像标签和历史行为序列。行为序列这块有个关键点,就是不能把长序列直接往里灌,得做压缩,比如用Pooling或者Transformer把序列压成一个固定长度的向量。Item塔这边,除了物品ID和类目标签,文本或视觉内容也很重要,但内容特征一般需要预训练模型来提,比如BERT或者CLIP,而且维度要和User塔对齐。这里有个权衡:ID特征记忆性强,但泛化差,对于长尾物品,得靠属性特征来弥补,否则新物品或者冷门物品就召不回来。
再说模型选型。基础版就是MLP双塔,结构简单,推理快。进阶版可以在User侧加Transformer来建模行为序列,但Item侧最好保持轻量,因为物料更新频繁,需要快速推理。损失函数我常用Sampled Softmax或者Cosine加Margin Loss,配合温度系数来调节分布的锐度。
负采样是召回里特别关键的环节。书面答案里列了好几种策略,但实际落地我倾向于混合策略。Batch内负采样实现简单,但分布有偏,热门物品会被过度采样;全局负采样可以修正分布,但需要配合logQ来矫正;Hard Negative Mining,也就是把线上召回TopK但用户没点击的样本拿来做负样本,能提升模型区分度。我一般按1:1:1的比例混合easy、batch内和hard负样本,这样收敛速度和区分度都能兼顾。
向量索引这块,方案选择取决于规模。百万级精度要求高的话,用HNSW,但内存占用大,需要控制ef参数。十亿级内存受限的话,用IVF-PQ,聚类中心数和量化比特数得做trade-off。但这里有个坑:物料更新频繁时,索引的实时增量是个大问题。HNSW支持动态增删,但性能会下降,所以更常见的做法是离线预计算全量Item向量,构建Faiss或Milvus索引,然后推送到KV或Redis;User向量则在线实时推理。索引还可以按类目或热度分片,降低检索空间。
说到实时更新,其实还有一个更隐蔽的问题:当物料频繁新增或修改时,索引的一致性和检索质量怎么保证?比如删除操作,如果原地动图索引,召回质量很容易崩。我一般会把删除标记为软删除,后台异步重建索引,再配合双缓冲影子索引做原子切换,上线前用固定query回放对比Recall@K和延迟,不通过就回滚。
所以整体来看,我会把召回模型看成是一个系统工程,离线、在线、索引、策略得一起考虑,不能只看模型本身。
关键一句:物料频繁更新时,索引的一致性和检索质量保证是难点,软删除加异步重建加双缓冲影子索引是常见解法
面试官还可能这样问
- 问法 1 · 场景切入
假设你在做电商首页的个性化推荐,用户来了之后需要从千万商品里快速召回几百个候选。你怎么搭建这个召回模型?从特征到索引,关键环节怎么设计?
- 问法 2 · 层层追问
召回模型你一般怎么搭?……双塔结构里user和item特征怎么处理?……负样本你怎么选?……向量建索引用哪种方案?
- 问法 3 · 直球架构
请描述推荐召回双塔模型的搭建流程,包括特征工程、模型选型、负采样策略和向量索引构建,每个环节的核心设计逻辑是什么?