Tensorflow-Horovod安装部署checklist

基础环境 GPU 检查多机中每个节点的GPU是否归属同一型号, horovod后台线程周期性处理提交的梯度, 如果由于GPU计算能力不同或网络延迟导致某次allreduce中某个提交者落后超过一个周期, 会发生使用错误的Tensor进行allreduce的情况, 通常, 这都会导致Tensor Shape Mismatch的错误, 笔者就层遇到过不小心同时使用M40和P40的情况, 在tensorflow1.8还能的运行, 但1.14就无法多机reduce, 定位了好久才发现是硬件不同
cuda 是否与驱动match:cuda兼容性检查下载, 随同一起安装的还有cupti等组件
cudnn 版本是否与cuda版本match: cudnn兼容性检查及下载
nccl 版本是否与cuda版本match: nccl兼容性检查及下载
mpi 其中libmpi.so要对外可见, 多机训练需要tensorflow编译的时候就要将MPI链接到lib中, 同时, MPI对于horovod也是必要依赖
Tensorflow tensorflow 选择的tensorflow 版本是否兼容系统cuda, 官方兼容列表
tensorboard tensorboard是否兼容tensorflow, tensorboard的版本号要与tensoflow保持一致
tensorflow-estimator tensorflow-estimator是否兼容了tensorflow, tensorflow 1.10.6 之后的特性, 是对底层API的封装, 需要与tensorflow版本号一致
bazel tensorflow对使用的bazel版本比较敏感, 如果没有修改bazelrc却出现bazelrc文件解析错误, 就要考虑下是不是bazel版本的问题, 参考tensorflow测试通过的bazel版本bazel下载
编译选项 tensorflow编译选项, 是否包含了cuda和nccl, 这两个缺省都是不安装的, 此处使用GPU, cuda为必须, 加之多机多卡, NCCL可以减少通信开销, 应该编译进tensorflow. 在1.13之前, nccl是随同config的过程一同配置, 1.14开始使用环境变量 + .bazelrc控制NCCL的安装, 具体的, 环境变量中需要export以下环境变量
export TF_NCCL_VERSION=2.4.2
export NCCL_HDR_PATH=/usr/local/nccl_2.4.2-1+cuda9.2_x86_64/include/
            
同时, 修改tensorflow/.bazelrc文件
build:nccl --define=with_nccl_support=true
#build:nccl --define=no_nccl_support=true
            
Horovod 环境变量 环境变量是否指定了libtensorflow_framework.so的路径以及NCCL路径信息
export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:/usr/lib/python2.7/site-packages/tensorflow/
export HOROVOD_WITH_TENSORFLOW=1
export HOROVOD_WITHOUT_PYTORCH=1
export HOROVOD_GPU_ALLREDUCE=NCCL
export HOROVOD_NCCL_HOME=/usr/local/nccl_2.1.15-1+cuda9.0_x86_64
export HOROVOD_NCCL_INCLUDE=/usr/local/nccl_2.1.15-1+cuda9.0_x86_64/include/
export HOROVOD_NCCL_LIB=/usr/local/nccl_2.1.15-1+cuda9.0_x86_64/lib/

iostat

iostat是一个基于/proc/diskstats文件计算的IO统计工具,它在周期性的去读取/proc/diskstats的IO统计信息并通过一定的公式计算出来。输出如下:

$iostatLinux 4.4.0-116-generic (jpc)   03/18/2018  _x86_64_    (8 CPU)
avg-cpu:  %user   %nice %system %iowait  %steal   %idle           
          5.94    0.08    3.02    2.08    0.00   88.89
Device: tps      kB_read/s    kB_wrtn/s    kB_read    kB_wrtn
sda     12.15       243.01       110.93    5014986    2289276
sdb     17.88        83.01        89.09    1712994    1838461
$iostat
Linux 4.4.0-116-generic (jpc)   03/18/2018  _x86_64_    (8 CPU)
avg-cpu:  %user   %nice %system %iowait  %steal   %idle           
          5.94    0.08    3.02    2.08    0.00   88.89
Device: tps      kB_read/s    kB_wrtn/s    kB_read    kB_wrtn
sda     12.15       243.01       110.93    5014986    2289276
sdb     17.88        83.01        89.09    1712994    1838461

tps:transfer per second,每秒传输的IO数量
kB_read/s:每秒读取的KB数量
kB_wrtn/s:每秒写的KB数量
kB_read:累计读取的KB数
kB_wrtn:累计写的KB数量

$iostat -x
Linux 4.4.0-116-generic (jpc)   03/18/2018  _x86_64_    (8 CPU)
avg-cpu: %user %nice %system %iowait %steal %idle   5.11    0.19    3.10    1.83    0.00   89.78
Device: rrqm/s wrqm/s   r/s    w/s     rkB/s    wkB/s     avgrq-sz avgqu-sz await  r_await  w_await  svctm  %util  
sda    0.06     7.13   18.23    7.51   614.39   163.88    60.47     0.03     1.11   0.64     2.27     0.42   1.09
sdb    0.77     3.13   15.46   11.81   249.41   128.89    27.75     0.08     3.03   0.52     6.32     0.18   0.49

rrqm/s:每秒合并读IO的次数
wrqm/s:每秒合并写IO的次数
r/s:每秒读IO完成的次数
w/s:每秒写IO完成的次数
rkB/s:每秒读IO的KB数量
wkB/s:每秒写IO的KB数量
avgrq-sz:平均IO扇区数
avgqu-sz:平均未完成的IO数量,包括在队列中的和硬件正在处理的。
await:平均每个IO耗时,包括在队列中和硬件操作的时间。
r_wait:平均每个读IO耗时**w_wait**:平均每个写IO耗时
svctm:Warning! Do not trust this field any more. This field will be removed in a future sysstat version
%util:磁盘利用率,只要有IO操作就算,由于硬件的并发处理IO能力,即使%util达到100%也不意味着已达存储介质的性能极限,只能说明在这个统计周期内,该介质一直都有IO操作。

/proc

/proc/diskstats

Linux的/proc存储了很多系统级统计信息,与IO相关的信息都存储在diskstat中,输出如下

$cat /proc/diskstats
sda 120880 392 8323045 78832 53591 51267 2315680 115900 0 76384 194700

一共11个字段,在内核文档””中有详细的解释,除了Field9之外,其他字段都是从开始计数的累计值。以sda为例,前两个分别是设备的major和minor,接下来分别是:

Field 1 – rd_io,表示120880个读IO被完成
Field 4 – rd_ticks,读操作一共耗时78832ms,从__make_request开始,到end_that_make_request()为止,包括在队列中等待的时间。
Field 5 – wr_io,表示53591个写IO被完成
Field 6 – wr_merges,表示发生了51267次写IO合并
Field 7 – wr_sectors,表示2315680个被写的扇区
Field 8 – wr_ticks,写操作一共耗时115900ms,
Field 9 – in_flight,IO队列中遗留了0个IO尚未处理,当有一个IO进入IO队列时,该值+1,每完成一个IO,该值-1
Filed 10 – io_ticks,表示处理IO花费了76384ms的自然时间,即只要in_flight不为0,io_ticks就在计数。io_ticks不是rd_ticks和wr_ticks的和,因为rd_ticks和wr_ticks是针对IO而言的,由于设备往往有并行处理IO的能力,所以io_ticks往往小于rd_ticks+wr_ticks。
Field 11 – time_in_queue,系统一共花费了194700ms用于IO操作
Field 2 – rd_merges,表示发生了392次读IO合并
Field 3 – rd_sectors,表示8323045个被读取的扇区

解决ubuntu16.04 在/etc/network/interfaces设置static ip无效

双网卡使用无线网卡上互联网,使用以太网卡连局域网,在/etc/network/interfaces里对以太网卡设置static ip无效,使用ifconfig临时设置也仅能工作一会,设置的ip马上就消失了,因为桌面版的ubuntu使用自己的NetworkManager来管理网络设备,要么kill掉下面所有的进程以使interfaces生效,要么使用右上角的NetworkManager配置ip
sudo ps -aux | grep NetworkManager0

解决unity丢图标的3个坑

现象1:
用了一年多的unity的右上角的网络图标和网易云音乐的图标消失不见了,我也不记得最近有update或upgrade过,然而这两个功能还是可以正常用
解决1:
安装Gnome,果然相应的图标就出来了

现象2:
Gnome3在PC上一点不好用,很明显是针对触控设备设计的,于是在登录界面设置选择ubuntu(unity),但是登录界面却还是Gnome3的
解决2:
删除gnome(后来想想应该是我删除的时候使用了gnome*,所以一些和unity共享的组件也被删除了,导致unity进不去), 将.xinitrc换成unity-session,找回了unity的登录界面

现象3:
输入的登录密码却不能进入桌面
解决3:
重新安装unity,图标也回来了。

#apt-get update 
#apt-get install --reinstall ubuntu-desktop
#apt-get install unity 
#reboot 

将ubuntu的home迁移至第二块磁盘

在忍受了一整周的磁盘将满的报警之后,今天终于着手准备将占据64G磁盘中的44G的Home迁移至另外一块磁盘,当然,这也是使用Linux做PC OS的正确使用方式。在Linux的目录管理风格的基础上,这个问题的实质就是将另一块盘挂载在home目录下而已。流程如下,希望能给后来者一些借鉴

  1. 准备一块磁盘,使用fdisk将其分区,使用mkfs将其格式化为ext等格式,这里不建议使用诸如ntfs等不支持linux权限的文件系统
  2. 使用“sudo cp -p ./* ./.* /media/xxx/xxx; sudo cp -pr ./* ./.* /media/xxx/xxx”将家目录保持属主及时间戳的拷贝到新的分区目录
  3. Ctrl+Alt+F1 切换到字符界面, 使用“w”查看当前登录用户, 使用“pkill”强制登出非root用户
  4. 如果想新建新的家目录,mkdir新的家目录,即使不打算修改家目录的路径,也不建议直接在这里删除旧的家目录,可以先新建一个新的,待全部完成之后再删除,或者新建一个与原来相同的符号链接保证兼容性。此外,要注意这个新目录的权限属主要和原来相同,否则会因为目标用户非root而无法挂载home,现象就是反复登录不能进入桌面。
  5. 使用“usermod -d “修改普通用户的家目录
  6. 修改/etc/fstab文件,将新的分区挂载到新的家目录,注意作为Home的磁盘不一定是sdb等,也可能是sda
  7. 重启即可

Ubuntu12.04/15.04禁止移动介质自动播放

网上有有很多关于Ubuntu10.04关闭移动介质自动播放的方法,包括在文件管理器里面设置或者使用gconf-editor,但是从12.04开始这两种方法都不再好用了,关于移动介质的处理方法被移到了System Settings==>Details==>Removable Media,打上钩,以后就不用担心我的6分区移动硬盘一插上就打开一堆窗口了