Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

跑DeepSpeech2单机多卡加速效果不理想 #3137

Closed
YuMS opened this issue Aug 1, 2017 · 3 comments
Closed

跑DeepSpeech2单机多卡加速效果不理想 #3137

YuMS opened this issue Aug 1, 2017 · 3 comments
Assignees
Labels
User 用于标记用户问题

Comments

@YuMS
Copy link

YuMS commented Aug 1, 2017

尝试用八卡跑DeepSpeech2,发现八卡的加速效果很不理想

具体做法为:

  1. 使用LibriSpeech数据集
  2. 使用v2接口,也就是models/deep_speech_2/train.py
  3. 只使用 6s-8s 的音频进行训练
  4. 每个卡上的batch_size一致,为16
  5. 显卡为 GeForce GTX 1080 Ti
  6. deep_speech_2使用的是models的7月28日develop分支中的版本,commit hash为 57e58ef0c923bad6ecd9fad9925d47f9cb0a98c5
  7. 运行环境为docker image paddlepaddle/paddle:latest-gpu,image id为e5d9d0d01214,7月31日版本。
  8. 使用下面的脚本
function join_by { local IFS="$1"; shift; echo "$*"; }

for i in $(seq 8)
do
  mkdir $i
  NUM_CARDS=$i
  DEVICES=$(join_by , $(seq 0 $(($NUM_CARDS-1)) ))
  CUDA_VISIBLE_DEVICES=$DEVICES python train.py --use_gpu=True  --batch_size $((16 * $NUM_CARDS)) --num_passes 1 --trainer_count $NUM_CARDS --min_duration 6.0 --max_duration 8.0 | tee -a $i/output.log
done

得到的结果为

一个epoch总时间(s) 每个minibatch的时间(s) 一个epoch中minibatch 数
771.4 0.79 972
533.2 1.10 486
402.2 1.24 324
363.5 1.50 243
330.0 1.69 195
308.3 1.90 162
307.2 2.21 139
288.7 2.37 122

image
image

另外,这之后我们为了进一步分析,在 paddle 的代码中直接做了修改再编译,增加了一些计时的输出。
通过具体看输出的timer信息,发现在使用不同数量显卡的情况下,在computeThread中,forward、backward和taskSem_wait 三个主要部分的耗时,在一个minibatch中占的总耗时的比例,都相同(各约1/3)。

不知道这样的情况是正常的吗?应该怎么解释?有没有加速的办法?应该怎么调试呢?

谢谢

@xinghai-sun xinghai-sun self-assigned this Aug 2, 2017
@guoshengCS guoshengCS added the User 用于标记用户问题 label Aug 2, 2017
@YuMS
Copy link
Author

YuMS commented Aug 5, 2017

做了一些nvprof做了一些GPU profiling,有如下forward/backward在卡数增加时变慢的一些发现,希望能为这个issue提供一些帮助。实验条件和原问题中实验条件基本一致,下面的分析以forward为例,backward可以得到的结论类似

  1. forward阶段调用次数最多,占用时间最长的两个kernel函数为gemv2N_kernel_valKeEltWiseBinaryOp,其余函数基本可以忽略不计。每一个kernel函数前面都会执行一次API call: cudaLaunch

  2. 从nvprof结果可以统计出两卡和八卡情况下实际kernel运算时间在forward阶段总时间的占比

    . forward总时间 kernel运算时间 kernel运算占总时间比例
    两卡 739.67ms 148ms 20.0%
    八卡 1053ms 151ms 14.4%

    可以看到,增加卡数时kernel函数计算时间并没有增加,推测是其他overhead时间增加了。

  3. 统计平均时间,单卡和八卡的forward阶段主要函数以及cudaLaunch的平均时间

    . cudaLaunch(us) gemv2N_kernel_val(us) KeEltWiseBinaryOp(us) cudaLaunch占比
    单卡 7.59 * 2 5.46 0.889 0.71
    双卡 10.875 * 2 5 . 35 0.920 0.78
    八卡 13.56 * 2 5.63 0.981 0.80

    可以看出,cudaLaunch是主要的overhead,并且是增加的overhead之一。

  4. 而尝试过直接启动八个进程,每个进程分别使用一个GPU进行一个独立的训练任务,cudaLaunch的时间是不会增加的

总结:可以提供的信息是,cudaLaunch时间在单任务使用单机多卡情况下会增加,原因不明。

@xinghai-sun
Copy link
Contributor

感谢@YuMS的详细实验,对我们很有启发。

我们在K40机器上实验,对齐你的实验配置,做了相同的实验,实验结果如下:

GPU Number Secs Per Epoch Acceleration
1 2003 1.0x
2 1108 1.8x
3 776 2.6x
4 572 3.5x
5 502 4.0x
6 440 4.5x
7 401 5.0x
8 396 5.1x

实验结果比你的结果略好,8卡相比1卡的加速比为5.1x (你的实验仅为2.7x)。可否使用最新的paddle和ds代码,再跑一次实验看看?近期我们切换到cudnn batch norm 和cudnn conv,我不确定你使用的paddle版本是否是切换后的。同时,我这边在重跑并double-check上述结果,有结果会反馈与你。

上述结果以log-scale绘图如下蓝线;此外,我们跑了仅有两个卷积层的网络(去掉三个RNNs层),绘图如下的红线;黑虚线为最理想的线性加速比。可以看到,蓝线(全网络)接近线性加速比,但仍有一定的加速空间,红线(仅卷积层)差距比较大。

time

该加速比确实低于DS2 paper的结果,需要注意的是该版本并未包含all-reduce等优化。后续我们会持续关注Paddle和DS2 On Paddle的性能。期待你提供新版本的double-check实验结果。

@xinghai-sun
Copy link
Contributor

xinghai-sun commented Aug 9, 2017

上述结果可以复现:我重跑一次的8卡加速比在5.4x.
commit hash (models): 5656f45

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
User 用于标记用户问题
Projects
None yet
Development

No branches or pull requests

4 participants