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

本文涉及的产品
交互式建模 PAI-DSW,每月250计算时 3个月
模型训练 PAI-DLC,100CU*H 3个月
模型在线服务 PAI-EAS,A10/V100等 500元 1个月
简介: 针对稀疏模型在分布式、图优化、算子、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)是人工智能的核心,专门研究计算机怎样模拟或实现人类的学习行为,以获取新的知识或技能,重新组织已有的知识结构使之不断改善自身的性能,它是使计算机具有智能的根本途径,其应用遍及人工智能的各个领域。 本课程将带你入门机器学习,掌握机器学习的概念和常用的算法。
相关文章
|
2月前
|
机器学习/深度学习 数据采集 人工智能
AI与机器学习:从理论到实践
【10月更文挑战第2天】本文将深入探讨AI和机器学习的基本概念,以及它们如何从理论转化为实际的应用。我们将通过Python代码示例,展示如何使用机器学习库scikit-learn进行数据预处理、模型训练和预测。无论你是AI领域的初学者,还是有一定基础的开发者,这篇文章都将为你提供有价值的信息和知识。
|
28天前
|
人工智能 JSON 算法
Qwen2.5-Coder 系列模型在 PAI-QuickStart 的训练、评测、压缩及部署实践
阿里云的人工智能平台 PAI,作为一站式、 AI Native 的大模型与 AIGC 工程平台,为开发者和企业客户提供了 Qwen2.5-Coder 系列模型的全链路最佳实践。本文以Qwen2.5-Coder-32B为例,详细介绍在 PAI-QuickStart 完成 Qwen2.5-Coder 的训练、评测和快速部署。
Qwen2.5-Coder 系列模型在 PAI-QuickStart 的训练、评测、压缩及部署实践
|
13天前
|
编解码 机器人 测试技术
技术实践 | 使用 PAI+LLaMA Factory 微调 Qwen2-VL 模型快速搭建专业领域知识问答机器人
Qwen2-VL是一款具备高级图像和视频理解能力的多模态模型,支持多种语言,适用于多模态应用开发。通过PAI和LLaMA Factory框架,用户可以轻松微调Qwen2-VL模型,快速构建文旅领域的知识问答机器人。本教程详细介绍了从模型部署、微调到对话测试的全过程,帮助开发者高效实现定制化多模态应用。
|
22天前
|
机器学习/深度学习 人工智能 算法
人工智能浪潮下的编程实践:构建你的第一个机器学习模型
在人工智能的巨浪中,每个人都有机会成为弄潮儿。本文将带你一探究竟,从零基础开始,用最易懂的语言和步骤,教你如何构建属于自己的第一个机器学习模型。不需要复杂的数学公式,也不必担心编程难题,只需跟随我们的步伐,一起探索这个充满魔力的AI世界。
39 12
|
21天前
|
机器学习/深度学习 存储 运维
分布式机器学习系统:设计原理、优化策略与实践经验
本文详细探讨了分布式机器学习系统的发展现状与挑战,重点分析了数据并行、模型并行等核心训练范式,以及参数服务器、优化器等关键组件的设计与实现。文章还深入讨论了混合精度训练、梯度累积、ZeRO优化器等高级特性,旨在提供一套全面的技术解决方案,以应对超大规模模型训练中的计算、存储及通信挑战。
54 4
|
1月前
|
人工智能 边缘计算 JSON
DistilQwen2 蒸馏小模型在 PAI-QuickStart 的训练、评测、压缩及部署实践
本文详细介绍在 PAI 平台使用 DistilQwen2 蒸馏小模型的全链路最佳实践。
|
28天前
|
机器学习/深度学习 人工智能 自然语言处理
探索机器学习:从理论到实践
在这篇文章中,我们将深入探讨机器学习的世界。我们将首先了解机器学习的基本概念和原理,然后通过一个简单的代码示例,展示如何实现一个基本的线性回归模型。无论你是初学者还是有经验的开发者,这篇文章都将帮助你更好地理解和应用机器学习。
|
1月前
|
机器学习/深度学习 数据采集 人工智能
探索机器学习:从理论到Python代码实践
【10月更文挑战第36天】本文将深入浅出地介绍机器学习的基本概念、主要算法及其在Python中的实现。我们将通过实际案例,展示如何使用scikit-learn库进行数据预处理、模型选择和参数调优。无论你是初学者还是有一定基础的开发者,都能从中获得启发和实践指导。
47 2
|
1月前
|
机器学习/深度学习 数据采集 人工智能
探索机器学习:从理论到实践
【10月更文挑战第35天】在这篇文章中,我们将深入探讨机器学习的世界。我们将从基础理论开始,然后逐步过渡到实际应用,最后通过代码示例来展示如何实现一个简单的机器学习模型。无论你是初学者还是有经验的开发者,这篇文章都将为你提供有价值的信息和见解。
|
2月前
|
机器学习/深度学习 数据可视化 数据挖掘
机器学习中空间和时间自相关的分析:从理论基础到实践应用
空间和时间自相关是数据分析中的重要概念,揭示了现象在空间和时间维度上的相互依赖关系。本文探讨了这些概念的理论基础,并通过野火风险预测的实际案例,展示了如何利用随机森林模型捕捉时空依赖性,提高预测准确性。
110 0
机器学习中空间和时间自相关的分析:从理论基础到实践应用

热门文章

最新文章

相关产品

  • 人工智能平台 PAI