最近核验:2026-10-09。以下是教学选型思路,不是 Twitter / X 的配置清单,也不是某个工具的性能排名。
不要从“我们应该用什么模型”开始
沿用信息流设计题的虚构社区。先问:最缺的是找不到内容、找到了却排不好,还是新内容迟迟进不来?这三件事,换同一个组件未必都管用。
这里有 2 个层次:逻辑组件负责什么,具体用什么实现。 “向量召回”是职责;用精确扫描、HNSW 还是 IVF-PQ,是实现选择。PyTorch、Faiss、数据库也不在同一个抽象层。
1 · 用户和内容用什么编码?
先代入两个虚构场景:
| 同样是内容推荐 | 先试什么 | 为什么,以及什么时候换 |
|---|---|---|
| 内容库小、变化慢,团队还在验证需求 | 简单特征与精确搜索基线(baseline) | 先把效果和错误看清;测到搜索成本确实成问题,再加近似索引 |
| 新内容不断进入,旧 ID 互动少,机器内存有限 | 内容表示、事件更新,以及精确搜索对照下的压缩索引实验 | 想改善新内容覆盖,但同时承担编码、更新和近似误差;是否划算要测 |
它们不是标准答案。比如小库也可能有很高的并发;内存紧也不代表一定要用 PQ。关键是把你这次的约束写出来,别让选型表替你思考。
| 可选实现 | 值得考虑的条件 | 要付出的代价 / 怎么检验 |
|---|---|---|
| ID embedding + 小 MLP | ID 有稳定重复行为,想先建立便宜基线 | 新 ID 缺少表示;按冷启动(cold start)和低频切片(slice)检查,别只看总体 |
| 文本 encoder + 结构化特征 | 内容文本有信息,希望利用描述迁移到新内容 | 文本清洗、截断、编码与重算成本;固定标签和候选(candidate)池,看新增语义有没有用 |
| 行为序列 encoder | 行为顺序、近期变化可能有用 | 历史读取与计算更贵;对比打乱顺序、缩短历史和简单 pooling,验证是否真需要顺序 |
| 图像 / 多模态 encoder | 文本确实漏掉图像中的信息 | 处理成本、缺失模态与缓存失效;遮掉图像再测,检查增量而不是只看中间特征漂亮 |
这些可以组合,不是互斥的“模型排行榜”。ID 和内容特征都能输入一个塔;序列建模也能只发生在用户侧。先说明缺什么信息,再解释为什么这个模块能补。
例如:如果内容塔(candidate tower)输入的标题本来就是空的,先补数据可能比换更大的文本模型有价值。如果序列打乱后结果没变,就还没有证据为昂贵的顺序建模买单。
2 · 索引怎么选,不只是问哪个最快?
先用同一批向量做精确检索(retrieval),留一份正确的 top-k 对照,再衡量近似方案。这个对照回答“索引有没有找回模型本来会选的东西”,不是“模型理解了用户”。
| 实现路线 | 什么时候拿来试 | 主要取舍 |
|---|---|---|
| Flat 精确扫描 | 小规模、验证实现,或硬件吞吐足够时 | 不丢近邻,但扫描成本随库大小增长 |
| HNSW | 想试图搜索的延迟—召回折中 | 额外图结构占内存;搜索参数、构建时间和更新能力要一起测 |
| IVF / IVF-PQ | 想缩小搜索范围,或压缩存储 | 分区和量化可能丢精度;还要维护训练好的索引参数 |
| 已封装的向量服务 | 需要持久化、过滤、分片(sharding)和运行管理 | 多一层依赖与运维约束;仍需核对搜索语义与版本能力 |
具体支持哪些更新和删除操作,依实现而异;不能因为都叫 HNSW 就默认行为一样。Faiss 是向量检索库,不自动等于完整的分布式数据库。Faiss 索引类型 · 官方选型指南
测试至少放在一张图或表里:近邻找回率、p95/p99 延迟、内存、构建/更新时间。不要只报一个 QPS,然后略过数据维度、机器和过滤条件。
一个很常见的坑:训练用 cosine,索引用 inner product
对非零向量,cosine 是归一化后的点积(inner product):
$$\cos(q,v)=\frac{q^\top v}{\|q\|\|v\|}.$$
如果训练与检索没有采用一致的归一化规则,向量范数可能改变排序。向量维度完全匹配,查询也不会报错,结果却不是你以为的那个分数。Faiss 距离定义
用 $q=(1,0)$ 查两个内容向量 $A=(2,0)$、$B=(100,100)$:点积分别是 2、100,会把 B 放前面;cosine 分别是 1、$1/\sqrt{2}\approx0.707$,会把 A 放前面。B 只是更长,不是方向更接近。
也别反过来说“少归一化一步,排名一定变”。若内容向量已经都是单位向量,对同一条非零查询,只改查询的正比例缩放不会改变精确点积排序,只会缩放分数。但如果按绝对阈值过滤,或要跨查询比较分数,这个尺度仍然重要;要返回 cosine 数值,就把两侧都归一化。
检验方法很直接:拿几个固定向量,手算分数,再比较离线代码和线上路径。零向量、NaN、重复 ID 和稳定的 tie-break 也值得测。
3 · 召回之后,排序器还能选什么?
| 选项 | 主要多看了什么 | 为什么不一开始就上最重的 |
|---|---|---|
| 规则 / 线性模型 / 树模型 | 清楚定义的特征与组合 | 易做基线;能否表达任务需要的交互仍要检验 |
| 小 MLP / 多任务 ranker | 用户—内容特征交互、多个行为目标 | 标签缺失、任务冲突、校准(calibration)和 loss 权重都需要处理 |
| 序列或联合编码模型 | 更细的历史—候选、文本—文本匹配 | 输入读取与交互计算更贵,适合先在小候选集检验增量 |
不是“越往下越好”。召回先缩小范围、排序再多花一些计算,是历史上已经存在的分工;具体阶段怎么划,要看你的工作量和目标。YouTube 2016 论文
排序器也不能凭空修复召回遗漏。反过来,召回集合已经包含足够多相关内容时,继续追求更大候选池可能只是在把成本转给下一层。
4 · 特征和表示在哪算?
| 位置 | 适合什么 | 容易漏掉什么 |
|---|---|---|
| 批处理 | 稳定特征、全量回填 | 新内容或编辑后的内容会等下一轮 |
| 事件驱动 / nearline | 发布、编辑后尽快刷新表示 | 重复与乱序事件、失败重试、积压监控 |
| 请求时 online | 只有这次请求才知道的信息 | 尾延迟、超时、特征缺失和降级(fallback)策略 |
这不是三选一。可以批量建立基础索引,事件更新处理变化,在线只补必要上下文。代价是多条路径必须对同一个字段有同一种解释。
5 · 合并、过滤和多样性别塞成一个黑盒
- 合并与预算:先去重,保留全部来源。不同模型的原始分数别直接混排;可以验证统一打分、来源配额或 rank-based fusion。
- 资格与权限:便宜的限制尽量提前处理,返回前再确认关键资格;内容被删除时,不能只等下一次向量回填。
- 列表体验:作者上限、主题重复或探索预算属于列表选择。它们和单条相关性有关,但不是同一个问题。
过滤太晚可能让最终列表不足;盲目增加 overfetch 又会增加成本。应该记录每层淘汰数量,检查哪些来源、哪些人群最容易被淘空。
把选择写成一句能被推翻的话
别写:“采用先进的多模态推荐架构。”
可以写:“我们怀疑文本缺少某类视觉信息,先在固定候选池和标签协议下比较带图与不带图;只有相关性增量覆盖重算和存储成本,才考虑加入内容侧。”
这句话有观察、改动、对照和退出条件。别人能质疑它,也能接着做实验。
把一次选型走完,而不是只留一张表
假设教学服务的症状是“新帖子搜不到”。先抽取失败样本:原文存在,向量任务成功,但索引里没有对应版本;旧帖子检索和排序正常。此时换更强的 encoder,并不解决已定位的更新延迟。
我们先比较两个改法:缩短批处理间隔,或增加事件驱动更新。前者改动小,但会反复扫描,最坏等待仍受批次约束;后者能更快响应编辑,但要处理重复、乱序、积压和补偿。若团队规模小、更新需求也不急,批处理可能已经够用,不能因为 nearline 听起来更高级就选它。
验证时固定内容与 encoder,分别测“发布到可检索”的分布、漏更率、重复事件后的幂等性,以及编码/索引写入成本。设一个具体的 freshness 目标,再判断哪个方案满足它。上线后还要确认旧内容的查询延迟没有因频繁写入而恶化。
反过来,如果最新版本已经在索引中,精确搜索也把它排很低,就继续查训练信号和表示;如果精确搜索靠前而 ANN 找不到,再查索引参数。同一句“搜不到”,可以对应三种完全不同的改动。
自测
ANN 找回率很高,但用户相关性很低,先查哪里?
索引可能忠实找回了模型的错误近邻。先检查表示、训练信号和任务评估,不要把“近似精确搜索”当成“近似真实偏好”。
要更新帖子内容,只换数据库里的文本够吗?
不够。还要考虑对应向量、特征缓存、索引版本,以及旧结果多久失效。更新路径和允许的新鲜度(freshness)需要明确。
下一篇:从组件图到可以上线的请求链
本页术语 11
- 基线 baseline
- 用来比较新方法的参考方法或配置
- 冷启动 cold start
- 用户或内容缺少历史证据,模型只能靠先验
- 切片 slice
- 按内容或用户属性划分的子群体,用来检查平均值掩盖了什么
- 候选 candidate
- 召回阶段捞出来、等待精排挑选的内容
- 内容塔 candidate tower
- 双塔检索中把候选内容编码成可预计算向量的模型分支
- 检索 retrieval
- 从外部语料里找出相关内容
- 分片 sharding
- 把参数、梯度或优化器状态切开分给多张卡,每张只存其中一份
- 点积 inner product
- 两个向量对应分量相乘再求和,双塔的打分方式
- 校准 calibration
- 模型给出的置信度是否等于真实正确率
- 降级 fallback
- 主路径不可用时切换到较简单但语义明确的备用行为
- 新鲜度 freshness
- 内容产生到可被检索之间的延迟