双塔模型工作
这两个问题问得非常落地!这已经是实际写代码和做架构落地的层面了。我们一个个来拆解,帮你把这套系统的最后一公里打通。
问题 1:静态特征走普通的 Embedding,用的什么 Embedding 模型?
答案是:没有使用任何外部的、预训练的“模型”(比如 BERT、Word2Vec 都不是)。
在推荐系统(RecSys)的代码里,所谓的“普通 Embedding”,其实就是一个“可训练的权重矩阵(Lookup Table / 查表)”。
如果你用 PyTorch 或 TensorFlow 写代码,它就是框架自带的一个基础网络层(nn.Embedding 或 tf.keras.layers.Embedding)。
具体是怎么运作的?
- 类别特征(Categorical)的查表:
- 假设“风险等级”有 5 种(1=保守, 2=稳健, 3=平衡, 4=进取, 5=激进)。
- 在代码里,你会初始化一个形状为
[5, 16]的矩阵(5行,16列)。一开始,这矩阵里全是随机生成的无意义小数。 - 当来了一个“激进(ID=5)”的用户,代码直接去这个矩阵里把第 5 行抽出来,这就是他的 16 维向量。
- 数值特征(Numerical)的处理:
- 比如用户的“年龄=35”、“资产=50000”。
- 做法A(分箱离散化):把年龄分成 0-20, 20-30, 30-40 等几个“桶(Bucket)”,35岁落入第3个桶(ID=3),然后像上面一样去查表。
- 做法B(全连接层映射):直接把 35 这个数字,乘以一个
[1, 16]的权重矩阵(Linear Layer),映射成 16 维向量。
- 它是怎么变聪明的?(端到端训练):
- 这个
[5, 16]的矩阵,是和上面的 MLP、SASRec 绑在一起联合训练的(End-to-End)。 - 当用户点击了某个产品(Loss下降),反向传播(Backpropagation)的梯度会一直传导到底层,直接修改这个矩阵里的数值。
- 训练几千万次后,这个矩阵里的数字就被“盘包浆”了,蕴含了极强的业务规律。
- 这个
总结: 推荐系统里的静态特征 Embedding 不是调包(不调外部模型),而是自己从零初始化的一个矩阵,靠着用户的点击数据,硬生生“喂”出来的专属特征表达。
问题 2:最终拿到 256 维 User Vector,去 Milvus 去召回吗?
答案是:完全正确!100% 就是这么干的!
这就是整个双塔模型在线上(Online)真实运转时的核心大招——向量检索(Vector Search)。
为了让你在面试时能把整个链路说得滴水不漏,我把这个过程分为“离线(提前做好的)”和“在线(毫秒级发生的)”两部分:
1. 离线/近线准备(Item 塔的工作)
- 算物品向量:系统后台有一个“Item 塔”。它提前把富途所有的股票、几千篇资讯、几百个营销活动,全部跑一遍模型,算出每个物品的 256 维 Item Vector。
- 建库与建索引:把这几万/几十万个 Item Vector 存入 Milvus。并且在 Milvus 里建立索引(工业界最常用的是 HNSW 索引 或 IVF_FLAT),这样搜索起来就不需要挨个对比,速度极快。
2. 在线实时召回(User 塔与 Milvus 的配合)
当用户打开富途牛牛 App 的那一瞬间(要求在 50~100 毫秒内返回结果):
- 特征组装:后台迅速拉取用户的静态特征(查表),并接收 Flink 传来的实时行为序列。
- 模型推理(Inference):把这些特征丢给部署在 GPU/CPU 上的 User 塔模型(比如通过 Triton Inference Server)。模型瞬间吐出这个用户的 256 维 User Vector。
- Milvus 检索(高潮来了):
- 业务代码拿着这个 256 维的 User Vector,向 Milvus 发起一次 RPC 请求:
milvus.search(data=[user_vector], top_k=100, metric_type="IP") - 注:
metric_type="IP"代表内积(Inner Product),双塔模型通常用内积来衡量相似度。
- 业务代码拿着这个 256 维的 User Vector,向 Milvus 发起一次 RPC 请求:
- 返回结果:Milvus 在几毫秒内,在几万个物品中,找到了与这个 User Vector 距离最近(内积最大)的 100 个物品的 ID。
- 召回完成:这 100 个物品,就是系统认为该用户此刻最可能感兴趣的东西。
💡 面试加分项(展现高级开发视角的“必杀技”)
如果你在面试中聊到了去 Milvus 召回 100 个物品,千万别停在这里! 你可以主动抛出下一步:
“从 Milvus 召回这 100 个候选物品后,我们不能直接展示给用户。因为双塔模型为了追求极速的向量检索,User 和 Item 是分开计算的,特征交叉做得不够深,预估的准确率还不够极致。
所以,拿到这 100 个物品后,我们还会进入『精排层(Ranking)』。
我们会把这 100 个物品和用户特征一起,喂给一个更庞大、更复杂的深度学习模型(比如 DeepFM 或 DIN)。精排模型不需要去 Milvus 检索,它只对这 100 个物品进行极其精细的打分(CTR 预估),最后选出得分最高的 3 个,再结合业务规则(比如不能连续推同一个活动),最终展示在用户的 App 界面上。”
如果你能把 特征 Embedding -> 双塔融合 -> Milvus 召回 (Recall) -> 复杂模型精排 (Ranking) 这个完整的工业界推荐漏斗(Funnel)说出来,面试官基本可以直接给你发 Offer 了,因为这证明你不仅懂局部算法,更具备全局的架构视野。

浙公网安备 33010602011771号