Что вам важнее в DL-проекте, удобство или производительность? Посмотрим на проблему глазами инженера-разработчика сложных систем с элементами искусственного интеллекта. Как типичный инструментарий в этой сфере справляется с обучением и выполнением?
В этой статье мы запустим пару нейросетей в MATLAB и сравним быстродействие ResNet с opensource-фреймворками. Так что, если хотите обсудить, в чем (кроме удобства) коммерческий фреймворк может выиграть у опенсорса, добро пожаловать!
С чего начинается MATLAB-нейросеть?
Наши заказчики охотно используют нейросети в качестве компонентов своих систем машинного зрения, предиктивной аналитики, анализа цифровых сигналов и во многих других областях. Мы часто пользуемся MATLAB, потому что он позволяет нам разработать и задеплоить сложную систему силами совсем небольшой команды, интегрировать все что нужно с другими тулбоксами MATLAB, чтобы за один присест создать и GUI для лабораторного стенда, и сайт, и подключить внешний код на Python, если надо.
Так вот, хоть мы и используем MATLAB в каждом ML/DL проекте, русская версия сравнения сред для глубокого обучения из Википедии не содержит даже строчки про MATLAB.
Это повод поговорить об этом фреймворке и сравнить его с остальными.
Если вы никогда не видели, как запустить нейронку в MATLAB, вот небольшой пример. Предположим, что вам нужно классифицировать эту картинку:
Какой код позволит нам это сделать?
net = resnet50(); % Открываем скачанную нейросеть
im = imread('cat.png'); % Открываем картинку
sz = net.Layers(1).InputSize; % Подгоняем картинку под нужную размерность
im = im(1:sz(1),1:sz(2),1:sz(3));
label = classify(net, im) % К какому классу относится наш объект?
И вот, что мы получим в ответ:
label =
categorical
Egyptian cat
Перед классификатором – кошка египетской породы, а перед нами – высокоуровневый фреймворк. Здесь можно делать fit-predict, а можно скачать и запустить готовую нейросеть. Поэкспериментируем с зашумленными изображениями.
% Получим пары “класс, уверенность”
predict_scores = predict(net, im);
[scores,indx] = sort(predict_scores, 'descend');
classNames = net.Layers(end).ClassNames;
classNamesTop = classNames(indx(1:5));
% Настраиваем область отображения
h = figure;
h.Position(3) = 2*h.Position(3); % Сократим ширину окна на 50%
ax1 = subplot(1,2,1);
ax2 = subplot(1,2,2);
% Выводим график
image(ax1,im);
barh(ax2,scores(5:-1:1))
xlabel(ax2,'Уверенность')
yticklabels(ax2,classNamesTop(5:-1:1))
ax2.YAxisLocation = 'right';
Завернём код в небольшой цикл и получим:
Совсем небольшой скрипт, а сколько возможностей. Многие популярные предобученные нейронки уже заложены в MATLAB Deep Learning Toolbox, а те, которых нет, – можно импортировать из ONNX, или из TensorFlow 2, или запустить через интерфейс с Python. Вы легко добавите модуль определения карты глубины на базе MiDaS или повысите разрешение изображения при помощи ESRGAN, и ваш робот будет постить в инстаграм 3D-шедевры в высоком разрешении.
Это далеко не весь функционал: в MATLAB можно рисовать графы сетей и делать контроль версий моделей, а можно просто обучать модели внутри блоков Simulink – достаточно лишь указать им датасет.
Это, конечно, хорошо, но будет ли сеть выполняться достаточно быстро на вашей платформе?
Покажите мне, где нужно ускорить
Самая большая часть времени в проекте уходит на понимание задачи и данных: никто не сможет вернуть время, потраченное на решение ненужной бизнесу задачи, а из мусорных данных получаются в основном мусорные модели.
Порассуждаем на основе диаграммы, которая является вольным переопределением CRISP-DM:
Что трудно ускорить: левая часть схемы выражает околобизнесовые затраты. Ускорить ее может наличие у компании опыта, хорошие практики/шаблоны, продуктивное общение с заказчиком и коллегами, удобство фреймворка, контроль версий, всякие генераторы кода и документации, и так далее. Объективно сравнить фреймворки по этой части довольно трудно.
Что значительно легче ускорить: вся правая часть схемы недавно была прерогативой дата сайентистов, но за последние 10 лет хорошо автоматизировалась (как за счет демократизации отрасли, так и за счет прогресса методов и штук вроде AutoML). В этой статье ограничимся тем, что сравним скорость выполнения и немного скорость обучения нейросетей.
Чего мы ожидаем от высокоуровневого фреймворка в плане скорости разработки?
Скоростного выполнения модели
Фреймворк должен оптимизировать код модели, а также позволять легко ее трансформировать и сравнивать производительность разных версий
Автоподбора модели и легкого перебора гиперпараметров
Графический редактор графов, отладчик интерфейсов (между слоями нейросети, например), скрипты, AutoML, учебные материалы и шаблоны, дружелюбное сообщество
Простого и удобного инструментария для работы с данными
Эксплоративный анализ, визуализация, удобный GUI, рефакторинг, версионирование, создание отчетов
Развёртки и поддержки проекта
Сборка проекта, интеграция всех источников данных и внешних компонентов, распаковка проекта на всех необходимых целевых платформах, симуляция и отладка в любых сценариях
Сравниваем скорость на ResNet-50
Что ж, значит в MATLAB тоже есть нейронки, отлично – не придется вручную писать обратное распространение ошибки. Что дальше? Недавно сотрудник MathWorks David Willingham представил доклад, где он сравнивает быстродействие трех фреймворков: MATLAB, PyTorch и Tensorflow.
David Willingham
MathWorks, Deep Learning Product Manager https://www.mathworks.com/matlabcentral/profile/authors/106350
Первое представление о различиях можно подсмотреть в уже упомянутой таблице в Википедии. Здесь фреймворки отличаются только лицензией и поддержкой библиотек для параллельных вычислений (OpenCL и OpenMP), что для нас второстепенно.
Сейчас мы изучим результаты сравнения на инференсе, но для начала сравним скорость обучения ResNet-50. Приходится же иногда переобучаться под новый датасет или обучать кастомную архитектуру.
Итак, для сравнения взята стандартная сетка для классификации изображений – ResNet, вариант с 50 слоями. По некоторым бенчмаркам, обучение на ImageNet 1000 на GPU NVIDIA M40 в течение 90 эпох должно занимать 14 дней, по другим – выходит что A100 отработает 50 эпох за десяток часов (AIME). На обучении наши инструменты показывают примерно одинаковые результаты. Может быть, и правда все упирается в железо.
Зато, когда сеть уже обучена, ее производительность будет зависеть от массы факторов, которые интересно изучить. Ее же нужно запускать для каждого пользователя и для каждого примера (фотографии, нового измерения с датчика, речевого сигнала…), на любой платформе, от сервера до бортовых вычислителей автономного робота. Пересылка через всякие интерфейсы и обращение к базам данных может отнять львиную долю времени...
Сравним выполнение моделей. Сначала – быстродействие на CPU.
Быстродействие на CPU
Давайте сравним запуск на CPU нейросети ResNet в таком сценарии: вы работаете на встраиваемой платформе, где нет ускорителей, или в системе, где нет CUDA. Например, сюда входит очень многое из робототехники, от институтских омни-тележек до космических спутников.
Оказывается, код нашей сетки выполняется в MATLAB на CPU чуть быстрее, чем в других фреймворках.
Оказывается, код нашей сетки выполняется в MATLAB на CPU чуть быстрее, чем в других фреймворках. Бенчмарк для CPU построен на Intel Xeon 3.6 GHz – такие солидные частоты редко встречаются на борту. На более приземленном CPU, возможно, код будет вести себя слегка иначе.
А что, если скомпилировать все при помощи MATLAB Coder? Сеть в MATLAB выполняется в 2 раза быстрее, чем на Tensorflow и в 3 раза быстрее, чем на PyTorch. Да, это не самая тяжелая нейросеть, и хорошо изученная к тому же, есть много приемов оптимизации, которые MathWorks могли заложить в предобученную сеть, включенную в MATLAB.
Если у вас робототехнический проект с CPU на борту, то MATLAB – в принципе единственный коробочный продукт, который позволяет обучать модели и запускать их на любой встраиваемой платформе.
Сохранится ли эффект на GPU? Давайте узнаем.
Быстродействие на GPU
Использование GPU позволяет добиться феноменальных скоростей обучения или выполнения нейросетей... при запуске на сравнительно больших объемах данных.
При прогоне через нейросеть на GPU одного примера за один проход (батч размера 1), если запускать сеть через скрипт, MATLAB есть над чем поработать, судя по графикам, 1 батч можно просто запускать на CPU, разницы не будет. Я обещал обсудить ситуации, когда MATLAB проигрывает – это как раз тот случай.
Пересылка из общей памяти в память GPU занимает много времени, и одновременная обработка данных (в виде батча) выгоднее, если в батче больше данных. Но, поскольку код модели и небольшой набор данных все-таки должны поместиться в памяти видеокарты, максимальный размер батча тоже ограничен.
Если в батче 32 примера, то все гораздо лучше. Теперь мы хорошо загружаем видеокарту и все фреймворки демонстрируют примерно одинаковый прирост быстродействия относительно запуска на CPU. Но это не все, можно ускориться. В MATLAB для этого есть два способа скомпилировать нейронку для GPU.
MEX-функции – это оболочки для внешних программ. Они ведут себя в точности так же, как функции MATLAB/Simulink, но могут попутно с выполнением кода MATLAB вызывать внешнюю программу, C/C++ или иной код. Инструментарий MEX генерирует C++ код для GPU, но не требует лицензии на GPU Coder для задач предсказания (predict).
Упакованный в MEX код нейросети ResNet выполняется на GPU почти в 2 раза быстрее на одном изображении (на одном батче), чем в PyTorch или TensorFlow.
Второй способ для получения оптимизированного кода – GPU Coder. Это уже специальный генератор кода для GPU. Чтобы его применить, нужно всего лишь переключить одну галочку в настройках генератора кода (она называется Generate GPU code), после чего мы получаем встраиваемый оптимизированный CUDA-код, не требующий какого-то специального окружения для запуска на целевой платформе.
Автоматически оптимизированная для TensorRT нейросеть выполняется очень быстро – почти в 3 раза быстрее, чем та же сеть на GPU в Tensorflow или PyTorch. И это на одном батче.
Заключение
В своём докладе MathWorks отмечают, что за полгода выполнение ResNet было ускорено почти в 2 раза. Видимо, как в ядре MATLAB, так и в архитектуре нейросети, ещё есть что оптимизировать. Это вселяет оптимизм – будем ожидать, что разработчики и в следующих версиях сохранят такой темп улучшений.
В общем и целом, MATLAB отвечает всем нашим ожиданиям от высокоуровневого фреймворка в том что касается разработки систем с элементами искусственного интеллекта (список критериев – выше). Нам он облегчает и работу с данными, и подбор алгоритмов классического машинного обучения, и подключение глубоких нейросетей, и разработку собственных топологий, если нужно. Так что мы используем его в проектах с ИИ для самых разных заказчиков.
Пожалуйста, расскажите нам в комментариях о своем опыте работы с нейросетями в MATLAB, о бенчмарках или предпочтениях по фреймворкам. Желаем всем очень производительных AI-проектов, выполненных в комфортной среде!
ZlodeiBaal
Ого. Использование матлаба в 2022. Я думал он остался в 2015 и особо не развивается.
Не понимаю, правда, почему вы бенчмаркаете pytorch|tensorflow без оптимизации под железо с оптимизированным matlab'ом…
n_kapyrin Автор
Кстати, в 2016 появился LiveScript (aka Live Editor), стало возможно работать в MATLAB в стиле Jupyter Notebooks. До этого – только скрипты и сторонний код для нейронок.
Если изучать быстродействие в вакууме, то Вы правы, сравнение не безупречно. Но если изучать количество телодвижений от стадии инженер+ТЗ+железка до прототипа со встроенной нейросеткой... То понятно что для всего нужен свой инструмент.
ZlodeiBaal
Не очень понимаю про какие телодвижения вы говорите.
Есть Torch-TensorRT | TF-TRT, где даже ничего менять не надо.
Есть инструменты инференса чистого. ONNX-Runtime (а вот тут я ещё десяток разбираю — habr.com/ru/company/recognitor/blog/524980 ), которые не тащат с собой кучу дополнительного кода + 1-2 строчками на разных платформах используются.
n_kapyrin Автор
Крутая статья, спасибо! Забавно, как много стойких стандартов создаёт MS. И похоже что у каждой компании есть свой отдельный ONNX-фреймворк.
sentimentaltrooper
Матлаб был в университетской среде потому что на нём как-то могли писать студенты. Первые лекции по ML с Coursera были еще как-то в Октаве потом всё ушло в Jupyter Notebooks, но мы уже тогда спрыгнули на питон. Инженер + ТЗ + железка это очень часто tiny YOLO на ComputeModule с чем справится и интерн (a потренирует в Colab). Если задача сложная и более научная, например анализ / классификация RF сигналов и надо самим думать и пялиться много на графики и т.п. то в команде прижился R и SciPy, к которому все прикручивается сильно проще и из которого потом можно так же просто экспортировать. В итоге в нашей научной команде, не настоящих программистов, ответа на вопрос зачем плаить зa лицензию Маталаба мы не нашли.
n_kapyrin Автор
Спасибо за дискуссию! Естественно, интересно было бы больше почитать про ваш стэк и задачи. Если комбинация инструментов эффективно решает ваши проблемы, то прекрасно.
Лично для меня MATLAB чуть ли не лучшее воспоминание среди институтских инструментов. Критерий: сколько всего удавалось сделать за один присест в одном инструменте.