推荐系统-双塔模型-进阶
这是一个非常深入的工业界实战问题。在面试中,如果你能把这个问题答好,基本就能证明你真正做过千万级DAU的推荐系统。
首先要澄清一个核心概念:“双塔模型(Two-Tower Model)”本身不是一个具体的算法(像ResNet或BERT那样),而是一种“架构范式”。
它的核心铁律是:用户塔(User Tower)和物品塔(Item Tower)必须完全解耦(分开计算),只能在最后一层通过点积(Dot Product)或余弦相似度进行交互。只有这样,Item向量才能提前算好存入 Milvus/Faiss,User向量才能在线实时计算并去库里检索。
在工业界,大家都是在这个“双塔”的壳子里,往里面塞不同的网络结构。目前业界主流的演进方向和具体模型有以下几种:
1. 经典基线:DSSM (Deep Structured Semantic Model)
- 出处:微软(最早用于搜索文本匹配,后来被广泛用于推荐召回)。
- 结构:最简单粗暴。用户侧特征(画像、统计量)拼接后过几层 MLP(全连接层);物品侧特征拼接后也过几层 MLP。最后输出两个固定维度的向量算内积。
- 业界现状:几乎所有大厂(包括富途、腾讯、阿里)在做一个新业务的冷启动时,V1.0 版本绝对是跑一个基础的 DSSM。它简单、好训练、容易上线。
2. 引入实时序列:YouTube DNN (召回版) / SASRec
- 痛点:基础 DSSM 无法很好地处理你前面提到的“Flink 实时传过来的用户行为序列”(比如用户刚刚连续看了3只科技股)。
- 业界解法:在 User 塔中引入序列建模。
- YouTube DNN 召回结构:把用户历史看过的物品 Embedding 进行 Average Pooling(平均池化),拼接到 User 塔中。
- SASRec (Self-Attentive Sequential Recommendation):User 塔里不用简单的池化,而是引入 Transformer 的 Self-Attention 机制,专门捕捉用户行为序列中的时间先后关系和重要性。
3. 解决“既要又要”:多兴趣召回模型 (MIND / ComiRec)
- 出处:阿里 (MIND - Multi-Interest Network with Dynamic routing)。
- 痛点:传统的双塔,User 塔最后只输出 1个 向量。但金融用户的兴趣是多样的(比如他既是个“稳健打新客”,又偶尔“炒美股期权”)。用1个向量去表达多个兴趣,会导致向量被“中和”掉,什么都召回不准。
- 业界解法:User 塔不再输出1个向量,而是通过胶囊网络(Capsule Network)或多头注意力,动态输出 K 个(比如 3~5 个)不同的 User 向量(分别代表他的稳健兴趣、激进兴趣等)。然后拿这 K 个向量分别去 Milvus 里并发检索,最后合并结果。这在电商和金融领域非常流行。
4. 引入图网络:GraphSage / PinSage
- 出处:Pinterest (PinSage)。
- 结构:不单纯依赖用户的属性标签,而是把“用户-股票-资讯”构建成一个巨大的异构图(Bipartite Graph)。User 塔和 Item 塔实际上是图神经网络(GNN)的聚合过程。
- 应用场景:在富途的“牛牛圈”社区推荐,或者“看了又看”、“买了又买”的场景中,图神经网络双塔的召回效果奇佳。
工业界真正的核心壁垒:不是模型结构,而是“怎么训练”
在面试高级AI开发时,如果你只背诵了 DSSM 或 MIND 的结构,只能算及格。工业界双塔模型真正的难点在于样本构造和损失函数(Loss)的设计。
业界目前最前沿的做法(也是大厂拉开差距的地方)是:
- In-batch Softmax (批内负采样):
双塔模型通常用 Contrastive Learning(对比学习)的思路训练。Google 提出在同一个 Batch 内,把其他用户的正样本作为当前用户的负样本,极大提升了训练效率和模型区分度。 - Hard Negative Mining (困难负样本挖掘):
如果只拿“用户点击的”当正样本,“随机抽取的”当负样本,模型学不到精髓(因为随机抽的太容易区分了)。业界会在训练时,故意喂给模型一些“用户曝光了但没有点击的(Hard Negatives)”,逼着双塔模型去学习极其细微的特征差异。
总结:富途会用什么?
针对富途牛牛这个岗位(千万级用户、毫秒级实时决策),他们大概率的演进路线是:
- 底层框架:基于 TensorFlow (TFRS) 或 PyTorch 搭建双塔。
- 模型结构:User 塔是一个融合了 Flink 实时序列特征的深度网络(可能带有 Attention 机制处理序列),Item 塔是一个标准的 MLP。
- 高阶可能:如果业务足够复杂,他们极有可能在探索 MIND(多兴趣双塔),以应对金融用户极其割裂的投资偏好。
你如果在沟通中抛出 “User塔如何处理 Flink 传来的实时序列特征(Pooling 还是 Attention)” 以及 “双塔训练时如何做 Hard Negative 挖掘” 这两个点,面试官会立刻把你当做核心骨干候选人来看待。
双塔模型的embeding 是什么模型?
这是一个非常经典且极易混淆的误区!很多刚接触向量检索(Vector Search)或 RAG(检索增强生成)的开发者,都会把 “自然语言的 Embedding(如 Sentence-BERT)” 和 “推荐系统里的特征 Embedding” 搞混。
直接回答你的问题:绝对不是使用 Sentence-BERT,它确实是经过推荐系统专门训练出来的特殊模型(通常是端到端训练的 Embedding 层)。
为了让你在架构设计和面试中彻底理清这个概念,我们必须把这两种 Embedding 严格区分开:
1. 为什么不能用 Sentence-BERT?
Sentence-BERT(或 OpenAI 的 text-embedding-ada-002 等)是 NLP(自然语言处理)模型。
它的强项是理解“人类语言的语义”。比如你输入一段话:“今天大盘走势很好,适合买入”,它能把这句话变成向量。
但是,“风险等级=激进” 或者 “用户ID=8848” 或者 “性别=男”,这些属于结构化/类别型特征(Categorical Features)。
如果你把“激进”这两个中文字符扔给 Sentence-BERT,它只会根据汉语词典的语义给你算出一个向量。Sentence-BERT 根本不知道在富途的业务里,“激进”意味着这个用户喜欢买期权、喜欢满仓干、喜欢高频交易。
2. 推荐系统里的 Embedding 是怎么来的?(核心机制)
在富途这种推荐系统中,像“风险等级=激进”这样的特征,它的 16 维向量是在推荐模型(如双塔模型、DeepFM)训练的过程中,由神经网络自己“悟”出来的。
具体过程如下(以 PyTorch/TensorFlow 为例):
- 随机初始化(查表):系统里有一个巨大的“特征词典(Embedding Table)”。一开始,“激进”对应的 16 个小数是完全随机生成的(比如
[0.01, -0.02, 0.05...]),没有任何意义。 - 端到端训练(End-to-End Training):
- 系统拿过去一年的真实历史数据来训练模型。
- 数据样本:用户A(标签:激进) -> 曝光了“期权大礼包” -> 点击了(Label=1)。
- 数据样本:用户B(标签:保守) -> 曝光了“期权大礼包” -> 没点击(Label=0)。
- 反向传播(梯度下降):
- 当模型预测错误时,它会通过反向传播算法,去修改那 16 个小数。
- 经过几千万次的数据喂养,模型发现:只要用户带有“激进”这个标签,他点击“期权”、“高波动股票”的概率就极高。
- 最终成型:
- 训练结束后,“激进”这个标签的 16 维向量就被固定下来了。
- 此时,如果你去计算空间距离,你会神奇地发现:“激进”的向量,和“期权”的向量,在几何空间里紧紧挨在了一起! 而它离“货币基金”的向量非常远。
这就是推荐系统 Embedding 的魅力:它不是基于语言学语义,而是基于用户的真实业务行为(点击、交易、入金)学出来的“业务语义”。
3. 那么,Sentence-BERT 在这个系统里完全没用吗?
有用,但只用在“非结构化文本”上。
在这个 AI 营销平台中,用户的特征是结构化的(用专门训练的 Embedding 层),但营销物料/资讯可能是大段的文本。
比如,富途牛牛圈里有一篇深度长文《英伟达Q3财报深度解析》。
这个时候,系统就会调用 Sentence-BERT(或大模型),把这篇长文的标题和内容“浓缩”成一个 256 维的文本语义向量,然后作为“物品特征(Item Feature)”的一部分,输入到推荐模型中。
4. 纠正关于 Milvus 的认知
你提到“Milvus 默认的模型”。这里要澄清一下:
Milvus(或 Faiss、Pinecone)只是一个“向量数据库(Vector DB)”。
它本质上是个“带搜索功能的超级 Excel”。它自己不负责生成向量(虽然现在有些向量库集成了生成接口,但底层依然是调用外部模型)。
- 它的工作是:你把算好的 256 维向量存进去,它帮你用极其变态的速度(毫秒级)找出最相似的 Top 100。
- 向量是怎么算出来的,Milvus 根本不关心。 无论是 Sentence-BERT 算的文本向量,还是推荐模型算的用户特征向量,对 Milvus 来说都只是一堆浮点数。
总结
- NLP Embedding(如 Sentence-BERT):用来理解自然语言(文章、搜索词),是预训练好的。
- RecSys Embedding(推荐系统特征嵌入):用来理解业务特征(风险等级、用户ID、行为序列),是根据点击/交易数据,在推荐模型里从零开始训练出来的。
- 在富途的架构中,这两者会结合使用,最终拼接成用户的 User Vector,存入或用于查询 Milvus 这样的向量数据库。

浙公网安备 33010602011771号