diff --git a/Pic_Templates_and_Samples.pptx b/Pic_Templates_and_Samples.pptx
new file mode 100644
index 0000000..498ce4e
Binary files /dev/null and b/Pic_Templates_and_Samples.pptx differ
diff --git a/README.md b/README.md
index df5f56d..b1d8085 100644
--- a/README.md
+++ b/README.md
@@ -64,6 +64,9 @@
- **可解释性AI系统:** 随着机器学习在安全攸关(Safety-critical)领域的应用,机器学习系统越来越需要对决策给出充分解释。本书将会讨论可解释AI系统的常用方法和落地实践经验。
+- **机器人系统:** 机器人(无人车,无人机,家用机器人等)作为机器学习技术重要的应用领域,在最近数年得到了广泛应用。在实践中,机器人系统在实时性,安全性,鲁棒性等方面都有极高要求,这要求开发者具有算法和系统的双重思维,从而解决实际问题。本书中我们将结合最新研究成果和机器人系统实践经验讲解该类系统的设计原则和实现细节。
+
+
我们在持续拓展拓展本书的内容,如元学习系统,自动并行,深度学习集群调度,绿色AI系统,图学习系统等。我们也非常欢迎社区对于新内容提出建议,贡献章节。
## 构建指南
diff --git a/chapter_accelerator/accelerator_architecture.md b/chapter_accelerator/accelerator_architecture.md
index e24ed01..3194cd1 100644
--- a/chapter_accelerator/accelerator_architecture.md
+++ b/chapter_accelerator/accelerator_architecture.md
@@ -1,5 +1,4 @@
-加速器基本组成原理
-------------------
+## 加速器基本组成原理
上节主要介绍了加速器的意义以及设计思路,了解到加速器与通用处理器在设计上的区别,因此加速器的硬件结构与CPU的硬件结构有着根本的不同,通常都是由多种片上缓存以及多种运算单元组成。本章节主要通过GPU的Volta架构作为样例进行介绍。
@@ -36,7 +35,7 @@
- **常量内存(Constant Memory)**:常量内存其实只是全局内存的一种虚拟地址形式,并没有真正的物理硬件内存块。常量内存有两个特性,一个高速缓存,另一个更重要的特性是它支持将某个单个值广播到线程束中的每个线程中。
-- **纹理内存(Texture Memory)**:纹理内存是全局内存的一个特殊形态。当全局内存被绑定为纹理内存时,执行读写操作将通过专用的纹理缓存来加速。在早期的GPU上没有缓存,因此每个SM(流多处理器)上的纹理内存为设备提供了唯一真正缓存数据的方法。然而随着硬件的升级,一级缓存和二级缓存的出现,纹理缓存的这项优势已经荡然无存。纹理内存的另外一个特性,也是最有用的特性就是当访问存储单元时,允许GPU实现硬件相关的操作。比如说使用纹理内存,可以通过归一化的地址对数组进行访问,获取的数据可以通过硬件进行自动插值,从而达到快速处理数据的目的。此外对于二位数组和三维数组,支持硬件级的双线性插值与三线性插值。纹理内存另一个实用的特性是可以根据数组的索引自动处理边界条件,不需要对特殊边缘进行处理即可完成数组内元素操作,从而防止线程中分支的产生。
+- **纹理内存(Texture Memory)**:纹理内存是全局内存的一个特殊形态。当全局内存被绑定为纹理内存时,执行读写操作将通过专用的纹理缓存来加速。在早期的GPU上没有缓存,因此每个SM(流多处理器)上的纹理内存为设备提供了唯一真正缓存数据的方法。然而随着硬件的升级,一级缓存和二级缓存的出现,纹理缓存的这项优势已经荡然无存。纹理内存的另外一个特性,也是最有用的特性就是当访问存储单元时,允许GPU实现硬件相关的操作。比如说使用纹理内存,可以通过归一化的地址对数组进行访问,获取的数据可以通过硬件进行自动插值,从而达到快速处理数据的目的。此外对于二维数组和三维数组,支持硬件级的双线性插值与三线性插值。纹理内存另一个实用的特性是可以根据数组的索引自动处理边界条件,不需要对特殊边缘进行处理即可完成数组内元素操作,从而防止线程中分支的产生。
由于寄存器的高速读取特性,因此每次计算都离不开寄存器的参与。接着是一级缓存和共享内存,然后是常量内存、纹理内存、全局内存,最后则是主机端内存。根据不同存储器之间的存储速度的数量级的变化规律,选用适当类型的内存以及最大化地利用它们,从而发挥硬件的最大算力,减少计算时间。
@@ -83,4 +82,4 @@ GPU计算单元主要由标量计算单元和三维向量计算单元组成。
:width:`800px`
:label:`davinci_architecture`
-昇腾AI芯片的计算核心主要由AI Core构成,负责执行标量、向量和张量相关的计算密集型算子。AI Core采用了达芬奇架构,基本结构如 :numref:`davinci_architecture`所示,从控制上可以看成是一个相对简化的现代微处理器基本架构。它包括了三种基础计算单元:矩阵计算单元(Cube Unit)、向量计算单元(Vector Unit)和标量计算单元(Scalar Unit)。这三种计算单元分别对应了张量、向量和标量三种常见的计算模式,在实际的计算过程中各司其职,形成了三条独立的执行流水线,在系统软件的统一调度下互相配合达到优化计算效率的目的。 同GPU类似,在矩阵乘加速设计上,在AICore中也提供了矩阵计算单元作为昇腾AI芯片的核心计算模块,意图高效解决矩阵计算的瓶颈问题。矩阵计算单元提供强大的并行乘加计算能力,可以用一条指令完成两个$16\times16$矩阵的相乘运算,等同于在极短时间内进行了$16\times16\times16=4096$个乘加运算,并且可以实现FP16的运算精度。
+昇腾AI芯片的计算核心主要由AI Core构成,负责执行标量、向量和张量相关的计算密集型算子。AI Core采用了达芬奇架构 :cite:`2021Ascend`,基本结构如 :numref:`davinci_architecture`所示,从控制上可以看成是一个相对简化的现代微处理器基本架构。它包括了三种基础计算单元:矩阵计算单元(Cube Unit)、向量计算单元(Vector Unit)和标量计算单元(Scalar Unit)。这三种计算单元分别对应了张量、向量和标量三种常见的计算模式,在实际的计算过程中各司其职,形成了三条独立的执行流水线,在系统软件的统一调度下互相配合达到优化计算效率的目的。 同GPU类似,在矩阵乘加速设计上,在AICore中也提供了矩阵计算单元作为昇腾AI芯片的核心计算模块,意图高效解决矩阵计算的瓶颈问题。矩阵计算单元提供强大的并行乘加计算能力,可以用一条指令完成两个$16\times16$矩阵的相乘运算,等同于在极短时间内进行了$16\times16\times16=4096$个乘加运算,并且可以实现FP16的运算精度。
diff --git a/chapter_accelerator/accelerator_introduction.md b/chapter_accelerator/accelerator_introduction.md
index 3fea6b8..266c93d 100644
--- a/chapter_accelerator/accelerator_introduction.md
+++ b/chapter_accelerator/accelerator_introduction.md
@@ -1,9 +1,8 @@
-概述
-----
+## 概述
### 硬件加速器设计的意义
-未来人工智能发展的三大核心要素是数据、算法和算力。目前,人工智能系统算力大都构建在CPU+GPU之上,主体多是GPU。随着神经网络的层数越多,模型体量越大,算法越复杂,CPU和GPU很难再满足新型网络对于算力的需求。例如,2015年谷歌的AlphaGo与樊麾对弈时,用了1202个CPU和176个GPU,每盘棋需要消耗上千美元的电费,而与之对应的是樊麾的功耗仅为20瓦。
+未来人工智能发展的三大核心要素是数据、算法和算力。目前,人工智能系统算力大都构建在CPU+GPU之上,主体多是GPU。随着神经网络层数的增多,模型体量的增大,算法复杂度的上升,CPU和GPU很难再满足新型网络对于算力的需求。例如,2015年谷歌的AlphaGo与[樊麾](https://baike.baidu.com/item/樊麾)对弈时,用了1202个CPU和176个GPU,每盘棋需要消耗上千美元的电费,而与之对应的是樊麾的功耗仅为20瓦。
虽然GPU在面向向量、矩阵以及张量的计算上,引入许多新颖的优化设计,但由于GPU需要支持的计算类型复杂,芯片规模大、能耗高,人们开始将更多的精力转移到深度学习硬件加速器的设计上来。和传统CPU和GPU芯片相比,新型深度学习加速器会有更高的性能,以及更低的能耗。未来随着人们真正进入智能时代,智能应用的普及会越来越广泛,到那时每台服务器、每台智能手机、每个智能摄像头,都需要使用加速器。
diff --git a/chapter_accelerator/accelerator_programming.md b/chapter_accelerator/accelerator_programming.md
index bf33b8c..f86d5ae 100644
--- a/chapter_accelerator/accelerator_programming.md
+++ b/chapter_accelerator/accelerator_programming.md
@@ -1,5 +1,4 @@
-加速器基本编程原理
-------------------
+## 加速器基本编程原理
:label:`accelerator-program-title`
本章前两节主要介绍了硬件加速器设计的意义、思路以及基本组成原理。软硬件协同优化作为构建高效AI系统的一个重要指导思想,需要软件算法/软件栈和硬件架构在神经网络应用中互相影响、紧密耦合。为了最大限度地发挥加速器的优势,要求能够基于硬件系统架构提供易用、高效的编程方法。因此,在本节中将着重介绍加速器的可编程性,包括编程接口直接调用方式及算子编译器优化方式。最后,通过示例介绍如何通过编程使能加速器,提升神经网络算子的计算效率。
@@ -190,3 +189,5 @@ res = te.lang.cce.matmul(tensor_a, tensor_b, False, False, False, dst_dtype=dst_
4. **优化数据访存------提高并行性**:在进行内存结构变化(矩阵数据搬移)时,需要注意全局内存的合并访问、共享内存的存储体冲突等常见性能瓶颈点。
5. **资源负载均衡------增大吞吐量**:调整平衡每个线程处理的数据量、共享内存使用量、寄存器使用量,以获得更高的SM占用率。一般在实际程序中BlockTile和WarpTile的选取至关重要。
+
+6. **优化指令执行**:使用\#unroll功能进行循环展开来提升指令级并行,如 :numref:`gemm-tensor-core-algorith`中13行;使用向量化加载指令以提高带宽等,对于GPU Volta架构,最大向量化加载指令为ldg128,即128比特带宽,对于 :numref:`gemm-tensor-core-algorith`中5-6行数据由全局内存加载至共享内存时,即可采用Float4\*类型指针进行内存读取。
diff --git a/chapter_accelerator/summary.md b/chapter_accelerator/summary.md
index c19cab6..3ef0c3f 100644
--- a/chapter_accelerator/summary.md
+++ b/chapter_accelerator/summary.md
@@ -1,10 +1,16 @@
-总结
-----
+## 总结
-- 面向深度学习计算任务,加速器通常都是由多种片上缓存以及多种运算单元组成来提升性能。
+- 面向深度学习计算任务,加速器通常都是由多种片上缓存以及多种运算单元组成来提升性能。
-- 未来性能增长需要依赖架构上的改变,即需要利用可编程的硬件加速器来实现性能突破。
+- 未来性能增长需要依赖架构上的改变,即需要利用可编程的硬件加速器来实现性能突破。
-- 出于计算效率和易用性等原因,加速器一般会具有多个等级的编程方式,包括:算子库层级,编程原语层级和指令层级。
+- 出于计算效率和易用性等原因,加速器一般会具有多个等级的编程方式,包括:算子库层级,编程原语层级和指令层级。
-- 越底层的编程方式越能够灵活地制加速器,但同时对程序员的能力要求也越高。
+- 越底层的编程方式越能够灵活地控制加速器,但同时对程序员的能力要求也越高。
+
+
+## 扩展阅读
+
+- CUDA编程指导 [CUDA](https://docs.nvidia.com/cuda/cuda-c-programming-guide/index.html)
+- 昇腾社区 [Ascend](https://gitee.com/ascend)
+- MLIR应用进展 [MLIR](https://mlir.llvm.org/talks)
diff --git a/chapter_backend_and_runtime/compute_schedule_and_execute.md b/chapter_backend_and_runtime/compute_schedule_and_execute.md
index 9eb3268..3d191bd 100644
--- a/chapter_backend_and_runtime/compute_schedule_and_execute.md
+++ b/chapter_backend_and_runtime/compute_schedule_and_execute.md
@@ -169,7 +169,7 @@ compute(y, z)
- **串行执行**:将计算图展开为执行序列,按照执行序逐个串行执行,如 :numref:`graph_exec_2`所示。其特点为执行顺序固定,单线程执行,对系统资源要求相对较低。
-- **并行执行**:将计算图按照算子之间的依赖关系展开,有依赖关系的算子通过输入依赖保证执行顺序,没有依赖关系的算子则可以并行执行,如 :numref:`graph_exec_3`所示,Kernel_1和Kernel_2没有依赖可以并行执行,Kernel_3和Kernel_4没有依赖可以并行执行。其特点为执行顺序不固定,每轮执行的算子顺序大概率不一样,多线程执行,对系统资源要求相关较高。
+- **并行执行**:将计算图按照算子之间的依赖关系展开,有依赖关系的算子通过输入依赖保证执行顺序,没有依赖关系的算子则可以并行执行,如 :numref:`graph_exec_3`所示,Kernel_1和Kernel_2没有依赖可以并行执行,Kernel_3和Kernel_4没有依赖可以并行执行。其特点为执行顺序不固定,每轮执行的算子顺序大概率不一样,多线程执行,对系统资源要求相对较高。
串行执行和并行执行各有优点和缺点,总结对比见 :numref:`serial_vs_parallel`。
@@ -197,9 +197,9 @@ compute(y, z)
将一张异构计算图切分为多个子计算图后,执行方式一般分为子图拆分执行和子图合并执行:
-- **子图拆分执行**:将切分后的多个子图分开执行,即一个子图执行完再执行另一个子图,如 :numref:`graph_exec_6`所示,上一个子图的输出数据会传输给下一个子图的输入数据,并且下一个子图需要对输入数据拷贝为本图的device数据,如Graph_2\_GPU需要将Graph_1\_CPU的输出数据从CPU拷贝到GPU,反过来Graph_3\_CPU需要将Graph2GPU的输出数据从GPU拷贝到CPU,子图之间互相切换执行有一定的开销。
+- **子图拆分执行**:将切分后的多个子图分开执行,即一个子图执行完再执行另一个子图,如 :numref:`graph_exec_6`所示,上一个子图的输出数据会传输给下一个子图的输入数据,并且下一个子图需要将输入数据拷贝为本图的device数据,如Graph_2\_GPU需要将Graph_1\_CPU的输出数据从CPU拷贝到GPU,反过来Graph_3\_CPU需要将Graph2GPU的输出数据从GPU拷贝到CPU,子图之间互相切换执行有一定的开销。
-- **子图合并执行**:将切分后的多个子图进行合并,合并为一个整体大的DAG执行,如 :numref:`graph_exec_7`所示,通过算子的设备属性来插入拷贝算子以实现不同设备上的算子数据传输,并且拷贝算子也是进入整图中的,从而形成一个大的整图执行,减少子图之间的切换执行开销。
+- **子图合并执行**:将切分后的多个子图进行合并,合并为一个整体的DAG执行,如 :numref:`graph_exec_7`所示,通过算子的设备属性来插入拷贝算子以实现不同设备上的算子数据传输,并且拷贝算子也是进入整图中的,从而形成一个大的整图执行,减少子图之间的切换执行开销。

:width:`800px`
diff --git a/chapter_backend_and_runtime/index.md b/chapter_backend_and_runtime/index.md
index d23a4e8..5d166f9 100644
--- a/chapter_backend_and_runtime/index.md
+++ b/chapter_backend_and_runtime/index.md
@@ -15,6 +15,8 @@
- 掌握内存分配的常用方法
+- 掌握计算图调度和执行的常用方法
+
```toc
:maxdepth: 2
diff --git a/chapter_backend_and_runtime/kernel_selecter.md b/chapter_backend_and_runtime/kernel_selecter.md
index 91f3387..d2262a5 100644
--- a/chapter_backend_and_runtime/kernel_selecter.md
+++ b/chapter_backend_and_runtime/kernel_selecter.md
@@ -29,17 +29,17 @@
对于NCHW的数据是先取W轴方向数据,再取H轴方向数据,再取C轴方向,最后取N轴方向。其中物理存储与逻辑存储的之间的映射关系为
$$offsetnchw(n,c,h,w) = n*CHW + c*HW + h*W +w$$
-如 :numref:`nchw`所示,这种格式中,是按照最低维度W轴方向进行展开,W轴相邻的元素在内存排布中同样是相邻的。如果需要取下一个图片上的相同位置的元素,就必须跳过整个图像的尺寸($C*H*W$)。比如我有8张32\*32的RGB图像,此时$N=8,C=3,H=32,W=32$。在内存中存储们需要先按照W轴方向进行展开,然后按照H轴排列,这样之后便完成了一个通道的处理,之后按照同样的方式处理下一个通道。处理完全部通道后,处理下一张图片。PyTorch和MindSpore框架默认使用NCHW格式。
+如 :numref:`nchw`所示,这种格式中,是按照最低维度W轴方向进行展开,W轴相邻的元素在内存排布中同样是相邻的。如果需要取下一个图片上的相同位置的元素,就必须跳过整个图像的尺寸($C*H*W$)。比如我有8张32\*32的RGB图像,此时$N=8,C=3,H=32,W=32$。在内存中存储它们需要先按照W轴方向进行展开,然后按照H轴排列,这样之后便完成了一个通道的处理,之后按照同样的方式处理下一个通道。处理完全部通道后,处理下一张图片。PyTorch和MindSpore框架默认使用NCHW格式。

:width:`800px`
:label:`nchw`
类似的NHWC数据格式是先取C方向数据,再取W方向,然后是H方向,最后取N方向。NHWC是Tensorflow默认的数据格式。这种格式在PyTorch中称为Chanel-Last。
-$$offsetnchw(n,c,h,w) = n*HWC + h*HW + w*C +c$$
+$$offsetnhwc(n,h,w,c) = n*HWC + h*WC + w*C +c$$
:numref:`nchwandnhwc`展示了不同数据格式下逻辑排布到内存物理侧数据排布的映射。\[x:1\]代表从最内侧维度到最下一维度的索引变换。比如\[a:1\]表示当前行W轴结束后,下一个H轴排布。\[b:1\]表示最内侧C轴排布完成后进行按照W轴进行排列。
-
+
:width:`800px`
:label:`nchwandnhwc`
@@ -56,7 +56,7 @@ Precision)浮点表示。这种数据类型占用32位内存。还有一种精
:width:`800px`
:label:`floatdtype`
-如 :numref:`floatdtype`其中sign代表符号位,占1位,表示了机器数的正负,exponent表示指数位,Mantissa为尾数位。其数据计算采用二进制的科学计数法转换为十进制的计算方式如下:
+如 :numref:`floatdtype`其中sign代表符号位,占1位,表示了机器数的正负,exponent表示指数位,Mantissa为尾数位。其中float16类型的数据采用二进制的科学计数法转换为十进制的计算方式如下:
$$(-1)^{sign}\times 2^{exponent-15}\times (\frac{mantissa}{1024}+1)$$
其中如果指数位全为0时,且尾数位全为0时表示数字0。
如果指数位全为0,尾数位不全为0则表示一个非常小的数值。
diff --git a/chapter_backend_and_runtime/memory_allocator.md b/chapter_backend_and_runtime/memory_allocator.md
index 09ce17f..d07e8c0 100644
--- a/chapter_backend_and_runtime/memory_allocator.md
+++ b/chapter_backend_and_runtime/memory_allocator.md
@@ -15,7 +15,7 @@ In-Place内存分配还可以提高某些算子的执行效率。
### 内存分配 {#内存分配-1}
内存分配模块主要负责给图中算子的输入、输出分配Device内存。用户的前端脚本经过编译器前端处理后得到中间表达,后端根据中间表达进行算子选择和相关优化,可以得到算子最终的输入输出Tensor的形状、数据类型(Data
-Type)、格式(Format)等信息,根据这些信息我们可以计算出算子输入、输出Tensor的尺寸大小。基本的计算方法为:
+Type)、格式(Format)等信息,根据这些信息我们可以计算出算子输入、输出Tensor的尺寸大小。基本的计算方法为:
$$size=\left (\prod_{i=0}^{dimension}shape_i\right ) * sizeof\left ( data type \right )$$
得到Tensor的尺寸大小后,往往还需要对内存大小进行对齐操作。内存通常以4字节、8字节或16字节为一组进行访问,如果被搬运的内存大小不是这些值的倍数,内存后面会填充相应数量的空数据以使得内存长度达到这些值的倍数。因此,访问非对齐的内存可能会更加耗时。
@@ -24,9 +24,9 @@ $$size=\left (\prod_{i=0}^{dimension}shape_i\right ) * sizeof\left ( data type \
:label:`memory_allocate`
下面以 :numref:`memory_allocate`为例介绍内存分配的大致流程。首先我们会给Input
-Tensor、Conv2D的权重和Conv2D的输出分配内存地址。然后为BatchNorm的输入分配地址时,我们发现BatchNorm的输入就是Conv2D算子的输出,而该Tensor的地址已经在之前分配过了,因此只需要将Conv2D算子的输出地址共享给BatchNorm的输入,就可以避免内存的重复申请以及内存的冗余拷贝。以此类推,可以发现整个过程中可以将待分配的内存分成三种类型:一是整张图的输入Tensor,二是算子的权重或者属性,三是算子的输出Tensor,三种Tensor在训练过程中的生命周期有所不同。
+Tensor、Conv2D的权重和Conv2D的输出分配内存地址。然后为BatchNorm的输入分配地址时,我们发现BatchNorm的输入就是Conv2D算子的输出,而该Tensor的地址已经在之前分配过了,因此只需要将Conv2D算子的输出地址共享给BatchNorm的输入,就可以避免内存的重复申请以及内存的冗余拷贝。以此类推,可以发现整个过程中可以将待分配的内存分成三种类型:一是整张图的输入Tensor,二是算子的权重或者属性,三是算子的输出Tensor,三种类型在训练过程中的生命周期有所不同。
-在CPU上我们常常使用malloc函数直接申请内存,这种方式申请内存好处是随时申请随时释放,简单易用。然而在许多对性能要求严苛的计算场景中,由于所申请内存块的大小不定,频繁申请释放会降低性能。通常我们会使用内存池的方式去管理内存,先申请一定数量和大小的内存块留作备用,当程序有内存申请需求时,直接从内存池中的内存块中申请。当程序释放该内存块时,内存池会进行回收并用作后续程序内存申请时使用。
+在CPU上我们常常使用malloc函数直接申请内存,这种方式申请内存好处是随时申请随时释放,简单易用。然而在许多对性能要求严苛的计算场景中,由于所申请内存块的大小不定,频繁申请释放会降低性能。通常我们会使用内存池的方式去管理内存,先申请一定数量的内存块留作备用,当程序有内存申请需求时,直接从内存池中的内存块中申请。当程序释放该内存块时,内存池会进行回收并用作后续程序内存申请时使用。
在深度学习框架中,Device内存的申请也是非常频繁的,往往也是通过内存池的方式去管理Device内存,并让Device内存的生命周期与Tensor的生命周期保持一致。不同的深度学习框架在内存池的设计上大同小异,我们以 :numref:`device_malloc`的MindSpore框架内存申请为例,进程会从Device上申请足够大的内存,然后通过双游标从两端偏移为Tensor分配内存。首先从申请的首地址开始进行偏移,为算子权重的Tensor分配内存,这部分Tensor生命周期较长,往往持续整个训练过程。然后从申请Device地址的末尾开始偏移,为算子的输出Tensor分配内存,这部分内存的生命周期较短,往往在该算子计算结束并且后续计算过程中无需再次使用该算子的输出的情况下,其生命周期就可以结束。通过这种方式,我们只需要从Device上申请一次足够大的内存,后续算子的内存分配都是通过指针偏移进行分配,减少了直接从设备申请内存的耗时。

@@ -48,13 +48,13 @@ Tensor、Conv2D的权重和Conv2D的输出分配内存地址。然后为BatchNor
SOMAS(Safe Optimized Memory Allocation
Solver)。SOMAS将计算图并行流与数据依赖进行聚合分析,得到算子间祖先关系,构建张量全局生命周期互斥约束,使用多种启发式算法求解最优的内存静态规划,实现逼近理论极限的内存复用,从而提升支持的内存大小。
-由 :numref:`combine_memory_reuse_and_no_reuse`右边可知,经过SOMAS求解之后,同样的内存大小,可支持的Tensor数量达到了7个。
+由 :numref:`combine_memory_reuse_and_no_reuse`右边所示,经过SOMAS求解之后,同样的内存大小,可支持的Tensor数量达到了7个。
### 常见的内存分配优化手段
#### 内存融合
-上述内存分配的方式,都是以单个Tensor的维度去分配的,每个Tensor分配到的Device地址往往是离散的。但是对于某些特殊的算子,如AllReduce通信算子,我们需要为它们分配连续的内存。通信算子的执行包含通信等待、数据搬移、计算等步骤,而在大规模分布式集群的场景下,通信的耗时往往是性能瓶颈。针对这种场景,我们可以将多个通信算子融合成一个,为通信算子的输入分配连续的内存,从而减少通信的次数。
+上述内存分配的方式,都是以单个Tensor的维度去分配的,每个Tensor分配到的Device地址往往是离散的。但是对于某些特殊的算子,如AllReduce通信算子,我们需要为它们分配连续的内存。通信算子的执行包含通信等待、数据搬移、计算等步骤,而在大规模分布式集群的场景下,通信的耗时往往是性能瓶颈。针对这种场景,如 :numref:`memory_fusion`所示,我们可以将多个通信算子融合成一个,为通信算子的输入分配连续的内存,从而减少通信的次数。
又比如分布式训练中的神经网络权重初始化,通常将一个训练进程中的权重初始化,然后将该权重广播到其他进程中。当一个网络有较多权重的时候,需要多次进行广播。通常可以为所有权重分配连续的内存地址,然后广播一次,节省大量通信的耗时。

diff --git a/chapter_backend_and_runtime/overview.md b/chapter_backend_and_runtime/overview.md
index ef96e54..77a0dc8 100644
--- a/chapter_backend_and_runtime/overview.md
+++ b/chapter_backend_and_runtime/overview.md
@@ -2,9 +2,9 @@
编译器前端主要将用户代码进行解析翻译得到计算图IR并对其进行设备信息无关的优化,此时我们并不考虑程序执行的底层硬件信息。编译器后端的主要职责对前端下发的IR做进一步的计算图优化,让其更加贴合硬件,并为IR中的计算节点选择适合在硬件上执行的算子,然后为每个算子的输入输出分配硬件内存,最终生成一个可以在硬件上执行的任务序列。
-如 :numref:`compiler-backend-architecture`所示,编译器后端处于前端和硬件驱动层中间,主要负责计算图优化、算子选择和内存分配的任务。首先,需要根据硬件设备的特性将IR图进行等价图变换,以便在硬件上能够找到对应的执行算子,该过程是计算图优化的重要步骤之一。前端IR生成是解析用户代码,属于一个较高的抽象层次,隐藏一些底层运行的细节信息,此时无法直接对应硬件上的算子(算子是设备上的基本计算序列,例如MatMul、Convolution和ReLU等),需要将细节信息进行展开后,才能映射到目标硬件上的算子。对于某些前端IR的子集来说,一个算子便能够执行对应的功能,此时可以将这些IR节点进行合并成为一个计算节点,该过程称之为算子融合;对于一些复杂计算,后端并没有直接与之对应的算子,但是可以通过几个基本运算的算子组合达到同样的计算效果,此时可以将前端IR节点拆分成多个小算子。然后,我们需要进行算子选择。算子选择是在得到优化的IR图后,需要选取最合适的目标设备算子。针对用户代码所产生的IR往往可以映射成多种不同的硬件算子,但是生成不同的算子执行效率往往有很大的差别,如何根据前端IR选择出最高效的算子,是算子选择的核心问题。算子选择本质上是一个模式匹配问题。其最简单的方法就是每一个IR节点对应一个目标硬件的算子,但是这种方法往往对目标硬件的资源利用比较差。目前来说对于现有的编译器一般都对每一个IR节点提供了多个候选的算子,算子选择目标就是从中选择最优的一个算子作为最终执行在设备上的算子。总的来说,在机器学习系统中,对前端生成的IR图上的各个节点进行拆分和融合,让前端所表示的高层次IR逐步转换为可以在硬件设备上执行的低层次IR。得到了这种更加贴合硬件的IR后,对于每个单节点的IR可能仍然有很多种不同的选择,例如可以选择不同的输入输出格式和数据类型,我们需要对IR图上每个节点选择出最为合适的算子,算子选择过程可以认为是针对IR图的细粒度优化过程,最终生成完整的算子序列。最后,遍历算子序列,为每个算子分配相应的输入输出内存,然后将算子加载到设备上执行计算。
+如 :numref:`compiler-backend-architecture`所示,编译器后端处于前端和硬件驱动层中间,主要负责计算图优化、算子选择和内存分配的任务。首先,需要根据硬件设备的特性将IR图进行等价图变换,以便在硬件上能够找到对应的执行算子,该过程是计算图优化的重要步骤之一。前端IR生成是解析用户代码,属于一个较高的抽象层次,隐藏一些底层运行的细节信息,此时无法直接对应硬件上的算子(算子是设备上的基本计算序列,例如MatMul、Convolution和ReLU等),需要将细节信息进行展开后,才能映射到目标硬件上的算子。对于某些前端IR的子集来说,一个算子便能够执行对应的功能,此时可以将这些IR节点合并成为一个计算节点,该过程称之为算子融合;对于一些复杂计算,后端并没有直接与之对应的算子,但是可以通过几个基本运算的算子组合达到同样的计算效果,此时可以将前端IR节点拆分成多个小算子。然后,我们需要进行算子选择。算子选择是在得到优化的IR图后,需要选取最合适的目标设备算子。针对用户代码所产生的IR往往可以映射成多种不同的硬件算子,但是生成不同的算子执行效率往往有很大的差别,如何根据前端IR选择出最高效的算子,是算子选择的核心问题。算子选择本质上是一个模式匹配问题。其最简单的方法就是每一个IR节点对应一个目标硬件的算子,但是这种方法往往对目标硬件的资源利用比较差。目前来说对于现有的编译器一般都对每一个IR节点提供了多个候选的算子,算子选择目标就是从中选择最优的一个算子作为最终执行在设备上的算子。总的来说,在机器学习系统中,对前端生成的IR图上的各个节点进行拆分和融合,让前端所表示的高层次IR逐步转换为可以在硬件设备上执行的低层次IR。得到了这种更加贴合硬件的IR后,对于每个单节点的IR可能仍然有很多种不同的选择,例如可以选择不同的输入输出格式和数据类型,我们需要对IR图上每个节点选择出最为合适的算子,算子选择过程可以认为是针对IR图的细粒度优化过程,最终生成完整的算子序列。最后,遍历算子序列,为每个算子分配相应的输入输出内存,然后将算子加载到设备上执行计算。
-
+
:width:`800px`
:label:`compiler-backend-architecture`
@@ -19,3 +19,7 @@
### 内存分配
经过计算图优化和算子选择之后,我们可以得到IR图中每个算子的输入输出的形状(Shape)、数据类型、存储格式。根据这些信息,计算输入输出数据的大小,并为输入输出分配设备上的内存,然后将算子加载到设备上才能真正执行计算。此外,为了更充分地例用设备内存资源,可以对内存进行复用,提高内存利用率。
+
+### 计算调度与执行
+
+经过算子选择与内存分配之后,计算任务可以通过运行时完成计算的调度与在硬件上的执行。根据是否将算子编译为计算图,计算的调度可以分为单算子调度与计算图调度两种方式。而根据硬件提供的能力差异,计算图的执行方式又可以分为逐算子下发执行的交互式执行以及将整个计算图或者部分子图一次性下发到硬件的下沉式执行两种模式。
diff --git a/chapter_backend_and_runtime/summary.md b/chapter_backend_and_runtime/summary.md
index aec36cb..054a7e3 100644
--- a/chapter_backend_and_runtime/summary.md
+++ b/chapter_backend_and_runtime/summary.md
@@ -16,4 +16,9 @@
- 将通信算子的内存进行融合,可以提高通信的效率;合理分配In-Place算子的内存,可以节省内存使用并且提高计算效率。
-- 运行时对于算子的执行可以分为单算子调度和计算图调度两种模式,而在计算图调度模式中,根据具体硬件的能力又可以分为交互式执行和下沉式执行两种方式,交互式执行具备更多的灵活性,下沉执行可以获得更好的计算性能。
\ No newline at end of file
+- 运行时对于算子的执行可以分为单算子调度和计算图调度两种模式,而在计算图调度模式中,根据具体硬件的能力又可以分为交互式执行和下沉式执行两种方式,交互式执行具备更多的灵活性,下沉执行可以获得更好的计算性能。
+
+## 扩展阅读
+
+- 内存分配作为机器学习后端的重要部分,建议阅读 [Sublinear Memory Cost](https://arxiv.org/abs/1604.06174)、 [Dynamic Tensor Rematerialization](https://arxiv.org/abs/2006.09616)。
+- 对于运行时的调度以及执行,建议阅读 [A Lightweight Parallel and Heterogeneous Task Graph Computing System](https://arxiv.org/abs/2004.10908)、 [Dynamic Control Flow in Large-Scale Machine Learning](https://arxiv.org/abs/1805.01772)、[DEEP LEARNING WITH DYNAMIC COMPUTATION GRAPHS](https://arxiv.org/abs/1702.02181)。
\ No newline at end of file
diff --git a/chapter_computational_graph/background_and_functionality.md b/chapter_computational_graph/background_and_functionality.md
index 579f590..c073834 100644
--- a/chapter_computational_graph/background_and_functionality.md
+++ b/chapter_computational_graph/background_and_functionality.md
@@ -5,10 +5,10 @@
:label:`dag`
早期的机器学习框架主要为了支持基于卷积神经网络的图像分类问题。这些神经网络的拓扑结构简单(神经网络层往往通过串行构建),他们的拓扑结构可以用简单的配置文件来表达(例如Caffe中基于Protocol
-Buffer格式的模型定义)。随着机器学习的进一步发展,模型的拓扑日益复杂(包括混合专家,生成对抗网络,多注意力模型)。这些模型复杂的拓扑结构(例如说,分支结构,带有条件的if-else循环)会影响模型算子的执行、自动化梯度计算(一般称为自动微分)以及训练参数的自动化判断。为此,我们需要一个更加通用的技术来执行任意机器学习模型。因此,计算图应运而生。综合来看,计算图对于一个机器学习框架提供了以下几个关键作用:
+Buffer格式的模型定义)。随着机器学习的进一步发展,模型的拓扑日益复杂(包括混合专家,生成对抗网络,多注意力模型)。这些复杂的模型拓扑结构(例如:分支结构,带有条件的if-else循环)会影响模型算子的执行、自动化梯度计算(一般称为自动微分)以及训练参数的自动化判断。为此,我们需要一个更加通用的技术来执行任意机器学习模型,计算图应运而生。综合来看,计算图对于一个机器学习框架提供了以下几个关键作用:
-- **对于输入数据,算子和算子执行顺序的统一表达。**
- 机器学习框架用户可以用多种高层次编程语言(Python,Julia和C++)来编写训练程序。这些高层次程序需要统一的表达成框架底层C和C++算子的执行。因此,计算图的第一个核心作用是可以作为一个统一的数据结构来表达用户用不同语言编写的训练程序。这个数据结构可以准确表述用户的输入数据,模型所带有的多个算子,以及算子之间的执行顺序。
+- **对于输入数据、算子和算子执行顺序的统一表达。**
+ 机器学习框架用户可以用多种高层次编程语言(Python,Julia和C++)来编写训练程序。这些高层次程序需要统一的表达成框架底层C和C++算子的执行。因此,计算图的第一个核心作用是可以作为一个统一的数据结构来表达用户用不同语言编写的训练程序。这个数据结构可以准确表述用户的输入数据、模型所带有的多个算子,以及算子之间的执行顺序。
- **定义中间状态和模型状态。**
在一个用户训练程序中,用户会生成中间变量(神经网络层之间传递的激活值和梯度)来完成复杂的训练过程。而这其中,只有模型参数需要最后持久化,从而为后续的模型推理做准备。通过计算图,机器学习框架可以准确分析出中间状态的生命周期(一个中间变量何时生成,以及何时销毁),从而帮助框架更好的管理内存。
@@ -16,5 +16,5 @@ Buffer格式的模型定义)。随着机器学习的进一步发展,模型
- **自动化计算梯度。**
用户给定的训练程序仅仅包含了一个机器学习模型如何将用户输入(一般为训练数据)转化为输出(一般为损失函数)的过程。而为了训练这个模型,机器学习框架需要分析任意机器学习模型和其中的算子,找出自动化计算梯度的方法。计算图的出现让自动化分析模型定义和自动化计算梯度成为可能。
-- **高效程序执行。**
+- **优化程序执行。**
用户给定的模型程序往往是"串行化"地连接起来多个神经网络层。通过利用计算图来分析模型中算子的执行关系,机器学习框架可以更好地发现将算子进行异步执行的机会,从而以更快的速度完成模型程序的执行。
\ No newline at end of file
diff --git a/chapter_computational_graph/components_of_computational_graph.md b/chapter_computational_graph/components_of_computational_graph.md
index de587e4..ce5588f 100644
--- a/chapter_computational_graph/components_of_computational_graph.md
+++ b/chapter_computational_graph/components_of_computational_graph.md
@@ -1,13 +1,13 @@
## 计算图的基本构成
-计算图是用来表示深度学习网络模型在训练与推理过程中计算逻辑与状态的工具。计算框架在后端会将前端语言构建的神经网络模型前向计算与反向梯度计算以计算图的形式来进行表示。计算图由基本数据结构张量(Tensor)和基本运算单元算子(Operator)构成。在计算图中通常使用节点来表示算子,节点间的有向线段来表示张量状态,同时也描述了计算间的依赖关系。如 :numref:`simpledag`所示,将$\boldsymbol{Z}=relu(\boldsymbol{X}*\boldsymbol{Y})$转化为计算图表示,数据流将根据图中流向与算子进行前向计算和反向梯度计算来更新图中张量状态,以此达到训练模型的目的。
+计算图是用来表示深度学习网络模型在训练与推理过程中计算逻辑与状态的工具。计算框架在后端会将前端语言构建的神经网络模型前向计算与反向梯度计算以计算图的形式来进行表示。计算图由基本数据结构:张量(Tensor)和基本运算单元:算子(Operator)构成。在计算图中通常使用节点来表示算子,节点间的有向线段来表示张量状态,同时也描述了计算间的依赖关系。如 :numref:`simpledag`所示,将$\boldsymbol{Z}=relu(\boldsymbol{X}*\boldsymbol{Y})$转化为计算图表示,数据流将根据图中流向与算子进行前向计算和反向梯度计算来更新图中张量状态,以此达到训练模型的目的。

:width:`300px`
:label:`simpledag`
### 张量和算子
-在计算框架中,基础组件包含张量和算子,张量是基础数据结构,算子是基本运算单元。在数学中定义张量是基于向量与矩阵的推广,涵盖标量、向量与矩阵的概念。可以将标量理解为零阶张量,向量为一阶张量,我们熟悉的RGB彩色图像即为三阶张量。在计算框架中张量不仅存储数据,还存储数据类型、数据形状、维度或秩以及梯度传递状态等多个属性,如表3.2.1所示,列举了主要的属性和功能。
+在计算框架中,基础组件包含张量和算子,张量是基础数据结构,算子是基本运算单元。在数学中定义张量是基于向量与矩阵的推广,涵盖标量、向量与矩阵的概念。可以将标量理解为零阶张量,向量为一阶张量,我们熟悉的RGB彩色图像即为三阶张量。在计算框架中张量不仅存储数据,还存储数据类型、数据形状、维度或秩以及梯度传递状态等多个属性,如:numref:`tensor_attr`所示,列举了主要的属性和功能。
:张量属性
@@ -145,7 +145,7 @@ $$
其中$\nabla_{\boldsymbol{X}}\boldsymbol{z}$表示$\boldsymbol{z}$关于$\boldsymbol{X}$的梯度矩阵。
-上一小节中简单的循环控制模型前向传播可以表示为$\boldsymbol{Y}=\boldsymbol{W_2}(\boldsymbol{W_1}(\boldsymbol{W}(\boldsymbol{X})))$。在反向传播的过程中可以将前向计算等价为$\boldsymbol{Y}=\boldsymbol{W_2}\boldsymbol{X_2}$,首先得到参数$\boldsymbol{W_2}$的梯度表示。再接着根据$\boldsymbol{X_2}=\boldsymbol{W_1}\boldsymbol{X_1}$得到$\boldsymbol{W_1}$的梯度表示,按照层级即可推导得出$\boldsymbol{W}$的梯度表示。
+上一小节中简单的循环控制模型前向传播可以表示为$\boldsymbol{Y}=\boldsymbol{W_2}(\boldsymbol{W_1}(\boldsymbol{W}(\boldsymbol{X})))$。在反向传播的过程中可以将前向计算等价为$\boldsymbol{Y}=\boldsymbol{W_2}\boldsymbol{X_2}$,首先得到参数$\boldsymbol{W_2}$的梯度表示。再接着根据$\boldsymbol{X_2}=\boldsymbol{W_1}\boldsymbol{X_1}$得到$\boldsymbol{W_1}$的梯度表示,按照层级即可推导得出$\boldsymbol{W}$的梯度表示:
$$
\begin{aligned}
diff --git a/chapter_computational_graph/generation_of_computational_graph.md b/chapter_computational_graph/generation_of_computational_graph.md
index 1bf7216..726e200 100644
--- a/chapter_computational_graph/generation_of_computational_graph.md
+++ b/chapter_computational_graph/generation_of_computational_graph.md
@@ -22,19 +22,19 @@ def model(X, flag):
```
完成前端语言的模型完整构建表达后,执行模型运算时不会直接接收输入数据进行计算,而是使用计算框架的编译器对模型进行编译。由于在进行静态生成编译时并不读取输入数据,此时需要一种特殊的张量来表示输入数据辅助构建完整的计算图,这种特殊张量就被称之为"数据占位符"。在上述的伪代码中输入数据**X**需要使用占位符在静态图中表示。构造伪代码中的条件控制时,由于在静态图模式下构建网络并没有执行任何计算,对于条件控制在编译阶段并不会进行逻辑运算完成判断,因此需要将条件控制算子以及所有的分支计算子图加入计算图中。在执行阶段网络接受数据流入,调度条件控制算子时进行逻辑判断,控制数据流入不同的分支计算子图中进行后续计算。由于控制流和静态生成的特殊性,在部分计算框架中前端语言Python的控制流不能够被正确编译为等价的静态图结构,因此需要使用复杂的图内方法实现控制流。
-在后续的章节中我们会继续深入了解计算框架静态生成图结构的过程。静态生成的过程是采用计算框架编译器将代码编译为中间表示。计算框架编译器受传统编译器方案启发,设计体系结构包含两部分编译器前端和编译器后端。中间表示承上启下贯穿前端和后端,是前端源代码和目标硬件代码之间的中间数据格式。在计算框架编译器中中间表示以计算图形式存在,编译器会根据前端神经网络模型自动构建完整的前向计算图和反向计算图。
+在后续的章节中我们会继续深入了解计算框架静态生成图结构的过程。静态生成的过程是采用计算框架编译器将代码编译为中间表示。计算框架编译器受传统编译器方案启发,设计体系结构包含两部分:编译器前端和编译器后端。中间表示承上启下贯穿前端和后端,是前端源代码和目标硬件代码之间的中间数据格式。在计算框架编译器中中间表示以计算图形式存在,编译器会根据前端神经网络模型自动构建完整的前向计算图和反向计算图。

:width:`800px`
:label:`staticgen`
-经过编译后获取完整的计算图,能够根据全局信息完成图优化策略,进行编译优化形成与模型完全等价的静态图。编译器前端负责完成计算图与硬件无关的转换和优化,比如算子融合将网络中的两个或多个细粒度的算子融合为一个粗粒度算子,比如 :numref:`staticgen`中将*add*算子与*relu*合并为一个操作,可节省中间计算结果的存储、读取等过程,降低框架底层算子调度的开销,从而提升执行性能和效率。编译器后端负责与硬件相关的计算图优化、代码指令生成和编译,优化手段包括硬件算子选择、内存分配、内存复用等,提高算子执行效率和内存利用效率,降低内存开销。编译器后端因此使用静态图模型运行往往能够获取更好的性能和更少的内存占用。在后续章节中将详细介绍更多编译器前端和编译器后端的优化策略。
+经过编译后获取完整的计算图,能够根据全局信息完成图优化策略,进行编译优化形成与模型完全等价的静态图。编译器前端负责完成计算图与硬件无关的转换和优化,比如算子融合将网络中的两个或多个细粒度的算子融合为一个粗粒度算子,比如 :numref:`staticgen`中将*add*算子与*relu*合并为一个操作,可节省中间计算结果的存储、读取等过程,降低框架底层算子调度的开销,从而提升执行性能和效率。编译器后端负责与硬件相关的计算图优化、代码指令生成和编译,优化手段包括硬件算子选择、内存分配、内存复用等,提高算子执行效率和内存利用效率,降低内存开销。编译器后端因此使用静态图模型运行往往能够获取更好的性能和更少的内存占用。在后续章节中将详细介绍更多编译器前端和编译器后端的优化策略。
优化完成的计算图通过编译器后端根据计算硬件来生成适配的执行代码。在执行阶段,调用执行器接受输入数据,依据计算图调度算子执行训练或者推理任务。在训练任务调度算子执行时,由于在执行阶段已经编译获取模型整体结构,计算框架可以利用自动并行算法制定合理的模型切分与并行策略,进一步提高计算效率。
-使用静态图构建模型,编译构建完整的计算图后,计算图可以进行序列化保存,并且再次执行时允许使用序列化模型直接进行训练或推理,不需要再次编译前端语言源代码。得益于编译器前端、中间表示、编译器后端多级的计算框架编译器体系结构,编译器后端可以将神经网络模型中间表示转换为不同硬件代码。结合计算图序列化和计算图可转换多种部署硬件代码两种特性,使得静态图模型可以直接部署在不同的硬件上面,提供高效的推理服务。
+使用静态图构建模型,编译构建完整的计算图后,计算图可以进行序列化保存,再次执行时允许使用序列化模型直接进行训练或推理,无需重新编译前端语言源代码。得益于编译器前端、中间表示、编译器后端多级的计算框架编译器体系结构,编译器后端可以将神经网络模型中间表示转换为不同硬件代码。结合计算图序列化和计算图可转换成多种硬件代码两种特性,静态图模型可以直接部署在不同的硬件上面,提供高效的推理服务。
-尽管静态图具备强大的执行计算性能与直接部署能力,但是在部分计算框架中静态图模式下,使用前端语言编写神经网络模型以及定义模型训练过程代码较为繁琐,尤其掌握图内控制流方法具备一定的学习难度,因此熟练掌握并使用静态图模式对于初学者并不友好。其次,静态生成采用先编译后执行的方式,编译阶段和执行阶段分离,前端语言构建的神经网络模型经过编译后,计算图结构便固定执行阶段不再改变,并且经过优化用于执行的计算图结构与原始代码有较大的差距,导致代码中的错误难以定位到准确位置,增加了代码调试难度。此外在神经网络模型开发迭代环节,不能即时打印中间结果。若在源码中添加输出中间结果的代码,则需要将源码重新编译后,再调用执行器才能获取相关信息,降低了代码调试效率。而动态图模式则拥有更加灵活的特性,接下来讲解动态生成机制。
+尽管静态图具备强大的执行计算性能与直接部署能力,但是在部分计算框架中静态图模式下,使用前端语言编写神经网络模型以及定义模型训练过程代码较为繁琐,尤其掌握图内控制流方法具备一定的学习难度,因此熟练掌握并使用静态图模式对于初学者并不友好。其次,静态生成采用先编译后执行的方式,编译阶段和执行阶段分离,前端语言构建的神经网络模型经过编译后,计算图结构便固定执行阶段不再改变,并且经过优化用于执行的计算图结构与原始代码有较大的差距,导致代码中的错误难以定位到准确位置,增加了代码调试难度。此外在神经网络模型开发迭代环节,不能即时打印中间结果。若在源码中添加输出中间结果的代码,则需要将源码重新编译后,再调用执行器才能获取相关信息,降低了代码调试效率。而动态图模式则更加灵活,接下来讲解动态生成机制。
### 动态生成
@@ -44,7 +44,7 @@ def model(X, flag):
:width:`600px`
:label:`dynamic`
-由于动态图模式的编程友好性,动态图被广大深度学习研究者青睐使用。接下来使用上一小节的伪代码来讲解动态生成和静态生成的区别。
+由于动态图模式的编程友好性,动态图深受广大深度学习研究者青睐。接下来使用上一小节的伪代码来讲解动态生成和静态生成的区别。
尽管静态图和动态图在前端语言表达上略有差异,但本质的区别在于静态生成和动态生成的编译执行过程不同。使用前端语言构建完成模型表达后,动态生成并不采用计算框架编译器生成完整的静态计算图,而是采用前端语言的解释器Python API调用计算框架,框架利用自身的算子分发功能,将Python调用的算子在相应的硬件如CPU、GPU、NPU等上进行加速计算,然后再将计算结果返回给前端。该过程并不产生静态的计算图,而是按照前端语言描述模型结构,按照计算依赖关系进行调度执行,动态生成临时的图拓扑结构。
@@ -58,7 +58,7 @@ def model(X, flag):
对应于 :numref:`dynamicgen`中,当调用到关于张量$\boldsymbol{W1}$的*matmul*算子节点时,框架会执行两个操作:调用*matmul*算子,计算关于输入$\boldsymbol{X}$和$\boldsymbol{W1}$的乘积结果,同时根据反向计算过程$\boldsymbol{Grad\_W1}=\boldsymbol{Grad\_Y}*\boldsymbol{X}$,记录下需要参与反向计算的算子和张量$\boldsymbol{X}$。计算框架依照算子调度顺序记录参与反向计算的算子和张量。当前向计算执行完毕,计算框架根据动态生成的前向计算图结构拓扑关系,利用记录的反向计算算子和张量动态生成反向计算图,最终完成神经网络模型的梯度计算和参数更新。
-尽管动态生成中完整的网络结构在执行前是未知的,不能使用静态图中的图优化技术来提高计算执行性能。但其即刻算子调用与计算的能力,使得模型代码在运行的时候,每执行一句立即进行运算并会返回具体的值,方便开发者在模型构建优化过程中进行错误分析、结果查看等调试工作,为研究和实验提供了高效的助力。
+尽管动态生成中完整的网络结构在执行前是未知的,不能使用静态图中的图优化技术来提高计算执行性能。但其即刻算子调用与计算的能力,使得模型代码在运行的时候,每执行一句就会立即进行运算并会返回具体的值,方便开发者在模型构建优化过程中进行错误分析、结果查看等调试工作,为研究和实验提供了高效的助力。
此外得益于动态图模式灵活的执行计算特性,动态生成可以使用前端语言的原生控制流,充分发挥前端语言的编程友好性特性。解决了静态图中代码难调试、代码编写繁琐以及控制流复杂等问题,对于初学者更加友好,提高了算法开发迭代效率和神经网络模型改进速率。
@@ -136,8 +136,8 @@ def model(X, flag):
|框架|动态图转静态图|
| :-:| :---: |
| TensorFlow |@tf_function追踪算子调度构建静态图,
其中AutoGraph机制可以自动转换控制流为静态表达 |
-| MindSpore | context.set_context(mode=context.PYNATIVE_MODE) 动态图模式
context.set_context(mode=context.GRAPH_MODE) 静态图模式
\@ms_function支持基于源码转换 |
+| MindSpore | context.set_context(mode=context.PYNATIVE_MODE) 动态图模式,
context.set_context(mode=context.GRAPH_MODE) 静态图模式,
\@ms_function支持基于源码转换 |
| PyTorch | torch.jit.script()支持基于源码转换,
torch.jit.trace()支持基于追踪转换 |
-| PaddlePaddle | paddle.jit.to_static()支持基于源码转换,
paddle.jit.TracedLayer.trace()支持基于追踪转换 |
+| PaddlePaddle | paddle.jit.to_static()支持基于源码转换,
paddle.jit.TracedLayer.trace()支持基于追踪转换 |
:label:`dynamic_static_switch`
diff --git a/chapter_computational_graph/summary.md b/chapter_computational_graph/summary.md
index 7abd3c4..0ac51c1 100644
--- a/chapter_computational_graph/summary.md
+++ b/chapter_computational_graph/summary.md
@@ -20,4 +20,10 @@
- 根据计算图可以找到相互独立的算子进行并发调度,提高计算的并行性。而存在依赖关系的算子则必须依次调度执行。
-- 计算图的训练任务可以使用同步或者异步机制,异步能够有效提高硬件使用率,缩短训练时间。
\ No newline at end of file
+- 计算图的训练任务可以使用同步或者异步机制,异步能够有效提高硬件使用率,缩短训练时间。
+
+## 扩展阅读
+
+- 计算图是计算框架的核心理念之一,了解主流计算框架的设计思想,有助于深入掌握这一概念,建议阅读 [TensorFlow 设计白皮书](https://arxiv.org/abs/1603.04467)、 [PyTorch计算框架设计论文](https://arxiv.org/abs/1912.01703)、[MindSpore技术白皮书](https://mindspore-website.obs.cn-north-4.myhuaweicloud.com/white_paper/MindSpore_white_paperV1.1.pdf)。
+- 图外控制流直接使用前端语言控制流,熟悉编程语言即可掌握这一方法,而图内控制流则相对较为复杂,建议阅读[TensorFlow控制流](http://download.tensorflow.org/paper/white_paper_tf_control_flow_implementation_2017_11_1.pdf)论文。
+- 动态图和静态图设计理念与实践,建议阅读[TensorFlow Eager 论文](https://arxiv.org/pdf/1903.01855.pdf)、[TensorFlow Eager Execution](https://tensorflow.google.cn/guide/eager?hl=zh-cn)示例、[TensorFlow Graph](https://tensorflow.google.cn/guide/intro_to_graphs?hl=zh-cn)理念与实践、[MindSpore动静态图](https://www.mindspore.cn/docs/programming_guide/zh-CN/r1.6/design/dynamic_graph_and_static_graph.html)概念。
\ No newline at end of file
diff --git a/chapter_data_processing/data_order.md b/chapter_data_processing/data_order.md
index fe1e276..1e38a8d 100644
--- a/chapter_data_processing/data_order.md
+++ b/chapter_data_processing/data_order.md
@@ -8,7 +8,7 @@
MindSpore通过约束算子线程组间的通信行为来确保对当前算子的下游算子的输入顺序与自己的输入顺序相同,基于这种递归的约束,确保了整个并行数据处理最后一个算子的输出顺序与第一个算子的输入顺序相同。具体实现中,MindSpore以Connector为算子线程组间的通信组件,对Connector的核心操作为上游算子的Push操作以及下游算子的Pop操作,我们重点关注MindSpore对这两个行为的约束。
-Connector的使用有如下两个要求:
+Connector的使用有如下两个要求:
- Connector两端的数据生产线程组和数据消费线程组中的线程分别从0开始编号。
diff --git a/chapter_data_processing/extension.md b/chapter_data_processing/extension.md
index 4ae9574..89d7ac1 100644
--- a/chapter_data_processing/extension.md
+++ b/chapter_data_processing/extension.md
@@ -76,7 +76,7 @@ outputs = pipe.run()
:width:`800px`
:label:`distributed_data_preprocess_based_on_3rd_party_software`
-该方案虽然再业内被广泛使用,却面临着三个问题:
+该方案虽然在业内被广泛使用,却面临着三个问题:
- 由于数据处理和数据训练采用不同的框架,使得用户为此常常需要在两个不同的框架中编写不同语言的程序,增加了用户的使用负担。
diff --git a/chapter_data_processing/program_model.md b/chapter_data_processing/program_model.md
index f340beb..a528aa7 100644
--- a/chapter_data_processing/program_model.md
+++ b/chapter_data_processing/program_model.md
@@ -35,7 +35,7 @@ val count = ones.reduce(_+_)
主流机器学习系统中的数据模块同样也采用了类似的编程抽象,如TensorFlow的数据模块tf.data :cite:`murray2021tf`,
以及MindSpore的数据模块MindData等。接下来我们以MindData的接口设计为例子来介绍如何面向机器学习这个场景设计好的编程抽象来帮助用户方便的构建模型训练中多种多样的数据处理流水线。
-MindData是机器学习系统MindSpore的数据模块,主要负责完成机器学习模型训练中的数据预处理任务,MindData的向用户提供的核心编程抽象为基于Dataset(数据集)的变换处理。这里的Dataset是一个数据帧的概念(Data
+MindData是机器学习系统MindSpore的数据模块,主要负责完成机器学习模型训练中的数据预处理任务,MindData向用户提供的核心编程抽象为基于Dataset(数据集)的变换处理。这里的Dataset是一个数据帧的概念(Data
Frame),即一个Dataset为一个多行多列,且每一列都有列名的关系数据表。

| prefetch | 从存储介质中预取数据集 |
| project | 从Dataset数据表中选择一些列用于接下来的处理 |
| zip | 将多个数据集合并为一个数据集 |
-| repeat | 多轮次训练中,重复整个数据流水多次。 |
-| create_dict_iterator | 对数据集创建一个返回字典类型数据的迭代器。 |
+| repeat | 多轮次训练中,重复整个数据流水多次 |
+| create_dict_iterator | 对数据集创建一个返回字典类型数据的迭代器 |
| ... | ... |
上述描述了数据集的接口抽象,而对数据集的具体操作实际上是由具体的数据算子函数定义。为了方便用户使用,MindData对机器学习领域常见的数据类型及其常见数据处理需求都内置实现了丰富的数据算子库。针对视觉领域,MindData提供了常见的如Decode(解码)、Resize(缩放)、RandomRotation(随机旋转)、Normalize(正规化)以及HWC2CHW(通道转置)等算子;针对文本领域,MindData提供了Ngram、NormalizeUTF8、BertTokenizer等算子;针对语音领域,MindData提供了TimeMasking(时域掩盖)、LowpassBiquad(双二阶滤波器)、ComplexNorm(归一化)等算子;这些常用算子能覆盖用户的绝大部分需求。
@@ -102,7 +102,7 @@ dataset = dataset.map(input_columns="label", operations=onehot_op)
有了基于数据集变换的编程抽象、以及针对机器学习各种数据类型的丰富变换算子支持,我们可以覆盖用户绝大部分的数据处理需求。然而由于机器学习领域本身进展快速,新的数据处理需求不断涌现,可能会有用户想要使用的数据变换算子没有被数据模块覆盖支持到的情况发生。为此我们需要设计良好的用户自定义算子注册机制,使得用户可以方便在构建数据处理流水线时使用自定义的算子。
-机器学习场景中,用户的开发编程语言以Python为主,所以我们可以认为用户的自定义算子更多情况下实际上是一个Python函数或者Python类。数据模块支持自定义算子的难度主要由数据模块对计算的调度实现方式有关系,比如Pytorch的dataloader的计算调度主要在Python层面实现,得益于Python语言的灵活性,在dataloader的数据流水中插入自定义的算子相对来说比较容易;而像TensorFlow的tf.data以及MindSpore的MindData的计算调度主要在C++层面实现,这使得数据模块想要灵活的在数据流中插入用户定义的Python算子变得较为有挑战性。接下来我们以MindData中的算子自定义算子注册使用实现为例子展开讨论这部分内容。
+机器学习场景中,用户的开发编程语言以Python为主,所以我们可以认为用户的自定义算子更多情况下实际上是一个Python函数或者Python类。数据模块支持自定义算子的难度主要与数据模块对计算的调度实现方式有关系,比如Pytorch的dataloader的计算调度主要在Python层面实现,得益于Python语言的灵活性,在dataloader的数据流水中插入自定义的算子相对来说比较容易;而像TensorFlow的tf.data以及MindSpore的MindData的计算调度主要在C++层面实现,这使得数据模块想要灵活的在数据流中插入用户定义的Python算子变得较为有挑战性。接下来我们以MindData中的自定义算子注册使用实现为例子展开讨论这部分内容。

diff --git a/chapter_data_processing/summary.md b/chapter_data_processing/summary.md
index 7918724..5b6dc38 100644
--- a/chapter_data_processing/summary.md
+++ b/chapter_data_processing/summary.md
@@ -1,3 +1,3 @@
-## 章节总结
+## 总结
-本章我们围绕着易用性、高效性和保序性三个维度展开研究如何设计实现机器学习系统中的数据预处理模块。在易用性维度我们重点探讨了数据模块的编程模型,通过借鉴历史上优秀的并行数据处理系统的设计经验,我们认为基于描述数据集变换的编程抽象较为适合作为数据模块的编程模型,在具体的系统实现中,我们不仅要在上述的编程模型的基础上提供足够多内置算子方便的用户的数据预处理编程,同时还要考虑如何支持用户方便的使用自定义算子。在高效性方面,我们从数据读取和计算两个方面分别介绍了特殊文件格式设计和计算并行架构设计。我们也使用我们在前几章中学习到的模型计算图编译优化技术来优化用户的数据预处理计算图,以进一步的达到更高的数据处理吞吐率。机器学习场景中模型对数据输入顺序敏感,于是衍生出来保序性这一特殊性质,我们在本章中对此进行了分析并通过MindSpore中的Connector的特殊约束实现来展示真实系统实现中如何确保保序性。最后,我们也针对部分情况下单机CPU数据预处理性能的问题,介绍了当前基于异构处理加速的纵向扩展方案,和基于分布式数据预处理的横向扩展方案,我们相信读者学习了本章后能够对机器学习系统中的数据模块有深刻的认知,也对数据模块未来面临的挑战有所了解。
+本章我们围绕着易用性、高效性和保序性三个维度展开研究如何设计实现机器学习系统中的数据预处理模块。在易用性维度我们重点探讨了数据模块的编程模型,通过借鉴历史上优秀的并行数据处理系统的设计经验,我们认为基于描述数据集变换的编程抽象较为适合作为数据模块的编程模型,在具体的系统实现中,我们不仅要在上述的编程模型的基础上提供足够多内置算子方便用户的数据预处理编程,同时还要考虑如何支持用户方便的使用自定义算子。在高效性方面,我们从数据读取和计算两个方面分别介绍了特殊文件格式设计和计算并行架构设计。我们也使用我们在前几章中学习到的模型计算图编译优化技术来优化用户的数据预处理计算图,以进一步的达到更高的数据处理吞吐率。机器学习场景中模型对数据输入顺序敏感,于是衍生出来保序性这一特殊性质,我们在本章中对此进行了分析并通过MindSpore中的Connector的特殊约束实现来展示真实系统实现中如何确保保序性。最后,我们也针对部分情况下单机CPU数据预处理性能的问题,介绍了当前基于异构处理加速的纵向扩展方案,和基于分布式数据预处理的横向扩展方案,我们相信读者学习了本章后能够对机器学习系统中的数据模块有深刻的认知,也对数据模块未来面临的挑战有所了解。
diff --git a/chapter_distributed_training/collective.md b/chapter_distributed_training/collective.md
index 164be65..e429c57 100644
--- a/chapter_distributed_training/collective.md
+++ b/chapter_distributed_training/collective.md
@@ -1,62 +1,44 @@
## 集合通讯
-接下来,我们会讲解常见的大型深度模型训练的系统实现。
-这一类系统往往部署在商用的数据中心(Data
-Centers),以及如何在数据中心中高效实现集合通讯,从而让分布式训练系统免于网络瓶颈。
+接下来,我们会讲解常见的大型深度模型训练的系统实现。这一类系统往往部署在商用的数据中心(Data Centers),以及如何在数据中心中高效实现集合通讯,从而让分布式训练系统免于网络瓶颈。
### 在数据中心的梯度计算
-
+
:width:`800px`
:label:`ch10-datacentre`
- :numref:`ch10-datacentre` 描述了一个典型的用于深度学习模型训练的数据中心。数据中心中的训练服务器一般会有多个设备。如需增加服务器,我们会将多个训练服务器放置在一个机柜(Rack)上,同时接入一个架顶交换机(Top
-of Rack
-Switch)来连接多个服务器。当一个机柜满的时候,我们可以通过在架顶交换机之间增加骨干交换机(Spine
-Switch),接入新的机柜。通过这种方式,我们可以在数据中心内不断增加服务器,从而为神经网络的训练提供海量的算力和内存。目前的商用数据中心可能拥有超过一百万台服务器。
+ :numref:`ch10-datacentre` 描述了一个典型的用于深度学习模型训练的数据中心。数据中心中的训练服务器一般会有多个设备。如需增加服务器,我们会将多个训练服务器放置在一个机柜(Rack)上,同时接入一个架顶交换机(Top of Rack Switch)来连接多个服务器。当一个机柜满的时候,我们可以通过在架顶交换机之间增加骨干交换机(Spine Switch),接入新的机柜。通过这种方式,我们可以在数据中心内不断增加服务器,从而为神经网络的训练提供海量的算力和内存。目前的商用数据中心可能拥有超过一百万台服务器。
-在数据中心中训练大型神经网络的首要挑战是:如何高效计算大量的平均梯度。假设给定一个千亿级别参数的神经网络(GPT-3模型含有1750亿参数),如果用32位浮点数来表达每一个参数,那么每一步训练中,一个数据并行模式下的模型副本(Model
-replica)就需要生成700GB的本地梯度数据(即 175G $\times$ 4 bytes =
-700GB)。假如我们有3个模型副本,那么至少需要传输1.4TB(即,700GB
-$\times$
-$(3-1)$)的本地梯度(这是因为$N$个副本中,我们只需要传送$N-1$梯度来完成平均梯度计算)。当平均梯度计算完成后,我们需要进一步将平均梯度广播到全部的模型副本(即1.4TB的数据),更新本地参数,从而确保模型副本不会偏离(Diverge)。
+在数据中心中训练大型神经网络的首要挑战是:如何高效计算大量的平均梯度。假设给定一个千亿级别参数的神经网络(GPT-3模型含有1750亿参数),如果用32位浮点数来表达每一个参数,那么每一步训练中,一个数据并行模式下的模型副本(Model replica)就需要生成700GB的本地梯度数据(即 175G $\times$ 4 bytes = 700GB)。假如我们有3个模型副本,那么至少需要传输1.4TB(即,700GB $\times$ $(3-1)$)的本地梯度(这是因为$N$个副本中,我们只需要传送$N-1$梯度来完成平均梯度计算)。当平均梯度计算完成后,我们需要进一步将平均梯度广播到全部的模型副本(即1.4TB的数据),更新本地参数,从而确保模型副本不会偏离(Diverge)。
当前的数据中心往往使用以太网(Ethernet)构建网络。主流的商用以太网链路带宽一般是10Gbps和25Gbps。利用以太网传输海量梯度会产生严重的传输延迟,从而降低模型训练的速度。新型深度学习训练集群(如英伟达的DGX系列机器)往往配置有更快的Inifiband。单个InfiniBand链路可以提供100Gbps和200Gbps的带宽。即使拥有这种高速网络,传输TB级别的本地梯度依然需要大量延迟(1TB的数据需要在200Gbps的链路上传输25秒)。
-为了避免通过网络传输数据,现代深度学习服务器一般都会配备多个计算设备(例如说,DGX-3机器会被配备8个A100
-GPU),而在一个服务器内的多个设备可以通过高速机内网络互联(如NVLink)。这种高速机内网络可以提供高达400GB/s的带宽,从而让传输TB级别数成为可能。然而,受限于单个服务器的散热,成本和硬件故障等需求,在一个服务器内我们无法无限制的持续增加设备,大型深度学习模型的训练最终还是需要多个服务器共同完成。因此,计算平均梯度需要同时借助以太网或者是InfiniBand,以及服务器内部的NVLink等机内网络。
+为了避免通过网络传输数据,现代深度学习服务器一般都会配备多个计算设备(例如说,DGX-3机器会被配备8个A100 GPU),而在一个服务器内的多个设备可以通过高速机内网络互联(如NVLink)。这种高速机内网络可以提供高达400GB/s的带宽,从而让传输TB级别数成为可能。然而,受限于单个服务器的散热,成本和硬件故障等需求,在一个服务器内我们无法无限制的持续增加设备,大型深度学习模型的训练最终还是需要多个服务器共同完成。因此,计算平均梯度需要同时借助以太网或者是InfiniBand,以及服务器内部的NVLink等机内网络。
### Allreduce算法
-为了在数据中心中高效完成梯度平均的操作,我们往往会实现
-Allreduce算法。这个算法诞生的背景是:传统计算平均梯度的方法往往是在集群中找出一个设备来收集本地梯度,计算平均梯度,然后再将平均梯度广播到全部的设备。这种做法易于实现,但是其引入了两个问题。首先,多设备共同给这个聚合设备发送数据的时候,在聚合设备上往往会产生严重的带宽不足和网络拥塞。其次,单设备需要负担大量的梯度平均的计算,而受限于单设备上的有限算力,这种平均计算会受限于算力瓶颈。
+为了在数据中心中高效完成梯度平均的操作,我们往往会实现Allreduce算法。这个算法诞生的背景是:传统计算平均梯度的方法往往是在集群中找出一个设备来收集本地梯度,计算平均梯度,然后再将平均梯度广播到全部的设备。这种做法易于实现,但是其引入了两个问题。首先,多设备共同给这个聚合设备发送数据的时候,在聚合设备上往往会产生严重的带宽不足和网络拥塞。其次,单设备需要负担大量的梯度平均的计算,而受限于单设备上的有限算力,这种平均计算会受限于算力瓶颈。
-
+
:width:`800px`
:label:`ch10-allreduce-state`
-为了解决上述问题,人们设计了Allreduce算法。该算法的核心设计思路是:让全部的节点参与进来平均梯度的网络通信和平均计算中,从而将巨大的网络和算力开销均摊给全部节点,从而解决使用单个梯度聚合节点的问题。假设我们有$M$个设备,每个设备有一个模型副本,该模型由$N$个参数构成。那么按照Allreduce算法要求,我们需要首先将全部的参数按照设备数量切分成$M$个分区(Partition),每个分区具有$N/M$个参数。
-为了讲解Allreduce的过程,我们首先给出这个算法的初始和终止状态。如 :numref:`ch10-allreduce-state`
-所示,该例子含有3个设备,每个设备有一个模型副本,这个副本有3个参数。那么按照Allreduce的分区方法,参数会被划分成3个分区(3个设备),而每一个分区有1个参数($N/M$,N代表3个参数,M代表3个设备)。在这个例子中,假定设备1拥有参数2,4,6,设备2拥有参数1,2,3,设备3拥有参数4,8,12,那么Allreduce结束后,全部的设备都拥有梯度相加后的结果7,14,21,其中分区1的结果7是由3个设备中分区1的初始结果相加而成(7
-= 1 + 2 +
-4)。为了计算平均梯度,每个设备只需要在最后将梯度之和除以设备数量即可(分区1的最终结果为7除以3)。
+为了解决上述问题,人们设计了Allreduce算法。该算法的核心设计思路是:让全部的节点参与进来平均梯度的网络通信和平均计算中,从而将巨大的网络和算力开销均摊给全部节点,从而解决使用单个梯度聚合节点的问题。假设我们有$M$个设备,每个设备有一个模型副本,该模型由$N$个参数构成。那么按照Allreduce算法要求,我们需要首先将全部的参数按照设备数量切分成$M$个分区(Partition),每个分区具有$N/M$个参数。为了讲解Allreduce的过程,我们首先给出这个算法的初始和终止状态。如 :numref:`ch10-allreduce-state` 所示,该例子含有3个设备,每个设备有一个模型副本,这个副本有3个参数。那么按照Allreduce的分区方法,参数会被划分成3个分区(3个设备),而每一个分区有1个参数($N/M$,N代表3个参数,M代表3个设备)。在这个例子中,假定设备1拥有参数2,4,6,设备2拥有参数1,2,3,设备3拥有参数4,8,12,那么Allreduce结束后,全部的设备都拥有梯度相加后的结果7,14,21,其中分区1的结果7是由3个设备中分区1的初始结果相加而成(7 = 1 + 2 + 4)。为了计算平均梯度,每个设备只需要在最后将梯度之和除以设备数量即可(分区1的最终结果为7除以3)。
-
+
:width:`800px`
:label:`ch10-allreduce-process`
-Allreduce算法会把梯度的加和计算拆分成$M-1$个Reduce步骤和$M-1$个Broadcast步骤(其中$M$是节点的数量)。Reduce步骤是为了计算出梯度的和(Summation),Broadcast步骤是为了把梯度之和广播给全部的节点。为了说明这些步骤的执行过程,我们利用
- :numref:`ch10-allreduce-process` 。Allreduce算法由Reduce步骤开始,在第一个Reduce步骤中,Allreduce算法会对全部节点进行配对(Pairing),让他们共同完成梯度相加的操作。在 :numref:`ch10-allreduce-process` 的第一个Reduce步骤中,设备1和设备2进行了配对共同对分区1的数据相加。其中,设备2把本地的梯度数据1发送给设备1,设备将接收到1和本地的分区1内的梯度数据:2进行相加,计算出中间(intermediate)梯度相加的结果:3。于此同时,设备1和设备3进行配对,共同完成对分区3的数据相加。而设备3和设备2进行配对,共同完成对于分区2的数据相加。
+Allreduce算法会把梯度的加和计算拆分成$M-1$个Reduce步骤和$M-1$个Broadcast步骤(其中$M$是节点的数量)。Reduce步骤是为了计算出梯度的和(Summation),Broadcast步骤是为了把梯度之和广播给全部的节点。为了说明这些步骤的执行过程,我们利用 :numref:`ch10-allreduce-process` 。Allreduce算法由Reduce步骤开始,在第一个Reduce步骤中,Allreduce算法会对全部节点进行配对(Pairing),让他们共同完成梯度相加的操作。在 :numref:`ch10-allreduce-process` 的第一个Reduce步骤中,设备1和设备2进行了配对共同对分区1的数据相加。其中,设备2把本地的梯度数据1发送给设备1,设备将接收到1和本地的分区1内的梯度数据:2进行相加,计算出中间(intermediate)梯度相加的结果:3。于此同时,设备1和设备3进行配对,共同完成对分区3的数据相加。而设备3和设备2进行配对,共同完成对于分区2的数据相加。
在上述Reduce的步骤中,梯度的计算实现了以下几个特性:
- **网络优化:**
- 全部设备都同时在接收和发送数据,利用起了每个设备的入口(Ingress)和出口(Egress)带宽。因此Allreduce过程中可利用的带宽是$M \times B$,其中$M$是节点数量,
- $B$是节点带宽,从而让系统实现网络带宽上的可扩展性。
+ 全部设备都同时在接收和发送数据,利用起了每个设备的入口(Ingress)和出口(Egress)带宽。因此Allreduce过程中可利用的带宽是$M \times B$,其中$M$是节点数量,$B$是节点带宽,从而让系统实现网络带宽上的可扩展性。
- **算力优化:**
- 全部设备的处理器都参与了梯度相加的计算。。因此Allreduce过程中可利用的处理器是$M \times P$,其中$M$是节点数量,
- $P$是处理器数量,从而让系统实现计算上的可扩展性。
+ 全部设备的处理器都参与了梯度相加的计算。因此Allreduce过程中可利用的处理器是$M \times P$,其中$M$是节点数量,$P$是处理器数量,从而让系统实现计算上的可扩展性。
- **负载均衡:**
由于数据分区是平均划分的,因此每次设备分摊到的通讯和计算开销是相等的。
@@ -65,6 +47,4 @@ Allreduce算法会把梯度的加和计算拆分成$M-1$个Reduce步骤和$M-1$
接下来,Allreduce算法将进入Broadcast阶段。这一阶段的过程和Reduce步骤类似,核心区别是节点进行配对后,他们不再进行数据相加,而是将Reduce的计算结果进行广播。在 :numref:`ch10-allreduce-process` 中的第一个Broadcast步骤中,设备1会将分区2的结果14直接写入设备3的分区2中。设备2会讲分区3的结果21直接写入设备1中。设备3会将分区1的结果直接写入设备2中。在一个3个节点的Allreduce集群中,我们会重复2次Broadcast步骤来将每个分区的Reduce结果告知全部的节点。
-Allreduce算法已经被常见的分布式训练框架(包括Horovod, KungFu, TensorFlow
-distributed, PyTorch
-distributed)等支持。当用户选择使用数据并行模式的过程,其底层会默认触发。
\ No newline at end of file
+Allreduce算法已经被常见的分布式训练框架(包括Horovod, KungFu, TensorFlow distributed, PyTorch distributed)等支持。当用户选择使用数据并行模式的过程,其底层会默认触发。
\ No newline at end of file
diff --git a/chapter_distributed_training/index.md b/chapter_distributed_training/index.md
index 54c6f4f..f23f6f9 100644
--- a/chapter_distributed_training/index.md
+++ b/chapter_distributed_training/index.md
@@ -2,9 +2,7 @@
随着机器学习的进一步发展,科学家们设计出更大型,更多功能的机器学习模型(例如说,GPT-3)。这种模型含有大量参数,需要复杂的计算以及处理海量的数据。单个机器上有限的资源无法满足训练大型机器学习模型的需求。因此,我们需要设计分布式训练系统,从而将一个机器学习模型任务拆分成多个子任务,并将子任务分发给多个计算节点,解决资源瓶颈。
-在本章节中,我们会引入分布式机器学习系统的相关概念,设计挑战,系统实现和实例研究。我们会首先讨论分布式训练系统的定义,设计动机和好处。进一步,我们会讨论常见的分布式训练方法:数据并行,模型并行和流水线并行。在实际中,这些分布式训练方法会被参数服务器(Parameter
-Servers),或者是集合通讯库(Collective Communication
-Libraries)实现。不同的系统实现具有各自的优势和劣势。我们会用大型预训练模型和大型深度学习推荐系统作为实例来探讨不同系统实现的利与弊。
+在本章节中,我们会引入分布式机器学习系统的相关概念,设计挑战,系统实现和实例研究。我们会首先讨论分布式训练系统的定义,设计动机和好处。进一步,我们会讨论常见的分布式训练方法:数据并行,模型并行和流水线并行。在实际中,这些分布式训练方法会被参数服务器(Parameter Servers),或者是集合通讯库(Collective Communication Libraries)实现。不同的系统实现具有各自的优势和劣势。我们会用大型预训练模型和大型深度学习推荐系统作为实例来探讨不同系统实现的利与弊。
本章的学习目标包括:
diff --git a/chapter_distributed_training/methods.md b/chapter_distributed_training/methods.md
index 4956c5f..efb45ab 100644
--- a/chapter_distributed_training/methods.md
+++ b/chapter_distributed_training/methods.md
@@ -4,20 +4,13 @@
### 概述
-
+
:width:`800px`
:label:`ch10-single-node`
-分布式训练系统的设计目标是:将单节点训练系统转化成**等价的**并行训练系统,从而在不影响模型精度的条件下完成训练过程的加速。一个单节点训练系统往往如 :numref:`ch10-single-node`所示。一个训练过程会由多个数据小批次(mini-batch)完成。在图中,一个数据小批次被标示为**数据**。训练系统会利用数据小批次来生成梯度,提升模型精度。这个过程由一个训练**程序**实现。在实际中,这个程序往往实现了一个多层神经网络的执行过程。
-该神经网络的执行由一个计算图(Computational
-Graph)表达。这个图有多个相互连接的算子(Operator),每个算子会拥有计算参数。每个算子往往会实现一个神经网络层(Neural
-Network Layer),而参数则代表了这个层在训练中所更新的的权重(Weights)。
+分布式训练系统的设计目标是:将单节点训练系统转化成**等价的**并行训练系统,从而在不影响模型精度的条件下完成训练过程的加速。一个单节点训练系统往往如 :numref:`ch10-single-node`所示。一个训练过程会由多个数据小批次(mini-batch)完成。在图中,一个数据小批次被标示为**数据**。训练系统会利用数据小批次来生成梯度,提升模型精度。这个过程由一个训练**程序**实现。在实际中,这个程序往往实现了一个多层神经网络的执行过程。该神经网络的执行由一个计算图(Computational Graph)表达。这个图有多个相互连接的算子(Operator),每个算子会拥有计算参数。每个算子往往会实现一个神经网络层(Neural Network Layer),而参数则代表了这个层在训练中所更新的的权重(Weights)。
-为了更新参数,计算图的执行会分为**前向**传播和**反向**传播两个阶段。前向传播的第一步会将数据读入第一个算子,该算子会根据当前的参数,计算出传播给下一个算子的数据。算子依次重复这个前向传播的过程(算子1
--\> 算子2 -\>
-算子3),直到最后一个算子结束。最后的算子随之马上开始反向传播。反向传播中,每个算子依次计算出梯度(梯度3
--\> 梯度2 -\>
-梯度1),并利用梯度更新本地的参数。反向传播最终在第一个算子结束。反向传播的结束也标志本次数据小批次的结束,系统随之读取下一个小批次,继续更新模型。
+为了更新参数,计算图的执行会分为**前向**传播和**反向**传播两个阶段。前向传播的第一步会将数据读入第一个算子,该算子会根据当前的参数,计算出传播给下一个算子的数据。算子依次重复这个前向传播的过程(算子1 -\> 算子2 -\> 算子3),直到最后一个算子结束。最后的算子随之马上开始反向传播。反向传播中,每个算子依次计算出梯度(梯度3 -\> 梯度2 -\> 梯度1),并利用梯度更新本地的参数。反向传播最终在第一个算子结束。反向传播的结束也标志本次数据小批次的结束,系统随之读取下一个小批次,继续更新模型。
:分布式训练方法分类
@@ -27,27 +20,19 @@ Network Layer),而参数则代表了这个层在训练中所更新的的权
| 多程序 | 多程序单数据:模型并行 | 多程序多数据:混合并行 |
:label:`ch10-parallel-methods`
-给定一个单节点训练系统,人们会对**数据**和**程序**分区(Partition),从而完成并行加速。 :numref:`ch10-parallel-methods`总结了不同的切分方法。单节点训练系统可以被归类于
-单程序单数据模式。而假如用户希望使用更多的设备来实现并行计算,他们首先可以选择对数据进行分区,并将同一个程序复制到多个设备上并行执行。这种方式是单程序多数据模式,常被称为**数据并行**(Data
-Parallelism)。另一种并行方式是对程序进行分区:程序的算子会被分发给多个设备按照依次完成。这种模式是
-多程序单数据模式,常被称为**模型并行**(Model
-Parallelism)。当训练超大型智能模型时,开发人们往往要同时对数据和程序进行切分,从而实现最高程度的并行。这种模式是多程序多数据模式,常被称为**混合并行**(Hybrid
-Parallelism)。
+给定一个单节点训练系统,人们会对**数据**和**程序**分区(Partition),从而完成并行加速。 :numref:`ch10-parallel-methods`总结了不同的切分方法。单节点训练系统可以被归类于单程序单数据模式。而假如用户希望使用更多的设备来实现并行计算,他们首先可以选择对数据进行分区,并将同一个程序复制到多个设备上并行执行。这种方式是单程序多数据模式,常被称为**数据并行**(Data Parallelism)。另一种并行方式是对程序进行分区:程序的算子会被分发给多个设备按照依次完成。这种模式是多程序单数据模式,常被称为**模型并行**(Model Parallelism)。当训练超大型智能模型时,开发人们往往要同时对数据和程序进行切分,从而实现最高程度的并行。这种模式是多程序多数据模式,常被称为**混合并行**(Hybrid Parallelism)。
接下来,我们详细讲解各种并行方法的执行过程。
### 数据并行
-
+
:width:`800px`
:label:`ch10-data-parallel`
-数据并行往往可以解决单节点的算力不足。这种并行方式在人工智能框架中最为常见,具体实现包括:TensorFlow
-DistributedStrategy,PyTorch Distributed,Horovod DistributedOptimizer等。在一个数据并行系统中,假设用户给定一个训练批大小$N$,并且希望使用$M$个并行设备来加速训练。那么,该训练批大小会被分为$M$个分区,每个设备会分配到$N/M$个训练样本。这些设备共享一个训练程序的副本,在不同数据分区上独立执行,计算梯度。不同的设备(假设设备编号为$i$)会根据本地的训练样本估计出梯度$G_i$。为了确保训练程序参数的一致性,本地梯度$G_i$需要聚合,计算出平均梯度$(\sum_{i=1}^{N} G_i) / N$。最终,训练程序利用平均梯度修正模型参数,完成小批量的训练。
+数据并行往往可以解决单节点的算力不足。这种并行方式在人工智能框架中最为常见,具体实现包括:TensorFlow DistributedStrategy,PyTorch Distributed,Horovod DistributedOptimizer等。在一个数据并行系统中,假设用户给定一个训练批大小$N$,并且希望使用$M$个并行设备来加速训练。那么,该训练批大小会被分为$M$个分区,每个设备会分配到$N/M$个训练样本。这些设备共享一个训练程序的副本,在不同数据分区上独立执行,计算梯度。不同的设备(假设设备编号为$i$)会根据本地的训练样本估计出梯度$G_i$。为了确保训练程序参数的一致性,本地梯度$G_i$需要聚合,计算出平均梯度$(\sum_{i=1}^{N} G_i) / N$。最终,训练程序利用平均梯度修正模型参数,完成小批量的训练。
-:numref:`ch10-data-parallel`展示了2个设备构成的数据并行例子。假设用户给定的批大小(Batch
-Size)是64,那么每个设备会分配到32个训练样本,并且具有相同的神经网络参数(程序副本)。本地的训练样本会依次通过这个程序副本中的算子,完成前向传播和反向传播。在反向传播的过程中,程序副本会生成局部梯度。不同设备上对应的局部梯度(如设备1和设备2上各自的梯度1)会进行聚合,从而计算平均梯度。这个聚合的过程往往由集合通讯库(Collective
-Communication)的Allreduce操作来完成。
+:numref:`ch10-data-parallel`展示了2个设备构成的数据并行例子。假设用户给定的批大小(Batch Size)是64,那么每个设备会分配到32个训练样本,并且具有相同的神经网络参数(程序副本)。本地的训练样本会依次通过这个程序副本中的算子,完成前向传播和反向传播。在反向传播的过程中,程序副本会生成局部梯度。不同设备上对应的局部梯度(如设备1和设备2上各自的梯度1)会进行聚合,从而计算平均梯度。这个聚合的过程往往由集合通讯库(Collective Communication)的Allreduce操作来完成。
### 模型并行
@@ -55,17 +40,13 @@ Communication)的Allreduce操作来完成。
:width:`800px`
:label:`ch10-model-parallel-intra-op`
-模型并行往往用于解决单节点的内存不足问题。一个常见的内存不足场景是模型中含有大型算子,例如说深度神经网络中需要计算大量分类的全连接层(Fully
-Connected
-Layer)。完成这种大型算子计算所需的内存可能超过单设备的内存容量。那么我们需要对这个大型算子进行切分。假设这个算子具有$P$个参数,而我们拥有$N$个设备,那么我们可以将$P$个参数平均分配给$N$个设备(每个设备分配$P/N$个参数),从而让每个设备负责更少的计算量,能够在内存容量的限制下完成前向传播和反向传播中所需的计算。这种切分方式是模型并行的应用,被称为**算子内并行**(Intra-operator
-Parallelism)。
+模型并行往往用于解决单节点的内存不足问题。一个常见的内存不足场景是模型中含有大型算子,例如说深度神经网络中需要计算大量分类的全连接层(Fully Connected Layer)。完成这种大型算子计算所需的内存可能超过单设备的内存容量。那么我们需要对这个大型算子进行切分。假设这个算子具有$P$个参数,而我们拥有$N$个设备,那么我们可以将$P$个参数平均分配给$N$个设备(每个设备分配$P/N$个参数),从而让每个设备负责更少的计算量,能够在内存容量的限制下完成前向传播和反向传播中所需的计算。这种切分方式是模型并行的应用,被称为**算子内并行**(Intra-operator Parallelism)。
:numref:`ch10-model-parallel-intra-op`给出了一个由2个设备实现的算子内并行的例子。在这个例子中,假设一个神经网络具有2个算子,算子1的计算(包含正向和反向传播)需要预留16G的内存,算子2的计算需要预留1G的内存。而本例中的设备最多可以提供10G的内存。为了完成这个神经网络的训练,我们需要对算子1实现并行。具体做法是,将算子1的参数平均分区,设备1和设备2各负责其中部分算子1的参数。由于设备1和设备2的参数不同,因此它们各自负责程序分区1和程序分区2。在训练这个神经网络的过程中,数据(小批量)会首先传给算子1。由于算子1的参数分别由2个设备负责,因此数据会被广播给这2个设备。不同设备根据本地的参数分区完成前向计算,生成的本地计算结果需要进一步合并(Combine),发送给下游的算子2。在反向传播中,算子2的数据会被广播给设备1和设备2,这些设备根据本地的算子1分区各自完成局部的反向计算。计算结果进一步合并传播回数据,最终完成反向传播。
-另一种内存不足的场景是:模型的总内存需求超过了单设备的内存容量。在这种场景下,假如我们总共有$N$个算子和$M$个设备,我们可以将算子平摊给这$M$个设备,让每个设备仅需负责$N/M$个算子的前向和反向计算,降低设备的内存开销。这种并行方式是模型并行的另一种应用,被称为**算子间并行**(Inter-operator
-Parallelism)。
+另一种内存不足的场景是:模型的总内存需求超过了单设备的内存容量。在这种场景下,假如我们总共有$N$个算子和$M$个设备,我们可以将算子平摊给这$M$个设备,让每个设备仅需负责$N/M$个算子的前向和反向计算,降低设备的内存开销。这种并行方式是模型并行的另一种应用,被称为**算子间并行**(Inter-operator Parallelism)。
-
+
:width:`800px`
:label:`ch10-model-parallel-inter-op`
@@ -73,7 +54,7 @@ Parallelism)。
### 混合并行
-
+
:width:`800px`
:label:`ch10-hybrid-parallel`
diff --git a/chapter_distributed_training/overview.md b/chapter_distributed_training/overview.md
index a9e294b..2f55ac4 100644
--- a/chapter_distributed_training/overview.md
+++ b/chapter_distributed_training/overview.md
@@ -2,49 +2,36 @@
### 设计动机
-接下来,我们详细讨论分布式训练系统的设计动机
+接下来,我们详细讨论分布式训练系统的设计动机。
-
+
:width:`800px`
:label:`ch10-computation-increase`
##### 算力不足
-单处理器的算力不足是促使人们设计分布式训练系统的一个主要原因。一个处理器的算力可以用**每秒钟浮点数操作**(Floating
-Point Operations Per Second,FLOPS)来衡量。
-如 :numref:`ch10-computation-increase`所示,根据摩尔定律(Moore's
-Law),中央处理器的算力每18个月增长2倍。虽然计算加速卡,如GPU和Tensor
-Processing
-Unit(TPU),针对机器学习计算(如矩阵相乘)提供了大量的算力。这些加速卡的发展最终也受限于摩尔定律,增长速度也停留在每18个月2倍。而与此同时,机器学习模型正在快速发展。短短数年,我们从仅能识别有限物体的AlexNet模型,一路发展到在复杂任务中打败人类的AlphaStar。这期间,模型对于算力需求每18个月增长了35倍。解决处理器性能和算力需求之间的鸿沟
-的关键就在于利用分布式计算。通过大型数据中心和云计算设施,我们可以快速获取大量的处理器。通过分布式训练系统有效管理这些处理器,我们可以实现算力的快速增长,从而持续满足模型的需求。
+单处理器的算力不足是促使人们设计分布式训练系统的一个主要原因。一个处理器的算力可以用**每秒钟浮点数操作**(Floating Point Operations Per Second,FLOPS)来衡量。如 :numref:`ch10-computation-increase`所示,根据摩尔定律(Moore's Law),中央处理器的算力每18个月增长2倍。虽然计算加速卡,如GPU和Tensor Processing Unit(TPU),针对机器学习计算(如矩阵相乘)提供了大量的算力。这些加速卡的发展最终也受限于摩尔定律,增长速度也停留在每18个月2倍。而与此同时,机器学习模型正在快速发展。短短数年,我们从仅能识别有限物体的AlexNet模型,一路发展到在复杂任务中打败人类的AlphaStar。这期间,模型对于算力需求每18个月增长了35倍。解决处理器性能和算力需求之间的鸿沟的关键就在于利用分布式计算。通过大型数据中心和云计算设施,我们可以快速获取大量的处理器。通过分布式训练系统有效管理这些处理器,我们可以实现算力的快速增长,从而持续满足模型的需求。
##### 内存不足
-在训练机器学习模型的过程中,训练系统需要在内存中存储大量数据。这些数据包括:模型参数(Parameters)以及训练和更新这些参数所产生的中间数据,如特征图(Feature
-Map)和梯度(Gradients)。假设一个深度神经网络模型具有10亿的参数,所有特征图共有20亿参数,每个参数都由一个32位浮点数表达,而更新这些参数至少还需要产生与特征图和参数等量的梯度。由于一个32位浮点数需要4个字节(Byte)的内存来存储,那么训练这个10亿规模的模型就需要至少24GB($24 \times 10^9$
-Byte)的内存。现在,随着大型预训练模型的崛起,一个深度神经网络(如GPT-3)会拥有超过千亿的参数。假设我们依然使用32位浮点数来存储参数,激活值和梯度,那么训练这个模型就至少需要1.2TB的内存。而如今的训练加速卡(如NVIDIA
-A100)仅能提供最高80GB的内存。单卡内存空间的增长受到硬件规格,散热和成本等诸多因素,难以进一步快速增长。因此,我们需要分布式训练系统来同时使用数百个训练加速卡,从而为千亿级别的模型提供所需的TB级别的内存。
+在训练机器学习模型的过程中,训练系统需要在内存中存储大量数据。这些数据包括:模型参数(Parameters)以及训练和更新这些参数所产生的中间数据,如特征图(Feature Map)和梯度(Gradients)。假设一个深度神经网络模型具有10亿的参数,所有特征图共有20亿参数,每个参数都由一个32位浮点数表达,而更新这些参数至少还需要产生与特征图和参数等量的梯度。由于一个32位浮点数需要4个字节(Byte)的内存来存储,那么训练这个10亿规模的模型就需要至少24GB($24 \times 10^9$ Byte)的内存。现在,随着大型预训练模型的崛起,一个深度神经网络(如GPT-3)会拥有超过千亿的参数。假设我们依然使用32位浮点数来存储参数,激活值和梯度,那么训练这个模型就至少需要1.2TB的内存。而如今的训练加速卡(如NVIDIA A100)仅能提供最高80GB的内存。单卡内存空间的增长受到硬件规格,散热和成本等诸多因素,难以进一步快速增长。因此,我们需要分布式训练系统来同时使用数百个训练加速卡,从而为千亿级别的模型提供所需的TB级别的内存。
### 分布式训练架构
受限于单节点的有限算力,内存和存储资源,人们把关注投向了日益成熟的云计算数据中心。一个数据中心管理着数十万个计算服务器。随着数据中心的全球部署,人们可以很方便地获得数百个服务器。这些服务器可以通过分布式训练系统来协调和管理,解决训练大型机器学习模型过程遇到的算力,内存和存储不足,从而完成训练过程的加速。
-
+
:width:`800px`
:label:`ch10-single-vs-multi`
-在设计分布式训练系统的过程中,我们需要找出有资源瓶颈的计算任务,根据计算任务的特点,将其拆分成多个子任务,然后将子任务分发给多个节点(可以是服务器,机器,或者是加速卡)并行完成。
- :numref:`ch10-single-vs-multi`描述了如何将单节点执行转换为分布式执行的一般过程。在机器学习系统中,一个计算任务往往会有一组数据(例如训练样本)或者任务(例如算子)作为输入,利用一个计算节点(例如GPU)生成一组输出(例如梯度)。假如单节点成为瓶颈,我们可以利用分布式计算进行加速。分布式执行一般具有三个步骤:第一步,我们需要将输入进行**切分**。第二步,每个输入部分会分发给不同的计算节点,实现**并行**计算。第三步,每个计算节点的输出,进一步**合并**,最终得到和单节点等价的计算结果。这种切分-并行-合并的模式,本质上实现了分而治之算法(Divide-and-Conquer
-Algorithm)的设计思想:由于每个计算节点只需要负责更小的子任务,因此其可以更快速的完成计算,最终形成对整个计算过程的加速。
+在设计分布式训练系统的过程中,我们需要找出有资源瓶颈的计算任务,根据计算任务的特点,将其拆分成多个子任务,然后将子任务分发给多个节点(可以是服务器,机器,或者是加速卡)并行完成。 :numref:`ch10-single-vs-multi`描述了如何将单节点执行转换为分布式执行的一般过程。在机器学习系统中,一个计算任务往往会有一组数据(例如训练样本)或者任务(例如算子)作为输入,利用一个计算节点(例如GPU)生成一组输出(例如梯度)。假如单节点成为瓶颈,我们可以利用分布式计算进行加速。分布式执行一般具有三个步骤:第一步,我们需要将输入进行**切分**。第二步,每个输入部分会分发给不同的计算节点,实现**并行**计算。第三步,每个计算节点的输出,进一步**合并**,最终得到和单节点等价的计算结果。这种切分-并行-合并的模式,本质上实现了分而治之算法(Divide-and-Conquer Algorithm)的设计思想:由于每个计算节点只需要负责更小的子任务,因此其可以更快速的完成计算,最终形成对整个计算过程的加速。
### 用户益处
通过使用分布式训练系统,我们往往可以获得以下几个关键好处:
-- **提升系统性能**:使用分布式训练,往往可以带来训练性能的巨大提升。一个分布式训练系统往往用以下这个指标来衡量性能:到达目标精度所需的时间(time-to-accuracy)。这个指标由两个参数决定:
- 一个数据周期所需的完成时间,以及一个数据周期模型所提升的精度。通过持续增加并行处理节点,我们可以将数据周期的完成时间不断变短,最终显著减少到达目标精度所需的时间。
+- **提升系统性能**:使用分布式训练,往往可以带来训练性能的巨大提升。一个分布式训练系统往往用以下这个指标来衡量性能:到达目标精度所需的时间(time-to-accuracy)。这个指标由两个参数决定:一个数据周期所需的完成时间,以及一个数据周期模型所提升的精度。通过持续增加并行处理节点,我们可以将数据周期的完成时间不断变短,最终显著减少到达目标精度所需的时间。
-- **经济性(Economy)**:使用分布式训练,我们也可以进一步减少训练及其模型所需的成本。受限于单节点散热的上限,单节点的算力越高,起所需的散热硬件成本也更高。因此,在提供同等的算力的条件下,组合多个计算节点是一个更加经济高效的方式。这促使需要云服务商(如亚马逊和微软等)更加注重给用户提供成本高效的分布式机器学习系统。
+- **经济性(Economy)**:使用分布式训练,我们也可以进一步减少训练及其模型所需的成本。受限于单节点散热的上限,单节点的算力越高,其所需的散热硬件成本也更高。因此,在提供同等的算力的条件下,组合多个计算节点是一个更加经济高效的方式。这促使云服务商(如亚马逊和微软等)需要更加注重给用户提供成本高效的分布式机器学习系统。
-- **抵御硬件故障**:分布式训练系统同时能有效提升抵御硬件故障的能力。机器学习训练集群往往由商用硬件(Commodity
- Hardware)组成,这类硬件(例如说,磁盘和网卡)运行一定周期就会产生故障。而仅使用单个硬件进行训练的话,那么一个硬件的故障就会造成整个训练的任务的失败。通过将这个训练任务又多个硬件共同完成,即使一个硬件故障了,我们也可以通过将这个硬件上相应的计算子任务转移给其余硬件,继续完成训练,从而避免训练任务的失败。
\ No newline at end of file
+- **抵御硬件故障**:分布式训练系统同时能有效提升抵御硬件故障的能力。机器学习训练集群往往由商用硬件(Commodity Hardware)组成,这类硬件(例如说,磁盘和网卡)运行一定周期就会产生故障。而仅使用单个硬件进行训练的话,那么一个硬件的故障就会造成整个训练的任务的失败。通过将这个训练任务由多个硬件共同完成,即使一个硬件故障了,我们也可以通过将这个硬件上相应的计算子任务转移给其余硬件,继续完成训练,从而避免训练任务的失败。
\ No newline at end of file
diff --git a/chapter_distributed_training/parameter_servers.md b/chapter_distributed_training/parameter_servers.md
index 8e6fddd..7d3ffb9 100644
--- a/chapter_distributed_training/parameter_servers.md
+++ b/chapter_distributed_training/parameter_servers.md
@@ -4,51 +4,32 @@
### 计算和存储分离
-利用参数服务器的其中一个核心需求是实现:计算和存储的分离。在训练模型中,计算可以被理解为计算更新模型参数所需要的计算(例如说,计算本地梯度和计算平均梯度),而存储可以被理解为将模型参数存储在内存设备中(例如说,主机内存,加速卡内存和SSD设备)。传统的神经网络训练中,计算往往是核心瓶颈,因此我们只需要配置有合适数量的带有加速卡的服务器,常被称为训练服务器(Training
-servers)。
+利用参数服务器的其中一个核心需求是实现:计算和存储的分离。在训练模型中,计算可以被理解为计算更新模型参数所需要的计算(例如说,计算本地梯度和计算平均梯度),而存储可以被理解为将模型参数存储在内存设备中(例如说,主机内存,加速卡内存和SSD设备)。传统的神经网络训练中,计算往往是核心瓶颈,因此我们只需要配置有合适数量的带有加速卡的服务器,常被称为训练服务器(Training servers)。
-随着机器学习的发展,新型的稀疏模型被开发出来。相比于传统的神经网络训练,稀疏模型的训练往往不需要大量昂贵的计算加速卡(GPU),而需要海量的内存来存储嵌入表(Embedding
-table)。例如说,一个大型深度学习推荐系统中,它们往往使用小型的深度神经网络(如Multi-layer
-Perception),训练这种神经网络只需要几个GPU即可。而另一方面,推荐系统中往往需要存储PB级别的嵌入表。嵌入表往往由推荐系统的用户特征(User
-feature)和产品特征(Item
-feature)构成。这些特征往往是大型向量(Vector)。现代推荐系统需要服务数亿的用户,推荐数以千万的商品。假设用户的特征是1MB,而系统需要服务10亿的用户,那么用户的嵌入表就会有1PB的大小。而这个大小远远超过了一个深度学习服务器所具有的内存。假如我们部署大量的昂贵的深度学习服务器来存储海量嵌入表,那么这些服务器上的加速卡的使用率将会极低,无法实现对于硬件的高效利用。
+随着机器学习的发展,新型的稀疏模型被开发出来。相比于传统的神经网络训练,稀疏模型的训练往往不需要大量昂贵的计算加速卡(GPU),而需要海量的内存来存储嵌入表(Embedding table)。例如说,一个大型深度学习推荐系统中,它们往往使用小型的深度神经网络(如Multi-layer Perception),训练这种神经网络只需要几个GPU即可。而另一方面,推荐系统中往往需要存储PB级别的嵌入表。嵌入表往往由推荐系统的用户特征(User feature)和产品特征(Item feature)构成。这些特征往往是大型向量(Vector)。现代推荐系统需要服务数亿的用户,推荐数以千万的商品。假设用户的特征是1MB,而系统需要服务10亿的用户,那么用户的嵌入表就会有1PB的大小。而这个大小远远超过了一个深度学习服务器所具有的内存。假如我们部署大量的昂贵的深度学习服务器来存储海量嵌入表,那么这些服务器上的加速卡的使用率将会极低,无法实现对于硬件的高效利用。
-
+
:width:`800px`
:label:`ch10-parameter-servers`
-为了解决上述问题,人们往往会在稀疏模型集群中混合部署:训练服务器和参数服务器,从而实现对于计算需求和内存需求分别满足。 :numref:`ch10-parameter-servers` 描述了带有参数服务器的机器学习集群。这个集群中含有2个训练服务器和2个参数服务器,训练服务器一般是拥有加速卡的计算优化服务器(Compute-optimised
-server)。而参数服务器一般是内存优化服务器(Memory-optimised
-server),其的内存大小一般远远大于计算优化服务器。在一个稀疏模型中往往拥有神经网络参数和嵌入表参数。神经网络较小,其可以存储在训练服务器内存中。而嵌入表很大,因此需要存储在额外的参数服务器中。参数服务器一般会按照键-值对(Key-value
-pairs)的方式来存储参数。常用的键包括用户名(User ID),产品名(Item
-ID)或者是参数名(Parameter
-Key)。常用的值是以多维度向量(Multi-dimensional
-tensors)表达的模型参数。假如存在多个参数服务器,参数服务器会用数据分区函数(例如,哈希函数和区域划分)将健-值映射到不同参数服务器上。
+为了解决上述问题,人们往往会在稀疏模型集群中混合部署:训练服务器和参数服务器,从而实现对于计算需求和内存需求分别满足。 :numref:`ch10-parameter-servers` 描述了带有参数服务器的机器学习集群。这个集群中含有2个训练服务器和2个参数服务器,训练服务器一般是拥有加速卡的计算优化服务器(Compute-optimised server)。而参数服务器一般是内存优化服务器(Memory-optimised server),其的内存大小一般远远大于计算优化服务器。在一个稀疏模型中往往拥有神经网络参数和嵌入表参数。神经网络较小,其可以存储在训练服务器内存中。而嵌入表很大,因此需要存储在额外的参数服务器中。参数服务器一般会按照键-值对(Key-value pairs)的方式来存储参数。常用的键包括用户名(User ID),产品名(Item ID)或者是参数名(Parameter Key)。常用的值是以多维度向量(Multi-dimensional tensors)表达的模型参数。假如存在多个参数服务器,参数服务器会用数据分区函数(例如,哈希函数和区域划分)将健-值映射到不同参数服务器上。
-为了完成对于模型的训练,在每一步训练中,训练服务器会根据当前的小批量训练数据,找到本批量中需要用到的参数。例如说,本小批量数据只会训练部分用户的特征,那么这些用户的特征才会需要。根据参数服务器的数据分区函数,训练服务器可以知道参数当前在哪个参数服务器上,它们因此会用参数的键(Key)向对应的参数服务器发起拉取请求(Pull
-request)。参数服务器响应,并返回对应的值(Value)。训练服务器将拉取的参数(往往是嵌入表)和本地内存中的模型参数(往往是神经网络)进行合并,从而对合并的模型进行训练,计算梯度。假如训练服务器实现了数据并行,那么训练服务器计算出的本地梯度需要利用Allreduce计算出平均梯度。对于训练服务器本地内存中的参数,训练服务器可以马上利用平均梯度进行修改。对于在参数服务器中存储的参数,训练服务器发起推送请求(Push
-request)将平均梯度发送到参数服务器,参数服务器更新本地存储的参数。
+为了完成对于模型的训练,在每一步训练中,训练服务器会根据当前的小批量训练数据,找到本批量中需要用到的参数。例如说,本小批量数据只会训练部分用户的特征,那么这些用户的特征才会需要。根据参数服务器的数据分区函数,训练服务器可以知道参数当前在哪个参数服务器上,它们因此会用参数的键(Key)向对应的参数服务器发起拉取请求(Pull request)。参数服务器响应,并返回对应的值(Value)。训练服务器将拉取的参数(往往是嵌入表)和本地内存中的模型参数(往往是神经网络)进行合并,从而对合并的模型进行训练,计算梯度。假如训练服务器实现了数据并行,那么训练服务器计算出的本地梯度需要利用Allreduce计算出平均梯度。对于训练服务器本地内存中的参数,训练服务器可以马上利用平均梯度进行修改。对于在参数服务器中存储的参数,训练服务器发起推送请求(Push request)将平均梯度发送到参数服务器,参数服务器更新本地存储的参数。
-在以上的参数服务器架构中,机器学习集群拥有者可以灵活的根据梯度计算所需要算力配置合理数量的训练服务器。他们也可以根据参数的数量配置大部分的稀疏参数(Sparse
-parameters)在参数服务器中,仅留下小部分的密集参数(Dense
-parameters)在训练服务器中。密集参数和稀疏参数的核心区别是:稀疏参数在每一步训练不一定都会被用到,他们需要根据当前训练小批量来决定。而密集参数每一步训练都需要用到。因此为了频繁从参数服务器中拉取,密集参数往往会存储在训练服务器中。
+在以上的参数服务器架构中,机器学习集群拥有者可以灵活的根据梯度计算所需要算力配置合理数量的训练服务器。他们也可以根据参数的数量配置大部分的稀疏参数(Sparse parameters)在参数服务器中,仅留下小部分的密集参数(Dense parameters)在训练服务器中。密集参数和稀疏参数的核心区别是:稀疏参数在每一步训练不一定都会被用到,他们需要根据当前训练小批量来决定。而密集参数每一步训练都需要用到。因此为了避免频繁从参数服务器中拉取,密集参数往往会存储在训练服务器中。
### 数据副本
-在参数服务器的实际部署中,人们往往需要解决数据热点问题。互联网数据往往符合幂律概率(Power-law
-distribution),这会导致部分稀疏参数在训练过程中被访问的次数会显著高于其他参数。例如说,热门商品的特征向量被训练服务器拉取的次数就会远远高于非热门商品。因此,存储了热门数据的参数服务器所承受的数据拉取和推送请求会远远高于其他参数服务器,因此形成数据热点,伤害了系统的可扩展性。
+在参数服务器的实际部署中,人们往往需要解决数据热点问题。互联网数据往往符合幂律概率(Power-law distribution),这会导致部分稀疏参数在训练过程中被访问的次数会显著高于其他参数。例如说,热门商品的特征向量被训练服务器拉取的次数就会远远高于非热门商品。因此,存储了热门数据的参数服务器所承受的数据拉取和推送请求会远远高于其他参数服务器,因此形成数据热点,伤害了系统的可扩展性。
解决数据热点问题的关键是利用在没有副本的情况下,通用的做法是每隔一段时间将所有参数在外存中保存一份检查点(checkpoint)。当出现机器故障时,首先所有的训练必须停止,等待故障的机器恢复上线,然后从外存中重新加载检查点。这就会导致从上一次保存检查点到故障发生时的数据全部丢失。保存一次检查点的开销随模型大小而增加,训练大模型时通常每隔1-2小时保存一次。因此无副本的参数服务器如果发生故障,会丢失最多1-2小时的数据。
-解决参数服务器故障和数据热点问题的常用技术是构建模型主从副本(Master-slave
-replication)。一份参数在多个机器上拥有副本,并指定其中一个副本作为主副本。训练服务器的所有更新操作都向主副本写入并同步至从副本上。如何取得共识确定哪一个副本是主副本是分布式系统领域一个经典问题,已经有了相当多的成熟的算法,例如Paxos和Raft。此外,主副本上的更新如何复制到从副本上也同样是分布式系统领域的经典共识问题。通常系统设计者需要在可用性(Availability)和一致性(Consistency)之间做出取舍。如果参数服务器副本间采用强一致性的复制协议(例如,链式副本(Chain replication))则可能导致训练服务器的推送请求失败,即参数服务器不可用。反之,如果参数服务器采用弱一致性的复制协议,则可能导致副本间存储的参数不一致。
+解决参数服务器故障和数据热点问题的常用技术是构建模型主从副本(Master-slave replication)。一份参数在多个机器上拥有副本,并指定其中一个副本作为主副本。训练服务器的所有更新操作都向主副本写入并同步至从副本上。如何取得共识确定哪一个副本是主副本是分布式系统领域一个经典问题,已经有了相当多的成熟的算法,例如Paxos和Raft。此外,主副本上的更新如何复制到从副本上也同样是分布式系统领域的经典共识问题。通常系统设计者需要在可用性(Availability)和一致性(Consistency)之间做出取舍。如果参数服务器副本间采用强一致性的复制协议(例如,链式副本(Chain replication))则可能导致训练服务器的推送请求失败,即参数服务器不可用。反之,如果参数服务器采用弱一致性的复制协议,则可能导致副本间存储的参数不一致。
### 掉队者问题
-参数服务器的另一大核心作用是可以让用户方便解决掉队者问题。在之前的讨论中,在每一步训练结束后,训练服务器都需要计算平均梯度来对每一个模型副本进行更新,从而保证下一步训练开始前,全部模型副本的参数的一致性,这种对于参数一致性的确保一般被称为同步训练(Synchronous
-training)。同步训练一般会有助于训练系统达到更好的模型精度,但是当系统规模变大,我们往往会在系统中引入掉队者(Straggler)。掉队者出现的原因很多。常见的原因包括:掉队者设备可能和其他设备不在同一个机柜中,因此掉队者的通讯带宽显著小于其他设备。另外,掉队者设备也可能和其他进程共享本地的服务器计算和通讯资源,形成资源竞争,从而降低了性能。
+参数服务器的另一大核心作用是可以让用户方便解决掉队者问题。在之前的讨论中,在每一步训练结束后,训练服务器都需要计算平均梯度来对每一个模型副本进行更新,从而保证下一步训练开始前,全部模型副本的参数的一致性,这种对于参数一致性的确保一般被称为同步训练(Synchronous training)。同步训练一般会有助于训练系统达到更好的模型精度,但是当系统规模变大,我们往往会在系统中引入掉队者(Straggler)。掉队者出现的原因很多。常见的原因包括:掉队者设备可能和其他设备不在同一个机柜中,因此掉队者的通讯带宽显著小于其他设备。另外,掉队者设备也可能和其他进程共享本地的服务器计算和通讯资源,形成资源竞争,从而降低了性能。
掉队者对于基于Allreduce的同步训练系统的性能有显著影响,这是因为Allreduce让全部节点参与到平均梯度的计算和通讯中,而每个节点负责等量的数据。因此任何一个掉队者的出现,都会让整个Allreduce操作延迟完成。为了解决这个问题,人们也会使用参数服务器来计算平均梯度。一种常见的设计是:训练服务器训练出本地梯度后,会把本地梯度全部推送到参数服务器。参数服务器在等到一定数据训练服务器(例如说90%的训练服务器)的本地梯度后,就开始计算平均梯度。这样可以确保平均梯度的计算不会被落后者的出现延误。计算好的平均梯度马上推送给全部训练服务器,开始下一轮训练。
-解决掉队者的另外一种常见做法是利用参数服务器实现**异步训练**(Asynchronous
-training)。在一个异步训练系统中,每个训练服务器在训练开始时,有相同的模型参数副本。在训练中,他们计算出本地梯度后会马上将本地梯度推送到参数服务器,参数服务器将推送的梯度立刻用于更新参数,并把更新好的参数马上推送回对应的训练服务器。在这个过程中,不同的训练服务器很可能会使用不同版本的模型参数进行本地梯度的计算,这种做法有可能会伤害模型的精度,但它同时让不同训练服务器可以按照各自的运算速度来推送和拉取参数,而无需等待同伴,因此避免了掉队者对于整个集群性能的影响。
\ No newline at end of file
+解决掉队者的另外一种常见做法是利用参数服务器实现**异步训练**(Asynchronous training)。在一个异步训练系统中,每个训练服务器在训练开始时,有相同的模型参数副本。在训练中,他们计算出本地梯度后会马上将本地梯度推送到参数服务器,参数服务器将推送的梯度立刻用于更新参数,并把更新好的参数马上推送回对应的训练服务器。在这个过程中,不同的训练服务器很可能会使用不同版本的模型参数进行本地梯度的计算,这种做法有可能会伤害模型的精度,但它同时让不同训练服务器可以按照各自的运算速度来推送和拉取参数,而无需等待同伴,因此避免了掉队者对于整个集群性能的影响。
\ No newline at end of file
diff --git a/chapter_distributed_training/pipeline.md b/chapter_distributed_training/pipeline.md
index 7727cfc..6a47173 100644
--- a/chapter_distributed_training/pipeline.md
+++ b/chapter_distributed_training/pipeline.md
@@ -1,20 +1,14 @@
## 流水线并行
-在数据并行和模型并行以外,流水线并行是另一种常用的并行加速方法。
-流水线并行往往被应用在大型模型并行系统中。这种系统通过算子内并行和算子间并行解决单设备内存不足的问题。
-然而,当这类系统的运行中,计算图中的下游设备需要长期持续处于空闲状态,等待上游设备的计算完成,才可以开始计算,这极大降低了设备的平均使用率。这种现象被称为模型并行空洞(Model
-Parallelism Bubble)。
+在数据并行和模型并行以外,流水线并行是另一种常用的并行加速方法。流水线并行往往被应用在大型模型并行系统中。这种系统通过算子内并行和算子间并行解决单设备内存不足的问题。然而,当这类系统的运行中,计算图中的下游设备需要长期持续处于空闲状态,等待上游设备的计算完成,才可以开始计算,这极大降低了设备的平均使用率。这种现象被称为模型并行空洞(Model Parallelism Bubble)。
-
+
:width:`800px`
:label:`ch10-pipeline-parallel`
-为了减少空洞,提升设备使用率,我们可以在模型并行系统中构建流水线。这种做法的核心想法是将一个数据小批量(Data
-Mini-batch)划分为多个微批量(Micro-batch)。假设一个数据小批量有$D$个训练数据,这个小批量可以被划分为$M$个微批量,那么微批量的大小就是$D/M$。每个微批量相应进入训练系统,完成前向传播(Forwards
-propagation)和反向传播(Backwards
-propagation),计算出梯度。每个微批量对应的梯度将会缓存,等到全部微批量完成,缓存的梯度会被加和,算出平均梯度,更新模型参数。
+为了减少空洞,提升设备使用率,我们可以在模型并行系统中构建流水线。这种做法的核心想法是将一个数据小批量(Data Mini-batch)划分为多个微批量(Micro-batch)。假设一个数据小批量有$D$个训练数据,这个小批量可以被划分为$M$个微批量,那么微批量的大小就是$D/M$。每个微批量相应进入训练系统,完成前向传播(Forwards propagation)和反向传播(Backwards propagation),计算出梯度。每个微批量对应的梯度将会缓存,等到全部微批量完成,缓存的梯度会被加和,算出平均梯度,更新模型参数。
:numref:`ch10-pipeline-parallel` 进一步给出了一个流水线并行的执行例子。在本例中,模型参数需要切分给4个设备存储。为了充分利用起来这4个设备,我们将小批量切分为2个微批量。当设备1完成第一个微批量的前向传播后(表示为$F_{0,0}$)后,他会将中间结果发送给设备2,触发响应的前向传播任务(表示为$F_{1,0}$)。与此同时,设备1也可以开始第二个微批量的前向传播任务(表示为$F_{0,1}$)。前向传播会在流水线的最后一个设备--设备3--完成。系统于是开始反向传播。设备4开始第1个微批量的反向传播任务(表示为$B_{3,0}$)。该任务完成后的中间结果会被发送给设备3,触发响应的反向传播任务(表示为$B_{2,0}$)。与此同时,设备4会缓存好对应第1个微批量的梯度,接下来开始第2个微批量计算(表示为$B_{3,1}$)。当设备4完成了全部的反向传播计算后,他会将本地缓存的梯度进行相加,并且除以微批量数量,计算出平均梯度,该梯度用于更新模型参数。
-流水线并行的关键因素是流水线泡沫(Bubble)。当设备完成前向传播后,必须等到全部反向传播开发,在此期间设备会处于空闲状态。在 :numref:`ch10-pipeline-parallel` 中,我们可以看到设备1在完成2个前向传播任务后,要等很多时间才能开始2个传向传播任务。这其中的等待时间即被称为泡沫。为了减少设备的等待时间,一种常见的做法是尽可能的增加微批量的数量,从而让反向传播尽可能早的开始。然而,使用非常小的微批量大小,可能会造成加速器无法被充分利用。因此最优的微批量大小是多种因素的折中。其中最核心的因素是流水线泡沫的大小和加速器的计算能力。
+流水线并行的关键因素是流水线泡沫(Bubble)。当设备完成前向传播后,必须等到全部反向传播开始,在此期间设备会处于空闲状态。在 :numref:`ch10-pipeline-parallel` 中,我们可以看到设备1在完成2个前向传播任务后,要等很多时间才能开始2个反向传播任务。这其中的等待时间即被称为泡沫。为了减少设备的等待时间,一种常见的做法是尽可能的增加微批量的数量,从而让反向传播尽可能早的开始。然而,使用非常小的微批量大小,可能会造成加速器无法被充分利用。因此最优的微批量大小是多种因素的折中。其中最核心的因素是流水线泡沫的大小和加速器的计算能力。
diff --git a/chapter_distributed_training/summary.md b/chapter_distributed_training/summary.md
index 2ba6e1e..296440d 100644
--- a/chapter_distributed_training/summary.md
+++ b/chapter_distributed_training/summary.md
@@ -4,7 +4,7 @@
- 分布式训练系统的设计往往遵循"分而治之"的设计思路。
-- 利用分布式训练系统,人们可以显著提升性能性能,经济性,并且帮助抵御硬件故障。
+- 利用分布式训练系统,人们可以显著提升性能,经济性,并且帮助抵御硬件故障。
- 分布式训练系统可以通过数据并行增加设备来提升算力。
@@ -16,9 +16,21 @@
- 为了提供海量的带宽,机器学习集群拥有异构的网络:以太网,机内网络(NVLink)和InfiniBand。
-- 为了解决单节点瓶颈,我们可以使用
- Allreduce来分摊梯度聚合过程中的计算和通讯开销。
+- 为了解决单节点瓶颈,我们可以使用Allreduce来分摊梯度聚合过程中的计算和通讯开销。
- 参数服务器可以帮助机器学习集群实现计算-存储的分离,从而更好的支持大型稀疏模型。
-- 参数服务器常用数据副本技术解决数据热点问题,同时它们也可以被用来解决同步训练系统中常见的掉队者问题。
\ No newline at end of file
+- 参数服务器常用数据副本技术解决数据热点问题,同时它们也可以被用来解决同步训练系统中常见的掉队者问题。
+
+
+## 扩展阅读
+
+- 分布式机器学习系统:[综述](https://dl.acm.org/doi/abs/10.1145/3377454)
+
+- 利用集合通讯支持并行训练的实践:[Horovod](https://arxiv.org/abs/1802.05799)
+
+- 流水线并行的实践:[gPipe](https://arxiv.org/abs/1811.06965)
+
+- 在大规模数据并行下的实践:[Accurate, Large Minibatch SGD: Training ImageNet in 1 Hour](https://arxiv.org/abs/1706.02677)
+
+- 模型并行在超大模型上的实践:[ZeRO](https://arxiv.org/abs/1910.02054)
diff --git a/chapter_explainable_AI/index.md b/chapter_explainable_AI/index.md
index 5b9f682..c434bd7 100644
--- a/chapter_explainable_AI/index.md
+++ b/chapter_explainable_AI/index.md
@@ -6,7 +6,7 @@
因此,从商业推广层面以及从法规层面,我们都需要打开黑盒模型,对模型进行解释,可解释AI正是解决该类问题的技术。
-本章的学习目标包括:
+本章的学习目标包括:
- 掌握可解释AI的目标和应用场景
diff --git a/chapter_federated_learning/horizontal_fl.md b/chapter_federated_learning/horizontal_fl.md
index 1dd98b9..fefa9e4 100644
--- a/chapter_federated_learning/horizontal_fl.md
+++ b/chapter_federated_learning/horizontal_fl.md
@@ -2,7 +2,7 @@
### 云云场景中的横向联邦
-在横向联邦学习系统中,具有相同数据结构的多个参与者通过参数或云服务器协同学习机器学习模型。一个典型的假设是参与者是诚实的,而服务器是诚实但好奇的,因此不允许任何参与者向服务器泄漏信息。这种系统的训练过程通常包括以下四个步骤:
+在横向联邦学习系统中,具有相同数据结构的多个参与者通过参数或云服务器协同建立机器学习模型。一个典型的假设是参与者是诚实的,而服务器是诚实但好奇的,因此不允许任何参与者向服务器泄漏信息。这种系统的训练过程通常包括以下四个步骤:
①:参与者在本地计算训练梯度,使用加密、差异隐私或秘密共享技术掩饰所选梯度,并将掩码后的结果发送到服务器;
@@ -12,12 +12,14 @@
④:参与者用解密的梯度更新他们各自的模型。
-和传统分布式学习相比,联邦学习存在训练结点不稳定和通信代价大的难点。这些难点导致了联邦学习无法和传统分布式学习一样:在每次单步训练之后,同步不同训练结点上的权重。为了提高计算通信比并降低频繁通信带来的高能耗,谷歌公司提出了联邦平均算法(Federated Averaging,FedAvg)。 :numfef:`ch10-federated-learning-fedavg`展示了FedAvg的整体流程。在每轮联邦训练过程中,端侧进行多次单步训练。然后云侧聚合多个端侧权重,并取加权平均。
+和传统分布式学习相比,联邦学习存在训练结点不稳定和通信代价大的难点。这些难点导致了联邦学习无法和传统分布式学习一样:在每次单步训练之后,同步不同训练结点上的权重。为了提高计算通信比并降低频繁通信带来的高能耗,谷歌公司在2017年 :cite:`fedavg`提出了联邦平均算法(Federated Averaging,FedAvg)。 :numfef:`ch10-federated-learning-fedavg`展示了FedAvg的整体流程。在每轮联邦训练过程中,端侧进行多次单步训练。然后云侧聚合多个端侧权重,并取加权平均。

-
+:width:`800px`
:label:`ch10-federated-learning-fedavg`
+随着研究和应用的深入,研究者们意识到了FedAvg不适用于某些场景。比如在数据异质性(端上数据不是I.I.D分布)、系统异质性(端设备时断时连)的情况下,对模型参数只进行简单的加权平均会在训练过程中引入大量偏差,从而影响模型的收敛速度、预测性能。针对此,研究人员提出了基于Momentum :cite:`FedAvg_Momentum`、Variation Control :cite:`scaffold`、Bayesian :cite:`FedBE`、Distillation :cite:`PATE`和Proximal Estimation :cite:`FedProx`等原理开发的算法和系统框架。
+
### 端云场景中的横向联邦
端云联邦的总体流程和云云联邦一样,但端云联邦学习面临的难点还包括以下三个方面:
@@ -42,7 +44,7 @@
联邦学习客户端(FL-Client)负责本地数据训练,并在和FL-Server进行通信时,对上传权重进行安全加密。
-
+
:label:`ch10-federated-learning-architecture`
@@ -52,4 +54,4 @@
2.松耦合组网:使用FL-Server集群。每个FL-Server接收和下发权重给部分FL-Client,减少单个FL-Server的带宽压力。此外,支持FL-Client以松散的方式接入。任意FL-Client的中途退出都不会影响全局任务,并且FL-Client在任意时刻访问任意FL-Server都能获得训练所需的全量数据。
-3.加密模块:MindSpore Federated为了防止模型梯度的泄露,部署了多种加密算法:本地差分隐私(LDP)、基于多方安全计算(MPC)的安全聚合算法和华为自研的基于符号的维度选择差分隐私算法(SignDS)。
\ No newline at end of file
+3.加密模块:MindSpore Federated为了防止模型梯度的泄露,部署了多种加密算法:本地差分隐私(LDP)、基于多方安全计算(MPC)的安全聚合算法和华为自研的基于符号的维度选择差分隐私算法(SignDS)。
diff --git a/chapter_federated_learning/outlook.md b/chapter_federated_learning/outlook.md
index 10e8bcd..2584d30 100644
--- a/chapter_federated_learning/outlook.md
+++ b/chapter_federated_learning/outlook.md
@@ -1,3 +1,36 @@
## 展望
-待补充
+为了实现联邦学习的大规模商用,我们仍然需要做许多的研究工作。比如我们无法查看联邦学习的分布式化的数据,那就很难选择模型的超参数以及设定优化器,只能采用一些基于模拟的方案来调测模型;比如用于移动设备时,单用户的标签数据很少,甚至无法获取数据的标签信息,联邦学习如何用于无监督学习;比如由于参与方的数据分布不一致,训练同一个全局模型,很难评价模型对于每个参与方的好坏;比如数据一直是公司的核心资产,不同的公司一直在致力于收集数据和创造数据孤岛,如何有效地激励公司或者机构参与联邦学习的系统中来。下面将介绍一些MindSpore Federated在进行的一些尝试和业界的相关工作。
+
+**异构场景下的联邦学习**
+
+之前探讨的横向联邦和纵向联邦学习都是让不同的参与方共同建立一个共享的机器学习模型。然而,企业级联邦学习框架往往需要适应多种异构场景,如数据异构(不同客户端数据规模以及分布不一致),设备异构(不同客户端设备计算能力,通信效率不一致),以及模型异构(不同本地客户端模型学到的特征不一致)。
+
+比较主流的两种联邦异构场景下的工作:
+
+1)对异构数据具有高度鲁棒性的本地模型个性化联邦学习策略:
+
+联邦学习训练的是一个全局模型,基于所有数据得到一个全局最优解,但是不同参与方的数据量和分布都是不同的,很多场景下全局模型无法在把握整体的同时又照顾到这种差异。当某一方的数据和整体偏离比较大时,联邦学习的效果确实有可能不如本地训练的效果。那么如何在所有参与方总体的收益最大化的同时,让个体的收益也能够最大化,这就是个性化联邦学习。
+
+个性化联邦学习并不要求所有参与方最终使用的模型必须是一样的,比如允许每个参与方在参与联邦之后,根据自己的数据对模型进行微调,从而生成本方独特的个性化模型。在进行个性化微调之后,往往模型在本地测试集上的效果会更好。在这种方式下,不同参与方的模型结构是一样的,但是模型参数会有所不同。还有一些方案,是让所有的参与方拥有同样的特征提取层,但是任务分类层不同。还有的思路是将知识蒸馏引入联邦学习中,将联邦学习的全局模型作为teacher,将个性化模型作为student,可以缓解个性化过程中的过拟合问题。
+
+2)对于异构模型进行模型聚合的策略研究:
+
+一般在FedAvg的联邦聚合范式下,本地迭代训练次数越少、聚合地越频繁,模型收敛精度会越好,尤其是在不同参与客户端的数据是非iid的情况下。但是聚合会带来通信成本开销,联邦学习存在通信成本与模型精度的Trade-off。因此很多研究者聚焦于如何设计自适应聚合方案,要求在给定训练时间开销的前提下,找到本地更新和全局通信之间的最佳平衡,令全局模型的泛化误差最小。
+
+ **通信效率提升**
+
+端云联邦学习流程中,每一个全局训练轮次里,每个参与方都需要给服务器发送完整的模型参数更新,然后服务器将聚合后的模型参数下发。现代的深度学习网络动辄有数百万甚至更大量级的参数,如此多的参数量传输将会带来巨大的通信开销带来性能瓶颈(用户流量、通信时延、客户端参与数量)。为了降低通信开销,MindSpore Federated采取了一些改善通信效率的方法:
+
+1)智能调频策略:通过改变全局模型聚合的轮次来提高联邦学习效率,减少训练任务达到收敛的通信开销。一种直觉是在模型训练初期,参数变化剧烈,因此设置较大的聚合频率,使得模型快速收敛;在模型训练中后期,参数趋于稳定,因此设置较小的聚合频率,减少通信成本。
+
+2)通信压缩方案:对权重差进行量化以及稀疏化操作,即每次通信仅上传一小部分最重要参数的梯度,从而代替上传所有参数。之所以选择权重差做量化和稀疏,是因为它比权重值的分布更易拟合,而且稀疏性更高。量化就是将FP32的数据类型映射到INT8甚至更低比特表示的数值上,一方面降低存储和通信开销,另一方面可以更好地采用一些压缩编码方式进行传输(如哈夫曼编码、有限状态熵编码等)。比较常用的稀疏化方法有Top-k稀疏,即按梯度的绝对值从小到大排序,每轮只上传前k个参数,如何选取合适的\(k\)是一个有挑战性的问题。这个方案对于模型的联邦学习训练来说是有损的,在精度损失和通信压缩率之间也是trade-off。
+
+**联邦生态**
+
+在前面的章节中,我们介绍了面向隐私保护的联邦学习领域的一些技术与实践,然而随着探索地更加深入,联邦学习领域也变得更具包容性,它涵盖了分不是机器学习、模型压缩部署、信息安全、加密算法、博弈论等等。随着越来越多的公司、高校和机构参与进来,现在的联邦学习已经不仅仅是一种技术解决方案,还是一个隐私保护的生态系统,比如不同的参与方希望以可持续的方式加入联邦,如何设计激励机制,以确保利润可以相对公平地被联邦参与方共享,同时对于恶意的实施攻击或者破坏行为的参与方进行有效遏制。
+
+另外,随着用户数据隐私保护和合理使用的法律法规越来越多的被推出,制定联邦学习的技术标准显得愈加重要,这一标准能够在法律监管部门和技术开发人员之间建立一座桥梁,让企业知道采用何种技术,能够在合乎法规的同时更好地进行信息的共享。
+
+2020年底正式出版推行了由IEEE 标准委员会(SASB)通过的联邦学习国际标准(IEEE P3652.1),该标准旨在提供一个搭建联邦学习的体系架构和应用的指导方针,主要内容包括:联邦学习的描述和定义、场景需求分类和安全测评、联邦学习个性指标的评估如何量化、联合管控的需求。这也是国际上首个针对人工智能协同技术框架订立的标准,标志着联邦学习开启大规模工业化应用的新篇章。
+
diff --git a/chapter_federated_learning/overview.md b/chapter_federated_learning/overview.md
index 33bbf22..07d7bac 100644
--- a/chapter_federated_learning/overview.md
+++ b/chapter_federated_learning/overview.md
@@ -1,45 +1,47 @@
-## 概述
-
-随着人工智能的飞速发展,大规模和高质量的数据越来越重要,但也制约了其进一步的发展。隐私、监管和工程等问题造成了设备与设备之间的数据不能共享,进而导致了数据孤岛问题的出现。为了解决这一难题,联邦学习(Federated Learning,FL)应运而生。联邦学习的概念最早在2016年被提了出来,能有效帮助多个机构在满足用户隐私保护、数据安全和政府法规的要求下,进行数据使用和机器学习建模。
-
-### 定义
-
-联邦学习的核心即为数据不动,模型动。显然,若是将数据从各方集中在一起,不符合法律法规。联邦学习让模型在各个数据方“移动”,这样就可以达到数据不出端即可建模的效果。在联邦学习中,各方数据都保留在本地,通过交换加密的参数建立机器学习模型。
-
-### 应用场景
-
-在实际的应用场景中,根据样本和特征的重叠情况,联邦学习可以被分为横向联邦学习(样本不同,特征重叠),纵向联邦学习(特征不同,样本重叠)和联邦迁移学习(样本和特征都不重叠)。
-
-**横向联邦学习**适用于不同参与方拥有的特征相同但参与的个体不同的场景。比如,在广告推荐场景中,有多个不同的手机用户。算法开发人员使用不同手机用户的相同特征(点击次数、停留时间或使用频次等特征)的数据来建立模型。由于这些特征数据不能出端,因此,横向联邦学习可以被联合多个用户的数据来构建模型。
-
-**纵向联邦学习**适用于样本重叠多特征重叠少的场景。比如,有两个不同机构,一家是保险公司,另一家是医院。它们的用户群体很有可能包含该地的大部分居民,用户的交集可能较大。由于保险公司记录的都是用户的收支行为与信用评级,而医院则保有用户的疾病与购药记录,因此它们的用户特征交集较小。纵向联邦学习就是将这些不同特征在加密的状态下加以聚合,以增强模型能力的联邦学习。
-
-**联邦迁移学习**的核心是找到源领域和目标领域之间的相似性。比如有两个不同机构,一家是位于中国的银行,另一家是位于美国的电商。由于受到地域限制,这两家机构的用户群体交集很小。同时,由于机构类型的不同,二者的数据特征也只有小部分重合。在这种情况下,要想进行有效的联邦学习,就必须引入迁移学习,来解决单边数据规模小和标签样本少的问题,从而提升模型的效果。
-
-### 部署场景
-
-联邦学习和参数服务器(数据中心分布式学习)架构非常相似,都是采用中心化的服务器和分散的客户端去构建同一个机器学习模型。此外,根据客户端来源和规模的不同,联邦学习还可以细分为跨设备(cross-device)与跨组织(cross-silo)联邦学习。一般而言,跨组织联邦学习的用户一般是企业、机构单位级别的,而跨设备联邦学习针对的则是便携式电子设备、移动端设备等。 :numref:`ch10-federated-learning-different-connection`展示了三者的区别和联系:
-
-
-
-:label:`ch10-federated-learning-different-connection`
-
-### 联邦学习框架
-
-随着用户和开发人员对联邦学习技术的需求不断增长,联邦学习工具和框架的数量也越来越多。下面将介绍一些主流的联邦学习框架。
-
-TensorFlow联邦(TFF)是谷歌公司牵头的联邦学习开源框架,用于在分散数据上进行机器学习和其他计算。TFF的开发是为了促进联邦学习(FL)的开放研究和实验,这是一种机器学习的方法,在许多参与的客户中训练共享的全局模型,这些客户将其训练数据保存在本地。例如,联邦学习已被用于训练移动键盘的预测模型,而无需将敏感的键入数据上载到服务器。
-
-PaddleFL是百度提出的一个基于PaddlePaddle的开源联邦学习框架。研究人员可以很轻松地用PaddleFL复制和比较不同的联邦学习算法,开发人员也比较容易在大规模分布式集群中部署PaddleFL联邦学习系统。PaddleFL提供很多种联邦学习策略(横向联邦学习、纵向联邦学习)及其在计算机视觉、自然语言处理、推荐算法等领域的应用。此外,PaddleFL还将提供传统机器学习训练策略的应用,例如多任务学习、联邦学习环境下的迁移学习。依靠着PaddlePaddle的大规模分布式训练和Kubernetes对训练任务的弹性调度能力,PaddleFL可以基于全栈开源软件轻松地部署。
-
-FATE (Federated AI Technology Enabler) 由微众银行提出,是全球首个联邦学习工业级开源框架,可以让企业和机构在保护数据安全和数据隐私的前提下进行数据协作。 FATE项目使用多方安全计算 (MPC) 以及同态加密 (HE) 技术构建底层安全计算协议,以此支持不同种类的机器学习的安全计算,包括逻辑回归、基于树的算法、深度学习和迁移学习等。 FATE于2019年2月首次对外开源,并成立 [FATE TSC](https://github.com/FederatedAI/FATE-Community/blob/master/FATE_Project_Technical_Charter.pdf) 对FATE社区进行开源治理,成员包含国内主要云计算和金融服务企业。
-
-FedML是一个USC牵头提出的联邦学习开源研究和基准库,它有助于开发新的联合学习算法和公平的性能比较。FedML支持三种计算范式(分布式训练、移动设备上训练和独立模拟),供用户在不同的系统环境中进行实验。FedML还通过灵活和通用的API设计和参考基线实现促进多样化的算法研究。为非I.I.D设置精心策划的全面基准数据集旨在进行公平比较。FedML在https://FedML.ai上维护源代码、文档和用户社区。
-
-PySyft是UCL、DeepMind和OpenMind发布的安全和隐私深度学习Python库,包括联邦学习、差分隐私和多方学习。PySyft使用差分隐私和加密计算(如多方计算(MPC)和同态加密(HE))将私有数据与模型训练解耦流。
-
-Fedlearner是字节跳动提出的协作机器学习框架,它允许对分布在机构之间的数据进行联合建模。Fedlearner附带了用于群集管理、作业管理、作业监控和网络代理的周围基础架构。Fedlearner采用云原生部署方案。数据存放在HDFS。通过Kubernetes管理和拉起任务。每个Fedlearner的训练任务需要参与双方同时拉起K8S任务,通过Master节点统一管理,Worker建实现通信。
-
-OpenFL是英特尔提出的用于联邦学习的Python框架。OpenFL旨在成为数据科学家的灵活、可扩展和易于学习的工具。OpenFL由英特尔物联网集团(IOTG)和英特尔实验室开发。
-
-MindSpore Fedrated是华为提出的一款开源联邦学习框架,支持千万级无状态终端设备商用化部署,在用户数据留存在本地的情况下,使能全场景智能应用。 MindSpore Federated优先专注于大规模参与方的横向联邦的应用场景,使参与联邦学习的各用户在不共享本地数据的前提下共建AI模型。MindSpore Fedrated主要解决隐私安全、大规模联邦聚合、易用性和跨平台部署等联邦学习在工业场景部署的难点。
\ No newline at end of file
+## 概述
+
+随着人工智能的飞速发展,大规模和高质量的数据越来越重要,但也制约了其进一步的发展。隐私、监管和工程等问题造成了设备与设备之间的数据不能共享,进而导致了数据孤岛问题的出现。为了解决这一难题,联邦学习(Federated Learning,FL)应运而生。联邦学习的概念最早在2016年被提了出来,能有效帮助多个机构在满足用户隐私保护、数据安全和政府法规的要求下,进行数据使用和机器学习建模。
+
+### 定义
+
+联邦学习的核心即为数据不动,模型动。显然,若是将数据从各方集中在一起,无法保证对用户隐私的保护,不符合相关法律法规。联邦学习让模型在各个数据方“移动”,这样就可以达到数据不出端即可建模的效果。在联邦学习中,各方数据都保留在本地,通过(在中心服务器上)交换加密的参数建立机器学习模型。
+
+### 应用场景
+
+在实际的应用场景中,根据样本和特征的重叠情况,联邦学习可以被分为横向联邦学习(样本不同,特征重叠),纵向联邦学习(特征不同,样本重叠)和联邦迁移学习(样本和特征都不重叠)。
+
+**横向联邦学习**适用于不同参与方拥有的特征相同、但参与的个体不同的场景。比如,在广告推荐场景中,算法开发人员使用不同手机用户的相同特征(点击次数、停留时间或使用频次等)的数据来建立模型;抑或者是在输入法中用来预测由于这些特征数据不能出端,因此,横向联邦学习被用来联合多用户的数据来构建模型。
+
+**纵向联邦学习**适用于样本重叠多、特征重叠少的场景。比如,有两个不同机构,一家是保险公司,另一家是医院。它们的用户群体很有可能包含该地的大部分居民,用户的交集可能较大。由于保险公司记录的都是用户的收支行为与信用评级,而医院则保有用户的疾病与购药记录,因此它们的用户特征交集较小。纵向联邦学习就是将这些不同特征在加密的状态下加以聚合,以增强模型能力的联邦学习。
+
+**联邦迁移学习**的核心是找到源领域和目标领域之间的相似性。比如有两个不同机构,一家是位于中国的银行,另一家是位于美国的电商。由于受到地域限制,这两家机构的用户群体交集很小。同时,由于机构类型的不同,二者的数据特征也只有小部分重合。在这种情况下,要想进行有效的联邦学习,就必须引入迁移学习,来解决单边数据规模小和标签样本少的问题,从而提升模型的效果。
+
+### 部署场景
+
+联邦学习和参数服务器(数据中心分布式学习)架构非常相似,都是采用中心化的服务器和分散的客户端去构建同一个机器学习模型。此外,根据客户端来源和规模的不同,联邦学习还可以细分为跨组织(cross-silo)与跨设备(cross-device)联邦学习。一般而言,跨组织联邦学习的用户一般是企业、机构单位级别的,而跨设备联邦学习针对的则是便携式电子设备、移动端设备等。 :numref:`ch10-federated-learning-different-connection`展示了三者的区别和联系:
+
+
+:width:`800px`
+:label:`ch10-federated-learning-different-connection`
+
+### 常用框架
+
+随着用户和开发人员对联邦学习技术的需求不断增长,联邦学习工具和框架的数量也越来越多。下面将介绍一些主流的联邦学习框架。
+
+[TFF](https://www.tensorflow.org/federated) (TensorFlow Federated)是谷歌牵头开发的联邦学习开源框架,用于在分散数据上进行机器学习和其他计算。TFF的开发是为了促进联邦学习的开放研究和实验,这是一种机器学习的方法,在许多参与的客户中训练共享的全局模型,这些客户将其训练数据保存在本地。例如,联邦学习已被用于训练移动键盘的预测模型,而无需将敏感的键入数据上载到服务器。
+
+[PaddleFL](https://paddlefl.readthedocs.io/en/latest/index.html)是百度提出的一个基于PaddlePaddle的开源联邦学习框架。研究人员可以很轻松地用PaddleFL复制和比较不同的联邦学习算法,开发人员也比较容易在大规模分布式集群中部署PaddleFL联邦学习系统。PaddleFL提供很多种联邦学习策略(横向联邦学习、纵向联邦学习)及其在计算机视觉、自然语言处理、推荐算法等领域的应用。此外,PaddleFL还将提供传统机器学习训练策略的应用,例如多任务学习、联邦学习环境下的迁移学习。依靠着PaddlePaddle的大规模分布式训练和Kubernetes对训练任务的弹性调度能力,PaddleFL可以基于全栈开源软件轻松地部署。
+
+[FATE](https://fate.fedai.org) (Federated AI Technology Enabler)由微众银行提出,是全球首个联邦学习工业级开源框架,可以让企业和机构在保护数据安全和数据隐私的前提下进行数据协作。 FATE项目使用多方安全计算 (MPC) 以及同态加密 (HE) 技术构建底层安全计算协议,以此支持不同种类的机器学习的安全计算,包括逻辑回归、基于树的算法、深度学习和迁移学习等。 FATE于2019年2月首次对外开源,并成立 [FATE TSC](https://github.com/FederatedAI/FATE-Community/blob/master/FATE_Project_Technical_Charter.pdf) 对FATE社区进行开源治理,成员包含国内主要云计算和金融服务企业。
+
+[FedML](https://FedML.ai)是一个USC牵头提出的联邦学习开源研究和基准库,它有助于开发新的联合学习算法和公平的性能比较。FedML支持三种计算范式(分布式训练、移动设备上训练和独立模拟),供用户在不同的系统环境中进行实验。FedML还通过灵活和通用的API设计和参考基线实现促进多样化的算法研究。为非I.I.D设置精心策划的全面基准数据集旨在进行公平比较。
+
+[PySyft](https://openmined.github.io/PySyft/index.html)是UCL、DeepMind和OpenMined发布的安全和隐私深度学习Python库,包括联邦学习、差分隐私和多方学习。PySyft使用差分隐私和加密计算(如多方计算(MPC)和同态加密(HE))将私有数据与模型训练解耦流。
+
+[Fedlearner](https://github.com/bytedance/fedlearner)是字节跳动提出的协作机器学习框架,它允许对分布在机构之间的数据进行联合建模。Fedlearner附带了用于群集管理、作业管理、作业监控和网络代理的周围基础架构。Fedlearner采用云原生部署方案。数据存放在HDFS。通过Kubernetes管理和拉起任务。每个Fedlearner的训练任务需要参与双方同时拉起K8S任务,通过Master节点统一管理,Worker建实现通信。
+
+[OpenFL](https://openfl.readthedocs.io/en/latest/index.html)是英特尔提出的用于联邦学习的Python框架。OpenFL旨在成为数据科学家的灵活、可扩展和易于学习的工具。
+
+[Flower](https://flower.dev)是剑桥大学、Adap等发布的联邦学习开源系统,主要针对在大规模、异质化设备上部署联邦学习算法的应用场景进行优化。
+
+[MindSpore Fedrated](https://www.mindspore.cn/en) (昇思)是华为提出的一款开源联邦学习框架,支持千万级无状态终端设备商用化部署,在用户数据留存在本地的情况下,使能全场景智能应用。 MindSpore Federated优先专注于大规模参与方的横向联邦的应用场景,使参与联邦学习的各用户在不共享本地数据的前提下共建AI模型。MindSpore Fedrated主要解决隐私安全、大规模联邦聚合、易用性和跨平台部署等联邦学习在工业场景部署的难点。
diff --git a/chapter_federated_learning/privacy_encryption_algorithm.md b/chapter_federated_learning/privacy_encryption_algorithm.md
index 1229bea..d7d3b03 100644
--- a/chapter_federated_learning/privacy_encryption_algorithm.md
+++ b/chapter_federated_learning/privacy_encryption_algorithm.md
@@ -2,7 +2,7 @@
联邦学习过程中,用户数据仅用于本地设备训练,不需要上传至中央FL-Server。这样可以避免用户个人数据的直接泄露。然而联邦学习框架中,模型的权重以明文形式上云仍然存在间接泄露用户隐私的风险。敌手获取到用户上传的明文权重后,可以通过重构、模型逆向等攻击恢复用户的个人训练数据,导致用户隐私泄露。
-MindSpore Federated Learning框架,提供了基于本地差分隐私(LDP)和基于多方安全计算(MPC)的安全聚合算法,在本地模型的权重上云前对其进行加噪或加扰。在保证模型可用性的前提下,解决联邦学习中的隐私泄露问题。
+MindSpore Federated框架,提供了基于本地差分隐私(LDP)和基于多方安全计算(MPC)的安全聚合算法,在本地模型的权重上云前对其进行加噪或加扰。在保证模型可用性的前提下,解决联邦学习中的隐私泄露问题。
### 基于LDP的安全聚合
@@ -16,7 +16,7 @@ $$
在联邦学习中,假设FL-Client本地训练之后的模型权重矩阵是$W$,由于模型在训练过程中会“记住”训练集的特征,所以敌手可以借助$W$还原出用户的训练数据集。
-MindSpore Federated Learning提供基于本地差分隐私的安全聚合算法,防止本地模型的权重上云时泄露隐私数据。
+MindSpore Federated提供基于本地差分隐私的安全聚合算法,防止本地模型的权重上云时泄露隐私数据。
FL-Client会生成一个与本地模型权重$W$相同维度的差分噪声矩阵$G$,然后将二者相加,得到一个满足差分隐私定义的权重$W_p$:
@@ -28,7 +28,7 @@ FL-Client将加噪后的模型权重$W_p$上传至云侧FL-Server进行联邦聚
### 基于MPC的安全聚合
-尽管差分隐私技术可以适当保护用户数据隐私,但是当参与FL-Client数量比较少或者高斯噪声幅值较大时,模型精度会受较大影响。为了同时满足模型保护和模型收敛这两个要求,MindSpore Federated Learning提供了基于MPC的安全聚合方案。
+尽管差分隐私技术可以适当保护用户数据隐私,但是当参与FL-Client数量比较少或者高斯噪声幅值较大时,模型精度会受较大影响。为了同时满足模型保护和模型收敛这两个要求,MindSpore Federated提供了基于MPC的安全聚合方案。
在这种训练模式下,假设参与的FL-Client集合为$U$,对于任意FL-Client $u$和$v$,
它们会两两协商出一对随机扰动$p_{uv}$、$p_{vu}$,满足
@@ -49,4 +49,87 @@ $$
从而FL-Server聚合结果$\overline{x}$为:
-上面的过程只是介绍了聚合算法的主要思想,基于MPC的聚合方案是精度无损的,代价是通讯轮次的增加。
\ No newline at end of file
+上面的过程只是介绍了聚合算法的主要思想,基于MPC的聚合方案是精度无损的,代价是通讯轮次的增加。
+
+### 基于LDP-SignDS算法的安全聚合
+
+对于先前的基于维度加噪的LDP算法,在隐私预算一定时,添加到每个维度的噪声规模基本上与模型参数的数量成正比。因此,对于高维模型,可能需要非常多的参与方来减轻噪音对模型收敛的影响。为了解决上述“维度依赖”问题,MindSpore Federated 进一步提供了基于维度选择的**Sign-based Dimension Selection (SignDS)** :cite:`jiang2022signds`算法。SignDS算法的主要思想是,对于每一条真实的本地更新$\Delta\in\mathbb{R}^{d}$,用户端首先选择一小部分更新最明显的维度构建topk集合$S_k$,并以此选择一个维度集合$J$返回给FL-Server。FL-Server根据维度集合$J$构建一条对应的稀疏更新$\Delta^\prime$,并聚合所有稀疏更新进用于更新全局模型。由于本地模型更新与本地数据信息相关联,直接选取真实的最大更新维度可能导致隐私泄露。对此,SignDS算法在两方面实现了隐私保证。一方面,算法使用了一种基于指数机制(Exponential Mechanism, EM :cite:`mcsherry2007mechanism`)的维度选择算法**EM-MDS**,使得所选维度集满足严格的$\epsilon$-LDP保证;另一方面,在构建稀疏更新时,对所选维度分配一个常量值而不直接使用实际更新值,以保证稀疏更新和本地数据不再直接关联。由于维度选择满足$\epsilon$-LDP,且分配给所选维度的更新值与本地数据无关,根据差分隐私的传递性 :cite:`dwork2014algorithmic`,所构建的稀疏更新同样满足$\epsilon$-LDP保证。**相较于之前基于维度加噪的LDP算法,SignDS算法可以显著提升高维模型的训练精度。同时,由于FL-Client只需上传一小部分的维度值而不是所有的模型权重,因此联邦学习的上行通信量也被大大降低。**
+
+下面,我们分别对topk集合$S_k$的构建和EM-MDS维度选择算法进行详细介绍。
+
+首先,由于实际更新值有正负,直接给所有选定的维度分配相同的常量值可能会明显改变模型更新方向,影响模型收敛。为了解决这个问题,SignDS提出了一种基于符号的topk集合构建策略。具体来讲,算法引入了一个额外的符号变量$s\in\\{-1,1\\}$。该变量由FL-Client以等概率随机采样,用于确定本地更新$\Delta$的topk集合$S_k$。如果$s=1$,我们将$\Delta$按**真实更新值**排序,并将**最大**的$k$个更新维度记为$S_k$。我们进一步从$S_k$中随机选择一部分维度,并将$s=1$作为这些维度的更新值用以构建稀疏更新。直觉上,$S_k$中维度的更新值很可能大于零。因此,将$s=1$分配给选定的维度不会导致模型更新方向的太大差异,从而减轻了对模型精度的影响。类似的,当$s=-1$时,我们选取**最小**的$k$个更新维度记为$S_k$,并将$s=-1$分配给所选维度。
+
+下面,我们进一步介绍用于维度选择的EM-MDS算法。简单来说,EM-MDS算法的目的是从输出维度域$\mathcal{J}$中以一定概率$\mathcal{P}$随机选择一个维度集合$J\in\mathcal{J}$,不同维度集合对应的概率不同。我们假设$J$总共包含$h$个维度,其中有$\nu$个维度属于topk集合(即$|S_k \cap J|=\nu$,且$\nu\in[0,h]$),另外$h-\nu$个维度属于非topk集合。直观上,$\nu$越大,$J$中包含的topk维度越多,模型收敛越好。因此,我们希望给$\nu$较大的维度集合分配更高的概率。基于这个想法,我们将评分函数定义为:
+
+$$
+u(S_{k}, J) = 𝟙(|S_k\cap J| \geq \nu_{th}) = 𝟙(\nu \geq \nu_{th})
+$$
+:eqlabel:`score_function`
+
+$u(S_{k}, J)$用来衡量输出维度集合$J$中包含的topk维度的数量是否超过某一阈值$\nu_{th}$($\nu_{th}\in[1,h]$),超过则为1,否则为0。进一步,$u(S_{k}, J)$的敏感度可计算为:
+
+$$
+\phi = \max_{J\in\mathcal{J}} ||u(S_{k}, J) - u(S^\prime_{k}, J)||= 1 - 0 = 1
+$$
+:eqlabel:`sensitivity`
+
+注意 :eqref:`sensitivity`对于任意一对不同的topk集合$S_k$和$S_k^\prime$均成立。
+
+根据以上定义,EM-MDS算法描述如下:
+
+*给定真实本地更新$\Delta\in\mathbb{R}^{d}$的topk集合$S_k$和隐私预算$\epsilon$,输出维度集合$J\in\mathcal{J}$的采样概率为:*
+
+$$
+ \mathcal{P}=\frac{\mathrm{exp}(\frac{\epsilon}{\phi}\cdot u(S_{k}, J))}{\sum_{J^\prime\in\mathcal{J}}\mathrm{exp}(\frac{\epsilon}{\phi}\cdot u(S_{k}, J^\prime))}
+ =
+ \frac{\mathrm{exp}(\epsilon\cdot 𝟙(\nu \geq \nu_{th}))}{\sum_{\tau=0}^{\tau=h}\omega_{\tau}\cdot \mathrm{exp}(\epsilon\cdot 𝟙(\tau\geq\nu_{th}))}
+ =
+ \frac{\mathrm{exp}(\epsilon\cdot 𝟙(\nu \geq \nu_{th}))}{\sum_{\tau=0}^{\tau=\nu_{th}-1}\omega_{\tau} + \sum_{\tau=\nu_{th}}^{\tau=h}\omega_{\tau}\cdot \mathrm{exp}(\epsilon)}
+$$
+:eqlabel:`emmds`
+
+*其中,$\nu$是$J$中包含的topk维度数量,$\nu_{th}$是评分函数的阈值,$J^\prime$是任意一输出维度集合,$\omega_{\tau}=\binom{k}{\tau}\binom{d-k}{h-\tau}$是所有包含$\tau$个topk维度的集合数。*
+
+我们进一步提供了EM-MDS算法的隐私证明:
+
+对于每个FL-Client,给定随机采样的符号值$x$,任意两个本地更新$\Delta$,$\Delta^\prime$的topk集合记为$S_k$和$S_k^\prime$,对于任意输出维度集合$J\in\mathcal{J}$,令$\nu=|S_k \cap J|$, $\nu^\prime=|S_k^\prime \cap J|$为$J$与两组topk维度集的交集数量。根据 :eqref:`emmds`,以下不等式成立:
+
+$$
+\frac{\mathrm{Pr}\[J|\Delta\]}{\mathrm{Pr}\[J|\Delta^\prime\]} = \frac{\mathrm{Pr}\[J|S_{k}\]}{\mathrm{Pr}\[J|S^\prime_{k}\]} = \frac{\frac{\mathrm{exp}(\frac{\epsilon}{\phi}\cdot u(S_{k}, J))}{\sum_{J^\prime\in\mathcal{J}}\mathrm{exp}(\frac{\epsilon}{\phi}\cdot u(S_{k}, J^\prime))}}{\frac{\mathrm{exp}(\frac{\epsilon}{\phi}\cdot u(S^\prime_{k}, J))}{\sum_{J^\prime\in\mathcal{J}}\mathrm{exp}(\frac{\epsilon}{\phi}\cdot u(S^\prime_{k}, J^\prime))}}
+ = \frac{\frac{\mathrm{exp}(\epsilon\cdot 𝟙(\nu \geq \nu_{th}))}{\sum_{\tau=0}^{\tau=h}\omega_{\tau}\cdot \mathrm{exp}(\epsilon\cdot 𝟙(\tau\geq\nu_{th}))}}{\frac{
+ \mathrm{exp}(\epsilon\cdot 𝟙(\nu^\prime \geq \nu_{th}))}{\sum_{\tau=0}^{\tau=h}\omega_{\tau}\cdot \mathrm{exp}(\epsilon\cdot 𝟙(\tau\geq\nu_{th}))}} \\
+ = \frac{\mathrm{exp}(\epsilon\cdot 𝟙(\nu \geq \nu_{th}))}{
+ \mathrm{exp}(\epsilon\cdot 𝟙(\nu^\prime \geq \nu_{th}))}
+ \leq \frac{\mathrm{exp}(\epsilon\cdot 1)}{\mathrm{exp}(\epsilon\cdot 0)} = \mathrm{exp}(\epsilon)
+$$
+
+*证明EM-MDS算法满足$\epsilon$-LDP保证。*
+
+值得注意的是,计算 :eqref:`emmds`需要先确定topk维度数的阈值$\nu_{th}$。为此,我们首先推导在给定阈值$\nu_{th}$时,任意一组输出维度集合$J$包含的topk维度的概率分布和期望:
+
+$$
+\mathrm{Pr}(\nu=\tau|\nu_{th})=
+ \begin{cases}
+ \omega_{\tau} / \Omega \quad \quad \quad \quad \quad \mathrm{ } &if \quad \tau\in\[0,\nu_{th}\) \\
+ \omega_{\tau}\cdot\mathrm{exp}(\epsilon) / \Omega \quad \quad &if \quad \tau\in\[\nu_{th},h\]
+ \end{cases}
+$$
+:eqlabel:`discrete-prob`
+
+$$
+ \mathbb{E}\[\nu|\nu_{th}\] = \sum_{\tau=0}^{\tau=h}\tau\cdot \mathrm{Pr}(\nu=\tau|\nu_{th})
+$$
+:eqlabel:`expectation`
+
+这里,$\Omega$为 :eqref:`emmds`中$\mathcal{P}$的分母部分。直觉上,$\mathbb{E}\[\nu|\nu_{th}\]$越高,随机采样的$J$集合中包含的topk维度的概率就越大,从而模型效用就越好。因此,我们将$\mathbb{E}\[\nu|\nu_{th}\]$最高时的阈值确定为目标阈值$\nu_{th}^{\*}$,即:
+
+$$
+\nu_{th}^{\*} = \underset{\nu_{th}\in\[1, h\]}{\operatorname{argmax}} \mathbb{E}\[\nu|\nu_{th}\]
+$$
+:eqlabel:`threshold`
+
+最后,我们在 :numref:`signds_workflow`中描述了SignDS算法的详细流程。给定本地模型更新$\Delta$,我们首先随机采样一个符号值$s$并构建topk集合$S_k$。接下来,我们根据 :eqref:`threshold`确定阈值$\nu_{th}^{\*}$并遵循 :eqref:`emmds`定义的概率选择输出集合$J$。考虑到输出域$\mathcal{J}$包含$\binom{d}{k}$个可能的维度集合,以一定概率直接从$\mathcal{J}$中随机采样一个组合需要很大的计算成本和空间成本。因此,我们采用了逆采样算法以提升计算效率。具体来说,我们首先从标准均匀分布中采样一个随机值$\beta\sim U(0,1)$,并根据 :eqref:`discrete-prob`中$p(\nu=\tau|\nu_{th})$的累计概率分布$CDF_{\tau}$确定输出维度集合中包含的topk维度数$\nu$。最后,我们从topk集合$S_k$中随机选取$\nu$个维度,从非topk集合中随机采样$h-\nu$个维度,以构建最终的输出维度集合$J$。
+
+
+:width:`800px`
+:label:`signds_workflow`
diff --git a/chapter_federated_learning/summary.md b/chapter_federated_learning/summary.md
index 720966e..a3f35af 100644
--- a/chapter_federated_learning/summary.md
+++ b/chapter_federated_learning/summary.md
@@ -1,3 +1,7 @@
## 小结
-在这一章,我们简单介绍了联邦学习的背景、系统架构、联邦平均算法、隐私加密算法以及实际部署时的挑战。联邦学习是一个新起步的人工智能算法,可以在“数据保护”与“数据孤岛”这两大约束条件下,建立有效的机器学习模型。此外,由于联邦学习场景的特殊性(端侧数据不上传、安全隐私要求高和数据非独立同分布等特点),使得系统和算法的开发难度更高:如何平衡计算和通讯的开销?如何保证模型不会泄露隐私?算法如何在非独立同分布场景下收敛?等等,都需要开发人员对实际的联邦学习场景有更深刻的认识。
\ No newline at end of file
+在这一章,我们简单介绍了联邦学习的背景、系统架构、联邦平均算法、隐私加密算法以及实际部署时的挑战。联邦学习是一个新起步的人工智能算法,可以在“数据保护”与“数据孤岛”这两大约束条件下,建立有效的机器学习模型。此外,由于联邦学习场景的特殊性(端侧数据不上传、安全隐私要求高和数据非独立同分布等特点),使得系统和算法的开发难度更高:如何平衡计算和通讯的开销?如何保证模型不会泄露隐私?算法如何在非独立同分布场景下收敛?这些难点都需要开发人员对实际的联邦学习场景有更深刻的认识。
+
+在这一章,我们简单介绍了联邦学习的背景、系统架构、联邦平均算法、隐私加密算法以及实际部署时的挑战。联邦学习是一个新起步的人工智能算法,可以在“数据保护”与“数据孤岛”这两大约束条件下,建立有效的机器学习模型。
+
+此外,由于联邦学习场景的特殊性(端侧数据不上传、安全隐私要求高和数据非独立同分布等特点),使得系统和算法的开发难度更高。如何平衡计算和通讯的开销,如何保证模型不会泄露隐私,以及算法如何在非独立同分布场景下收敛等等,都需要开发人员对实际的联邦学习场景有更深刻的认识。
diff --git a/chapter_federated_learning/vertical_fl.md b/chapter_federated_learning/vertical_fl.md
index 6ffd635..7629463 100644
--- a/chapter_federated_learning/vertical_fl.md
+++ b/chapter_federated_learning/vertical_fl.md
@@ -6,7 +6,7 @@
### 纵向联邦架构
-
+
:width:`800px`
:label:`federated-learning-vfl-arch`
@@ -49,7 +49,7 @@ $${t_i}^{'}=H^{'}(K_{b:i}) \\I=\{t_1,...,t_w\}\cap \{{t_1}^{'},...,{t_v}^{'}\}$$
在确样本ID对齐后,就可以使用这些公共的数据来训练机器学习模型。目前,线性回归、决策树和神经网络等模型已经被广泛应用到纵向联邦系统中。
在纵向联邦的模型训练过程中,一般会引入第三方协作者C来实现中心服务器功能,并且假设这个第三方协作者C是可信的,不会与其他参与方合谋。中心服务器在训练过程中作为中立方,产生和分发密钥,并对加密数据进行解密和计算。但中心服务器角色是非必须的,例如在两方联邦学习的场景下,不需要第三方协作者C来协调双方的训练任务,可以由具有标签数据的企业A来充当中心服务服务器的角色。不失一般性,下面继续以包含第三方协作者C的方案来描述纵向联邦模型联合训练过程。
-
+
:width:`800px`
:label:`federated-learning-vfl-train`
@@ -65,4 +65,3 @@ Paillier算法是一种满足加法的同态加密算法,已经广泛应用在
模型联合训练完成后就可以投入生产环境部署应用。由于纵向联邦中每个参与方具有部分模型结构,因此推理也需要双方协作完成计算。联合推理过程和联合训练类似,首先第三方协作者C将推理数据ID发送给企业A和B,双方在本地完成推理计算后将结果加密后传输到第三方协作者C,由C计算模型最终的联合推理结果。
-
diff --git a/chapter_frontend_and_ir/intermediate_representation.md b/chapter_frontend_and_ir/intermediate_representation.md
index 94321ca..5cb1f31 100644
--- a/chapter_frontend_and_ir/intermediate_representation.md
+++ b/chapter_frontend_and_ir/intermediate_representation.md
@@ -10,8 +10,8 @@
引入中间表示后,中间表示既能面向多个前端,表达多种源程序语言,又能对接多个后端,连接不同目标机器,如 :numref:`intermediate_representation`所示。在此基础上,编译流程就可以在前后端直接增加更多的优化流程,这些优化流程以现有IR为输入,又以新生成的IR为输出,被称为优化器。优化器负责分析并改进中间表示,极大程度的提高了编译流程的可拓展性,也降低了优化流程对前端和后端的破坏。
-
-:width:`800px`
+
+:width:`850px`
:label:`intermediate_representation`
随着编译器技术的不断演进,中间表示主要经历了三个发展阶段。在早期阶段,中间表示是封闭在编译器内部的,供编译器编写者使用。在中期阶段,随着编译器的开源,中间表示逐步开源公开,主要供编译器设计者、分析工具设计者使用。现阶段,中间表示朝着软件生态构建的方向发展,旨在构建统一的中间表示。
@@ -30,14 +30,14 @@
: 中间表示的分类
:::
-1\) 线性中间表示
+1\) 线性中间表示/Users/liangzhibo/Desktop/中间表示-中间表示结构.png
线性中间表示类似抽象机的汇编代码,将被编译代码表示为操作的有序序列,对操作序列规定了一种清晰且实用的顺序。由于大多数处理器采用线性的汇编语言,线性中间表示广泛应用于编译器设计。
常用线性中间表示有堆栈机代码(Stack-Machine Code)和三地址代码(Three
Address Code) :cite:`2007Compilers` 。堆栈机代码是一种单地址代码,提供了简单紧凑的表示。堆栈机代码的指令通常只有一个操作码,其操作数存在一个栈中。大多数操作指令从栈获得操作数,并将其结果推入栈中。三地址代码,简称为3AC,模拟了现代RISC机器的指令格式。它通过一组四元组实现,每个四元组包括一个运算符和三个地址(两个操作数、一个目标)。对于表达式a-b\*5,堆栈机代码和三地址代码如 :numref:`linear_ir`所示。
-
+
:width:`800px`
:label:`linear_ir`
@@ -50,7 +50,7 @@ Graph,DAG)、控制流图(Control-Flow Graph,CFG)等。
AST抽象语法树采用树型中间表示的形式,是一种接近源代码层次的表示。对于表达式$a*5+a*5*b$,其AST表示如 :numref:`AST_DAG`所示。可以看到,AST形式包含$a*5$的两个不同副本,存在冗余。在AST的基础上,DAG提供了简化的表达形式,一个节点可以有多个父节点,相同子树可以重用。如果编译器能够证明$a$的值没有改变,则DAG可以重用子树,降低求值过程的代价。

-:width:`600px`
+:width:`400px`
:label:`AST_DAG`
3、混合中间表示
@@ -61,8 +61,8 @@ IR使用线性中间表示表示基本块,使用图中间表示表示这些块
Single Assignment, SSA) :cite:`Richard1995A`
形式呈现,这些指令构成一个指令线性列表。SSA形式要求每个变量只赋值一次,并且每个变量在使用之前定义。控制流图中,每个节点为一个基本块,基本块之间通过边实现控制转移。
-
-:width:`600px`
+
+:width:`800px`
:label:`LLVM_IR`
### 机器学习框架的中间表示
@@ -99,12 +99,36 @@ IR作为PyTorch模型的中间表示,通过JIT即时编译的形式,将Pytho
PyTorch框架采用命令式编程方式,其TorchScript
IR以基于SSA的线性IR为基本组成形式,并通过JIT即时编译的Tracing和Scripting两种方法将Python代码转换成TorchScript
-IR。如 :numref:`TorchScript_IR`给出了Python示例代码及其TorchScript
-IR。
+IR。如下Python代码使用了Scripting方法并打印其对应的中间表示图:
+```python
+import torch
-
-:width:`800px`
-:label:`TorchScript_IR`
+@torch.jit.script
+def test_func(input):
+ rv = 10.0
+ for i in range(5):
+ rv = rv + input
+ rv = rv/2
+ return rv
+
+print(test_func.graph)
+```
+该中间表示图的结构为:
+```
+graph(%input.1 : Tensor):
+ %9 : int = prim::Constant[value=1]()
+ %5 : bool = prim::Constant[value=1]() # test.py:6:1
+ %rv.1 : float = prim::Constant[value=10.]() # test.py:5:6
+ %2 : int = prim::Constant[value=5]() # test.py:6:16
+ %14 : int = prim::Constant[value=2]() # test.py:8:10
+ %rv : float = prim::Loop(%2, %5, %rv.1) # test.py:6:1
+ block0(%i : int, %rv.9 : float):
+ %rv.3 : Tensor = aten::add(%input.1, %rv.9, %9) # :5:9
+ %12 : float = aten::FloatImplicit(%rv.3) # test.py:7:2
+ %rv.6 : float = aten::div(%12, %14) # test.py:8:7
+ -> (%5, %rv.6)
+ return (%rv)
+```
TorchScript是PyTorch的JIT实现,支持使用Python训练模型,然后通过JIT转换为语言无关的模块,从而提升模型部署能力,提高编译性能。同时,TorchScript
@@ -116,12 +140,38 @@ Jax机器学习框架同时支持静态图和动态图,其中间表示采用Ja
Representation) IR。Jaxpr
IR是一种强类型、纯函数的中间表示,其输入、输出都带有类型信息,函数输出只依赖输入,不依赖全局变量。
-
-:width:`800px`
-:label:`Jaxpr`
Jaxpr IR的表达采用ANF(A-norm
-Form)函数式表达形式,如 :numref:`Jaxpr`所示。ANF形式将表达式划分为两类:原子表达式(aexp)和复合表达式(cexp)。原子表达式用于表示常数、变量、原语、匿名函数,复合表达式由多个原子表达式组成,可看作一个匿名函数或原语函数调用,组合的第一个输入是调用的函数,其余输入是调用的参数。
+Form)函数式表达形式,ANF文法如下所示:
+
+```
+ ::= NUMBER | STRING | VAR | BOOLEAN | PRIMOP
+ | (lambda (VAR ...) )
+ ::= ( ...)
+ | (if )
+ ::= (let ([VAR ]) ) | |
+```
+
+ANF形式将表达式划分为两类:原子表达式(aexp)和复合表达式(cexp)。原子表达式用于表示常数、变量、原语、匿名函数,复合表达式由多个原子表达式组成,可看作一个匿名函数或原语函数调用,组合的第一个输入是调用的函数,其余输入是调用的参数。如下代码打印了一个函数对应的JaxPr:
+```python
+from jax import make_jaxpr
+import jax.numpy as jnp
+
+def test_func(x, y):
+ ret = x + jnp.sin(y) * 3
+ return jnp.sum(ret)
+
+print(make_jaxpr(test_func)(jnp.zeros(8), jnp.ones(8)))
+```
+其对应的JaxPr为:
+```
+{ lambda ; a:f32[8] b:f32[8]. let
+ c:f32[8] = sin b
+ d:f32[8] = mul c 3.0
+ e:f32[8] = add a d
+ f:f32[] = reduce_sum[axes=(0,)] e
+ in (f,) }
+```
Jax框架结合了Autograd 和 JIT,基于Jaxpr
IR,支持循环、分支、递归、闭包函数求导以及三阶求导,并且支持自动微分的反向传播和前向传播。
@@ -132,8 +182,8 @@ TensorFlow框架同时支持静态图和动态图,是一个基于数据流编
为了适配不同的硬件平台,基于静态计算图,TensorFlow采用了多种IR设计,其编译生态系统如 :numref:`TFIR`所示。蓝色部分是基于图的中间表示,绿色部分是基于SSA的中间表示。在中间表示的转换过程中,各个层级的中间表示各自为政,无法互相有效地沟通信息,也不清楚其他层级的中间表示做了哪些优化,因此每个中间表示只能尽力将当前的优化做到最好,造成了很多优化在每个层级的中间表示中重复进行, 从而导致优化效率的低下。尤其是从图中间表示到SSA中间表示的变化过大,转换开销极大。此外,各个层级的相同优化的代码无法复用,也降低了开发效率。
-
-:width:`600px`
+
+:width:`1000px`
:label:`TFIR`
4、MLIR
@@ -178,17 +228,38 @@ typed)。每个节点需要有一个具体的类型,这个对于性能最大
在结合MindSpore框架的自身特点后,MindIR的定义如 :numref:`MindIR`所示。
-
-:width:`800px`
+
+:width:`1100px`
:label:`MindIR`
-接下来我们通过 :numref:`MindIR_example`中的一段程序作为示例,来进一步分析MindIR。
+接下来我们通过如下的一段程序作为示例,来进一步分析MindIR。
-
-:width:`600px`
-:label:`MindIR_example`
+```python
+def func(x, y):
+ return x / y
-在ANF中,每个表达式都用let表达式绑定为一个变量,通过对变量的引用来表示对表达式输出的依赖,而在MindIR中,每个表达式都绑定为一个节点,通过节点与节点之间的有向边表示依赖关系。其函数图表示如 :numref:`MindIR_graph`所示。
+@ms_function
+def test_f(x, y):
+ a = x - 1
+ b = a + y
+ c = b * func(a, b)
+ return c
+```
+
+该函数对应的ANF表达式为:
+```
+lambda (x, y)
+ let a = x - 1 in
+ let b = a + y in
+ let func = lambda (x, y)
+ let ret = x / y in
+ ret end in
+ let %1 = func(a, b) in
+ let c = b * %1 in
+ c end
+```
+
+在ANF中,每个表达式都用let表达式绑定为一个变量,通过对变量的引用来表示对表达式输出的依赖,而在MindIR中,每个表达式都绑定为一个节点,通过节点与节点之间的有向边表示依赖关系。该函数对应的MindIR的可视化表示如 :numref:`MindIR_graph`所示。

:width:`800px`
diff --git a/chapter_frontend_and_ir/summary.md b/chapter_frontend_and_ir/summary.md
index fdd82c5..21c69cc 100644
--- a/chapter_frontend_and_ir/summary.md
+++ b/chapter_frontend_and_ir/summary.md
@@ -1,11 +1,10 @@
-总结
-----
+## 总结
- 中间表示是编译器的核心数据结构之一,是程序编译过程中介于源语言和目标语言之间的程序表示。
- 传统编译器的中间表示从组织结构出发,可以分为线性中间表示,图中间表示以及混合中间表示。
-- 机器学习框架的中间对中间表示有一系列新的需求,这些新的需求是传统中间表示所不能完美支持的。因此需要在传统中间表示的基础上扩展新的,更适用于机器学习框架的中间表示。
+- 机器学习框架对中间表示有一系列新的需求,这些新的需求是传统中间表示所不能完美支持的。因此需要在传统中间表示的基础上扩展新的,更适用于机器学习框架的中间表示。
- 自动微分的基本思想是将计算机程序中的运算操作分解为一个有限的基本操作集合,且集合中基本操作的求导规则均为已知,在完成每一个基本操作的求导后,使用链式法则将结果组合得到整体程序的求导结果。
@@ -13,10 +12,19 @@
- 前向自动微分更适用于对输入维度小于输出维度的网络求导,反向自动微分则更适用于对输出维度小于输入维度的网络求导。
-- 自动微分的实现方法大体上可以划分为基本表达式法,操作符重载法以及代码变化法。
+- 自动微分的实现方法大体上可以划分为基本表达式法、操作符重载法以及代码变化法。
- 类型系统是指类型的集合以及使用类型来规定程序行为的规则,用于定义不同的类型,指定类型的操作和类型之间的相互作用,广泛应用于编译器、解释器和静态检查工具中。
- 静态分析,是指在不实际运行程序的情况下,通过词法分析、语法分析、控制流、数据流分析等技术对代码进行分析验证的技术
- 编译优化意在解决编译生成的中间表示的低效性,前端执行的均为与硬件无关的编译优化。
+
+
+## 扩展阅读
+
+- 一种基于图的中间表示类型: [综述](https://dl.acm.org/doi/10.1145/202530.202534)
+
+- 机器学习框架中的自动微分: [综述](https://arxiv.org/abs/1502.05767)
+
+- 函数式框架中的反向自动微分: [综述](https://dl.acm.org/doi/10.1145/1330017.1330018)
diff --git a/chapter_introduction/applicable_readers.md b/chapter_introduction/applicable_readers.md
index ace0a2a..f4eed3e 100644
--- a/chapter_introduction/applicable_readers.md
+++ b/chapter_introduction/applicable_readers.md
@@ -1,13 +1,12 @@
## 适用读者
-本书由浅入深地讨论了机器学习系统的设计原理和实现。本书的常见读者包括:
+本书由浅入深地讨论机器学习系统的设计原理和实现经验。其读者包括:
- **学生:**
- 随着大量机器学习课程在大学中的普及,学生已经开始掌握大量机器学习的基础理论和神经网络的实现。然而,需要训练出可以实际应用的机器学习模型,需要对现代机器学习系统有充分的认识。
+ 本书将帮助学生获得大量机器学习系统的设计原则和一手实践经验。从而帮助其更全面理解机器学习算法的实践挑战和理论优劣。
- **科研人员:**
- 研发新型的机器学习模型不仅仅需要会使用基础的机器学习系统接口。同时,新型的模型往往需要给系统提供新的自定义算子(Custom
- Operators),又或者是会利用高级的分布式执行算子来实现大模型的开发。这一系列需求都需要对底层系统具有充分认识。
+ 本书将帮助科研人员学习到机器学习落地实践中遇到的种种挑战,引导设计出能解决大规模实际问题的下一代机器学习算法。
- **开发人员:**
- 大量的数据和AI驱动的公司都部署了机器学习基础设施。这一设施的核心就是机器学习系统。因此了解机器学习系统有助于开发人员对于系统性能调优,以定位问题,并且根据业务需求对机器学习系统进行深度定制。
\ No newline at end of file
+ 本书将帮助开发人员深刻理解机器学习系统的内部架构,从而帮助其优化系统性能,调试问题,并且根据业务需求对机器学习系统进行定制。
\ No newline at end of file
diff --git a/chapter_introduction/components_of_machine_learning_systems.md b/chapter_introduction/components_of_machine_learning_systems.md
index d95a3b9..5189f42 100644
--- a/chapter_introduction/components_of_machine_learning_systems.md
+++ b/chapter_introduction/components_of_machine_learning_systems.md
@@ -1,35 +1,35 @@
-## 机器学习系统基本组成
+## 基本组成
-为了达到上述设计目标,一个现代的机器学习框架往往具有如 :numref:`framework_architecture`所示的基本架构。
+一个完整的机器学习系统往往具有如 :numref:`framework_architecture`所示的基本架构。
-
+
:width:`600px`
:label:`framework_architecture`
-- **编程接口:** 一个机器学习框架面向用户的编程接口(Programming
- interface)需要特殊设计。编程接口提供简单易用的编程函数(往往是Python)从而让用户定义出各式各样的神经网络和相关的训练过程。同时,编程接口要兼顾性能:神经网络的执行可以调用硬件相关C和C++函数(许多加速器和操作系统的编程接口)。该部分的内容将在第2章展开。
+- **编程接口:** 为了支持广泛的开发者,机器学习框架的编程接口不仅需要高层次简易编程(例如,Python,Julia和Java),同时也需要支持低层次高性能编程(利用C和C++函数调用操作系统和硬件加速器)。
- **计算图:**
- 用户定义的机器学习程序往往会表达成一个计算图(Computational
- graph)。这个计算图使得用户并行计算和异步执行得以实现。该部分内容将在第3章展开。
-
-- **计算加速器:**
- 现代计算加速器提供了丰富的编程接口让应用来优化其相关性能。而如何高效使用计算加速器是许多机器学习框架的核心。我们将在第4章中讨论加速器的加速原理和相关使用技巧。
+ 利用不同编程接口实现的机器学习程序需要共享一个运行后端。实现这一后端的关键技术是:应用无关的计算图。计算图包含计算节点,节点之间的边表达计算依赖。计算图可以被同步和异步执行。
- **编译器前端:**
- 在将计算图发送到加速器执行之前,机器学习框架往往会对计算图做一系列硬件无关的一系列优化,这一过程被称之为:编译器前端。其中核心步骤是对用户定义的神经网络训练实现自动微分。在此期间,计算图会被表示为中间表达(Intermediate
- Representation),并同时应用类型系统和静态分析等一系列技术。我们将在第5章中讨论相关内容。
+ 给定一个计算图,机器学习框架会对计算图做一系列优化。和硬件无关的优化由编译器前端实现。编译器前端实现包括:中间表达,自动微分,类型推导和静态分析等等。
-- **编译器后端:**
- 编译器前端生成的中间表达可以进一步针对硬件的特性(例如说,L2/L3大小,指令流水线长度)进行性能优化,硬件算子选择,内存分配。这一以硬件为核心的编译过程被称为:编译器后端,该部分内容将在第6章中讨论。
+- **编译器后端和运行时:**
+ 机器学习框架利用编译器后端对计算图可以进一步针对硬件的特性(例如说,L2/L3大小,指令流水线长度)进行性能优化。最终优化后的计算图通过运行时执行在通用处理器(CPU)或者是硬件加速器之上。运行时需要实现算子选择和内存分配等技术。
+
+- **硬件加速器:**
+ 现代硬件加速器提供了丰富的编程接口。在本书中,我们将会介绍硬件加速器的基本组成原理和编程接口。我们同时会给出一个硬件加速器使用案例来从0到1讲述如何高效使用加速器。
- **数据处理:**
- 机器学习框架会集成多种数据管理模块。其中包括数据预处理模块,模型参数checkpoint,模型可视化和训练结果可视化等。该部分内容将在第7章中讨论。
+ 机器学习系统拥有专门的数据处理框架来实现数据读取,存储和预处理的功能由数据处理模块(例如,TensorFlow的tf.data和PyTorch的DataLoader)。这一框架需要针对机器学习应用实现易用性,保序性和高效性等设计目标。
- **模型部署:**
- 在模型完成训练后,用户需要对模型进行部署。该过程中,我们会根据部署硬件的特点进行模型格式的转换,针对硬件特性进行推理性能优化。同时,移动硬件往往具有小内存的特点。因此大量的模型压缩技术也在部署中得到应用。这些相关内容将在第8章中讨论。
+ 在模型完成训练后,下一个常用的系统功能是:模型部署。为了确保模型可以在内存有限的硬件上执行,我们会使用模型转换,量化,蒸馏等模型压缩技术。同时,我们也需要实现针对推理硬件平台(例如,英伟达Jetson)的模型算子优化。最后,为了保证模型的安全(不被黑客窃取),实践者还会对模型进行混淆设计。
- **分布式训练:**
- 当模型的训练需要大量内存和算力的时候,机器学习框架会提供原生的分布式执行编程接口。分布式机器学习系统已经在工业界得到大量的部署。相关内容会在第9章讨论。
+ 分布式训练日渐成为一个机器学习框架的核心组件。本书将介绍常见的分布式训练方法(数据并行,模型并行,混合并行和流水线并行)。同时我们会深入介绍这些方法的高效系统实现(包括集合通讯库和参数服务器)。
-除了上述核心组件以外,机器学习系统作为一个依然高速发展的前沿学科,还有大量的问题正在被密集研究,相关的前沿问题将在本书的第10章中展开讨论。另外,机器学习算法相关的理论知识是本书的预备知识,本书不做深入讨论。基础的机器学习理论知识可以在附录中找到。
\ No newline at end of file
+- **拓展模块:**
+ 机器学习系统的广泛部署使得许多的扩展模块陆续出现。本书将会介绍得到大量实践部署的拓展模块:深度学习推荐系统,联邦学习系统,强化学习系统,可解释性AI系统和机器人系统。
+
+机器学习算法相关的理论知识是本书的预备知识,本书不做深入讨论。基础的机器学习理论知识可以在附录中找到。
\ No newline at end of file
diff --git a/chapter_introduction/machine_learning_applications.md b/chapter_introduction/machine_learning_applications.md
index d82caed..e790865 100644
--- a/chapter_introduction/machine_learning_applications.md
+++ b/chapter_introduction/machine_learning_applications.md
@@ -1,10 +1,14 @@
## 机器学习应用
-通俗来讲,机器学习是指从数据中学习出有用知识的计算技术。从处理的数据类型和学习模式来说,机器学习可以分为监督学习(Supervised
+通俗来讲,机器学习是指从数据中学习出有用知识的技术。从学习模式来说,机器学习可以分为监督学习(Supervised
Learning)、无监督学习(Unsupervised Learning)、强化学习(Reinforcement
-Learning)等等。监督学习是已知输入输出对应关系情况下的学习,比如给定输入图像和它对应的内容标签,则学习图像分类(Classification);而无监督学习是只有输入数据但不知道输出标签情况下的学习,比如:给定一堆猫和狗的图像,自主学会猫和狗的分类,这种无监督分类也称为聚类(Clustering);强化学习则是给定一个学习环境和任务目标,算法自主地去不断尝试、改进自己、以实现任务目标。比如AlphaGo围棋就是用强化学习实现的,给定的环境是围棋的规则、而目标则是胜利得分。
+Learning)等:
-从应用领域上划分,主要可以包括计算机视觉、自然语言处理和智能决策这三大部分,而且这三大部分之间也有很多交集。
+* 监督学习是已知输入输出对应关系情况下的学习,比如: 给定输入图像和它对应的内容标签,学习图像分类(Classification)。
+* 无监督学习是只有输入数据但不知道输出标签情况下的学习,比如:给定一堆猫和狗的图像,自主学会猫和狗的分类,这种无监督分类也称为聚类(Clustering)。
+* 强化学习则是给定一个学习环境和任务目标,算法自主地去不断尝试、改进自己、以实现任务目标 ,比如: AlphaGo围棋就是用强化学习实现的,给定的环境是围棋的规则、而目标则是胜利得分。
+
+从应用领域上划分,主要包括计算机视觉、自然语言处理和智能决策这三大部分,而且这三大部分之间也有交集。
狭义上来讲基于图像的应用都可归为计算机视觉方面的应用,典型的应用有人脸识别、物体识别、目标跟踪、人体姿态估计、以及图像的理解、修复、分割与检测等等。
计算机视觉方法广泛应用于自动驾驶、智慧城市、智慧安防等领域。
自然语言处理涉及文本或者语音方面的应用,典型的应用包括语言翻译、文本转语音、语音转文本、以及文本理解、分类、风格变换与纠错等等。
@@ -16,4 +20,4 @@ Machine,SVM)、逻辑回归(Logistic Regression)、朴素贝叶斯(Naive
Bayes)
等方法。然而得力于大数据互联网和计算机性能的提升,以深度学习(Deep
Learning)为代表的方法得到了广泛的研究和应用。
-虽然机器学习算法很多,但无论是经典算法还是深度学习算法的计算往往以向量、矩阵运算为主体的,因此本书主要通过深度神经网络为例子展开机器学习系统的介绍。下面我们来快速了解一下机器学习系统的设计需求、目标、以及其组成原理。
\ No newline at end of file
+虽然机器学习算法很多,但无论是经典算法还是深度学习算法的计算往往以向量、矩阵运算为主体的,因此本书主要通过深度神经网络为例子展开机器学习系统的介绍。下面我们来快速了解一下机器学习系统的设计需求、实现目标以及组成原理。
\ No newline at end of file
diff --git a/chapter_introduction/requirements_for_machine_learning_systems.md b/chapter_introduction/requirements_for_machine_learning_systems.md
index f1540c6..671bc64 100644
--- a/chapter_introduction/requirements_for_machine_learning_systems.md
+++ b/chapter_introduction/requirements_for_machine_learning_systems.md
@@ -1,39 +1,38 @@
-## 机器学习系统的需求
-
+## 设计目标
+
:width:`600px`
:label:`framework_position`
-为了支持日益增长的机器学习应用,开发者普遍需要一个新型的系统软件:机器学习框架(如 :numref:`framework_position`所示)。这种框架一方面可以帮助用户进行高效的开发,另一方面使得机器学习模型的训练和部署可以高效使用通用处理器和计算加速器。在设计机器学习框架的过程,人们总结出了以下几个设计需求:
+开发者需要设计和实现机器学习系统来满足以下目标(如 :numref:`framework_position`所示):
- **支持多种神经网络:**
- 深度学习的崛起使得神经网络成为了大量机器学习应用的核心。不同的应用具有多种数据形态和机器学习的目标,因此人们设计出了大量不同的神经网络,例如,卷积神经网络(Convolutional
+ 深度学习的巨大成功使得神经网络成为了机器学习应用的核心。不同应用需要不同的神经网络,例如,卷积神经网络(Convolutional
Neural Networks),图神经网络(Graph Neural
- Networks),自注意力神经网络(Self-attention Neural
- Networks)等等。人们需要一个统一的框架来开发各种各种的神经网络。
+ Networks),自注意力神经网络(Self-Attention Neural
+ Networks)等。这些神经网络需要一个共同的系统软件来进行开发和运行。
- **支持自动微分:**
- 神经网络模型的的一个核心优点是:其可以利用数据、标注(Label)和目标损失函数(Loss
- Function)来自动计算梯度(Gradients),以实现机器学习模型的参数更新。一套神经网络模型可以应用在不同的数据场景中。为了实现这个目标,人们希望机器学习框架可以对任意神经网络自动化地计算出梯度。
+ 为了训练神经网络,我们需要利用数据、标注(Label)和目标损失函数(Loss
+ Function)来计算梯度(Gradients)。因此,机器学习通系统需要有一个通用的方法来**自动化**计算梯度(这一过程被称之为自动微分)。
- **支持数据管理和处理:**
- 机器学习的核心是数据,这其中不仅包括训练、评估和测试数据集,还包括训练后产生的模型参数(Checkpoint),以及训练过程中产生的调试数据(Debugging
- Data)。为了方便这些数据快速导入机器学习框架,我们需要框架本身支持不同类型的数据,以及进行高效的数据处理(如:数据增强和数据清洗)。
+ 机器学习的核心是数据。这些数据包括训练、评估、测试数据集和模型参数。因此,我们需要系统本身支持数据读取、存储和预处理(例如,数据增强和数据清洗)。
- **支持模型的训练和部署:**
- 为了让机器学习模型达到最佳的性能,人们需要使用各种优化方法(例如Mini-Batch
- SGD和其变种)来迭代计算梯度,最终模型的性能达到令开发者满意的状态(该过程称为训练)。同时,根据应用的要求,训练好的模型也需要部署到各种计算设备中,以提供模型推理服务(Inference)。
+ 为了让机器学习模型达到最佳的性能,人们需要使用优化方法(例如,Mini-Batch
+ SGD)来通过多步迭代反复计算梯度(这一过程称之为训练)。训练完成后,系统需要将训练好的模型部署推理设备。
-- **高效使用计算加速器:**
- 神经网络的相关计算可以被表达成矩阵计算,而这一类计算可以被计算加速器(如GPU)极大地加速。因此,机器学习框架需要具备高效利用加速器的能力。
+- **高效使用硬件加速器:**
+ 神经网络的相关计算往往通过矩阵计算实现。这一类计算可以被硬件加速器(例如,通用图形处理器-GPU)加速。因此,机器学习系统需要高效利用多种硬件加速器。
- **分布式计算:**
- 随着数据量的增大和应用的复杂度上升,人们正设计出与之相对应的大型深度神经网络。这一类神经网络往往需要大量的内存来存储参数。同时它们也需要大量的加速器从而实现计算的加速。因此,机器学习框架需要具备分布式执行的能力。
+ 随着训练数据量和神经网络参数量的上升,机器学习系统的内存用量远远超过了单个机器可以提供的内存。因此,机器学习框架需要天然具备分布式执行的能力。
-在设计机器学习系统之初,开发者曾尝试通过传统的**神经网络开发库**(如Theano和Caffe)、以及**大数据计算框架**(如Apache
+在设计机器学习系统之初,开发者曾尝试拓展**神经网络开发库**(如Theano和Caffe)和**大数据计算框架**(如Apache
Spark和Google
-Pregel)等方式来达到以上设计目标。可是他们发现(如 :numref:`comparison_of_ml_frameworks`所示),
-神经网络库虽然提供了神经网络开发、自动微分和加速器的支持,但是其缺乏管理和处理大型数据集、模型部署和分布式执行的能力,使得其无法满足产品级机器学习应用的开发。
-此外,虽然大数据计算框架具有成熟的分布式执行和数据管理能力,但是其缺乏对神经网络、自动微分和加速器的支持,使得其并不适合开发以神经网络为核心的机器学习应用。因此,业界从头设计出了包括MindSpore、PaddlePaddle、TensorFlow,PyTorch等一系列机器学习框架。
+Pregel)来达到以上目标。可是他们发现(如 :numref:`comparison_of_ml_frameworks`所示),
+神经网络库虽然提供了神经网络开发、自动微分和硬件加速器的支持,但是其缺乏管理和处理大型数据集、模型部署和分布式执行的能力,无法满足产品级机器学习应用的开发任务。
+另一方面,虽然大数据计算框架具有成熟的分布式执行和数据管理能力,但是其缺乏对神经网络、自动微分和加速器的支持,使得其并不适合开发以神经网络为核心的机器学习应用。因此,业界设计出了包括MindSpore、PaddlePaddle、TensorFlow,PyTorch等一系列新型机器学习系统(框架)。
:机器学习框架和相关系统的比较
diff --git a/chapter_model_deployment/model_compression.md b/chapter_model_deployment/model_compression.md
index 95a5a38..978cb0c 100644
--- a/chapter_model_deployment/model_compression.md
+++ b/chapter_model_deployment/model_compression.md
@@ -41,7 +41,7 @@ $round(\cdot)$和$clip(\cdot)$分别表示取整和截断操作,$q_{min}$和$q
#### 训练后量化
-训练后量化也可以分成两种,权重量化和全量化。权重量化仅量化模型的权重以压缩模型的大小,在推理时将权重反量化为原始的FP32数据,后续推理流程与普通的FP32模型一致。权重量化的好处是不需要校准数据集,不需要实现量化算子,且模型的精度误差较小,由于实际推理使用的仍然是FP32算子,所以推理性能不会提高。全量化不仅会量化模型的权重,还会量化模型的激活值,在模型推理时执行量化算子来加快模型的推理速度、为了量化激活值,需要用户提供一定数量的校准数据集用于统计每一层激活值的分布,并对量化后的算子做校准。校准数据集可以来自训练数据集或者真实场景的输入数据,需要数量通常非常小。在做训练后量化时会以校准数据集为输入,执行推理流程然后统计每层激活值的数据分布并得到相应的量化参数,具体的操作流程如下:
+训练后量化也可以分成两种,权重量化和全量化。权重量化仅量化模型的权重以压缩模型的大小,在推理时将权重反量化为原始的FP32数据,后续推理流程与普通的FP32模型一致。权重量化的好处是不需要校准数据集,不需要实现量化算子,且模型的精度误差较小,由于实际推理使用的仍然是FP32算子,所以推理性能不会提高。全量化不仅会量化模型的权重,还会量化模型的激活值,在模型推理时执行量化算子来加快模型的推理速度。为了量化激活值,需要用户提供一定数量的校准数据集用于统计每一层激活值的分布,并对量化后的算子做校准。校准数据集可以来自训练数据集或者真实场景的输入数据,需要数量通常非常小。在做训练后量化时会以校准数据集为输入,执行推理流程然后统计每层激活值的数据分布并得到相应的量化参数,具体的操作流程如下:
- 使用直方图统计的方式得到原始FP32数据的统计分布$P_f$;
@@ -90,13 +90,13 @@ $$\zeta_c=\frac{||w_c-E(w_c)||}{||\hat{w_c}-E(\hat{w_c})||}$$
#### 稀疏策略
-明确了模型稀疏的对象之后,我们需要确定模型稀疏的具体策略,具体来说我们需要决定何时对模型进行稀疏以及如何对模型进行稀疏。目前最常见模型稀疏的一般流程为:预训练、剪枝、微调。具体而言,我们首先需要训练得到一个收敛的稠密模型,然后在此基础上进行稀疏和微调。选择在预训练之后进行稀疏动作的原因基于这样一个共识,即预训练模型的参数蕴含了学习到的知识,继承这些知识然后进行稀疏得到的模型效果要比从头开始训练好。除了基于预训练模型进行进行一步修剪之外,训练和剪枝交替进行也是一种常用的策略。相比于一步修剪的方法,这种逐步的修剪方式,使得训练和剪枝紧密结合,可以更有效地发现冗余的卷积核,被广泛采用于现代神经网络剪枝方法中。
+明确了模型稀疏的对象之后,我们需要确定模型稀疏的具体策略,具体来说我们需要决定何时对模型进行稀疏以及如何对模型进行稀疏。目前最常见模型稀疏的一般流程为:预训练、剪枝、微调。具体而言,我们首先需要训练得到一个收敛的稠密模型,然后在此基础上进行稀疏和微调。选择在预训练之后进行稀疏动作的原因基于这样一个共识,即预训练模型的参数蕴含了学习到的知识,继承这些知识然后进行稀疏得到的模型效果要比从头开始训练好。除了基于预训练模型进行进一步修剪之外,训练和剪枝交替进行也是一种常用的策略。相比于一步修剪的方法,这种逐步的修剪方式,使得训练和剪枝紧密结合,可以更有效地发现冗余的卷积核,被广泛采用于现代神经网络剪枝方法中。
以下通过一个具体实例(Deep Compression([@han2015deep]))
来说明如何进行网络修剪:如 :numref:`ch08-fig-deepcomp`所示,在去掉大部分的权值之后,深度卷积神经网络的精度将会低于其原始的精度。对剪枝后稀疏的神经网络进行微调,可以进一步提升压缩后网络的精度。剪枝后的模型可以进一步进行量化,使用更低比特的数据来表示权值;此外,结合霍夫曼(Huffman)编码可以进一步地降低深度神经网络的存储。
![Deep Compression([@han2015deep])](../img/ch08/deepcomp.png)
-:width:`700px`
+:width:`800px`
:label:`ch08-fig-deepcomp`
除了直接去除冗余的神经元之外,基于字典学习的方法也可以用来去掉深度卷积神经网络中无用的权值([@bagherinezhad2017lcnn])。通过学习一系列卷积核的基,可以把原始卷积核变换到系数域上并且它们稀疏。比如,Bagherinezhad等人([@bagherinezhad2017lcnn])将原始卷积核分解成卷积核的基和稀疏系数的加权线性组合。
@@ -113,10 +113,10 @@ $$\mathcal{L}_{KD}(\theta_S) = \mathcal{H}(o_S,\mathbf{y}) +\lambda\mathcal{H}(\
其中,$\mathcal{H}(\cdot,\cdot)$是交叉熵函数,$o_S$和$o_T$分别是学生网络和教师网络的输出,$\mathbf{y}$是标签。公式 :eqref:`ch08-equ-c2Fcn_distill`中的第一项使得学生神经网络的分类结果接近预期的真实标签,而第二项的目的是提取教师神经网络中的有用信息并传递给学生神经网络,$\lambda$是一个权值参数用来平衡两个目标函数。$\tau(\cdot)$是一个软化(soften)函数,将网络输出变得更加平滑。
-公式 :eqref:`ch08-equ-c2Fcn_distill`仅仅从教师神经网络分类器输出的数据中提取有价值的信息,并没有从其它中间层去将教师神经网络的信息进行挖掘。因此,Romero等人[@FitNet])进一步地开发了一种学习轻型学生神经网络的方法,该算法可以从教师神经网络中任意的一层来传递有用的信息给学生神经网络。此外,事实上,并不是所有的输入数据对卷积神经网络的计算和完成后续的任务都是有用的。例如,在一张包含一个动物的图像中,对分类和识别结果比较重要的是动物所在的区域,而不是那些无用的背景信息。所以,有选择性地从教师神经网络的特征图中提取信息是一个更高效的方式。于是,Zagoruyko和Komodakis([@attentionTS])提出了一种基于感知(attention)损失函数的学习方法来提升学生神经网络的性能,如 :numref:`ch08-fig-AttentionTS`所示。该算法在学习学生神经网络的过程中,引入了Attention模块,选择性地将教师神经网络中的信息传递给学生神经网络,并帮助其进行训练。
+公式 :eqref:`ch08-equ-c2Fcn_distill`仅仅从教师神经网络分类器输出的数据中提取有价值的信息,并没有从其它中间层去将教师神经网络的信息进行挖掘。因此,Romero等人[@FitNet])进一步地开发了一种学习轻型学生神经网络的方法,该算法可以从教师神经网络中任意的一层来传递有用的信息给学生神经网络。此外,事实上,并不是所有的输入数据对卷积神经网络的计算和完成后续的任务都是有用的。例如,在一张包含一个动物的图像中,对分类和识别结果比较重要的是动物所在的区域,而不是那些无用的背景信息。所以,有选择性地从教师神经网络的特征图中提取信息是一个更高效的方式。于是,Zagoruyko和Komodakis([@attentionTS])提出了一种基于感知(attention)损失函数的学习方法来提升学生神经网络的性能,公式 :eqref:`ch08-equ-c2Fcn_distill`仅仅从教师神经网络分类器输出的数据中提取有价值的信息,并没有从其它中间层去将教师神经网络的信息进行挖掘。因此,Romero等人[@FitNet])进一步地开发了一种学习轻型学生神经网络的方法,该算法可以从教师神经网络中任意的一层来传递有用的信息给学生神经网络。此外,事实上,并不是所有的输入数据对卷积神经网络的计算和完成后续的任务都是有用的。例如,在一张包含一个动物的图像中,对分类和识别结果比较重要的是动物所在的区域,而不是那些无用的背景信息。所以,有选择性地从教师神经网络的特征图中提取信息是一个更高效的方式。于是,Zagoruyko和Komodakis([@attentionTS])提出了一种基于感知(attention)损失函数的学习方法来提升学生神经网络的性能,如 :numref:`ch08-fig-distillation`所示。该算法在学习学生神经网络的过程中,引入了感知模块Attention,选择性地将教师神经网络中的信息传递给学生神经网络,并帮助其进行训练。感知图可以识别输入图像不同位置对最终分类结果的重要性,并从教师网络传递到学生网络。
-![文献([@attentionTS])所提出的教师神经网络-学生神经网络学习算法,该算法在学习学生神经网络的过程中,引入了感知模块(Attention),选择性地将教师神经网络中的信息传递给学生神经网络,并帮助其进行训练。感知图可以识别输入图像不同位置对最终分类结果的重要性,并从教师网络传递到学生网络。](../img/ch08/AttentionTS.png)
-:width:`800px`
-:label:`ch08-fig-AttentionTS`
+
+:width:`500px`
+:label:`ch08-fig-distillation`
知识蒸馏是一种有效的帮助小网络优化的方法,能够进一步和剪枝、量化等其他压缩方法结合,训练得到精度高、计算量小的高效模型。
diff --git a/chapter_model_deployment/model_converter_and_optimizer.md b/chapter_model_deployment/model_converter_and_optimizer.md
index 6de5027..cd92372 100644
--- a/chapter_model_deployment/model_converter_and_optimizer.md
+++ b/chapter_model_deployment/model_converter_and_optimizer.md
@@ -4,7 +4,7 @@
前面我们提到过,不同的训练框架(Tensorflow、PyTorch、MindSpore、MXNet、CNTK等)都定义了自己的模型的数据结构,推理系统需要将它们转换到统一的一种数据结构上。Open Neural Network Exchange(ONNX)正是为此目的而设计的。ONNX支持广泛的机器学习运算符集合,并提供了不同训练框架的转换器,例如TensorFlow模型到ONNX模型的转换器、PyTorch模型到ONNX模型的转换器等。
模型转换本质上是将模型这种结构化的数据,从一种数据结构转换为另一种数据结构的过程。进行模型转换首先要分析两种数据结构的异同点,然后针对结构相同的数据做搬运;对于结构相似的数据做一一映射;对于结构差异较大的数据则需要根据其语义做合理的数据转换;更进一步如果两种数据结构上存在不兼容,则模型转换无法进行。ONNX的一个优势就在于其强大的表达能力,从而大多数业界框架的模型都能够转换到ONNX的模型上来而不存在不兼容的情况.
-模型可以抽象为是一种图,从而模型的数据结构可以解构为以下两个要点:
+模型可以抽象为一种图,从而模型的数据结构可以解构为以下两个要点:
- 模型拓扑表达:从图的角度来说,就是图的边;从模型的角度来说,就是模型中的数据流和控制流等,模型数据流和控制流的定义又可以引申出子图的表达形式、模型输入输出的表达形式、控制流结构的表达形式等。比如Tensorflow1.x中的控制流表达为一种有环图,通过Enter、Exit、Switch、LoopCond、NextIteration等算子来解决成环,而ONNX通过Loop,If等算子来表达控制流,从而避免引入了有环,所以在将Tensorflow1.x的控制流模型转化为ONNX模型时,需要将Tensorflow模型中的控制流图结构融合成ONNX的While或者If算子。
@@ -35,7 +35,7 @@ $$\pmb{Y_{conv}}=\pmb{W_{conv}}*\pmb{X_{conv}}+\pmb{B_{conv}}$$
这里我们不需要理解公式 :eqref:`ch08-equ-conv_equation`中每个变量的含义,只需要注意到一点,该公式是$\pmb{Y_{conv}}$关于$\pmb{X_{conv}}$的,其他符号均表示常量。
-Batchnorm算子的计算过程如公式 :eqref:`equ:bn-equation`所示。
+Batchnorm算子的计算过程如公式 :eqref:`ch08-equ-bn_equation`所示。
$$\pmb{Y_{bn}}=\gamma\frac{\pmb{X_{bn}}-\mu_{\mathcal{B}}}{\sqrt{{\sigma_{\mathcal{B}}}^{2}+\epsilon}}+\beta$$
:eqlabel:`ch08-equ-bn_equation`
@@ -71,7 +71,7 @@ $$\pmb{Y_{bn}}=\pmb{A}*\pmb{X_{conv}}+\pmb{B}$$
:width:`500px`
:label:`ch08-fig-bn_replace`
-如 :numref:`ch08-fig-bn_replace`,我们以Batchnorm算子替换成Scale算子为例,阐述算子替换的原理。我们直接将Batchnorm的计算公式 :eqref:`ch08-equ-replace_scale`进行分解,并将常量合并简化,Batchnorm的计算公式可以写成:
+如 :numref:`ch08-fig-bn_replace`,我们以Batchnorm算子替换成Scale算子为例,阐述算子替换的原理。我们直接将Batchnorm的计算公式 :eqref:`ch08-equ-bn_equation`进行分解,并将常量合并简化,Batchnorm的计算公式可以写成:
$$\pmb{Y_{bn}}=scale*\pmb{X_{bn}}+offset$$
:eqlabel:`ch08-equ-replace_scale`
@@ -88,6 +88,6 @@ $$\pmb{Y_{bn}}=scale*\pmb{X_{bn}}+offset$$
:width:`500px`
:label:`ch08-fig-crop_reorder`
-如 :numref:`ch08-fig-crop_reorder`,Crop算子是从输入的feature map中裁取一部分作为输出,经过Crop算子后,feature map的size就降低了。如果我们将这个裁切的过程前移,提前对feature map进行裁切,那么后续算子的计算量也会相应地减少,从而提高模型部署时的推理性能。Crop算子前移带来的性能提升跟Crop算子的参数有关。但是Crop算子一般只能沿着的element wise类算子前移。
+如 :numref:`ch08-fig-crop_reorder`,Crop算子是从输入的feature map中裁取一部分作为输出,经过Crop算子后,feature map的size就降低了。如果我们将这个裁切的过程前移,提前对feature map进行裁切,那么后续算子的计算量也会相应地减少,从而提高模型部署时的推理性能。Crop算子前移带来的性能提升跟Crop算子的参数有关。但是Crop算子一般只能沿着element wise类算子前移。
通过前面的实验数据我们可以看到,通过推理前的模型优化,可以为推理的时延、功耗、内存占用带来极大的收益。
diff --git a/chapter_model_deployment/model_inference.md b/chapter_model_deployment/model_inference.md
index 0690d2d..0692879 100644
--- a/chapter_model_deployment/model_inference.md
+++ b/chapter_model_deployment/model_inference.md
@@ -20,8 +20,6 @@
- 处理离群值: 离群值是与数据中的其他值保持一定距离的数据点,适当地排除离群值可以提升模型的准确性。
-针对特定的原始数据,往往存在特定的数据处理手段。在前述8.2"机器学习数据基本类型及常见数据变换方式"章节中,分别详细介绍了图像、音频、文本等数据的预处理方法。
-
#### 后处理
通常,模型推理结束后,需要把推理的输出数据传递给用户完成后处理,常见的数据后处理手段有:
@@ -125,48 +123,36 @@ ARMv8系列的CPU上有32个NEON寄存器v0-v31,如 :numref:`ch08-fig-register
卷积计算归根到底是矩阵乘法,两个二维矩阵相乘的时间复杂度是$O(n^3)$。我们可以使用Winograd来降低矩阵乘法的复杂度。
-以一维卷积运算为例,记为F(m,r),其中,m代表输出的个数,r为卷积核的个数。输入为$d=[d_0 \ d_0 \ d_2 \ d_3]$,卷积核为$g=[g_0 \ g_0 \ g_2]^T$,该卷积计算可以写成矩阵形式如公式 :eqref:`ch08-equ-conv_matmul_one_dimension`所示,需要6次乘法和4次加法。
+以一维卷积运算为例,记为F(m,r),其中,m代表输出的个数,r为卷积核的个数。输入为$d=[d_0 \ d_1 \ d_2 \ d_3]$,卷积核为$g=[g_0 \ g_1 \ g_2]^T$,该卷积计算可以写成矩阵形式如公式 :eqref:`ch08-equ-conv_matmul_one_dimension`所示,需要6次乘法和4次加法。
-$$F(2, 3)=
-\left[ \begin{matrix} d_0 & d_0 & d_2 \\ d_1 & d_2 & d_3 \end{matrix} \right] \left[ \begin{matrix} g_0 \\ g_1 \\ g_2 \end{matrix} \right]=
-\left[ \begin{matrix} y_0 \\ y_1 \end{matrix} \right]$$
+$$F(2, 3)=\left[ \begin{matrix} d_0 & d_1 & d_2 \\ d_1 & d_2 & d_3 \end{matrix} \right] \left[ \begin{matrix} g_0 \\ g_1 \\ g_2 \end{matrix} \right]=\left[ \begin{matrix} y_0 \\ y_1 \end{matrix} \right]$$
:eqlabel:`ch08-equ-conv_matmul_one_dimension`
可以观察到,卷积运算转换为矩阵乘法时输入矩阵中存在着重复元素$d_1$和$d_2$,因此,卷积转换的矩阵乘法相对一般的矩阵乘有了优化空间。可以通过计算中间变量$m_0-m_3$得到矩阵乘的结果,见公式 :eqref:`ch08-equ-conv-2-winograd`:
-$$F(2, 3)=
-\left[ \begin{matrix} d_0 & d_0 & d_2 \\ d_1 & d_2 & d_3 \end{matrix} \right] \left[ \begin{matrix} g_0 \\ g_1 \\ g_2 \end{matrix} \right]=
-\left[ \begin{matrix} m_0+m_1+m_2 \\ m_1-m_2+m_3 \end{matrix} \right]$$
+$$F(2, 3)=\left[ \begin{matrix} d_0 & d_1 & d_2 \\ d_1 & d_2 & d_3 \end{matrix} \right] \left[ \begin{matrix} g_0 \\ g_1 \\ g_2 \end{matrix} \right]=\left[ \begin{matrix} m_0+m_1+m_2 \\ m_1-m_2+m_3 \end{matrix} \right]$$
:eqlabel:`ch08-equ-conv-2-winograd`
其中,$m_0-m_3$的分别见公式 :eqref:`ch08-equ-winograd-param`:
-$$\begin{aligned}
-m_0=(d_0-d_2)*g_0 \\
-m_1=(d_1+d_2)*(\frac{g_0+g_1+g_2}{2}) \\
-m_2=(d_0-d_2)*(\frac{g_0-g_1+g_2}{2}) \\
-m_2=(d_1-d_3)*g_2
-\end{aligned}$$
+$$\begin{aligned}m_0=(d_0-d_2)*g_0 \\m_1=(d_1+d_2)*(\frac{g_0+g_1+g_2}{2}) \\m_2=(d_0-d_2)*(\frac{g_0-g_1+g_2}{2}) \\m_2=(d_1-d_3)*g_2\end{aligned}$$
:eqlabel:`ch08-equ-winograd-param`
-
通过$m_0-m_3$间接计算r1,r2,需要的运算次数包括:输入d的4次加法;输出m的4次乘法和4次加法。在推理阶段,权重的数值是常量,因此卷积核上的运算可以在图编译阶段计算,不计入在线的run时间。所以总的运算次数为4次乘法和8次加法,与直接运算的6次乘法和4次加法相比,乘法次数减少,加法次数增加。在计算机中,乘法一般比加法慢,通过减少乘法次数,增加少量加法,可以实现加速。
计算过程写成矩阵形式如公式 :eqref:`ch08-equ-winograd-matrix`所示,其中,⊙为对应位置相乘,A、B、G都是常量矩阵。这里写成矩阵计算是为了表达清晰,实际使用时,按照公式 :eqref:`ch08-equ-winograd-param`手写展开的计算速度更快。
-$$\mathbf{Y}=\mathbf{A^T}(\mathbf{G}g)*(\mathbf{B^T}d)$$
-:label:`ch08-equ-winograd-matrix`
-$$\mathbf{B^T}=
-\left[ \begin{matrix} 1 & 0 & -1 & 0 \\ 0 & 1 & 1 & 0 \\ 0 & -1 & 1 & 0 \\ 0 & 1 & 0 & -1 \end{matrix} \right]$$
+$$\mathbf{Y}=\mathbf{A^T}(\mathbf{G}g)*(\mathbf{B^T}d)$$
+:eqlabel:`ch08-equ-winograd-matrix`
+
+$$\mathbf{B^T}=\left[ \begin{matrix} 1 & 0 & -1 & 0 \\ 0 & 1 & 1 & 0 \\ 0 & -1 & 1 & 0 \\ 0 & 1 & 0 & -1 \end{matrix} \right]$$
:eqlabel:`ch08-equ-winograd-matrix-bt`
-$$\mathbf{G}=
-\left[ \begin{matrix} 1 & 0 & 0 \\ 0.5 & 0.5 & 0.5 \\ 0.5 & -0.5 & 0.5 \\ 0 & 0 & 1 \end{matrix} \right]$$
+$$\mathbf{G}=\left[ \begin{matrix} 1 & 0 & 0 \\ 0.5 & 0.5 & 0.5 \\ 0.5 & -0.5 & 0.5 \\ 0 & 0 & 1 \end{matrix} \right]$$
:eqlabel:`ch08-equ-winograd-matrix-g`
-$$\mathbf{A^T}=
-\left[ \begin{matrix} 1 & 1 & -1 & 0 \\ 0 & 1 & -1 & -1 \end{matrix} \right] \\$$
+$$\mathbf{A^T}=\left[ \begin{matrix} 1 & 1 & -1 & 0 \\ 0 & 1 & -1 & -1 \end{matrix} \right] \\$$
:eqlabel:`ch08-equ-winograd-matrix-at`
diff --git a/chapter_model_deployment/summary.md b/chapter_model_deployment/summary.md
index f28210a..3151166 100644
--- a/chapter_model_deployment/summary.md
+++ b/chapter_model_deployment/summary.md
@@ -11,3 +11,11 @@
- 针对模型的推理功耗,主要的优化思路是降低模型的计算量,这与针对模型推理时延的优化手段有重合之处,可以参考离线的模型优化技术 :numref:`ch08-sec-fusion`和模型压缩技术 :numref:`ch08-sec-model_compression`。
- 本章除了介绍优化模型部署的各方面指标的优化技术以外,还介绍了安全部署相关的技术,如模型混淆、模型加密等。部署安全一方面可以保护企业的重要资产,另一方面可以防止黑客通过篡改模型从而入侵攻击部署环境。
+
+## 扩展阅读
+
+- Google量化白皮书 [量化](https://arxiv.org/abs/1806.08342)
+
+- 诺亚高精度剪枝算法 [剪枝](https://arxiv.org/abs/2010.10732)
+
+- 针对多核处理器的自动图并行调度框架 [性能优化](https://proceedings.mlsys.org/paper/2021/file/a5e00132373a7031000fd987a3c9f87b-Paper.pdf)
diff --git a/chapter_preface_advanced/index.md b/chapter_preface_advanced/index.md
index 67f9135..bd0598f 100644
--- a/chapter_preface_advanced/index.md
+++ b/chapter_preface_advanced/index.md
@@ -12,7 +12,7 @@
上述四个方面的不同需求,在设计AI框架系统的时候,需要基于场景充分的予以考虑,另外还需要考虑:
-通用性:也可以称为泛化性,是不是所有的模型算法同一套代码,没有针对某个网络的特殊定制代码? 是不是所有硬件同一套机制,在机器学习系统中针对特定硬件版本的定制只存在于硬件相关层?上面提到的不同环境下部署要求千差万别,是同一套方案还是几套方案来支持呢。
+通用性:也可以称为泛化性,是不是所有的模型算法同一套代码,没有针对某个网络的特殊定制代码? 是不是所有硬件同一套机制,在机器学习系统中针对特定硬件版本的定制只存在于硬件相关层?上面提到的不同环境下部署要求千差万别,是同一套方案还是几套方案来支持呢?
易用性:对新用户而言,易用性关注更多的是入门的门槛,能不能一键式的安装、升级和运行常见的模型;对深度用户,如:算法研究人员而言,是不是能够轻松的表达算法、调试算法和部署算法模型是易用性的重点。另外,生态兼容性是易用性的一个重要考量,方便的使用常用的工具、第三方库兼容和对接,支持更多的硬件进行训练和部署是重要的因素。
diff --git a/chapter_programming_interface/c_python_interaction.md b/chapter_programming_interface/c_python_interaction.md
index a1156fe..946cdf4 100644
--- a/chapter_programming_interface/c_python_interaction.md
+++ b/chapter_programming_interface/c_python_interaction.md
@@ -40,7 +40,8 @@ Binding)。在Pybind11出现以前,将C和C++函数进行Python绑定的手
- 算子属性:构造函数\_\_init\_\_中初始化属性,因加法没有属性,因此\_\_init\_\_不需要额外输入。
- 算子输入输出及合法性校验:infer_shape方法中约束两个输入维度必须相同,输出的维度和输入维度相同。infer_dtype方法中约束两个输入数据必须是float32类型,输出的数据类型和输入数据类型相同。
- 算子输出
+
+- 算子输出
MindSpore中实现注册TensorAdd代码如下:
```python
diff --git a/chapter_programming_interface/index.md b/chapter_programming_interface/index.md
index e899f3d..f0d79d1 100644
--- a/chapter_programming_interface/index.md
+++ b/chapter_programming_interface/index.md
@@ -2,7 +2,7 @@
现代机器学习框架包含大量的组件。这些组件使得用户得以高效开发机器学习算法,处理数据,部署模型,性能调优和使用硬件加速器。在设计这些组件的编程接口时,一个核心的诉求是:如何平衡框架性能和易用性?为了达到最优的性能,开发者需要利用硬件亲和的编程语言如:C和C++来进行开发。这是因为:C和C++的使用使得机器学习框架可以高效调用硬件的底层API,从而最大限度发挥硬件性能。同时,现代操作系统(如Linux和Windows)提供丰富的基于C和C++的编程接口(如文件系统,网络编程,多线程管理等),通过直接调用操作系统API,可以降低框架运行的开销。
-从易用性的角度分析,机器学习框架的使用者往往具有丰富的行业背景(如数据科学家,生物学家,化学家,物理学家等)。他们的常用的编程语言是高层次脚本语言:Python,Matlab,R和Julia。相比于C和C++,这些语言在提供编程的易用性的同时,丧失了C和C++对底层硬件和操作系统进行深度优化的能力。因此,机器学习框架的核心设计目标是:其要具有易用编程接口来支持用户用高层次语言如Python来实现机器学习算法,同时其也要具备以C和C++为核心的低层次编程接口,使得框架开发者可以用C和C++实现大量高性能组件,从而在硬件上高效执行。在本章中,我们将会讲述如何达到这个设计目标。
+从易用性的角度分析,机器学习框架的使用者往往具有丰富的行业背景(如数据科学家,生物学家,化学家,物理学家等)。他们常用的编程语言是高层次脚本语言:Python,Matlab,R和Julia。相比于C和C++,这些语言在提供编程的易用性的同时,丧失了C和C++对底层硬件和操作系统进行深度优化的能力。因此,机器学习框架的核心设计目标是:其要具有易用编程接口来支持用户用高层次语言如Python来实现机器学习算法,同时其也要具备以C和C++为核心的低层次编程接口,使得框架开发者可以用C和C++实现大量高性能组件,从而在硬件上高效执行。在本章中,我们将会讲述如何达到这个设计目标。
本章的学习目标包括:
diff --git a/chapter_programming_interface/ml_workflow.md b/chapter_programming_interface/ml_workflow.md
index f87ea1d..5e3aa97 100644
--- a/chapter_programming_interface/ml_workflow.md
+++ b/chapter_programming_interface/ml_workflow.md
@@ -3,7 +3,7 @@
机器学习系统编程模型的首要设计目标是:对开发者的整个工作流进行完整的编程支持。一个常见的机器学习任务一般包含如 :numref:`img_workflow`所示的流程。这个工作流完成了训练数据集的读取,模型的训练,测试和调试。通过归纳,我们可以将这一工作流中用户所需要自定义的部分通过定义以下API来支持(我们这里假设用户的高层次API以Python函数的形式提供):
- **数据处理:**
- 首先,用户需要数据处理API来支持将数据集从磁盘读入。进一步,用户需要对读取数据进行数据预处理,从而可以将数据输入后续的机器学习模型中。
+ 首先,用户需要数据处理API来支持将数据集从磁盘读入。进一步,用户需要对读取的数据进行预处理,从而可以将数据输入后续的机器学习模型中。
- **模型结构:**
完成数据的读取后,用户需要模型定义API来定义机器学习模型。这些模型带有模型参数,可以对给定的数据进行推理。
@@ -19,7 +19,7 @@
- **测试和调试:**
训练过程中,用户需要测试API来对当前模型的精度进行评估。当精度达到目标后,训练结束。这一过程中,用户往往需要调试API来完成对模型的性能和正确性进行验证。
-
+
:width:`800px`
:label:`img_workflow`
@@ -43,7 +43,7 @@ AI处理器上,则--device_target选择Ascend,代码运行在CPU、GPU同理
### 数据处理
配置好运行信息后,首先讨论数据处理API的设计。这些API提供了大量Python函数支持用户用一行命令即可读入常见的训练数据集(如MNIST,CIFAR,COCO等)。
-在加载之前需要下载数据集存放在./datasets/MNIST_Data路径中;MindSpore提供了用于数据处理的API模块
+在加载之前需要将下载的数据集存放在./datasets/MNIST_Data路径中;MindSpore提供了用于数据处理的API模块
mindspore.dataset,用于存储样本和标签。在加载数据集前,通常会对数据集进行一些处理,mindspore.dataset也集成了常见的数据处理方法。
以下代码读取了MNIST的数据是大小为$28 \times 28$的图片,返回DataSet对象。
@@ -125,7 +125,7 @@ net = MLPNet()
**SGD**的更新是对每个样本进行梯度下降,因此计算速度很快,但是单样本更新频繁,会造成震荡;为了解决震荡问题,提出了带有Momentum的SGD,该方法的参数更新不仅仅由梯度决定,也和累计的梯度下降方向有关,使得增加更新梯度下降方向不变的维度,减少更新梯度下降方向改变的维度,从而速度更快也减少震荡。
-自适应学习率**AdaGrad**是通过以往的梯度自适应更新学习率不同的参数$W_i$具有不同的学习率。AdaGrad对频繁变化的参数以更小的步长更新,而稀疏的参数以更大的步长更新。因此对稀疏的数据表现比较好。**Adadelta**是对AdaGrad的改进,解决了AdaGrad优化过程中学习率$\alpha$单调减少问题;Adadelta不对过去的梯度平方进行累加,用指数平均的方法计算二阶动量,避免了二阶动量持续累积,导致训练提前结束。**Adam**可以理解为Adadelta和Momentum的结合,对一阶二阶动量均采用指数平均的方法计算。
+自适应学习率**AdaGrad**是通过以往的梯度自适应更新学习率,不同的参数$W_i$具有不同的学习率。AdaGrad对频繁变化的参数以更小的步长更新,而稀疏的参数以更大的步长更新。因此对稀疏的数据表现比较好。**Adadelta**是对AdaGrad的改进,解决了AdaGrad优化过程中学习率$\alpha$单调减少问题;Adadelta不对过去的梯度平方进行累加,用指数平均的方法计算二阶动量,避免了二阶动量持续累积,导致训练提前结束。**Adam**可以理解为Adadelta和Momentum的结合,对一阶二阶动量均采用指数平均的方法计算。
MindSpore提供了丰富的API来让用户导入损失函数和优化器。在下面的例子中,计算了输入和真实值之间的softmax交叉熵损失,导入Momentum优化器。
```python
diff --git a/chapter_programming_interface/neural_network_layer.md b/chapter_programming_interface/neural_network_layer.md
index 812623a..cc5fb69 100644
--- a/chapter_programming_interface/neural_network_layer.md
+++ b/chapter_programming_interface/neural_network_layer.md
@@ -89,7 +89,7 @@ output = fully_connected(output, fc3_weights)
随着深度神经网络应用领域的扩大,诞生出了丰富的模型构建组件。在卷积神经网络的计算过程中,前后的输入是没有联系的,然而在很多任务中往往需要处理序列信息,如语句、语音、视频等,为了解决此类问题诞生出循环神经网络(Recurrent Neural Network,RNN);
循环神经网络很好的解决了序列数据的问题,但是随着序列的增加,长序列又导致了训练过程中梯度消失和梯度爆炸的问题,因此有了长短期记忆(Long Short-term Memory,LSTM);
在语言任务中还有Seq2Seq它将RNN当成编解码(Encoder-Decoder)结构的编码器(Encoder)和解码器(Decode);
-在解码器中又常常使用注意力机制(Attention);基于编解码器和注意力机制又有Transformer;
+在解码器中又常常使用注意力机制(Attention);基于编解码器和注意力机制又有Transformer;
Transformer又是BERT模型架构的重要组成。随着深度神经网络的发展,未来也会诞生各类模型架构,架构的创新可以通过各类神经网络基本组件的组合来实现。
### 神经网络层的实现原理
@@ -119,7 +119,7 @@ Cell和Module是模型抽象方法也是所有网络的基类。
:width:`800px`
:label:`cell_abs`
-神经网络接口层基类实现,仅做了简化的描述,在实际实现时,执行计算的\_\_call\_\_方法并不会让用户直接重载,它往往在\_\_call\_\_之外定义一个执行操作的方法(对于神经网络模型该方法是实现网络结构的连接,对于神经网络层则是实现计算过程)后然后在\_\_call\_\_调用;如MindSpore的Cell因为动态图和静态图的执行是不一样的,因此在\_\_call\_\_里定义动态图和计算图的计算执行,在construct方法里定义层或者模型的操作过程。
+神经网络接口层基类实现,仅做了简化的描述,在实际实现时,执行计算的\_\_call\_\_方法并不会让用户直接重载,它往往在\_\_call\_\_之外定义一个执行操作的方法(对于神经网络模型该方法是实现网络结构的连接,对于神经网络层则是实现计算过程)后再\_\_call\_\_调用;如MindSpore的Cell因为动态图和静态图的执行是不一样的,因此在\_\_call\_\_里定义动态图和计算图的计算执行,在construct方法里定义层或者模型的操作过程。
### 自定义神经网络层
@@ -146,7 +146,8 @@ class Conv2D(Cell):
```
有了上述定义在使用卷积层时,就不需要创建训练变量了。
-如我们需要对$30 \times 30$大小10个通道的输入使用$3 \times 3$的卷积核做卷积,卷积后输出通道为20调用方式如下:
+如我们需要对$30 \times 30$大小10个通道的输入使用$3 \times 3$的卷积核做卷积,卷积后输出通道为20。
+调用方式如下:
```python
conv = Conv2D(in_channel=10, out_channel=20, filter_size=3, stride=2, padding=0)
output = conv(input)
diff --git a/chapter_programming_interface/summary.md b/chapter_programming_interface/summary.md
index a386a63..6a86d6f 100644
--- a/chapter_programming_interface/summary.md
+++ b/chapter_programming_interface/summary.md
@@ -19,3 +19,8 @@
- Python和C之间的互操作性一般通过CType等技术实现。
- 机器学习框架一般具有多种C和C++接口允许用户定义和注册C++实现的算子。这些算子使得用户可以开发高性能模型,数据处理函数,优化器等一系列框架拓展。
+
+## 扩展阅读
+
+- MindSpore编程指南:[MindSpore](https://www.mindspore.cn/docs/programming_guide/zh-CN/r1.6/index.html)
+- Python和C/C++混合编程:[Pybind11](https://pybind11.readthedocs.io/en/latest/basics.html#creating-bindings-for-a-simple-function)
\ No newline at end of file
diff --git a/chapter_recommender_system/overview.md b/chapter_recommender_system/overview.md
index 625e0df..f995b32 100644
--- a/chapter_recommender_system/overview.md
+++ b/chapter_recommender_system/overview.md
@@ -5,12 +5,12 @@
### 推荐模型
基于深度学习的推荐模型在过去几年受到了学术界和工业界的高度关注,得到了快速发展。目前主流的推荐模型 :cite:`10.1145/2988450.2988454,10.1145/3124749.3124754,ijcai2017-239,naumov2019deep`的基本结构可以总结如图 :numref:`ch10-recommendation-models`。
-
+
:width:`800px`
:label:`ch10-recommendation-models`
-推荐模型以用户和内容的交互历史、用户属性、内容属性等特征作为输入,另输入特征进行充分相互作用,再将交互结果交由稠密深度神经网络来预测用户点击候选内容的可能性。为了加深读者的对推荐模型的理解,此处我们以Wide & Deep模型 :cite:`10.1145/2988450.2988454`作为例子,深入分析推荐模型的输入特征以及输入特征之间如何交互。由于推荐模型的设计不在本章的讨论范围内,所以下面的介绍中重点介绍模型的基本结构以方便理解推荐系统的设计。对Wide & Deep模型的设计理念、数据生成、数据预处理等细节感兴趣的读者可以自行阅读论文以进一步了解。
+推荐模型以用户和内容的交互历史、用户属性、内容属性等特征作为输入,令输入特征进行充分相互作用,再将交互结果交由稠密深度神经网络来预测用户点击候选内容的可能性。为了加深读者的对推荐模型的理解,此处我们以Wide & Deep模型 :cite:`10.1145/2988450.2988454`作为例子,深入分析推荐模型的输入特征以及输入特征之间如何交互。由于推荐模型的设计不在本章的讨论范围内,所以下面的介绍中重点介绍模型的基本结构以方便理解推荐系统的设计。对Wide & Deep模型的设计理念、数据生成、数据预处理等细节感兴趣的读者可以自行阅读论文以进一步了解。
Wide & Deep模型是一个设计简洁然而性能优异的模型,由谷歌(Google)在开发并应用于谷歌应用商店中,该模型在谷歌的实际生产环境中可以大幅提升应用的下载率。
@@ -25,7 +25,7 @@ Wide & Deep模型对输入数据进行两部分处理:Wide部分和Deep部分
在实际的生产环境中,除了推荐模型本身,推荐系统通常包括:数据收集、数据处理、数据存储、模型训练、模型存储、模型评估、推理服务等多个子系统。如图 :numref:`ch10-abstract-recommendation-systems`所示,这些子系统之间分工协作、紧密配合,构成一个从用户反馈、到模型更新、再到新推荐结果生成的闭环。下一小节中将以英伟达(NVIDIA)公司的Merlin开源框架 :cite:`Merlin`为例,概括介绍推荐系统流水线上的组件,并重点介绍模型训练、推理子系统的结构。
-
+
:width:`800px`
:label:`ch10-abstract-recommendation-systems`
diff --git a/chapter_recommender_system/summary.md b/chapter_recommender_system/summary.md
index aa525a7..6761fa4 100644
--- a/chapter_recommender_system/summary.md
+++ b/chapter_recommender_system/summary.md
@@ -1,3 +1,15 @@
## 小结
-推荐系统作为深度学习在工业界最成功的落地成果之一,极大地提升了用户的在线服务体验,并且为各大公司创造了可观的利润,然而也带来了许多系统层面的挑战亟待解决。本节简单介绍了典型的工业界推荐系统架构及其面临的挑战,并给出了潜在的解决方案的方向。在实际生产环境中,具体的系统设计方案根据不同推荐场景的需求而变化,不存在一种万能的解决方案。
+推荐系统作为深度学习在工业界最成功的落地成果之一,极大地提升了用户的在线服务体验,并且为各大公司创造了可观的利润,然而也带来了许多系统层面的挑战亟待解决。本节简单介绍了典型的工业界推荐系统架构及其面临的挑战,并给出了潜在的解决方案的方向。在实际生产环境中,具体的系统设计方案需要根据不同推荐场景的需求而变化,不存在一种万能的解决方案。
+
+## 扩展阅读
+
+- 推荐模型:[Wide & Deep](https://arxiv.org/abs/1606.07792)
+
+- 开源推荐系统框架:[Merlin](https://irsworkshop.github.io/2020/publications/paper_21_Oldridge_Merlin.pdf)
+
+- 软硬件协同设计加速超大规模深度学习推荐系统训练:[ZionEX](https://arxiv.org/abs/2104.05158v5)
+
+- 利用多级缓存支持超大规模深度学习推荐系统训练:[Distributed Hierarchical GPU Parameter Server for Massive Scale Deep Learning Ads Systems](https://arxiv.org/abs/2003.05622)
+
+- 工业界机器学习系统的实践:[Hidden Technical Debt in Machine Learning Systems](https://papers.nips.cc/paper/2015/hash/86df7dcfd896fcaf2674f757a2463eba-Abstract.html)
\ No newline at end of file
diff --git a/chapter_recommender_system/system_architecture.md b/chapter_recommender_system/system_architecture.md
index a9f1361..0f69acd 100644
--- a/chapter_recommender_system/system_architecture.md
+++ b/chapter_recommender_system/system_architecture.md
@@ -11,9 +11,9 @@ Merlin是英伟达公司开发的一个开源推荐系统框架,帮助使用
3. 推理服务:类似地,推理服务器在接到一批用户的推荐请求后,从参数服务器拉去相应的嵌入项和稠密神经网络参数来响应用户的请求。推荐系统的推理服务对延迟十分敏感,例如脸书公司的DLRM :cite:`naumov2019deep`基准在MLPerf评测中的服务器延迟限定在30ms[^1]。因此如何在限定延迟(latency-bounded)的情况下尽可能提升吞吐(throughput)是推理服务面临的关键问题。在GPU推理场景下,常见的优化手段有:请求动态合批处理、核融合、低精度部署等 :cite:`10.1145/3437801.3441578,wang-etal-2021-lightseq`. Triton提供了请求调度的功能并且支持多种不同的机器学习框架作为后端。
-在工业界,为了提升系统在发生故障的情况下的可用性,以上介绍的各个组件在实际中部署中都应该具备基本的容灾和故障恢复能力。以推理服务为例,在线服务中的深度学习推荐模型通常都采用多副本分布式部署。同一个模型的多个副本通常会被部署在至少两个不同的地理区域内的多个数据中心中,如图 :numref:`ch10-recommendation-systems`,以应对大面积停电或者网络中断而导致整个地区的所有副本都不可用。除了容错方面的考虑,部署多个副本还有其他几点优势。首先,将模型部署在靠近用户的云服务器上可以提升响应速度。其次,部署多份副本也可以拓展模型推理服务的吞吐率。
+在工业界,为了提升系统在发生故障的情况下的可用性,以上介绍的各个组件在实际中部署中都应该具备基本的容灾和故障恢复能力。以推理服务为例,在线服务中的深度学习推荐模型通常都采用多副本分布式部署。同一个模型的多个副本通常会被部署在至少两个不同的地理区域内的多个数据中心中,如 :numref:`ch10-recommendation-systems`,以应对大面积停电或者网络中断而导致整个地区的所有副本都不可用。除了容错方面的考虑,部署多个副本还有其他几点优势。首先,将模型部署在靠近用户的云服务器上可以提升响应速度。其次,部署多份副本也可以拓展模型推理服务的吞吐率。
-
+
:width:`800px`
:label:`ch10-recommendation-systems`
diff --git a/chapter_recommender_system/system_problem.md b/chapter_recommender_system/system_problem.md
index 71e33aa..b81816f 100644
--- a/chapter_recommender_system/system_problem.md
+++ b/chapter_recommender_system/system_problem.md
@@ -3,7 +3,7 @@
在线服务系统的两个主要诉求:
- 大模型的高效存储。
- 为了提升训练和推理的性能,通常推荐模型全部存储在内存中,然而纯内存存储对于内存的需求极高。推荐模型的输入中包含大量无法直接进行矩阵运算的类别数据,而由于每种类别数据包含的每种情况都需要一个单独的嵌入项来表示,而稠密深度神经网络的参数可以共享,在大规模推荐模型中,嵌入表占据了绝大部分内存 :cite:`MLSYS2021_979d472a,MLSYS2020_f7e6c855`。举例说明,假设一个推荐模型需要处理1亿条短视频内容,而每条短视频对应的嵌入项为一个64维的32位浮点数向量,那么仅该内容嵌入表就需要就需要占据大约24GB内存。如果考虑到用户标识符等其他嵌入表,那么单个模型可以轻易占据近100GB内存。而在工业界生产环境中,TB级的推荐模型 :cite:`MLSYS2020_f7e6c855`也是非常常见的。此外,在线推荐系统中需要同时运行多个模型负责不同的服务,甚至同一个服务也会上线多个模型以供算法开发人员验证不同的模型结构或者训练策略,因此系统中通常会同时存在上百个超大模型。综上所述,在线推荐系统亟需既能拓展存储容量,又不会影响训练和推理性能的存储解决方案。
+ 为了提升训练和推理的性能,通常推荐模型全部存储在内存中,然而纯内存存储对于内存的需求极高。推荐模型的输入中包含大量无法直接进行矩阵运算的类别数据,而由于每种类别数据包含的每种情况都需要一个单独的嵌入项来表示,而稠密深度神经网络的参数可以共享,在大规模推荐模型中,嵌入表占据了绝大部分内存 :cite:`MLSYS2021_979d472a,MLSYS2020_f7e6c855`。举例说明,假设一个推荐模型需要处理1亿条短视频内容,而每条短视频对应的嵌入项为一个64维的32位浮点数向量,那么仅该内容嵌入表就需要占据大约24GB内存。如果考虑到用户标识符等其他嵌入表,那么单个模型可以轻易占据近100GB内存。而在工业界生产环境中,TB级的推荐模型 :cite:`MLSYS2020_f7e6c855`也是非常常见的。此外,在线推荐系统中需要同时运行多个模型负责不同的服务,甚至同一个服务也会上线多个模型以供算法开发人员验证不同的模型结构或者训练策略,因此系统中通常会同时存在上百个超大模型。综上所述,在线推荐系统亟需既能拓展存储容量,又不会影响训练和推理性能的存储解决方案。
- 大模型的快速更新。
在线服务系统所面对的环境是复杂多变的,因此其中的机器学习模型必须不断更新以应对新的数据分布。以一个短视频推荐系统为例,其面对的变化主要来自三点。首先,每时每刻都有大量的新视频上传,这些新视频的特征分布和模型训练时所见到的数据不同;其次,对于不断加入的新用户,模型难以直接给出最优的推荐结果;最后,全部用户和内容之间的交互在不断改变,表现为热点视频在持续变化。因此,为了应对以上变化,在线服务中不可能奢望仅仅训练一次模型就能够一劳永逸地解决问题。目前业界主流的做法是利用新产生的数据不断地增量式更新所部属的模型。在学术界和工业界大量的研究和实践 :cite:`10.1145/2020408.2020444,10.1145/2648584.2648589,10.1145/3267809.3267817,9355295`中都发现模型更新可以有效缓解概念漂移带来的危害,而且更新的频率越高,模型的性能越好。
diff --git a/chapter_rl_sys/control.md b/chapter_rl_sys/control.md
new file mode 100644
index 0000000..94c305d
--- /dev/null
+++ b/chapter_rl_sys/control.md
@@ -0,0 +1,24 @@
+## 控制系统
+
+虽然控制理论已牢牢植根于基于模型(Model-based)的设计传统,但丰富的数据和机器学习给控制理论带来了新的机遇。控制理论和机器学习的交叉点涵盖了广泛的研究方向,包括但不限于动态系统的学习、在线学习和控制、深度学习的控制理论观点、强化学习以及在各种现实世界系统中的应用。
+从机器学习的角度来看,未来的主要挑战之一是超越模式识别并解决数据驱动控制和动态过程优化方面的问题。
+
+理论方面,线性二次控制(Linear-Quadratic
+Control)是经典的控制方法,最近有关于图神经网络在分布式线性二次控制的研究 :cite:`pmlr-v144-gama21a`。作者称将线性二次问题转换为自监督学习问题,能够找到基于图神经网络(Graph
+Neural
+Networks,GNN)的最佳分布式控制器,他们还推导出了所得闭环系统稳定的充分条件。随着基于数据和学习的机器人控制方法不断得到重视,研究人员必须了解何时以及如何在现实世界中最好地利用这些方法,因为安全是至关重要的,有的研究通过学习不确定的动力学来安全地提高性能,鼓励安全或稳健的强化学习方法,以及可以正式认证所学控制策略的安全性的方法 :cite:`brunke2021safe`。 :numref:`safe\_learning\_control`展示了安全学习控制(Safe Learning
+Control)系统的框架图,用数据驱动的方法来学习控制策略,兼顾安全性。Lyapunov :cite:`pmlr-v144-mehrjou21a`
+函数是评估非线性动力系统稳定性的有效工具,最近有人提出Neural
+Lyapunov来将安全性纳入考虑。
+
+应用方面,有基于神经网络的自动驾驶汽车模型预测控制 :cite:`vianna2021neural`,也有研究将最优控制和学习相结合并应用在陌生环境中的视觉导航 :cite:`pmlr-v100-bansal20a`,该研究将基于模型的控制与基于学习的感知相结合来解决。基于学习的感知模块产生一系列航路点通过无碰撞路径引导机器人到达目标。基于模型的规划器使用这些航路点来生成平滑且动态可行的轨迹,该轨迹使用反馈控制在物理系统上执行。在模拟的现实世界杂乱环境和实际地面车辆上的实验表明,与纯粹基于几何映射或基于端到端学习的替代方案相比,这种新的系统可以在新环境中更可靠、更有效地到达目标位置。强化学习和模仿学习与控制论有密切联系:LEOC :cite:`pmlr-v144-zhang21b`整合了强化学习和经典控制理论的原则方法。有人将基于模型的离线强化学习算法扩展到高维视觉观察空间并在真实机器人上执行基于图像的抽屉关闭任务方面表现出色 :cite:`pmlr-v144-rafailov21a`。控制部分通过神经网络优化可以更加平滑、节能、安全,如何将
+神经网络和传统控制理论结合,特别是和运动学算法相结合,将会是一个有趣的方向。
+
+
+
+:width:`800px`
+
+:label:`safe\_learning\_control`
+
+:bibliography:`../mlsys.bib`
+
diff --git a/chapter_rl_sys/index.md b/chapter_rl_sys/index.md
new file mode 100644
index 0000000..52e9da0
--- /dev/null
+++ b/chapter_rl_sys/index.md
@@ -0,0 +1,20 @@
+# 机器人系统
+
+在本章中,我们介绍机器学习的一个重要分支——机器人及其在系统方面的知识。本章的学习目标包括:
+
+- 掌握机器人学习基本知识。
+
+- 掌握通用机器人操作系统。
+
+- 掌握感知系统、规划系统、控制系统。
+
+```toc
+:maxdepth: 2
+
+rl_sys_intro
+ros
+perception
+planning
+control
+summary
+```
diff --git a/chapter_rl_sys/perception.md b/chapter_rl_sys/perception.md
new file mode 100644
index 0000000..a028344
--- /dev/null
+++ b/chapter_rl_sys/perception.md
@@ -0,0 +1,25 @@
+## 感知系统
+
+感知系统不仅可以包括视觉,还可以包含触觉、声音等。在未知环境中,机器人想实现自主移动和导航必须知道自己在哪(例如通过相机重定位 :cite:`ding2019camnet`),周围什么情况(例如通过3D物体检测 :cite:`yi2020segvoxelnet`或语义分割),这些要依靠感知系统来实现 :cite:`xu2019depth,xu2020selfvoxelo,xu2022rnnpose,xu2022robust,yang2021pdnet,huang2021vs,huang2021life,huang2019prior,zhu2020ssn`。
+一提到感知系统,不得不提的就是即时定位与建图(Simultaneous Localization
+and
+Mapping,SLAM)系统。SLAM大致过程包括地标提取、数据关联、状态估计、状态更新以及地标更新等。视觉里程计Visual
+Odometry是SLAM中的重要部分,它估计两个时刻机器人的相对运动(Ego-motion)。ORB-SLAM :cite:`campos2021orb`系列是视觉SLAM中有代表性的工作, :numref:`orbslam3` 展示了最新的ORB-SLAM3的主要系统组件。香港科技大学开源的基于单目视觉与惯导融合的SLAM技术VINS-Mono :cite:`8421746`也很值得关注。多传感器融合、优化数据关联与回环检测、与前端异构处理器集成、提升鲁棒性和重定位精度都是SLAM技术接下来的发展方向。
+
+最近,随着机器学习的兴起,基于学习的SLAM框架也被提了出来。TartanVO是第一个基于学习的视觉里程计(VO)模型,该模型可以推广到多个数据集和现实世界场景,并优于传统基于几何的方法。
+UnDeepVO :cite:`li2018undeepvo`是一个无监督深度学习方案,能够通过使用深度神经网络估计单目相机的
+6-DoF 位姿及其视图深度。DROID-SLAM :cite:`teed2021droid`是用于单目、立体和
+RGB-D 相机的深度视觉 SLAM,它通过Bundle
+Adjustment层对相机位姿和像素深度的反复迭代更新,具有很强的鲁棒性,故障大大减少,尽管对单目视频进行了训练,但它可以利用立体声或
+RGB-D 视频在测试时提高性能。其中,Bundle Adjustment
+(BA)与机器学习的结合被广泛研究 :cite:`tang2018ba,tanaka2021learning`。CMU提出通过主动神经
+SLAM
+的模块化系统帮助智能机器人在未知环境中的高效探索 :cite:`chaplot2020learning`。
+
+
+
+:width:`800px`
+
+:label:`orbslam3`
+
+:bibliography:`../mlsys.bib`
diff --git a/chapter_rl_sys/planning.md b/chapter_rl_sys/planning.md
new file mode 100644
index 0000000..3e71735
--- /dev/null
+++ b/chapter_rl_sys/planning.md
@@ -0,0 +1,16 @@
+## 规划系统
+
+规划不仅包含运动路径规划,还包含高级任务规划 :cite:`9712373`。其中,运动规划是机器人技术的核心问题之一,应用范围从导航到复杂环境中的操作。它具有悠久的研究历史,方法需要有概率完整性和最优性的保证。然而,当经典运动规划在处理现实世界的机器人问题(在高维空间中)时,挑战仍然存在。研究人员在继续开发新算法来克服与这些方法相关的限制,包括优化计算和内存负载、更好的规划表示和处理维度灾难等。
+
+相比之下,机器学习的最新进展为机器人专家研究运动规划问题开辟了新视角:经典运动规划器的瓶颈可以以数据驱动的方式解决;基于深度学习的规划器可以避免几何输入的局限性,例如使用视觉或语义输入进行规划等。最近的工作有:基于深度神经网络的四足机器人快速运动规划框架,通过贝叶斯学习进行运动规划 :cite:`quintero2021motion`,通过运动规划器指导的视觉运动策略学习。ML4KP :cite:`ML4KP`是一个用于有效运动动力学运动规划的C++库,该库可以轻松地将机器学习方法集成到规划过程中。
+自动驾驶领域和行人和车辆轨迹预测 :cite:`qiu2021egocentric`方面也涌现出使用机器学习解决运动规划的工作,比如斯坦福大学提出Trajectron++ :cite:`salzmann2020trajectron++`。强化学习在规划系统上也有重要应用 :cite:`aradi2020survey,sun2021adversarial`,比如基于MetaDrive模拟器 :cite:`li2021metadrive`,最近有一些关于多智能体强化学习,多智能体车流模拟、驾驶行为分析 :cite:`peng2021learning`,考虑安全性因素的强化学习 :cite:`peng2021safe`,以及拓展到由真人专家在旁边监督,出现危险的时候接管的专家参与的强化学习工作(Online
+Imitation Learning、Offline
+RL):cite:`li2021efficient`,样本效率极高,是单纯强化学习算法的50倍。为了更好地说明强化学习是如何应用在自动驾驶中的, :numref:`rl\_ad`展示了一个基于深度强化学习的自动驾驶POMDP模型。
+
+
+
+:width:`800px`
+
+:label:`rl\_ad`
+
+:bibliography:`../mlsys.bib`
diff --git a/chapter_rl_sys/rl_sys_intro.md b/chapter_rl_sys/rl_sys_intro.md
new file mode 100644
index 0000000..91fb59a
--- /dev/null
+++ b/chapter_rl_sys/rl_sys_intro.md
@@ -0,0 +1,32 @@
+## 概述
+
+机器人学是一个交叉学科,它涉及了计算机科学、机械工程、电气工程、生物医学工程、数学等多种学科,并有诸多应用,比如自动驾驶汽车、机械臂、无人机、医疗机器人等。机器人能够自主地完成一种或多种任务或者辅助人类完成指定任务。通常,人们把机器人系统划分为感知系统、决策(规划)和控制系统等组成部分 :cite:`buehler2009darpa`。
+
+近些年,随着机器学习的兴起,经典机器人技术出现和机器学习技术结合的趋势,称为机器人学习(Robot
+Learning):cite:`peters2016robot`。机器人学习包含了计算机视觉、自然语言处理、语音处理、强化学习和模仿学习等人工智能技术在机器人上的应用,让机器人通过学习,自主地执行各种决策控制任务。
+
+机器人学习系统(Robot Learning
+System)是一个较新的概念。作为系统和机器人学习的交叉方向,仿照机器学习系统的概念,我们把机器人学习系统定义为"支持机器人模型训练和部署的系统"。按照涉及的机器人数量,可以划分为单机器人学习系统和多机器人学习系统。多机器人学习系统协作和沟通中涉及的安全和隐私问题,也会是一个值得研究的方向。最近机器人学习系统在室内自主移动 :cite:`zhu2017target,pmlr-v100-bansal20a,9123682,huang2018navigationnet`,道路自动驾驶 :cite:`pmlr-v155-huang21a,pmlr-v155-sun21a,Sun2022SelfSupervisedTA`,机械臂工业操作 :cite:`tobin2017domain,finn2017deep,chen2020transferable,duan2017one`等行业场景得到充分应用和发展。一些机器人学习基础设施项目也在进行中,如具备从公开可用的互联网资源、计算机模拟和
+真实机器人试验中学习能力的大规模的计算系统RobotBrain :cite:`saxena2014robobrain`。在自动驾驶领域,受联网的自动驾驶汽车
+(CAV) 对传统交通运输行业的影响,"车辆计算"(Vehicle Computing) :cite:`9491826`
+(如 :numref:`vehicle-computing`)概念引起广泛关注,并激发了如何让计算能力有限使用周围的CAV计算平台来执行复杂的计算任务的研究。最近,有很多自动驾驶系统的模拟器,代表性的比如CARLA :cite:`Dosovitskiy17`,支持安全RL、MARL、真实地图数据导入、泛化性测试等任务的MetaDrive :cite:`li2021metadrive`,还有CarSim和
+TruckSim :cite:`benekohal1988carsim`,它们可以作为各种自动驾驶算法的训练场并对算法效果进行评估。另外针对自动驾驶的系统开发平台也不断涌现,如ERDOS,
+D3 (Dynamic
+Deadline-Driven) :cite:`10.1145/3492321.3519576`和强调模块化思想的Pylot :cite:`gog2021pylot`,可以让模型训练与部署系统与这些平台对接。
+
+
+
+:width:`800px`
+
+:label:`vehicle\_computing`
+
+ :numref:`learning\_decision\_module`是一个典型的感知、规划、控制的模块化设计的自动驾驶系统框架图,接下来,我们也将按照这个顺序依次介绍通用框架、感知系统、规划系统和控制系统。
+
+
+
+:width:`800px`
+
+:label:`learning\_decision\_module`
+
+:bibliography:`../mlsys.bib`
diff --git a/chapter_rl_sys/ros.md b/chapter_rl_sys/ros.md
new file mode 100644
index 0000000..d7f0bb4
--- /dev/null
+++ b/chapter_rl_sys/ros.md
@@ -0,0 +1,108 @@
+## 通用机器人操作系统
+
+
+
+:width:`800px`
+
+:label:`ROS2\_arch`
+
+机器人操作系统(ROS) :cite:`quigley2009ros,maruyama2016exploring,koubaa2017robot`起源于斯坦福大学人工智能实验室的一个机器人项目。它是一个自由、开源的框架,提供接口、工具来构建先进的机器人。由于机器人领域的快速发展和复杂化,代码复用和模块化的需求日益强烈,ROS适用于机器人这种多节点多任务的复杂场景。目前也有一些机器人、无人机甚至无人车都开始采用ROS作为开发平台。在机器人学习方面,ROS/ROS2可以与深度学习结合,有开发人员为ROS/ROS2开发了的深度学习节点,并支持NVIDIA
+Jetson和TensorRT。NVIDIA
+Jetson是NVIDIA为自主机器开发的一个嵌入式系统,包括CPU、GPU、PMIC、DRAM
+和闪存的一个模组化系统,可以将自主机器软件运作系统运行速率提升。TensorRT
+是由 Nvidia 发布的机器学习框架,用于在其硬件上运行机器学习推理。
+
+作为一个适用于机器人编程的框架,ROS把原本松散的零部件耦合在了一起,为他们提供了通信架构。虽然叫做"操作系统",ROS更像是一个中间件,给各种基于ROS的应用程序建立起了沟通的桥梁,通过这个中间件,机器人的感知、决策、控制算法可以组织和运行。ROS采用了分布式的设计思想,支持C++、Pyhton等多种编程语言,方便移植。对ROS来讲,最小的进程单元是节点,由节点管理器来管理。参数配置存储在参数服务器中。ROS的通信方式包含:主题(Topic)、服务(Service)、参数服务器(Parameter
+Server)、动作库(ActionLib)这四种。
+
+ROS提供了很多内置工具,比如三维可视化器rviz,用于可视化机器人、它们工作的环境和传感器数据。它是一个高度可配置的工具,具有许多不同类型的可视化和插件。catkin是ROS
+构建系统(类似于Linux下的CMake),Catkin
+Workspace是创建、修改、编译catkin软件包的目录。roslaunch可用于在本地和远程启动多个ROS
+节点以及在ROS参数服务器上设置参数的工具。此外还有机器人仿真工具Gazebo和移动操作软件和规划框架MoveIt! :cite:`coleman2014reducing`。ROS为机器人开发者提供了不同编程语言的接口,比如C++语言ROS接口roscpp,python语言的ROS接口rospy。ROS中提供了许多机器人的统一机器人描述格式URDF(Unified
+Robot Description
+Format)文件,URDF使用XML格式描述机器人文件。ROS也有一些需要提高的地方,比如它的通信实时性能有限,与工业级要求的系统稳定性还有一定差距。
+
+ROS2 :cite:`maruyama2016exploring`项目在ROSCon 2014上被宣布,第一个ROS2发行版
+Ardent Apalone
+是于2017年发布。ROS2增加了对多机器人系统的支持,提高了多机器人之间通信的网络性能,而且支持微控制器和跨系统平台,不仅可以运行在现有的X86和ARM系统上,还将支持MCU等嵌入式微控制器,不止能运行在Linux系统之上,还增加了对Windows、MacOS、RTOS等系统的支持。更重要的是,ROS
+2还加入了实时控制的支持,可以提高控制的时效性和整体机器人的性能。ROS
+2的通信系统基于DDS(Data Distribution
+Service),即数据分发服务,如 :numref:`ROS2\_arch`所示。
+
+ROS2依赖于使用shell环境组合工作区。"工作区"(Workspace)是一个ROS术语,表示使用ROS2进行开发的系统位置。核心ROS2
+工作区称为Underlay。随后的工作区称为Overlays。使用ROS2
+进行开发时,通常会同时有多个工作区处于活动状态。接下来我们详细介绍一下ROS2的核心概念(这一部分我们参考了文献 [^1])。
+
+### ROS2 Nodes
+
+ROS
+Graph是一个由ROS2元素组成的网络,在同一时间一起处理数据。它包括所有的可执行文件和它们之间的联系。ROS2
+中的每个节点都应负责一个单一的模块用途(例如,一个节点用于控制车轮马达,一个节点用于控制激光测距仪等)。每个节点都可以通过主题、服务、动作或参数向其他节点发送和接收数据。一个完整的机器人系统由许多协同工作的节点组成。在
+ROS 2 中,单个可执行文件(C++ 程序、Python
+程序等)可以包含一个或多个节点,如 :numref:`ros2\_graph`。
+
+
+
+:width:`800px`
+
+:label:`ros2\_graph`
+
+节点之间的互相发现是通过ROS2底层的中间件实现的。 过程总结如下
+
+- 当一个节点启动后, 它会向其他拥有相同ROS域名(ROS domain,
+ 可以通过设置ROS\_DOMAIN\_ID环境变量来设
+ 置)的节点进行广播,说明它已经上线。
+ 其他节点在收到广播后返回自己的相关信息,这样节点间的连接就可以建
+ 立了,之后就可以通信了。
+
+- 节点会定时广播它的信息,这样即使它已经错过了最初的发现过程,它也可以和新上线的节点进行连接。
+
+- 节点在下线前它也会广播其他节点自己要下线了。
+
+### ROS2 Topics
+
+ROS2将复杂系统分解为许多模块化节点。主题(Topics)是 ROS
+Graph的重要元素,它充当节点交换消息的总线。一个节点可以向任意数量的主题发布数据,同时订阅任意数量的主题,如 :numref:`ros2\_topics`所示。主题是数据在节点之间以及因此在系统的不同部分之间移动的主要方式之一。
+
+rqt是ROS的一个软件框架,以插件的形式实现了各种 GUI 工具。可以在 rqt
+中将所有现有的GUI工具作为可停靠窗口运行。这些工具仍然可以以传统的独立方法运行,但rqt可以更轻松地同时管理屏幕上的所有各种窗口。
+
+
+
+:width:`800px`
+
+:label:`ros2\_topics`
+
+### ROS 2 Services
+
+服务(Services)是 ROS
+图中节点的另一种通信方式。服务基于调用和响应模型,而不是主题的发布者-订阅者模型。虽然主题允许节点订阅数据流并获得持续更新,但服务仅在客户端专门调用它们时才提供数据。节点可以使用ROS2中的服务进行通信。与主题那种单向通信模式,节点发布可由一个或多个订阅者使用的信息的方式不同
+服务是客户端向节点发出请求的请求/响应模式提供服务,服务处理请求并生成响应。
+
+
+
+:width:`800px`
+
+:label:`ros2\_services`
+
+### ROS 2 Parameters
+
+参数(Parameters)是节点的配置值。您可以将参数视为节点设置。节点可以将参数存储为整数、浮点数、布尔值、字符串和列表。在ROS2
+中,每个节点都维护自己的参数。
+
+### ROS 2 Actions
+
+动作(Actions)是ROS2中的一种通信类型,适用于长时间运行的任务。它们由三个部分组成:目标、反馈和结果。动作建立在主题和服务之上。它们的功能类似于服务,除了可以取消动作。它们还提供稳定的反馈,而不是返回单一响应的服务。动作使用客户端-服务器模型,类似于发布者-订阅者模型(在主题教程中描述)。"动作客户端"节点将目标发送到"动作服务器"节点,该节点确认目标并返回反馈流和结果。动作类似于允许您执行长时间运行的任务、提供定期反馈并且可以取消的服务。机器人系统可能会使用动作进行导航。动作目标可以告诉机器人前往某个位置。当机器人导航到该位置时,它可以沿途发送更新(即反馈),然后在到达目的地后发送最终结果消息。
+
+
+
+:width:`800px`
+
+:label:`ros2\_actions`
+
+:bibliography:`../mlsys.bib`
+
+
+[^1]: https://docs.ros.org/en/foxy/Tutorials/Understanding-ROS2-Nodes.html
\ No newline at end of file
diff --git a/chapter_rl_sys/summary.md b/chapter_rl_sys/summary.md
new file mode 100644
index 0000000..ba7bb28
--- /dev/null
+++ b/chapter_rl_sys/summary.md
@@ -0,0 +1,3 @@
+## 小结
+
+在这一章,我们简单介绍了机器人学习系统的基本概念,包括通用机器人操作系统、感知系统、规划系统和控制系统等,给读者对机器人学习问题的基本认识。当前,机器人学习是一个快速发展的人工智能分支,许多实际问题都有可能通过机器人学习算法的进一步发展得到解决。另一方面,由于机器人学习问题设置的特殊性,也使得相应系统与相关硬件的耦合程度更高、更复杂:如何更好地平衡各种传感器负载?如何在计算资源有限的情况下最大化计算效率(实时性)?等等,都需要对计算机系统的设计和使用有更好的理解。
diff --git a/config.ini b/config.ini
index 110d999..9b3abc7 100644
--- a/config.ini
+++ b/config.ini
@@ -77,7 +77,7 @@ header_links = GitHub, https://github.com/openmlsys/openmlsys-zh, fab fa-github,
favicon = static/favicon.png
-# html_logo = static/logo-with-text.png
+html_logo = static/logo-with-text.png
[pdf]
diff --git a/img/ch01/framework_architecture.png b/img/ch01/framework_architecture.png
new file mode 100644
index 0000000..57b6136
Binary files /dev/null and b/img/ch01/framework_architecture.png differ
diff --git a/img/ch01/framework_architecture.svg b/img/ch01/framework_architecture.svg
deleted file mode 100644
index 1c58d29..0000000
--- a/img/ch01/framework_architecture.svg
+++ /dev/null
@@ -1,442 +0,0 @@
-
-
-
-
diff --git a/img/ch01/framework_position.png b/img/ch01/framework_position.png
new file mode 100644
index 0000000..f178f1f
Binary files /dev/null and b/img/ch01/framework_position.png differ
diff --git a/img/ch01/framework_position.svg b/img/ch01/framework_position.svg
deleted file mode 100644
index 8c30515..0000000
--- a/img/ch01/framework_position.svg
+++ /dev/null
@@ -1,270 +0,0 @@
-
-
-
-
diff --git a/img/ch02/img_workflow.svg b/img/ch02/img_workflow.svg
new file mode 100644
index 0000000..79db4fd
--- /dev/null
+++ b/img/ch02/img_workflow.svg
@@ -0,0 +1,172 @@
+
+
+
+
diff --git a/img/ch02/workflow.svg b/img/ch02/workflow.svg
deleted file mode 100644
index 3cce87a..0000000
--- a/img/ch02/workflow.svg
+++ /dev/null
@@ -1,168 +0,0 @@
-
-
-
-
diff --git a/img/ch03/ast.svg b/img/ch03/ast.svg
index d3cf21f..e06ab5e 100644
--- a/img/ch03/ast.svg
+++ b/img/ch03/ast.svg
@@ -3,79 +3,74 @@
+ id="tspan106">解析语法分析语法树转写静态图代码静态生成
diff --git a/img/ch03/ast1.svg b/img/ch03/ast1.svg
new file mode 100644
index 0000000..d3cf21f
--- /dev/null
+++ b/img/ch03/ast1.svg
@@ -0,0 +1,258 @@
+
+
+
+
diff --git a/img/ch03/dynamic-gen.svg b/img/ch03/dynamic-gen.svg
index 2d647e5..f155d82 100644
--- a/img/ch03/dynamic-gen.svg
+++ b/img/ch03/dynamic-gen.svg
@@ -3,154 +3,224 @@
+ style="fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none"
+ id="path324" />运行前向matmul算子matmul算子反向计算运行前向add算子add算子反向计算运行前向ReLU算子ReLU算子反向计算梯度反向计算
diff --git a/img/ch03/dynamic-gen1.svg b/img/ch03/dynamic-gen1.svg
new file mode 100644
index 0000000..2d647e5
--- /dev/null
+++ b/img/ch03/dynamic-gen1.svg
@@ -0,0 +1,508 @@
+
+
+
+
diff --git a/img/ch03/dynamic.svg b/img/ch03/dynamic.svg
index 76bf01a..6b6a00a 100644
--- a/img/ch03/dynamic.svg
+++ b/img/ch03/dynamic.svg
@@ -2,259 +2,673 @@
+ id="layer1"
+ transform="translate(-31.425089,-138.98401)">
+
+
+
+
+ Y
+
+
+
+
+
+ W
+
+
+
+
+
+ A
+
+
+
+
+
+
+ *
+
+
+
+
+
+
+ ReLU
+
+
+
+
+
+ 前端定义
+
+
+
+
+
+
+
+
+
+ 计
+
+
+
+
+ 算
+
+
+
+
+ 框
+
+
+
+
+ 架
+
+
+
+
+ 算
+
+
+
+
+ 子
+
+
+
+
+ 分
+
+
+
+
+ 发
+
+
+
+
+
+
+ 硬
+
+
+
+
+ 件
+
+
+
+
+ 执
+
+
+
+
+ 行
+
+
+
+
+
+
+
diff --git a/img/ch03/dynamic1.svg b/img/ch03/dynamic1.svg
new file mode 100644
index 0000000..76bf01a
--- /dev/null
+++ b/img/ch03/dynamic1.svg
@@ -0,0 +1,260 @@
+
+
+
+
diff --git a/img/ch03/static.svg b/img/ch03/static.svg
index 9241c40..a76d82a 100644
--- a/img/ch03/static.svg
+++ b/img/ch03/static.svg
@@ -3,109 +3,109 @@
+ id="tspan230">静态计算图
diff --git a/img/ch03/static1.svg b/img/ch03/static1.svg
new file mode 100644
index 0000000..9241c40
--- /dev/null
+++ b/img/ch03/static1.svg
@@ -0,0 +1,342 @@
+
+
+
+
diff --git a/img/ch04/中间表示-LLVMIR.png b/img/ch04/中间表示-LLVMIR.png
new file mode 100644
index 0000000..f03bcc7
Binary files /dev/null and b/img/ch04/中间表示-LLVMIR.png differ
diff --git a/img/ch04/中间表示-LLVMIR.svg b/img/ch04/中间表示-LLVMIR.svg
deleted file mode 100644
index a3aa537..0000000
--- a/img/ch04/中间表示-LLVMIR.svg
+++ /dev/null
@@ -1,197 +0,0 @@
-
-
-
-
diff --git a/img/ch04/中间表示-MLIR.png b/img/ch04/中间表示-MLIR.png
new file mode 100644
index 0000000..24affc3
Binary files /dev/null and b/img/ch04/中间表示-MLIR.png differ
diff --git a/img/ch04/中间表示-MLIR.svg b/img/ch04/中间表示-MLIR.svg
deleted file mode 100644
index fddf16b..0000000
--- a/img/ch04/中间表示-MLIR.svg
+++ /dev/null
@@ -1,321 +0,0 @@
-
-
-
-
diff --git a/img/ch04/中间表示-MindIR.png b/img/ch04/中间表示-MindIR.png
new file mode 100644
index 0000000..d831996
Binary files /dev/null and b/img/ch04/中间表示-MindIR.png differ
diff --git a/img/ch04/中间表示-MindIR.svg b/img/ch04/中间表示-MindIR.svg
deleted file mode 100644
index 8dfce81..0000000
--- a/img/ch04/中间表示-MindIR.svg
+++ /dev/null
@@ -1,380 +0,0 @@
-
-
-
-
diff --git a/img/ch04/中间表示-中间表示结构.png b/img/ch04/中间表示-中间表示结构.png
new file mode 100644
index 0000000..4fb9ddd
Binary files /dev/null and b/img/ch04/中间表示-中间表示结构.png differ
diff --git a/img/ch04/中间表示-中间表示结构.svg b/img/ch04/中间表示-中间表示结构.svg
deleted file mode 100644
index 7f8a454..0000000
--- a/img/ch04/中间表示-中间表示结构.svg
+++ /dev/null
@@ -1,364 +0,0 @@
-
-
-
-
diff --git a/img/ch04/中间表示-线性中间表示.png b/img/ch04/中间表示-线性中间表示.png
new file mode 100644
index 0000000..be66275
Binary files /dev/null and b/img/ch04/中间表示-线性中间表示.png differ
diff --git a/img/ch04/中间表示-线性中间表示.svg b/img/ch04/中间表示-线性中间表示.svg
deleted file mode 100644
index e1a6444..0000000
--- a/img/ch04/中间表示-线性中间表示.svg
+++ /dev/null
@@ -1,744 +0,0 @@
-
-
-
-
diff --git a/img/ch04/自动微分-前向模式自动微分示例.png b/img/ch04/自动微分-前向模式自动微分示例.png
index ac7f559..4fb73ab 100644
Binary files a/img/ch04/自动微分-前向模式自动微分示例.png and b/img/ch04/自动微分-前向模式自动微分示例.png differ
diff --git a/img/ch04/自动微分-反向模式自动微分示例.png b/img/ch04/自动微分-反向模式自动微分示例.png
index f6f3615..7d8f189 100644
Binary files a/img/ch04/自动微分-反向模式自动微分示例.png and b/img/ch04/自动微分-反向模式自动微分示例.png differ
diff --git a/img/ch05/compiler-backend-architecture.jpeg b/img/ch05/compiler-backend-architecture.jpeg
deleted file mode 100644
index 1b50bcc..0000000
Binary files a/img/ch05/compiler-backend-architecture.jpeg and /dev/null differ
diff --git a/img/ch05/compiler-backend-architecture.png b/img/ch05/compiler-backend-architecture.png
new file mode 100644
index 0000000..adfbba1
Binary files /dev/null and b/img/ch05/compiler-backend-architecture.png differ
diff --git a/img/ch05/data_format.png b/img/ch05/data_format.png
index eed7b3b..705473b 100644
Binary files a/img/ch05/data_format.png and b/img/ch05/data_format.png differ
diff --git a/img/ch05/floatdtype.png b/img/ch05/floatdtype.png
index 52d4cb6..794f2f9 100644
Binary files a/img/ch05/floatdtype.png and b/img/ch05/floatdtype.png differ
diff --git a/img/ch06/SM.svg b/img/ch06/SM.svg
index 3a7f420..1e5a42b 100644
--- a/img/ch06/SM.svg
+++ b/img/ch06/SM.svg
@@ -1,9571 +1,1362 @@
-
-
-
-
+
+
+
diff --git a/img/ch06/V100.svg b/img/ch06/V100.svg
index 56a90b6..fd10467 100644
--- a/img/ch06/V100.svg
+++ b/img/ch06/V100.svg
@@ -1,22683 +1,37483 @@
-
-
-
-
+
+
+
diff --git a/img/ch06/compute_unit.svg b/img/ch06/compute_unit.svg
index 206e415..57f0796 100644
--- a/img/ch06/compute_unit.svg
+++ b/img/ch06/compute_unit.svg
@@ -1,13867 +1,1793 @@
-
-
-
-
+
+
+
diff --git a/img/ch06/tensor_core.svg b/img/ch06/tensor_core.svg
index a390252..0ca6a46 100644
--- a/img/ch06/tensor_core.svg
+++ b/img/ch06/tensor_core.svg
@@ -1,392 +1,1396 @@
-
-
-
-
+
+
+
diff --git a/img/ch08/deepcomp.png b/img/ch08/deepcomp.png
index a1af159..2e4dee6 100644
Binary files a/img/ch08/deepcomp.png and b/img/ch08/deepcomp.png differ
diff --git a/img/ch08/distillation.png b/img/ch08/distillation.png
new file mode 100644
index 0000000..9af7862
Binary files /dev/null and b/img/ch08/distillation.png differ
diff --git a/img/ch08/model_obfuscate.png b/img/ch08/model_obfuscate.png
index 53e0805..68eb540 100644
Binary files a/img/ch08/model_obfuscate.png and b/img/ch08/model_obfuscate.png differ
diff --git a/img/ch08/quant-minmax-outpoints.png b/img/ch08/quant-minmax-outpoints.png
index 2f88454..ba4bbae 100644
Binary files a/img/ch08/quant-minmax-outpoints.png and b/img/ch08/quant-minmax-outpoints.png differ
diff --git a/img/ch08/quant-minmax.png b/img/ch08/quant-minmax.png
index 67f8dc7..7701632 100644
Binary files a/img/ch08/quant-minmax.png and b/img/ch08/quant-minmax.png differ
diff --git a/img/ch09/ch10-allreduce-process.png b/img/ch09/ch10-allreduce-process.png
new file mode 100644
index 0000000..c97e3db
Binary files /dev/null and b/img/ch09/ch10-allreduce-process.png differ
diff --git a/img/ch09/ch10-allreduce-state.png b/img/ch09/ch10-allreduce-state.png
new file mode 100644
index 0000000..953a15e
Binary files /dev/null and b/img/ch09/ch10-allreduce-state.png differ
diff --git a/img/ch09/ch10-computation-increase.png b/img/ch09/ch10-computation-increase.png
new file mode 100644
index 0000000..84db6f5
Binary files /dev/null and b/img/ch09/ch10-computation-increase.png differ
diff --git a/img/ch09/ch10-data-parallel.png b/img/ch09/ch10-data-parallel.png
new file mode 100644
index 0000000..5de643a
Binary files /dev/null and b/img/ch09/ch10-data-parallel.png differ
diff --git a/img/ch09/ch10-datacentre.png b/img/ch09/ch10-datacentre.png
new file mode 100644
index 0000000..53b9cef
Binary files /dev/null and b/img/ch09/ch10-datacentre.png differ
diff --git a/img/ch09/ch10-hybrid-parallel.png b/img/ch09/ch10-hybrid-parallel.png
new file mode 100644
index 0000000..f212425
Binary files /dev/null and b/img/ch09/ch10-hybrid-parallel.png differ
diff --git a/img/ch09/ch10-model-parallel-inter-op.png b/img/ch09/ch10-model-parallel-inter-op.png
new file mode 100644
index 0000000..791c0a5
Binary files /dev/null and b/img/ch09/ch10-model-parallel-inter-op.png differ
diff --git a/img/ch09/ch10-model-parallel-intra-op.png b/img/ch09/ch10-model-parallel-intra-op.png
index 1a9ddcd..e07949a 100644
Binary files a/img/ch09/ch10-model-parallel-intra-op.png and b/img/ch09/ch10-model-parallel-intra-op.png differ
diff --git a/img/ch09/ch10-parameter-servers.png b/img/ch09/ch10-parameter-servers.png
new file mode 100644
index 0000000..a129339
Binary files /dev/null and b/img/ch09/ch10-parameter-servers.png differ
diff --git a/img/ch09/ch10-pipeline-parallel.png b/img/ch09/ch10-pipeline-parallel.png
new file mode 100644
index 0000000..d012401
Binary files /dev/null and b/img/ch09/ch10-pipeline-parallel.png differ
diff --git a/img/ch09/ch10-single-node.png b/img/ch09/ch10-single-node.png
new file mode 100644
index 0000000..a181440
Binary files /dev/null and b/img/ch09/ch10-single-node.png differ
diff --git a/img/ch09/ch10-single-vs-multi.png b/img/ch09/ch10-single-vs-multi.png
new file mode 100644
index 0000000..f5fe3e2
Binary files /dev/null and b/img/ch09/ch10-single-vs-multi.png differ
diff --git a/img/ch10/ch10-abstract-recommendation-systems.png b/img/ch10/ch10-abstract-recommendation-systems.png
new file mode 100644
index 0000000..dbb6593
Binary files /dev/null and b/img/ch10/ch10-abstract-recommendation-systems.png differ
diff --git a/img/ch10/ch10-federated-learning-architecture.png b/img/ch10/ch10-federated-learning-architecture.png
deleted file mode 100644
index 8ec60b6..0000000
Binary files a/img/ch10/ch10-federated-learning-architecture.png and /dev/null differ
diff --git a/img/ch10/ch10-federated-learning-architecture.svg b/img/ch10/ch10-federated-learning-architecture.svg
new file mode 100644
index 0000000..b48b20f
--- /dev/null
+++ b/img/ch10/ch10-federated-learning-architecture.svg
@@ -0,0 +1,1557 @@
+
+
+
+
diff --git a/img/ch10/ch10-federated-learning-signds.PNG b/img/ch10/ch10-federated-learning-signds.PNG
new file mode 100644
index 0000000..58668a4
Binary files /dev/null and b/img/ch10/ch10-federated-learning-signds.PNG differ
diff --git a/img/ch10/ch10-federated-learning-vfl-arch.png b/img/ch10/ch10-federated-learning-vfl-arch.png
deleted file mode 100644
index 656882e..0000000
Binary files a/img/ch10/ch10-federated-learning-vfl-arch.png and /dev/null differ
diff --git a/img/ch10/ch10-federated-learning-vfl-arch.svg b/img/ch10/ch10-federated-learning-vfl-arch.svg
new file mode 100644
index 0000000..e2cbada
--- /dev/null
+++ b/img/ch10/ch10-federated-learning-vfl-arch.svg
@@ -0,0 +1,619 @@
+
+
+
+
diff --git a/img/ch10/ch10-federated-learning-vfl-train.png b/img/ch10/ch10-federated-learning-vfl-train.png
deleted file mode 100644
index 4d1c90f..0000000
Binary files a/img/ch10/ch10-federated-learning-vfl-train.png and /dev/null differ
diff --git a/img/ch10/ch10-federated-learning-vfl-train.svg b/img/ch10/ch10-federated-learning-vfl-train.svg
new file mode 100644
index 0000000..92cb18b
--- /dev/null
+++ b/img/ch10/ch10-federated-learning-vfl-train.svg
@@ -0,0 +1,927 @@
+
+
+
+
diff --git a/img/ch10/ch10-recommendation-models.png b/img/ch10/ch10-recommendation-models.png
new file mode 100644
index 0000000..53bb1f1
Binary files /dev/null and b/img/ch10/ch10-recommendation-models.png differ
diff --git a/img/ch10/ch10-recommendation-systems.png b/img/ch10/ch10-recommendation-systems.png
new file mode 100644
index 0000000..440d8ff
Binary files /dev/null and b/img/ch10/ch10-recommendation-systems.png differ
diff --git a/img/ch13/ROS2_arch.png b/img/ch13/ROS2_arch.png
new file mode 100644
index 0000000..1e5a8ef
Binary files /dev/null and b/img/ch13/ROS2_arch.png differ
diff --git a/img/ch13/idm.png b/img/ch13/idm.png
new file mode 100644
index 0000000..75cd9db
Binary files /dev/null and b/img/ch13/idm.png differ
diff --git a/img/ch13/orbslam3.png b/img/ch13/orbslam3.png
new file mode 100644
index 0000000..44c2863
Binary files /dev/null and b/img/ch13/orbslam3.png differ
diff --git a/img/ch13/rl_ad.png b/img/ch13/rl_ad.png
new file mode 100644
index 0000000..f186382
Binary files /dev/null and b/img/ch13/rl_ad.png differ
diff --git a/img/ch13/ros2_actions.png b/img/ch13/ros2_actions.png
new file mode 100644
index 0000000..0fcffae
Binary files /dev/null and b/img/ch13/ros2_actions.png differ
diff --git a/img/ch13/ros2_graph.png b/img/ch13/ros2_graph.png
new file mode 100644
index 0000000..b934e3c
Binary files /dev/null and b/img/ch13/ros2_graph.png differ
diff --git a/img/ch13/ros2_services.png b/img/ch13/ros2_services.png
new file mode 100644
index 0000000..2369bd4
Binary files /dev/null and b/img/ch13/ros2_services.png differ
diff --git a/img/ch13/ros2_topics.png b/img/ch13/ros2_topics.png
new file mode 100644
index 0000000..075d094
Binary files /dev/null and b/img/ch13/ros2_topics.png differ
diff --git a/img/ch13/safe_learning_control.png b/img/ch13/safe_learning_control.png
new file mode 100644
index 0000000..5b67f5f
Binary files /dev/null and b/img/ch13/safe_learning_control.png differ
diff --git a/img/ch13/vehicle_computing.png b/img/ch13/vehicle_computing.png
new file mode 100644
index 0000000..d600e54
Binary files /dev/null and b/img/ch13/vehicle_computing.png differ
diff --git a/index.md b/index.md
index fcc54be..c876304 100644
--- a/index.md
+++ b/index.md
@@ -24,6 +24,7 @@ chapter_recommender_system/index
chapter_federated_learning/index
chapter_reinforcement_learning/index
chapter_explainable_AI/index
+chapter_rl_sys/index
```
@@ -32,4 +33,4 @@ chapter_explainable_AI/index
appendix_machine_learning_introduction/index
chapter_references/index
-```
\ No newline at end of file
+```
diff --git a/info/Pic-Instruction/Pic_Templates_and_Samples.pptx b/info/Pic-Instruction/Pic_Templates_and_Samples.pptx
new file mode 100644
index 0000000..498ce4e
Binary files /dev/null and b/info/Pic-Instruction/Pic_Templates_and_Samples.pptx differ
diff --git a/info/Pic-Instruction/Requirements and Instructions.md b/info/Pic-Instruction/Requirements and Instructions.md
new file mode 100644
index 0000000..a80e416
--- /dev/null
+++ b/info/Pic-Instruction/Requirements and Instructions.md
@@ -0,0 +1,15 @@
+## 书籍图片制作模板
+为了保证图书中图片尽量统一,我们输出了图形的基础模板,包括色系、线条、箭头、框图等流程图常用的模块。
+大家可以根据自己绘制流程图的需求,选择合适的组件进行绘制。为了方便大家作图,我们以PPT的形式提供给大家,不需要开发者掌握单独的作图工具。
+使用的简单流程如下:
+1、梳理流程图的逻辑。
+2、使用PPT中的模板进行绘制。
+3、通过PPT导出图片,建议为png格式。
+4、将导出后的图片放到相应img目录相应的章节,在文档中进行引用。
+
+字体说明:
+1、正文采用五号字体(中文为宋体,英文为 Time New Roman)。
+2、插图/插表的标题用小五号黑体,插图/插表的其他文字用小五号字体(中文为宋体,英文为 Time New Roman)。
+3、代码采用小五号, Courier New字体。
+
+
diff --git a/info/editors.md b/info/editors.md
index 5131e2c..03f086d 100644
--- a/info/editors.md
+++ b/info/editors.md
@@ -36,7 +36,9 @@
第13章 - 可解释性AI系统:[@HaoyangLee](https://github.com/HaoyangLee)
-附录:机器学习介绍:[@zsdonghao](https://github.com/zsdonghao)
+第14章 - 机器人学习系统:[@Jack](https://github.com/Jiankai-Sun)
+
+附录:机器学习介绍:[@Hao](https://github.com/zsdonghao)
## 加入我们
diff --git a/info/info.md b/info/info.md
index 0ae7ade..d1ab4ba 100644
--- a/info/info.md
+++ b/info/info.md
@@ -1,7 +1,7 @@
## 环境安装
机器学习系统书籍部署在Github是依赖于d2lbook工具实现的。因此我们首先要安装d2lbook。
```bash
-git clone git@github.com:d2l-ai/d2l-book.git
+git clone https://github.com/openmlsys/d2l-book.git
cd d2l-book
python setup.py install
```
@@ -12,7 +12,7 @@ python setup.py install
## 编译HTML版本
在编译前先下载[openmlsys-zh](https://github.com/openmlsys/openmlsys-zh) 所有的编译命令都在改文件目录内执行。
```bash
- git clone git@github.com:openmlsys/openmlsys-zh.git
+ git clone https://github.com/openmlsys/openmlsys-zh.git
cd openmlsys-zh
```
使用d2lbook工具编译HTML。
diff --git a/mlsys.bib b/mlsys.bib
index 787516a..021ac01 100644
--- a/mlsys.bib
+++ b/mlsys.bib
@@ -439,6 +439,15 @@ series = {ADKDD'14}
note = {\url{http://www.nvidia.com/object/volta-architecture-whitepaper.html}}
}
+@inproceedings{2021Ascend,
+ title={Ascend: a Scalable and Unified Architecture for Ubiquitous Deep Neural Network Computing : Industry Track Paper},
+ author={Liao, Heng and Tu, Jiajin and Xia, Jing and Liu, Hu and Zhou, Xiping and Yuan, Honghui and Hu, Yuxing},
+ booktitle={2021 IEEE International Symposium on High-Performance Computer Architecture (HPCA)},
+ year={2021},
+ pages = {789–801},
+ doi = {10.1109/HPCA51647.2021.00071},
+}
+
@article{2018Modeling,
title={Modeling Deep Learning Accelerator Enabled GPUs},
author={Raihan, M. A. and Goli, N. and Aamodt, T.},
@@ -739,6 +748,89 @@ location = {Halifax, NS, Canada},
series = {ADKDD'17}
}
+@inproceedings{fedavg,
+ author = {Brendan McMahan and
+ Eider Moore and
+ Daniel Ramage and
+ Seth Hampson and
+ Blaise Ag{\"{u}}era y Arcas},
+ title = {Communication-Efficient Learning of Deep Networks from Decentralized
+ Data},
+ booktitle = {Proceedings of the 20th International Conference on Artificial Intelligence
+ and Statistics, {AISTATS} 2017, 20-22 April 2017, Fort Lauderdale,
+ FL, {USA}},
+ series = {Proceedings of Machine Learning Research},
+ volume = {54},
+ pages = {1273--1282},
+ publisher = {{PMLR}},
+ year = {2017},
+ url = {http://proceedings.mlr.press/v54/mcmahan17a.html},
+}
+
+@inproceedings{scaffold,
+ title={Scaffold: Stochastic controlled averaging for federated learning},
+ author={Karimireddy, Sai Praneeth and Kale, Satyen and Mohri, Mehryar and Reddi, Sashank and Stich, Sebastian and Suresh, Ananda Theertha},
+ booktitle={International Conference on Machine Learning},
+ pages={5132--5143},
+ year={2020},
+ organization={PMLR}
+}
+
+@article{FedDF,
+ title={Ensemble distillation for robust model fusion in federated learning},
+ author={Lin, Tao and Kong, Lingjing and Stich, Sebastian U and Jaggi, Martin},
+ journal={Advances in Neural Information Processing Systems},
+ volume={33},
+ pages={2351--2363},
+ year={2020}
+}
+
+@inproceedings{PATE,
+ author = {Nicolas Papernot and
+ Mart{\'{\i}}n Abadi and
+ {\'{U}}lfar Erlingsson and
+ Ian J. Goodfellow and
+ Kunal Talwar},
+ title = {Semi-supervised Knowledge Transfer for Deep Learning from Private
+ Training Data},
+ booktitle = {5th International Conference on Learning Representations, {ICLR} 2017,
+ Toulon, France, April 24-26, 2017, Conference Track Proceedings},
+ publisher = {OpenReview.net},
+ year = {2017},
+}
+
+@inproceedings{FedProx,
+ title={Federated optimization in heterogeneous networks},
+ author={Li, Tian and Sahu, Anit Kumar and Zaheer, Manzil and Sanjabi, Maziar and Talwalkar, Ameet and Smith, Virginia},
+ booktitle={Proceedings of Machine Learning and Systems},
+ volume={2},
+ pages={429--450},
+ year={2020}
+}
+
+@inproceedings{FedBE,
+ author = {Hong{-}You Chen and
+ Wei{-}Lun Chao},
+ title = {FedBE: Making Bayesian Model Ensemble Applicable to Federated Learning},
+ booktitle = {9th International Conference on Learning Representations, {ICLR} 2021,
+ Virtual Event, Austria, May 3-7, 2021},
+ year = {2021},
+}
+
+@article{FedAvg_Momentum,
+ author = {Tzu{-}Ming Harry Hsu and
+ Hang Qi and
+ Matthew Brown},
+ title = {Measuring the Effects of Non-Identical Data Distribution for Federated
+ Visual Classification},
+ journal = {CoRR},
+ volume = {abs/1909.06335},
+ year = {2019},
+ url = {http://arxiv.org/abs/1909.06335},
+ eprinttype = {arXiv},
+ eprint = {1909.06335},
+}
+
@inproceedings{ijcai2017-239,
author = {Huifeng Guo and Ruiming TANG and Yunming Ye and Zhenguo Li and Xiuqiang He},
title = {DeepFM: A Factorization-Machine based Neural Network for CTR Prediction},
@@ -835,4 +927,563 @@ series = {PPoPP '21}
doi = "10.18653/v1/2021.naacl-industry.15",
pages = "113--120",
abstract = "Transformer and its variants have achieved great success in natural language processing. Since Transformer models are huge in size, serving these models is a challenge for real industrial applications. In this paper, we propose , a highly efficient inference library for models in the Transformer family. includes a series of GPU optimization techniques to both streamline the computation of Transformer layers and reduce memory footprint. supports models trained using PyTorch and Tensorflow. Experimental results on standard machine translation benchmarks show that achieves up to 14x speedup compared with TensorFlow and 1.4x speedup compared with , a concurrent CUDA implementation. The code will be released publicly after the review.",
-}
\ No newline at end of file
+}
+
+@article{jiang2022signds,
+ title={SignDS-FL: Local Differentially Private Federated Learning with Sign-based Dimension Selection},
+ author={Jiang, Xue and Zhou, Xuebing and Grossklags, Jens},
+ journal={ACM Transactions on Intelligent Systems and Technology (TIST)},
+ year={2022},
+ publisher = {Association for Computing Machinery},
+ address = {New York, USA}
+}
+
+@article{dwork2014algorithmic,
+ title={The algorithmic foundations of differential privacy},
+ author={Dwork, Cynthia and Roth, Aaron},
+ journal={Foundations and Trends in Theoretical Computer Science},
+ volume={9},
+ number={3--4},
+ pages={211--407},
+ year={2014},
+}
+
+@inproceedings{mcsherry2007mechanism,
+ title={Mechanism design via differential privacy},
+ author={McSherry, Frank and Talwar, Kunal},
+ booktitle={IEEE Symposium on Foundations of Computer Science},
+ pages={94--103},
+ year={2007},
+}
+
+@inproceedings{quigley2009ros,
+ title={ROS: an open-source Robot Operating System},
+ author={Quigley, Morgan and Conley, Ken and Gerkey, Brian and Faust, Josh and Foote, Tully and Leibs, Jeremy and Wheeler, Rob and Ng, Andrew Y and others},
+ booktitle={ICRA workshop on open source software},
+ volume={3},
+ number={3.2},
+ pages={5},
+ year={2009},
+ organization={Kobe, Japan}
+}
+
+@inproceedings{maruyama2016exploring,
+ title={Exploring the performance of ROS2},
+ author={Maruyama, Yuya and Kato, Shinpei and Azumi, Takuya},
+ booktitle={Proceedings of the 13th ACM SIGBED International Conference on Embedded Software (EMSOFT)},
+ pages={1--10},
+ year={2016}
+}
+
+@inproceedings{ding2019camnet,
+ title={CamNet: Coarse-to-fine retrieval for camera re-localization},
+ author={Ding, Mingyu and Wang, Zhe and Sun, Jiankai and Shi, Jianping and Luo, Ping},
+ booktitle={Proceedings of the IEEE/CVF International Conference on Computer Vision},
+ pages={2871--2880},
+ year={2019}
+}
+
+@inproceedings{yi2020segvoxelnet,
+ title={Segvoxelnet: Exploring semantic context and depth-aware features for 3d vehicle detection from point cloud},
+ author={Yi, Hongwei and Shi, Shaoshuai and Ding, Mingyu and Sun, Jiankai and Xu, Kui and Zhou, Hui and Wang, Zhe and Li, Sheng and Wang, Guoping},
+ booktitle={2020 IEEE International Conference on Robotics and Automation (ICRA)},
+ pages={2274--2280},
+ year={2020},
+ organization={IEEE}
+}
+
+@ARTICLE{9712373, author={Sun, Jiankai and Huang, De-An and Lu, Bo and Liu, Yun-Hui and Zhou, Bolei and Garg, Animesh}, journal={IEEE Robotics and Automation Letters}, title={PlaTe: Visually-Grounded Planning With Transformers in Procedural Tasks}, year={2022}, volume={7}, number={2}, pages={4924-4930}, doi={10.1109/LRA.2022.3150855}}
+
+@inproceedings{li2018undeepvo,
+ title={Undeepvo: Monocular visual odometry through unsupervised deep learning},
+ author={Li, Ruihao and Wang, Sen and Long, Zhiqiang and Gu, Dongbing},
+ booktitle={2018 IEEE international conference on robotics and automation (ICRA)},
+ pages={7286--7291},
+ year={2018},
+ organization={IEEE}
+}
+
+@inproceedings{quintero2021motion,
+ title={Motion planning via bayesian learning in the dark},
+ author={Quintero-Pena, Carlos and Chamzas, Constantinos and Unhelkar, Vaibhav and Kavraki, Lydia E},
+ booktitle={ICRA: Workshop on Machine Learning for Motion Planning},
+ year={2021}
+}
+
+@MISC{ML4KP,
+author = {Edgar Granados and Aravind Sivaramakrishnan and Troy McMahon and Zakary Littlefield and Kostas E. Bekris},
+title = {Machine Learning for Kinodynamic Planning (ML4KP)},
+howpublished = {\url{https://github.com/PRX-Kinodynamic/ML4KP}},
+year = {2021--2021}
+}
+
+
+
+@article{aradi2020survey,
+ title={Survey of deep reinforcement learning for motion planning of autonomous vehicles},
+ author={Aradi, Szil{\'a}rd},
+ journal={IEEE Transactions on Intelligent Transportation Systems},
+ year={2020},
+ publisher={IEEE}
+}
+
+@article{vianna2021neural,
+ title={Neural Network Based Model Predictive Control for an Autonomous Vehicle},
+ author={Vianna, Maria Luiza Costa and Goubault, Eric and Putot, Sylvie},
+ journal={arXiv preprint arXiv:2107.14573},
+ year={2021}
+}
+
+@article{qiu2021egocentric,
+ title={Egocentric Human Trajectory Forecasting with a Wearable Camera and Multi-Modal Fusion},
+ author={Qiu, Jianing and Chen, Lipeng and Gu, Xiao and Lo, Frank P-W and Tsai, Ya-Yen and Sun, Jiankai and Liu, Jiaqi and Lo, Benny},
+ journal={arXiv preprint arXiv:2111.00993},
+ year={2021}
+}
+
+@InProceedings{pmlr-v155-huang21a,
+ title = {Learning a Decision Module by Imitating Driver’s Control Behaviors},
+ author = {Huang, Junning and Xie, Sirui and Sun, Jiankai and Ma, Qiurui and Liu, Chunxiao and Lin, Dahua and Zhou, Bolei},
+ booktitle = {Proceedings of the 2020 Conference on Robot Learning},
+ pages = {1--10},
+ year = {2021},
+ editor = {Kober, Jens and Ramos, Fabio and Tomlin, Claire},
+ volume = {155},
+ series = {Proceedings of Machine Learning Research},
+ month = {16--18 Nov},
+ publisher = {PMLR},
+ pdf = {https://proceedings.mlr.press/v155/huang21a/huang21a.pdf},
+ url = {https://proceedings.mlr.press/v155/huang21a.html},
+ abstract = {Autonomous driving systems have a pipeline of perception, decision, planning, and control. The decision module processes information from the perception module and directs the execution of downstream planning and control modules. On the other hand, the recent success of deep learning suggests that this pipeline could be replaced by end-to-end neural control policies, however, safety cannot be well guaranteed for the data-driven neural networks. In this work, we propose a hybrid framework to learn neural decisions in the classical modular pipeline through end-to-end imitation learning. This hybrid framework can preserve the merits of the classical pipeline such as the strict enforcement of physical and logical constraints while learning complex driving decisions from data. To circumvent the ambiguous annotation of human driving decisions, our method learns high-level driving decisions by imitating low-level control behaviors. We show in the simulation experiments that our modular driving agent can generalize its driving decision and control to various complex scenarios where the rule-based programs fail. It can also generate smoother and safer driving trajectories than end-to-end neural policies. Demo and code are available at https://decisionforce.github.io/modulardecision/.}
+}
+
+
+@InProceedings{pmlr-v155-sun21a,
+ title = {Neuro-Symbolic Program Search for Autonomous Driving Decision Module Design},
+ author = {Sun, Jiankai and Sun, Hao and Han, Tian and Zhou, Bolei},
+ booktitle = {Proceedings of the 2020 Conference on Robot Learning},
+ pages = {21--30},
+ year = {2021},
+ editor = {Kober, Jens and Ramos, Fabio and Tomlin, Claire},
+ volume = {155},
+ series = {Proceedings of Machine Learning Research},
+ month = {16--18 Nov},
+ publisher = {PMLR},
+ pdf = {https://proceedings.mlr.press/v155/sun21a/sun21a.pdf},
+ url = {https://proceedings.mlr.press/v155/sun21a.html},
+ abstract = {As a promising topic in cognitive robotics, neuro-symbolic modeling integrates symbolic reasoning and neural representation altogether. However, previous neuro-symbolic models usually wire their structures and the connections manually, making the underlying parameters sub-optimal. In this work, we propose the Neuro-Symbolic Program Search (NSPS) to improve the autonomous driving system design. NSPS is a novel automated search method that synthesizes the Neuro-Symbolic Programs. It can produce robust and expressive Neuro-Symbolic Programs and automatically tune the hyper-parameters. We validate NSPS in the CARLA driving simulation environment. The resulting Neuro-Symbolic Decision Programs successfully handle multiple traffic scenarios. Compared with previous neural-network-based driving and rule-based methods, our neuro-symbolic driving pipeline achieves more stable and safer behaviors in complex driving scenarios while maintaining an interpretable symbolic decision-making process.}
+}
+
+@ARTICLE{9491826, author={Lu, Sidi and Shi, Weisong}, journal={IEEE Internet Computing}, title={The Emergence of Vehicle Computing}, year={2021}, volume={25}, number={3}, pages={18-22}, doi={10.1109/MIC.2021.3066076}}
+
+@article{benekohal1988carsim,
+ title={CARSIM: Car-following model for simulation of traffic in normal and stop-and-go conditions},
+ author={Benekohal, Rahim F and Treiterer, Joseph},
+ journal={Transportation research record},
+ volume={1194},
+ pages={99--111},
+ year={1988},
+ publisher={SAGE Publishing}
+}
+
+@book{buehler2009darpa,
+ title={The DARPA urban challenge: autonomous vehicles in city traffic},
+ author={Buehler, Martin and Iagnemma, Karl and Singh, Sanjiv},
+ volume={56},
+ year={2009},
+ publisher={springer}
+}
+
+
+@InProceedings{pmlr-v100-bansal20a,
+ title = {Combining Optimal Control and Learning for Visual Navigation in Novel Environments},
+ author = {Bansal, Somil and Tolani, Varun and Gupta, Saurabh and Malik, Jitendra and Tomlin, Claire},
+ booktitle = {Proceedings of the Conference on Robot Learning},
+ pages = {420--429},
+ year = {2020},
+ editor = {Kaelbling, Leslie Pack and Kragic, Danica and Sugiura, Komei},
+ volume = {100},
+ series = {Proceedings of Machine Learning Research},
+ month = {30 Oct--01 Nov},
+ publisher = {PMLR},
+ pdf = {http://proceedings.mlr.press/v100/bansal20a/bansal20a.pdf},
+ url = {https://proceedings.mlr.press/v100/bansal20a.html},
+ abstract = {Model-based control is a popular paradigm for robot navigation because it can leverage a known dynamics model to efficiently plan robust robot trajectories. However, it is challenging to use model-based methods in settings where the environment is a priori unknown and can only be observed partially through onboard sensors on the robot. In this work, we address this short-coming by coupling model-based control with learning-based perception. The learning-based perception module produces a series of waypoints that guide the robot to the goal via a collision-free path. These waypoints are used by a model-based planner to generate a smooth and dynamically feasible trajectory that is executed on the physical system using feedback control. Our experiments in simulated real-world cluttered environments and on an actual ground vehicle demonstrate that the proposed approach can reach goal locations more reliably and efficiently in novel environments as compared to purely geometric mapping-based or end-to-end learning-based alternatives. Our approach does not rely on detailed explicit 3D maps of the environment, works well with low frame rates, and generalizes well from simulation to the real world. Videos describing our approach and experiments are available on the project website4.}
+}
+
+@article{levine2018learning,
+ title={Learning hand-eye coordination for robotic grasping with deep learning and large-scale data collection},
+ author={Levine, Sergey and Pastor, Peter and Krizhevsky, Alex and Ibarz, Julian and Quillen, Deirdre},
+ journal={The International journal of robotics research},
+ volume={37},
+ number={4-5},
+ pages={421--436},
+ year={2018},
+ publisher={SAGE Publications Sage UK: London, England}
+}
+
+@incollection{peters2016robot,
+ title={Robot learning},
+ author={Peters, Jan and Lee, Daniel D and Kober, Jens and Nguyen-Tuong, Duy and Bagnell, J Andrew and Schaal, Stefan},
+ booktitle={Springer Handbook of Robotics},
+ pages={357--398},
+ year={2016},
+ publisher={Springer}
+}
+
+@article{saxena2014robobrain,
+ title={Robobrain: Large-scale knowledge engine for robots},
+ author={Saxena, Ashutosh and Jain, Ashesh and Sener, Ozan and Jami, Aditya and Misra, Dipendra K and Koppula, Hema S},
+ journal={arXiv preprint arXiv:1412.0691},
+ year={2014}
+}
+
+@inproceedings{zhu2017target,
+ title={Target-driven visual navigation in indoor scenes using deep reinforcement learning},
+ author={Zhu, Yuke and Mottaghi, Roozbeh and Kolve, Eric and Lim, Joseph J and Gupta, Abhinav and Fei-Fei, Li and Farhadi, Ali},
+ booktitle={2017 IEEE international conference on robotics and automation (ICRA)},
+ pages={3357--3364},
+ year={2017},
+ organization={IEEE}
+}
+
+@ARTICLE{9123682, author={Pan, Bowen and Sun, Jiankai and Leung, Ho Yin Tiga and Andonian, Alex and Zhou, Bolei}, journal={IEEE Robotics and Automation Letters}, title={Cross-View Semantic Segmentation for Sensing Surroundings}, year={2020}, volume={5}, number={3}, pages={4867-4873}, doi={10.1109/LRA.2020.3004325}}
+
+@article{tang2018ba,
+ title={Ba-net: Dense bundle adjustment network},
+ author={Tang, Chengzhou and Tan, Ping},
+ journal={arXiv preprint arXiv:1806.04807},
+ year={2018}
+}
+
+@inproceedings{tanaka2021learning,
+ title={Learning To Bundle-Adjust: A Graph Network Approach to Faster Optimization of Bundle Adjustment for Vehicular SLAM},
+ author={Tanaka, Tetsuya and Sasagawa, Yukihiro and Okatani, Takayuki},
+ booktitle={Proceedings of the IEEE/CVF International Conference on Computer Vision},
+ pages={6250--6259},
+ year={2021}
+}
+
+@inproceedings{tobin2017domain,
+ title={Domain randomization for transferring deep neural networks from simulation to the real world},
+ author={Tobin, Josh and Fong, Rachel and Ray, Alex and Schneider, Jonas and Zaremba, Wojciech and Abbeel, Pieter},
+ booktitle={2017 IEEE/RSJ international conference on intelligent robots and systems (IROS)},
+ pages={23--30},
+ year={2017},
+ organization={IEEE}
+}
+
+@inproceedings{finn2017deep,
+ title={Deep visual foresight for planning robot motion},
+ author={Finn, Chelsea and Levine, Sergey},
+ booktitle={2017 IEEE International Conference on Robotics and Automation (ICRA)},
+ pages={2786--2793},
+ year={2017},
+ organization={IEEE}
+}
+
+@article{duan2017one,
+ title={One-shot imitation learning},
+ author={Duan, Yan and Andrychowicz, Marcin and Stadie, Bradly and Jonathan Ho, OpenAI and Schneider, Jonas and Sutskever, Ilya and Abbeel, Pieter and Zaremba, Wojciech},
+ journal={Advances in neural information processing systems},
+ volume={30},
+ year={2017}
+}
+
+@book{koubaa2017robot,
+ title={Robot Operating System (ROS).},
+ author={Koub{\^a}a, Anis and others},
+ volume={1},
+ year={2017},
+ publisher={Springer}
+}
+
+@article{coleman2014reducing,
+ title={Reducing the barrier to entry of complex robotic software: a moveit! case study},
+ author={Coleman, David and Sucan, Ioan and Chitta, Sachin and Correll, Nikolaus},
+ journal={arXiv preprint arXiv:1404.3785},
+ year={2014}
+}
+
+@inproceedings{salzmann2020trajectron++,
+ title={Trajectron++: Dynamically-feasible trajectory forecasting with heterogeneous data},
+ author={Salzmann, Tim and Ivanovic, Boris and Chakravarty, Punarjay and Pavone, Marco},
+ booktitle={European Conference on Computer Vision},
+ pages={683--700},
+ year={2020},
+ organization={Springer}
+}
+
+@inproceedings{gog2021pylot,
+ title={Pylot: A modular platform for exploring latency-accuracy tradeoffs in autonomous vehicles},
+ author={Gog, Ionel and Kalra, Sukrit and Schafhalter, Peter and Wright, Matthew A and Gonzalez, Joseph E and Stoica, Ion},
+ booktitle={2021 IEEE International Conference on Robotics and Automation (ICRA)},
+ pages={8806--8813},
+ year={2021},
+ organization={IEEE}
+}
+
+@inproceedings{Dosovitskiy17,
+ title = { {CARLA}: {An} Open Urban Driving Simulator},
+ author = {Alexey Dosovitskiy and German Ros and Felipe Codevilla and Antonio Lopez and Vladlen Koltun},
+ booktitle = {Proceedings of the 1st Annual Conference on Robot Learning},
+ pages = {1--16},
+ year = {2017}
+}
+
+@inproceedings{10.1145/3492321.3519576,
+author = {Gog, Ionel and Kalra, Sukrit and Schafhalter, Peter and Gonzalez, Joseph E. and Stoica, Ion},
+title = {D3: A Dynamic Deadline-Driven Approach for Building Autonomous Vehicles},
+year = {2022},
+isbn = {9781450391627},
+publisher = {Association for Computing Machinery},
+address = {New York, NY, USA},
+url = {https://doi.org/10.1145/3492321.3519576},
+doi = {10.1145/3492321.3519576},
+abstract = {Autonomous vehicles (AVs) must drive across a variety of challenging environments that impose continuously-varying deadlines and runtime-accuracy tradeoffs on their software pipelines. A deadline-driven execution of such AV pipelines requires a new class of systems that enable the computation to maximize accuracy under dynamically-varying deadlines. Designing these systems presents interesting challenges that arise from combining ease-of-development of AV pipelines with deadline specification and enforcement mechanisms.Our work addresses these challenges through D3 (Dynamic Deadline-Driven), a novel execution model that centralizes the deadline management, and allows applications to adjust their computation by modeling missed deadlines as exceptions. Further, we design and implement ERDOS, an open-source realization of D3 for AV pipelines that exposes finegrained execution events to applications, and provides mechanisms to speculatively execute computation and enforce deadlines between an arbitrary set of events. Finally, we address the crucial lack of AV benchmarks through our state-of-the-art open-source AV pipeline, Pylot, that works seamlessly across simulators and real AVs. We evaluate the efficacy of D3 and ERDOS by driving Pylot across challenging driving scenarios spanning 50km, and observe a 68% reduction in collisions as compared to prior execution models.},
+booktitle = {Proceedings of the Seventeenth European Conference on Computer Systems},
+pages = {453–471},
+numpages = {19},
+location = {Rennes, France},
+series = {EuroSys '22}
+}
+
+@article{li2021metadrive,
+ author = {Li, Quanyi and Peng, Zhenghao and Xue, Zhenghai and Zhang, Qihang and Zhou, Bolei},
+ journal = {ArXiv preprint},
+ title = {Metadrive: Composing diverse driving scenarios for generalizable reinforcement learning},
+ url = {https://arxiv.org/abs/2109.12674},
+ volume = {abs/2109.12674},
+ year = {2021}
+}
+
+@article{peng2021learning,
+ author = {Peng, Zhenghao and Li, Quanyi and Hui, Ka Ming and Liu, Chunxiao and Zhou, Bolei},
+ journal = {Advances in Neural Information Processing Systems},
+ title = {Learning to Simulate Self-Driven Particles System with Coordinated Policy Optimization},
+ volume = {34},
+ year = {2021}
+}
+
+
+@inproceedings{peng2021safe,
+ author = {Peng, Zhenghao and Li, Quanyi and Liu, Chunxiao and Zhou, Bolei},
+ booktitle = {5th Annual Conference on Robot Learning},
+ title = {Safe Driving via Expert Guided Policy Optimization},
+ year = {2021}
+}
+
+@ARTICLE{8421746, author={Qin, Tong and Li, Peiliang and Shen, Shaojie}, journal={IEEE Transactions on Robotics}, title={VINS-Mono: A Robust and Versatile Monocular Visual-Inertial State Estimator}, year={2018}, volume={34}, number={4}, pages={1004-1020}, doi={10.1109/TRO.2018.2853729}}
+
+@article{campos2021orb,
+ title={Orb-slam3: An accurate open-source library for visual, visual--inertial, and multimap slam},
+ author={Campos, Carlos and Elvira, Richard and Rodr{\'\i}guez, Juan J G{\'o}mez and Montiel, Jos{\'e} MM and Tard{\'o}s, Juan D},
+ journal={IEEE Transactions on Robotics},
+ volume={37},
+ number={6},
+ pages={1874--1890},
+ year={2021},
+ publisher={IEEE}
+}
+
+@inproceedings{li2021efficient,
+ author = {Li, Quanyi and Peng, Zhenghao and Zhou, Bolei},
+ booktitle = {International Conference on Learning Representations},
+ title = {Efficient Learning of Safe Driving Policy via Human-AI Copilot Optimization},
+ year = {2021}
+}
+
+@article{chaplot2020learning,
+ title={Learning to explore using active neural slam},
+ author={Chaplot, Devendra Singh and Gandhi, Dhiraj and Gupta, Saurabh and Gupta, Abhinav and Salakhutdinov, Ruslan},
+ journal={arXiv preprint arXiv:2004.05155},
+ year={2020}
+}
+
+@article{teed2021droid,
+ title={Droid-slam: Deep visual slam for monocular, stereo, and rgb-d cameras},
+ author={Teed, Zachary and Deng, Jia},
+ journal={Advances in Neural Information Processing Systems},
+ volume={34},
+ year={2021}
+}
+
+@article{brunke2021safe,
+ title={Safe learning in robotics: From learning-based control to safe reinforcement learning},
+ author={Brunke, Lukas and Greeff, Melissa and Hall, Adam W and Yuan, Zhaocong and Zhou, Siqi and Panerati, Jacopo and Schoellig, Angela P},
+ journal={Annual Review of Control, Robotics, and Autonomous Systems},
+ volume={5},
+ year={2021},
+ publisher={Annual Reviews}
+}
+
+
+@InProceedings{pmlr-v144-gama21a,
+ title = {Graph Neural Networks for Distributed Linear-Quadratic Control},
+ author = {Gama, Fernando and Sojoudi, Somayeh},
+ booktitle = {Proceedings of the 3rd Conference on Learning for Dynamics and Control},
+ pages = {111--124},
+ year = {2021},
+ editor = {Jadbabaie, Ali and Lygeros, John and Pappas, George J. and A. Parrilo, Pablo and Recht, Benjamin and Tomlin, Claire J. and Zeilinger, Melanie N.},
+ volume = {144},
+ series = {Proceedings of Machine Learning Research},
+ month = {07 -- 08 June},
+ publisher = {PMLR},
+ pdf = {http://proceedings.mlr.press/v144/gama21a/gama21a.pdf},
+ url = {https://proceedings.mlr.press/v144/gama21a.html},
+ abstract = {The linear-quadratic controller is one of the fundamental problems in control theory. The optimal solution is a linear controller that requires access to the state of the entire system at any given time. When considering a network system, this renders the optimal controller a centralized one. The interconnected nature of a network system often demands a distributed controller, where different components of the system are controlled based only on local information. Unlike the classical centralized case, obtaining the optimal distributed controller is usually an intractable problem. Thus, we adopt a graph neural network (GNN) as a parametrization of distributed controllers. GNNs are naturally local and have distributed architectures, making them well suited for learning nonlinear distributed controllers. By casting the linear-quadratic problem as a self-supervised learning problem, we are able to find the best GNN-based distributed controller. We also derive sufficient conditions for the resulting closed-loop system to be stable. We run extensive simulations to study the performance of GNN-based distributed controllers and showcase that they are a computationally efficient parametrization with scalability and transferability capabilities.}
+}
+
+
+@InProceedings{pmlr-v144-mehrjou21a,
+ title = {Neural Lyapunov Redesign},
+ author = {Mehrjou, Arash and Ghavamzadeh, Mohammad and Sch\"olkopf, Bernhard},
+ booktitle = {Proceedings of the 3rd Conference on Learning for Dynamics and Control},
+ pages = {459--470},
+ year = {2021},
+ editor = {Jadbabaie, Ali and Lygeros, John and Pappas, George J. and A. Parrilo, Pablo and Recht, Benjamin and Tomlin, Claire J. and Zeilinger, Melanie N.},
+ volume = {144},
+ series = {Proceedings of Machine Learning Research},
+ month = {07 -- 08 June},
+ publisher = {PMLR},
+ pdf = {http://proceedings.mlr.press/v144/mehrjou21a/mehrjou21a.pdf},
+ url = {https://proceedings.mlr.press/v144/mehrjou21a.html},
+ abstract = {Learning controllers merely based on a performance metric has been proven effective in many physical and non-physical tasks in both control theory and reinforcement learning. However, in practice, the controller must guarantee some notion of safety to ensure that it does not harm either the agent or the environment. Stability is a crucial notion of safety, whose violation can certainly cause unsafe behaviors. Lyapunov functions are effective tools to assess stability in nonlinear dynamical systems. In this paper, we combine an improving Lyapunov function with automatic controller synthesis in an iterative fashion to obtain control policies with large safe regions. We propose a two-player collaborative algorithm that alternates between estimating a Lyapunov function and deriving a controller that gradually enlarges the stability region of the closed-loop system. We provide theoretical results on the class of systems that can be treated with the proposed algorithm and empirically evaluate the effectiveness of our method using an exemplary dynamical system.}
+}
+
+
+@InProceedings{pmlr-v144-zhang21b,
+ title = {{LEOC}: A Principled Method in Integrating Reinforcement Learning and Classical Control Theory},
+ author = {Zhang, Naifu and Capel, Nicholas},
+ booktitle = {Proceedings of the 3rd Conference on Learning for Dynamics and Control},
+ pages = {689--701},
+ year = {2021},
+ editor = {Jadbabaie, Ali and Lygeros, John and Pappas, George J. and A. Parrilo, Pablo and Recht, Benjamin and Tomlin, Claire J. and Zeilinger, Melanie N.},
+ volume = {144},
+ series = {Proceedings of Machine Learning Research},
+ month = {07 -- 08 June},
+ publisher = {PMLR},
+ pdf = {http://proceedings.mlr.press/v144/zhang21b/zhang21b.pdf},
+ url = {https://proceedings.mlr.press/v144/zhang21b.html},
+ abstract = {There have been attempts in reinforcement learning to exploit a priori knowledge about the structure of the system. This paper proposes a hybrid reinforcement learning controller which dynamically interpolates a model-based linear controller and an arbitrary differentiable policy. The linear controller is designed based on local linearised model knowledge, and stabilises the system in a neighbourhood about an operating point. The coefficients of interpolation between the two controllers are determined by a scaled distance function measuring the distance between the current state and the operating point. The overall hybrid controller is proven to maintain the stability guarantee around the neighborhood of the operating point and still possess the universal function approximation property of the arbitrary non-linear policy. Learning has been done on both model-based (PILCO) and model-free (DDPG) frameworks. Simulation experiments performed in OpenAI gym demonstrate stability and robustness of the proposed hybrid controller. This paper thus introduces a principled method allowing for the direct importing of control methodology into reinforcement learning.}
+}
+
+
+@InProceedings{pmlr-v144-rafailov21a,
+ title = {Offline Reinforcement Learning from Images with Latent Space Models},
+ author = {Rafailov, Rafael and Yu, Tianhe and Rajeswaran, Aravind and Finn, Chelsea},
+ booktitle = {Proceedings of the 3rd Conference on Learning for Dynamics and Control},
+ pages = {1154--1168},
+ year = {2021},
+ editor = {Jadbabaie, Ali and Lygeros, John and Pappas, George J. and A. Parrilo, Pablo and Recht, Benjamin and Tomlin, Claire J. and Zeilinger, Melanie N.},
+ volume = {144},
+ series = {Proceedings of Machine Learning Research},
+ month = {07 -- 08 June},
+ publisher = {PMLR},
+ pdf = {http://proceedings.mlr.press/v144/rafailov21a/rafailov21a.pdf},
+ url = {https://proceedings.mlr.press/v144/rafailov21a.html},
+ abstract = {Offline reinforcement learning (RL) refers to the task of learning policies from a static dataset of environment interactions. Offline RL enables extensive utilization and re-use of historical datasets, while also alleviating safety concerns associated with online exploration, thereby expanding the real-world applicability of RL. Most prior work in offline RL has focused on tasks with compact state representations. However, the ability to learn directly from rich observation spaces like images is critical for real-world applications like robotics. In this work, we build on recent advances in model-based algorithms for offline RL, and extend them to high-dimensional visual observation spaces. Model-based offline RL algorithms have achieved state of the art results in state based tasks and are minimax optimal. However, they rely crucially on the ability to quantify uncertainty in the model predictions. This is particularly challenging with image observations. To overcome this challenge, we propose to learn a latent-state dynamics model, and represent the uncertainty in the latent space. Our approach is both tractable in practice and corresponds to maximizing a lower bound of the ELBO in the unknown POMDP. Through experiments on a range of challenging image-based locomotion and robotic manipulation tasks, we find that our algorithm significantly outperforms previous offline model-free RL methods as well as state-of-the-art online visual model-based RL methods. Moreover, we also find that our approach excels on an image-based drawer closing task on a real robot using a pre-existing dataset. All results including videos can be found online at \url{https://sites.google.com/view/lompo/}.}
+}
+
+@inproceedings{chen2020transferable,
+ title={Transferable active grasping and real embodied dataset},
+ author={Chen, Xiangyu and Ye, Zelin and Sun, Jiankai and Fan, Yuda and Hu, Fang and Wang, Chenxi and Lu, Cewu},
+ booktitle={2020 IEEE International Conference on Robotics and Automation (ICRA)},
+ pages={3611--3618},
+ year={2020},
+ organization={IEEE}
+}
+
+@article{sun2021adversarial,
+ title={Adversarial inverse reinforcement learning with self-attention dynamics model},
+ author={Sun, Jiankai and Yu, Lantao and Dong, Pinqian and Lu, Bo and Zhou, Bolei},
+ journal={IEEE Robotics and Automation Letters},
+ volume={6},
+ number={2},
+ pages={1880--1886},
+ year={2021},
+ publisher={IEEE}
+}
+
+@article{huang2018navigationnet,
+ title={NavigationNet: A large-scale interactive indoor navigation dataset},
+ author={Huang, He and Shen, Yujing and Sun, Jiankai and Lu, Cewu},
+ journal={arXiv preprint arXiv:1808.08374},
+ year={2018}
+}
+
+@inproceedings{xu2019depth,
+ title={Depth completion from sparse lidar data with depth-normal constraints},
+ author={Xu, Yan and Zhu, Xinge and Shi, Jianping and Zhang, Guofeng and Bao, Hujun and Li, Hongsheng},
+ booktitle={Proceedings of the IEEE/CVF International Conference on Computer Vision},
+ pages={2811--2820},
+ year={2019}
+}
+
+@inproceedings{zhu2020ssn,
+ title={Ssn: Shape signature networks for multi-class object detection from point clouds},
+ author={Zhu, Xinge and Ma, Yuexin and Wang, Tai and Xu, Yan and Shi, Jianping and Lin, Dahua},
+ booktitle={European Conference on Computer Vision},
+ pages={581--597},
+ year={2020},
+ organization={Springer}
+}
+
+@inproceedings{huang2019prior,
+ title={Prior guided dropout for robust visual localization in dynamic environments},
+ author={Huang, Zhaoyang and Xu, Yan and Shi, Jianping and Zhou, Xiaowei and Bao, Hujun and Zhang, Guofeng},
+ booktitle={Proceedings of the IEEE/CVF International Conference on Computer Vision},
+ pages={2791--2800},
+ year={2019}
+}
+
+@article{xu2020selfvoxelo,
+ title={Selfvoxelo: Self-supervised lidar odometry with voxel-based deep neural networks},
+ author={Xu, Yan and Huang, Zhaoyang and Lin, Kwan-Yee and Zhu, Xinge and Shi, Jianping and Bao, Hujun and Zhang, Guofeng and Li, Hongsheng},
+ journal={arXiv preprint arXiv:2010.09343},
+ year={2020}
+}
+
+@article{huang2021life,
+ title={LIFE: Lighting Invariant Flow Estimation},
+ author={Huang, Zhaoyang and Pan, Xiaokun and Xu, Runsen and Xu, Yan and Zhang, Guofeng and Li, Hongsheng and others},
+ journal={arXiv preprint arXiv:2104.03097},
+ year={2021}
+}
+
+@inproceedings{huang2021vs,
+ title={VS-Net: Voting with Segmentation for Visual Localization},
+ author={Huang, Zhaoyang and Zhou, Han and Li, Yijin and Yang, Bangbang and Xu, Yan and Zhou, Xiaowei and Bao, Hujun and Zhang, Guofeng and Li, Hongsheng},
+ booktitle={Proceedings of the IEEE/CVF Conference on Computer Vision and Pattern Recognition},
+ pages={6101--6111},
+ year={2021}
+}
+
+@article{yang2021pdnet,
+ title={PDNet: Towards Better One-stage Object Detection with Prediction Decoupling},
+ author={Yang, Li and Xu, Yan and Wang, Shaoru and Yuan, Chunfeng and Zhang, Ziqi and Li, Bing and Hu, Weiming},
+ journal={arXiv preprint arXiv:2104.13876},
+ year={2021}
+}
+
+@article{xu2022robust,
+ title={Robust Self-supervised LiDAR Odometry via Representative Structure Discovery and 3D Inherent Error Modeling},
+ author={Xu, Yan and Lin, Junyi and Shi, Jianping and Zhang, Guofeng and Wang, Xiaogang and Li, Hongsheng},
+ journal={IEEE Robotics and Automation Letters},
+ year={2022},
+ publisher={IEEE}
+}
+
+@article{xu2022rnnpose,
+ title={RNNPose: Recurrent 6-DoF Object Pose Refinement with Robust Correspondence Field Estimation and Pose Optimization},
+ author={Xu, Yan and Lin, Junyi and Zhang, Guofeng and Wang, Xiaogang and Li, Hongsheng},
+ journal={arXiv preprint arXiv:2203.12870},
+ year={2022}
+}
+
+@article{Sun2022SelfSupervisedTA,
+ title={Self-Supervised Traffic Advisors: Distributed, Multi-view Traffic Prediction for Smart Cities},
+ author={Jiankai Sun and Shreyas Kousik and David Fridovich-Keil and Mac Schwager},
+ journal={arXiv preprint},
+ year={2022}
+}
diff --git a/static/favicon.png b/static/favicon.png
index ae6cec9..4ab345b 100644
Binary files a/static/favicon.png and b/static/favicon.png differ
diff --git a/static/logo-with-text.png b/static/logo-with-text.png
new file mode 100644
index 0000000..ee55e2d
Binary files /dev/null and b/static/logo-with-text.png differ
diff --git a/static/logo.png b/static/logo.png
index ae6cec9..bcd6e7a 100644
Binary files a/static/logo.png and b/static/logo.png differ
diff --git a/tools/contribution_analysis.py b/tools/contribution_analysis.py
new file mode 100644
index 0000000..36f96ca
--- /dev/null
+++ b/tools/contribution_analysis.py
@@ -0,0 +1,42 @@
+import requests
+import csv
+
+def analysis_issue():
+ total_data = []
+ for page_num in range(20):
+ print(f"Pulling page {page_num}")
+ response = requests.get('https://api.github.com/repos/openmlsys/openmlsys-zh/issues', params={"state": "all", "per_page": 30, "page": page_num})
+ print(f"Result status: {response}")
+ data = response.json()
+ if len(data) == 0:
+ break
+ total_data += data
+
+ all_issues = []
+ node_ids = set([])
+ for item in total_data:
+ if isinstance(item, dict):
+ if item["node_id"] not in node_ids:
+ all_issues.append([item["user"]["login"], item["author_association"], 1, [item["url"].split("/")[-1]]])
+ node_ids.add(item["node_id"])
+ print(f"All issues and pr count {len(all_issues)}")
+ total_count = {}
+ for issue_item in all_issues:
+ if total_count.get(issue_item[0], None) is None:
+ total_count[issue_item[0]] = issue_item
+ else:
+ total_count[issue_item[0]][-2] += 1
+ total_count[issue_item[0]][-1] += issue_item[-1]
+
+ keys = sorted(total_count, key=lambda x: total_count[x][-2])
+
+ final_res = []
+ for key in keys:
+ total_count[key][-1] = ",".join(total_count[key][-1])
+ final_res.append(total_count[key])
+
+ res_file = open("contribution_stats.csv", "w")
+ csv_writer = csv.writer(res_file)
+ csv_writer.writerow(["github id", "role", "issue and pr count", "issue or pr ids"])
+ csv_writer.writerows(final_res)
+analysis_issue()
\ No newline at end of file