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) :
- Téléchargez cuDNN depuis https://developer.nvidia.com/rdp/cudnn-download (nécessite une inscription, qui est gratuite)
tar -xvf cudnn-7.0-linux-x64-v3.0-prod.tgz
- 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.
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.
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.