cmd_argument_en.md 6.3 KB
Newer Older
Y
Yancey 已提交
1
# Command-line arguments
Z
zhangjinchao01 已提交
2

3 4
We'll take `doc/howto/cluster/src/word2vec` as an example to introduce distributed training using PaddlePaddle v2 API.

Y
Yancey 已提交
5
## Starting parameter server
Z
zhangjinchao01 已提交
6

武毅 已提交
7
Type the below command to start a parameter server which will wait for trainers to connect:
Z
zhangjinchao01 已提交
8

武毅 已提交
9
```bash
Y
Yancey 已提交
10
$ paddle pserver --port=7164 --ports_num=1 --ports_num_for_sparse=1 --num_gradient_servers=1 --nics=eth0
武毅 已提交
11
```
Z
zhangjinchao01 已提交
12

武毅 已提交
13
If you wish to run parameter servers in background, and save a log file, you can type:
Y
Yancey 已提交
14

武毅 已提交
15
```bash
Y
Yancey 已提交
16
$ stdbuf -oL /usr/bin/nohup paddle pserver --port=7164 --ports_num=1 --ports_num_for_sparse=1 --num_gradient_servers=1 --nics=eth0 &> pserver.log &
武毅 已提交
17
```
Z
zhangjinchao01 已提交
18

T
typhoonzero 已提交
19 20 21 22
Parameter Description

- port: **required, default 7164**, port which parameter server will listen on. If ports_num greater than 1, parameter server will listen on multiple ports for more network throughput.
- ports_num: **required, default 1**, total number of ports will listen on.
23
- ports_num_for_sparse: **required, default 0**, number of ports which serves sparse parameter update.
T
typhoonzero 已提交
24
- num_gradient_servers: **required, default 1**, total number of gradient servers.
Y
Yancey 已提交
25 26 27
- nics: **optional, default xgbe0,xgbe1**, network device name which paramter server will listen on.

## Starting trainer
Z
zhangjinchao01 已提交
28

武毅 已提交
29
Type the command below to start the trainer(name the file whatever you want, like "train.py")
Z
zhangjinchao01 已提交
30

武毅 已提交
31 32 33
```bash
$ python train.py
```
Z
zhangjinchao01 已提交
34

武毅 已提交
35
Trainers' network need to be connected with parameter servers' network to finish the job. Trainers need to know port and IPs to locate parameter servers. You can pass arguments to trainers through [environment variables](https://en.wikipedia.org/wiki/Environment_variable) or pass to `paddle.init()` function. Arguments passed to the `paddle.init()` function will overwrite environment variables.
Z
zhangjinchao01 已提交
36

武毅 已提交
37
Use environment viriables:
Z
zhangjinchao01 已提交
38

武毅 已提交
39 40 41 42 43 44 45 46 47 48 49
```bash
export PADDLE_INIT_USE_GPU=False
export PADDLE_INIT_TRAINER_COUNT=1
export PADDLE_INIT_PORT=7164
export PADDLE_INIT_PORTS_NUM=1
export PADDLE_INIT_PORTS_NUM_FOR_SPARSE=1
export PADDLE_INIT_NUM_GRADIENT_SERVERS=1
export PADDLE_INIT_TRAINER_ID=0
export PADDLE_INIT_PSERVERS=127.0.0.1
python train.py
```
Z
zhangjinchao01 已提交
50

武毅 已提交
51
Pass arguments:
Z
zhangjinchao01 已提交
52

武毅 已提交
53 54 55 56 57 58 59 60 61 62
```python
paddle.init(
        use_gpu=False,
        trainer_count=1,
        port=7164,
        ports_num=1,
        ports_num_for_sparse=1,
        num_gradient_servers=1,
        trainer_id=0,
        pservers="127.0.0.1")
Z
zhangjinchao01 已提交
63
```
武毅 已提交
64

T
typhoonzero 已提交
65 66 67
Parameter Description

- use_gpu: **optional, default False**, set to "True" to enable GPU training.
G
gongweibao 已提交
68
- trainer_count: **required, default 1**, number of threads in current trainer.
T
typhoonzero 已提交
69 70
- port: **required, default 7164**, port to connect to parameter server.
- ports_num: **required, default 1**, number of ports for communication.
71
- ports_num_for_sparse: **required, default 0**, number of ports for sparse type caculation.
G
gongweibao 已提交
72
- num_gradient_servers: **required, default 1**, number of trainers in current job.
T
typhoonzero 已提交
73 74
- trainer_id: **required, default 0**, ID for every trainer, start from 0.
- pservers: **required, default 127.0.0.1**, list of IPs of parameter servers, separated by ",".
武毅 已提交
75

Y
Yancey 已提交
76
## Prepare Training Dataset
武毅 已提交
77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93

Here's some example code [prepare.py](https://github.com/PaddlePaddle/Paddle/tree/develop/doc/howto/usage/cluster/src/word2vec/prepare.py), it will download public `imikolov` dataset and split it into multiple files according to job parallelism(trainers count). Modify `SPLIT_COUNT` at the begining of `prepare.py` to change the count of output files.

In the real world, we often use `MapReduce` job's output as training data, so there will be lots of files. You can use `mod` to assign training file to trainers:

```python
import os
train_list = []
flist = os.listdir("/train_data/")
for f in flist:
  suffix = int(f.split("-")[1])
  if suffix % TRAINER_COUNT == TRAINER_ID:
    train_list.append(f)
```

Example code `prepare.py` will split training data and testing data into 3 files with digital suffix like `-00000`, `-00001` and`-00002`:

Y
Yancey 已提交
94
```bash
武毅 已提交
95 96 97 98 99 100 101 102
train.txt
train.txt-00000
train.txt-00001
train.txt-00002
test.txt
test.txt-00000
test.txt-00001
test.txt-00002
Z
zhangjinchao01 已提交
103 104
```

武毅 已提交
105
When job started, every trainer needs to get it's own part of data. In some distributed systems a storage service will be provided, so the date under that path can be accessed by all the trainer nodes. Without the storage service, you must copy the training data to each trainer node.
Z
zhangjinchao01 已提交
106

武毅 已提交
107
Different training jobs may have different data format and `reader()` function, developers may need to write different data prepare scripts and `reader()` functions for their job.
Z
zhangjinchao01 已提交
108

Y
Yancey 已提交
109
## Prepare Training program
110

武毅 已提交
111
We'll create a *workspace* directory on each node, storing your training program, dependencies, mounted or downloaded dataset directory.
Z
zhangjinchao01 已提交
112

武毅 已提交
113
Your workspace may looks like:
Y
Yancey 已提交
114 115

```bash
武毅 已提交
116 117 118 119 120 121 122 123 124 125 126 127 128
.
|-- my_lib.py
|-- word_dict.pickle
|-- train.py
|-- train_data_dir/
|   |-- train.txt-00000
|   |-- train.txt-00001
|   |-- train.txt-00002
`-- test_data_dir/
    |-- test.txt-00000
    |-- test.txt-00001
    `-- test.txt-00002
```
Z
zhangjinchao01 已提交
129

武毅 已提交
130 131
- `my_lib.py`: user defined libraries, like PIL libs. This is optional.
- `word_dict.pickle`: dict file for training word embeding.
T
typhoonzero 已提交
132
- `train.py`: training program. Sample code: [api_train_v2_cluster.py](https://github.com/PaddlePaddle/Paddle/tree/develop/doc/howto/usage/cluster/src/word2vec/api_train_v2_cluster.py). ***NOTE:*** You may need to modify the head part of `train.py` when using different cluster platform to retrive configuration environment variables:
Z
zhangjinchao01 已提交
133

武毅 已提交
134 135 136 137 138 139 140
  ```python
  cluster_train_file = "./train_data_dir/train/train.txt"
  cluster_test_file = "./test_data_dir/test/test.txt"
  node_id = os.getenv("OMPI_COMM_WORLD_RANK")
  if not node_id:
      raise EnvironmentError("must provied OMPI_COMM_WORLD_RANK")
  ```
Z
zhangjinchao01 已提交
141

武毅 已提交
142 143
- `train_data_dir`: containing training data. Mount from storage service or copy trainning data to here.
- `test_data_dir`: containing testing data.
Y
Yancey 已提交
144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161

## Async SGD Update

We can set some parameters of the optimizer to make it support async SGD update.
For example, we can set the `is_async` and `async_lagged_grad_discard_ratio` of the `AdaGrad` optimizer:

```python
adagrad = paddle.optimizer.AdaGrad(
    is_async=True,
    async_lagged_grad_discard_ratio=1.6,
    learning_rate=3e-3,
    regularization=paddle.optimizer.L2Regularization(8e-4))
```

- `is_async`: Is Async-SGD or not.
- `async_lagged_grad_discard_ratio`: For async SGD gradient commit control.
  when `async_lagged_grad_discard_ratio * num_gradient_servers` commit passed,
  current async gradient will be discard silently.