Ubuntu 16.04 LTS 安装 MXNet 过程

Ubuntu 16.04 发布有一段时间了, 其中有一个我比较需要的亮点是对 4K 的显示器支持的更好, 一直想升级, 但是, 因为怕坑太多, 一直没有升级. 前几天官方发布了一个新的版本 16.04.1, 修复了大量的 bug, 于是, 忍不住终于升级了. 总体来说, 14.04 到 16.04 的升级还是非常平滑的, 除了 Emacs 使用 spacemacs 的配置出了一点问题, 目前还没有出现影响到工作的问题. 搜狗输入法正常使用, OpenCV 3.1.0 也能正常编译安装, CUDA 和 cudnn 都没问题. chrome 和 virtualbox 也都正常. 这篇 note 就来记录一下在 Ubuntu 16.04 上安装 OpenCV 3.1.0, CUDA8 cudnn 以及编译 MXNet 的过程.

一般配置

  1. 源: 建议选择清华的源, 之前一直都是使用 aliyun 的源, 速度 1M 左右, 选择了清华的源之后, 速度能飙到 5M+
  2. 安装必要的软件, 包括 git, emacs, tmux, zsh 等, 系统中 tmux 已经升级到了 2.1 版本, 所以, 配置的时候 set -g mouse-select-pane on 等已经被移除, 取而代之的是 set -g mouse.

安装显卡驱动

显卡驱动建议直接安装系统自带的 NVIDIA 提供的驱动, 虽然不是最新的版本, 但是, 符合 CUDA8 的要求了. 方法是: 在 Hub 中搜索 additional drivers. 在弹出的对话框中选择 NVIDIA 的驱动. 然后点击 Apply Changes 等待完成. 重启电脑之后驱动安装成功.

试过安装官网下载的最新的驱动, 结果是安装完之后黑屏, 只有光标闪烁, 所以, 不建议自己从官网下载安装驱动.

安装CUDA

我习惯使用 sh 来安装CUDA, 所以, 我下载的是 cuda_8.0.27_linux.run, 然后按照官网的方法, sudo sh cuda_8.0.27_linux.run, 因为之前已经通过 Additional Drivers 安装过显卡驱动了, 所以, 这一步不安装显卡驱动, 只安装了 cuda toolkit. 安装很顺利, 过程也很快.

一点小 Hack

注: 最新版的 CUDA 已经解决了这个问题
参考 caffe 的解决方法
在当前的 CUDA8 要求 gcc 的版本要小于 5.3, 而 ubuntu 16.04 中的版本是 5.4, 可以通过下面的方法解决这个问题.

>注释掉/删除 /usr/local/cuda/include/host_config.h 的第 115 行.

1
2
--- #error -- unsupported GNU version! gcc versions later than 5.3 are not supported!
+++ //#error -- unsupported GNU version! gcc versions later than 4.9 are not supported!

安装OpenCV

OpenCV 3 对 Python 的支持更好, 所以, 我安装的是 OpenCV 3.1.0. 需要说明的是:

  1. OpenCV 冲 3.x版本之后, SIFT 等算法从 OpenCV 中剥离了出来, 放到了 opencv_contrib 中去了, 安装方法与 2.x略有不同
  2. OpenCV 在 python 中的数据是 numpy 格式, 所以, 需要先安装 numpy
  3. 关闭 CUDA 选项, 打开这个选项的话, 编译最后的链接过程会失败.(这个选项一般都不会用到, OpenCV 在 cmake 的时候是搜索 cuda, 如果在系统中发现 cuda, 会自动打开这个选项, 所以, 要显式关闭这个选项)

这部分的安装主要参考的是 caffe 文档的相关说明. 在下载的时候, 要注意保持 opencv 和 opencv_contrib 版本号的一致.

  1. Python 相关

    1
    2
    3
    sudo apt install python-pip
    sudo pip install --upgrade pip
    sudo pip install numpy
  2. 安装依赖

    1
    2
    3
    sudo apt-get install --assume-yes libopencv-dev build-essential cmake git libgtk2.0-dev pkg-config python-dev python-numpy libdc1394-22 libdc1394-22-dev libjpeg-dev libpng12-dev libtiff5-dev libjasper-dev libavcodec-dev libavformat-dev libswscale-dev libxine2-dev libgstreamer0.10-dev libgstreamer-plugins-base0.10-dev libv4l-dev libtbb-dev libqt4-dev libfaac-dev libmp3lame-dev libopencore-amrnb-dev libopencore-amrwb-dev libtheora-dev libvorbis-dev libxvidcore-dev x264 v4l-utils unzip
    sudo apt-get install build-essential cmake git
    sudo apt-get install ffmpeg libopencv-dev libgtk-3-dev python-numpy python3-numpy libdc1394-22 libdc1394-22-dev libjpeg-dev libpng12-dev libtiff5-dev libjasper-dev libavcodec-dev libavformat-dev libswscale-dev libxine2-dev libgstreamer1.0-dev libgstreamer-plugins-base1.0-dev libv4l-dev libtbb-dev qtbase5-dev libfaac-dev libmp3lame-dev libopencore-amrnb-dev libopencore-amrwb-dev libtheora-dev libvorbis-dev libxvidcore-dev x264 v4l-utils unzip
  3. 编译
    进入到 opencv 的解压缩目录中

    1
    2
    3
    4
    5
    mkdir build
    cd build/
    # ../../opencv_contrib-3.1.0/modules 替换成相应的 opencv_contrib 的目录
    cmake -D CMAKE_BUILD_TYPE=RELEASE -D CMAKE_INSTALL_PREFIX=/usr/local -D WITH_TBB=ON -D WITH_V4L=ON -D WITH_QT=ON -D WITH_OPENGL=ON -D WITH_CUDA=OFF -D OPENCV_EXTRA_MODULES_PATH=../../opencv_contrib-3.1.0/modules ..
    make -j$(nproc)
  4. 安装
    在编译目录中执行下面的命令

    1
    2
    sudo apt-get install checkinstall
    sudo checkinstall

至此, OpenCV 3.1.0 就安装完成了.

安装 MXNet

MXNet 的安装基本上是官方的标准流程.

1
2
3
sudo apt-get install -y build-essential git libatlas-base-dev
git clone --recursive https://github.com/dmlc/mxnet
cd mxnet; make -j$(nproc)

在编译之前, 可以修改 MXNet 的 config.mk 文件, 来满足个性化的需求.

1
2
3
cd mxnet
cp make/config.mk .
emacs -nw config.mk # 或者使用其它顺手的编辑器

贴出来我的 config.mk 文件, 供参考

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
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
export CC = gcc
export CXX = g++
export NVCC = nvcc
# whether compile with debug
DEBUG = 0
# /home/gys/local/cuda/lib64 是 cudnn 的目录, 告诉编译器去哪里找 cudnn 对应的链接库. /usr/local/share/OpenCV/3rdparty/lib/ 是 OpenCV 3.1.0 的一个库目录, 不加的话, 在编译的时候会因为找不到 ippv 而失败
ADD_LDFLAGS = -L/home/gys/local/cuda/lib64 -L/usr/local/share/OpenCV/3rdparty/lib/
# 同样是 cudnn 对应的头文件目录
ADD_CFLAGS = -I/home/gys/local/cuda/include -march=native
#---------------------------------------------
# matrix computation libraries for CPU/GPU
#---------------------------------------------
# whether use CUDA during compile
USE_CUDA = 1
# cuda 的安装目录
USE_CUDA_PATH = /usr/local/cuda
# whether use CuDNN R3 library
USE_CUDNN = 1
# whether use cuda runtime compiling for writing kernels in native language (i.e. Python)
USE_NVRTC = 0
# whether use opencv during compilation
# you can disable it, however, you will not able to use
# imbin iterator
USE_OPENCV = 1
# use openmp for parallelization
USE_OPENMP = 1
USE_BLAS = atlas
# add path to intel library, you may need it for MKL, if you did not add the path
# to environment variable
USE_INTEL_PATH = NONE
# If use MKL, choose static link automatically to allow python wrapper
ifeq ($(USE_BLAS), mkl)
USE_STATIC_MKL = 1
else
USE_STATIC_MKL = NONE
endif
#----------------------------
# distributed computing
#----------------------------
# whether or not to enable multi-machine supporting
USE_DIST_KVSTORE = 0
# whether or not allow to read and write HDFS directly. If yes, then hadoop is
# required
USE_HDFS = 0
# path to libjvm.so. required if USE_HDFS=1
LIBJVM=$(JAVA_HOME)/jre/lib/amd64/server
# whether or not allow to read and write AWS S3 directly. If yes, then
# libcurl4-openssl-dev is required, it can be installed on Ubuntu by
# sudo apt-get install -y libcurl4-openssl-dev
USE_S3 = 0
#----------------------------
# additional operators
#----------------------------
# path to folders containing projects specific operators that you don't want to put in src/operators
EXTRA_OPERATORS =

为了加速 GPU 计算, 我们忽略显卡的兼容, 只支持当前的显卡
首先要查询当前的显卡的 compute capacity, 然后修改 mshadow 的编译选项, 例如, 我的 1080 的编译选项如下:

1
2
# mxnet/mshadow/make/mshadow.mk
MSHADOW_NVCCFLAGS = -gencode arch=compute_61,code=sm_61

更新环境变量

把下面一行加入到相应的 $SHELL 的配置文件中. 我用的 是zsh, 不同的 shell 会有不同的设置环境变量的方法.

1
export LD_LIBRARY_PATH=/usr/local/cuda/lib64:/home/gys/local/cuda/lib64:$LD_LIBRARY_PATH

测试安装结果