-
Notifications
You must be signed in to change notification settings - Fork 29
Для разработчиков: Проблемы интеграции с NVIDIA DALI
NVIDIA Data Loading Library (DALI) - это библиотека, предназначенная для быстрой загрузки и предобработки изображений, в том числе с использованием GPU. В какой-то момент в Лакмусе предпринималась попытка использовать DALI для ускорения аугментаций, но обнаружившиеся сложности и ограничения сделать этого не позволили. Здесь содержится краткий отчёт о проблемах, актуальность которых стоит проверить, если в будущем будет решено попробовать ещё раз.
Нельзя так просто взять и выполнить при помощи DALI произвольную аугментацию на GPU: надо выстраивать весь Pipeline целиком, на предоставляемых библиотекой операторах, начиная со считывания данных с диска. На моменте считывания и возникает первая сложность: стандартного Reader для формата Pascal VOC нет, наиболее близкий - CocoReader. (В NVIDIA retinanet-examples кстати тоже используется формат COCO, так что если будем переходить, может иметь смысл просто сконвертировать датасеты). Кастомизированное чтение для PyTorch и MXNET реализуется при помощи так называемого ExternalSource, но в Tensorflow он внезапно не поддерживается.
Есть также простенький FileReader, который возвращает данные в виде пар (image_content, label). Но label - это одно число, а image_content каких-либо дополнительных метаданных о считанном изображении не содержит. Нам же помимо самого изображения нужно считывать так же bounding boxes, положение которых в ходе ряда трансформаций (вроде поворота, сдвига и т.д.) тоже меняется. Можно извернуться, передав специально сформированный временный файл в параметре file_list, и заставить FileReader возвращать в качестве label имя изображения, благо они у нас числовые, но тогда считывать и преобразовывать bboxes всё равно придётся вне Pipelin-а DALI. В итоге это приведёт к необходимости гонять данные туда-сюда с GPU на CPU и вряд ли будет эффективным.
С преобразованием bounding boxes, даже если их удастся считать, всё тоже не очень хорошо, как позволяет мне судить количество операторов, включающих слово BBoxes среди списка Supported Operations. Там отнюдь не все, которые используются у нас сейчас.
И даже с аугментациями самих изображений есть проблемы - не все поддерживают рандомизированные версии, как в нашей ретине. В доке есть пример, как сделать рандомизацию для таких операторов, но... там тоже используется неподдерживаемый в TF ExternalSource. Возможно, от каких-то трансформаций можно будет безболезненно отказаться, или заменить, или мне даже где-то встречался "псевдо-random" способ, но для этого нужно провести ревизию на тему, какие аугментации нам действительно нужны.
При этом абсолютно нет уверенности, что в текущем варианте ретины получится воспользоваться преимуществом GPU-аугментаций. Для тренировки модели сейчас используется метод keras Sequential fit_generator, про генератор изображений которого в документации написано: "The generator is run in parallel to the model, for efficiency. For instance, this allows you to do real-time data augmentation on images on CPU in parallel to training your model on GPU." С одной стороны, DALI позволяет задавать устройство, на котором будет выполняться аугментация, с другой - получится ли этим нормально воспользоваться - непонятно.
Помимо этого, Pipeline в DALI и DALIIterator для Tensorflow реализуют итерационный механизм, в то время как текущие генераторы для fit_generator предоставляют произвольный доступ по индексу при помощи __get_item__. Можно ли использовать DALIIterator в fit_generator или придётся сильно менять код - это тоже тема для исследования.
В итоге всё это наводит намысль, что попытки интегрироваться с DALI могут привести к очень костыльному решению, которое не даст никакого прироста эффективности. Если всё-таки возникнет стойкая необходимость оптимизации препроцессинга изображений, стоит посмотреть другие библиотеки, для Tensorflow они имеются в наличии. В случае перехода на NVIDIA retinanet-examples, можно попробовать, не впишется ли туда DALI - вероятность этого достаточно высокая.
Last update | Обновлено: 15.05.2020
The Lacmus project is distributed under the GNU license. All rights reserved. | Проект Lacmus распостраняется под лицензией GNU. Все права зищищены.