data_dispatch.md 5.6 KB
Newer Older
T
typhoonzero 已提交
1 2
## 训练数据的存储和分发

G
gongweibao 已提交
3 4
### 概念解释

T
typhoonzero 已提交
5
### 流程介绍
T
typhoonzero 已提交
6
生产环境中的训练数据集通常体积很大,并被存储在诸如Hadoop HDFS,Ceph,AWS S3之类的分布式存储之上。这些分布式存储服务通常会把数据切割成多个分片分布式的存储在多个节点之上。这样就可以在云端执行多种数据类计算任务,包括:
T
typhoonzero 已提交
7 8 9 10

* 数据预处理任务
* Paddle训练任务
* 在线模型预测服务
G
gongweibao 已提交
11 12 13
<div style="align: center">
<img src="src/paddle-cloud-in-data-center.png" width="800"/>
</div>
T
typhoonzero 已提交
14

G
gongweibao 已提交
15
在上图中显示了在一个实际生产环境中的应用(人脸识别)的数据流图。生产环境的日志数据会通过实时流的方式(Kafka)和离线数据的方式(HDFS)存储,并在集群中运行多个分布式数据处理任务,比如流式数据处理(online data process),离线批处理(offline data process)完成数据的预处理,提供给paddle作为训练数据。用户也可以上传labeled data到分布式存储补充训练数据。在paddle之上运行的深度学习训练输出的模型会提供给在线人脸识别的应用使用。
T
typhoonzero 已提交
16

G
gongweibao 已提交
17 18
### 训练数据存储
我们选择[CephFS](http://docs.ceph.com/docs/master/cephfs/)作为存储系统。
T
typhoonzero 已提交
19

G
gongweibao 已提交
20
- 无论是从[PFSClient](../file_manager/README.md)的角度,还是从[Pod](https://kubernetes.io/docs/concepts/workloads/pods/pod/)中运行任务的角度,统一用`/pfs/$DATACENTER/home/$USER`来访问用户自己的数据。  
G
gongweibao 已提交
21
- `/pfs/$DATACENTER/common`下存放公共数据集合
G
gongweibao 已提交
22
	- 做只读挂载 
T
typhoonzero 已提交
23

G
gongweibao 已提交
24 25 26
<div style="align: center">
<img src="src/file_storage.png" width="700" align=center/>
</div>
T
typhoonzero 已提交
27

28
### 文件预处理
T
typhoonzero 已提交
29

G
gongweibao 已提交
30
在开始训练之前, 数据集需要预先被转换成PaddlePaddle分布式训练使用的存储格[RecordIO](https://github.com/PaddlePaddle/Paddle/issues/1947)。我们提供两个转换方式:
T
typhoonzero 已提交
31

32 33
- 提供给用户本地转换的库,用户可以编写程序完成转换。
- 用户可以上传自己的数据集,在集群运行MapReduce job完成转换。
T
typhoonzero 已提交
34

35
转换生成的文件名会是以下格式:
T
typhoonzero 已提交
36

37 38
```text
name_prefix-aaaaa-of-bbbbb
T
typhoonzero 已提交
39 40
```

41
"aaaaa"和"bbbbb"都是五位的数字,每一个文件是数据集的一个shard,"aaaaa"代表shard的index,"bbbbb"代表这个shard的最大index。
T
typhoonzero 已提交
42

43 44 45 46 47 48
比如ImageNet这个数据集可能被分成1000个shard,它们的文件名是:
```text
imagenet-00000-of-00999
imagenet-00001-of-00999
...
imagenet-00999-of-00999
T
typhoonzero 已提交
49 50
```

51 52 53 54 55
#### 转换库

无论是在本地或是云端转换,我们都提供Python的转换库,接口是:
```python
def convert(output_path, reader, num_shards, name_prefix)
T
typhoonzero 已提交
56 57
```

58 59 60 61
- `output_path`: directory in which output files will be saved.
- `reader`: a [data reader](https://github.com/PaddlePaddle/Paddle/blob/develop/doc/design/reader/README.md#data-reader-interface), from which the convert program will read data instances.
- `num_shards`: the number of shards that the dataset will be partitioned into.
- `name_prefix`: the name prefix of generated files.
T
typhoonzero 已提交
62

63
`reader`每次输出一个data instance,这个instance可以是单个值,或者用tuple表示的多个值:
T
typhoonzero 已提交
64 65

```python
66 67 68
yield 1 # 单个值
yield numpy.random.uniform(-1, 1, size=28*28) # 单个值
yield numpy.random.uniform(-1, 1, size=28*28), 0 # 多个值
T
typhoonzero 已提交
69
```
T
typhoonzero 已提交
70

71
每个值的类型可以是整形、浮点型数据、字符串,或者由它们组成的list,以及numpy.ndarray。如果是其它类型,会被Pickle序列化成字符串。
T
typhoonzero 已提交
72

73 74 75 76 77 78 79 80 81 82 83
### 示例程序

#### 使用转换库

以下`reader_creator`生成的`reader`每次输出一个data instance,每个data instance包涵两个值:numpy.ndarray类型的值和整型的值:
```python
def reader_creator():
	def reader():
		for i in range(1000):
			yield numpy.random.uniform(-1, 1, size=28*28), 0 # 多个值
	return reader
T
typhoonzero 已提交
84 85
```

86 87 88 89
`reader_creator`生成的`reader`传入`convert`函数即可完成转换:
```python
convert("./", reader_creator(), 100, random_images)
```
T
typhoonzero 已提交
90

91 92 93 94 95 96 97
以上命令会在当前目录下生成100个文件:
```text
random_images-00000-of-00099
random_images-00001-of-00099
...
random_images-00099-of-00099
```
Y
yi.wu 已提交
98

99
#### 进行训练
Y
yi.wu 已提交
100

G
gongweibao 已提交
101
PaddlePaddle提供专用的[data reader creator](https://github.com/PaddlePaddle/Paddle/blob/develop/doc/design/reader/README.md#python-data-reader-design-doc),生成给定`RecordIO`文件对应的data reader。**无论在本地还是在云端,reader的使用方式都是一致的**
Y
yi.wu 已提交
102

T
typhoonzero 已提交
103
```python
104
# ...
G
gongweibao 已提交
105
reader = paddle.reader.creator.RecordIO("/pfs/datacenter_name/home/user_name/random_images-*-of-*")
106 107
batch_reader = paddle.batch(paddle.dataset.mnist.train(), 128)
trainer.train(batch_reader, ...)
T
typhoonzero 已提交
108 109
```

110
以上代码的reader输出的data instance与生成数据集时,reader输出的data instance是一模一样的。
Y
yi.wu 已提交
111

112 113 114 115
### 上传训练文件

使用下面命令,可以把本地的数据上传到存储集群中。

G
gongweibao 已提交
116
```bash  
G
gongweibao 已提交
117
paddle pfs cp filename /pfs/$DATACENTER/home/$USER/folder/
118 119 120
```

比如,把之前示例中转换完毕的random_images数据集上传到云端的`/home/`可以用以下指令:
G
gongweibao 已提交
121 122

```bash  
G
gongweibao 已提交
123
paddle pfs cp random_images-*-of-* /pfs/$DATACENTER/home/$USER/folder/
124
```
G
gongweibao 已提交
125 126 127 128 129 130

需要`$DATACENTER`的配置写到配置文件中,例如

```
# config file
[datacenter_1]
G
gongweibao 已提交
131 132 133
username=user
usercert=user.pem
userkey=user-key.pem
G
gongweibao 已提交
134 135 136
endpoint=datacenter1.paddlepaddle.org

[datacenter_2]
G
gongweibao 已提交
137 138 139
username=user
usercert=user.pem
userkey=user-key.pem
G
gongweibao 已提交
140 141
endpoint=datacenter2.paddlepaddle.org
```
T
typhoonzero 已提交
142
## TODO
G
gongweibao 已提交
143
### 文件访问的权限
G
gongweibao 已提交
144 145
控制用户权限  

G
gongweibao 已提交
146 147 148 149 150
- 用户可以把自己的数据分享给别人

### 文件访问方式
不用mount的方式来访问数据,而是直接用API的接口远程访问

G
gongweibao 已提交
151 152
例如:  

G
gongweibao 已提交
153
```
G
gongweibao 已提交
154
f = open('/pfs/datacenter_name/home/user_name/test1.dat')
G
gongweibao 已提交
155 156
```

T
typhoonzero 已提交
157 158

### 支持用户自定义的数据预处理job