Создайте локального и автономного чат-бота с помощью WebLLM.

Опубликовано: 13 января 2024 г.

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

Теперь, когда вы лучше понимаете ИИ на стороне клиента, вы готовы добавить WebLLM в веб-приложение списка дел. Код вы можете найти в ветке web-llm репозитория GitHub .

WebLLM — это веб-среда выполнения для LLM, предоставляемая компиляцией машинного обучения. Вы можете опробовать WebLLM как отдельное приложение . Приложение создано на основе облачных чат-приложений, таких как Gemini , но вывод LLM выполняется на вашем устройстве, а не в облаке. Ваши подсказки и данные никогда не покидают ваше устройство, и вы можете быть уверены, что они не будут использованы для обучения моделей.

Чтобы выполнить вывод модели на устройстве, WebLLM объединяет WebAssembly и WebGPU . В то время как WebAssembly позволяет эффективно выполнять вычисления на центральном процессоре (ЦП), WebGPU предоставляет разработчикам низкоуровневый доступ к графическому процессору (GPU) устройства.

Browser Support

  • Хром: 113.
  • Край: 113.
  • Предварительная версия технологии Firefox: поддерживается.
  • Предварительная версия технологии Safari: поддерживается.

Source

Установить ВебЛЛМ

WebLLM доступен в виде пакета npm . Вы можете добавить этот пакет в свое приложение списка дел, запустив npm install @mlc-ai/web-llm .

Выберите модель

Далее вам нужно выбрать LLM для локального выполнения. Доступны различные модели.

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

  • Токен: наименьшая единица текста, которую LLM может обработать.
  • Контекстное окно: максимальное количество токенов, которые может обработать модель.
  • Параметры или веса: внутренние переменные, изученные во время обучения, исчисляемые миллиардами.
  • Квантование: количество битов, представляющих веса. Большее количество битов означает более высокую точность, но и более высокое использование памяти.
  • Форматы чисел с плавающей запятой: 32-битные числа с плавающей запятой (полная точность, F32) обеспечивают более высокую точность, а 16-битные числа с плавающей запятой (половинная точность, F16) имеют более высокую скорость и меньшее использование памяти, но требуют совместимого оборудования.

Эти ключевые термины, как правило, являются частью названия модели. Например, Llama-3.2-3B-Instruct-q4f32_1-MLC содержит следующую информацию:

  • Модель LLaMa 3.2.
  • Модель имеет 3 миллиарда параметров.
  • Он идеально настроен для инструкций и быстрых помощников (Instruct).
  • Он использует 4-битное (q4) равномерное (_1) квантование .
  • Он имеет 32-битные числа с плавающей запятой полной точности.
  • Это специальная версия, созданная Machine Learning Compilation.

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

Модель с 3 миллиардами параметров и 4 битами на параметр уже на момент написания этой статьи могла иметь размер файла до 1,4 ГБ, который приложению необходимо загрузить на устройство пользователя перед первым использованием. Можно работать с моделями 3B, но когда дело доходит до возможностей перевода или простых знаний, модели 7B дают лучшие результаты. Однако с 3,3 ГБ и выше они значительно больше.

Чтобы создать механизм WebLLM и инициировать загрузку модели для вашего чат-бота со списком дел, добавьте в свое приложение следующий код:

import {CreateMLCEngine} from '@mlc-ai/web-llm';
const engine = await CreateMLCEngine('Llama-3.2-3B-Instruct-q4f32_1-MLC', {
  initProgressCallback: ({progress}) =>  console.log(progress);
});

Метод CreateMLCEngine принимает строку модели и необязательный объект конфигурации. Используя метод initProgressCallback , вы можете запросить ход загрузки модели, чтобы представить ее пользователям, пока они ждут.

Cache API: сделайте ваш LLM работающим в автономном режиме

Модель загружается в кэш-хранилище вашего сайта. API Cache был представлен вместе с Service Workers, чтобы ваш веб-сайт или веб-приложение работали в автономном режиме. Это лучший механизм хранения для кэширования моделей ИИ . В отличие от HTTP-кэширования, Cache API представляет собой программируемый кеш, который полностью находится под контролем разработчика.

После загрузки WebLLM считывает файлы модели из Cache API, а не запрашивает их по сети, что делает WebLLM полностью автономным.

Как и во всех хранилищах веб-сайтов, кеш изолирован для каждого источника. Это означает, что два источника, example.com и example.net , не могут использовать одно и то же хранилище. Если бы эти два веб-сайта хотели использовать одну и ту же модель, им пришлось бы загрузить ее отдельно.

Вы можете проверить кеш с помощью DevTools , перейдя в раздел «Приложение» > «Хранилище» и открыв хранилище кэша.

Настроить разговор

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

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

Подсказки для пользователя и помощника можно использовать для подсказок N-shot, предоставляя LLM примеры на естественном языке о том, как он должен вести себя или реагировать.

Вот минимальный пример настройки разговора для приложения списка дел:

const messages = [
  { role: "system",
    content: `You are a helpful assistant. You will answer questions related to
    the user's to-do list. Decline all other requests not related to the user's
    todos. This is the to-do list in JSON: ${JSON.stringify(todos)}`
  },
  {role: "user", content: "How many open todos do I have?"}
];

Ответьте на свой первый вопрос

Возможность завершения чата предоставляется как свойство созданного ранее движка WebLLM ( engine.chat.completions ). После загрузки модели вы можете запустить вывод модели, вызвав метод create() для этого свойства. В вашем случае вы хотите передавать ответы в потоковом режиме, чтобы пользователь мог начать читать, пока они сгенерированы, сокращая предполагаемое время ожидания:

const chunks = await engine.chat.completions.create({  messages,  stream: true, });

Этот метод возвращает AsyncGenerator , подкласс скрытого класса AsyncIterator . Используйте цикл for await...of для ожидания фрагментов по мере их поступления. Однако ответ содержит только новые токены ( delta ), поэтому вам придется собрать полный ответ самостоятельно.

let reply = '';

for await (const chunk of chunks) {
  reply += chunk.choices[0]?.delta.content ?? '';
  console.log(reply);
}

Оказывается, сети всегда приходилось иметь дело с потоковой передачей ответов. Вы можете использовать API, такие как DOMImplementation, для работы с этими потоковыми ответами и эффективного обновления HTML.

Результаты основаны исключительно на строках. Вы должны сначала проанализировать их, если хотите интерпретировать их как JSON или другие форматы файлов.

Однако у WebLLM есть некоторые ограничения: перед первым использованием приложению необходимо загрузить огромную модель, которую нельзя использовать совместно с разными источниками, поэтому другому веб-приложению, возможно, придется загрузить ту же модель еще раз. Хотя WebGPU обеспечивает производительность вывода, близкую к исходной, он не достигает полной собственной скорости.

Демо

Эти недостатки устраняются с помощью Prompt API — исследовательского API, предложенного Google, который также работает на стороне клиента, но использует центральную модель, загруженную в Chrome. Это означает, что несколько приложений могут использовать одну и ту же модель на полной скорости выполнения.

Подробнее о добавлении возможностей чат-бота с помощью Prompt API читайте в следующей статье.