敞开成长之旅!这是我参与「日新计划 12 月更文应战」的第11天,点击检查活动详情
作者:
vivo – 人工智能引荐团队:何鑫、李恒、周健、黄金宝
背景
vivo 人工智能引荐算法团队在深耕事务一起,也在积极探究适用于查找/广告/引荐大规模性稀少性算法练习结构。分别探究了 tensornet/XDL/tfra 等结构及组件,这些结构组件在分布式、稀少性功用上做了扩展,能够弥补 tensorflow 在查找/广告/引荐大规模性稀少性场景缺乏,但是在通用性、易用性以及功用特色上,这些结构存在各种缺乏。
DeepRec 是阿里巴巴集团供给的针对查找、引荐、广告场景模型的练习/预测引擎,在分布式、图优化、算子、Runtime 等方面对稀少模型进行了深度功用优化,供给了丰富的高维稀少特征功用的支撑。根据 DeepRec 进行模型迭代不仅能带来更好的事务作用,一起在 Training/Inference 功用有显着的功用进步。
作为 DeepRec 最早的一批社区用户,vivo 在 DeepRec 还是内部项目时,就与 DeepRec 开发者坚持亲近的合作。通过一年积累与打磨,DeepRec 赋能 vivo 各个事务添加,vivo 也作为 DeepRec 深度用户,将事务中的需求以及运用中的问题积极回馈到 DeepRec 开源社区。
事务介绍
vivo 人工智能引荐算法组的事务包含了信息流、视频、音乐、广告等查找/广告/引荐各类事务,基本涵盖了搜广推各类型的事务。
为了支撑上述场景的算法开发上线,vivo 自研了集特征数据、模型开发、模型推理等流程于一体的引荐服务渠道。通过成熟、规范的引荐组件及服务,该渠道为 vivo 内各引荐事务(广告、信息流等)供给一站式的引荐处理计划,便于事务快速构建引荐服务及算法战略高效迭代。
稀少模型练习
3.1 稀少功用
3.1.1 痛点
在实际事务实践发现,TensorFlow 原生 Embedding Layer 存在以下问题:
1.静态 Embedding OOV 问题
在构建 Embedding Layer 的时分,TensorFlow 需求首要构建一个静态 shape[Vocab_size, Embedding size ] 的 Variable,然后运用 Lookup 的算子将特征值的 Embedding 向量查询出。在增量或者流式练习中,会呈现 OOV 的问题。
2. 静态 Embedding hash 特征抵触
为了躲避上述的 OOV 问题,一般做法是将特征值 hash 到必定的规模,但是又会引进 hash 抵触的问题,导致不同的特征值共用同一个 Embedding,会造成信息丢掉,对模型练习是有损的。
3. 静态 Embedding 内存糟蹋
为了缓解 hash 抵触,一般会设置比实在的特征值个数 N 大一到两倍的 hash 规模,而这又会强行地添加模型的体积。
- 低频特征冗余
在引进稀少特征时,呈现频次较低以及良久未呈现的特征 ID 关于模型而言是冗余的。此外,穿插特征占有了很多的存储,能够在不影响练习作用的前提下过滤掉这些特征 ID。因而,迫切需求特征筛选以及准入机制。
总的来讲,TensorFlow 的 Embedding Layer 对实在的事务场景有几个不太友爱的点,第一是可拓展性差,第二是 hash 抵触导致模型练习有损,第三是无法处理冗余的稀少特征。而 DeepRec 奇妙地处理了上述问题,首要供给了根据 Embedding Variable 的动态 Embeeding 功用和特征准入/筛选功用。
3.1.2 Embedding Variable
DeepRec 中的 EmbeddingVariable 以 HashTable 作为内部存储的基本结构,动态的创建/释放 Embedding 向量,适配了 Embedding 前向查询,反向更新等 OP,然后处理了用户的痛点。
在构建 Embedding Layer 时运用 DeepRec的Embedding Variable。运用 Embedding Variable 具有动态维度的特性,模型练习对新增的特征值无感知。此外,因为摒弃了 hash 的操作,练习的模型也是无损的,一起模型的体积也会缩小。
3.1.3 特征准入/筛选
- 特征准入:
DeepRec 供给了根据 BloomFilter 和 Counter 两种战略的准入机制。特征准入能够防止模型稀少特征的快速添加,回绝低频特征进入模型,影响模型收敛作用。
- 特征筛选:
DeepRec 支撑两种筛选战略,一种是依照 global step 进行筛选,一种是依照 L2 weight 进行筛选,它们将不符合规则的特征从模型参数中除掉,确保特征的有效性。
3.1.4 收益
- 静态 Embedding 升级到动态 Embedding
运用 DeepRec 的动态 Eembedding 替换 TensorFlow 的静态 Embedding 后,确保所有特征 Embedding 无抵触,离线auc进步 0.5%,线上点击率进步 1.2%,一起模型体积缩小 20%。
- ID 特征的运用
在运用 TensorFlow 时,vivo 测验过对 ID 特征进行 hash 处理输入模型,实验标明这种操作比照基线具有负收益。这是因为 ID 特征过于稀少,一起 ID 具有仅有指示性,hash 处理会带来很多的 Embedding 抵触。根据动态 Embedding,运用 ID 特征离线 auc 进步 0.4%,线上点击率进步 1%;一起合作 global step 特征筛选,离线 auc 进步 0.2%,线上点击率进步 0.5%。
3.2 IO优化
3.2.1 痛点
目前 vivo 内部运用的是 TFRecord 数据格局存储练习数据,这种存储格局存在以下缺点:
1. 占用存储空间大
因为 TFRecord 采用 protocol buffer 结构化数据存储,存储不行紧凑,占用空间比较大,在练习时 I/O 开支也非常大。vivo 测验过运用 prebatch 的方法存储 TFRecord 以节约存储空间,但是此计划解析相对杂乱,I/O 开支进一步加剧。
2. 非明文存储
因为 TFRecord 以二进制格局存储,无法直接检查数据内容,存在解析困难、不便进行数据剖析的问题。
3.2.2 Parquet Dataset
Parquet 是一种列式存储的数据格局,能够节约存储资源,加快数据读取速度。DeepRec 的 Parquet Dataset 支撑读取 Parquet 文件,开箱即用,无需额定安装第三库,运用简略便利。一起,Parquet Dataset 能够加快数据读取速度,进步模型练习的 I/O 功用。
3.2.3 收益
vivo 内部测验运用 Parquet Dataset 来替换现有 TFRecord,进步练习速度 30%,削减样本存储本钱 38%,下降带宽本钱。一起,vivo 内部支撑 hive 查询 Parquet 文件,算法工程师能够高效快捷地剖析样本数据。
高功用推理结构
在事务逐步开展过程中,广告召回量添加 3.5 倍,一起方针预估数添加两倍,推理核算杂乱度添加,超时率超越 5%,严重影响线上服务可用性以及事务方针。因而,vivo 测验探究升级改造现有推理服务,确保事务可持续开展。vivo 借助 DeepRec 开源的诸多推理优化功用,在 CPU 推理改造以及 GPU 推理升级方面进行探究,并取得必定收益。
4.1 CPU 推理优化
vivo 直接运用 TensorFlow 供给的 C++ 接口调用 Session::Run,无法完结多 Session 并发处理 Request,导致单 Session 无法完结 CPU 的有效运用。假如通过多 Instance 方法(多进程),无法共享底层的 Variable,导致很多运用内存,而且每个 Instance 各自加载一遍模型,严重影响资源的运用率和模型加载功率。为了进步 CPU 运用率,也测验多组 Session Intra/Inter,均会导致 latency升高,服务可用性下降。
根据 ShareNothing 架构的 SessionGroup
DeepRec 供给的 SessionGroup 能够有效地处理上述问题,其基本架构如下图所示:
SessionGroup 可配置一组 Session,而且通过 Round Robin (支撑用户自定义战略)方法将用户恳求分发到某一个 Session。SessionGroup 对不同 Session 之间的资源进行隔离,每个 Session 拥有私有的线程池,而且支撑每个线程池绑定底层的 CPU Core(numa-aware),能够最大程度地防止共享资源导致的锁抵触开支。SessionGroup 中仅有共享的资源是 Variable,所有 Session 共享底层的 Variable,而且模型加载只需求加载一次。
在运用 SessionGroup 功用后,CPU 运用率低的问题显着得到缓解,在确保 latency 的前提下极大进步 QPS,单机 QPS 进步高达 80%,单机 CPU 运用率进步 75%。
4.2 GPU 推理优化
通过 SessionGroup 的优化,尽管 CPU 推理功用得到改善,但是超时率仍旧无法得到缓解。因为以下几点原因,vivo 测验探究 GPU 推理来优化线上功用。
-
多方针模型方针塔数较多
-
模型中运用 Attention、LayerNorm、GateNet 等杂乱结构
-
特征多,存在很多稀少特征
4.2.1 Device Placement Optimization
一般,关于稀少特征的处理一般是将其 Embedding 化,因为模型中存在很多的稀少特征,因而 vivo 的广告模型运用很多的 Embedding 算子。从推理的 timeline 能够看出,Embedding 算子涣散在 timeline 的各个阶段,导致很多的 GPU kernel launch 以及数据复制,因而图核算非常耗时。
Device Placement Optimization 完全将 Embedding Layer placed 到 CPU 上,处理Embedding layer 内部存在的 CPU 和 GPU 之间很多数据复制问题。
Device Placement Optimization 功用优化显着,CPU 算子(首要是 Embedding Layer)的核算会集在 timeline 的最初步,之后 GPU 首要负责网络层的核算。相较于 CPU 推理,Device Placement Optimization P99 下降 35%。
4.2.2 CUDA Multi-Stream 功用
在推理过程中,vivo 发现 GPU 运用率低,GPU 算力糟蹋。DeepRec 支撑用户运用 multi-stream 功用,多 stream 并发核算,进步 GPU 运用率。多线程并发 launch kernel 时,存在较大的锁开支,极大影响了 kernel launch 的功率,这儿的锁与 CUDA Driver 中 Context 相关。因而能够通过运用 MPS/Multi-context 来防止 launch 过程中锁开支,然后进一步进步 GPU 有效运用率。
此外,模型中存在很多的 H2D 以及 D2H 的数据复制,在原生代码中,核算 stream 和复制 stream 是独立的,这会导致 stream 之间存在很多同步开支,一起关于在 Recv 算子之后的核算算子,必须比及 MemCopy 完结之后才干被 launch 履行,MemCopy 和 launch 难以 overlap 履行。根据以上问题,NV 专家核算团队的同学在 multi-stream 功用基础上进一步优化,开发了 MergeStream 功用,答应 MemCopy 和核算运用相同的 stream,然后削减上述的同步开支以及答应 Recv 之后核算算子 launch 开支被 overlap。
vivo 在线上推理服务中运用了 multi-stream 功用,P99 下降 18%。更进一步地,在运用 merge stream 功用后,P99 下降 11%。
4.2.3 编译优化-BladeDISC
BladeDISC 是阿里集团自主研发的、原生支撑存在动态尺度模型的深度学习编译器。DeepRec 中集成了 BladeDISC,通过运用 BladeDISC 内置的 aStitch 大尺度算子交融技术关于存在较多访存密集型算子的模型有显著的作用。运用 BladeDISC 对模型进行编译优化,推理功用得到大幅度进步。
BladeDISC 将很多访存密集型算子编译成一个大的交融算子,能够大大削减结构调度和 kernel launch 的开支。区别于其他深度学习编译器的是,BladeDISC 还会通过优化 GPU 不同层次存储(特别是 SharedMemory)的运用来进步了访存操作和 Op 间数据交换的功用。图中能够看到,绿色是 Blade DISC 优化兼并的算子代替了原图中很多的算子。
另外,因为线上模型比较杂乱,为了进一步削减编译耗时、进步部署功率,vivo 启用了 BladeDISC 的编译缓存功用。敞开此功用时,BladeDISC 仅会在新旧版本模型的 Graph 结构发生改变时触发编译,假如新旧模型仅有权重变更则复用之前的编译成果。通过验证,编译缓存在确保正确性的一起,简直掩盖了编译模型的开支,模型更新速度与之前简直相同。在运用 BladeDISC 功用后,线上服务 P99 下降 21%。
4.2.4 总结
DeepRec 供给很多的处理计划能够帮助用户快速施行 GPU 推理。通过一系列优化,相较于 CPU 推理,GPU 推理 P99 下降 50%,GPU 运用率平均在 60% 以上。此外,线上一张英伟达 T4 显卡的推理功用超越两台 CPU 机器,节约了很多的机器资源,机器本钱下降 60%。
未来规划
根据 CPU 的分布式异步练习存在两个问题:一是异步练习会损失练习精度,模型难以收敛到最佳;二是跟着模型结构逐步杂乱,练习功用会急剧下降。未来,vivo 计划测验根据 GPU 的同步练习来加快杂乱模型练习。DeepRec 支撑两种 GPU 同步结构——SparseOperationKit(SOK)和HybridBackend。后续 vivo 将测验这两种 GPU 同步练习来加快模型练习。
DeepRec开源地址:github.com/alibaba/Dee…