Empezando con theano

Instalar Theano y configurar la GPU en Ubuntu 14.04

Puede usar las siguientes instrucciones para instalar Theano y configurar la GPU (suponga que tiene Ubuntu 14.04 recién instalado):

# 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

En ese momento, ejecutar nvidia-smi debería funcionar, pero ejecutar nvcc no funcionará.

# 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

En ese momento, tanto nvidia-smi como nvcc deberían funcionar.

Para probar si Theano puede usar la GPU:

Copie y pegue lo siguiente en 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

y ejecutarlo:

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

que debe devolver:

[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

Para saber tu versión de CUDA:

​nvcc -V

Ejemplo:

[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

Agregar cuDNN

Para agregar cuDNN (instrucciones de http://deeplearning.net/software/theano/library/sandbox/cuda/dnn.html):

  1. Descargue cuDNN de https://developer.nvidia.com/rdp/cudnn-download (es necesario registrarse, que es gratuito)
  2. tar -xvf cudnn-7.0-linux-x64-v3.0-prod.tgz
  3. Realice una de las siguientes

Opción 1: Copie los archivos *.h a CUDA_ROOT/include y los archivos *.so* a CUDA_ROOT/lib64 (de forma predeterminada, CUDA_ROOT es /usr/local/cuda en Linux ).

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

Opcion 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

De forma predeterminada, Theano detectará si puede usar cuDNN. Si es así, lo usará. De lo contrario, las optimizaciones de Theano no introducirán operaciones cuDNN. Entonces Theano seguirá funcionando si el usuario no los introdujo manualmente.

Para obtener un error si Theano no puede usar cuDNN, use este indicador de Theano: optimizer_incluyendo=cudnn.

Ejemplo:

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

Para saber tu versión de cuDNN:

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

Agregar CNMeM

La biblioteca CNMeM es una “biblioteca simple para ayudar a los marcos de aprendizaje profundo a administrar la memoria 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 ../..

Para usar con Theano, debe agregar el indicador lib.cnmem. Ejemplo:

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

La primera salida del script debería ser:

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

lib.cnmem=0.8 significa que puede usar hasta el 80% de la GPU.

Se ha informado que CNMeM brinda algunas mejoras de velocidad interesantes y cuenta con el apoyo de Theano, Torch y Caffee.

Theano - fuente 1:

La aceleración depende de muchos factores, como las formas y el modelo en sí. La velocidad aumenta de 0 a 2 veces más rápido.

Theano - fuente 2:

Si no cambia la bandera de Theano allow_gc, puede esperar un 20% de aceleración en la GPU. En algunos casos (modelos pequeños), vimos un 50% de aceleración.


Problemas comunes:

  • [Importando theano: AttributeError: el objeto ‘módulo’ no tiene atributo ‘find_graphviz’] (http://stackoverflow.com/q/38446771/395857)

Instalación o configuración

Instrucciones detalladas sobre cómo configurar o instalar theano.

Ejecutando Theano en múltiples núcleos de CPU

Puede ejecutar Theano en múltiples núcleos de CPU con el indicador OMP_NUM_THREADS=[number_of_cpu_cores].

Ejemplo:

OMP_NUM_THREADS=4 python gpu_test.py 

El script theano/misc/check_blas.py genera información sobre qué BLAS se usa:

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

Tu primer programa theano

En este ejemplo, compilaremos funciones que calculan la suma y la diferencia dados dos números reales.

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.