发布人:戎海栋(腾讯微信看一看团队)、丁辰(阿里巴巴 PAI 团队)

背景与现状

推荐系统是机器学习的重要应用领域,能够根据用户偏好自动推送相关内容,比如展示商品,投放广告,推荐视频、新闻等多媒体内容等。

在推荐系统领域,Embedding 已成为处理 ID 类稀疏特征的常用手段,作为一种“函数映射”,Embedding 通常将高维稀疏特征映射为低维稠密向量,再进行模型端到端训练。

在 TensorFlow 框架中,全部以稠密 Tensor 为基本数据单元对数据进行计算、存储以及传输。TensorFlow 也基于稠密 Tensor 提供了静态 Embedding 机制,用于存储 Embedding 的 Tensor shape 固定为 [vocabulary_size, embedding_dimension]vocabulary_size 通常由 ID 空间决定,需要将其 Hash 映射到 vocabulary_size 范围内,在大规模推荐场景下,静态 Embedding 机制存在以下弊端:

  • 特征冲

特征 IDs 通常为字符串类型且规模庞大,这会导致初始 vocabulary_size 难以估计,如果 vocabulary_size 估计过小,则导致 Hash 冲突率增加,即不同特征可能查找到相同的 Embedding,造成特征冲突,影响模型效果:

  • 内存浪费

如果 vocabulary_size 估计过大,则导致 Variable 会为大量永远不会被查找的 Embedding 预留资源,即内存浪费

  • 在线学习不友好

在线学习场景中,随着训练持续进行,新的特征不断增加,老的特征要不断淘汰,这与稠密 Tensor 的形状必须事先确定相矛盾:特征不能随训练任意增加,通过算法淘汰某些不重要的特征时,也无法单独释放该特征 embedding 占用的内存资源

  • 低效的 IO

推荐模型的更新过程具有稀疏性,即一段时间内训练更新的参数只占总量很少的一部分,但静态 Embedding 机制下,模型存取需要处理整个稠密 Tensor,这会带来极大的 IO 开销,难以支持超大模型训练

过去几年,工业界针对上述问题,在 TensorFlow 支持大规模推荐模型方面进行了大量探索,今天,我们很荣幸地推出 TensorFlow Recommenders-Addons (TFRA),这款开源 TensorFlow 软件包集成了相关优秀成果,使 TensorFlow 能够以更原生、更高效的方式支持 ID 类推荐模型的训练。相关成果已经过多家互联网公司真实商业场景的检验,实践证明,这些努力和进展大幅改善了这些企业实际业务的推荐效果,带来了真实的商业收益。同时我们也通过 SIG-Recommenders 维护并回馈给业界。

  • TensorFlow Recommenders-Addons (TFRA)

    https://github.com/tensorflow/recommenders-addons

TFRA 目前包含两个独立组件,其中一个是 DynamicEmbedding 组件,一个是 EmbeddingVariable 组件,下面我们分别介绍这两个组件的原理和使用:

tfra.dynamic_embedding

(DynamicEmbedding组件)

tfra.dynamic_embedding 组件基于腾讯微信看一看团队戎海栋、张亚霏、程川等人 2020 年提出的稀疏域隔离方案实现,其设计目标如下:

  • 使 TensorFlow 可以训练 Keys-Values 数据结构(Hash Table)

  • 与 TensorFlow 原有功能有更好的兼容性,不改变算法工程师建模习惯

  • 稀疏域隔离方案

    https://github.com/tensorflow/recommenders-addons/blob/master/rfcs/20200424-sparse-domain-isolation.md

该组件具有如下优点:

  • 有效避免 Hash 冲突问题,保证特征无损,能有效提升模型效果

  • 内存动态伸缩,训练更省资源

  • 复用 TensorFlow 所有优化器和初始化器

  • API 与原 TF 的

    tf.nn.embedding_lookup 等 API 同名且行为一致,学习成本低

2.1 实现原理及 API 设计

2.1.1 分层表达稀疏参数

推荐模型的稀疏参数通常存于 HashTable 中,但是 TensorFlow 优化器是为训练稠密 Tensor 而设计的,无法直接训练 HashTable 数据,幸运的是,我们观察到推荐类模型的训练过程具有稀疏性,即:每个迭代步所训练的参数仅是整个模型极少的一部分,因此我们借助 TensorFlow ResourceVariable 机制使用稠密 Tensor 表达“迭代参数”:

类似于文件系统的 memory cache 机制分两层表达稀疏参数

  • 用原生 tf.variable/tf.tensor 表达达迭代参数 (iteration weigths)

  • 用 tf.lookup.MutableHashTable 保存全量参数(full weights)

为了保持训练的连贯性,我们还需要做的是前向计算前从全量参数中读取本次迭代用到的 embedding 参数,反向计算后把训练好的迭代参数写回全量参数。

2.1.2 迭代参数继承自 ResourceVariable

为了保证与 TensorFlow 高度兼容性,我们需要迭代参数是个可被 TensorFlow 原生优化器训练的 ResourceVariable,同时也需要扩展一些方法以便支持稀疏训练有关的能力——为此我们定义了 TrainableWrapper 类,它是 ResourceVariable 的子类:

  • 扩展了 prefetch 和 update 方法实现对  HashTable 读写操作

  • 持有 HashTable(de.Variable) 和特征 ID(ids) 对象以支持前向读取反向更新

收益:原生优化器可以直接训练 TrainableWrapper

2.1.3 embedding_lookup 同名 API

embedding_lookup API 是迭代参数与全量参数间的桥梁

embedding lookup 是 Embedding 技术的关键语义,它通过查找操作将每个迭代步需要处理的特征权重从海量稀疏参数中提取出来,我们设计了和 TensorFlow 静态 Embedding 机制同名的 API:embedding_lookup,它是整个 pipeline 的信息汇聚点,我们巧妙的利用这个 API 创建了 TrainableWrapper——它具有两个关键作用:

  • embedding_lookup

    https://github.com/tensorflow/recommenders-addons/blob/master/docs/api_docs/dynamic_embedding/embedding_lookup.md

  • 维护稀疏参数 HashTable(params) 和 IDs(样本特征值)的关系

  • 从 HashTable 查找中最新稀疏参数,并更新到其持有的内存资源中

这样做的好处是 API 设计更加自然,同时 API 语义和行为都和 TensorFlow 静态 Embedding 同名 API 相同,有效降低算法工程师的学习成本。

2.1.4 API 概览

相关 API 均定义在 tfra.dynamic_embedding 命名空间下(相关链接见文末):

  • get_variable(...):定义一个动态 Embedding 的Variable,语义与tf.get_variable相同

  • embedding_lookup(...):动态版本的 tf.nn.embedding_lookup,参数行为相同

  • embedding_lookup_sparse(...):动态版本的 tf.nn.embedding_lookup_sparse

  • safe_embedding_lookup_sparse(...):动态版本的 tf.nn.safe_embedding_lookup_sparse

  • DynamicEmbeddingOptimizer(..):原生优化器修饰器,使他们支持动态 Embedding 训练

完整定义请访问:tfra.dynamic_embedding API Docs

  • tfra.dynamic_embedding API Docs

    https://github.com/tensorflow/recommenders-addons/blob/master/docs/api_docs/dynamic_embedding.md

2.2 使用示例

1. 安装 TFRA 软件包

pip install tensorflow-recommenders-addons

2. 导入 TFRA 的 dynamic_embedding 组件

import tensorflow as tf
from tensorflow_recommenders_addons import dynamic_embedding as de

3. 创建一个动态 Embedding 变量,其中 initializer 可复用 TensorFlow 全部原生初始化器

w = de.get_variable(name="dynamic_embeddings",devices=["/job:ps/replica:0/task:0/CPU:0","/job:ps/replica:0/task:1/CPU:0"],initializer=tf.random_normal_initializer(0, 0.005),dim=1,init_size=10000000)

4. 调用 embedding_lookup API 得到 embedding(此API 与 TF 同名原生 APIs 有相同入参和行为,sparse 版本的 embedding_lookup_sparse 和 safe_embedding_lookup_sparse API 说明可参考 API docs):

  • API docs

    https://github.com/tensorflow/recommenders-addons/blob/master/docs/api_docs/dynamic_embedding.md

embedding = de.embedding_lookup(params=w, ids=x, name="sparse-weights")

5. 使用 TensorFlow 任意优化器训练:

optimizer = de.DynamicEmbeddingOptimizer(tf.compat.v1.train.AdamOptimizer(0.001))
train_op = optimizer.minimize(loss)

6. 训练和模型保存无需额外 API

saver = tf.compat.v1.train.Saver()
with tf.compat.v1.Session() as sess:for i in range(epoch):sess.run(train_op)saver.save(sess, 'checkpoint/model')

tfra.embedding_variable

(EmbeddingVariable组件)

EmbeddingVariable 组件是基于阿里巴巴 PAI 团队 2019 年向 TensorFlow 社区提出 EmbeddingVariable 方案实现。

  • EmbeddingVariable

https://docs.google.com/document/d/1odez6-69YH-eFcp8rKndDHTNGxZgdFFRJufsW94_gl4/edit#

3.1 设计目标

主要目标是在 TensorFlow 框架之下,支持对稀疏参数存储,访问以及更新。

包含以下特性:

1. 动态可伸缩的 EmbeddingVariable (以下简称 EV),实现特征的动态新增与淘汰

2. 增量 Checkpoint 功能,便于稀疏参数在线训练并实时线上加载模型

3. 支持EV的查询以及相关 Optimizer 的参数更新

4. API 设计兼容原生 TensorFlow,用户侵入性小

5. 支持 Graph Mode 和 Eager Mode

3.2 设计原理

3.2.1 整体设计

使用 HashTable 作为底层数据结构进行存储稀疏参数,目前开源版本使用的是 Google 的 DenseHashMap。封装为 TensorFlow 的 Resource,由 TF 的 ResourceMgr 统一进行管理。Resource 封装在各个与 EV 相关 Operation 中,对 Resource 进行操作(稀疏参数的查询,更新,保存,恢复等)。用户可以直接调用 Operation 或调用封装的 Python API。

3.2.2 底层数据结构

EV 在底层数据结构使用了 HashMap + Tensor 的结构,HashMap 负责管理 KV 元数据,Tensor 存储 Embedding 及版本信息,其中 Tensor 中 version 存储最近一次更新 global_step 数,以便在特征淘汰的时候使用该信息。

3.2.3 算子实现与 API

围绕 Embedding 的语义,我们实现了对稀疏参数的查询、更新等算子,支持 Graph 和 Eager 模式

EVHandleOp

InitializeEVOp

EVIsInitializedOp

EVShapeOp

EVGatherOp

EVSparseApply{GradientDescent, Adagrad, Adam}

EVImport

EVExport

API 主要分为 EV 变量创建以及 Optimizer

tfra.embedding_variable.EmbeddingVariable(name, embedding_dim, ...) 其他参数同 tf.Variable

tfra.embedding_variable.GradientDescentOptimizer(...) 参数同 TensorFlow

tfra.embedding_variable.AdagradOptimizer(...) 参数同 TensorFlow

tfra.embedding_variable.AdamOptimizer(...) 参数同 TensorFlow

3.2.4 模型保存与恢复

我们采用全量+增量的方式保存稀疏模型

1. 全量模型

通过 EVImport/EVExport 两个 Op 对 EV 进行保存与恢复,自动在tf.train.Saver 中完成构图。

2. 增量模型

稀疏参数在训练过程中往往具有局部性特点,参数更新数量占全部参数比重很小,我们在增量模型保存时候只保存相对上一次的增量模型,这样节省了 I/O,而且使得部署增量模型更加快速,适合在线学习的场景。

具体设计为,在每次参数更新的时候记录更改的参数,统计一定间隔时间内参数更改,最后再调用参数保存。逻辑均通过 Operation在Graph 中表达,并且 checkpoint 数据格式兼容 TensorFlow。

3.2.5 使用示例

使用 HashTable 作为底层数据结构进行存储稀疏参数,目前开源版本使用的是 Google 的 DenseHashMap。封装为 TensorFlow 的 Resource,由 TF 的 ResourceMgr 统一进行管理。Resource 封装在各个与 EV 相关 Operation 中,对 Resource 进行操作(稀疏参数的查询,更新,保存,恢复等)。用户可以直接调用 Operation 或调用封装的 Python API。

1. 加载 TensorFlow 及 TFRA 包

import tensorflow as tf
import tensorflow_recommenders_addons as tfra

2. 创建 EmbeddingVariable 稀疏参数

embedding_var = tfra.embedding_variable.EmbeddingVariable(name = "embedding_var",embedding_dim = 16,initializer = tf.keras.initializers.RandomNormal(-1, 1))

3. 兼容原生 TensorFlow API 的稀疏参数查询

ids = ...
embedding_val = tf.nn.embedding_lookup(params = embedding_var,ids = ids)

4. 计算模型损失函数

loss = …

5. 创建支持普通 Variable 以及 EV 的优化器

optimizer = tfra.embedding_variable.AdamOptimizer(learning_rate=0.001)
train_op = optimizer.minimize(loss)

6. 创建 Saver

saver = tf.train.Saver()

7. 在 Graph Mode 下 迭代训练并保存模型

with tf.compat.v1.Session() as sess:for i in range(epoch):loss_t, _ = sess.run([loss, train_op])print("epoch:", i, "loss:" loss_t)saver.save(sess, "checkpoint/model")

社区分享

我们 2021 年 3 月 25 日在中文社区已经进行了一次社区分享,相关 ppt 和视频大家可以在此处找到(提取码: pqpt)

  • 此处

    https://pan.baidu.com/s/1bDLMzYoS4sDw_JpS_hdnMQ

未来规划

围绕稀疏参数在业务场景中还有很多功能有待完善,我们也将陆续开源 HashtableOnGPU、常用算子的 GPU 版本、特征过滤 API、AdaptiveEmbedding、Frequency Awareness Embedding 等功能。

TensorFlow Recommenders-Addons 现已在 GitHub  上开源,我们的目标是让其不断发展,能够灵活地进行学术研究以及工业应用,并以高度可扩展的方式构建全网推荐系统。

总结

我们希望此文能让您对 TensorFlow Recommenders Addons 有所了解。更多信息,请查看我们的教程或 API 参考。我们已经成立 TensorFlow SIG Recommenders 兴趣小组,一同推动基于 TensorFlow  的开源大规模推荐系统的发展,请考虑贡献您的一份力量!欢迎大家就嵌入向量学习和分布式训练与应用等主题开展合作和做出贡献。

  • 教程

https://github.com/tensorflow/recommenders-addons/tree/master/docs/tutorials

  • API 参考

https://github.com/tensorflow/recommenders-addons/tree/master/docs/api_docs

  • 贡献您的一份力量

    https://github.com/tensorflow/recommenders-addons

  • 加入SIG Recommenders邮件组

    https://groups.google.com/a/tensorflow.org/g/recommenders

致谢

TensorFlow Recommenders-Addons 是 SIG Recommenders-Addons 人员共同努力的成果。我们要感谢如下核心贡献者:

  • 腾讯的戎海栋、程川、李凡、范桂峰、张亚霏

  • 阿里巴巴 PAI 团队的丁辰,欧阳晋,刘童璇,李永

  • 唯品会的王东新

同时我们还要感谢 TensorFlow 团队成员:

  • 李双峰、魏巍、Thea Lamkin 和 Joana  Carrasqueira‎ 在社区工作上的推动和支持

  • 周玥枫、谭振宇的技术建议和方案评审

特别说明:此项工作中 dynamic_embedding 组件来自腾讯云帆 Oteam 相关成果。

TFRA 已经在生产环境中部署,并给相关企业带来商业收益,近期会有续篇来分享这些真实案例,敬请关注!

如果您想详细了解 本文讨论 的相关内容,请参阅以下文档。这些文档深入探讨了这篇文章中提及的许多主题:

  • get_variable(...)
    https://github.com/tensorflow/recommenders-addons/blob/master/docs/api_docs/dynamic_embedding/get_variable.md

  • embedding_lookup(...)

    https://github.com/tensorflow/recommenders-addons/blob/master/docs/api_docs/dynamic_embedding/embedding_lookup.md

  • tf.nn.embedding_lookup
    https://tensorflow.google.cn/api_docs/python/tf/nn/embedding_lookup

  • embedding_lookup_sparse(...)
    https://github.com/tensorflow/recommenders-addons/blob/master/docs/api_docs/dynamic_embedding/embedding_lookup_sparse.md

  • tf.nn.embedding_lookup_sparse
    https://tensorflow.google.cn/api_docs/python/tf/nn/embedding_lookup_sparse

  • safe_embedding_lookup_sparse(...)
    https://github.com/tensorflow/recommenders-addons/blob/master/docs/api_docs/dynamic_embedding/safe_embedding_lookup_sparse.md

  • tf.nn.safe_embedding_lookup_sparse
    https://tensorflow.google.cn/api_docs/python/tf/nn/safe_embedding_lookup_sparse

  • DynamicEmbeddingOptimizer(..)
    https://github.com/tensorflow/recommenders-addons/blob/master/docs/api_docs/dynamic_embedding/DynamicEmbeddingOptimizer.md

登陆官网了解更多 TensorFlow 搭建推荐系统内容,可登录 B 站 Google 中国 TensorFlow 频道观看《使用 TensorFlow 搭建推荐系统系列(全八讲)》视频,也可关注 TensorFlow 官方公众号获取更多资讯。

社区分享|TensorFlow Recommenders-Addons 开源啦!相关推荐

  1. 【社区分享】专注移动端机器学习交流,TensorFlow Lite 中文兴趣小组招募中!

    移动端机器学习的交流平台,TensorFlow Lite 的中文兴趣小组来啦!不论您是刚刚接触 TensorFlow Lite 的新手,或是已经在使用 TensorFlow Lite 的开发者,还是想 ...

  2. 开源社区那些事|社区分享

    1.举个例子 大家经常看到开源社区这四个字,什么是开源社区呢?咱们先看个例子. 一个程序员 A,写了一个简单的计算器,支持加减乘除四个功能,然后公开到网上了,类似一个在线文档,可以协同编辑,他就成了第 ...

  3. 白鹭引擎拉伸高度_答疑汇总|白鹭引擎架构师开源中国社区分享微信小游戏开发技巧...

    原标题:答疑汇总|白鹭引擎架构师开源中国社区分享微信小游戏开发技巧 1月31日-2月6日,开源中国社区邀请白鹭引擎首席架构师王泽以"微信小游戏开发技巧分享"为主题,为广大开发者带来 ...

  4. 社区分享|JumpServer引领我走向开源天地

    编者注:以下内容基于山东青岛的JumpServer社区用户Jonny·J的社区分享整理而成. "接触到JumpServer之后,我从一个开源受益者逐渐成长为开源的贡献者.其实我们每个人都可以 ...

  5. 基于代码、社区,两步成为开源赢家!

    作者 | Glenn Solomon 译者 | 香槟超新星,责编 | 郑丽媛 封图 | CSDN 下载自视觉中国 出品 | CSDN(ID:CSDNnews) 以下为译文: 在下一个数万亿级别的企业软 ...

  6. 计算机视觉 开源_年轻的计算机科学家分享了她的开源故事

    计算机视觉 开源 确切地说,我使用开源已有七年了. 这段时间似乎并不长,但是当您16岁时,这几乎是您生命的一半. 我的开源故事是发现,教育和指导机会. 我非常幸运. 我在圣诞节假期从五年级开始使用开源 ...

  7. 分享社交平台功能开源_需要考虑的3个开源社交平台

    分享社交平台功能开源 现代社交媒体平台被设计为令人着迷的原因并不奇怪:我们咨询的越多,他们所需要的数据就越多,从而使它们变得更聪明,更大,更强大. 在这些平台上,全球范围内的巨大兴趣创造了注意力经济, ...

  8. 社区分享 | 从零开始学习 TinyML(二)

    我们在上周的社区分享栏目中介绍了 社区分享 | 从零开始学习 TinyML(一),本周我们将继续学习. Hello World - 梦开始的地方(中) 在前面的准备工作中,我们完成了模型训练,并且将模 ...

  9. 社区分享|货拉拉通过JumpServer纳管大规模云上资产

    编者注:在2022年7月9日举办的"2022 JumpServer开源堡垒机城市遇见· 深圳站"活动中,深圳依时货拉拉科技有限公司核心基础设施部资深运维工程师李享海分享了题为< ...

最新文章

  1. 【C#串口编程计划】C#串口协议解析 -- 文本数据
  2. linux kernel 内存管理 感想总结(未完待续)
  3. J2Cache 中使用 Lettuce 替代 Jedis 管理 Redis 连接
  4. 李春雷 | 夜宿棚花村
  5. 响应文件是不是标书_标书的编制
  6. 使用 docker 搭建 nginx+php-fpm 环境 (两个独立镜像)
  7. 华为手机连接电脑用什么软件_屏幕镜像怎么连接电脑?使用这款软件,轻松投屏苹果手机到电脑...
  8. matlab求方差和标准差
  9. Unity字体展示下载
  10. windows下mysql高可用_[@小川游鱼][¥20]Windows平台MySQL高可用方案-问答-阿里云开发者社区-阿里云...
  11. 【网页设计】基于HTML+CSS+JavaScript制作美食网站舌尖上的美食
  12. css实现径向和线性渐变,CSS3的渐变属性 线性渐变 径向渐变 重复线性渐变和径向渐变...
  13. Excel 隔行插入行V2022.7(支持win11,支持Office 和WPS)
  14. linux 路由 pppoe ipv6,ubuntu PPPoE v6 Server配置
  15. 用html5 Canvas制作一个简单的游戏 英雄抓小怪物(上)
  16. ABP+AdminLTE+Bootstrap Table权限管理系统第五节--WBEAPI及SwaggerUI
  17. 电子器件系列十七:单稳态触发器
  18. 1279 红绿灯路口
  19. 纯静态网页限制vip普通会员浏览观看视频文章内容次数苹果cms为例
  20. ST股福音:涨停潮开始! 最全ST摘帽股汇总!

热门文章

  1. gitlab-ci配置详解(一)
  2. 无线物联网技术,在智能门禁系统的应用
  3. python下载图片插入excel_Python向Excel中插入图片的简单实现方法
  4. 超级强大的SVG SMIL animation动画详解
  5. android 对话框 美化,Android修改Dialog样式
  6. android 图片占用内存的计算
  7. 冯诺依曼 图灵计算机结构,冯诺依曼与图灵
  8. mysql log-slave-update_mysql数据库log-slave-updates 参数解释
  9. 什么是Mixin?带你了解Vue中的Mixin混入
  10. Citrix 服务器虚拟化之二十一 桌面虚拟化之部署Provisioning Services