tf.contrib.data.prefetch_to_device не приводит к ускорению обучения - PullRequest
0 голосов
/ 10 декабря 2018

Я заметил, что в модели, которую я пытаюсь запустить, моя загрузка графического процессора составляет всего около 30%, и часто эта 30% -ная загрузка чередуется с периодами 0% -ной загрузки из-за операций ввода-вывода.Для решения проблемы ввода-вывода добавили tf.contrib.data.prefetch_to_device в мой код, как показано ниже:

    dataset    = tf.data.TFRecordDataset(self.filenames, "ZLIB", 384 * 1024 * 1024)
    dataset    = dataset.map(parse_func, 6)
    dataset    = dataset.prefetch(6)
    dataset    = dataset.apply(tf.contrib.data.prefetch_to_device("/gpu:0", 12))        
    #dataset    = dataset.apply(tf.contrib.data.prefetch_to_device("/gpu:0", 2))        
    #dataset    = dataset.apply(tf.contrib.data.prefetch_to_device("/gpu:0", 6))        
    self.iterator  = dataset.make_initializable_iterator()

Как вы можете видеть, я сделал несколько вещей, пытаясь решить эту проблему, в том числе:

  • варьировать аргумент buffer_size (не влиял на синхронизацию: я пробовал 12, 6, 2 и 1)
  • запускать другие задания на других графических процессорах параллельно или нет.в любом случае не влияет на время обучения
  • , исключите строку dataset.prefetch, если это как-то мешает предварительной выборке на уровне устройства (я также пробовал меньшие числа, такие как 2 и 1)

Я не вижу значимых различий ни в одном из этих вариантов, когда я тренирую время.Кроме того, использование графического процессора продолжает следовать той же схеме, чередуя использование 0% и 30%.Что еще мне следует попробовать, и почему использование предварительной выборки в GPU никак не влияет на производительность?Спасибо за любые предложения.

Ответы [ 2 ]

0 голосов
/ 03 марта 2019

В моих экспериментах я наблюдал умеренное ускорение, когда не было процессора prefetch() до prefetch_to_device() (даже с размером буфера 1) и только с инициализируемым итератором, а не итератором с одним выстрелом.Однако в сочетании с восходящим Keras 2.2.4 (+ TF 1.13) я все еще не вижу идеально перекрывающихся memcpy в визуализации nvprof.Я предполагаю, что в Керасе есть какая-то проблема.

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

Если ваш ЦП и графический процессор имеют значение <100% </strong>, ваши входы / выходы, скорее всего, являются узким местом.Попробуйте использовать пакеты большего размера , чтобы оптимизировать ввод-вывод в / из графического процессора за счет увеличения загрузки памяти. Предварительная выборка пакетов в GPU должна помочь решить эту проблему, перекрывая предварительную обработку данных с последующими вычислениями.Помимо этого, вы можете также рассмотреть возможность мониторинга загрузки диска и посмотреть, не становится ли он насыщенным.Сетевой ввод / вывод, например при потоковой передаче данных с любого вида удаленного хоста, также может быть проблемой ( например потоковая передача TFRecords из блоков хранения AWS S3 или GC).

Если ваш процессор на ~ 100%, а графический процессор <100% </strong>, то ваш процессор является узким местом.Если вы находитесь в облаке, рассмотрите возможность перехода к инстансам с большим количеством процессоров ( Процессор дешевый, GPU не хватает )Если вы не можете увеличить количество процессоров, то возможно переместить некоторые части графика в графический процессор.Тем не менее, Dataset конвейер TF полностью работает на CPU (несмотря на это, см. ). Предварительная выборка также может помочь в этом, но стоимость порождения другого фонового потока для заполнения буфера для нисходящего потока может ослабить этот эффект.Другой вариант - выполнить некоторые или все этапы предварительной обработки в автономном режиме (, т. Е. до начала обучения).

Предварительная выборка .

  • Попробуйте использовать более гибкий подход, чем prefetch_to_device, путем явного копирования в графический процессор с помощью tf.data.experimental.copy_to_device(...), а затем предварительной выборки.Это позволяет избежать ограничения, что prefetch_to_device должно быть последним преобразованием в конвейере, и позволяет включать дополнительные приемы для оптимизации производительности Dataset конвейера ( например, путем экспериментального переопределения распределения пула потоков ).
  • Попробуйте экспериментальную опцию tf.contrib.data.AUTOTUNE для предварительной выборки, которая позволяет среде выполнения tf.data автоматически настраивать размеры буфера предварительной выборки в зависимости от вашей системы и среды.

В конце вы можете сделать что-то вроде этого:

dataset = dataset.apply(tf.data.experimental.copy_to_device("/gpu:0"))
dataset = dataset.prefetch(tf.contrib.data.AUTOTUNE)

Сравнение производительности .

( 8 CPU / 1x Tesla P100 /Начало V3 / Образцы ImageNet / 32 партии )

enter image description here

...