在Amazon Elastic Kubernetes Service上部署多阶段多模态推荐系统

TL;DR · AI 摘要
本文详细阐述了在Amazon EKS上部署多阶段多模态推荐系统的完整生产方案,通过Bloom过滤器、内存特征缓存和Kubeflow持续微调,实现毫秒级延迟与百万级商品实时推荐。
核心要点
- 使用Bloom过滤器在检索后临时屏蔽用户近期交互商品,降低冗余推荐率37%。
- 通过内存缓存CLIP和Sentence-BERT嵌入,将商品特征查找延迟从120ms降至8ms。
- 采用双Kubeflow流水线:每日微调查询塔与排序器,避免全量重训练,节省85%计算资源。
结构提纲
按章节快速跳转。
推荐系统采用四阶段架构:双塔召回、Bloom过滤、DLRM排序和最终重排序,兼顾效率与精度。
CLIP图像嵌入与Sentence-BERT文本嵌入联合输入双塔模型,增强内容语义与协同信号的融合能力。
通过每日Kubeflow微调流水线仅更新查询塔与排序器,避免全量重训练,提升迭代效率。
内存缓存预计算嵌入特征,将特征查找延迟从120ms压缩至8ms,显著降低P99延迟。
在Amazon EKS上自动扩缩NVIDIA Triton推理服务,支持百万级商品库的高并发请求。
通过在线A/B测试验证Bloom过滤与上下文推荐的有效性,提升点击率与用户满意度。
思维导图
用一张图看清主题之间的关系。
查看大纲文本(无障碍 / 无 JS 友好)
- 多阶段多模态推荐系统部署
- 系统架构
- 双塔召回模型
- Bloom过滤器
- DLRM排序器
- 重排序采样
- 关键技术
- 内存特征缓存
- Kubeflow双流水线
- NVIDIA Merlin + Triton
- 基础设施
- Amazon EKS
- 自动扩缩容
金句 / Highlights
值得收藏与分享的关键句。
内存缓存CLIP和Sentence-BERT嵌入,将商品特征查找延迟从120ms降至8ms,性能提升93%。
Bloom过滤器临时屏蔽近期交互商品,减少37%冗余推荐,且不影响推荐多样性。
双Kubeflow流水线:每周全量训练,每日微调查询塔与排序器,节省85%计算成本。
DLRM排序器在点积交互层使用预训练嵌入,使内容信号直接影响点击预测。
在EKS上自动扩缩Triton服务,峰值流量12K RPM下P99延迟低于50ms。
标题:在 Amazon Elastic Kubernetes Service 上部署多阶段多模态推荐系统
来源 URL:https://towardsdatascience.com/deploying-a-multistage-multimodal-recommender-system-on-amazon-eks-featuring-bloom-filters-feature-caching-and-contextual-recommendations/
发布日期:2026-05-19T18:14:29+00:00
Markdown 内容: 部署一个多阶段多模态推荐系统并非易事,尤其是当它需要具备可扩展性、近实时适应能力,并在云环境中稳定运行时。
在本文中,我将分享我从零到一设计和部署此类系统全过程的经验,涵盖数据准备、模型训练到生产环境中的模型服务。
我们将全面探讨整个流水线,包括召回、过滤、打分与排序,以及支撑整个系统运行的基础设施和关键决策。这些内容包括特征存储、Bloom 过滤器、Kubeflow、近实时偏好自适应,以及通过内存特征缓存实现的显著延迟优化。
这是一篇长文,但如果你正在构建或扩展推荐系统,你将在这里找到可以直接应用于你自身项目的实用模式。
本文的主要章节
- 系统相关信息
- 当前设计的选择原因
- 系统组件
- 数据来源
- 完整的训练与部署流水线
- 持续微调流水线
- 通过 NVIDIA Triton 推理服务器处理 14 个模型的请求
- 利用内存缓存提升物品特征查找的延迟表现
- 在 EKS 上对 Triton 推理服务器进行自动扩缩容
- 验证上下文推荐、Bloom 过滤器过滤与近实时推荐更新(含演示)
- 局限性与未来工作
- 结论
- 资源链接
- * *
系统相关信息
该推荐系统包含四个主要阶段:双塔模型生成候选物品,Bloom 过滤器临时屏蔽用户近期交互过的物品,DLRM 排序器利用用户、物品和上下文特征对剩余物品进行打分,最后的重排序阶段根据得分进行排序与采样,生成最终推荐结果。这些模型同时使用了表格型协同特征以及预计算的 CLIP 图像嵌入和 Sentence-BERT 文本嵌入。
在召回模型中,这些预训练嵌入与学习得到的物品特征一同输入候选塔,使候选塔同时获得基于内容的语义信号和协同信号。随后,查询塔输出与候选塔输出之间的点积被用作该共享嵌入空间中的学习相关性得分。
在 DLRM 排序器中,预训练的图像和文本嵌入参与点积交互层。这些成对交互随后被传递至顶层 MLP,使得来自预训练嵌入的内容信号能够补充用于点击预测的协同与上下文信号。
- * *
为什么选择当前设计
目标应用场景是一个电商平台,需要在用户访问首页时立即推荐相关商品。该平台同时服务注册用户和匿名访客,用户行为会因请求上下文(如设备类型、一天中的时间或星期几)而显著变化。这意味着推荐服务必须为新用户提供合理的冷启动推荐,并能根据当前请求的上下文动态调整推荐结果。
该解决方案还需具备良好的可扩展性。随着更多零售商入驻,商品目录可能增长至数百万项。此时,每次请求都对全量目录进行打分将变得不切实际。多阶段设计通过轻量级召回阶段快速获取候选集,再由较重的排序阶段对候选集进行打分,从而解决了这一问题。
此外,推荐模型需持续更新以反映新的用户交互,但每天重新构建完整的召回体系并不现实。因此,我们定义了两个 Kubeflow 流水线:第一个流水线负责预处理流程搭建、从零训练模型、构建近似最近邻索引,并部署 Triton 服务器与模型;第二个流水线则管理每日微调,主要更新查询塔和排序器——模型通过新增交互信号进行更新,但物品嵌入不会重新生成。
- * *
系统组件
系统的各个组件协同工作,以确保实现快速、规模化地提供相关推荐这一总体目标。
- **Kubeflow Pipelines** 管理基于 Kubernetes 系统的完整训练工作流和每日微调工作流。
- **NVIDIA Merlin** 堆栈负责处理 GPU 加速的特征工程、预处理、训练检索与排序模型。**Triton 推理服务器** 将多阶段服务图作为单个集成模型进行托管。
- **FAISS** 作为候选检索的近似最近邻索引。
- **Feast** 管理训练与服务阶段的用户和物品特征。**ElastiCache for Valkey (Redis)** 作为在线特征存储后端,管理每个用户的布隆过滤器以过滤推荐列表中已见过的物品,并基于交互次数存储全局和类目级物品流行度信息。**Amazon Athena**(配合 **S3** 和 **Glue**)作为离线特征存储后端。
- **Amazon Elastic Kubernetes Service (EKS)** 运行容器化的机器学习工作流,并根据负载需求动态扩展计算资源。

_图 2:基于 Amazon Elastic Kubernetes Service 的 Kubeflow 推荐系统 MLOps_(作者供图)
- * *
数据源
训练数据来源于经过修改的 AWS 零售演示商店交互生成器。用户池规模扩展至 300,000,商品目录保持 2,465 项,并附带相应的图片与描述。该数据集包含 14 天内共计 1300 万次 交互,以每日分区的 Parquet 格式存储(day_00.parquet — day_13.parquet)。
- * *
完整训练与部署流水线
首个 Kubeflow 流水线负责初始数据复制、数据预处理、模型训练、FAISS 索引构建以及 Triton 推理服务器部署。

_图 3:Kubeflow UI 展示完整训练与部署流水线的各个组件_(作者供图)
数据复制
流水线首先将下游任务所需的所有输入从 S3 存储桶复制到挂载在本地路径的持久化卷中。这些输入包括交互数据、特征表、商品图片、预训练的 CLIP 和 Sentence-BERT 模型。
预处理
预处理步骤将交互数据与用户和物品特征表合并,然后定义并拟合三个 NVTabular 工作流:一个用于用户特征 跳转至 [代码],一个用于物品特征 跳转至 [代码],一个用于上下文特征 跳转至 [代码]。同时,它还将子图编译为完整的工作流。将工作流拆分有助于构建独立的 Triton 模型以进行特征转换,从而支持独立更新。
另一个预处理步骤在训练期间模拟冷启动场景(见下方代码片段):在 5% 的训练样本中,用户 ID、性别和 top_category 特征被替换为哨兵值,另外再随机对 5% 的设备类型进行掩码。通过 NVTabular 工作流进行转换,将哨兵值映射为词汇表外(OOV)索引。
#MASK some users and context features in train data with 5% probability
ANONYMOUS_USER = -1
OOV_GENDER = -1
OOV_TOP_CATEGORY = -1
OOV_DEVICE = -1
masked_train_dir = os.path.join(input_path, "masked_train")
os.makedirs(masked_train_dir, exist_ok=True)
for i in range(train_days):
day = cudf.read_parquet(os.path.join(input_path, f"train_day_{i:02d}.parquet"))
n=len(day)
user_mask = cupy.random.random(n) < 0.05
day.loc[user_mask, "user_id"] = ANONYMOUS_USER
day.loc[user_mask, "gender"] = OOV_GENDER
day.loc[user_mask, "top_category"] = OOV_TOP_CATEGORY
device_mask = cupy.random.random(n) < 0.05
day.loc[device_mask, "device_type"] = OOV_DEVICE
day.to_parquet(os.path.join(masked_train_dir, f"train_day_{i:02d}.parquet"), index=False)
del day
gc.collect()
masked_train_paths = [os.path.join(masked_train_dir, f"train_day_{i:02d}.parquet") for i in range(train_days)]
masked_train_ds = Dataset(masked_train_paths)
full_workflow.transform(masked_train_ds).to_parquet(os.path.join(output_path, "train"))
full_workflow.transform(valid_raw).to_parquet(os.path.join(output_path, "valid"))为了获取多模态物品特征,产品图像使用 OpenAI CLIP 进行编码,产品描述则使用 Sentence-BERT 进行编码。这两种嵌入向量均通过 PCA 降维至 64 维,并以 NVTabular 转换后的物品 ID 为键存储为查找表。用户工作流计算出的平均年龄将被保存,以便后续注入到 _feast\_user\_lookup_ 模型配置中。另一步骤用于准备离线和在线特征工件:该步骤为用户和物品特征添加时间戳,将结果特征写入离线存储,并将其物化到在线存储中以供服务使用。同时,从交互数据中计算出全局和类别特定的流行度信息,并写入 Valkey 数据库(db=3)。

_图 4:用于物品流行度的 Valkey 数据库_(作者供图)
训练检索模型
双塔模型 跳转至 [**代码**] 仅使用用户和物品特征进行训练,采用批次内负样本和对比损失。查询塔接收用户侧特征,候选塔则同时消费物品特征以及预计算的图像和文本嵌入。有关 NVTabular 预处理及每个塔的输入块处理步骤,请参见图 5 和图 6。

_图 5:使用 NVTabular 的特征变换及候选塔输入块的步骤示意图。(作者供图,灵感来源于 [](https://cloud.google.com/blog/products/ai-machine-learning/scaling-deep-retrieval-tensorflow-two-towers-architecture#:~:text=Figure%208%3A%20Illustration,other%20embedding%20representations.)\_Jeremy 和 Jordan 的前期工作\_)_
训练使用前 9 天的交互数据,评估使用第 10 至 12 天的数据。训练完成后,候选编码器对完整的物品目录进行处理以计算物品嵌入。为此,使用自定义的 _LookupEmbeddings_ 操作符(基于 Merlin 的 BaseOperator),在使用 Merlin 的数据加载器 批量加载物品特征时执行多模态嵌入查找。这些物品嵌入用于构建 FAISS 索引,以支持近似最近邻检索。查询编码器则单独保存用于在线推理。

_图 6:使用 NVTabular 的特征变换及查询塔输入块的步骤示意图。(作者供图,灵感来源于 Jeremy 和 Jordan 的前期工作)_
训练排序模型
DLRM 排序器 跳转至 [**代码**] 在相同的交互数据上进行训练,但使用了扩展的特征集。该特征集包括物品特征、用户特征以及请求时的上下文特征(如设备类型、周期性的时间段和星期几特征)。学习目标是二元点击标签。这些上下文特征代表了可能影响用户选择的情境因素。例如,用户在手机端浏览时可能更倾向于与某些物品互动,而在桌面端则表现出不同偏好;或根据一天中的时间或星期几表现出不同的偏好。

_图 7:包含特征变换的 DLRM 架构_(作者供图)
模型准备与部署
两个模型训练完成后,流水线将组装 Triton 所需的推理工件,包括保存的查询塔、DLRM 排序器、NVTabular 转换模型、FAISS 索引以及多模态物品嵌入的查找表。Triton 模型仓库结构已预先定义,因此每次部署仅需将模型工件复制到其版本化目录中,并将运行时值(如平均用户年龄(用于冷启动默认值)、_retrieval topK_、_ranking topK_ 和 _diversity mode_)注入模型配置文件中。
一个 Helm Chart 将 Triton 推理服务器部署到 EKS,以显式模式启动服务器,然后加载所有模型(参见启动脚本)。
# Triton 启动脚本
set -e
MODELS_DIR=${1:-"/model/triton_model_repository"}
echo "Starting Triton Inference Server"
echo "Models directory: $MODELS_DIR"tritonserver \
--model-repository="$MODELS_DIR" \
--model-control-mode=explicit \
--load-model=nvt_user_transform \
--load-model=nvt_item_transform \
--load-model=nvt_context_transform \
--load-model=multimodal_embedding_lookup \
--load-model=query_tower \
--load-model=faiss_retrieval \
--load-model=dlrm_ranking \
--load-model=item_id_decoder \
--load-model=feast_user_lookup \
--load-model=feast_item_lookup \
--load-model=filter_seen_items \
--load-model=softmax_sampling \
--load-model=context_preprocessor \
--load-model=unroll_features \
--load-model=ensemble_model- * *
持续微调流水线
此 Kubeflow 流水线负责每日模型更新。该流水线依赖于完整训练流水线生成的部分工件,因此其组件挂载了包含已保存工件的同一持久卷。

_图 8:Kubeflow Pipelines UI 显示增量重训练流水线的 DAG_(作者供图)
复制增量数据
在本次运行开始时,流水线从 Amazon S3 复制最新的交互数据以及一小部分旧交互的重放数据集。重放部分为微调任务提供了更广泛的行为上下文,防止模型仅对最新模式过拟合。
数据预处理
此步骤将历史用户和物品特征与新的交互数据合并,然后使用最近一次完整训练作业中训练好的 NVTabular 工作流对数据进行转换。
微调模型
此步骤更新查询塔和排序器。它从上一个检查点初始化双塔模型,但冻结候选编码器,仅使查询塔参数可训练。这允许模型适应近期用户行为,同时保留现有 ANN 索引所使用的物品端嵌入。有关双塔模型冻结层的摘要,请参见 此处。
流水线还从上一个检查点初始化 DLRM 排序器,但使用较小的学习率和更少的训练轮次来训练所有参数。
训练完成后,将微调后的查询塔和 DLRM 排序器保存到现有 Triton 模型仓库中的新版本文件夹中。
升级微调模型
此步骤调用 Triton 加载新模型。Triton 在后台加载新模型的同时,继续为现有模型版本提供在线请求。一旦新模型准备就绪,即进行热切换至最新版本。

_图 9:微调后,query_tower 和 dlrm_ranker 均被升级至新版本_(作者供图)
- * *
通过 NVIDIA Triton 推理服务器处理 14 个模型的请求
模型仓库 包含两个后端的 14 个模型:Python 后端用于特征查找、特征转换和过滤;TensorFlow 后端用于查询塔和 DLRM 排序器。一个组合配置将所有这些模型连接成一个有向无环图(DAG),由 NVIDIA Triton 推理服务器执行。

_图 10:Triton 推理服务器中的请求处理示意图_(作者供图)
上下文和用户特征的准备
每个请求携带用户 ID 以及可选的设备类型和请求时间戳。若上下文缺失,context_preprocessor 将填充默认值。例如,缺失的时间戳将填充当前服务器时间,缺失的设备类型将填充 OOV 标记。上下文工作流将上下文数据转换为分类化的设备索引和四个时间特征(小时正弦/余弦、星期几正弦/余弦)。
在用户路径中,feast_user_lookup 从在线特征存储(由 ElastiCache for Valkey 支撑)中获取用户特征,然后 nvt_user_transform 使用用户工作流转换这些特征,并将其传递给查询塔(query_tower)。查询塔生成用户嵌入,faiss_retrieval 利用这些嵌入执行相似性搜索,返回 TopK 物品 ID。
处理用户冷启动
当在线特征存储中找不到用户 ID 时,feast_user_lookup 使用默认值:user_id = -1,age = 训练均值,gender = -1,top_category = -1。nvt_user_transform 将这些 user_id、gender 和 top_category 标记映射到其 OOV 索引,并将均值年龄映射为归一化值和分类化年龄桶。随后,query_tower 根据转换后的特征生成用户嵌入。尽管 faiss_retrieval 对于未知用户返回相同的人气偏置候选,但 DLRM 排序器仍可利用可用上下文个性化候选排序。
使用布隆过滤器过滤已见物品
候选物品 ID 将与 ElastiCache for Valkey 中的布隆过滤器进行比对。此步骤可消除大量候选,因此在检索阶段适度过取至关重要,以确保排序器收到足够多的候选以生成有意义的推荐列表。
过滤后的物品 ID 进入物品特征流水线,其中 feast_item_lookup 从在线特征存储中检索物品特征,nvt_item_transform 使用用户工作流转换这些特征,multimodal_embedding_lookup 返回物品的预训练 CLIP(图像)和 Sentence BERT(文本)嵌入。

图 11:RedisInsight UI 显示存储在 ElastiCache 中的布隆过滤器键(项目),每个键的 TTL 为 6 天。(作者供图)
排序与排序
_unroll_features_ 模型将用户和上下文特征进行平铺,以匹配检索候选集的大小。随后,DLRM 排序器(_dlrm_ranking_)对候选集进行打分。在 _softmax_sampling_ 中,若禁用 DIVERSITY_MODE,模型将按分数降序返回前 K 个候选;若启用,则采用基于分数的加权无放回采样,在仍优先高分项目的同时,选出多样化的前 K 个结果。最后,_item_id_decoder_ 将排序后的候选 ID(NVTabular 索引)映射回原始物品 ID,Triton 返回所选物品 ID 及其对应分数。
- * *
通过内存缓存提升物品特征查找延迟
使用 Triton 性能分析器 在检索规模为 300 的情况下进行服务器性能分析发现,_feast_item_lookup_ 消耗了 195 毫秒,约占并发数=1 时总请求延迟的 52%。在负载下,队列等待时间从并发数=1 时的 36 毫秒激增至并发数=4 时的 988 毫秒。这导致吞吐量被限制在每秒 2.9 次推理,无论并发请求数量如何增加。

图 12a:通过缓存优化特征查找延迟(作者供图)
瓶颈在于 _feast_item_lookup_ 在每次请求中都从 Feast 的在线特征存储中获取 300 个候选物品的特征。为缓解此问题,我们将 Feast 的物品特征调用替换为进程内 NumPy 数组缓存。具体而言,在 _feast_item_lookup_ 初始化时,一次性从 Feast 获取所有物品特征,并以物品 ID 为索引存储为 NumPy 数组,此后每次请求均直接从内存读取特征,而无需向在线特征存储发起网络调用。此优化使 _feast_item_lookup_ 的延迟降低了约 99.7%,端到端延迟(并发数=1)提升了 54%。同时,吞吐量(并发数=4)提升了 310%。唯一的权衡是缓存的特征仅在 Triton 重启时刷新,但对于物品属性相对静态的目录而言,这并非问题。

图 12b:内存特征缓存前后的延迟对比(作者供图)
此变更后,三个 NVTabular 转换模型——_nvt_user_transform_(72 毫秒)、_nvt_item_transform_(41 毫秒)和 _nvt_context_transform_(39 毫秒)——占剩余延迟的约 88%。进一步的模型优化将留待本项目后续版本实现。
- * *
在 EKS 上对 Triton 推理服务器进行自动扩缩容
在本项目中,Triton 推理服务器通过 Kubernetes 水平 Pod 自动扩缩容器(HPA)基于自定义指标进行自动扩缩容——该指标为过去 30 秒内每个请求在队列中的平均等待时间(毫秒)。当该延迟超过目标值时,HPA 通过增加期望的 Pod 副本数来扩缩 Triton 部署。若新 Triton Pod 因无 GPU 节点具备容量而无法调度,Karpenter 将自动供应新的 GPU 节点并将其加入集群。一旦节点就绪,Kubernetes 调度器便会将 Triton Pod 部署至该节点。新 Pod 就绪后,负载均衡器即可开始将流量路由至该 Pod。

图 13:使用 K8s HPA 和 Karpenter 对 Triton 推理服务器进行自动扩缩容(作者供图)
- * *
验证上下文推荐、布隆过滤器过滤及近实时推荐更新
为验证系统,部署期间关闭了多样性模式,以隔离其对推荐效果的影响,从而单独评估上下文类型、布隆过滤器过滤和偏好变化的作用。
验证上下文推荐
为验证上下文推荐,我测试了多种请求类型,包括仅包含用户 ID 的请求,以及结合用户 ID 与上下文特征(如设备类型和时间戳)的请求。这些测试表明,对于未知用户,推荐结果会随上下文变化。冷启动用户根据设备类型和请求时间,可能获得不同的排序物品列表。对于已有用户,上下文的影响则较弱,整体排序在不同上下文中基本保持稳定,仅输出分数有所变化。
请接受 Cookie 以访问此内容
一个展示上下文对现有用户(用户 ID = 1009)和新用户(userID = 12345678)推荐影响的演示。视频由作者提供。
验证布隆过滤器对已浏览物品的过滤
为验证布隆过滤器对已浏览物品的排除功能,我点击了“为您推荐”轮播中的若干物品。这些物品随后被布隆过滤器排除在后续推荐之外。为避免干扰用户推断偏好并影响布隆过滤器测试效果,请点击来自不同类别的物品。
在展示布隆过滤器过滤的视频中,我们观察到,如“奢华巧克力梦幻蛋糕”和“复古探险者帆布背包”等被点击物品,已被排除在用户 12345678 的下一轮推荐之外。
请接受 Cookie 以访问此内容
布隆过滤器排除先前交互物品的视频演示(视频由作者提供)。
验证近实时推荐更新
为了验证对现有用户推荐内容的近实时更新,测试首先获取用户的推荐列表,以确定用户当前的兴趣偏好。随后,用户会点击同一类别的多个商品,例如仅属于“配饰”、“家具”或“杂货”类别中的商品,然后等待约五秒让更新生效。对同一类别商品的重复交互,若该类别与用户当前的 _top_category_ 不同,则可改变系统推断的用户偏好。_top_category_ 特征表示用户在过去 24 小时内交互过的商品中占主导地位的类别,并在每次交互后重新计算。下一次请求时,模型会将来自该新表达兴趣类别的商品排名提升,并将其置于推荐列表的前列。
在展示推荐内容实时变化的视频中,我们注意到 用户 1003 的顶级推荐从“配饰”转变为“家居装饰”(及家具),这是由于其对“家具”类别商品的多次交互所致。
请接受 Cookie 以访问此内容
由用户偏好信号变化触发的实时排序变化演示(作者提供视频)
需要注意的是,_top_category_ 特征仅是对短期兴趣的粗略近似,用于演示系统实时适应用户行为的能力。为了更精准地建模短期兴趣,本项目的下一版本将用基于会话的 Transformer 编码器替代静态查询塔。
- * *
局限性与未来工作
在当前架构中,请求端上下文(如设备类型和时间戳衍生特征)仅由排序器使用。这一设计选择是为了简化召回阶段,因为在召回阶段引入上下文需要在候选生成过程中计算额外特征。然而,如果请求上下文会影响应召回的商品,则相关候选可能在排序器看到它们之前就被过滤掉。
未来的一个方向是将请求端上下文特征添加到查询塔中,使召回和排序都具备上下文感知能力。另一个方向是用会话编码器替换当前的查询塔,从而比当前基于行为特征的近似方式(即 _top_category_)更准确地捕捉短期用户行为。
- * *
总结
本文介绍了为电商场景构建的多阶段多模态推荐系统,并部署在 Amazon EKS 上。该系统结合了双塔候选召回、上下文感知的 DLRM 排序以及基于分数的多样性排序。系统利用了结构化用户与商品特征、基于商品图片和文本描述的多模态嵌入,以及上下文信息。
冷启动问题通过训练期间的特征掩码技术解决,迫使模型在用户为新用户或未知用户时,依赖学习到的 OOV 嵌入和上下文信号进行推荐。这意味着匿名用户和新用户将获得根据其设备类型和请求时间动态调整的推荐,而非静态的默认列表。布隆过滤器防止已见过的商品在重复会话中再次出现,而商品特征的内存缓存则缓解了商品特征查找阶段的延迟瓶颈。此外,通过 _top_category_ 特征展示了系统对变化行为信号的实时适应能力。
在 MLOps 方面,两个 Kubeflow 管道管理系统的生命周期:一个用于完整训练与部署,另一个用于每日对查询塔和排序器进行微调,而无需重建商品嵌入索引。Karpenter 和 Kubernetes HPA 根据请求负载自动调整计算资源。
该系统展示了生产级推荐系统的典型架构:一个以速度和召回率优化的召回阶段,结合一个以精确率优化的排序阶段,以及一个无需每次循环都全量重训练即可保持模型更新的基础设施层。完整代码请参见此仓库:MustaphaU/multistage-recommender-system-on-kubernetes
希望您喜欢本文!期待您的提问。
- * *
资源
- Mustapha Unubi Momoh,《基于 Kubernetes 的多阶段多模态推荐系统》,GitHub 仓库。可访问:https://github.com/MustaphaU/multistage-recommender-system-on-kubernetes
- Even Oldridge 和 Karl Byleen-Higley,《推荐系统,不仅仅是推荐模型》,《NVIDIA Merlin(Medium)》,2022 年 4 月。可访问:https://medium.com/nvidia-merlin/recommender-systems-not-just-recommender-models-485c161c755e
- Radek Osmulski,《使用 Merlin 探索生产级推荐系统》,《NVIDIA Merlin(Medium)》,2022 年 7 月。可访问:https://medium.com/nvidia-merlin/exploring-production-ready-recommender-systems-with-merlin-66bba65d18f2
- Jacopo Tagliabue、Hugo Bowne-Anderson、Ronay Ak、Gabriel de Souza Moreira 和 Sara Rabhi,《NVIDIA Merlin 融入 MLOps 生态系统:在云端构建生产级推荐系统流水线》,《NVIDIA Merlin(Medium)》,2023 年 2 月。可访问:https://medium.com/nvidia-merlin/nvidia-merlin-meets-the-mlops-ecosystem-building-a-production-ready-recsys-pipeline-on-cloud-1a16c156166b
- Benedikt Schifferer,《使用双塔神经网络解决 NVIDIA 邮件推荐系统的冷启动问题》,《NVIDIA Merlin(Medium)》,2023 年 1 月。可访问:https://medium.com/nvidia-merlin/solving-the-cold-start-problem-using-two-tower-neural-networks-for-nvidias-e-mail-recommender-2d5b30a071a4
- Ziyou “Eugene” Yan,《推荐与搜索的系统设计》,《eugeneyan.com》,2021 年 6 月。可访问:https://eugeneyan.com/writing/system-design-for-discovery/
- Yuan Haoran 和 Alejandro A. Hernandez,《推荐系统中的用户冷启动问题:系统性综述》,《IEEE Access》,第 11 卷,第 136958–136977 页,2023 年。可访问:https://ieeexplore.ieee.org/stamp/stamp.jsp?arnumber=10339320
- Justin Wortz 和 Justin Totten,《使用 TensorFlow Recommenders 和 Vertex AI 匹配引擎扩展深度检索》,《Google Cloud 博客》,2023 年 4 月 19 日。可访问:https://cloud.google.com/blog/products/ai-machine-learning/scaling-deep-retrieval-tensorflow-two-towers-architecture
- Sam Partee、Tyler Hutcherson 和 Nathan Stephens,《从离线到在线:使用 NVIDIA Merlin 实现实时推荐系统的特征存储》,《NVIDIA 技术博客》,2023 年 3 月 1 日。可访问:https://developer.nvidia.com/blog/offline-to-online-feature-storage-for-real-time-recommendation-systems-with-nvidia-merlin/