Почему операции, выполняемые на GPU, также выполняются на CPU (тензор потока)? - PullRequest
0 голосов
/ 06 декабря 2018

Я использую Tenorflow Profiler для профилирования моей модели, чтобы увидеть, сколько времени занимает каждая операция.Я нахожу какое-то странное поведение, например, операция Conv2D, которая помещается на графический процессор (я установил log_device_placement=True, чтобы увидеть размещение), также имеет большое время выполнения процессора.Вот код, который я использую для профилирования (tenorflow 1.4.0):

import tensorflow as tf
from tensorflow.python.profiler import option_builder

builder = option_builder.ProfileOptionBuilder
run_options = tf.RunOptions(trace_level=tf.RunOptions.FULL_TRACE)
run_metadata = tf.RunMetadata()
# run and collect metadata
my_session.run(fetch_something, feed_dict=feed_dict, 
  options=run_options, run_metadata=run_metadata)
profiler_opts = builder(builder.time_and_memory()).order_by('micros').build()
# this will output the following results
tf.profiler.profile(my_graph, run_meta=run_metadata, cmd='scope', options=profiler_opts)

Вот вывод профилировщика:

node name | requested bytes | total execution time | accelerator execution time | cpu execution time
MyScope/Conv2D (4511.35MB/4511.35MB, 823.47ms/823.47ms, 445.37ms/445.37ms, 378.11ms/378.11ms)

Из результата профилирования, Conv2Dоперация (tf.nn.conv2d) занимает 378,11 мс на процессоре и 445,37 мс на графическом процессоре.Почему тензор потока не использует только графический процессор для Conv2D?Время процессора для передачи данных между памятью и графическим процессором, потому что эта операция занимает много памяти (4511,35 МБ)?

======== update ========

Другое явление, которое я только что нашел.Когда «запрашиваемые байты» Conv2D велики (в моем случае> 4 ГБ), время выполнения ЦП велико (около 400 ~ 500 мс).Когда «запрашиваемых байтов» мало (в моем случае 1,5 ГБ), время выполнения ЦП короткое (около 15 мс).Я предполагаю, что время выполнения процессора Conv2D связано с потреблением памяти.Однако я не понимаю, почему в другой партии (my_session.run) Conv2D использует разное количество «запрошенных байтов».Тензор, к которому применяется Conv2D, имеет почти одинаковый размер для разных партий.

1 Ответ

0 голосов
/ 06 декабря 2018

Хотя я не вижу весь ваш график, но я предполагаю, что вы непрерывно подаете данные в feed_dict.
Таким образом, каждый раз, когда вычисляются тензоры, они принимают значение следующего элемента . в базовом наборе данных.Это также требует времени от CPU .Существует возможность подачи данных напрямую из памяти GPU , если для хранения данных в ней достаточно объекта tf.Tensor, см. документацию :

Есливсе ваши входные данные помещаются в память, самый простой способ создать из них набор данных - это преобразовать их в объекты tf.Tensor и использовать Dataset.from_tensor_slices ().

Пример из соответствующего разделаиз документации tenorflow :

# Load the training data into two NumPy arrays, for example using `np.load()`.
with np.load("/var/data/training_data.npy") as data:
  features = data["features"]
  labels = data["labels"]

# Assume that each row of `features` corresponds to the same row as `labels`.
assert features.shape[0] == labels.shape[0]

dataset = tf.data.Dataset.from_tensor_slices((features, labels))

Обратите внимание, что приведенный выше фрагмент кода будет вставлять массивы объектов и меток в ваш график TensorFlow как операции tf.constant ().Это хорошо работает для небольшого набора данных, но тратит память - потому что содержимое массива будет скопировано несколько раз - и может достигать предела 2 ГБ для буфера протокола tf.GraphDef.

Но это не тот случай.Таким образом, основываясь на предоставленной вами информации, я думаю, что потребление ресурсов ЦП в основном (или полностью) связано с операцией подачи данных на следующий ввод этого графика.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...