Использование Intel Movidius для нейронных сетей
Введение
Мы занимаемся разработкой глубоких нейронных сетей для анализа фото, видео и текстов. В прошлом месяце мы купили для одного из проектов очень интересную штуковину:
Intel Movidius Neural Compute Stick.
Это специализированное устройство для нейросетевых вычислений. По сути, внешняя видеокарточка, заточенная под нейронные сети, очень компактная и недорогая (~$83). Первыми впечатлениями от работы с Movidius«ом мы и хотим поделиться. Всех заинтересовавшихся прошу под кат.
Вычислительные мощности устройства
В плане вычислений нейронки чрезвычайно прожорливы: для их обучения нужны GPU, а для использования в реальных задачах — тоже GPU или мощные CPU. Movidius NCS позволяет использовать глубокие нейросети на устройствах, которые были первоначально на это не рассчитаны, например: Raspberry Pi, DJI Phantom 4, DJI Spark. Речь идёт только про этап предсказания (inference заранее обученной сети): обучение нейросетей на Movidius пока что не поддерживается.
Производительность чипа — около 100 гигафлопс, 10^9 FLOPS, (это примерно соответствует уровню топовых суперкомпьютеров начала 90ых, сейчас это порядка сотен петафлопс, 10^15).
Для справки: FLOPS — это количество вычислительных операций или инструкций, выполняемых над операндами с плавающей точкой (FP) в секунду. Для углубления в тему советую интеловскую статью.
Железка построена на базе чипа Myriad 2. В конфигурацию Myriad 2 входит 12 специализированных программируемых векторных процессоров. Компоненты SoC подключены к высокоскоростному внутреннему соединению, работающему с минимальными задержками. Myriad 2 позиционируется как сопроцессор совместно с процессором приложений в мобильных устройствах, или как автономный процессор в устройствах носимой или встраиваемой электроники.
Сам процессор Myriad 2
Ну, а в форм-факторе флешки (Neural Compute Stick) его можно использовать для встраивания нейросетей в беспилотники, например, вместе с Raspberry Pi.
Приступим к установке и запуску первой программы на NCS
Что нам понадобится
- Intel Movidius. Узнать, где он продаётся, можно по ссылке. Мы брали на Амазоне.
- Ubuntu 16.04 LTS или Raspbian OS. Официально поддерживаются только они, но в принципе можно попробовать использовать и на других линуксах.
- SDK с официального репозитория компании. Его мы скачаем дальше из консоли.
- Экспортированный из Tensorflow или Caffe бинарник с графом весов нейросети. Последняя версия Movidius поддерживает только форматы моделей Tensorflow или Caffe. Поскольку мы будем запускать стандартный пример, строить самим граф нам не придётся.
Подготовка
Подключаем Movidius в разъем USB 3.0. Далее пишем в консоли:
$ git clone https://github.com/movidius/ncsdk.git
$ cd ncsdk
$ sudo make install
Эти команды установят:
- NCS Libraries → /usr/local/lib
- NCS Toolkit binaries → /usr/local/bin
- NCS Include files → /usr/local/include
- NCS Python API → /opt/movidius
А также добавят путь к python-либе Мовидиуса в PYTHONPATH.
Запустим пример
В той же папке выполним команду для построения примеров:
$ make examples
Чтобы подготовить стандартный пример — обученную на ImageNet реализацию inception_v1 — выполним следующие команды:
$ cd examples/tensorflow/inception_v1
$ make all
Последняя команда использует описание сетки и уже обученные веса и компилирует бинарный граф, который мы можем потом уже запустить на Myriad 2 VPU.
Теперь мы запустим тестовый скрипт run.py. Коротко расскажу, что происходит в скрипте в целом (некоторые части скрипта опущены):
#Подключаем библиотеки NCS, numpy, sys и opencv
from mvnc import mvncapi as mvnc
import sys
import numpy
import cv2
#/Кусок кода опущен/
#Указываем путь к бинарному графу
graph_filename = 'graph'
#Указываем путь к папке с картинкой
image_filename = path_to_images + 'mouse.jpg'
#Проверяется доступность NCS-устройства, а затем производится его открытие,
#в ином случае выкидывается ошибка
devices = mvnc.EnumerateDevices()
if len(devices) == 0:
print('No devices found')
quit()
device = mvnc.Device(devices[0])
device.OpenDevice()
#Загружается предкомпилированный бинарный граф, экспортированный из TensorFlow
#(ещё поддерживается Caffe)
with open(path_to_networks + graph_filename, mode='rb') as f:
graphfile = f.read()
#/Кусок кода опущен/
#Подключенный выше граф грузится на устройство
graph = device.AllocateGraph(graphfile)
#Изображение переводится в подходящий формат и загружается на чип
img = cv2.imread(image_filename).astype(numpy.float32)
dx,dy,dz= img.shape
delta=float(abs(dy-dx))
if dx > dy: #crop the x dimension
img=img[int(0.5*delta):dx-int(0.5*delta),0:dy]
else:
img=img[0:dx,int(0.5*delta):dy-int(0.5*delta)]
img = cv2.resize(img, (reqsize, reqsize))
img=cv2.cvtColor(img,cv2.COLOR_BGR2RGB)
#Нормализация изображения
for i in range(3):
img[:,:,i] = (img[:,:,i] - mean) * std
print('Start download to NCS...')
graph.LoadTensor(img.astype(numpy.float16), 'user object')
#Получаем результат
output, userobj = graph.GetResult()
#Далее печатаем релевантный топ по категориям и закрываем NCS-устройство
top_inds = output.argsort()[::-1][:5]
print(''.join(['*' for i in range(79)]))
print('inception-v1 on NCS')
print(''.join(['*' for i in range(79)]))
for i in range(5):
print(top_inds[i], categories[top_inds[i]], output[top_inds[i]])
print(''.join(['*' for i in range(79)]))
graph.DeallocateGraph()
device.CloseDevice()
print('Finished')
Когда мы собирали пример, мы вводили в консоль команду make all, после которой в консоль выводилась полезная информация, например, можно увидеть, как быстро данные проходят через каждый слой сети с помощью Detailed Per Layer Profile. Полезная для отладки и оптимизации штука.
Запускаем скрипт:
$ python3 run.py
Тестовая картинка загрузится на NCS, пройдёт через Inception, и в консоли отобразится результат распознавания (вероятностное распределение по 1000+1 категории датасета ImageNet).
Number of categories: 1001
Start download to NCS...
*******************************************************************************
inception-v1 on NCS
*******************************************************************************
674 mouse, computer mouse 0.99512
663 modem 0.0037899
614 joystick 0.00031853
528 desktop computer 0.00021553
623 lens cap, lens cover 0.0001626
*******************************************************************************
Finished
Видно, что сеть с ~99% уверенностью полагает, что на картинке компьютерная мышь (благодаря нашей подсказке:)), на втором месте с близкой к 0% уверенности — модем, и так далее. Сетка права, так что поздравляем вас с первой нейронкой, успешно запущенной на этом устройстве!
Заключение
В конце хотелось бы перечислить главные достоинства и недостатки устройства.
Сперва плохие новости:
- Устройство официально поддерживает работу только с Raspbian OS или Ubuntu 16.04 LTS.
- Устройство и его SDK на данный момент поддерживают только файлы с весами нейросетей в формате Caffe и Tensorflow.
- На устройстве можно делать только предсказания (inference), а обучать модели нельзя.
Хорошие новости:
- Вы можете запускать нейронки на Raspberry Pi!
- Очень простой API на python/C.
- Низкая потребляемая мощность (1 Вт), устройство питается от USB.
- Очень быстрый для такого компактного устройства: например, препроцессинг фотографии ~800×800 и прогон её через Inception_v1 занимают ~120–130 миллисекунд.
- Есть коллекция уже готовых для запуска open-source моделей (так называемый Model Zoo).
- Интересно, что вы можете подключить сразу несколько NCS, которые прямо из коробки будут работать в параллельном режиме. Впрочем, мы это пока не тестировали.
Так Intel предлагает использовать Мовидиусы для ускорения вычислений
Само собой, у данного устройства есть аналоги.
Один из них — и пока самый многообещающий — это Gyrfalcon Technology Laceli, имеющий производительность в 28 раз больше, а энергетическую эффективность в 90 раз выше. Единственное препятствие для покупки — это то, что устройство ещё не вышло на рынок.
Еще один конкурент, который давно присутствует на рынке — это NVIDIA Jetson TX2. Отличия:
- Очень разные ценовые категории (559$ против 83$)
- Разные мощности (два ядра CPU на архитектуре Denver 2, четыре ядра ARM Cortex A57 и 256-ядерный Pascal GPU против одного Myriad 2)
- Разный форм-фактор: Jetson гораздо больше, NCS компактный
- Оба устройства решают одну и ту же задачу — задачу внедрения нейронок на борт чего-либо: автомобиля, беспилотника и пр.
Если интересно, напишем в ближайшем будущем еще одну статью про использование Jetson TX2 для нейронных сетей. Спасибо за внимание и хорошего дня)
P. S. Intel объявил о старте конкурса по оптимизации нейросетей для Intel Movidius Neural Compute Stick. Регистрация до 26 января, окончание конкурса — 15 марта.