Легко определить лучшую комбинацию модель/оборудование

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

Используя новейшую технологию компиляции PyTorch 2.0, octoml-profile автоматически выгружает модели на облачные устройства для создания профиля модели вашего приложения. С помощью этих идей вы можете принимать разумные решения на основе данных о том, как найти компромисс между затратами и скоростью и найти правильный баланс для требований вашего приложения.

Вот пример:

При наличии списка кандидатов из 5 языковых моделей для семантического поиска на 3 аппаратных объектах (ЦП Intel IceLake, ЦП Graviton3 и ГП NVIDIA T4) стоимость выполнения миллиона логических выводов с размером пакета 256 может варьироваться от 5 до 78 долларов США. Задержка вывода одиночного прогноза также сильно варьируется от 5 мс до 38 мс.

В этом посте мы рассмотрим этот пример и покажем вам, как оценить стоимость и использование вычислений для ускоренных моделей PyTorch до их развертывания в облаке. Мы начнем с типичного варианта использования octoml-profile: поиск идеального сочетания модели, аппаратного обеспечения и библиотеки ускорения для требований вашего приложения к задержке и стоимости вывода.

Следуйте вместе с сопутствующей записной книжкой Semantic Search tutorial.

Что такое octoml-профиль?

OctoML Profiler — это библиотека Python с открытым исходным кодом (под лицензией Apache 2.0) и облачный сервис, который упрощает процесс сравнительного анализа моделей PyTorch с реальными входными данными на удаленном оборудовании. Предоставляя информацию о производительности и стоимости оборудования для различных вариантов модели, библиотек ускорения и оборудования, octoml-profile дает вам уверенность в выборе идеального сочетания для развертывания вашей модели в облаке.

Вот как это работает:

  1. Во-первых, зарегистрируйтесь, чтобы сгенерировать токен API, и внесите несколько изменений кода — просто добавьте декоратор @accelerate в свою функцию прогнозирования и менеджер контекста remote_profile().
  2. octoml-profile использует Torch Dynamo для извлечения подграфов вычислений из модели.
  3. Сегменты подграфов, которые могут быть скомпилированы и ускорены, отправляются на удаленные серверы логического вывода GPU и CPU для выполнения логического вывода и измерения.
  4. Сегменты модели, которые не могут быть скомпилированы, такие как предварительная/постобработка или сторонние API, запускаются локально и синхронизируются.
  5. Наконец, время выполнения скомпилированных и нескомпилированных сегментов суммируется для получения общего времени логического вывода для каждой запрошенной комбинации серверной части оборудования и библиотеки ускорения.

Например, на приведенной выше диаграмме модель PyTorch состоит из 5 подграфов; каждый подграф является логической частью модели. Есть два подграфа (желтый и синий), которые можно скомпилировать и ускорить, чтобы они отправлялись на удаленное облачное оборудование для измерения логических выводов. Код предварительной обработки (зеленый), код постобработки (красный) и подграф-3 (черный) не могут быть скомпилированы, поэтому они запускаются локально на ноутбуке разработчика и синхронизируются. Скомпилированные подграфы запускаются на нескольких облачных графических процессорах и процессорах для профилирования нескольких целевых аппаратных средств.

Результаты запуска приведенного выше примера через OctoML Profiler с бэкендами NVIDIA T4 и Intel Ice Lake будут выглядеть следующим образом:

Profile 1/1 ran 2 times with 10 repeats per call:
   Segment                            Samples  Avg ms  Failures
===============================================================
0  Uncompiled                               2   3.996

1  Graph #1                         
     r6i.large/torch-eager-cpu             20  34.702         0
     g4dn.xlarge/torch-eager-cuda          20   5.088         0
     g4dn.xlarge/torch-inductor-cuda       20   3.221         0
     g4dn.xlarge/onnxrt-cuda               20   1.421         0

2  Uncompiled                               2   0.164

3  Graph #2                         
     r6i.large/torch-eager-cpu             20   0.026         0
     g4dn.xlarge/torch-eager-cuda          20   0.102         0
     g4dn.xlarge/torch-inductor-cuda       20   0.248         0
     g4dn.xlarge/onnxrt-cuda               20   0.053         0

4  Uncompiled                               2   0.126
---------------------------------------------------------------
Total uncompiled code run time: 4.285 ms
Total times (compiled + uncompiled) and on-demand cost per million inferences per backend:
    r6i.large/torch-eager-cpu (Intel Ice Lake)   39.013ms  $1.37
    g4dn.xlarge/torch-eager-cuda (Nvidia T4)      9.475ms  $1.38
    g4dn.xlarge/torch-inductor-cuda (Nvidia T4)   7.754ms  $1.13
    g4dn.xlarge/onnxrt-cuda (Nvidia T4)           5.759ms  $0.84

Обратите внимание, что приведенные выше «некомпилированные» подграфики — это именно те, которые обычно усложняют попытки профилирования производительности модели. Это связано с тем, что многие профилировщики требуют сериализации модели, а приведенные выше некомпилированные сегменты сложно сериализовать. С octoml-profile вы можете плавно профилировать без этого трения.

Проблема: поиск следующего поколения с языковыми моделями

Следуйте этому примеру с примером блокнота.

Представьте, что вы являетесь частью команды, которой поручено обновить функцию поиска вашего приложения. Возможно, ваше приложение предоставляет доступ к большим объемам текста — от медицинских или юридических документов до твитов или электронных писем. Существующая функция поиска использует лексическое сопоставление для поиска документов, которое просто ищет буквальные совпадения слов запроса. Ваша команда рассматривает возможность перехода на семантический поиск, чтобы повысить точность поиска по сравнению с лексическими совпадениями. Семантический поиск пытается обнаружить контекстуальное значение терминов и расшифровать намерения искателя. Это достигается путем поиска терминов суммы родства. Он начинается с встраивания всего текста корпуса в векторное пространство. Затем, когда выполняется поиск, запрос также встраивается в то же векторное пространство, и результаты поиска становятся ближайшими вложениями.

Вот пример:

Query: A man is eating pasta.
Result: Top 5 most similar sentences in corpus:
A man is eating food. (Score: 0.7035)
A man is eating a piece of bread. (Score: 0.5272)
A man is riding a horse. (Score: 0.1889)
A man is riding a white horse on an enclosed ground. (Score: 0.1047)
A cheetah is running behind its prey. (Score: 0.0980)

Специалисты по данным в вашей команде экспериментируют с несколькими языковыми моделями с открытым исходным кодом и сужают 5 моделей-кандидатов, которые соответствуют диапазону точности/качества для нужд приложения. Используя модели с открытым исходным кодом, а не API с закрытым исходным кодом, вы получаете ряд преимуществ: вы можете настраивать или настраивать модель в соответствии со своими конкретными потребностями, не неся непомерных затрат, вы можете развертывать ее в любом облаке или оборудовании, а ваши клиенты 'данные остаются исключительно в вашем приложении.

Краткий список выявленных подходящих моделей:

Проблемы с определением комбинаций модели и оборудования для приложений SLA

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

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

Здесь на помощь приходит octoml-profile. octoml-profile позволяет легко итеративно профилировать производительность логического вывода, обеспечиваемую комбинациями вариантов модели (различные модели и конфигурации, такие как размер пакета), аппаратными целями и библиотеками ускорения. На момент запуска OctoML Profiler поддерживает несколько графических процессоров NVIDIA, ЦП Intel IceLake и ЦП Graviton3. Обратите внимание, что стоимость запуска каждого типа оборудования колеблется от 10 центов до более 1 доллара.

В дополнение к изучению моделей с помощью комбинаций оборудования, octoml-profile также автоматически запускает библиотеки ускорения через ONNX Runtime и TorchInductor, такие как CUDA, TensorRT и провайдер исполнения ЦП.

Как использовать результаты octoml-profiler для разумного выбора оборудования

Следуйте указаниям в нашей записной книжке-компаньоне, чтобы добавить декоратор @accelerate к вашей функции вывода, оборачивая вызовы в наш менеджер контекста remote_profile. Затем мы профилируем все 5 языковых моделей на 3 доступных аппаратных целях: процессор Intel IceLake, процессор Graviton3 и графический процессор NVIDIA T4.:

Когда мы печатаем результаты фрейма данных, мы получаем 70 строк. Комбинаторный взрыв 5 моделей на 3 цели с 6 библиотеками ускорения огромен!

Мы будем использовать библиотеку статистической визуализации Вега-Альтаир для создания графиков, которые помогут интерпретировать эти результаты.

Сначала мы создадим гистограмму, чтобы определить самый дешевый бэкенд для каждой модели для высокопроизводительного варианта использования (размер пакета 256):

Вот некоторые выводы из нашего анализа стоимости оборудования для партии размером 256 выше:

  • Стоимость в долларах за миллион запросов (ось x) может резко варьироваться от примерно 5 долларов за paraphrase-MiniLM-L3-v2 (фиолетовый) с r7g.large (Graviton3) до примерно 77 долларов за all-distilroberta-v1 (зеленый) с r6i. большой (процессор IceLake).
  • paraphrase-MiniLM-L3-v2 (фиолетовый), как правило, самая доступная модель для работы на любом оборудовании.
  • Даже на том же оборудовании стоимость выполнения миллиона запросов может быть в 2 раза выше, если выбрана неправильная библиотека ускорения. Взгляните на первые 4 столбца модели MiniLM-L12-v2 (красный) для g4dn.xlarge (графический процессор NVIDIA T4). ONNX Runtime с CUDA EP может предоставить миллион выводов примерно за 15 долларов, тогда как с TensorRT затраты увеличиваются до 30 долларов за тот же миллион выводов.

Далее мы создадим аналогичную линейчатую диаграмму для самой быстрой серверной части по модели для размера пакета 256:

Вот некоторые выводы из нашего самого быстрого серверного анализа для пакета размером 256 выше:

  • Процессор Graviton3 (r7g.large) — самый медленный сервер.
  • Процессор Intel IceLake (r6i.large) более чем в два раза быстрее, чем Graviton3.
  • Графический процессор NVIDIA T4 (g4dn.xlarge) на сегодняшний день является самым быстрым сервером для всех моделей.

Давайте рассмотрим только графический процессор NVIDIA T4 для всех 5 моделей:

Здесь мы видим, что библиотека CUDA ONNX-Runtime обеспечивает самые быстрые результаты для большинства моделей, за исключением all-distilroberta-v1, где TorchInductor с CUDA работает немного лучше.

Это было много информации! Наконец, давайте построим график зависимости времени вывода от стоимости, чтобы лучше понять, какая комбинация модели/оборудования/библиотеки является лучшим выбором для выполнения логического вывода в производственной среде с высокой пропускной способностью (размер пакета 256):​​

Давайте рассмотрим идеальный диапазон кандидатов:

Теперь мы можем четко определить фиолетовый кружок, который соответствует paraphrase-MiniLM-L3-v2 на графическом процессоре NVIDIA T4 (g4dn), ускоренном с помощью CUDA EP ONNX Runtime. Эта комбинация обеспечивает вывод за 60 мс для пакета из 256 запросов и стоит около 9 долларов США за миллион запросов.

Рассмотрим другой вариант использования. Вместо высокой пропускной способности с размером пакета 256, возможно, мы хотим оптимизировать быстрые одиночные прогнозы с наименьшей задержкой для каждого запроса пользователя. Таким образом, мы повторно запустим приведенный выше анализ с размером партии, равным 1:

В этом случае максимально возможные задержки составляют от 5 мс до 7 мс, а стоимость за миллион запросов — от 5 до 70 центов с моделью paraphrase-MiniLM-L3-v2. Ваша организация может заплатить более высокую сумму за меньшую задержку и развернуть на Nvidia T4 с помощью ONNXRuntime CUDA EP. В качестве альтернативы, если вы решите, что стоимость важнее, и ищете самый дешевый вариант, хорошим вариантом будет развертывание на Graviton3 с серверной частью ЦП ONNXRuntime.

Профилирование моделей для развертывания — это необходимый шаг для выявления и сокращения ненужного раздувания облачных затрат. Традиционный подход к профилированию моделей — это очень ручной, неопределенный процесс, требующий недель инженерного времени — работа с различными библиотеками ускорения, аппаратными зависимостями и головными болями облачных провайдеров, не говоря уже о проблеме сериализации моделей. Современный подход с учетом компилятора — это octoml-profile. Наш инструмент обеспечивает радикально упрощенный рабочий процесс, требующий всего 3 строки дополнительного кода, чтобы пользователи могли быстро получить информацию.

Ознакомьтесь с нашей документацией Github, чтобы начать!