2016/05/17

Ubuntu 16.04에 Caffe와 CUDA-7.5 설치


(2016/05/20 추가)

Theano에서 CUDA-7.5 사용

CUDA를 설치한 김에 Theano에서도 GPU를 사용할 수 있게 설정해 보았다. theano-0.8.2가 최신 버전인데 Anaconda에서 theano 패키지를 설치하니까 버전 0.7이었다. theano-0.8.2를 우분투 16.04에 설치하는 방법은 여기를 참고하면 되는데 여기서도 gcc-5.3.1을 구 버전으로 대체하도록 권장하고 있더라. 지금까지 몇가지 시험해 본 바로는 gcc를 새로 설치하지 않아도 CUDA-7.5는 잘 동작하고 있다. 물론, Caffe와 theano-0.7, Python-3.5.1 환경에서만 테스트해 본 것이긴 하다.

아나콘다에서 theano 패키지는 아래와 같이 설치할 수 있다.

$ conda install theano

CUDA-7.5는 아래 글에서 설치했기 때문에 theano가 CUDA를 사용하도록 ~/.theanorc 파일에 아래 내용과 같이 설정해 주기만 하면 된다.

$ gedit ~/.theanorc

[cuda]
root = /usr/local/cuda

[global]
device = gpu
floatX = float32

[nvcc]
flags = -D_FORCE_INLINES

위에서 device=cpu로 바꾸면 theano가 CPU를 사용한다.

참고로, theano 테스트는 아래와 같이 python을 실행해서 theano.test()를 돌려 보라고 하는데 device가 gpu로 되어 있으면 무수한 오류가 발생하더라. cpu로 하면 그나마 나은데 그래도 오류가 좀 생기고 테스트 시간도 엄청 오래 걸려서 중간에 <Ctrl>+<c>로 관뒀다.

$ python
>>> import theano
>>> theano.test()

그런데, theano를 cpu 환경에서 사용하다가 gpu로 처음 설정해서 사용하는 경우에는 cache 폴더를 지우는 것이 좋다. CUDA 컴파일 오류가 생길 수 있다.

$ rm -rf ~/.theano

theano.test()를 돌린 경우에도 엄청난 cache가 쌓여 있을 수 있는데 원래 cache만 지우는 방법은 아래 명령과 같다.

$ theano-cache clear

결론적으로, theano에서 GPU 테스트는 여기의 소스를 돌려 보면 된다. 내 iMac의 CPU는 QuadCore i5-3470 3.20GHz이고, GPU는 NVIDIA GeForce GTX 675MX인데 첫번째 소스를 돌려 봤더니 GPU가 무려 50배 이상 빠른 결과를 보였다(0.5초 : 28초). 물론 어떤 연산을 하느냐에 따라 성능이 달라지겠지만 GPU 연산이 이렇게나 빠를 줄은 몰랐었다.

맺음말

인간들이 python으로 빨리 구현해 볼 수 있어서 python을 애용하는 듯 한데 python은 근본적으로 c/c++ 보다 느리고, process에서는 multi-core를 사용할 수 있지만 thread는 multi-core를 사용할 수 없는 한계가 있다. 더구나, python은 언어 자체가 2.x와 3.x 버전이 호환이 안되고 아직까지도 과도기이기 때문에 처음 python을 접하는 이들에게는 혼란을 줄 수도 있다. 물론, python 언어의 간결함은 성능보다 더 중요한 장점일 수 있다.

아무튼 Tensorflow도 그렇고 theano도 그렇고 python을 사용해서 모델을 빨리 만들고, 정확도가 좀 떨어지더라도 금방 결과를 볼 수 있다는 것이 생산성 측면에서는 큰 도움이 되는 것이 사실이다. 사용자들은 python만 알아도 되겠지만 backend에서는 c/c++을 여전히 사용하고 있다는 점을 간과해선 안될 것이다.

----------------------------

심심풀이로  Berkeley Vision and Learning Center(BVLC)에서 만든 c++ 기반의 오픈소스 Deep Learning Framework인 Caffe를 우분투 16.04에 설치해 보았다. 구글의 Tensorflow도 CPU only 옵션으로 설치해 봤는데 우분투 16.04에 그럭저럭 설치된다. NVIDIA CUDA는 Caffe 설치시 필요하기 때문에 설치했다. Tensorflow에서도 GPU를 연산에 사용하려면 CUDA를 설치해서 소스로 build 해 주어야 하는데 Caffe에 더 관심이 있어서 Tensorflow는 Anaconda 환경에서 binary 버전으로 설치했다. CUDA를 제목에 붙여 놓은 이유는 우분투 16.04에서 cuda-7.5 설치가 안된다는 글들이 보여서 약간의 도움을 주려는 의도이다.

Caffe 설치 절차는 여기를 따라가면 되는데 우분투에서는 이 곳을 참조해도 된다. 우선, 다음과 같이 Caffe framwork에서 필수로 사용하는 놈들과 옵션인 놈들이 있다. 옵션인 놈들 중에서도 OpenCV를 제외하고는 필수라고 보는게 좋을 듯하다. 옵션이라는 놈들을 설치하지 않으면 예제를 돌려 볼 수 없더라. 추가 옵션이 하나 더 있는데 NVIDIA cuDNN이다. 이놈은 NVIDIA site에 등록해야 받을 수 있는데 귀찮아서 제외했다.
  • NVIDIA CUDA 6.5+
  • BLAS: Atlas(기본) 또는 MKL 또는 OpenBLAS
  • Boost 1.55+
  • protobuf, glog, gflags, hdf5
  • (옵션) OpenCV, leveldb, snappy, lmdb
  • (옵션) NVIDIA cuDNN
NVIDIA CUDA/cuDNN을 제외하면 나머지는 모두 우분투 16.04의 패키지로 설치할 수 있다.

1. NVIDIA CUDA 7.5.18 설치

NVIDIA에서 CUDA 7.5를 내려 받아서 설치했다. deb 패키지로 내려 받거나 run 파일을 내려 받을 수 있는데, cuda_7.5.18_linux.run 파일을 내려 받아서 설치했다. deb으로는 안해 봐서 어느 방법이 좋은 지는 모르겠다. 이전 글의 NVIDIA 드라이버 설치 방법을 참고해서 복구 모드나 콘솔 모드로 부팅해서 실행하면 된다.

다만, 설치 문서를 보면 우분투 16.04의 gcc 버전이 5.3.1인데 gcc 4.9 이전 버전까지만 지원한다고 되어 있고 실제로 설치가 안된다. 하지만 무시하고 설치할 수 있는 --override 옵션을 보여 준다. 즉, 아래와 같이 설치하면 된다.

$ sudo sh cuda_7.5.18_linux.run --silent --override

그런데, 주의할 점은 이 놈이 NVIDIA 드라이버를 포함하고 있어서 기존에 설치된 드라이버를 대체해 버린다. iMac에서는 우려했던 대로 CUDA를 설치하고 나서 GUI로 로그인이 안되는 문제가 발생했다. 이전 글에 있는 대로 복구모드에서 NVIDIA-Linux-x86_64-352.63.run으로 드라이버를 다시 설치했다. 드라이버가 CUDA에 같이 들어 있는 이유는 아마 드라이버와 CUDA 라이브러리 버전이 일치해야 하기 때문일 텐데, 352.63이 구 버전이긴 해도 1년도 안된 것이라 호환성에 문제가 없으리라 예상했고 잘 돌아 가더라.

재부팅 후에 ~/.bashrc 파일 끝에 CUDA path를 아래 두 줄과 같이 잡아 준다.

$ gedit ~/.bashrc

export PATH=/usr/local/cuda-7.5/bin:$PATH
export LD_LIBRARY_PATH=/usr/local/cuda-7.5/lib64:$LD_LIBRARY_PATH

설치는 끝났고 잘 동작하는지 위의 설치 문서대로 테스트 해 봐야 한다. 터미널을 새로 열어서 Sample 프로그램을 build 하고 실행해 봐야 한다. 단, 그 전에 아래 명령과 같이 samples 이하 폴더들에게 사용자(aaa라 가정) 접근 권한을 부여해야 한다.

$ sudo chown -R aaa:aaa /usr/local/cuda/samples

$ cd /usr/local/cuda/samples/5_Simulations/nbody
$ make

make를 하면 우분투 16.04의 gcc 버전이 gcc 4.9 초과 버전이라 build가 안된다. 아래와 같이 /usr/local/cuda/include/host_config.h 파일에서 gcc 버전 check하는 부분을 코멘트 처리해 버린다.

$ sudo vi /usr/local/cuda/include/host_config.h
......
/* AAA
#if __GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ > 9)

#error -- unsupported GNU version! gcc versions later than 4.9 are not supported!

#endif
*/
/* __GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ > 9) */
......

이제 다시 make 하면 잘 된다.

$ make
$ ./nbody

nbody를 실행해서 불꽃놀이 창이 뜨면 CUDA가 제대로 동작하는 것이다.

2. Caffe에 필요한 우분투 패키지 설치

NVIDIA CUDA/cuDNN을 제외한 나머지는 아래와 같이 설치하면 된다.

$ sudo apt install libatlas-base-dev

$ sudo apt install --no-install-recommends libboost-all-dev

$ sudo apt install libprotobuf-dev protobuf-compiler libgoogle-glog-dev libgflags-dev libhdf5-serial-dev

$ sudo apt install libopencv-dev libleveldb-dev libsnappy-dev liblmdb-dev

3. Caffe build 및 설치

Caffe 소스는 github에서 받을 수 있다. git가 설치되어 있지 않다면 git를 먼저 설치해야 한다.

$ sudo apt install git
$ git clone https://github.com/BVLC/caffe

Caffe를 build하기에 앞서 Makefile.config 파일을 생성해서 수정해야 한다.
$ cd ./caffe
$ cp Makefile.config.example Makefile.config
$ gedit Makefile.config

OpenCV는 선택 사항인데 예제를 돌려 보려면 leveldb와 lmdb가 필요하다.

USE_OPENCV := 0
USE_LEVELDB := 1
USE_LMDB := 1

이외에도 Python API를 사용하려면 Path를 제대로 잡아 주어야 한다. 이제 Caffe를 make로 build 하는데 CPU core 갯수가 2개 이상이라면 -j<core 수> 옵션을 주는 것이 좋다. 

$ make all -j4
역시 여기서도 오류가 발생했는데 아래와 같이 NVIDIA 컴파일러에서 memcpy 함수를 못찾는 오류다. 소스를 보면 inline 함수를 사용해야 하는 상황인데 이걸 못 찾고 있는 거였다.

NVCC src/caffe/util/math_functions.cu
/usr/include/string.h: In function ‘void* __mempcpy_inline(void*, const void*, size_t)’:
/usr/include/string.h:652:42: error: ‘memcpy’ was not declared in this scope
   return (char *) memcpy (__dest, __src, __n) + __n;
                                          ^
Makefile:585: recipe for target '.build_release/cuda/src/caffe/util/math_functions.o' failed
make: *** [.build_release/cuda/src/caffe/util/math_functions.o] Error 1

Makefile을 수정해서 아래와 같이 NVCC가 inline 함수를 사용하도록 해준다.
$ gedit Makefile

NVCCFLAGS += -D_FORCE_INLINES -ccbin=$(CXX) -Xcompiler -fPIC $(COMMON_FLAGS)

참고로 cmake로 build할 경우에는 CMakeLists.txt 파일의 맨앞에 아래 한 줄을 넣어 주면 된다.
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -D_FORCE_INLINES")

다시 make 하고 test를 진행한다.

$ make all -j4
$ make test -j4
$ make runtest -j4

runtest에서 다시 오류가 발생했는데 아래와 같이 libhdf5 라이브러리를 못찾겠다는 오류다.

.build_release/tools/caffe: error while loading shared libraries: libhdf5_hl.so.10: cannot open shared object file: No such file or directory
Makefile:523: recipe for target 'runtest' failed
make: *** [runtest] Error 127

실제로 libhdf5_hl.so.10과 libhdf5.so.10 라이브러리는 libhdf5-serial-dev 패키지를 설치할 때 설치되지 않았더라. 소스로 부터 다시 build 하는 게 정석일 수도 있는데 직감으로 아래와 같이 해결했다.

$ cd /usr/lib/x86_64-linux-gnu
$ sudo ln -s libhdf5_serial_hl.so.10 libhdf5_hl.so.10
$ sudo ln -s libhdf5_serial.so.10 libhdf5.so.10

다시 runtest를 돌리니 잘 되더라.

$ make runtest -j4

4. Caffe Test

Caffe 설치 절차에 있는 내용에 따라 여기를 참고하여 MNIST 예제를 돌려 볼 필요가 있다

$ cd $CAFFE_ROOT
$ ./data/mnist/get_mnist.sh
$ ./examples/mnist/create_mnist.sh
$ ./examples/mnist/train_lenet.sh

참고로, 내 iMac에서 기본 GPU 사용 옵션으로 5분 10초 걸렸다(CPU 사용시 13분 47초 - 2.7배 GPU가 빠름). 학습횟수는 기본 설정값인 10,000회였고, 정확도는 99.1%였다.

나머지 설명은 Caffe 홈페이지에 잘 되어 있으니 이만 마쳐야 겠다.