O Keras com back-end Tensorflow pode ser forçado a usar CPU ou GPU à vontade?

96

Eu tenho o Keras instalado com o back-end Tensorflow e CUDA. Às vezes, eu gostaria de forçar Keras a usar a CPU. Isso pode ser feito sem dizer instalar um Tensorflow separado apenas de CPU em um ambiente virtual? Se sim, como? Se o backend fosse Theano, os sinalizadores poderiam ser definidos, mas eu não ouvi falar dos sinalizadores do Tensorflow acessíveis via Keras.

mikal94305
fonte

Respostas:

102

Se você quiser forçar Keras a usar CPU

Caminho 1

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

antes de importar o Keras / Tensorflow.

Caminho 2

Execute seu script como

$ CUDA_VISIBLE_DEVICES="" ./your_keras_code.py

Veja também

  1. https://github.com/keras-team/keras/issues/152
  2. https://github.com/fchollet/keras/issues/4613
Martin Thoma
fonte
19
Não funcionou para mim (Keras 2, Windows) - teve que definir os.environ['CUDA_VISIBLE_DEVICES'] = '-1'como na resposta abaixo
desertnaut
3
A que problema se refere o nº 152? Um link seria bom.
Martin R.
Não vejo nenhuma referência CUDA_DEVICE_ORDER=PCI_BUS_IDna edição nº 152
Thawn em
Estou em um terminal ipython3 e configurei import os os.environ["CUDA_DEVICE_ORDER"] = "PCI_BUS_ID" # see issue #152 os.environ["CUDA_VISIBLE_DEVICES"] = "" , agora como faço para "desfazer" isso? Gostaria que Keras usasse a GPU novamente.
Gabriel C de
1
@Gabriel C: você desfaz deletando essas linhas.
Martin Thoma de
68

Uma maneira bastante separável de fazer isso é usar

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)

Aqui, com booleans GPUe CPU, indicamos se gostaríamos de executar nosso código com a GPU ou CPU, definindo rigidamente o número de GPUs e CPUs que a sessão do Tensorflow pode acessar. As variáveis num_GPUe num_CPUdefinem este valor. num_coresem seguida, define o número de núcleos de CPU disponíveis para uso via intra_op_parallelism_threadse inter_op_parallelism_threads.

A intra_op_parallelism_threadsvariável determina o número de threads que uma operação paralela em um único nó no gráfico de computação pode usar (intra). Enquanto a inter_ops_parallelism_threadsvariável define o número de threads acessíveis para operações paralelas entre os nós do gráfico de computação (inter).

allow_soft_placement permite que as operações sejam executadas na CPU se qualquer um dos seguintes critérios forem atendidos:

  1. não há implementação de GPU para a operação

  2. não há dispositivos GPU conhecidos ou registrados

  3. há uma necessidade de co-localizar com outras entradas da CPU

Tudo isso é executado no construtor da minha classe antes de qualquer outra operação e é completamente separável de qualquer modelo ou outro código que eu uso.

Nota: Isso requer tensorflow-gpue cuda/ cudnndeve ser instalado porque a opção é fornecida para usar uma GPU.

Refs:

RACKGNOME
fonte
1
Esta é uma boa solução, pois apenas definir "CUDA_VISIBLE_DEVICES" causa CUDA_ERROR_NO_DEVICE seguido de muitos diagnósticos antes de continuar a execução na CPU. Embora ... ambos os métodos funcionem!
jsfa11
1
Esta é a única solução consistente que funciona para mim. Continue voltando para ele.
Authman Apatira
1
Você pode explicar o que os outros parâmetros significam? como allow_soft_placement, intra_op_parallelism_threads,inter_op_parallelism_threads
Nagabhushan SN
são inter/ intra_op_parallelism_threadsreferem-se a operações de CPU ou GPU?
bluesummers de
1
@bluesummers Eles pertencem à paralelização de CPU
RACKGNOME
57

Isso funcionou para mim (win10), coloque antes de importar keras:

import os
os.environ['CUDA_VISIBLE_DEVICES'] = '-1'
Neuraléptico
fonte
o que isso faz?
kRazzy R
4
Com Win, força o TF a usar CPU e ignorar qualquer GPU. Não tive sorte com 0 ou em branco, mas -1 parecia funcionar.
Neuraléptico de
1
Trabalhou em Win10 x64 para mim. Eu também não tive sorte em ganhar 0 ou branco e apenas -1 funcionou.
Cypher
4
Trabalhou para mim no Ubuntu
TripleS
Eu tenho duas GPUs em minha máquina, definir 'CUDA_VISIBLE_DEVICES' = 0/1 se refere à ID física das GPUs disponíveis. Definir como -1 usa CPU.
Prashanth Muthurajaiah
30

Basta importar tensortflow e usar keras, é muito fácil.

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
fonte
2
A melhor resposta aqui
xssChauhan
5
Quando defini o tf.device('/cpu:0'), ainda posso ver a memória sendo alocada para o python posteriormente com nvidia-smi.
CMCDragonkai
@CMCDragonkai Resolva ou não ^ _ ^?
lhdgriver
4
Não parece funcionar para mim também, ainda usa gpu quando eu configuro para usar cpu
liyuan
Não deve ser também a definição do modelo e a compilação executada sob o mesmo with?
matt525252
22

De acordo com o tutorial do keras , você pode simplesmente usar o mesmo tf.deviceescopo do tensorflow regular:

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
fonte
2
Como isso pode ser feito no Keras com Tensorflow como back-end, em vez de usar o Tensorflow para chamar as camadas Keras?
mikal94305
Eu não entendo sua pergunta. O código interno withpode ser qualquer código Keras.
sygi
1
Como isso pode ser feito com um modelo treinado carregado do disco? Atualmente, estou treinando em GPU, mas quero verificar depois na CPU
ghostbust555
Não acho que esses modelos sejam intercambiáveis.
Sygi
3
Consegui mudar o treinamento de gpu para cpu no meio do treinamento usando o método mencionado acima, em que salvo o modelo intermediário com model.save e recarrego-o com um tf.device diferente usando keras.models.load_model. O mesmo se aplica se você deseja treinar e prever em um dispositivo diferente.
TheLoneNut
3

Acabei de passar algum tempo descobrindo. A resposta de Thoma não está completa. Diga que seu programa étest.py , você deseja usar gpu0 para executar este programa e manter outros gpus livres.

Você deveria escrever CUDA_VISIBLE_DEVICES=0 python test.py

Observe que DEVICESnão éDEVICE

DDz
fonte
0

Para pessoas que trabalham no PyCharm e para forçar a CPU, você pode adicionar a seguinte linha na configuração Executar / Depurar, em Variáveis ​​de ambiente:

<OTHER_ENVIRONMENT_VARIABLES>;CUDA_VISIBLE_DEVICES=-1
aprendiz
fonte