pipedream

References

Item Instructions
github repo msr-fiddle/pipedream

Follow the ReadMe

按照ReadMe走完了实验,得到了VGG的一些结果。
实验的代码如下:

1
2
3
4
5
6
7
8
9
10
CUDA_VISIBLE_DEVICES=0 python main.py -a vgg16 -b 64 --data_dir <path to ImageNet directory>  # Profile

python optimizer_graph_hierarchical.py -f ../profiler/image_classification/profiles/vgg16/graph.txt -n 4 --activation_compression_ratio 1 -o vgg16_partitioned # Optimize

python convert_graph_to_model.py -f vgg16_partitioned/gpus=4.txt -n VGG16Partitioned -a vgg16 -o ../runtime/image_classification/models/vgg16/gpus=4 --stage_to_num_ranks 0:3,1:1 # Convert

python main_with_runtime.py --module models.vgg16.gpus=4 -b 64 --data_dir <path to ImageNet> --rank 0 --local_rank 0 --master_addr <master IP address> --config_path models/vgg16/gpus=4/hybrid_conf.json --distributed_backend gloo
python main_with_runtime.py --module models.vgg16.gpus=4 -b 64 --data_dir <path to ImageNet> --rank 0 --local_rank 0 --master_addr <master IP address> --config_path models/vgg16/gpus=4/hybrid_conf.json --distributed_backend gloo
python main_with_runtime.py --module models.vgg16.gpus=4 -b 64 --data_dir <path to ImageNet> --rank 0 --local_rank 0 --master_addr <master IP address> --config_path models/vgg16/gpus=4/hybrid_conf.json --distributed_backend gloo
python main_with_runtime.py --module models.vgg16.gpus=4 -b 64 --data_dir <path to ImageNet> --rank 0 --local_rank 0 --master_addr <master IP address> --config_path models/vgg16/gpus=4/hybrid_conf.json --distributed_backend gloo # Run

最后一步Run的时候,可以选择3个模式:数据并行、模型并行、混合并行模式。

其中混合并行模式的结果:

混合模式并行结果

hybrid_conf.json

1
2
3
4
{
"module_to_stage_map": [0, 1, 1],
"stage_to_rank_map": {"0": [0, 1, 2], "1": [3]}
}

内存占用
1
2
3
4
[2021-04-23 08:06:59.134] main_with_runtime.py line:373 [INFO] : Rank: [0]	Memory: 8.655 (11.075)
[2021-04-23 08:06:59.141] main_with_runtime.py line:373 [INFO] : Rank: [1] Memory: 8.655 (10.498)
[2021-04-23 08:06:59.176] main_with_runtime.py line:373 [INFO] : Rank: [2] Memory: 8.603 (10.589)
[2021-04-23 08:06:59.396] main_with_runtime.py line:373 [INFO] : Rank: [3] Memory: 3.145 (4.238)

运行语言模型

数据准备

出现错误:

1
2
3
4
5
6
7
8
9
Traceback (most recent call last):
File "preprocess.py", line 15, in <module>
from fairseq.data import indexed_dataset, dictionary
File "/root/training_results_v0.5/v0.5.0/nvidia/submission/code/translation/pytorch/fairseq/data/__init__.py", line 11, in <module>
from .language_pair_dataset import LanguagePairDataset
File "/root/training_results_v0.5/v0.5.0/nvidia/submission/code/translation/pytorch/fairseq/data/language_pair_dataset.py", line 11, in <module>
from . import data_utils, FairseqDataset
File "/root/training_results_v0.5/v0.5.0/nvidia/submission/code/translation/pytorch/fairseq/data/data_utils.py", line 16, in <module>
import fairseq.data.batch_C

解决方案:
在这个repo中搜索fairseq,发现有此目录,并且在同级目录下有setup.py,里面内容查看后有编译fairseq的命令,则运行python setup.py build_ext && python setup.py install即可。最后需要将运行目录下的fairseq重命名,即mv fairseq fairseq.old,否则python在导入package的时候会重定向到当前目录下的fairseq,就仍然找不到fairseq.data.batch_C

最后执行完毕后执行后续profile脚本仍旧报错,显示找不到vocab.bpe.32000,通过google搜索,直接找到包含这个文件的数据包,下载下来解压后当作dataset,然后修改代码中的指定文件名,OK。

运行脚本

运行profile和runtime的时候均会遇到如下报错:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
THCudaCheck FAIL file=/opt/pytorch/pytorch/aten/src/THC/generic/THCTensorMath.cu line=35 error=209 : no kernel image is available for execution on the device
Traceback (most recent call last):
File "main_with_runtime.py", line 580, in <module>
main()
File "main_with_runtime.py", line 177, in main
output_tensors = stage(*tuple(input_tensors))
File "/opt/conda/lib/python3.6/site-packages/torch/nn/modules/module.py", line 507, in __call__
result = self.forward(*input, **kwargs)
File "/workspace/pipedream/runtime/translation/models/gnmt/gpus=4/stage0.py", line 20, in forward
out5 = self.layer5(out4, out1)
File "/opt/conda/lib/python3.6/site-packages/torch/nn/modules/module.py", line 507, in __call__
result = self.forward(*input, **kwargs)
File "/workspace/pipedream/runtime/translation/seq2seq/models/encoder.py", line 64, in forward
return self.emu_bidir_lstm(self.layer1, self.layer2, input, lengths)
File "/workspace/pipedream/runtime/translation/seq2seq/models/encoder.py", line 53, in emu_bidir_lstm
out1 = model1(inputl1)
File "/opt/conda/lib/python3.6/site-packages/torch/nn/modules/module.py", line 507, in __call__
result = self.forward(*input, **kwargs)
File "/opt/conda/lib/python3.6/site-packages/torch/nn/modules/rnn.py", line 556, in forward
return self.forward_tensor(input, hx)
File "/opt/conda/lib/python3.6/site-packages/torch/nn/modules/rnn.py", line 536, in forward_tensor
output, hidden = self.forward_impl(input, hx, batch_sizes, max_batch_size, sorted_indices)
File "/opt/conda/lib/python3.6/site-packages/torch/nn/modules/rnn.py", line 509, in forward_impl
dtype=input.dtype, device=input.device)
RuntimeError: cuda runtime error (209) : no kernel image is available for execution on the device at /opt/pytorch/pytorch/aten/src/THC/generic/THCTensorMath.cu:35

查阅资料,主要原因是pytorch版本与cuda算力不匹配。但是我们用的pytorch版本是1.1,显卡是1080Ti,对应算力是6.1,是符合匹配的。所以应该是pytorch是docker自带的,编译的二进制无法运行在我们的显卡上,所以需要对pytorch做重新编译。参考1 参考2

编译pytorch的时候遇到了MKL错误,通过设置关闭MKLDNN选项解决,编译命令NO_MKLDNN=1 python setup.py install参考。但是后面又遇到了问题!

重温PipeDream的环境搭建,发现在一开始的时候pipedream就通过dockerfile重编译pytorch,并且指定了torch_cuda_arch_list=”5.2 6.0 6.1 7.0 7.5+PTX”,应该已经重编译过了。。。迷茫

Searching Solutions:

  1. My Titan V card had no issue but my GTX 1080 Ti reported “cuda runtime error (209): … no kernel image is available for execution on the device” upon using something from rnn.py.

尝试将cuda降级到10.0

对齐所有版本号

  1. Ubuntu16.04 没法对齐,但是应该没区别
  2. CUDA 10.0
  3. GPU driver 418.56(—>418.197)
  4. 仍旧是no kernel image is available for execution oin the device at ...

CUDA10.0安装

  1. 打开nvidia官网的toolkit下载网站,找到对应版本
  2. 下载runfile类型的文件
  3. sudo sh cuda_10.0.130_410.48_linux.run
  4. nvcc --version 验证版本

GPU driver 418.56

  1. 不好安装418.56,安装418.197.02好了,应该可以
  2. sudo apt remove dkms
  3. ubuntu-drivers device
  4. sudo apt install nvidia-driver-418-server
  5. nvidia-smi 验证版本,为什么cuda version还是10.1??

转在宿主机编译运行pipedream

  1. 复制容器中修改后的/opt/pytorch/pytorch到宿主机,根据pipedream项目中的dockerfile中的编译命令启动编译
  2. 运行run.sh: no module named torchvision
  3. pip install —no-deps torchvision==0.2.1 # 要加—no-deps,不然会自动更新pytorch版本
  4. 后续出现错误,估计可能是数据集的问题,重新准备数据集
  5. 解决数据集问题后运行ok,但是结果不太能理解。

准备数据集

  1. 参考这个
  2. 顺着readme完成。

PipeDream解析

以vgg为例,进入runtime/image_classification/models/vgg16/gpus=4/文件夹,

1
2
3
4
5
6
7
8
9
10
11
>>> tree ./
./
├── dp_conf.json
├── hybrid_conf_2-2.json
├── hybrid_conf.json
├── __init__.py
├── mp_conf.json
├── stage0.py
├── stage1.py
├── stage2.py
└── vgg16.py
  1. stage0.py, stage1.py,查看里面的forward,可以发现stage0与stage1相接可以组成一个vgg16的网络。
  2. dp_conf.json表示数据并行的配置
  3. mp_conf.json表示模型并行的配置
  4. __init__.py种有个model,返回了一个列表,列表中包含了3个module:Stage0(), Stage1(), criterion(loss)

配置解析

vgg & gpu=4

1
2
3
4
5
6
7
8
9
10
11
>>> cat dp_conf.json
{
"module_to_stage_map": [0, 0, 0],
"stage_to_rank_map": {"0": [0, 1, 2, 3]}
}

>>> cat mp_conf.json
{
"module_to_stage_map": [0, 1, 1],
"stage_to_rank_map": {"0": [0], 1: [1]}
}

几个问题需要解决:

  1. 看起来len(module)==len(module_to_stage_map),为什么vgg16的网络的module长度是3,vgg网络的module表示什么意义?
    因为对应model/__init__.py中的model返回的了列表,包含了3个model
  2. 为什么dp_conf.json中的stage没有1,这样无法完整啊?
    反过来思考,相当于所有卡都对应stage0,而stage0对应3个module,即每个卡对应一个完整的模型。
  3. 为什么mp_conf.json中的rank没有2,3,这样应该只有2个?
    反过来理解,相当于第一张卡对应stage0(Stage0),第二张卡对应stage1(Stage1+Loss),但是这样看起来似乎只占用了两个?

vgg & gpu=4_straight

这一组中的stage有4份,4个依次相接组成vgg16网络

1
2
3
4
5
6
7
8
9
10
11
>>> cat dp_conf.json
{
"module_to_stage_map": [0, 0, 0, 0, 0],
"stage_to_rank_map": {"0": [0, 1, 2, 3, 4, 5]}
}

>>> cat mp_conf.json
{
"module_to_stage_map": [0, 1, 2, 3, 3],
"stage_to_rank_map": {"0": [0], "1": [1], "2": [2], "3": [3]}
}

  1. 为什么这里的module_to_stage_map长度是5?
  2. 为什么dp_conf.json中有6个rank?

哪些地方体现了内存差异

  1. 不同批次之间需要使用不同版本的Weights,在上游的worker需要储存更多的weights
  2. 同一个批次,在不同的stage中,可以使用相同的weights,也可以使用不同的weights,pipedream默认使用不同的weights。 如果开启了,那么实际上会导致内存占用更多,看起来更均衡实际上,相当于把论文中的Figure9的上三角填补成了一个正方形(值得注意的是,里面的Wx大小并不相同)
  3. vgg16+gpu=4+1080Ti 自带内存不均+内存不足,可以作为一个例子。这个可以继续分析一下Stage0的parameter占用量。

Run in our environment

  1. 路径:/data/sdc/pipedream
  2. conda环境: conda activate pp4
  3. 运行:(pp4) mindspore@gpu12:/data/sdc/pipedream/runtime/image_classification$ bash run.sh
  4. 结束:pkill python
  5. logger输出: ./log.txt

ToDo

  1. What does module mean in PipeDream
  2. set stage_num_to_rank to different …
  3. Run Language Processing Tasks

转载请注明来源,欢迎对文章中的引用来源进行考证,欢迎指出任何有错误或不够清晰的表达。