web-dev-qa-db-fra.com

Pourquoi mon GPU est-il plus lent que le CPU lors de la formation de modèles LSTM/RNN?

Ma machine a les spécifications suivantes: 

CPU: Xeon E5-1620 v4

GPU: Titan X (Pascal) 

Ubuntu 16.04

Pilote Nvidia 375.26

CUDA a pris 8.0

nuDuN 5.1

Je me suis référencé sur les exemples Keras suivants avec Tensorflow comme référence référence

SCRIPT NAME                  GPU       CPU
stated_lstm.py               5sec      5sec 
babi_rnn.py                  10sec     12sec
imdb_bidirectional_lstm.py   240sec    116sec
imbd_lstm.py                 113sec    106sec

Mon gpu est clairement en train d'exécuter mon cpu dans des modèles non lstm. 

SCRIPT NAME                  GPU       CPU
cifar10_cnn.py               12sec     123sec
imdb_cnn.py                  5sec      119sec
mnist_cnn.py                 3sec      47sec 

Quelqu'un d'autre a-t-il vécu cela? 

18
agsolid

Si vous utilisez Keras, utilisez CuDNNLSTM à la place de LSTM ou CuDNNGRU à la place de GRU . Dans mon cas (2 Tesla M60), je vois 10 fois plus de performances. En passant, j'utilise la taille de lot 128 suggérée par @Alexey Golyshev.

13
neurite

Trop petite taille de lot. Essayez d'augmenter.

Résultats pour ma GTX1050Ti:

 imdb_bidirectional_lstm.py 
 batch_size time 
 32 (par défaut) 252 
 64 131 
 96. .32 (valeur par défaut) 108 
 64 50 
 96 34 
 128 25 
12
Alexey Golyshev

J'ai des problèmes similaires ici:

Test 1

CPU: CPU E5-2697 v3 @ 2,60 GHz des processeurs Intel (X) Xeon (MD)

Ubuntu 14.04

imdb_bidirectional_lstm.py: 155s

Test 2

GPU: GTX 860m

Pilote Nvidia: 369,30

CUDA Toolkit: V8.0

nuDu: v6.0

imdb_bidirectional_lstm.py: 450s

Analyser

Quand j'observe la courbe de charge du GPU, j'ai trouvé une chose intéressante: 

  • pour lstm, la charge du processeur graphique saute rapidement entre ~ 80% et ~ 10%

charge GPU

Ceci est principalement dû au calcul séquentiel dans la couche LSTM. N'oubliez pas que LSTM nécessite une entrée séquentielle pour calculer les pondérations des couches masquées de manière itérative. En d'autres termes, vous devez attendre l'état masqué au moment t-1 pour calculer l'état masqué au moment t

Ce n'est pas une bonne idée pour les cœurs GPU, car ce sont de nombreux petits cœurs qui aiment faire des calculs en parallèle. La calcul séquentiel ne peut pas utiliser pleinement leurs capacités de calcul. C'est pourquoi nous constatons une charge de GPU d'environ 10% à 20% la plupart du temps.

Mais dans la phase de rétropropagation, le processeur graphique peut exécuter un calcul dérivé en parallèle, ce qui permet d’observer un pic de charge du processeur graphique d’environ 80%.

3
Zekun Zhang

C'est juste un pourboire. 

L'utilisation du GPU est puissante quand

  1. votre réseau de neurones est grand.

  2. votre taille_batch est grande.

- C'est ce que j'ai trouvé de googler. 

1
Dane Lee