Укажите gpu в коде Tensorflow: /gpu:0 всегда работает?

У меня на рабочей станции 3 видеокарты, одна из них Quadro K620, а две другие — Titan X. Теперь я хотел бы запустить код тензорного потока на одной из видеокарт, чтобы оставить остальные бездействующими для другой. задача.

Однако, независимо от установки tf.device('/gpu:0') или tf.device('/gpu:1'), я обнаружил, что первая видеокарта Titan X работает всегда, не знаю почему.

import argparse
import os
import time
import tensorflow as tf
import numpy as np
import cv2

from Dataset import Dataset
from Net import Net

FLAGS = None

if __name__ == "__main__":
    parser = argparse.ArgumentParser()
    parser.add_argument('--foldername', type=str, default='./data-large/')
    parser.add_argument('--batch_size', type=int, default=100)
    parser.add_argument('--num_epoches', type=int, default=100)
    parser.add_argument('--learning_rate', type=float, default=0.5)

    FLAGS = parser.parse_args()
    net = Net(FLAGS.batch_size, FLAGS.learning_rate)

    with tf.Graph().as_default():
        # Dataset is a class for encapsulate the input pipeline
        dataset = Dataset(foldername=FLAGS.foldername,
                              batch_size=FLAGS.batch_size,
                              num_epoches=FLAGS.num_epoches)

        images, labels = dataset.samples_train

        ## The following code defines the network and train
        with tf.device('/gpu:0'): # <==== THIS LINE
            logits = net.inference(images)
            loss = net.loss(logits, labels)
            train_op = net.training(loss)

            init_op = tf.group(tf.initialize_all_variables(), tf.initialize_local_variables())
            sess = tf.Session()
            sess.run(init_op)
            coord = tf.train.Coordinator()
            threads = tf.train.start_queue_runners(sess=sess, coord=coord)
            start_time = time.time()
            try:
                step = 0
                while not coord.should_stop():
                    _, loss_value = sess.run([train_op, loss])
                    step = step + 1
                    if step % 100 == 0:
                        format_str = ('step %d, loss = %.2f, time: %.2f seconds')
                        print(format_str % (step, loss_value, (time.time() - start_time)))
                        start_time = time.time()
            except tf.errors.OutOfRangeError:
                print('done')
            finally:
                coord.request_stop()

            coord.join(threads)
            sess.close()

Что касается строки "<=== THIS LINE:"

Если я ставлю tf.device('/gpu:0'), монитор говорит:

|-------------------------------+----------------------+----------------------+
| GPU  Name        Persistence-M| Bus-Id        Disp.A | Volatile Uncorr. ECC |
| Fan  Temp  Perf  Pwr:Usage/Cap|         Memory-Usage | GPU-Util  Compute M. |
|===============================+======================+======================|
|   0  Quadro K620         Off  | 0000:03:00.0      On |                  N/A |
| 34%   45C    P0     2W /  30W |    404MiB /  1993MiB |      5%      Default |
+-------------------------------+----------------------+----------------------+
|   1  GeForce GTX TIT...  Off  | 0000:04:00.0     Off |                  N/A |
| 22%   39C    P2   100W / 250W |  11691MiB / 12206MiB |      8%      Default |
+-------------------------------+----------------------+----------------------+
|   2  GeForce GTX TIT...  Off  | 0000:81:00.0     Off |                  N/A |
| 22%   43C    P2    71W / 250W |    111MiB / 12206MiB |      0%      Default |
+-------------------------------+----------------------+----------------------+

показывает, что 1-я карта Titan X работает.

Если я ставлю tf.device('/gpu:1'), монитор говорит:

|-------------------------------+----------------------+----------------------+
| GPU  Name        Persistence-M| Bus-Id        Disp.A | Volatile Uncorr. ECC |
| Fan  Temp  Perf  Pwr:Usage/Cap|         Memory-Usage | GPU-Util  Compute M. |
|===============================+======================+======================|
|   0  Quadro K620         Off  | 0000:03:00.0      On |                  N/A |
| 34%   45C    P0     2W /  30W |    411MiB /  1993MiB |      3%      Default |
+-------------------------------+----------------------+----------------------+
|   1  GeForce GTX TIT...  Off  | 0000:04:00.0     Off |                  N/A |
| 22%   52C    P2    73W / 250W |  11628MiB / 12206MiB |     12%      Default |
+-------------------------------+----------------------+----------------------+
|   2  GeForce GTX TIT...  Off  | 0000:81:00.0     Off |                  N/A |
| 22%   42C    P2    71W / 250W |  11628MiB / 12206MiB |      0%      Default |
+-------------------------------+----------------------+----------------------+

показывает, что работают две карты Titan X, а не только 2-й Titan X.

Итак, какая причина стоит за этим и как указать графический процессор, в котором я хочу запускать свою программу?


person C. Wang    schedule 03.11.2016    source источник


Ответы (1)


Просто предположение, но поведение по умолчанию для tf.train.Optimizer< /a> объект (который, как я ожидаю, создается в net.training(loss)) при вызове minimize() равно colocate_gradients_with_ops=False. Это может привести к тому, что операции обратного распространения будут размещены на устройстве по умолчанию, которым будет /gpu:0.

Чтобы выяснить, происходит ли это, вы можете перебрать sess.graph_def и найти узлы, которые либо имеют /gpu:0 в поле NodeDef.device, либо имеют пустое поле device (в этом случае они будут помещены в /gpu:0 по умолчанию).

Еще один способ проверить, какие устройства используются, — использовать параметр output_partition_graphs=True при выполнении шага. Это показывает, какие устройства TensorFlow на самом деле использует (вместо sess.graph_def, какие устройства запрашивает ваша программа), и должно показывать, какие именно узлы работают на /gpu:0.

person mrry    schedule 03.11.2016
comment
Я распечатал sess.graph_def и обнаружил, что действительно есть узлы без информации об устройстве. Эти узлы относятся к вводу, который должен быть создан перед кодом with tf.device('/gpu:0'). Однако я не могу включить две строки кода перед with tf.device('/gpu:0') в блок, потому что он содержит операции по перетасовке очереди FIFO, которая, похоже, работает только на процессоре. Итак, как я могу полностью отобразить всю программу на указанный графический процессор? - person C. Wang; 07.11.2016
comment
Одним из возможных вариантов является расширение блока with tf.device('/gpu:1'): вокруг кода создания набора данных и добавление следующего параметра при создании сеанса: tf.Session(config=tf.ConfigProto(allow_soft_placement=True)). Это позволит TensorFlow перемещать любые операции, выполняемые только для ЦП, обратно на ЦП, а все остальное размещать на ГП 1. - person mrry; 07.11.2016