Как установить конкретный gpu в тензорном потоке?

Я хочу указать gpu для запуска моего процесса. И я установил его следующим образом:

import tensorflow as tf
with tf.device('/gpu:0'):
    a = tf.constant(3.0)
with tf.Session() as sess:
    while True:
        print sess.run(a)

Однако он по-прежнему выделяет память в обоих моих двух gpus.

|    0      7479    C   python                         5437MiB 
|    1      7479    C   python                         5437MiB 

Ответ 1

Я считаю, что вам нужно установить CUDA_VISIBLE_DEVICES=1. Или какой GPU вы хотите использовать. Если вы сделаете видимым только один графический процессор, вы будете называть его /gpu:0 в тензорном потоке независимо от того, для какой переменной среды вы установили.

Больше информации об этой переменной среды: https://devblogs.nvidia.com/cuda-pro-tip-control-gpu-visibility-cuda_visible_devices/

Ответ 2

Для этого есть 3 способа:

  1. Использование переменной окружения CUDA_VISIBLE_DEVICES. путем установки переменной среды CUDA_VISIBLE_DEVICES="1" делает видимым только устройство 1, а путем установки CUDA_VISIBLE_DEVICES="0,1" делает видимыми устройства 0 и 1. Вы можете сделать это в Python, имея строку os.environ["CUDA_VISIBLE_DEVICES"]="0,1" после импорта пакета os.

  2. Использование with tf.device('/gpu:2') и создание графика. Затем он будет использовать графическое устройство 2 для запуска.

  3. Используя config = tf.ConfigProto(device_count = {'GPU': 1}), а затем sess = tf.Session(config=config). Это будет использовать устройство GPU 1.

Ответ 3

TF выделяет всю доступную память на каждом видимом графическом процессоре, если не указано иное. Вот 5 способов придерживаться только одного (или нескольких) графических процессоров.

Решение Bash. Установите CUDA_VISIBLE_DEVICES=0,1 в своем терминале/консоли перед запуском ноутбука Python или Jupyter:

$CUDA_VISIBLE_DEVICES=0,1 python script.py

Решение Python. выполните следующие 2 строки кода перед созданием сеанса

import os
os.environ["CUDA_VISIBLE_DEVICES"]="0,1"

Автоматизированное решение. Приведенный ниже метод автоматически обнаружит устройства с графическим процессором, которые не используются другими сценариями, и установит для вас CUDA_VISIBLE_DEVICES. Вы должны вызвать mask_unused_gpus перед построением сеанса. Это отфильтрует графические процессоры по текущему использованию памяти. Таким образом, вы можете запускать несколько экземпляров вашего скрипта одновременно, не изменяя код и не устанавливая параметры консоли.

Функция:

import subprocess as sp
import os

def mask_unused_gpus(leave_unmasked=1):
  ACCEPTABLE_AVAILABLE_MEMORY = 1024
  COMMAND = "nvidia-smi --query-gpu=memory.free --format=csv"

  try:
    _output_to_list = lambda x: x.decode('ascii').split('\n')[:-1]
    memory_free_info = _output_to_list(sp.check_output(COMMAND.split()))[1:]
    memory_free_values = [int(x.split()[0]) for i, x in enumerate(memory_free_info)]
    available_gpus = [i for i, x in enumerate(memory_free_values) if x > ACCEPTABLE_AVAILABLE_MEMORY]

    if len(available_gpus) < leave_unmasked: raise ValueError('Found only %d usable GPUs in the system' % len(available_gpus))
    os.environ["CUDA_VISIBLE_DEVICES"] = ','.join(map(str, available_gpus[:leave_unmasked]))
  except Exception as e:
    print('"nvidia-smi" is probably not installed. GPUs are not masked', e)

mask_unused_gpus(2)

Ограничения: если вы запустите несколько сценариев одновременно, это может вызвать коллизию, поскольку память не выделяется сразу при создании сеанса. В случае, если это проблема для вас, вы можете использовать рандомизированную версию, как в оригинальном исходном коде: mask_busy_gpus()

Tensorflow 2.0 предлагает еще один метод:

gpus = tf.config.experimental.list_physical_devices('GPU')
if gpus:
  # Restrict TensorFlow to only use the first GPU
  try:
    tf.config.experimental.set_visible_devices(gpus[0], 'GPU')
  except RuntimeError as e:
    # Visible devices must be set at program startup
    print(e)

Tensorflow/Keras также позволяет указать gpu для использования с конфигурацией сессии. Я могу рекомендовать его только в том случае, если установка переменной среды не является опцией (то есть запуск MPI). Потому что он, как правило, наименее надежный из всех методов, особенно с керасом.

config = tf.ConfigProto()
config.gpu_options.visible_device_list = "0,1"
with tf.Session(config) as sess:
#or K.set_session(tf.Session(config))

Ответ 4

Вы можете изменить настройки параметров графического процессора, добавив в начале своего скрипта Python:

gpu_options = tf.GPUOptions(visible_device_list="0")
sess = tf.Session(config=tf.ConfigProto(gpu_options=gpu_options))

"0" - это имя графического процессора, который вы хотите использовать. Вы можете получить список доступных графических процессоров, введя команду nvidia-smi в командной строке терминала.


В Keras эти 2 функции позволяют выбрать процессор или графический процессор, а в случае графического процессора - долю памяти, которая будет использоваться.

import os
from keras.backend.tensorflow_backend import set_session
import tensorflow as tf



def set_cpu_option():
    os.environ["CUDA_DEVICE_ORDER"] = "PCI_BUS_ID"  # see issue #152
    os.environ["CUDA_VISIBLE_DEVICES"] = ""
    os.environ["CUDA_VISIBLE_DEVICES"] = ""


def set_gpu_option(which_gpu, fraction_memory):
    config = tf.ConfigProto()
    config.gpu_options.per_process_gpu_memory_fraction = fraction_memory
    config.gpu_options.visible_device_list = which_gpu
    set_session(tf.Session(config=config))
    return

set_gpu_option("0", 0.9)
# or 
set_cpu_option()