展心展力 metaapp:基于 DeepRec 的稀疏模型训练实践

本文涉及的产品
交互式建模 PAI-DSW,5000CU*H 3个月
简介: 针对稀疏模型在分布式、图优化、算子、Runtime 等方面进行了深度的性能优化,并且完全开源。为metaapp取得了显著的性能提升和成本下降。

作者

metaapp-推荐广告研发部:臧若舟,朱越,司灵通

1 背景

推荐场景大模型在国内的使用很早,早在 10 年前甚至更早,百度已经用上了自研的大规模分布式的 parameter server 系统结合上游自研的 worker 来实现 TB 级别的万亿参数的稀疏模型。后来,各家平台也陆续基于这种方案,开发了自己的分布式训练系统,普遍特点是大量使用 id embedding,因此参数量巨大,模型大小也非常夸张。当然,随着开源训练工具 TensorFlow/Pytorch 的流行,使用 TensorFlow/Pytorch 作为 worker,结合自研 ps 的方案也十分流行。究其原因,以 TensorFlow 为例,虽然内置了分布式训练系统,但是对于大规模 id embedding 的支持却非常糟糕,无法作为完整的平台使用。而使用 TensorFlow+ 自研 ps 的方案也存在不少问题,比如自研 ps 一般对于特征输入都有特定的要求、二次开发成本比较高等。

一个典型的分布式 worker-ps 架构

2 业务介绍

metaapp- 推荐广告研发部,主要负责 metaapp 拳头产品 233 乐园的首页信息流的推荐和广告系统,是比较传统的推广搜组。我们在 2020 年之前也是采用了 TensorFlow+ 自研分布式 ps 的方案,模型大小在接近 TB 级别(业务体量较小),整个方案的迭代和维护成本都比较高。

在这种背景下,经过多方考量,阿里云机器学习平台 PAI 开源的 DeepRec(脱胎于 PAI-TF),作为支持了淘宝搜索、猜你喜欢、定向、直通车等核心业务的训练平台,直接基于 TensorFlow 做二次开发,针对稀疏模型在分布式、图优化、算子、Runtime 等方面进行了深度的性能优化,并且完全开源。

而因为我们公司本身跟阿里云有着深度的合作,阿里云也主动介绍了当时还是内部项目的 DeepRec 给我们尝试。在近 2 年的工作后,DeepRec 已经全量用于我们的模型训练和线上 inference,并且取得了显著的性能提升和成本下降。

3 稀疏模型训练

3.1 EmbeddingVariable 多级存储

由于模型参数量大,一些特征的 embedding 大小达到了接近 TB 级别,完全基于内存存储对于成本的要求过高,因此自然而然就会想到多级存储:将最热的 embedding 放在显存或者内存里,其余的可以分级放在 PMEM、SSD 等成本较低的存储介质中。而 DeepRec 中 提供了基于 EmbeddingVariable 的 Embedding 多级存储功能。DeepRec 目前对于 embedding 存放在各种存储介质的支持已经相当完善。

下面介绍下我们团队升级 DeepRec 在存储这一块的过程和经验:

3.1.1 compaction 的性能问题

我们原本基于自研的分布式 parameter server,而当时 PMEM 类的存储介质还不普及,因此我们选择了比较高性能的 SSD 作为多级存储介质。于是我们自然而然采用了类 leveldb(rocksdb)的方案作为 SSD 存储方案。但这种方案在模型训练时,由于参数不断增加和更新,后台会进行频繁的 compaction,此时会有严重的写放大问题导致 ps 的读取时间大大延长,从而导致模型训练的瓶颈几乎都在 ps 侧。ps:据说 rocksdb 在 2022 年底的 7.5.3 版本大幅改进了 compaction 的性能,在后台 compaction 时几乎不会影响读取的性能。

3.1.2 DeepRec 的方案

而在早期我们试用 DeepRec 时,DeepRec 的 EmbeddingVariable 对于 SSD 存储的方案同样是基于 leveldb,因此同样遇到了跟我们自研的方案类似的问题。后续我们将此问题的测试结果反馈给了 DeepRec 相关的同学,他们基于此后续推出了基于 SSDHASH 的存储方案,大大提升了 compaction 时的读取性能,因此模型训练基于不再受困于 ps 的读取性能问题。后续又进一步了基于 SSDHASH 的同步和异步两种 compaction 的方式。使用同步 compaction 时,向 SSD 写入数据和 compaction 将会使用同一个线程,异步时则各使用一个线程。这里也推荐大家使用这种方案。

3.1.3 压缩模型大小

进一步的,如果能把模型大小控制在数十 GB,那 ps 的性能就可以进一步提升了。因为采用 DeepRec,自定义各种压缩方式的算子变得非常轻松。我们调研并实现了了多篇 embedding 压缩方向的 paper,最后采用了 binary code 的方式实现了 embedding 的 multihash 方案,可以自由控制 embedding 的大小。我们尝试在最大的特征 uid embedding 上使用了 multihash,把模型大小从 800GB 降低到 40GB 以下,auc 的损失仅在千分之三左右,线上点击率下降了 1.5%;进一步的,我们通过优化序列推荐模型,更好的通过序列特征建模了用户的个性化,可以发现在序列模型的基础上把 uid embedding 换成 multihash 的方案,对于线上点击率的影响仅有 0.3% 左右,因此可以放心全量 multihash 方案。我们也把基于 multihash 的 embedding variable 算子以 pr 的形式提交给了 DeepRec。

3.2 基于 GPU 的分布式训练

在解决了 ps 的性能瓶颈后,模型训练的速度就和模型 Tensor 计算的算力近似线性相关了。而近几年随着序列模型的发展,搜广推的矩阵计算复杂度也在显著提升。此时使用 gpu+ 大 batch size 来代替 cpu 作为 worker 的方案,无论在性能还是成本控制上都有巨大的优势。而阿里云机器学习平台 PAI 开源的 HybridBackend 平台就支持了基于 GPU 的分布式训练方案,并且深度支持了 DeepRec。



可以看到使用 hb 的方案在训练速度上对比 TF-PS 原生方案的优势。

3.2.1 模型参数完全放在显存里

想要充分释放 gpu 的算力,减少因为数据拷贝带来的性能损耗,最好的方案自然是把所有参数都放在 gpu 显存里。上面 2.1.3 提到的压缩模型大小,为这种方案提供了可能性。调大 batch size 则可以进一步提高显卡的利用率。经过测试,在这种情况下,单张 V100 显卡的算力可以超过 20 台 40core worker 节点的算力。

3.2.2 解决了多卡训练丢失数据的问题

在单机多卡训练时,我们发现和单卡训练相比有近 1/3 的数据被丢弃,这是由于 hybridbackend 默认使用所有 worker 按照 row group 平分数据的策略,以提高读取效率。当 group 数目不够均分时,多余的数据会被丢弃,当 parquet 文件较多且比较小时,该问题尤为严重。我们通过使用每个 worker 加载所有的 group,再按照 batch 平分数据的策略,极大地缓解了数据丢失的情况,读取压力也在可接收范围内,后续可考虑将两策略结合降低 worker 的读取压力。

4 模型 inference

4.1 痛点

在我们的实际场景里,线上 inference 的痛点大部分来自于维护成本。因为推荐广告业务场景,需要大量尝试各种模型在线上分配流量做 AB test,因此线上存在的模型量级大概是 10 倍的基线模型量级。而每次上线一个模型,都需要给对应的模型分配相应的资源,并且这个资源跟 AB test 的流量正相关;而每次调整 AB test 流量(比如模型效果不错,放大流量观察)的时候,又需要调整该模型分配的资源。这个过程比较难实现自动化,往往需要算法工程师手动扩缩容。

4.2 基于 Processer 库的 inference 方案解决痛点



上面这个图是我们线上实际的 inference 方案。

4.2.1 单机器运行所有模型

基于上面的痛点,我们给出的方案是使用大规格机器(比如 128C,512G 内存)来做线上 inference,然后每台机器都会有线上所有的模型实例。每台机器运行一个 serving-proxy 会自动的管理所有的模型进程,包括模型上下线、模型更新等。这种方案的好处是整个维护成本基本没有了,所有事情基本都自动化完成了。因为线上整体的流量相对稳定(比如扩大 AB test 模型的流量,自然基线模型流量就减少了,整体是稳定的),所以各个模型之间资源竞争也不需要重新分配资源。

4.2.2 基于 DeepRec 提供的 Processer 库

DeepRec Serving Processor 是用于线上高性能服务的 Library,可以参考文档。因为本身是一个独立的 so 包,我们可以很方便的对接到自己的 Serving RPC 框架中。我们采用 golang 语言来完成了我们自己的 serving rpc 项目,优点自然是开发成本低并且性能不错。

4.2.3 使用 DeepRec 的 Session Group

直接使用 TensorFlow 提供的 C++ 接口调用 Session::Run,无法实现多 Session 并发处理 Request,导致单 Session 无法实现 CPU 的有效利用。如果通过多 Instance 方式(多进程),无法共享底层的 Variable,导致大量使用内存,并且每个 Instance 各自加载一遍模型,严重影响资源的使用率和模型加载效率。



DeepRec 中 SessionGroup 可配置一组 Session,并且通过 Round Robin (支持用户自定义策略)方式将用户请求分发到某一个 Session。SessionGroup 对不同 Session 之间的资源进行隔离,每个 Session 拥有私有的线程池,并且支持每个线程池绑定底层的 CPU Core(numa-aware),可以最大程度地避免共享资源导致的锁冲突开销。SessionGroup 中唯一共享的资源是 Variable,所有 Session 共享底层的 Variable,并且模型加载只需要加载一次。

我们使用 session group 后,实测调整到合适的 group 数量,可以提高 50% 的 inference 性能。

4.2.4 基于 oneDNN 的优化

DeepRec 集成了英特尔开源的跨平台深度学习性能加速库 oneDNN(oneAPI Deep Neural Network Library),并且修改 oneDNN 原有的线程池,统一成 DeepRec 的 Eigen 线程池,减少了线程池切换开销,避免了不同线程池之间竞争而导致的性能下降问题。oneDNN 已经针对大量主流算子实现了性能优化,包括 MatMul、BiasAdd、LeakyReLU 等在业务场景中使用到的常见算子,为业务模型提供了强有力的性能支持。更值得一提的是, oneDNN 的算子支持 BF16 数据类型,与搭载 AMX(Advanced Matrix Extensions)指令集的第四代英特尔® 至强® 可扩展处理器同时使用,可显著提升模型训练和推理性能。在 DeepRec Serving Processor 编译选项中,只需加入“--config=mkl_threadpool”,便可轻松开启 oneDNN 优化。

4.2.5 子图优化

子图融合是推理性能优化的常用方法。但是对于本模型中左图所示的子图结构含有 Reshape 算子,原生 tensorflow 并没有对应结构的图优化器以及算子实现,我们通过手动融合来实现,融合前后的子图构成如下图所示。这样减少了多余算子的运行开销,减少了内存访问,提升了计算效率。再结合 oneDNN 加速融合算子,最终业务端到端加速了 10%,CPU 利用率下降 10%。



4.2.6 cost model 的设计

由于大机器的 cpu core 数较多,而我们是一台机器有所有模型的进程,那么所有模型都共享所有 cpu core 显然会造成不必要的资源竞争等。因此给不同模型设计合理的 cost model 就很有必要。我们目前采用比较简单的方式,因为基线模型和需要做 AB test 的模型资源差别较大(流量差距大),我们会给每个基线模型分配对应的 core,然后让所有非基线模型共享一组 core(总体 AB test 的流量有上限)。虽然这个方案很简单,但是取得了非常好的效果,大概有 30% 的性能提升。

5 后续规划

1、cost model 的优化,显然有更好的方案来动态的调整每个模型需要的 core。我们打算开发更好的 cost model 并提供给 DeepRec。

2、开源我们的 inference 架构方案,因为在我们的业务里,基于 DeepRec processor 设计的 inference 架构带来了巨大的便利,并且性能很好,我们预计在上半年会开源我们的 inference 架构方案,欢迎大家到时关注。

相关实践学习
使用PAI-EAS一键部署ChatGLM及LangChain应用
本场景中主要介绍如何使用模型在线服务(PAI-EAS)部署ChatGLM的AI-Web应用以及启动WebUI进行模型推理,并通过LangChain集成自己的业务数据。
机器学习概览及常见算法
机器学习(Machine Learning, ML)是人工智能的核心,专门研究计算机怎样模拟或实现人类的学习行为,以获取新的知识或技能,重新组织已有的知识结构使之不断改善自身的性能,它是使计算机具有智能的根本途径,其应用遍及人工智能的各个领域。 本课程将带你入门机器学习,掌握机器学习的概念和常用的算法。
相关文章
|
16天前
|
机器学习/深度学习 人工智能 分布式计算
人工智能平台PAI 操作报错合集之机器学习PAI deeprec中的sok该怎么使用
阿里云人工智能平台PAI (Platform for Artificial Intelligence) 是阿里云推出的一套全面、易用的机器学习和深度学习平台,旨在帮助企业、开发者和数据科学家快速构建、训练、部署和管理人工智能模型。在使用阿里云人工智能平台PAI进行操作时,可能会遇到各种类型的错误。以下列举了一些常见的报错情况及其可能的原因和解决方法。
|
11月前
|
机器学习/深度学习 存储 人工智能
预约直播 | 展心展力MetaApp:基于DeepRec的稀疏模型训练实践
阿里云AI技术分享会第十一期《基于DeepRec的稀疏模型训练实践》将在2023年7月5日晚18:00开启直播,精彩不容错过。
|
存储 机器学习/深度学习 算法
DeepRec 大规模稀疏模型训练推理引擎
本文将以下三个方面展开介绍:DeepRec 背景(我们为什么要做 DeepRec)、DeepRec 功能(设计动机和实现)以及DeepRec 社区(最新发布的 2206 版本主要功能)
DeepRec 大规模稀疏模型训练推理引擎
《DeepRec:大规模稀疏模型训练引擎》电子版地址
《DeepRec:大规模稀疏模型训练引擎》.ppt
95 0
《DeepRec:大规模稀疏模型训练引擎》电子版地址
|
存储 机器学习/深度学习 人工智能
阿里巴巴开源大规模稀疏模型训练/预测引擎DeepRec
经历6年时间,在各团队的努力下,阿里巴巴集团大规模稀疏模型训练/预测引擎DeepRec正式对外开源,助力开发者提升稀疏模型训练性能和效果。
阿里巴巴开源大规模稀疏模型训练/预测引擎DeepRec
|
存储 机器学习/深度学习 人工智能
阿里巴巴开源大规模稀疏模型训练/预测引擎DeepRec
经历6年时间,在各团队的努力下,阿里巴巴集团大规模稀疏模型训练/预测引擎DeepRec正式对外开源,助力开发者提升稀疏模型训练性能和效果。
666 1
阿里巴巴开源大规模稀疏模型训练/预测引擎DeepRec
|
1天前
|
机器学习/深度学习 传感器 算法
【机器学习】在聚类算法中,使用曼哈顿距离和使用欧式距离有什么区别?
【5月更文挑战第12天】【机器学习】在聚类算法中,使用曼哈顿距离和使用欧式距离有什么区别?
|
1天前
|
数据采集 机器学习/深度学习 人工智能
【机器学习】在使用K-means算法之前,如何预处理数据?
【5月更文挑战第12天】【机器学习】在使用K-means算法之前,如何预处理数据?
|
1天前
|
机器学习/深度学习 算法 数据可视化
【机器学习】比较分层聚类(Hierarchical Clustering)和K-means聚类算法
【5月更文挑战第12天】【机器学习】比较分层聚类(Hierarchical Clustering)和K-means聚类算法
|
1天前
|
机器学习/深度学习 数据采集 算法
深入理解并应用机器学习算法:支持向量机(SVM)
【5月更文挑战第13天】支持向量机(SVM)是监督学习中的强分类算法,用于文本分类、图像识别等领域。它寻找超平面最大化间隔,支持向量是离超平面最近的样本点。SVM通过核函数处理非线性数据,软间隔和正则化避免过拟合。应用步骤包括数据预处理、选择核函数、训练模型、评估性能及应用预测。优点是高效、鲁棒和泛化能力强,但对参数敏感、不适合大规模数据集且对缺失数据敏感。理解SVM原理有助于优化实际问题的解决方案。