Сравнение оборудования ускорителей Google, Intel и NVIDIA

За последний год начали появляться специальные микросхемы, предназначенные для ускорения вывода машинного обучения на периферии. Облако не требуется. Первой на рынок вышла Intel со своим оборудованием на базе Moividius. Однако за последние пару месяцев мы стали свидетелями появления как Google с их оборудованием на основе EdgeTPU под названием Coral, так и NVIDIA с их предложением на базе GPU Jetson Nano.

Появление нового оборудования, предназначенного для запуска моделей машинного обучения на значительно увеличенных скоростях и при относительно низком энергопотреблении, без необходимости подключения к облаку, делает периферийные вычисления гораздо более привлекательным предложением. Тем более, что наряду с этим новым оборудованием мы увидели выпуск TensorFlow 2.0, а также TensorFlow Lite для микроконтроллеров и нового сверхнизкого энергопотребления, такого как SparkFun Edge.

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

Единственный вопрос теперь заключается в том, какая из новых платформ ускорения может делать выводы быстрее? Пора провести сравнительный анализ и выяснить это.

Заголовок результатов сравнительного анализа

Мы собираемся продолжить и сравним логический вывод на следующих платформах; Coral Dev Board, NVIDIA Jetson Nano, Coral USB Accelerator с Raspberry Pi, оригинальный Movidus Neural Compute Stick с Raspberry Pi и Intel Neural Compute второго поколения Stick 2 »снова с Raspberry Pi . Наконец, просто чтобы добавить клюшку, мы также будем запускать те же модели на моем Apple MacBook Pro (2016) с четырехъядерным процессором Intel Core i7 с тактовой частотой 2,9 ГГц и ванильным Raspberry Pi 3, Model B + без каких-либо ускорение.

Этот первоначальный тест проводился с моделями MobileNet v2 SSD и MobileNet v1 SSD, обе модели были обучены на наборе данных Общие объекты в контексте (COCO). Использовалось одно тестовое изображение размером 3888 × 2916 пикселей, которое содержало в кадре два узнаваемых объекта, банан🍌 и яблоко🍎. Размер изображения был уменьшен до 300 × 300 пикселей перед представлением модели, и каждая модель запускалась 10 000 раз, прежде чем было взято среднее время вывода.

Возможно, неудивительно, что результаты показывают, что две выделенные платы, Coral Dev Board от Google и Jetson Nano Developer Kit от NVIDIA, являются лучшими из всех рассмотренных нами платформ. Из этих двух плат Coral Dev Board работала быстрее, время вывода примерно в 4 раза меньше, чем у Jetson Nano для той же модели машинного обучения.

ℹ️ Информация Хотя я включил цену на платформы вместе с результатами тестов, к цене на наклейке добавлены «дополнительные» 35 долларов, которые вам понадобятся для Raspberry Pi. для Coral USB Accelerator и Intel Neural Compute Sticks эта цифра в заголовке - это еще не все. Вы должны смотреть на цену с точки зрения производительности, а не только с точки зрения начального шока, и для периферийных вычислений эта производительность не сводится только к скорости вывода.

Часть I - Бенчмаркинг

Более глубокий анализ результатов

Бенчмаркинг проводился с использованием TensorFlow или для платформ с аппаратным ускорением, которые не поддерживают TensorFlow их родную структуру, с использованием тех же моделей, что и на других платформах, преобразованных в соответствующую родную структуру. Для оборудования Coral на базе EdgeTPU мы использовали TensorFlow Lite, а для оборудования на базе Movidius Intel мы использовали их инструментарий OpenVINO. Мы также протестировали NIVIDIA Jetson Nano как с ванильным TensorFlow (с поддержкой графического процессора), так и снова с той же моделью TensorFlow, но оптимизированной с использованием фреймворка NVIDIA TensorRT.

Логический вывод был выполнен с использованием моделей MobileNet v2 SSD и MobileNet v1 0.75 depth SSD, обе модели обучены на наборе данных Общие объекты в контексте (COCO). Тестовое изображение размером 3888 × 2916 пикселей было уменьшено до 300 × 300 пикселей перед тем, как представить его модели, и каждая модель запускалась 10 000 раз, прежде чем было взято среднее время вывода. Первый прогон логического вывода, который занимал больше времени из-за накладных расходов на загрузку, был отброшен.

Тесты проводились дважды на NVIDIA Jetson Nano, сначала с использованием обычных моделей TensorFlow, а второй раз с использованием этих моделей после оптимизации с использованием библиотеки NVIDIA TensorFlow с TensorRT.

Неудивительно, что неускоренный Raspberry Pi демонстрирует худшую из всех платформ, которые мы тестировали, поддерживая логический вывод всего от 1 до 2 кадров в секунду.

Если вы заинтересованы в повышении производительности Raspberry Pi, вы можете попробовать создать TensorFlow Lite для Raspberry Pi. К сожалению, в настоящее время нет доступных двоичных дистрибутивов, его нельзя развернуть с помощью pip. Поэтому, если вы хотите опробовать TensorFlow Lite, вам придется собрать его из исходного кода либо путем кросс-компиляции, либо изначально на самом Raspberry Pi. Я не собираюсь идти по этому пути прямо сейчас, поэтому вместо этого мы отбросим Raspberry Pi как исключение и более подробно рассмотрим другие платформы.

🆕 Обновление (8 мая). Теперь я сел и посмотрел на разницу в производительности между запуском TensorFlow и TensorFlow Lite на Raspberry Pi. Как и следовало ожидать, все работает быстрее. Но я был удивлен насколько быстрее.

Наши результаты Jetson Nano особенно интересны по сравнению с результатами тестирования, опубликованными NVIDIA для платы.

Мы наблюдаем значительно более медленные выводы в нашем собственном тестировании с использованием TensorFlow, чем в тестах NVIDIA, примерно в 3 раза медленнее с MobileNet v2 SSD. Однако, вернувшись к их исходному коду, который был написан на C ++ и использует собственный TensorRT для логических выводов, и следуя их инструкциям по тестированию, я смог успешно воспроизвести их опубликованные результаты тестов производительности MobileNet V2.

Хотя наши модели, оптимизированные с помощью TensorRT, работают на Jetson Nano значительно быстрее, чем обычные модели TensorFlow, они все равно не работают так быстро, как в исходных тестах NVIDIA C ++. В разговоре с NVIDIA они сказали мне, что это не просто разница между скомпилированным и интерпретируемым языком, между C ++ и Python.

Вместо этого они говорят, что … есть ошибка с TensorFlow и« TensorFlow с TensorRT , над исправлением которой сейчас работает NVIDIA.». Однако если отложить эту проблему в сторону, из наших результатов ясно, что Если вы хотите запустить модель TensorFlow на Jetson Nano, вам действительно нужно использовать TensorRT для увеличения скорости вывода. Разница в производительности между ванильными и постоптимизированными моделями более чем в 4 раза больше.

Из двух специализированных плат, Coral Dev Board и NVIDIA Jetson Nano, логический вывод был примерно в 4 раза быстрее на оборудовании Coral для обеих моделей. Однако имейте в виду, что, хотя TensorFlow Lite все еще находится на ранней стадии развития, недавно он представил поддержку ускорения графического процессора для логических выводов. Запуск моделей, использующих TensorFlow Lite с поддержкой графического процессора, должен сократить время, необходимое для вывода на Jetson Nano. Это оставляет открытой возможность того, что разрыв между платформами может сократиться в будущем.

NVIDIA также будет утверждать, что, поскольку она поддерживает полный TensorFlow, а не TensorFlow Lite, их платформа имеет и другие преимущества. Но это преимущество сузилось после того, как Google снял ограничения на модели с Edge TPU Model Compiler в начале месяца.

Однако полностью перевернул этот аргумент с ног на голову. Несмотря на то, что эти две платы всегда будут напрямую сравнивать, они действительно созданы для разных целей. Плата NVIDIA построена на базе существующей технологии GPU, а плата Google представляет собой специализированную микросхему ASIC, предназначенную непосредственно для работы с более мелкими квантованными моделями. Мы видим, что оборудование Edge TPU здесь быстрее, потому что оно предназначено для работы с меньшими моделями на периферии. Аппаратное обеспечение на базе графического процессора NVIDIA более гибкое, но эта дополнительная возможность приводит к снижению скорости.

Однако, помимо различий между тестами NVIDIA и нашими собственными, мы также наблюдаем большую разницу между нашими результатами и собственными опубликованными тестами Google для оборудования Coral. Мы наблюдаем гораздо более медленное время вывода, в 8 раз, для Coral Dev Board.

Наиболее очевидное различие здесь заключается в том, что мы используем разные модели, тесты Google MobileNet проводились с использованием моделей с входным размером 224 × 224, тогда как я использовал входной размер 300 × 300 и MobileNet SSD.

Но настоящая разница возникает из-за того, что мы измеряем разные вещи.

Хотя мы изменяем размер изображения перед тем, как начать синхронизацию нашего вывода, мы все еще передаем изображение в TensorFlow, который затем должен принять его и преобразовать во что-то, что может использовать наша модель. Цифры Google предназначены только для этапа вывода, это гораздо более чистая (и более короткая) операция. Я бы сказал, что мой тест лучше отражает то, что люди будут делать в мире. Цифры Google хороши, но большинство людей не интересуется временем, которое проходит между передачей тензора в модель и получением результата.

Но если вы действительно хотите, чтобы что-то работало быстрее, вы можете много оптимизировать наш цикл вывода, особенно когда речь идет о преобразовании изображений во что-то, что TensorFlow передаст модели.

Разница между нашими тестами и результатами Google для Coral USB Accelerator еще шире, примерно в 20 раз, что довольно безумно. Не все это можно списать на ту же проблему, что и раньше. Однако я думаю, что остальная часть разрыва между результатами почти наверняка связана с разницей в скорости между USB 2.0 и USB 3.0.

Хотя Coral USB Accelerator поддерживает скорость USB 3.0, мы снижаем ее скорость, подключая его к Raspberry Pi, который имеет более медленную шину USB 2.0. Это все замедлит. Это в сочетании с проблемой, когда тесты Google и наши собственные тесты просто совпадают, просто измеряют разные вещи, вот почему эти цифры так сильно расходятся.

Если посмотреть на аппаратное обеспечение ускорителя, то Coral USB Accelerator быстрее в 2 раза, чем Intel Neural Compute Stick 2. Со старшим, первым поколением Intel Movidius Neural Compute Stick оказалось на последнем месте. Хотя производительность Intel Neural Compute Stick также значительно ниже результатов собственных тестов Intel, она согласуется с другими результатами, которые я видел для оборудования.

Однако, что впечатляет как для платформ Google, так и для Intel, так это ускорение между ускоренным и исходным временем вывода на Raspberry Pi, несмотря на то, что оба они ограничиваются более медленными скоростями шины USB 2.0.

Мы наблюдаем увеличение скорости в 10 раз при использовании Coral USB Accelerator по сравнению с исходным таймингом Raspberry Pi. Это поразительно.

Это важно, если учесть, чем не является USB-ускоритель. В отличие от Coral Dev Board, которая предназначена в качестве оценочной платы для System-on-Module (SoM), которая будет выпущена в большом количестве позже в этом году, USB-ускоритель, скорее всего, нацелен на специалистов по обработке данных и производителей. а не разработчиками встроенного оборудования. Специалисты по обработке данных будут использовать ускоритель со своим ноутбуком Linux для обработки своих данных, а производители будут использовать его с Raspberry Pi для создания роботов и автономных транспортных средств. Обе группы могли бы получить выгоду от более быстрого выполнения логических выводов.

Факторы окружающей среды

Хотя скорость вывода, вероятно, является нашей самой важной мерой, это устройства, предназначенные для машинного обучения на периферии. Это означает, что нам также нужно обращать внимание на факторы окружающей среды. Разработка смарт-объекта - это не только программное обеспечение, которое вы на него устанавливаете, вы также должны обращать внимание на другие факторы, и здесь мы особенно озабочены нагревом и охлаждением и диапазоном мощности. Потому что при проектировании для Интернета вещей может потребоваться компромисс между скоростью вывода и этими другими факторами.

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

Потребляемая мощность

Измерения тока производились с помощью мультиметра, встроенного в кабель USB. Использовались два разных измерителя; один с платами Raspberry Pi и NVIDIA Jetson Nano был разработан для соединений micro-USB, другой, используемый с Coral Dev Board и MacBook Pro, был разработан для соединений USB-C. Оба измерителя показали точность ± 0,01 А (10 мА).

Измерения тока для NVIDIA Jetson Nano проводились, когда плата работала без головы, без использования монитора, клавиатуры или мыши.

По вполне понятным причинам MacBook Pro явно выделяется в этой таблице. Хотя и он, и Coral Dev Board питаются от USB-C, это очень разные звери. В то время как Coral Dev Board работает от 5 В, как и другие наши платформы, MacBook Pro рассчитывает на 20 В. Итак, пока я продолжал и измерял текущую потребляемую мощность на предмет интереса, в дальнейшем мы проигнорируем это.

$ ./osx-cpu-temp -f
Num fans: 2
Fan 0 - Left side   at 3767 RPM (100%)
Fan 1 - Right side  at 3487 RPM (100%)

Я действительно только хотел знать, сколько тянули эти вращающиеся фанаты.

За исключением MacBook Pro, все наши платформы используют номинальное входное напряжение 5 В. Однако на самом деле напряжение будет несколько колебаться из-за требований, предъявляемых платой, и большинство USB-источников фактически находятся в диапазоне от +5,1 до + 5,2 В. Поэтому при выполнении грубых расчетов для получения мощности (в ваттах) я обычно принимаю напряжение USB-источника питания равным + 5,15 В, поскольку хороший источник обычно пытается поддерживать подаваемое напряжение около этого значения, несмотря на быстрые колебания потребляемого тока.

Эти колебания спроса часто случаются, когда вы используете периферийные устройства с Raspberry Pi, и часто вызывают отключение электричества, а многие USB-зарядные устройства, предназначенные для обеспечения постоянного тока для зарядки мобильных телефонов, обычно этого не делают. Я хорошо со всем справляюсь.

Глядя на Coral Dev Board и аналогичный NVIDIA Jetson Nano, мы видим, что Dev Board потребляет больше тока в режиме ожидания, но меньше во время вывода. Так что некоторые колебания и балансировки там в зависимости от количества времени, которое устройство будет проводить в режиме ожидания.

ℹ️ Информация. Пиковый ток для NVIDIA Jetson Nano меньше, чем вы могли ожидать, учитывая совет по питанию платы, который рекомендует источник питания 4А, если вы выполняете тесты. или большая нагрузка. Вероятно, это связано с тем, что мы запускаем плату NVIDIA без головы, без монитора, клавиатуры или мыши. Эти аксессуары добавляют дополнительную нагрузку на электроэнергию. Например, для подключения монитора к порту HDMI требуется 50 мА, для добавления модуля камеры требуется 250 мА, а клавиатуры и мыши могут потреблять всего 100 мА или более 1000 мА в зависимости от марки и модели.

С другой стороны, хотя все ускорители на основе Raspberry Pi в некоторой степени увеличивают время ожидания, они потребляют меньше тока, чем неускоренный Raspberry Pi во время логического вывода. Другими словами, они работают намного быстрее, но при меньшем потреблении тока они по-прежнему потребляют меньше энергии.

Отопление и охлаждение

Внешние температуры были измерены с помощью лазерного инфракрасного термометра, который имеет точность ± 2 ° C для температур ≤100 ° C после того, как был завершен расширенный тестовый прогон с 50 000 заключений.

Температуры были измерены с использованием ряда методов; в случае Coral Dev Board и NVIDIA Jetson Nano измерялась температура радиаторов, а для Coral USB Accelerator и Intel и Movidius Neural Compute Stick измерялась температура внешних корпусов. Для Raspberry Pi внешняя температура измерялась на корпусе SoC, а для MacBook Pro - на нижней стороне ноутбука.

Температура ЦП была сообщена операционной системой с помощью следующего вызова командной строки на Raspberry Pi, Coral Dev Board и NVIDIA Jetson Nano.

$ paste <(cat /sys/class/thermal/thermal_zone*/type) <(cat /sys/class/thermal/thermal_zone*/temp) | column -s $'\t' -t | sed 's/\(.\)..$/.\1°C/'
AO-therm         38.0°C
CPU-therm        31.0°C
GPU-therm        30.5°C
PLL-therm        28.5°C
PMIC-Die         100.0°C
thermal-fan-est  31.0°C

Точный ответ варьировался в зависимости от количества датчиков, установленных на платформе, от одного датчика ЦП на Raspberry Pi до 6 датчиков, присутствующих на Jetson Nano. Для удобства температура MacBook Pro измерялась с помощью приложения osx-cpu-temp командной строки.

Неускоренная плата Raspberry Pi с ванильным TensorFlow достигла температуры 74 ° C во время расширенного теста, что означало, что она страдала от теплового дросселирования процессора, она приблизилась к точке 80 ° C, где может произойти дополнительное постепенное дросселирование. Поэтому я бы порекомендовал, если вы собираетесь запускать логический вывод в течение продолжительных периодов времени с помощью Raspberry Pi, вы должны добавить по крайней мере пассивный радиатор, чтобы избежать троттлинга процессора. Возможно даже, что маленький веер тоже может быть хорошей идеей. Потому что, давайте посмотрим правде в глаза, троттлинг процессора может испортить вам день.

Еще один необычный вариант - Coral USB Accelerator. Внешний вид USB Accelerator оставался заметно холодным во время логических выводов по сравнению с его прямым конкурентом Intel Neural Compute Stick 2, который работал на 10 ° C горячее. Что действительно интересно, так это то, что это произошло за счет температуры процессора Raspberry Pi, которая была на +8–9 ° C выше, чем с Neural Compute Stick. Я действительно заинтригован, чтобы узнать, что там происходит?

Как ни странно, по крайней мере, вентилятор на плате Coral Dev Board, кажется, раскручивается, когда температура процессора достигает ~ 65 ° C, что снижает температуру процессора до ~ 60 ° C. Это снижает внешнюю температуру радиатора с ~ 50 ° C до ~ 35 ° C. Это довольно разумно, так что вентилятор кажется вполне подходящим для платы.

Резюме

По крайней мере, на данный момент кажется, что Coral Dev Board и USB Accelerator имеют явное преимущество, поскольку модели MobileNet работают в 3–4 раза быстрее, чем их прямые конкуренты.

Однако, как мы уже обсуждали, скорость вывода - не единственный решающий фактор для оборудования, предназначенного для развертывания в мире на грани событий, и даже этот довольно обширный обзор тестов не затронул все эти факторы. . Также существует проблема, связанная с потенциальной ошибкой в ​​реализации TensorRT Python, из-за которой эти тесты стоит пересмотреть после того, как NVIDIA решит проблему, чтобы увидеть, насколько исправление, которое это повлияет на результаты.

Часть II - Методология

Воспроизведение результатов

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



Подготовка Coral Dev Board

Настроить плату Coral Dev можно, следуя моим инструкциям, которые проведут вас через начальную настройку платы, а также запустят несколько начальных примеров моделей на оборудовании.

ℹ️ Информация. Если у вас под рукой нет запасного ноутбука под управлением Linux, вы можете использовать Raspberry Pi для прошивки новой прошивки на Coral Dev Board.

Однако с тех пор, как были написаны мои оригинальные инструкции, в дистрибутив Mendel OS были внесены некоторые изменения, которые включают повышенную безопасность для аутентификации SSH. Вы больше не можете сразу подключиться по SSH к Coral Dev Board, используя пользователя mendel, поскольку аутентификация по паролю по умолчанию отключена. Теперь вы должны сначала перенести SSH-ключ на плату с помощью нового инструмента разработки Mendel (MDT).

Подготовка Coral USB Accelerator и Raspberry Pi

Аналогично Coral Dev Board вы можете настроить Coral USB Accelerator для использования на Raspberry Pi, следуя моим инструкциям.

Если вы хотите использовать USB-ускоритель со своим ноутбуком, а не с Raspberry Pi, он совместим с любым компьютером с USB-портом, на котором работает Debian 6.0 или выше (или производная версия, такая как Ubuntu 10.0+). Его можно использовать с машинами с процессором x86_64 или ARM64 с набором инструкций ARMv8.

ℹ️ Информация. Хотя USB-ускоритель можно использовать с любым USB-портом, если вы подключите его к порту USB 2.0 (как мы делаем с Raspberry Pi), вы снизите пропускную способность до / от ускорителя, так как он имеет интерфейс USB 3.1, обеспечивающий скорость передачи 5 Гбит / с. Это замедлит процесс вывода. Да, это повлияло на наши результаты здесь.

Подготовка Intel Neural Compute Stick 2 и Raspberry Pi

Настройка Intel Neural Compute Stick 2 очень похожа на USB Coral Accelerator, и снова вы можете следовать моим инструкциям, чтобы настроить его и запустить несколько первых моделей-примеров.

ℹ️ Информация. Подготовка Raspberry Pi к использованию старого Movidius Neural Compute Stic первого поколения k должна быть точно такой же, как для Intel Neural Compute Stick 2, как и OpenVINO. инструментарий поддерживает оба поколения оборудования.

Подготовка NVIDIA Jetson Nano

Наконец, вы можете настроить NVIDIA Jetson Nano, следуя моим инструкциям. Первоначальная настройка и установка Jetson Nano, вероятно, являются наиболее длительными из всех платформ, поскольку TensorFlow не предустановлен в образе по умолчанию.

⚠️ Предупреждение. Хотя образ ОС Jetson Nano помещается на карту емкостью 16 ГБ, использование такой маленькой карты обычно приводит к заполнению корневой файловой системы и ошибкам «на устройстве не остается места» во время логического вывода. Убедитесь, что вы используете карту не менее 32 ГБ при прошивке образа, и, если она доступна, карта на 64 ГБ может быть лучшим выбором.

Однако в дополнение к нашей первоначальной настройке для запуска сценариев тестирования нам необходимо убедиться, что вилка Pillow библиотеки изображений Python (PIL) также установлена ​​вместе с некоторыми недостающими зависимостями.

$ sudo apt-get install libfreetype6 libfreetype6-dev
$ pip3 install Pillow

Также нам нужно установить object_detection библиотеку, которая нам понадобится для оптимизации модели, начиная с ее зависимостей.

$ sudo apt-get install protobuf-compiler python-pil python-lxml python-tk
$ pip3 install --user Cython
$ pip3 install --user contextlib2
$ pip3 install --user jupyter
$ pip3 install --user matplotlib

Теперь возьмите репозиторий TensorFlow Models, который содержит API обнаружения объектов TensorFlow и связанные файлы, а также репозиторий COCO API.

$ git clone https://github.com/tensorflow/models.git
$ git clone https://github.com/cocodataset/cocoapi.git

Теперь нам нужно создать COCO API и скопировать подкаталог pycocotools на место внутри дистрибутива TensorFlow Models. Вам нужно будет установить инструменты установки Python, если они еще не установлены.

$ sudo apt-get install python3-setuptools
$ cd cocoapi/PythonAPI

Поскольку мы используем Python 3.x, а не Python 2.x, теперь вам нужно быстро отредактировать Makefile, заменив вхождения python на python3.

Итак, откройте Makefile в своем любимом редакторе, и после этого он должен выглядеть так:

all:
# install pycocotools locally
python3 setup.py build_ext --inplace
rm -rf build
install:
# install pycocotools to the Python site-packages
python3 setup.py build_ext install
rm -rf build

затем создайте pycocotools локально и скопируйте их в каталог моделей,

$ make
$ cp -r pycocotools ~/models/research/

и продолжайте создавать библиотеки Protobuf.

$ cd ~/models/research
$ protoc object_detection/protos/*.proto --python_out=.

⚠️ Предупреждение. Если при компиляции возникают ошибки, возможно, вы используете несовместимый protobuf компилятор. В таком случае вам следует воспользоваться инструкциями по ручной установке.

Продолжайте и добавьте object_detection каталоги в свой PYTHONPATH,

$ export PYTHONPATH=$PYTHONPATH:/home/jetson/models/research:/home/jetson/models/research/slim

и, наконец, в ваш ~/.bashrc файл.

$ echo 'export PYTHONPATH=$PYTHONPATH:/home/jetson/models/research:/home/jetson/models/research/slim' >> ~/.bashrc

Вы можете проверить, правильно ли вы установили TensorFlow Object Detection
API, запустив model_builder_test.py тестовый скрипт, как показано ниже.

$ cd ~/models/research
$ python3 object_detection/builders/model_builder_test.py
   .
   .
   .
Ran 16 tests in 0.309s
OK (skipped=1)
$

Создание файла подкачки на Jetson Nano также может помочь с более крупными моделями.

$ sudo fallocate -l 4G /var/swapfile
$ sudo chmod 600 /var/swapfile
$ sudo mkswap /var/swapfile
$ sudo swapon /var/swapfile
$ sudo bash -c 'echo "/var/swapfile swap swap defaults 0 0" >> /etc/fstab'

Однако решение о добавлении должно быть основано на размере вашей SD-карты. Вероятно, не рекомендуется делать это, если вы не использовали карту 64 ГБ или больше.

Подготовка Raspberry Pi

Установка TensorFlow на Raspberry Pi раньше была непростым процессом, однако к середине прошлого года все стало намного проще.

Скачайте последний выпуск Raspbian Lite и настройте свой Raspberry Pi. Если вы не используете проводную сеть или не подключили к Raspberry Pi дисплей и клавиатуру, вам нужно как минимум подключить Raspberry Pi к беспроводной сети и включить SSH.

После того, как вы настроили Raspberry Pi, включите его, а затем откройте окно терминала на своем ноутбуке и подключитесь к Raspberry Pi по SSH.

% ssh [email protected]

После входа в систему вы можете установить TensorFlow.

$ sudo apt-get install libatlas-base-dev
$ sudo apt-get install python3-pip
$ pip3 install tensorflow

Установка займет некоторое время. Так что вы можете сделать перерыв и выпить кофе. После завершения установки вы можете протестировать установку следующим образом.

$ python3 -c "import tensorflow as tf; tf.enable_eager_execution(); print(tf.reduce_sum(tf.random_normal([1000, 1000])))"

⚠️ Предупреждение. Если официальный пакет TensorFlow недавно не обновлялся, вы будете получать Предупреждения во время выполнения, когда import tensorflow. Это не вызывает беспокойства, а просто указывает на то, что колеса были созданы под Python 3.4, и вы используете их с Python 3.5. Они совместимы с более новыми версиями Python.

Теперь, когда TensorFlow успешно установлен, нам также нужно будет продолжить и установить OpenCV вместе со всеми его многочисленными зависимостями,

$ sudo apt-get install libwebp6 libwebp-dev
$ sudo apt-get install libtiff5 libtiff5-dev
$ sudo apt-get install libjasper1 libjasper-dev
$ sudo apt-get install libilmbase12 libilmbase-dev
$ sudo apt-get install libopenexr22 libopenexr-dev 
$ sudo apt-get install libgstreamer0.10-0 libgstreamer0.10-dev
$ sudo apt-get install libgstreamer1.0-0 libgstreamer1.0-dev
$ sudo apt-get install libavcodec-dev
$ sudo apt-get install libavformat57 libavformat-dev
$ sudo apt-get install libswscale4 libswscale-dev
$ sudo apt-get install libqtgui4
$ sudo apt-get install libqt4-test
$ pip3 install opencv-python

поскольку позже нам понадобится OpenCV для нашего сценария тестирования. По той же причине нам нужно установить вилку Pillow библиотеки изображений Python (PIL).

$ pip3 install Pillow

ℹ️ Информация Я установил Raspbian Lite в качестве своего дистрибутива на свой Raspberry Pi, если бы я вместо этого установил полную версию Raspbian, некоторые из этих зависимостей уже присутствовали бы и не необходимо установить.

Подготовка MacBook Pro

Установить TensorFlow на ваш MacBook не так сложно, хотя это может оказаться довольно длительным процессом, если вы устанавливаете из исходников. Однако, в зависимости от того, нужны ли вам инструменты C ++, такие как summarize_graph, большинство людей смогут обойтись без установки с pip, что намного проще.

Первый шаг в подготовке MacBook - установить Homebrew.

$ /usr/bin/ruby -e "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/master/install)"

После установки Homebrew вы можете продолжить и установить Python,

$ brew install python python3
$ brew link python
$ brew link python3
$ brew postinstall python3

⚠️ Предупреждение Обычный pip3 install --user отключен для Python, установленного с помощью Homebrew. Это из-за ошибки в distutils. Поэтому, когда вы видите -U установку в инструкциях, просто продолжайте и вместо этого установите /usr/local/.

и как только Python будет установлен, вы можете установить OpenCV и его привязки, которые нам понадобятся для нашего сценария тестирования.

$ brew install opencv
$ pip3 install numpy scipy scikit-image matplotlib scikit-learn

Однако это займет некоторое время, так что можно пойти и выпить чашечку кофе.

После завершения установки вы можете проверить, правильно ли установлен OpenCV, попытавшись импортировать его в Python. Если вы не видите ошибки, значит установка прошла успешно.

$ python3
Python 3.7.3 (default, Mar 27 2019, 09:23:32)
[Clang 9.0.0 (clang-900.0.39.2)] on darwin
Type "help", "copyright", "credits" or "license" for more information.
>>> import cv2
>>>

Теперь мы можем установить TensorFlow. Вы можете сделать это либо в виртуальной среде Python с помощью virtualenv, либо непосредственно в системной среде.

$ pip3 install tensorflow

Установка займет некоторое время. Так что вы можете сделать перерыв и выпить кофе. После завершения установки вы можете протестировать установку следующим образом.

$ python3 -c "import tensorflow as tf; tf.enable_eager_execution(); print(tf.reduce_sum(tf.random_normal([1000, 1000])))"

⚠️ Предупреждение. Обратите внимание: если вы выбрали установку TensorFlow из исходного кода, вы не сможете импортировать модель tensorflow Python, пока ваш текущий рабочий каталог - это каталог $INSTALL_DIR/tensorflow/. Это вызовет ошибку ImportError: «Не удалось импортировать тензорный поток. Не импортируйте тензорный поток ». Если вы получили эту ошибку, просто измените каталог из исходного каталога и повторите попытку.

Подготовка модели к логическому выводу

Я собираюсь использовать предварительно обученные модели для запуска наших тестов. Что мы собираемся сделать, так это взять эти предварительно обученные модели TensorFlow, а затем преобразовать их, если необходимо, чтобы они работали на каждой платформе. На этом этапе мы должны провести логический вывод как можно более наивным способом. Без особой оптимизации, если таковая имеется, сверх того, что необходимо для запуска модели, чтобы дать нам базовую скорость.

Мы можем использовать наши модели TensorFlow более или менее из коробки как на Jetson Nano, на котором выполняется полная установка TensorFlow с расширениями для поддержки NVIDIA TensorRT, так и на Raspberry Pi и MacBook Pro. Хотя, как мы видели, модели TensorFlow, которые оптимизированы с использованием библиотек NVIDIA TensorRT, будут работать значительно быстрее на оборудовании Jetson.

Однако, чтобы использовать эти модели TensorFlow на оборудовании на основе EdgeTPU от Google или на оборудовании на базе Movidius от Intel, нам придется преобразовать их в соответствующие собственные форматы. Итак, давайте сделаем это сейчас.

Преобразование модели TensorFlow для работы на Edge TPU

У Google есть хороший обзор того, как конвертировать модели TensorFlow для работы на оборудовании Edge TPU. Сначала вам нужно взять модель и преобразовать ее в TensorFlow Lite перед компиляцией модели TensorFlow Lite для использования в EdgeTPU с помощью веб-компилятора.

Давайте начнем с того, что возьмем квантованную версию нашей модели MobileNet SSD V1 из Coral Model Zoo вместе с файлом связанных этикеток. Хотя на сайте Coral есть предварительно преобразованная версия этой модели, доступная для скачивания, давайте рассмотрим процесс преобразования этой модели.

Если на вашем ноутбуке еще не установлен TensorFlow, вам следует сделать это сейчас, затем загрузить модель и распаковать.

$ cd ~
$ wget http://download.tensorflow.org/models/object_detection/ssd_mobilenet_v1_quantized_300x300_coco14_sync_2018_07_18.tar.gz
$ tar -zxvf ssd_mobilenet_v1_quantized_300x300_coco14_sync_2018_07_18.tar.gz

Чтобы преобразовать модель из TensorFlow в TensorFlow Lite, вам нужно знать, как называются входные и выходные узлы модели. Самый простой способ выяснить это - использовать инструмент summarize_graph для проверки модели и получения предположений о вероятных входных и выходных узлах. К сожалению, если вы ранее устанавливали TensorFlow с помощью pip, этот инструмент не будет доступен, вам придется вернуться и установить из исходного кода, чтобы получить доступ к инструментам C ++.

⚠️ Предупреждение. Если у вас работает LittleSnitch, возможно, вам придется временно выключить сетевой монитор, если во время установки вы получите сообщение об ошибке Хост не работает.

Затем из исходного каталога TensorFlow вы можете продолжить и собрать инструмент summarize_graph, используя bazel,

$ bazel build tensorflow/tools/graph_transforms:summarize_graph

и запустите его на квантованной версии нашей модели SSD MobileNet v1.

$ bazel-bin/tensorflow/tools/graph_transforms/summarize_graph --in_graph=/Users/aa/Downloads/ssd_mobilenet_v1_0.75_depth_quantized_300x300_coco14_sync_2018_07_18/tflite_graph.pb

ℹ️ Информация Edge TPU поддерживает только модели TensorFlow Lite с полностью 8-битным квантованием. Если у вас есть модель TensorFlow с плавающей запятой, если она не была обучена с помощью обучения с квантованием, вы не сможете преобразовать ее для работы с Edge TPU, поскольку нет поддержки квантования после обучения.

После запуска инструмента summarize_graph вы должны увидеть что-то вроде этого:

Found 1 possible inputs: (name=normalized_input_image_tensor, type=float(1), shape=[1,300,300,3])
No variables spotted.
Found 1 possible outputs: (name=TFLite_Detection_PostProcess, op=TFLite_Detection_PostProcess)
Found 4137705 (4.14M) const parameters, 0 (0) variable parameters, and 0 control_edges
Op types used: 451 Const, 389 Identity, 105 Mul, 94 FakeQuantWithMinMaxVars, 70 Add, 35 Sub, 35 Relu6, 35 Rsqrt, 34 Conv2D, 25 Reshape, 13 DepthwiseConv2dNative, 12 BiasAdd, 2 ConcatV2, 1 RealDiv, 1 Sigmoid, 1 Squeeze, 1 Placeholder, 1 TFLite_Detection_PostProcess

Отсюда мы можем использовать Оптимизирующий конвертер TensorFlow Lite (TOCO) для преобразования квантованного замороженного графика в формат плоского буфера TensorFlow Lite.

$ bazel run tensorflow/lite/toco:toco -- --input_file=/Users/aa/Downloads/ssd_mobilenet_v1_0.75_depth_quantized_300x300_coco14_sync_2018_07_18/tflite_graph.pb --output_file=/Users/aa/Downloads/ssd_mobilenet_v1_0.75_depth_quantized_300x300_coco14_sync_2018_07_18/tflite_graph.tflite --input_shapes=1,300,300,3 --input_arrays=normalized_input_image_tensor --output_arrays='TFLite_Detection_PostProcess','TFLite_Detection_PostProcess:1','TFLite_Detection_PostProcess:2','TFLite_Detection_PostProcess:3' --inference_type=QUANTIZED_UINT8 --mean_values=128 --std_values=128 --change_concat_input_ranges=false --allow_custom_ops

Эта команда принимает входной тензор normalized_input_image_tensor после изменения размера каждого кадра изображения камеры до 300 × 300 пикселей. Выходные данные квантованной модели представляют четыре массива: detection_boxes, detection_classes, detection_scores и num_detections.

Затем мы можем взять наш недавно сгенерированный файл tflite_graph.tflite и загрузить его в Coral Web Compiler, чтобы сделать его совместимым с Edge TPU. После завершения преобразования нам просто нужно нажать кнопку загрузки, чтобы загрузить нашу совместимую с Edge TPU модель, которую можно скопировать на Coral Dev Board.

Преобразование модели TensorFlow в формат OpenVINO IR

Однако нам все еще нужно преобразовать наши модели в формат OpenVINO IR, чтобы мы могли запускать наши тесты на Intel Neural Compute Stick 2.

Однако это оказывается камнем преткновения, поскольку программное обеспечение, необходимое для преобразования моделей TensorFlow, не входит в состав урезанной версии набора инструментов OpenVINO, установленного на Raspberry Pi. Это означает, что нам нужна настоящая машина x86 под управлением Ubuntu Linux с установленным OpenVINO.

К счастью, нам не нужно подключать Neural Compute Stick. Нам просто нужна полная установка OpenVINO, и мы можем сделать это в облаке. Возможно, самый быстрый способ сделать это - запустить экземпляр у поставщика облачных услуг, такого как Digital Ocean, а затем установить инструментарий OpenVINO и запустить оптимизатор моделей, часть программного обеспечения, которое может преобразовать нашу модель TensorFlow в формат Intel OpenVINO IR. по экземпляру.

Идите вперед и загрузите набор инструментов OpenVINO для Linux либо на свой ноутбук, либо прямо в свой облачный экземпляр. Если вы загрузили его на свой ноутбук, вы можете скопировать его с локального компьютера на хост в облаке, используя scp.

$ scp l_openvino_toolkit_p_2019.1.094.tgz [email protected]:

Убедитесь, что у вас запущен X-сервер и включена пересылка X11 на локальный компьютер, поскольку он понадобится вам в процессе установки инструментария OpenVINO. Затем войдите в свой экземпляр Digital Ocean, используя пароль, который был отправлен вам по электронной почте, или используя свой SSH-ключ.

$ ssh -XY [email protected]

Вы можете проверить свое SSH-соединение, чтобы убедиться, что перенаправление X11 настроено и работает, установив и запустив xterm на удаленном компьютере. Если все в порядке, оно должно появиться на рабочем столе вашего ноутбука.

# apt-get install xterm
# xterm

Затем вы можете продолжить и установить версию набора инструментов OpenVINO для Ubuntu.

# tar xvf l_openvino_toolkit_<VERSION>.tgz
# cd l_openvino_toolkit_p_2019.1.094
# ./install_openvino_dependencies.sh
# ./install_GUI.sh

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

После завершения установки мы можем продолжить и проверить, что все установлено правильно, запустив демонстрацию логического вывода. Прежде чем мы это сделаем, нам сначала нужно установить предварительные условия для демонстрации.

# cd /opt/intel/openvino/deployment_tools/model_optimizer/install_prerequisites
# ./install_prerequisites.sh

Поскольку у нас нет Neural Compute Stick или другого оборудования, подключенного к нашему облачному экземпляру, нам нужно будет использовать ЦП, а не устройство MYRIAD, которое мы используем при выполнении логического вывода на нашем Raspberry Pi.

# cd ../../demo/
# ./demo_squeezenet_download_convert_run.sh -d CPU

Если все работает, мы готовы преобразовать наши модели TensorFlow в формат OpenVINO IR. К сожалению, сделать это не так просто, как вы ожидали, в основном из-за диапазона уровней, который поддерживает OpenVINO.

Оказывается, преобразовать модели, изначально созданные в TensorFlow, сложно, и инструкции на самом деле не охватывают, как преобразовать что-либо, кроме самых простых моделей. Однако давайте начнем с того, что возьмем модель SSD MobileNet v2, обученную на наборе данных COCO, и загрузим ее в наш облачный экземпляр.

# cd ~
# wget http://download.tensorflow.org/models/object_detection/ssd_mobilenet_v2_coco_2018_03_29.tar.gz
# tar -zxvf ssd_mobilenet_v2_coco_2018_03_29.tar.gz

Отсюда мы можем использовать оптимизатор модели OpenVINO и некоторые уловки для преобразования нашей модели MobileNet в формат OpenVINO IR. Если вы конвертируете предварительно обученную модель TensorFlow и не уверены в форме, вы можете использовать TensorBoard, чтобы загрузить модель и изучить ее, чтобы определить форму.

К счастью, модель SSD MobileNet v2 является одной из поддерживаемых замороженных топологий для преобразования, поэтому мы можем продолжить и преобразовать ее, как показано ниже.

# python3 /opt/intel/openvino/deployment_tools/model_optimizer/mo_tf.py --input_model ~/ssd_mobilenet_v2_coco_2018_03_29/frozen_inference_graph.pb --input_shape [1,300,300,3] --data_type FP16 --tensorflow_use_custom_operations_config /opt/intel/openvino/deployment_tools/model_optimizer/extensions/front/tf/ssd_support.json --tensorflow_object_detection_api_pipeline_config ~/ssd_mobilenet_v2_coco_2018_03_29/pipeline.config --reverse_input_channels --output_dir ~/
   .
   .
   .
[ SUCCESS ] Generated IR model.
[ SUCCESS ] XML file: /root/frozen_inference_graph.xml
[ SUCCESS ] BIN file: /root/frozen_inference_graph.bin
[ SUCCESS ] Total execution time: 91.58 seconds.
#

⚠️ Предупреждение Перед запуском сценария тестирования TensorFlow, который включает оптимизацию для TensorRT с моделью SSD MobileNet v2 на Jetson Nano, вы должны удалить строку batch_norm_trainable из файла pipeline.config в каталог моделей. Это устарело и не поддерживается.

Мы также хотим преобразовать глубинную модель MobileNet v1 SSD 0.75, которая снова была обучена на наборе данных COCO, которая должна работать несколько быстрее на нашем оборудовании, хотя и с меньшей точностью. Итак, возьмите модель и загрузите ее в наш облачный экземпляр.

# cd ~
# wget http://download.tensorflow.org/models/object_detection/ssd_mobilenet_v1_0.75_depth_300x300_coco14_sync_2018_07_03.tar.gz
# tar -zxvf ssd_mobilenet_v1_0.75_depth_300x300_coco14_sync_2018_07_03.tar.gz

На этот раз вместо того, чтобы указывать model_optimizer на файл замороженной модели, мы собираемся направить его на мета-график. Мы также вынуждены указывать выходные узлы. Точно так же, как преобразование моделей из TensorFlow в TensorFlow Lite зависит от модели и того, как она была обучена, преобразование в формат OpenVINO IR не является полностью шаблонным.

#python3 /opt/intel/openvino/deployment_tools/model_optimizer/mo_tf.py --input_meta_graph ssd_mobilenet_v1_0.75_depth_300x300_coco14_sync_2018_07_03/model.ckpt.meta --input_shape [1,300,300,3] --data_type FP16 --tensorflow_use_custom_operations_config /opt/intel/openvino/deployment_tools/model_optimizer/extensions/front/tf/ssd_support.json --tensorflow_object_detection_api_pipeline_config ssd_mobilenet_v1_0.75_depth_300x300_coco14_sync_2018_07_03/pipeline.config --reverse_input_channels --output_dir ~/ --output="detection_boxes,detection_classes,detection_scores,num_detections"
   .
   .
   .
[ SUCCESS ] Generated IR model.
[ SUCCESS ] XML file: /root/model.ckpt.xml
[ SUCCESS ] BIN file: /root/model.ckpt.bin
[ SUCCESS ] Total execution time: 46.14 seconds.
$

ℹ️ Информация. Точные заклинания командной строки, необходимые для преобразования модели из TensorFlow в формат OpenVINO IR, не всегда очевидны. Лучшее место для получения помощи по этой теме - форум Компьютерное зрение в Intel Developer Zone.

После преобразования у нас будут файлы моделей .bin и .xml, необходимые для использования нашей модели TensorFlow с OpenVINO на Raspberry Pi с Intel Neural Compute Stick 2.

⚠️ Предупреждение. Убедитесь, что вы используете ту же версию набора инструментов OpenVINO на Raspberry Pi, что и в облаке. Здесь мы используем 2019.1.0 как в облаке, так и на Raspberry Pi. Если у вас есть несовпадающая версия, вы можете увидеть ошибку невозможно проанализировать будущие версии при попытке загрузить преобразованные сети.

Теперь вы можете скопировать эти файлы моделей обратно из облака на свой Raspberry Pi. Войдите в Raspberry Pi с помощью Neural Compute Stick 2 и возьмите их из своего облачного экземпляра вместе с соответствующим файлом меток.

$ cd ~
$ scp "[email protected]:frozen_inference_graph.*" .
$ wget https://gist.githubusercontent.com/aallan/fbdf008cffd1e08a619ad11a02b74fa8/raw/4183a4fd800c2d2d6211fd5129bf88d709072564/coco_labels.txt

Мы закончили, по крайней мере, для этих двух моделей.

После того, как вы сконвертировали все свои модели, вы можете закрыть экземпляр и уничтожить его. Он будет безвозвратно удален из вашего аккаунта и гарантирует, что вам не будет выставлен счет за дальнейшее использование.

⚠️ Предупреждение. Если вы хотите взглянуть на более постоянную установку, вам следует ознакомиться с инструкциями по созданию образа Docker, который затем можно развернуть в Digital Ocean. Поскольку внесенные нами изменения будут потеряны при замедлении вращения.

Код эталонного тестирования

Мы можем написать довольно короткий кусок кода, который можно запустить на трех наших платформах; Raspberry Pi, MacBook Pro и NVIDIA Jetson Nano. Поскольку эти три платформы могут запускать наши модели TensorFlow с полки.

Однако нам потребуются дополнительные версии кода для конкретных платформ как для оборудования на базе Coral EdgeTPU, так и для оборудования на базе Intel Movidius. Наконец, необходима четвертая версия для NVIDIA Jetson Nano, которая возьмет нашу обычную модель TensorFlow и оптимизирует ее с помощью TensorRT для вывода.

$ ./benchmark_tf.py --model ssd_mobilenet_v2/tf_for_rpi_and_nvidia_and_macbook/frozen_inference_graph.pb --label ssd_mobilenet_v2/tf_for_rpi_and_nvidia_and_macbook/coco_labels.txt --input fruit.jpg --output out.jpg --runs 10000

При синхронизации выполнения TensorFlow возникают значительные накладные расходы при первой загрузке модели логического вывода в сеанс TensorFlow. Последующие времена вывода короче и более последовательны. Если вы посмотрите на код тестирования, мы учли это, отказавшись от первого запуска.

Примечательно, что, хотя время «первого запуска» может удвоиться с оборудованием Edge TPU и Movidius, оно значительно больше на машинах на базе CPU и GPU. Первый запуск на оборудовании на базе CPU или GPU может быть значительно увеличен до десятков секунд. Кажется, что NVIDIA Jetson Nano особенно уязвима для этой проблемы, время выполнения первого логического вывода может составлять от тридцати до сотен секунд в зависимости от используемой модели.

ℹ️ Информация. В Ресурсы, которые идут вместе с этим сообщением о тестировании, я включил предварительно оптимизированные модели TensorRT. Их можно передать непосредственно в обычный сценарий TensorFlow, а не запускать (более медленный) сценарий с поддержкой TensorRT. Это должно дать тот же результат, что и передача обычных моделей TensorFlow оптимизированному сценарию TensorRT, который выполнит это преобразование.

В заключение

Уравнять эти платформы и напрямую сравнивать их на самом деле не так уж и тривиально. Хотя они предназначены для решения одной и той же задачи, чтобы ускорить выполнение логических выводов машинного обучения, различия в архитектуре и наборах инструментов затрудняют прямое сравнение. Преобразование моделей - особенно сложная проблема, поскольку как формат Intel OpenVINO IR, так и квантование для TensorFlow Lite от Google оказывается непростым делом в зависимости от вашей модели.

Ссылки на руководства по началу работы

Если вы хотите начать работу с любым аппаратным ускорителем, который я использовал в этом тесте, я собрал пошаговые руководства для оборудования Google, Intel и NVIDIA. Этого, в сочетании с ресурсами из этого поста, должно быть достаточно, чтобы вы начали.













Это сообщение спонсирует Коралл из Google.