kaldi在java中运行_Kaldi中的多GPU应该如何理解,nnet3中的多GPU运行应该怎么设置?...

这篇博客探讨了在Kaldi中如何管理和利用多GPU进行nnet3训练。介绍了如何通过设置`num-jobs-initial`和`num-jobs-final`来调整进程数,并讨论了在`compute-mode`为default时如何避免资源浪费。通过插入延迟时间来错开不同nj的GPU查询,以实现更有效的多GPU利用。此外,文章提到了Kaldi的cuda-memory-proportion参数,解释了其按需分配显存的机制,特别适合单机少卡场景。
摘要由CSDN通过智能技术生成

Kaldi中的nnet3是默认使用GPU运行的,至于多卡GPU的问题,还是先要对number of jobs(nj)的概念有所了解。假如用的是steps/nnet3/train_raw_dnn.py去训练网络图,这时候会需要设置num-jobs-initial和num-jobs-final,这两个分别表示网络训练初期的进程数与末期的进程数,而这个nj会根据epoch和数据量自动在某些特定的iteration去递增,从initial渐变增加到final。

另外,我个人习惯是把显卡的compute mode设为default,而不是exclusive;可能会不少人觉得exclusive后,会显得多卡运行,因为每张卡都有进程nj在跑了,但如果在一张12GB的卡上跑一个只有2kMB的进程,那其实这张卡还很空,利用率也太低了。如果显卡是设置为default,那就会充分使用一张卡的所有显存~但这时候又会出现另一个问题。

假如我们设置了1到10个nj,那在训练时,敲nvidia-smi查看进程占用显存的情况时,一个nj占用2k+MB,有5个nj同在一张卡上正在运行,那对于这张12GB的卡来说是接近占满了;如果后面再多一个nj,那程序就OOM了,这个时候去想多卡问题就显得很有必要(如果只有一张卡的话,那就把final nj设小)。

在运行kaldi程序前,不少人会发现--cmd这个option,它可以写run.pl进行单机执行,也可以写queue.pl去集群;其实这个queue.pl也是能实现单机多卡,它会调用gridengin去调配显卡资源,不过实现的操作比较复杂,我不是很推荐用gridengin来做这事。我想介绍的是另一种方式来做到多GPU跑nnet3,那是利用队列和compute_pr。

每个nj运行的机制是这样子:先执行compute_pr查询当前机子每张卡的空闲率,选用空闲率最大的那张卡,然后逐步去占用它,直至这个nj占够了它需要的空间;如果有多个nj,那这些nj就会同时去查询空闲率,因为它们是同时查询,所以通常会出现一起判定用一张卡的结果。所以能做的就是,不让这些nj同时查询,在每次查询中插入等待时间来错开nj的查询;通过错开查询,每次迭代开始的nj就成队列形式,逐个逐个去查询去占用。当等待时间越大,第一个nj就已经完成查询与占用,此时每张卡的空闲率情况就发生了改变,那第二个nj查询时,就不会直接跟上第一个nj而是用另一张更空的卡……如此类推,所以nj就成功错开地占用显卡。

在代码上实现插入等待时间,是在steps/libs/nnet3/train/frame_level_objf/common.py的train_new_model()中thread下169行加入time.sleep(20),这里的意思是每当把一个thread push到threads队列后,就sleep 20秒才执行下一个nj的查询与占用:

至于LSTM是不是默认多卡训练,这其实没关系的,是否多卡跟网络类型无关

补充:今年2019年更新的kaldi会有一种对半调用显存的机制,那是因为nnet3-train有一个新参数cuda-memory-proportion=0.5;这表示每个进程调用显存时,会直接把该显卡的一半显存先占用了(无论是default还是独占模型);如果单机少卡的情况下想开多进程跑网络,每个nj直接占用一半显存显然是不合理的。

如果仔细看这个参数的底层代码,会发现当初始设置是较少的比例时,若当前nj实际需要的显存大于分配显存,就会触发按需分配,重新分配刚好这个nj能运行的显存。例如,cuda-memory-proportion=0.1,代码初始给nj只分配了1G显存资源,若1G资源也能运行该nj,则就是以1G运行;若1G资源不足以运行该nj(它实际需要2.5G),那程序会再分配2.5G来运行它;这就是按需分配。

补充2:如果是ASR的朋友,上述要修改的脚本则是kaldi/egs/wsj/s5/steps/libs/nnet3/train/chain_objf/acoustic_model.py当中nnet3-chain-train的那部分

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值