Premiers pas avec theano

Installer Theano et configurer le GPU sur Ubuntu 14.04

Vous pouvez utiliser les instructions suivantes pour installer Theano et configurer le GPU (en supposant un Ubuntu 14.04 fraîchement installé) :

# Install Theano
sudo apt-get install python-numpy python-scipy python-dev python-pip python-nose g++ libopenblas-dev git
sudo pip install Theano

# Install Nvidia drivers, CUDA and CUDA toolkit, following some instructions from http://docs.nvidia.com/cuda/cuda-installation-guide-linux/index.html
wget http://developer.download.nvidia.com/compute/cuda/7.5/Prod/local_installers/cuda-repo-ubuntu1404-7-5-local_7.5-18_amd64.deb # Got the link at https://developer.nvidia.com/cuda-downloads
sudo dpkg -i cuda-repo-ubuntu1404-7-5-local_7.5-18_amd64.deb
sudo apt-get update
sudo apt-get install cuda

sudo reboot

À ce stade, exécuter nvidia-smi devrait fonctionner, mais exécuter nvcc ne fonctionnera pas.

# Execute in console, or (add in ~/.bash_profile then run "source ~/.bash_profile"):
export PATH=/usr/local/cuda-7.5/bin:$PATH
export LD_LIBRARY_PATH=/usr/local/cuda-7.5/lib64:$LD_LIBRARY_PATH

À ce stade, nvidia-smi et nvcc devraient fonctionner.

Pour tester si Theano est capable d’utiliser le GPU :

Copiez-collez ce qui suit dans gpu_test.py :

# Start gpu_test.py
# From http://deeplearning.net/software/theano/tutorial/using_gpu.html#using-gpu
from theano import function, config, shared, sandbox
import theano.tensor as T
import numpy
import time

vlen = 10 * 30 * 768  # 10 x #cores x # threads per core
iters = 1000

rng = numpy.random.RandomState(22)
x = shared(numpy.asarray(rng.rand(vlen), config.floatX))
f = function([], T.exp(x))
print(f.maker.fgraph.toposort())
t0 = time.time()
for i in xrange(iters):
    r = f()
t1 = time.time()
print("Looping %d times took %f seconds" % (iters, t1 - t0))
print("Result is %s" % (r,))
if numpy.any([isinstance(x.op, T.Elemwise) for x in f.maker.fgraph.toposort()]):
    print('Used the cpu')
else:
    print('Used the gpu')
# End gpu_test.py

et exécutez-le :

THEANO_FLAGS='mode=FAST_RUN,device=gpu,floatX=float32' python gpu_test.py

qui devrait retourner :

[email protected]:~$ THEANO_FLAGS='mode=FAST_RUN,device=gpu,floatX=float32' python gpu_test.py
Using gpu device 0: GeForce GTX 690
[GpuElemwise{exp,no_inplace}(<CudaNdarrayType(float32, vector)>), HostFromGpu(GpuElemwise{exp,no_inplace}.0)]
Looping 1000 times took 0.658292 seconds
Result is [ 1.23178029  1.61879349  1.52278066 ...,  2.20771813  2.29967761
  1.62323296]
Used the gpu

Pour connaître votre version CUDA :

​nvcc -V

Exemple:

[email protected]:~$ nvcc -V
nvcc: NVIDIA (R) Cuda compiler driver
Copyright (c) 2005-2015 NVIDIA Corporation
Built on Tue_Aug_11_14:27:32_CDT_2015
Cuda compilation tools, release 7.5, V7.5.17

Ajout de cuDNN

Pour ajouter cuDNN (instructions de http://deeplearning.net/software/theano/library/sandbox/cuda/dnn.html) :

  1. Téléchargez cuDNN depuis https://developer.nvidia.com/rdp/cudnn-download (nécessite une inscription, qui est gratuite)
  2. tar -xvf cudnn-7.0-linux-x64-v3.0-prod.tgz
  3. Effectuez l’une des opérations suivantes

Option 1 : Copiez les fichiers *.h dans CUDA_ROOT/include et les fichiers *.so* dans CUDA_ROOT/lib64 (par défaut, CUDA_ROOT est /usr/local/cuda sous Linux ).

sudo cp cuda/lib64/* /usr/local/cuda/lib64/
sudo cp cuda/include/cudnn.h /usr/local/cuda/include/

Option 2:

export LD_LIBRARY_PATH=/home/user/path_to_CUDNN_folder/lib64:$LD_LIBRARY_PATH
export CPATH=/home/user/path_to_CUDNN_folder/include:$CPATH
export LIBRARY_PATH=/home/user/path_to_CUDNN_folder/lib64:$LD_LIBRARY_PATH

Par défaut, Theano détectera s’il peut utiliser cuDNN. Si c’est le cas, il l’utilisera. Sinon, les optimisations Theano n’introduiront pas les opérations cuDNN. Ainsi, Theano fonctionnera toujours si l’utilisateur ne les a pas introduits manuellement.

Pour obtenir une erreur si Theano ne peut pas utiliser cuDNN, utilisez ce drapeau Theano : optimizer_incluant=cudnn.

Exemple:

THEANO_FLAGS='mode=FAST_RUN,device=gpu,floatX=float32,optimizer_including=cudnn' python gpu_test.py

Pour connaître votre version de cuDNN :

cat /usr/local/cuda/include/cudnn.h | grep CUDNN_MAJOR -A 2

Ajout de CNMeM

La bibliothèque CNMeM est une “bibliothèque simple pour aider les frameworks Deep Learning à gérer la mémoire CUDA”.

# Build CNMeM without the unit tests
git clone https://github.com/NVIDIA/cnmem.git cnmem
cd cnmem
mkdir build
cd build
sudo apt-get install -y cmake
cmake ..
make

# Copy files to proper location
sudo cp ../include/cnmem.h /usr/local/cuda/include
sudo cp *.so /usr/local/cuda/lib64/
cd ../..

Pour utiliser avec Theano, vous devez ajouter le drapeau lib.cnmem. Exemple:

THEANO_FLAGS='mode=FAST_RUN,device=gpu,floatX=float32,lib.cnmem=0.8,optimizer_including=cudnn' python gpu_test.py

La première sortie du script devrait être :

Using gpu device 0: GeForce GTX TITAN X (CNMeM is enabled with initial size: 80.0% of memory, cuDNN 5005)

lib.cnmem=0.8 signifie qu’il peut utiliser jusqu’à 80 % du GPU.

CNMeM a été signalé comme apportant des améliorations de vitesse intéressantes et est pris en charge par Theano, Torch et Caffee.

Théano - source 1:

La vitesse dépend de nombreux facteurs, comme les formes et le modèle lui-même. L’accélération passe de 0 à 2 fois plus rapide.

Theano - source 2 :

Si vous ne modifiez pas le drapeau Theano allow_gc, vous pouvez vous attendre à une accélération de 20 % sur le GPU. Dans certains cas (petits modèles), nous avons constaté une accélération de 50 %.


Problèmes courants :

Installation ou configuration

Instructions détaillées sur la configuration ou l’installation de theano.

Exécution de Theano sur plusieurs cœurs de processeur

Vous pouvez exécuter Theano sur plusieurs cœurs de processeur avec le OMP_NUM_THREADS=[number_of_cpu_cores] flag.

Exemple:

OMP_NUM_THREADS=4 python gpu_test.py 

Le script theano/misc/check_blas.py affiche des informations sur le BLAS utilisé :

cd [theano_git_directory]
OMP_NUM_THREADS=4 python theano/misc/check_blas.py

Votre premier programme theano

Dans cet exemple, nous allons compiler des fonctions qui calculent la somme et la différence étant donné deux nombres réels.

from __future__ import print_function
import theano
import theano.tensor as T

#define two symbolic scalar
s_x = T.fscalar()
s_y = T.fscalar()

#compute something
s_sum = s_x + s_y
s_diff = s_x - s_y

#compile a function that adds two number
#theano will call system compiler at here
fn_add = theano.function(inputs=[s_x, s_y], outputs=s_sum)
fn_diff = theano.function(inputs=[s_x, s_y], outputs=s_diff)

#call the compiled functions
print(fn_add(2., 2.)) #4.
print(fn_diff(2., 2.)) #0.