diff --git a/ch18_后端架构选型、离线及实时计算/img/18-2-10-1.png b/ch18_后端架构选型、离线及实时计算/img/18-2-10-1.png new file mode 100644 index 0000000..53c0fb5 Binary files /dev/null and b/ch18_后端架构选型、离线及实时计算/img/18-2-10-1.png differ diff --git a/ch18_后端架构选型、离线及实时计算/img/18-2-10-2.png b/ch18_后端架构选型、离线及实时计算/img/18-2-10-2.png new file mode 100644 index 0000000..d5f2749 Binary files /dev/null and b/ch18_后端架构选型、离线及实时计算/img/18-2-10-2.png differ diff --git a/ch18_后端架构选型、离线及实时计算/img/18-2-4-1.png b/ch18_后端架构选型、离线及实时计算/img/18-2-4-1.png new file mode 100644 index 0000000..5db6666 Binary files /dev/null and b/ch18_后端架构选型、离线及实时计算/img/18-2-4-1.png differ diff --git a/ch18_后端架构选型、离线及实时计算/img/18-2-4-2.png b/ch18_后端架构选型、离线及实时计算/img/18-2-4-2.png new file mode 100644 index 0000000..b5344fd Binary files /dev/null and b/ch18_后端架构选型、离线及实时计算/img/18-2-4-2.png differ diff --git a/ch18_后端架构选型、离线及实时计算/img/18-2-5-1.png b/ch18_后端架构选型、离线及实时计算/img/18-2-5-1.png new file mode 100644 index 0000000..fba6a2c Binary files /dev/null and b/ch18_后端架构选型、离线及实时计算/img/18-2-5-1.png differ diff --git a/ch18_后端架构选型、离线及实时计算/img/18-2-5-2.png b/ch18_后端架构选型、离线及实时计算/img/18-2-5-2.png new file mode 100644 index 0000000..d09a059 Binary files /dev/null and b/ch18_后端架构选型、离线及实时计算/img/18-2-5-2.png differ diff --git a/ch18_后端架构选型、离线及实时计算/img/18-2-6-1.png b/ch18_后端架构选型、离线及实时计算/img/18-2-6-1.png new file mode 100644 index 0000000..ff572fe Binary files /dev/null and b/ch18_后端架构选型、离线及实时计算/img/18-2-6-1.png differ diff --git a/ch18_后端架构选型、离线及实时计算/img/18-2-6-2.png b/ch18_后端架构选型、离线及实时计算/img/18-2-6-2.png new file mode 100644 index 0000000..459d8f5 Binary files /dev/null and b/ch18_后端架构选型、离线及实时计算/img/18-2-6-2.png differ diff --git a/ch18_后端架构选型、离线及实时计算/img/18-2-9-1.png b/ch18_后端架构选型、离线及实时计算/img/18-2-9-1.png new file mode 100644 index 0000000..894619e Binary files /dev/null and b/ch18_后端架构选型、离线及实时计算/img/18-2-9-1.png differ diff --git a/ch18_后端架构选型、离线及实时计算/img/18-2-9-2.png b/ch18_后端架构选型、离线及实时计算/img/18-2-9-2.png new file mode 100644 index 0000000..5fb2c8f Binary files /dev/null and b/ch18_后端架构选型、离线及实时计算/img/18-2-9-2.png differ diff --git a/ch18_后端架构选型、离线及实时计算/img/18-2-9-3.png b/ch18_后端架构选型、离线及实时计算/img/18-2-9-3.png new file mode 100644 index 0000000..7d6b87a Binary files /dev/null and b/ch18_后端架构选型、离线及实时计算/img/18-2-9-3.png differ diff --git a/ch18_后端架构选型、离线及实时计算/img/18-2-9-4.png b/ch18_后端架构选型、离线及实时计算/img/18-2-9-4.png new file mode 100644 index 0000000..1823c37 Binary files /dev/null and b/ch18_后端架构选型、离线及实时计算/img/18-2-9-4.png differ diff --git a/ch18_后端架构选型、离线及实时计算/第十八章_后端架构选型、离线及实时计算.md b/ch18_后端架构选型、离线及实时计算/第十八章_后端架构选型、离线及实时计算.md index 232ebb7..ae4d52e 100644 --- a/ch18_后端架构选型、离线及实时计算/第十八章_后端架构选型、离线及实时计算.md +++ b/ch18_后端架构选型、离线及实时计算/第十八章_后端架构选型、离线及实时计算.md @@ -66,18 +66,212 @@ ### 18.2.4 Spark MLllib +  MLlib(Machine Learnig lib) 【4】是Spark对常用的机器学习算法的实现库,同时包括相关的测试和数据生成器。 + +  MLlib是MLBase一部分,其中MLBase分为四部分:MLlib、MLI、ML Optimizer和MLRuntime。 +- ML Optimizer会选择它认为最适合的已经在内部实现好了的机器学习算法和相关参数,来处理用户输入的数据,并返回模型或别的帮助分析的结果; +- MLI 是一个进行特征抽取和高级ML编程抽象的算法实现的API或平台; +- MLlib是Spark实现一些常见的机器学习算法和实用程序,包括分类、回归、聚类、协同过滤、降维以及底层优化,该算法可以进行可扩充; MLRuntime 基于Spark计算框架,将Spark的分布式计算应用到机器学习领域。 + +  MLlib主要包含三个部分: +- 底层基础:包括Spark的运行库、矩阵库和向量库 +- 算法库:包含广义线性模型、推荐系统、聚类、决策树和评估的算法 +- 实用程序:包括测试数据的生成、外部数据的读入等功能 + +架构图 +![架构图](./img/18-2-4-1.png) + + +  MLlib目前支持4种常见的机器学习问题: 分类、回归、聚类和协同过滤,MLlib在Spark整个生态系统中的位置如图下图所示。 + ### 18.2.5 Ray +  Ray【5】是加州大学伯克利分校实时智能安全执行实验室(RISELab)的研究人员针对机器学习领域开发的一种新的分布式计算框架,该框架旨在让基于Python的机器学习和深度学习工作负载能够实时执行,并具有类似消息传递接口(MPI)的性能和细粒度。 + +  增强学习的场景,按照原理定义,因为没有预先可用的静态标签信息,所以通常需要引入实际的目标系统(为了加快训练,往往是目标系统的模拟环境)来获取反馈信息,用做损失/收益判断,进而完成整个训练过程的闭环反馈。典型的步骤是通过观察特定目标系统的状态,收集反馈信息,判断收益,用这些信息来调整参数,训练模型,并根据新的训练结果产出可用于调整目标系统的行为Action,输出到目标系统,进而影响目标系统状态变化,完成闭环,如此反复迭代,最终目标是追求某种收益的最大化(比如对AlphoGo来说,收益是赢得一盘围棋的比赛)。 + +  在这个过程中,一方面,模拟目标系统,收集状态和反馈信息,判断收益,训练参数,生成Action等等行为可能涉及大量的任务和计算(为了选择最佳Action,可能要并发模拟众多可能的行为)。而这些行为本身可能也是千差万别的异构的任务,任务执行的时间也可能长短不一,执行过程有些可能要求同步,也有些可能更适合异步。 + +  另一方面,整个任务流程的DAG图也可能是动态变化的,系统往往可能需要根据前一个环节的结果,调整下一个环节的行为参数或者流程。这种调整,可能是目标系统的需要(比如在自动驾驶过程中遇到行人了,那么我们可能需要模拟计算刹车的距离来判断该采取的行动是刹车还是拐弯,而平时可能不需要这个环节),也可能是增强学习特定训练算法的需要(比如根据多个并行训练的模型的当前收益,调整模型超参数,替换模型等等)。 + +  此外,由于所涉及到的目标系统可能是具体的,现实物理世界中的系统,所以对时效性也可能是有强要求的。举个例子,比如你想要实现的系统是用来控制机器人行走,或者是用来打视频游戏的。那么整个闭环反馈流程就需要在特定的时间限制内完成(比如毫秒级别)。 + +  总结来说,就是增强学习的场景,对分布式计算框架的任务调度延迟,吞吐量和动态修改DAG图的能力都可能有很高的要求。按照官方的设计目标,Ray需要支持异构计算任务,动态计算链路,毫秒级别延迟和每秒调度百万级别任务的能力。 + +  Ray的目标问题,主要是在类似增强学习这样的场景中所遇到的工程问题。那么增强学习的场景和普通的机器学习,深度学习的场景又有什么不同呢?简单来说,就是对整个处理链路流程的时效性和灵活性有更高的要求。 + +Ray框架优点 +- 海量任务调度能力 +- 毫秒级别的延迟 +- 异构任务的支持 +- 任务拓扑图动态修改的能力 + +  Ray没有采用中心任务调度的方案,而是采用了类似层级(hierarchy)调度的方案,除了一个全局的中心调度服务节点(实际上这个中心调度节点也是可以水平拓展的),任务的调度也可以在具体的执行任务的工作节点上,由本地调度服务来管理和执行。 +与传统的层级调度方案,至上而下分配调度任务的方式不同的是,Ray采用了至下而上的调度策略。也就是说,任务调度的发起,并不是先提交给全局的中心调度器统筹规划以后再分发给次级调度器的。而是由任务执行节点直接提交给本地的调度器,本地的调度器如果能满足该任务的调度需求就直接完成调度请求,在无法满足的情况下,才会提交给全局调度器,由全局调度器协调转发给有能力满足需求的另外一个节点上的本地调度器去调度执行。 + +  架构设计一方面减少了跨节点的RPC开销,另一方面也能规避中心节点的瓶颈问题。当然缺点也不是没有,由于缺乏全局的任务视图,无法进行全局规划,因此任务的拓扑逻辑结构也就未必是最优的了。 + +架构图 +![架构图](./img/18-2-5-1.png) + +任务调度图 +![任务调度图](./img/18-2-5-2.png) + +  Ray架构现状: +- API层以上 的部分还比较薄弱,Core模块核心逻辑估需要时间打磨。 +- 国内目前除了蚂蚁金服和RISELab有针对性的合作以外,关注程度还很低,没有实际的应用实例看到,整体来说还处于比较早期的框架构建阶段。 + +  Github地址:https://github.com/ray-project/ray + ### 18.2.6 Spark stream +  随着大数据的发展,人们对大数据的处理要求也越来越高,原有的批处理框架MapReduce适合离线计算,却无法满足实时性要求较高的业务,如实时推荐、用户行为分析等。 Spark Streaming是建立在Spark上的实时计算框架,通过它提供的丰富的API、基于内存的高速执行引擎,用户可以结合流式、批处理和交互试查询应用。本文将详细介绍Spark Streaming实时计算框架的原理与特点、适用场景。 + +  Spark是一个类似于MapReduce的分布式计算框架,其核心是弹性分布式数据集,提供了比MapReduce更丰富的模型,可以在快速在内存中对数据集进行多次迭代,以支持复杂的数据挖掘算法和图形计算算法。Spark Streaming【6】是一种构建在Spark上的实时计算框架,它扩展了Spark处理大规模流式数据的能力。 + +  Spark Streaming的优势在于: +- 能运行在100+的结点上,并达到秒级延迟。 +- 使用基于内存的Spark作为执行引擎,具有高效和容错的特性。 +- 能集成Spark的批处理和交互查询。 +- 为实现复杂的算法提供和批处理类似的简单接口。 + +Spark Streaming架构图 +![Spark Streaming架构图](./img/18-2-6-1.png) + +  Spark Streaming把实时输入数据流以时间片Δt (如1秒)为单位切分成块。Spark Streaming会把每块数据作为一个RDD,并使用RDD操作处理每一小块数据。每个块都会生成一个Spark Job处理,最终结果也返回多块。 + +Spark Streaming基本原理图 +![Spark Streaming基本原理图](./img/18-2-6-2.png) + +  正如Spark Streaming最初的目标一样,它通过丰富的API和基于内存的高速计算引擎让用户可以结合流式处理,批处理和交互查询等应用。因此Spark Streaming适合一些需要历史数据和实时数据结合分析的应用场合。当然,对于实时性要求不是特别高的应用也能完全胜任。另外通过RDD的数据重用机制可以得到更高效的容错处理。 + ### 18.2.7 Horovod +  Horovod【7】 是 Uber 开源的又一个深度学习工具,它的发展吸取了 Facebook「一小时训练 ImageNet 论文」与百度 Ring Allreduce 的优点,可为用户实现分布式训练提供帮助。 + +  Horovod 支持通过用于高性能并行计算的低层次接口 – 消息传递接口 (MPI) 进行分布式模型训练。有了 MPI,就可以利用分布式 Kubernetes 集群来训练 TensorFlow 和 PyTorch 模型。 + +  分布式 TensorFlow 的参数服务器模型(parameter server paradigm)通常需要对大量样板代码进行认真的实现。但是 Horovod 仅需要几行。下面是一个分布式 TensorFlow 项目使用 Horovod 的示例: +``` +import tensorflow as tf +import horovod.tensorflow as hvd +# Initialize Horovod +hvd.init() +# Pin GPU to be used to process local rank (one GPU per process) +config = tf.ConfigProto() +config.gpu_options.visible_device_list = str(hvd.local_rank()) +# Build model… +loss = … +opt = tf.train.AdagradOptimizer(0.01) +# Add Horovod Distributed Optimizer +opt = hvd.DistributedOptimizer(opt) +# Add hook to broadcast variables from rank 0 to all other processes during +# initialization. +hooks = [hvd.BroadcastGlobalVariablesHook(0)] +# Make training operation +train_op = opt.minimize(loss) +# The MonitoredTrainingSession takes care of session initialization, +# restoring from a checkpoint, saving to a checkpoint, and closing when done +# or an error occurs. +with tf.train.MonitoredTrainingSession(checkpoint_dir=“/tmp/train_logs”, + config=config, + hooks=hooks) as mon_sess: + while not mon_sess.should_stop(): + # Perform synchronous training. + mon_sess.run(train_op) +``` + +  在该示例中,粗体文字指进行单个 GPU 分布式项目时必须做的改变: + +- hvd.init() 初始化 Horovod。 +- config.gpu_options.visible_device_list = str(hvd.local_rank()) 向每个 TensorFlow 流程分配一个 GPU。 +- opt=hvd.DistributedOptimizer(opt) 使用 Horovod 优化器包裹每一个常规 TensorFlow 优化器,Horovod 优化器使用 ring-allreduce 平均梯度。 +- hvd.BroadcastGlobalVariablesHook(0) 将变量从第一个流程向其他流程传播,以实现一致性初始化。如果该项目无法使用 MonitoredTrainingSession,则用户可以运行 hvd.broadcast_global_variables(0)。 + +  之后,可以使用 mpirun 命令使该项目的多个拷贝在多个服务器中运行: + +``` +$ mpirun -np 16 -x LD_LIBRARY_PATH -H +server1:4,server2:4,server3:4,server4:4 python train.py +``` + +  mpirun 命令向四个节点分布 train.py,然后在每个节点的四个 GPU 上运行 train.py。 + +  Github地址:https://github.com/uber/horovod + ### 18.2.8 BigDL +  BigDL【9】是一种基于Apache Spark的分布式深度学习框架。它可以无缝的直接运行在现有的Apache Spark和Hadoop集群之上。BigDL的设计吸取了Torch框架许多方面的知识,为深度学习提供了全面的支持;包括数值计算和高级神经网络;借助现有的Spark集群来运行深度学习计算,并简化存储在Hadoop中的大数据集的数据加载。 + +  BigDL优点: +- 丰富的深度学习支持。模拟Torch之后,BigDL为深入学习提供全面支持,包括数字计算(通过Tensor)和高级神经网络 ; 此外,用户可以使用BigDL将预先训练好的Caffe或Torch模型加载到Spark程序中。 +- 极高的性能。为了实现高性能,BigDL在每个Spark任务中使用英特尔MKL和多线程编程。因此,在单节点Xeon(即与主流GPU 相当)上,它比开箱即用开源Caffe,Torch或TensorFlow快了数量级。 +- 有效地横向扩展。BigDL可以通过利用Apache Spark(快速分布式数据处理框架),以及高效实施同步SGD和全面减少Spark的通信,从而有效地扩展到“大数据规模”上的数据分析 + +  BigDL缺点: +- 对机器要求高 jdk7上运行性能差 在CentOS 6和7上,要将最大用户进程增加到更大的值(例如514585); 否则,可能会看到错误,如“无法创建新的本机线程”。 +- 训练和验证的数据会加载到内存,挤占内存 + +  BigDL满足的应用场景: +- 直接在Hadoop/Spark框架下使用深度学习进行大数据分析(即将数据存储在HDFS、HBase、Hive等数据库上); +- 在Spark程序中/工作流中加入深度学习功能; +- 利用现有的 Hadoop/Spark 集群来运行深度学习程序,然后将代码与其他的应用场景进行动态共享,例如ETL(Extract、Transform、Load,即通常所说的数据抽取)、数据仓库(data warehouse)、功能引擎、经典机器学习、图表分析等。 + ### 18.2.9 Petastorm +  Petastorm是一个由 Uber ATG 开发的开源数据访问库。这个库可以直接基于数 TB Parquet 格式的数据集进行单机或分布式训练和深度学习模型评估。Petastorm 支持基于 Python 的机器学习框架,如 Tensorflow、Pytorch 和 PySpark,也可以直接用在 Python 代码中。 + +深度学习集群 +![深度学习集群](./img/18-2-9-1.png) + +  即使是在现代硬件上训练深度模型也很耗时,而且在很多情况下,很有必要在多台机器上分配训练负载。典型的深度学习集群需要执行以下几个步骤: +- 一台或多台机器读取集中式或本地数据集。 +- 每台机器计算损失函数的值,并根据模型参数计算梯度。在这一步通常会使用 GPU。 +- 通过组合估计的梯度(通常由多台机器以分布式的方式计算得出)来更新模型系数。 + +  通常,一个数据集是通过连接多个数据源的记录而生成的。这个由 Apache Spark 的 Python 接口 PySpark 生成的数据集稍后将被用在机器学习训练中。Petastorm 提供了一个简单的功能,使用 Petastorm 特定的元数据对标准的 Parquet 进行了扩展,从而让它可以与 Petastorm 兼容。 +有了 Petastorm,消费数据就像在 HDFS 或文件系统中创建和迭代读取对象一样简单。Petastorm 使用 PyArrow 来读取 Parquet 文件。 + +  将多个数据源组合到单个表格结构中,从而生成数据集。可以多次使用相同的数据集进行模型训练和评估。 +![深度学习集群](./img/18-2-9-2.png) + +  为分布式训练进行分片 +在分布式训练环境中,每个进程通常负责训练数据的一个子集。一个进程的数据子集与其他进程的数据子集正交。Petastorm 支持将数据集的读时分片转换为正交的样本集。 +![Petastorm 将数据集的非重叠子集提供给参与分布式训练的不同机器](./img/18-2-9-3.png) + +  本地缓存 +Petastorm 支持在本地存储中缓存数据。当网络连接速度较慢或带宽很昂贵时,这会派上用场。 +![本地缓存](./img/18-2-9-4.png) + +Github地址:https://github.com/uber/petastorm + ### 18.2.10 TensorFlowOnSpark +  TensorFlowOnSpark【10】为 Apache Hadoop 和 Apache Spark 集群带来可扩展的深度学习。 通过结合深入学习框架 TensorFlow 和大数据框架 Apache Spark 、Apache Hadoop 的显着特征,TensorFlowOnSpark 能够在 GPU 和 CPU 服务器集群上实现分布式深度学习。 + +  满足的应用场景: +为了利用TensorFlow在现有的Spark和Hadoop集群上进行深度学习。而不需要为深度学习设置单独的集群。 + +架构图 +![架构图](./img/18-2-10-1.png) + +运行流程图 +![架构图](./img/18-2-10-2.png) + +  优点: +- 轻松迁移所有现有的TensorFlow程序,<10行代码更改; +- 支持所有TensorFlow功能:同步/异步训练,模型/数据并行,推理和TensorBoard; +- 服务器到服务器的直接通信在可用时实现更快的学习; +- 允许数据集在HDFS和由Spark推动的其他来源或由TensorFlow拖动; +- 轻松集成您现有的数据处理流水线和机器学习算法(例如,MLlib,CaffeOnSpark); +- 轻松部署在云或内部部署:CPU和GPU,以太网和Infiniband。 +- TensorFlowOnSpark是基于google的TensorFlow的实现,而TensorFlow有着一套完善的教程,内容丰富。 + +  劣势: +- 开源时间不长,未得到充分的验证。 + +  Github 地址: https://github.com/yahoo/TensorFlowOnSpark + ## 18.3 如何选择合适的分布式计算框架进行模型训练? ## 18.4 如何进行实时计算?