Comparando CPUs y GPUs para inteligencia artificial

Comparando CPUs y GPUs para inteligencia artificial

16 septiembre 2019 0 Por Alvaro

En el mundo de la inteligencia artificial se habla mucho sobre coches autónomos, drones que persiguen un objetivo común (créditos a mi compañero Ricardo García Pinel) o robots que dan volteretas procesando los datos que obtienen de su entorno. Una de las cosas que tienen en común es la forma de procesar los datos que obtienen de las imágenes. Lo hacen por medio de unidades de procesamiento gráfico (Graphics processing unit – GPUs).

Pero un momento, Álvaro, ¿qué es eso de las GPUs? ¿Por qué un coche autónomo no procesa con un microprocesador normal y corriente de toda la vida como un Intel?

Antes de continuar voy a hablar un poco en “lenguaje llano” sobre las GPUs y las CPUs, ya que está bien al menos entender las principales diferencias.

GPUs y CPUs:


Básicamente, en los ordenadores normales de hoy en día se pueden utilizar dos unidades de procesamiento para realizar cálculos: por un lado, se encuentran las unidades de procesamiento central (CPUs) y, por otro, las unidades de procesamiento gráfico (GPUs).

  • CPUs: son los microprocesadores que se han utilizado siempre como unidad de procesamiento. Estos microprocesadores son muy muy buenos haciendo tareas secuenciales, que no se pueden paralelizar. Hay distintas marcas, las más conocidas y que compiten por prácticamente todo el mercado son Intel y AMD.
  • GPUs: son los procesadores gráficos que tienen las tarjetas gráficas. Se usan muchísimo para gaming, donde los videojuegos se benefician de la manera de procesar matrices que tienen las GPUs. Al fin y al cabo, las imágenes en HD no dejan de ser la unión de matrices de datos… Entre las marcas más conocidas se encuentran Nvidia y AMD.

La diferencia más importante entre los dos componentes a nivel de arquitectura es el número de núcleos que suelen tener. Las CPUs tienen muchos menos núcleos que las GPUs, lo que hace que para procesamiento paralelo sean peores. Sin embargo, los núcleos de las CPUs son mucho más potentes, por lo que para tareas secuenciales son mucho mejores.

Comparativa de las arquitecturas de una CPU y de una GPU

Las tarjetas gráficas inicialmente tuvieron como propósito el de servir para procesar imágenes, pero se ha ido aprovechando su potencia para problemas de cálculo matricial. Inicialmente los desarrolladores que usaban la potencia de las GPUs para sus problemas matemáticos tenían que traducir sus problemas a triángulos y polígonos. Afortunadamente, este hecho cambió con la llegada de las arquitecturas CUDA, que permitían usar las GPUs para cálculo paralelo de propósito general.

Actualmente, usando Python, C, Fortran… es posible utilizar CUDA para calcular problemas matemáticos con GPUs. En mi caso, he tenido la  curiosidad de comparar la capacidad de cómputo de las CPUs y de las GPUs para ver si era verdad todo lo que había leído sobre la potencia de las GPUs en cálculos sobre matrices.

Comparativa de cálculo matricial entre CPUs y GPUs:


He querido comparar el rendimiento de una CPU y de una GPU de las que se venden en el mercado. Para llevar a cabo esta comparativa he utilizado el siguiente hardware:

  • CPU: AMD Ryzen 5 3600
  • GPU: Asus Geforce GTX 1060

Comparativa Ryzen vs Asus Geforce GTX 1060

En materia de software, para hacer la comparativa he utilizado Tensorflow, Python como lenguaje de programación y Jupyter Notebooks como entorno de desarrollo.

El código que he usado para la comparativa es el siguiente:

import sys
import numpy as np
import tensorflow as tf
from datetime import datetime

def prueba_dispositivo(nombre_dispositivo, tamanio_matriz):
    '''
    Calcula el tiempo consumido en hacer multiplicaciones 
    matriciales usando un dispositivo y un tamaño de filas y 
    columnas de la matriz aleatoria
 
    :param nombre_dispositivo: nombre del dispositivo reconocible
                               para tensorflow
    :param tamanio_matriz: número de filas y de columnas de 
                           la matriz aleatoria

    Ejemplo:

             prueba_dispositivo("/cpu:0", 100)
    '''
    dimension=(int(tamanio_matriz),int(tamanio_matriz))

    with tf.device(nombre_dispositivo):
        random_matrix = tf.random_uniform(shape=dimension, 
                            minval=0, maxval=1, seed=1993)
        dot_operation = tf.matmul(random_matrix, 
                           tf.transpose(random_matrix))
        sum_operation = tf.reduce_sum(dot_operation)

    inicio = datetime.now()
    with tf.Session(config=tf.ConfigProto(log_device_placement=True)) 
                                         as session:
            result = session.run(sum_operation)
    tiempo_consumido = datetime.now() - inicio
    return tiempo_consumido

resultados = {'CPU':[], 'GPU':[]}
for tamanio_matriz in np.geomspace(10, 15000, num=200):
    resultados['CPU'].append(prueba_dispositivo("/cpu:0", 
                                                tamanio_matriz))
    resultados['GPU'].append(prueba_dispositivo("/gpu:0", 
                                                tamanio_matriz))

Se trata de un problema bastante sencillo de multiplicación de matrices en función del tamaño de las mismas. En este caso he querido generar las mismas matrices para ambos componentes (así elimino el sesgo aleatorio de generación de datos) y he calculado el tiempo de procesamiento que consume cada uno de los dispositivos.

Los resultados del análisis de rendimiento que he conseguido los podemos ver en la siguiente representación:

La GPU, clara vencedora en cálculo matricial

Como vemos, inicialmente cuando la matriz es muy pequeña no hay apenas diferencia entre procesar con CPUs o con GPUs. Sin embargo, a medida que aumenta el tamaño de las matrices, el tiempo consumido por la CPU aumenta de manera exponencial, no así en el caso de las GPUs. El tiempo máximo de las CPUs en este experimento es de 25 segundos y la diferencia ya empieza a ser muy notoria si comparamos con las GPUs. La diferencia para matrices mucho más grandes es abismal, siendo las GPUs claras ganadoras para procesamiento matricial en paralelo. Muy útiles además de para procesamiento de redes convolucionales, para el procesamiento de muchos datos donde los cálculos matriciales sean una norma.

Espero que este artículo os sirva como prueba de la capacidad de las GPUs para procesamiento matricial y, en especial, para procesamiento de problemas con redes neuronales. ¿Usas GPUs para problemas matemáticos?,  déjanos un comentario 😀

¡Comparte!