Улучшения WebAssembly и WebGPU для более быстрого веб-ИИ, часть 1

Узнайте, как улучшения WebAssembly и WebGPU повышают производительность машинного обучения в Интернете.

Остин Энг
Austin Eng
Дипти Гандлури
Deepti Gandluri
Франсуа Бофор
François Beaufort

Выводы ИИ в сети

Мы все слышали эту историю: ИИ меняет наш мир. Интернет не является исключением.

В этом году в Chrome добавлены функции генеративного искусственного интеллекта, включая создание собственных тем и/или помощь в написании первого черновика текста . Но ИИ – это нечто большее; ИИ может обогатить сами веб-приложения.

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

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

Это мощно по нескольким причинам:

  • Сокращение затрат . Выполнение вывода в клиенте браузера значительно снижает затраты на сервер, и это может быть особенно полезно для запросов GenAI, которые могут быть на порядки дороже, чем обычные запросы.
  • Задержка : для приложений, которые особенно чувствительны к задержке, например аудио- или видеоприложений, выполнение всей обработки на устройстве приводит к уменьшению задержки.
  • Конфиденциальность : запуск на стороне клиента также потенциально может открыть новый класс приложений, требующих повышенной конфиденциальности, когда данные не могут быть отправлены на сервер.

Как рабочие нагрузки ИИ сегодня выполняются в Интернете

Сегодня разработчики приложений и исследователи создают модели с использованием платформ, модели выполняются в браузере с использованием среды выполнения, такой как Tensorflow.js или ONNX Runtime Web , а среды выполнения используют для выполнения веб-API.

Все эти среды выполнения в конечном итоге сводятся к работе на ЦП через JavaScript или WebAssembly или на графическом процессоре через WebGL или WebGPU.

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

Рабочие нагрузки машинного обучения

Рабочие нагрузки машинного обучения (ML) проталкивают тензоры через граф вычислительных узлов. Тензоры — это входы и выходы этих узлов, которые выполняют большой объем вычислений над данными.

Это важно, потому что:

  • Тензоры — это очень большие структуры данных, выполняющие вычисления на моделях, которые могут иметь миллиарды весов.
  • Масштабирование и логический вывод могут привести к параллелизму данных . Это означает, что одни и те же операции выполняются над всеми элементами тензоров.
  • ML не требует точности. Чтобы приземлиться на Луну, вам может понадобиться 64-битное число с плавающей запятой, но для распознавания лиц вам может понадобиться только море 8-битных чисел или меньше.

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

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

Веб-сборка

WebAssembly (Wasm) — это компактный и эффективный формат байт-кода, который может понимать и выполнять среда выполнения. Он разработан с учетом преимуществ базового аппаратного обеспечения и поэтому может работать на скорости, близкой к исходной. Код проверяется и выполняется в безопасной для памяти изолированной среде.

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

Спецификация WebAssembly является итеративной и разрабатывается в открытой группе сообщества W3C .

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

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

Иллюстрация ноутбука, планшета и телефона

Большинство производственных приложений, которые выполняют вывод искусственного интеллекта в Интернете, используют WebAssembly как для вычислений ЦП, так и для взаимодействия с вычислениями специального назначения. В собственных приложениях вы можете получить доступ к вычислениям как общего, так и специального назначения, поскольку приложение может получить доступ к возможностям устройства.

В Интернете, в целях переносимости и безопасности, мы тщательно оцениваем, какой набор примитивов предоставляется. Это балансирует доступность Интернета с максимальной производительностью, обеспечиваемой оборудованием.

WebAssembly — это переносимая абстракция процессоров, поэтому все выводы Wasm выполняются на процессоре. Хотя это не самый производительный выбор, процессоры широко доступны и работают при большинстве рабочих нагрузок на большинстве устройств.

Для небольших рабочих нагрузок, таких как текстовые или звуковые нагрузки, использование графического процессора будет дорогостоящим. Есть ряд недавних примеров, когда Wasm является правильным выбором:

Еще больше вы можете узнать в демонстрациях с открытым исходным кодом, таких как: шепот-tiny , llama.cpp и Gemma2B, работающий в браузере .

Используйте комплексный подход к своим приложениям

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

Например, при обнаружении ориентиров лица в MediaPipe выводы ЦП и ГП сопоставимы (при работе на устройстве Apple M1), но есть модели, в которых отклонение может быть значительно выше.

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

  • Предоставляйте расширения ЦП, критически важные для производительности
  • Включить запуск более крупных моделей
  • Обеспечьте беспрепятственное взаимодействие с другими веб-API.

Более быстрые вычисления

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

Помните, модели машинного обучения не всегда требуют высокого уровня точности. Ослабленный SIMD — это предложение, которое снижает некоторые строгие требования к недетерминированности, что приводит к более быстрому созданию кода для некоторых векторных операций, которые являются «горячими точками» с точки зрения производительности. Кроме того, Relaxed SIMD представляет новые инструкции скалярного произведения и FMA, которые ускоряют существующие рабочие нагрузки в 1,5–3 раза. Это было включено в Chrome 114.

Формат с плавающей запятой половинной точности использует 16 бит для IEEE FP16 вместо 32 бит, используемых для значений одинарной точности. По сравнению со значениями одинарной точности использование значений половинной точности имеет ряд преимуществ: снижение требований к памяти, что позволяет обучать и развертывание более крупных нейронных сетей, а также снижение пропускной способности памяти. Пониженная точность ускоряет передачу данных и математические операции.

Большие модели

Указатели на линейную память Wasm представляются как 32-битные целые числа. Это имеет два последствия: размеры кучи ограничены 4 ГБ (когда компьютеры имеют гораздо больше физической оперативной памяти), а код приложения, предназначенный для Wasm, должен быть совместим с 32-битным размером указателя (что).

Загрузка этих моделей в WebAssembly может быть ограниченной, особенно в случае таких больших моделей, как сегодня. Предложение Memory64 снимает эти ограничения: размер линейной памяти превышает 4 ГБ и соответствует адресному пространству собственных платформ.

У нас есть полноценная работающая реализация в Chrome, релиз которой ожидается позднее в этом году. На данный момент вы можете проводить эксперименты с флагом chrome://flags/#enable-experimental-webassembly-features и отправлять нам отзывы .

Лучшее веб-взаимодействие

WebAssembly может стать отправной точкой для специализированных вычислений в Интернете.

WebAssembly можно использовать для размещения приложений на графическом процессоре в Интернете. Это означает, что одно и то же приложение C++, которое может работать на устройстве, с небольшими изменениями может работать и в Интернете.

Emscripten , набор инструментов компилятора Wasm, уже имеет привязки для WebGPU. Это отправная точка для вывода ИИ в Интернете, поэтому очень важно, чтобы Wasm мог беспрепятственно взаимодействовать с остальной частью веб-платформы. Мы работаем над несколькими различными предложениями в этой области.

Интеграция обещаний JavaScript (JSPI)

Типичные приложения C и C++ (а также многих других языков) обычно пишутся с использованием синхронного API. Это означает, что приложение прекратит выполнение до завершения операции. Такие блокирующие приложения обычно более интуитивно понятны в написании, чем приложения, поддерживающие асинхронность.

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

Следующий пример — вычисление чисел Фибоначчи с использованием обещаний JavaScript для сложения.

long promiseFib(long x) {
 if (x == 0)
   return 0;
 if (x == 1)
   return 1;
 return promiseAdd(promiseFib(x - 1), promiseFib(x - 2));
}
// promise an addition
EM_ASYNC_JS(long, promiseAdd, (long x, long y), {
  return Promise.resolve(x+y);
});
emcc -O3 fib.c -o b.html -s ASYNCIFY=2

В этом примере обратите внимание на следующее:

  • Макрос EM_ASYNC_JS генерирует весь необходимый связующий код, чтобы мы могли использовать JSPI для доступа к результату обещания, как это было бы для обычной функции.
  • Специальный параметр командной строки -s ASYNCIFY=2 . Это вызывает возможность генерировать код, использующий JSPI для взаимодействия с импортом JavaScript, возвращающим обещания.

Дополнительные сведения о JSPI, его использовании и его преимуществах см. в статье «Введение в WebAssembly JavaScript Promise Integration API на v8.dev» . Узнайте о текущей пробной версии Origin .

Управление памятью

Разработчики имеют очень мало контроля над памятью Wasm; модуль имеет собственную память. Любые API, которым требуется доступ к этой памяти, должны копировать ее или копировать, и это использование может действительно накапливаться. Например, графическому приложению может потребоваться копирование и копирование каждого кадра.

Предложение по управлению памятью направлено на обеспечение более детального контроля над линейной памятью Wasm и сокращение количества копий в конвейере приложения. Это предложение находится на этапе 1, мы создаем его прототип в V8, движке JavaScript Chrome, чтобы информировать об эволюции стандарта.

Решите, какой бэкэнд вам подходит

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

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

Продолжить чтение Часть 2