Skip to content

Commit

Permalink
add data science chapter
Browse files Browse the repository at this point in the history
add data science chapter
  • Loading branch information
luweizheng authored Jan 20, 2024
2 parents 9d0aede + a83275a commit 71d9349
Show file tree
Hide file tree
Showing 67 changed files with 68,723 additions and 1,349 deletions.
3 changes: 3 additions & 0 deletions _toc.yml
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,10 @@ subtrees:
- file: ch-intro/index
entries:
- file: ch-intro/computer-architecture
- file: ch-intro/serial-parallel
- file: ch-intro/thread-process
- file: ch-intro/parallel-program-design
- file: ch-intro/performance-metrics
- file: ch-data-science/index
entries:
- file: ch-data-science/data-science-lifecycle
Expand Down
5 changes: 1 addition & 4 deletions ch-dask-dataframe/read-write.ipynb
Original file line number Diff line number Diff line change
Expand Up @@ -85,10 +85,7 @@
" shutil.copyfileobj(response, out_file)\n",
" zf = ZipFile(zip_file_path, 'r')\n",
" zf.extractall(folder_path)\n",
" zf.close()\n",
" print(f\"数据已下载并解压到 {folder_path}\")\n",
"else:\n",
" print(f\"文件夹 {folder_path} 已存在,无需操作。\")"
" zf.close()"
]
},
{
Expand Down
Empty file removed ch-dask/dask-array.ipynb
Empty file.
2 changes: 1 addition & 1 deletion ch-dask/dask-dataframe-intro.ipynb
Original file line number Diff line number Diff line change
Expand Up @@ -754,7 +754,7 @@
"\n",
"至此,我们知道 Dask DataFrame 将大数据切分成了 Partition,并且延迟执行的。Dask 构建了 Task Graph,来分别对每个 Partition 进行了计算。\n",
"\n",
"执行 `compute()` 之前,Dask 构建的是一个计算图,可以用 `visualize()` 可视化计算图"
"执行 `compute()` 之前,Dask 构建的是一个计算图 Task Graph,用 `visualize()` 可视化 Task Graph"
]
},
{
Expand Down
8 changes: 4 additions & 4 deletions ch-dask/dask-distributed.ipynb
Original file line number Diff line number Diff line change
Expand Up @@ -4,19 +4,19 @@
"cell_type": "markdown",
"metadata": {},
"source": [
"(dask-distributed=)\n",
"(dask-distributed)=\n",
"# 将 Dask 扩展到集群\n",
"\n",
"刚刚的任务都是在单机场景下使用 Dask。`dask.distributed` 可以帮助我们把 Dask 任务扩展到多台计算节点。\n",
"\n",
"## Dask 集群\n",
"\n",
"如 {numref}`dask-distributed` 所示,一个 Dask 集群必须包含一个调度器(Scheduler)和多个工作节点(Worker)。用户通过客户端(Client)向调度器提交计算任务,调度器对任务进行分析,生成 Task Graph,并将 Task 分发到多个 Worker 上。每个 Worker 承担一小部分计算任务,Worker 之间也要互相通信,比如计算结果的归集等。\n",
"如 {numref}`dask-distributed-img` 所示,一个 Dask 集群必须包含一个调度器(Scheduler)和多个工作节点(Worker)。用户通过客户端(Client)向调度器提交计算任务,调度器对任务进行分析,生成 Task Graph,并将 Task 分发到多个 Worker 上。每个 Worker 承担一小部分计算任务,Worker 之间也要互相通信,比如计算结果的归集等。\n",
"\n",
"```{figure} ../img/ch-dask/dask-distributed.svg\n",
"---\n",
"width: 800px\n",
"name: dask-distributed\n",
"width: 600px\n",
"name: dask-distributed-img\n",
"---\n",
"Dask Distributed\n",
"```\n",
Expand Down
491 changes: 278 additions & 213 deletions ch-dask/task-graph-partitioning.ipynb

Large diffs are not rendered by default.

67,590 changes: 67,590 additions & 0 deletions ch-data-science/data-science-lifecycle.ipynb

Large diffs are not rendered by default.

51 changes: 0 additions & 51 deletions ch-data-science/data-science-lifecycle.md

This file was deleted.

2 changes: 1 addition & 1 deletion ch-data-science/index.md
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
# 数据科学背景知识
# 数据科学

Python 分布式编程主要服务于数据科学和人工智能等对高性能计算领域,本章主要介绍数据科学相关背景知识,如果相关基础较好,也可以直接跳过本章。

Expand Down
28 changes: 3 additions & 25 deletions ch-intro/computer-architecture.md
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
(multi-core-cluster-heterogeneous-computing)=
(computer-architecture)=
# 现代计算机体系结构

大数据与人工智能应用对算力要求极高,为应对飞速增长的算力需求,芯片与硬件厂商近年来重点发展多核、集群(Cluster)和异构计算(Heterogeneous Computing)。{numref}`computer-arch` 展示了现代计算机的体系结构。
Expand All @@ -23,30 +23,8 @@ name: computer-arch

## 网卡

单台计算机的计算能力有限,为搭建一个高速互联的集群,数据中心服务器之间通常配置了高速网络,比如 RoCE(RDMA over Converged Ethernet)或 InfiniBand。每台计算机上配有至少一块高速网卡,多台计算机之间通过光纤互联,以获得极低的延迟和极高的吞吐率。这样不同节点之间的通信就像在单个节点上进行计算一样
单台计算机的计算能力有限,为搭建一个高速互联的集群,数据中心服务器之间通常配置了高速网络,比如 RoCE(RDMA over Converged Ethernet)或 InfiniBand。每台计算机上配有至少一块高速网卡,多台计算机之间通过光纤互联,以获得极低的延迟和极高的吞吐率。这样不同节点之间互相访问数据就像在单个节点上进行一样

## 异构计算

在异构计算的框架下,CPU 和主存通常被称为主机(Host),各类专用的加速器被称为设备(Device)。尽管异构计算是一个很宽泛的概念,但当前基于 GPU 的异构计算是主流,尤其是以英伟达为代表的 GPU 占据了大量市场份额,所以这里主要以 GPU 为例介绍异构计算。GPU 有区别于 CPU 的芯片微架构和编译软件栈。软件层面,英伟达的 GPU 提供了 CUDA(Compute Unified Device Architecture)编程接口,硬件层面,GPU 有很多个专用计算核心(CUDA Core)和 GPU 上的存储。通常,数据从主存到 GPU 存储之间搬运有一定成本。其他加速器与英伟达 GPU 整体结构也很相似。

## 顺序执行与并行执行

如果不对计算任务(Task)进行并行加速,大部分计算任务是顺序执行的,即 {numref}`serial-timeline` 所示。这里的 Worker 可以是一个计算核心,也可以是集群中的一个节点。

```{figure} ../img/ch-intro/serial-timeline.svg
---
width: 600px
name: serial-timeline
---
顺序执行的时间轴示意图
```

集群和异构计算提供了更多可利用的计算核心,并行计算将计算任务分布到多个 Worker 上,如 {ref}`distributed-timeline` 所示。无论是在单机多核编程,还是在集群多机,都需要一个调度器(Scheduler)将计算任务分布到不同的 Worker 上。

```{figure} ../img/ch-intro/_distributed-timeline.svg
---
width: 600px
name: distributed-timeline
---
分布式执行的时间轴示意图
```
在异构计算的框架下,CPU 和主存通常被称为主机(Host),各类专用的加速器被称为设备(Device)。尽管异构计算是一个很宽泛的概念,但当前基于 GPU 的异构计算是主流,尤其是以英伟达为代表的 GPU 占据了大量市场份额,所以这里主要以 GPU 为例介绍异构计算。GPU 有区别于 CPU 的芯片微架构和编译软件栈。软件层面,英伟达的 GPU 提供了 CUDA(Compute Unified Device Architecture)编程接口,硬件层面,GPU 有很多个专用计算核心(CUDA Core)和 GPU 上的存储(GPU Memory)。通常,数据从主存到 GPU 存储之间搬运有一定时间成本。其他加速器与英伟达 GPU 整体结构也很相似。
54 changes: 54 additions & 0 deletions ch-intro/parallel-program-design.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
(parallel-program-design)=
# 并行程序设计方法

## PCAM

如何设计软件和算法,使得程序可以并行运行在多核或者集群上?早在 1995 年,Ian Foster 在其书中提出了 PCAM 方法 {cite}`foster1995designing`,其思想可以用来指导并行算法的设计。PCAM 主要有四个步骤:切分(Partitioning)、通信(Communication)、聚集(Agglomeration)和分发(Mapping);{numref}`pcam-img` 展示了这四个步骤。

```{figure} ../img/ch-intro/pcam.png
---
width: 400px
name: pcam-img
---
PCAM 方法
```

* Partitioning:将整个问题切分为多个子问题或子任务,切分既包括计算部分也包括数据部分。
* Communication:不同子任务之间通信方式,包括通信的数据结构、通信算法。
* Agglomeration:考虑到当前所拥有的硬件性能和编程难度,将上面两步进一步整合,将细粒度的任务整合成更高效的任务。
* Mapping:将整合好的任务分发给多个处理器。

比如,有一个超大矩阵,矩阵大小为 $M \times M$,这个矩阵大到无法放在单个计算节点上计算,现在想得到这个矩阵的最大值。设计并行算法时,可以考虑如下思路:

* 将矩阵切分成子矩阵,每个子矩阵 $m \times m$ 大小,在每台计算节点上执行 `max()` 函数求得子矩阵的最大值。
* 将每个子矩阵的最大值汇集到一个计算节点,再该节点再次执行一下 `max()` 求得整个矩阵的最大值。
* 子矩阵切分方式 $m \times m$ 可以在单个计算节点上运行,聚集值再次求最大值也可以在单给计算节点上运行。
* 将以上计算分发到多个节点。

## 切分方式

设计并行程序最困难也是最关键的部分是如何进行切分,常见的切分方式有:

* 任务并行:一个复杂的程序往往包含多个任务,将不同的任务交给不同的 Worker,如果任务之间没有太多复杂的依赖关系,这种方式可以很好地并发执行。
* 几何分解:所处理的数据结构化,比如矩阵可以根据一维或多维分开,分配给不同的 Worker,刚才提到的对矩阵求最大值就是一个例子。

## 案例:MapReduce

Google 2004 年提出 MapReduce {cite}`dean2004MapReduce`,这是一种典型的大数据并行计算范式。{numref}`map-reduce` 展示了使用 MapReduce 进行词频统计的处理方式。

```{figure} ../img/ch-intro/map-reduce.png
---
width: 600px
name: map-reduce
---
MapReduce 进行词频统计
```

MapReduce 中主要涉及四个阶段:

* 切分(Split):将大数据切分成很多份小数据,每份小数据可以在单个 Worker 上计算。
* 映射(Map):对每个小数据执行 Map 操作,Map 是一个函数映射,程序员需要自定义 Map 函数,Map 函数输出一个键值对(Key-Value)。在词频统计的例子中,每出现一个词,计 1 次,Key 是词,Value 是 1,表示出现 1 次。
* 交换(Shuffle):将相同的 Key 归结到相同的 Worker 上。这一步涉及数据交换。词频统计的例子中,将相同的词发送到同一个 Worker 上。
* 聚合(Reduce):所有相同的 Key 进行聚合操作,程序员需要自定义 Reduce 函数。词频统计的例子中,之前 Shuffle 阶段将已经将数据归结到了一起,现在只需要将所有词频求和。

MapReduce 的编程范式深刻影响了 Apache Hadoop、Apache Spark、Dask 等开源项目。
38 changes: 38 additions & 0 deletions ch-intro/performance-metrics.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
(performance-metrics)=
# 性能指标

为了客观地评估并行计算程序的性能,需要有一些标准。FLOPS 和加速比是最通用的指标,对于特定的问题,比如人工智能和大数据,也有一些特定的评测基准。

## FLOPS

传统的高性能计算经常使用 FLOPS(Floating Point OPerations per Second)来衡量软硬件的性能。

:::{note}
所谓浮点数,指的是计算机一定比特位数来表示小数。用更多的比特位数,数值越精确,精度越高,但计算的成本越高。业界已经形成了一些标准,电气电子工程师学会(Institute of Electrical and Electronics Engineers, IEEE)定义了 16 位浮点数(FP16)、32 位浮点数(FP32)和 64 位浮点数(FP64)在计算机中的表示方法。大部分科学计算任务需要 FP64,深度学习等任务只需要 FP32、FP16 甚至更低。严格意义上来讲,需要明确是 FP32 还是 FP64 精度下的 FLOPS。因为不同硬件所能提供的 FP32 和 FP64 算力有很大差异。
:::

FLOPS 指每秒钟能够完成多少次浮点计算。如果进行一个 $n$ 维向量加法:$a + b$,所需的浮点计算次数为 $n$。将浮点计算次数除以时间,就是 FLOPS。

FLOPS 指标既依赖于硬件性能,也与软件和算法高度相关。{numref}`thread-process` 提到线程安全问题,{numref}`serial-parallel` 中有任务分发的过程,如果软件算法设计不够好,大量计算资源闲置,应用程序的 FLOPS 可能很低。

## 加速比

理论上,并行程序应该比对应的串行程序更快,所用时间更短。执行时间的缩短可以用**加速比**来衡量:

$$
加速比 = \frac{t_s}{t_p}
$$

其中 $t_s$ 为串行程序执行时间,$t_p$ 为并行程序执行时间。

在加速比指标基础上,还有一种衡量方法,叫做**效率**

$$
效率 = \frac{加速比}{N} = \frac{t_s}{N \cdot {t_p}}
$$

其中 $N$ 为并行程序所使用的计算核心的数目。当加速比为 $N$ 时,串行程序可以被线性拓展到多个计算核心上,可以说并行程序获得了*线性加速比*

线性加速比是最理想的情况,实际上很难达到。{numref}`serial-parallel` 中的示意图中可以看到,并行程序需要有 Scheduler 将不同的任务分发到多个 Worker 上,多个 Worker 之间还要通信。

另外,在使用 GPU 时,计算效率指标的 $N$ 取值应该是多少也有一定争议。GPU 上的计算核心成千上万,我们很难在一个 GPU 计算核心上测试得到 $t_s$;GPU 与 CPU 是协同工作的,计算加速比或效率时,是否要把 CPU 考虑进来?
22 changes: 22 additions & 0 deletions ch-intro/serial-parallel.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
(serial-parallel)=
# 串行执行与并行执行

如果不对计算任务(Task)进行并行加速,大部分计算任务是串行执行的,即 {numref}`serial-timeline` 所示。这里的 Worker 可以是一个计算核心,也可以是集群中的一个节点。

```{figure} ../img/ch-intro/serial-timeline.svg
---
width: 600px
name: serial-timeline
---
串行执行的时间轴示意图
```

集群和异构计算提供了更多可利用的计算核心,并行计算将计算任务分布到多个 Worker 上,如 {numref}`distributed-timeline` 所示。无论是在单机多核编程,还是在集群多机,都需要一个调度器(Scheduler)将计算任务分布到不同的 Worker 上。随着更多 Worker 参与,任务总时间缩短,节省的时间可用于其他任务。

```{figure} ../img/ch-intro/distributed-timeline.svg
---
width: 600px
name: distributed-timeline
---
分布式执行的时间轴示意图
```
4 changes: 2 additions & 2 deletions ch-intro/thread-process.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ CPU、GPU、网卡等都是硬件层面上的概念,在软件层面,经常

## 进程与线程

CPU、GPU、网卡等都是被操作系统(Operating System,OS)管理的。操作系统一方面管理硬件,另一方面通过各类应用软件为用户提供服务。正在运行的软件就是进程(Process)。以个人的笔记本电脑为例,使用浏览器浏览网页时,操作系统创建了一个浏览器的进程;使用文本编辑软件 Word 编写文字内容时操作系统创建了一个 Word 进程。macOS 上的**活动监视器**如 {numref}`mac-process` 所示,和 Windows 上的**任务管理器**,都可以看到操作系统当前运行的进程,以及各个进程对 CPU、内存等资源的占用。
CPU、GPU、网卡等都是被操作系统(Operating System,OS)管理的。操作系统一方面管理硬件,另一方面通过各类应用软件为用户提供服务。正在运行的软件就是进程(Process)。以个人的笔记本电脑为例,使用浏览器浏览网页时,操作系统创建了一个浏览器的进程;使用文本编辑软件 Word 编写文字内容时,操作系统创建了一个 Word 进程。macOS 上的**活动监视器**如 {numref}`mac-process` 所示,和 Windows 上的**任务管理器**,都可以看到操作系统当前运行的进程,以及各个进程对 CPU、内存等资源的占用。

```{figure} ../img/ch-intro/mac-process.png
---
Expand All @@ -15,7 +15,7 @@ name: mac-process
进程和线程
```

技术层面上,操作系统管理所有进程的执行,为它们合理的分配资源:操作系统以进程为单位分配主存空间,每个进程都有自己的地址空间、数据栈等等。
技术层面上,操作系统管理所有进程的执行,为它们合理地分配资源:操作系统以进程为单位分配主存空间,每个进程都有自己的地址空间、数据栈等等。

大部分编程语言实现时,一个进程包含多个线程,即 {numref}`process-thread` 所示。每个线程运行在一个物理计算核心上,一个进程的多个线程可利用多个物理计算核心。

Expand Down
2 changes: 1 addition & 1 deletion contribute/info.md
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ git clone https://github.com/godaai/python-data-science.git
```bash
conda create -n dispy
source activate dispy
conda install python=3.11
conda install python=3.11 anaconda::graphviz
pip install -r requirements.txt
```

Expand Down
Loading

0 comments on commit 71d9349

Please sign in to comment.