深度学EBET易博真人平台习框架(一):AI 模型是如何训练出来的

  新闻资讯     |      2023-09-01 14:37

  EBET易博app本系列专题以百度 PaddlePaddle(飞桨)开源深度学习框架为例,深入浅出,介绍下深度学习框架的底层计算原理及实现(Python 前端和 C++ 后端)。

  首先,我们用 tensorflow、pytorch 或者 paddlepaddle 写一段 python 代码来组建一个神经网络模型,然后训练,达到一定精度后再保存模型,最后基于训练好的模型做图像识别、语音识别等任务。这个流程想必大家都很清楚了,那这一切都是谁来计算的呢?答案是后台框架,你所写的 python 代码只不过是前端 API,真正调用的是后端 C 或 C++ 计算逻辑,而前端 python API 和 后端计算逻辑正是通过 pybind 绑定的。

  深度学习框架最基本的功能就是要能提供一系列算子(俗称『OP』,operator 的简称),支持前向计算和反向梯度更新。如此说来,框架应该很简单呀。实则不然,且听我细细道来。首先,这些 OP 数量很大,比如卷积、全连接、各种激活函数(如 Relu、Sigmoid)、各种梯度更新算法(如 Adam、RMS)等等。其次,组建神经网络模型时,需要提供静态图模式(声明式编程)和动态图模式(函数式编程)。动态图好理解,就是我们平时写代码的逻辑,do A - do B - do C,按流程顺序执行任务,每写完一行代码就能得到相应的结果。而静态图就不大好理解了,用户所写的代码仅仅是为了构建一张图,图构建完之后再去执行,执行完才能得到结果,而不像动态图那样能实时获取结果。静态图这种方式有什么好处呢?答案是便于做性能优化,通过优化这张图的结构,使得程序执行效率更高。静态图中的『图』,又叫做 SSA Graph,Directed Acyclic Single Static Assignment Graph(有向无环静态单赋值图),那这张图是如何构建出来的呢?如何去描述?如何把它序列化成二进制字节流在不同进程间传递呢?如何执行的?又是如何优化的呢?

  还有,样本数据该如何存储呢?内存?缓存?SSD?还是哈希表,这些存储资源该怎么管理呢?原始样本文件又如何转化成模型『认识』的 feed data 呢?

  另外,模型如何保存呢?保存完整模型还是保存部分模型(比如只保留模型最后两层)?模型又是如何加载呢?从头开始训练(冷启动)和增量训练(热启动)又有什么区别?

  更重要的是,随着模型越来越大,参数规模达到百亿、千亿,甚至万亿,对模型的训练性能提出了非常高的要求,高性能的训练框架不仅能大大缩短训练时间,同时大大节约硬件资源,这可是实打实的真金白银呀。另外,在推荐领域,All is Embedding,大规模稀疏参数需要大量的存储空间,单机无法容纳,需要借助分布式文件系统。于是,参数服务器(Parameter Server)这一解决方案应运而生。

  考虑到不同厂家的各类 AI 芯片,如英伟达的 GPU、华为的昇腾、百度的昆仑等芯片,想要充分利用这些高性能 AI 硬件的能力,软件必须得兼容这些硬件,而它们的编程语法, 编译方法和英特尔的 x86 CPU 又不一样,比如 cuda 编程等,硬件之间又涉及到通信问题,如 nccl。自然地,CPU 参数服务器进化成了异构参数服务器。参数服务器系统中又牵扯出了各式各样的并行优化策略,如数据并行、模型并行、流水线并行、混合并行、自动并行等,数据和模型中的各个层(layer)要如何切分,才能充分利用硬件资源呢?不仅如此,分布式系统中的通信算法,如 gloo、mpi 等,不同进程间又涉及到同步问题,如 barrier 算法。

  从应用层面看,还包括基于 k8s、docker、yarn等训练资源调度系统的搭建、实现基于 C++、Java、Go 等主流语言的线上低时延, 高吞吐推理预测服务、终端低功耗的 PaddleLite 解决方案等。一款合格的深度学习训练框架应该是工业级的产品,具备高性能、支持各类 AI 硬件、能大规模部署、能支持所有 AI 模型,API 还必须得是用户友好的。