Несколько сеансов Tensorflow с несколькими графическими процессорами

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

Например, я попытался разделить сеансы на разные ресурсы с помощью API-интерфейса python, используя в script1.py:

with tf.device("/gpu:0"):
    # do stuff

в script2.py:

with tf.device("/gpu:1"):
    # do stuff

в script3.py

with tf.device("/cpu:0"):
    # do stuff

Если я запускаю каждый script сам по себе, я вижу, что он использует указанное устройство. (Также модели очень хорошо вписываются в один графический процессор и не используют другой, даже если оба доступны.)

Однако, если один script запущен, и я пытаюсь запустить другой, я всегда получаю эту ошибку:

I tensorflow/core/common_runtime/local_device.cc:40] Local device intra op parallelism threads: 8
I tensorflow/stream_executor/cuda/cuda_gpu_executor.cc:909] successful NUMA node read from SysFS had negative value (-1), but there must be at least one NUMA node, so returning NUMA node zero
I tensorflow/core/common_runtime/gpu/gpu_init.cc:103] Found device 0 with properties: 
name: GeForce GTX 980
major: 5 minor: 2 memoryClockRate (GHz) 1.2155
pciBusID 0000:01:00.0
Total memory: 4.00GiB
Free memory: 187.65MiB
I tensorflow/stream_executor/cuda/cuda_gpu_executor.cc:909] successful NUMA node read from SysFS had negative value (-1), but there must be at least one NUMA node, so returning NUMA node zero
I tensorflow/core/common_runtime/gpu/gpu_init.cc:103] Found device 1 with properties: 
name: GeForce GTX 980
major: 5 minor: 2 memoryClockRate (GHz) 1.2155
pciBusID 0000:04:00.0
Total memory: 4.00GiB
Free memory: 221.64MiB
I tensorflow/core/common_runtime/gpu/gpu_init.cc:127] DMA: 0 1 
I tensorflow/core/common_runtime/gpu/gpu_init.cc:137] 0:   Y Y 
I tensorflow/core/common_runtime/gpu/gpu_init.cc:137] 1:   Y Y 
I tensorflow/core/common_runtime/gpu/gpu_device.cc:702] Creating    TensorFlow device (/gpu:0) -> (device: 0, name: GeForce GTX 980, pci bus id: 0000:01:00.0)
I tensorflow/core/common_runtime/gpu/gpu_device.cc:702] Creating TensorFlow device (/gpu:1) -> (device: 1, name: GeForce GTX 980, pci bus id: 0000:04:00.0)
I tensorflow/core/common_runtime/gpu/gpu_bfc_allocator.cc:42] Allocating 187.40MiB bytes.
E tensorflow/stream_executor/cuda/cuda_driver.cc:932] failed to allocate 187.40M (196505600 bytes) from device: CUDA_ERROR_OUT_OF_MEMORY
F tensorflow/core/common_runtime/gpu/gpu_bfc_allocator.cc:47] Check failed: gpu_mem != nullptr  Could not allocate GPU device memory for device 0. Tried to allocate 187.40MiB
Aborted (core dumped)

Кажется, каждый процесс tensorflow пытается захватить все графические процессоры на машине, когда он загружается, даже если не все устройства будут использоваться для запуска модели.

Я вижу, что есть возможность ограничить количество графических процессоров, каждый из которых использует

tf.GPUOptions(per_process_gpu_memory_fraction=0.5)

... Я не пробовал, но похоже, что два процесса попытаются использовать 50% каждого графического процессора вместо запуска каждого процесса на отдельном графическом процессоре...

Кто-нибудь знает, как настроить shadoworflow для использования только одного графического процессора и оставить другой доступным для другого процесса с тензорным потоком?

Ответ 1

TensorFlow попытается использовать (равную долю памяти) все видимые для него графические устройства. Если вы хотите запускать разные сеансы на разных графических процессорах, вы должны сделать следующее.

  • Запуск каждой сессии в другом процессе Python.
  • Запустите каждый процесс с другим значением переменной CUDA_VISIBLE_DEVICES. Например, если ваш script называется my_script.py и у вас есть 4 графических процессора, вы можете запустить следующее:

    $ CUDA_VISIBLE_DEVICES=0 python my_script.py  # Uses GPU 0.
    $ CUDA_VISIBLE_DEVICES=1 python my_script.py  # Uses GPU 1.
    $ CUDA_VISIBLE_DEVICES=2,3 python my_script.py  # Uses GPUs 2 and 3.
    

    Обратите внимание, что устройства GPU в TensorFlow по-прежнему будут пронумерованы от нуля (т.е. "/gpu:0" и т.д.), но они будут соответствовать устройствам, которые вы сделали видимыми с помощью CUDA_VISIBLE_DEVICES.