Keras avec le backend Tensorflow peut-il être forcé d'utiliser le CPU ou le GPU à volonté?

96

J'ai Keras installé avec le backend Tensorflow et CUDA. J'aimerais parfois forcer Keras à utiliser le processeur. Cela peut-il être fait sans, par exemple, installer un Tensorflow séparé, uniquement CPU, dans un environnement virtuel? Si c'est le cas, comment? Si le backend était Theano, les indicateurs pourraient être définis, mais je n'ai pas entendu parler des indicateurs Tensorflow accessibles via Keras.

mikal94305
la source

Réponses:

102

Si vous souhaitez forcer Keras à utiliser le processeur

Voie 1

import os
os.environ["CUDA_DEVICE_ORDER"] = "PCI_BUS_ID"   # see issue #152
os.environ["CUDA_VISIBLE_DEVICES"] = ""

avant l'importation de Keras / Tensorflow.

Voie 2

Exécutez votre script en tant que

$ CUDA_VISIBLE_DEVICES="" ./your_keras_code.py

Voir également

  1. https://github.com/keras-team/keras/issues/152
  2. https://github.com/fchollet/keras/issues/4613
Martin Thoma
la source
19
Cela n'a pas fonctionné pour moi (Keras 2, Windows) - a dû définir os.environ['CUDA_VISIBLE_DEVICES'] = '-1'comme dans une réponse ci
desertnaut
3
À quel problème fait référence le n ° 152? Un lien serait bien.
Martin R.
Je ne vois aucune référence à CUDA_DEVICE_ORDER=PCI_BUS_IDdans le numéro 152
Dégel
Je suis dans un terminal ipython3 et j'ai défini import os os.environ["CUDA_DEVICE_ORDER"] = "PCI_BUS_ID" # see issue #152 os.environ["CUDA_VISIBLE_DEVICES"] = "" , maintenant comment "annuler" cela? J'aimerais que Keras utilise à nouveau le GPU.
Gabriel C
1
@Gabriel C: vous l'annulez en supprimant ces lignes.
Martin Thoma
68

Une façon plutôt séparable de faire ceci est d'utiliser

import tensorflow as tf
from keras import backend as K

num_cores = 4

if GPU:
    num_GPU = 1
    num_CPU = 1
if CPU:
    num_CPU = 1
    num_GPU = 0

config = tf.ConfigProto(intra_op_parallelism_threads=num_cores,
                        inter_op_parallelism_threads=num_cores, 
                        allow_soft_placement=True,
                        device_count = {'CPU' : num_CPU,
                                        'GPU' : num_GPU}
                       )

session = tf.Session(config=config)
K.set_session(session)

Ici, avec booleans GPUet CPU, nous indiquons si nous souhaitons exécuter notre code avec le GPU ou le CPU en définissant de manière rigide le nombre de GPU et de CPU auxquels la session Tensorflow est autorisée à accéder. Les variables num_GPUet num_CPUdéfinissez cette valeur. num_coresdéfinit ensuite le nombre de cœurs CPU disponibles pour une utilisation via intra_op_parallelism_threadsetinter_op_parallelism_threads .

La intra_op_parallelism_threadsvariable dicte le nombre de threads qu'une opération parallèle dans un seul nœud du graphe de calcul est autorisée à utiliser (intra). Alors que la inter_ops_parallelism_threadsvariable définit le nombre de threads accessibles pour les opérations parallèles à travers les nœuds du graphe de calcul (inter).

allow_soft_placement permet d'exécuter des opérations sur la CPU si l'un des critères suivants est rempli:

  1. il n'y a pas d'implémentation GPU pour l'opération

  2. il n'y a aucun périphérique GPU connu ou enregistré

  3. il est nécessaire de co-localiser avec d'autres entrées du CPU

Tout cela est exécuté dans le constructeur de ma classe avant toute autre opération, et est complètement séparable de tout modèle ou autre code que j'utilise.

Remarque: Cela nécessite tensorflow-gpuet cuda/ cudnndoit être installé car l'option est donnée d'utiliser un GPU.

Réf:

RACKGNOME
la source
1
C'est une bonne solution car la simple définition de "CUDA_VISIBLE_DEVICES" provoque CUDA_ERROR_NO_DEVICE suivi de nombreux diagnostics avant de continuer à s'exécuter sur le CPU. Bien que ... les deux méthodes fonctionnent!
jsfa11
1
C'est la seule solution cohérente qui fonctionne pour moi. Continuez à y revenir.
Authman Apatira
1
Pouvez-vous expliquer ce que signifient les autres paramètres? comme allow_soft_placement, intra_op_parallelism_threads,inter_op_parallelism_threads
Nagabhushan SN
sont les inter/ se intra_op_parallelism_threadsréfèrent aux opérations CPU ou GPU?
bluesummers
1
@bluesummers Ils concernent la parallélisation du processeur
RACKGNOME
59

Cela a fonctionné pour moi (win10), place avant d'importer des keras:

import os
os.environ['CUDA_VISIBLE_DEVICES'] = '-1'
Neuraleptique
la source
qu'est-ce que cela fait?
kRazzy R
4
Avec Win, force TF à utiliser le CPU et à ignorer tout GPU. Je n'ai pas eu de chance avec 0 ou avec un blanc, mais -1 semblait faire l'affaire.
Neuraleptic
1
J'ai travaillé sur Win10 x64 pour moi. Je n'ai pas non plus eu de chance de gagner 0 ou de blanc et seulement -1 a fonctionné.
Chiffre du
4
A travaillé pour moi sur Ubuntu
TripleS
J'ai deux GPU dans ma machine, le réglage de 'CUDA_VISIBLE_DEVICES' = 0/1 fait référence à l'ID physique des GPU disponibles. Le définir sur -1 utilise le processeur.
Prashanth Muthurajaiah
30

Il suffit d'importer tensortflow et d'utiliser des keras, c'est aussi simple que cela.

import tensorflow as tf
# your code here
with tf.device('/gpu:0'):
    model.fit(X, y, epochs=20, batch_size=128, callbacks=callbacks_list)
harshlal028
la source
2
La meilleure réponse ici
xssChauhan
5
Lorsque j'ai défini le tf.device('/cpu:0'), je pouvais toujours voir la mémoire allouée à python plus tard avec nvidia-smi.
CMCDragonkai
@CMCDragonkai Résolvez-le ou pas ^ _ ^?
lhdgriver
4
Cela ne semble pas non plus fonctionner pour moi, utilise toujours gpu lorsque je le configure pour utiliser cpu
liyuan
Ne devrait pas être également la définition du modèle et la compilation exécutée sous le même with?
matt525252
22

Selon le didacticiel keras , vous pouvez simplement utiliser la même tf.deviceportée que dans le tensorflow normal:

with tf.device('/gpu:0'):
    x = tf.placeholder(tf.float32, shape=(None, 20, 64))
    y = LSTM(32)(x)  # all ops in the LSTM layer will live on GPU:0

with tf.device('/cpu:0'):
    x = tf.placeholder(tf.float32, shape=(None, 20, 64))
    y = LSTM(32)(x)  # all ops in the LSTM layer will live on CPU:0
sygi
la source
2
Comment cela peut-il être fait dans Keras avec Tensorflow comme backend, plutôt que d'utiliser Tensorflow pour appeler des couches Keras?
mikal94305
Je ne comprends pas votre question. Le code à l'intérieur withpeut être n'importe quel code Keras.
sygi
1
Comment cela peut-il être fait avec un modèle entraîné chargé à partir du disque? Je suis actuellement en train de m'entraîner sur le GPU mais je veux vérifier ensuite sur le CPU
ghostbust555
3
J'ai pu basculer l'entraînement de gpu à cpu au milieu de l'entraînement en utilisant la méthode mentionnée ci-dessus où j'enregistre le modèle entre les deux avec model.save puis le recharge avec un tf.device différent en utilisant keras.models.load_model. La même chose s'applique si vous souhaitez vous entraîner puis prédire sur un appareil différent.
TheLoneNut
3

Je viens de passer un peu de temps à comprendre. La réponse de Thoma n'est pas complète. Disons que votre programme est test.py, vous voulez utiliser gpu0 pour exécuter ce programme et garder les autres gpus libres.

Tu devrais écrire CUDA_VISIBLE_DEVICES=0 python test.py

Remarquez que ce n'est DEVICESpasDEVICE

DDz
la source
0

Pour les personnes travaillant sur PyCharm et pour forcer le processeur, vous pouvez ajouter la ligne suivante dans la configuration Exécuter / Déboguer, sous Variables d'environnement:

<OTHER_ENVIRONMENT_VARIABLES>;CUDA_VISIBLE_DEVICES=-1
apprenant
la source