Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
tensorflow
GitHub Repository: tensorflow/docs-l10n
Path: blob/master/site/pt-br/guide/gpu.ipynb
25115 views
Kernel: Python 3
#@title Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # # https://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License.

O código do TensorFlow e os modelos do tf.keras são executados de forma transparente em uma única GPU sem precisar de alterações no código.

Observação: use tf.config.list_physical_devices('GPU') para confirmar que o TensorFlow está usando a GPU.

A maneira mais simples de executar em várias GPUs, em uma ou várias máquinas, é usando as estratégias de distribuição.

Este guia é para usuários que tentaram essas estratégias e descobriram que precisam controlar de forma granular como o TensorFlow usa a GPU. Para ver como fazer a depuração de problemas de desempenho para cenários com uma ou várias GPUs, confira o guia Otimize o desempenho de GPUs no TensorFlow.

Configuração

Confirme se a versão de GPU do TensorFlow mais recente está instalada.

import tensorflow as tf print("Num GPUs Available: ", len(tf.config.list_physical_devices('GPU')))

Visão geral

O TensorFlow tem suporte à execução de computações em diversos tipos de dispositivos, incluindo CPUs e GPUs, que são representadas por strings identificadores. Por exemplo:

  • "/device:CPU:0": a CPU da sua máquina.

  • "/GPU:0": notação abreviada para a primeira GPU da sua máquina visível no TensorFlow.

  • "/job:localhost/replica:0/task:0/device:GPU:1": nome totalmente qualificado da segunda GPU da sua máquina visível no TensorFlow.

Se uma operação do TensorFlow tiver implementações para CPUs e GPUs, por padrão o dispositivo com GPU será priorizado quando a operação for atribuída. Por exemplo, tf.matmul tem kernels para CPU e GPU e, em um sistema com dispositivos CPU:0 e GPU:0, o dispositivo GPU:0 será selecionado para executar tf.matmul, a menos que você solicite explicitamente que seja executado em outro dispositivo.

Se uma operação do TensorFlow não tiver uma implementação para GPU correspondente, então a operaçãoo será feita no dispositivo com CPU. Por exemplo, como tf.cast tem apenas um kernel para CPU, em um sistema com dispositivos CPU:0 e GPU:0, o dispositivo CPU:0 será selecionado para executar tf.cast, mesmo que seja solicitado que execute no dispositivo GPU:0.

Log do posicionamento dos dispositivos

Para descobrir a quais dispositivos seus tensores e operações estão atribuídos, defina tf.debugging.set_log_device_placement(True) como a primeira declaração do seu programa. Ao ativar o log do posicionamento dos dispositivos, todas as alocações ou operações de tensores serão exibidas via print.

tf.debugging.set_log_device_placement(True) # Create some tensors a = tf.constant([[1.0, 2.0, 3.0], [4.0, 5.0, 6.0]]) b = tf.constant([[1.0, 2.0], [3.0, 4.0], [5.0, 6.0]]) c = tf.matmul(a, b) print(c)

O código acima exibirá via print que a operação MatMul foi executada na GPU:0.

Posicionamento manual dos dispositivos

Se você quiser que uma operação específica seja executada em um dispositivo da sua escolha em vez do dispositivo selecionado automaticamente, pode usar with tf.device para criar um contexto de dispositivo, e todas as operações dentro desse contexto serão executadas no mesmo dispositivo designado.

tf.debugging.set_log_device_placement(True) # Place tensors on the CPU with tf.device('/CPU:0'): a = tf.constant([[1.0, 2.0, 3.0], [4.0, 5.0, 6.0]]) b = tf.constant([[1.0, 2.0], [3.0, 4.0], [5.0, 6.0]]) # Run on the GPU c = tf.matmul(a, b) print(c)

Você verá que, agora, a e b estão atribuídos à CPU:0. Como um dispositivo não foi especificado explicitamente para a operação MatMul, o runtime do TensorFlow escolherá um baseado na operação e nos dispositivos disponíveis (GPU:0 neste exemplo) e copiará automaticamente os tensores entre os dispositivos, se necessário.

Como limitar o aumento de uso da memória das GPUs

Por padrão, o TensorFlow mapeia praticamente toda a memória de GPU de todas as GPUs (sujeito aos CUDA_VISIBLE_DEVICES) visíveis para o processo. Isso é feito para usar com mais eficiência os recursos de memória de GPU relativamente preciosos nos dispositivos ao reduzir a fragmentação de memória. Para limitar o TensorFlow a um conjunto de GPUs específico, use o método tf.config.set_visible_devices.

gpus = tf.config.list_physical_devices('GPU') if gpus: # Restrict TensorFlow to only use the first GPU try: tf.config.set_visible_devices(gpus[0], 'GPU') logical_gpus = tf.config.list_logical_devices('GPU') print(len(gpus), "Physical GPUs,", len(logical_gpus), "Logical GPU") except RuntimeError as e: # Visible devices must be set before GPUs have been initialized print(e)

Em alguns casos, é desejável que o processo aloque somente uma parte da memória disponível ou aumente o uso de memória conforme o processo precisar. O TensorFlow conta com dois métodos para controlar esse comportamento.

A primeira opção é ativar o aumento de memória chamando tf.config.experimental.set_memory_growth, que tenta alocar somente a quantidade de memória de GPU necessária para as alocações do runtime: ele começa alocando pouquíssima memória e, à medida que o programa é executado e mais memória de GPU se torna necessária, a região de memória de GPU é expandida para o processo do TensorFlow. A memória não é liberada, pois isso poderia levar à sua fragmentação. Para ativar o aumento de memória de uma GPU específica, use o código abaixo antes de alocar qualquer tensor ou executar qualquer operação:

gpus = tf.config.list_physical_devices('GPU') if gpus: try: # Currently, memory growth needs to be the same across GPUs for gpu in gpus: tf.config.experimental.set_memory_growth(gpu, True) logical_gpus = tf.config.list_logical_devices('GPU') print(len(gpus), "Physical GPUs,", len(logical_gpus), "Logical GPUs") except RuntimeError as e: # Memory growth must be set before GPUs have been initialized print(e)

Outra forma de ativar essa opção é definindo a variável de ambiente TF_FORCE_GPU_ALLOW_GROWTH como true. Essa configuração é específica para a plataforma.

O segundo método é configurar um dispositivo com GPUs virtuais por meio de tf.config.set_logical_device_configuration e definir um limite estrito para o total de memória de GPU que será alocada.

gpus = tf.config.list_physical_devices('GPU') if gpus: # Restrict TensorFlow to only allocate 1GB of memory on the first GPU try: tf.config.set_logical_device_configuration( gpus[0], [tf.config.LogicalDeviceConfiguration(memory_limit=1024)]) logical_gpus = tf.config.list_logical_devices('GPU') print(len(gpus), "Physical GPUs,", len(logical_gpus), "Logical GPUs") except RuntimeError as e: # Virtual devices must be set before GPUs have been initialized print(e)

Isso é útil se você quiser verdadeiramente vincular a quantidade de memória de GPU disponível ao processo do TensorFlow, o que é uma prática comum para desenvolvimento local quando a GPU é compartilhada com outras aplicações, como uma interface gráfica do usuário de uma estação de trabalho.

Uso de uma única GPU em um sistema com várias GPUs

Se você tiver mais de uma GPU em seu sistema, a GPU com o menor ID será selecionada por padrão. Se você quiser que a execução seja feita em uma GPU diferente, precisará especificar essa preferência explicitamente:

tf.debugging.set_log_device_placement(True) try: # Specify an invalid GPU device with tf.device('/device:GPU:2'): a = tf.constant([[1.0, 2.0, 3.0], [4.0, 5.0, 6.0]]) b = tf.constant([[1.0, 2.0], [3.0, 4.0], [5.0, 6.0]]) c = tf.matmul(a, b) except RuntimeError as e: print(e)

Se o dispositivo que você especificar não existir, será exibido um erro de dispositivo desconhecido: RuntimeError: .../device:GPU:2 unknown device.

Se você quiser que o TensorFlow escolha automaticamente um dispositivo existente e compatível para executar as operações caso o dispositivo especificado não exista, pode chamar tf.config.set_soft_device_placement(True).

tf.config.set_soft_device_placement(True) tf.debugging.set_log_device_placement(True) # Creates some tensors a = tf.constant([[1.0, 2.0, 3.0], [4.0, 5.0, 6.0]]) b = tf.constant([[1.0, 2.0], [3.0, 4.0], [5.0, 6.0]]) c = tf.matmul(a, b) print(c)

Uso de várias GPUs

Ao desenvolver para usar várias GPUs, o modelo poderá utilizar recursos adicionais. Ao desenvolver em um sistema com uma única GPU, você pode simular várias GPUs por meio de dispositivos virtuais, o que facilita o teste de ambientes com várias GPUs sem exigir recursos adicionais.

gpus = tf.config.list_physical_devices('GPU') if gpus: # Create 2 virtual GPUs with 1GB memory each try: tf.config.set_logical_device_configuration( gpus[0], [tf.config.LogicalDeviceConfiguration(memory_limit=1024), tf.config.LogicalDeviceConfiguration(memory_limit=1024)]) logical_gpus = tf.config.list_logical_devices('GPU') print(len(gpus), "Physical GPU,", len(logical_gpus), "Logical GPUs") except RuntimeError as e: # Virtual devices must be set before GPUs have been initialized print(e)

Quando houver várias GPUs lógicas disponíveis para o runtime, você poderá utilizar as várias GPUs com tf.distribute.Strategy ou com posicionamento manual.

Com tf.distribute.Strategy

A prática recomendada de uso de várias GPUs é utilizar tf.distribute.Strategy. Veja um exemplo simples:

tf.debugging.set_log_device_placement(True) gpus = tf.config.list_logical_devices('GPU') strategy = tf.distribute.MirroredStrategy(gpus) with strategy.scope(): inputs = tf.keras.layers.Input(shape=(1,)) predictions = tf.keras.layers.Dense(1)(inputs) model = tf.keras.models.Model(inputs=inputs, outputs=predictions) model.compile(loss='mse', optimizer=tf.keras.optimizers.SGD(learning_rate=0.2))

Esse programa executará uma cópia do seu modelo em cada GPU, dividindo os dados de entrada entre elas. Isso também é conhecido como "paralelismo de dados".

Confira mais informações sobre estratégias de distribuição neste guia.

Posicionamento manual

tf.distribute.Strategy funciona por baixo dos panos por meio da replicação da computação entre os dispositivos. É possível implementar a replicação manualmente criando seu modelo em cada GPU. Por exemplo:

tf.debugging.set_log_device_placement(True) gpus = tf.config.list_logical_devices('GPU') if gpus: # Replicate your computation on multiple GPUs c = [] for gpu in gpus: with tf.device(gpu.name): a = tf.constant([[1.0, 2.0, 3.0], [4.0, 5.0, 6.0]]) b = tf.constant([[1.0, 2.0], [3.0, 4.0], [5.0, 6.0]]) c.append(tf.matmul(a, b)) with tf.device('/CPU:0'): matmul_sum = tf.add_n(c) print(matmul_sum)