Запускаем LLM в браузере с WebAssembly и WebGPU
Как WebAssembly берёт на себя логику на CPU, а WebGPU — параллельную работу на GPU, чтобы чат-бот на WebLLM работал приватно прямо во вкладке браузера, и какие у этого есть практические ограничения.
Откройте веб-страницу — без установки, без аккаунта и без связи с каким-либо AI-сервером — и начните переписываться с ботом, ответы которого целиком генерируются на вашем собственном ноутбуке. С машины ничего не уходит, счёта за API нет, а сетевой кабель можно выдернуть сразу после загрузки страницы, и чат-бот этого даже не заметит.
Это не мечта на пять лет вперёд. Всё это работает уже сегодня, в той же вкладке, где вы читаете почту. За этим стоят две технологии, которые обычно обсуждают по отдельности, хотя сильнее всего они именно вместе: WebAssembly и WebGPU.
Если большую часть времени вы пишете на JavaScript, эти названия могут звучать как что-то из мира игровых движков или забота команды графики. На деле они меняют саму суть браузера: из программы, которая рисует страницы, он превращается в платформу для настоящих вычислений и всё чаще — для локального AI-инференса.
Почему JavaScript нужна помощь
JavaScript хорошо справляется с тем, для чего его создавали: работа с DOM, обработка событий, логика приложения. Но дайте ему что-то по-настоящему тяжёлое — декодирование видео, обработку изображений, физическую симуляцию или нейросеть, — и трещины становятся видны. Сборка мусора и динамическая типизация делают язык приятным в работе, но они же мешают, когда на счету каждая миллисекунда процессорного времени.
Раньше стандартным ответом было вынести тяжёлую работу на сервер. Загрузили картинку, обработали удалённо, скачали результат. У такого подхода есть цена. Счета за серверы растут с каждым новым пользователем, сетевые задержки делают интерфейс медленным, а данные пользователя вынуждены покидать его устройство — что само по себе проблема приватности.
WebAssembly и WebGPU не заменяют JavaScript. Они дают браузеру силу, которой у него никогда не было.
WebAssembly в двух словах
Wasm, сокращение от WebAssembly, — это компактный бинарный формат, который исполняет стековая виртуальная машина. Идея в том, чтобы у языков высокого уровня появилась переносимая цель компиляции и веб-приложения могли приблизиться к нативной скорости.
Задумывался он вовсе не только для веба. Wasm работает в изолированной песочнице с безопасной памятью и, будучи встроенным в страницу, подчиняется политике same-origin браузера, но может запускаться и в средах, не имеющих к вебу никакого отношения.
На практике процесс выглядит так:
- Берёте C, C++, Rust или любой язык, для которого есть компилятор с поддержкой Wasm.
- Код компилируется в файл
.wasm— это бинарный байткод, а не JavaScript, и он куда ближе к машинному языку. - Браузер выполняет этот байткод в собственной песочнице со скоростью, недостижимой для JIT-компилируемого JavaScript.
- Wasm вызывает JavaScript и наоборот, поэтому переписывать всё приложение не нужно — переносите только тяжёлые части.
Figma использует Wasm в движке рендеринга, и во многом поэтому редактирование дизайна в браузере ощущается таким же отзывчивым, как в десктопном приложении. На нём же работает веб-версия Google Earth, а несколько игровых движков уровня AAA умеют экспортировать прямо в Wasm.
Главное, что стоит запомнить: Wasm отвечает за вычисления. Он ускоряет тяжёлую логику, но прямого доступа к GPU не даёт. Для массового параллелизма и графики нужен другой партнёр.
WebGPU — преемник WebGL
Если вы работали с WebGL, то WebGPU — его преемник, и это не просто очередное обновление. Он с нуля спроектирован под современные графические API вроде Vulkan, Metal и Direct3D 12. WebGL же — обёртка над устаревающим OpenGL ES.
В документации MDN этот API описан как способ дать веб-разработчикам доступ к GPU системы для высокопроизводительных вычислений и отрисовки сложной графики в браузере. Отличия от WebGL глубокие:
- WebGL строился вокруг рисования на canvas и никогда толком не справлялся с вычислениями общего назначения на GPU (GPGPU).
- В WebGPU вычислительные шейдеры — полноправная часть API, а не что-то прикрученное сбоку.
- Он даёт низкоуровневый контроль через такие сущности, как
GPUAdapter,GPUDeviceиGPUQueue, — это гораздо ближе к нативным графическим API. - Поскольку он напрямую ложится на современные GPU API, накладные расходы у него намного меньше, чем у WebGL, который всё транслирует через старый слой OpenGL.
На практике это значит, что GPU, который раньше отрисовывал разве что 3D-сцены в браузерных играх, может делать куда больше: обучать небольшие модели, выполнять инференс нейросетей, параллельно обрабатывать изображения и гонять крупные физические симуляции — всё через вычислительные шейдеры прямо в браузере.
Два слоя, которые дополняют друг друга
Легко упустить, что Wasm и WebGPU — не соперники. Они дополняют друг друга.
- Wasm берёт на себя оркестрацию и тяжёлую логику на стороне CPU. Это разбор модели, токенизация, управление памятью и весь тот сложный код, который инструменты машинного обучения обычно пишут на C++ или Rust.
- WebGPU берёт на себя массово-параллельное выполнение. Это огромные матричные операции в основе любой нейросети, которые на одном CPU еле ползли бы.
Вместе они делают LLM внутри вкладки браузера технически реальной. Без WebGPU модель мучительно медленно работала бы на CPU. Без Wasm логику рантайма было бы трудно оптимизировать на чистом JavaScript.
WebLLM как рабочий пример
Одна из самых наглядных демонстраций — WebLLM от команды MLC AI. Это движок LLM-инференса в браузере с ускорением на WebGPU и вообще без сервера. Он полностью совместим с форматом OpenAI API, так что если вы уже вызываете chat.completions, учить почти ничего не придётся. Упрощённый пример использования:
import { CreateMLCEngine } from "@mlc-ai/web-llm";
// Callback to track model download & loading progress
const initProgressCallback = (progress) => {
console.log(progress.text);
};
// A small model already compiled into MLC format
const selectedModel = "Llama-3-8B-Instruct-q4f32_1-MLC";
async function main() {
const engine = await CreateMLCEngine(selectedModel, {
initProgressCallback,
});
const reply = await engine.chat.completions.create({
messages: [
{ role: "user", content: "Explain WebGPU in one sentence" },
],
});
console.log(reply.choices[0].message.content);
}
main();
Вот что происходит за кулисами:
CreateMLCEngineскачивает веса модели, уже сжатые и квантованные, а также Wasm-библиотеку с логикой инференса.- Слой Wasm выполняет токенизацию, управляет контекстом диалога и оркестрирует весь процесс инференса.
- Тяжёлые матричные операции, составляющие суть каждого прямого прохода, выполняются как вычислительные шейдеры WebGPU и используют параллелизм GPU вашего устройства.
- Всё остаётся внутри песочницы браузера, поэтому ни промпты, ни данные пользователя не покидают устройство.
В итоге у вас чат-бот, приватный по умолчанию, работающий офлайн после кэширования модели и не нагружающий сервер, за который иначе пришлось бы платить. Инди-разработчики и небольшие команды могут выпускать AI-функции без счёта за облачные GPU, который взлетает вместе с трафиком.
Не только языковые модели
Связка Wasm и WebGPU применима далеко не только к LLM. Вот ещё несколько областей, где её уже используют:
- Обработка изображений и видео: сложные фильтры, удаление фона и апскейлинг, для которых раньше требовался запрос к серверу, теперь работают в реальном времени на клиенте.
- Компьютерное зрение: распознавание объектов или лиц прямо с камеры, без отправки видеопотока за пределы устройства.
- Интерактивная работа с данными: тяжёлые численные расчёты в духе NumPy прямо в браузерных ноутбуках.
- 3D-игры и симуляции: и Unity, и Unreal осваивают экспорт под WebGPU, и рендеринг в браузере становится намного ближе к тому, что дают нативные сборки.
- CAD и 3D-дизайн в браузере: работа со сложными 3D-моделями без десктопного софта.
Ограничения, которые стоит учесть
Прежде чем переносить каждый AI-бэкенд на клиент, держите в голове эти ограничения:
- Поддержка в браузерах пока не повсеместная. WebGPU включён по умолчанию в Chrome, Edge и свежих сборках Safari, но в Firefox он всё ещё экспериментальный и включается флагом.
- Первая загрузка может быть большой. Даже небольшую модель сначала нужно доставить в браузер пользователя, поэтому продумайте первый запуск — обычно с понятным индикатором прогресса.
- Производительность по-прежнему зависит от железа. Офисный ноутбук со встроенной графикой и близко не сравнится с мощной дискретной видеокартой, так что выбирайте модель под свою реальную аудиторию.
- Отладка меняется. Вы больше не ловите баги в серверной логике, которую контролируете. Вы отлаживаете код, который работает на огромном и непредсказуемом множестве клиентских устройств.
Ничто из этого не повод отказываться от технологии. Это лишь напоминание, что работа на клиенте тоже требует продуманной архитектуры.
Почему на этот раз всё иначе
Многие веб-тренды угасают, но здесь почти все крупные производители браузеров тянут в одну сторону. Google, Apple, Microsoft и Mozilla вместе развивают эти стандарты в рамках W3C, так что это не ставка одного вендора, от которой могут тихо отказаться.
Граница между веб-приложением и нативным продолжает размываться. Браузер, который когда-то лишь показывал документы, теперь способен на серьёзные вычисления и даже AI-инференс — без установки, без лишнего сервера и с заметно лучшей приватностью, ведь данным пользователя не нужно покидать устройство.
Если вы считали Wasm и WebGPU нишевой графической темой, поставьте небольшой эксперимент. Загрузите компактную модель через WebLLM в каком-нибудь пет-проекте и почувствуйте, каково это — AI, который работает у вас в руках, а не на чужом сервере. Для следующих шагов: код лежит в репозитории WebLLM, сам стандарт — на webassembly.org, а справочник — на странице WebGPU API в MDN.