С ростом популярности и возможностей больших языковых моделей (LLM) всё больше компаний стремятся внедрять их в свои бизнес-приложения.
Большие языковые модели широко используются в разных типах приложений: от чат-ботов и виртуальных ассистентов до генерации контента и создания поисковых или рекомендательных систем. О вариантах использования специализированных LLM-приложениях можно почитать у нас в блоге.
При внедрении LLM-приложений компании сталкиваются с важным выбором между использованием serverless архитектуры и выделенными системами. Этот выбор затрагивает не только технические аспекты, но и вопросы стоимости, производительности, а также гибкости управления. Не существует универсального решения — каждый вариант требует анализа с учётом специфики вашего проекта, доступного бюджета, требований к безопасности и операционных возможностей.
Serverless архитектура для LLM-приложений: преимущества и особенности
Традиционные методы развёртывания требуют затрат для настройки и управления инфраструктурой, включая масштабирование и мониторинг серверов. В отличие от этого, бессерверные технологии, предлагаемые облачными провайдерами (AWS Lambda, Azure Functions, Google Cloud Functions и другие), позволяют разработчикам сосредоточиться на коде, а не на инфраструктуре. Код автоматически запускается в ответ на события, а ресурсы для выполнения масштабируются по необходимости, что упрощает процесс управления и снижает операционные издержки.
Одним из ключевых преимуществ бессерверного подхода для LLM-приложений является автоматическое масштабирование и оплата только за фактическое использование ресурсов, что особенно важно для приложений с переменной или непредсказуемой нагрузкой. Это делает бессерверные архитектуры подходящим вариантом для компаний, которые хотят оперативно внедрить LLM-приложения, минимизируя при этом начальные затраты и риски.
В целом многие сходятся во мнении, что бессерверные решения обеспечивают простоту использования и являются отличным вариантом для быстрого прототипирования и компаний с ограниченными ресурсами DevOps. Они позволяют быстро проверять гипотезы и масштабироваться без необходимости управления инфраструктурой.
С другой стороны, выделенные среды предлагают больший контроль, возможности для кастомизации и могут значительно экономить на затратах при масштабировании.
О чём эта статья
В этой статье мы рассмотрим несколько шаблонов интеграции LLM в serverless среде, которые позволяют организовать последовательную и параллельную обработку промптов, кэшировать результаты обработки промптов, а также управлять ошибками. Применение этих шаблонов покажем на примере создания разных материалов для маркетинговой кампании новой модели автомобиля.
1. Прямой вызов модели (Direct Invocation)
Прямой вызов модели — это простой и быстрый способ интеграции LLM в приложения. В этом подходе serverless-функция напрямую вызывает API языковой модели, а результат возвращается синхронно, без использования промежуточных сервисов.
Этот метод подходит для задач с простым циклом «запрос-ответ». Например, такие функции могут генерировать рекламные тексты, отвечать на типовые запросы клиентов или автоматически создавать описания продуктов на основе входных данных.
Синхронная обработка запросов делает этот подход подходящим для сценариев, требующих минимальной задержки. Например, это актуально для генерации текстов в режиме реального времени. Однако важно учитывать, что объёмные ответы от моделей могут увеличить время отклика и вызвать превышение тайм-аутов. Чтобы избежать таких проблем, можно настроить максимальное время выполнения функции или использовать стриминг данных, возвращая частичные результаты по мере их поступления.
Прямой вызов LLM через serverless-функции отлично подходит для сценариев с небольшими объёмами данных и простыми запросами, где важна быстрая реакция системы без сложной оркестрации.
2. Обработка цепочек промптов (Prompt chaining)
Цепочка промптов — это метод, который включает в себя разбиение сложной задачи на серию более мелких, взаимосвязанных промптов, где выходные данные одного промпта служат входными данными для следующего. Severless решения могут управлять вызовами на каждом этапе и передавать промежуточные результаты дальше по цепочке.
Пример цепочки промптов
1. Генерация текста подробного описания автомобиля
Задача: создать подробное описание автомобиля, используя спецификации и изображения.
Результат: модель генерирует детальное описание, основанное на предоставленных данных.
2. Сохранение описания
Задача: сохранить подготовленное на шаге 1 описание автомобиля.
Результат: сгенерированный результат вызова API модели (полное описание автомобиля) передаётся на следующий шаг.
3. Генерация текста краткого описания автомобиля
Задача: создать краткое описание автомобиля специально для галереи изображений.
Результат: модель создаёт короткое и ёмкое описание для отображения в брошюре рядом с изображениями.
4. Сохранение и передача краткого описания на следующий шаг
Задача: сохранить результат генерации краткого описания и передать его на следующий шаг.
Результат: вывод текущего шага (краткое описание) передаётся как входные данные для следующего шага.
5. Создание заголовка
Задача: сгенерировать броский заголовок для использования в брошюре.
Результат: модель создаёт яркое и лаконичное предложение, подходящее для рекламных материалов.
6. Завершение процесса
Итоговый результат включает полное описание, краткое описание для галереи и заголовок для брошюры.
3. Параллельная обработка промптов (шаблон Fan-out/Fan-in)
Параллельная обработка промптов в serverless-среде — это метод, который позволяет ускорить выполнение запросов к модели, выполняя их одновременно, а не последовательно. Каждый промпт обрабатывается как независимая задача, что особенно полезно при работе с большими объёмами данных или при генерации множества текстов.
В serverless-архитектуре каждая задача запускается автоматически в виде отдельной функции. Если нужно обработать несколько запросов одновременно, серверлесс-платформа распределяет их по разным вычислительным узлам, эффективно используя ресурсы и обеспечивая высокую скорость работы.
Особенности параллельной обработки промптов
- Независимость ветвей. Каждая ветвь обрабатывает свою задачу автономно, без ожидания завершения других процессов. Это значит, что разные задачи могут выполняться параллельно, не влияя друг на друга. Например, одна ветвь может заниматься генерацией текстов, в то время как другая — анализом данных.
- Одновременное выполнение. Все ветви запускаются и работают одновременно, что существенно ускоряет выполнение задач. Это позволяет использовать ресурсы нескольких процессоров или вычислительных узлов для обработки разных запросов, снижая общее время выполнения.
- Объединение результатов. После завершения всех параллельных ветвей система переходит к следующему этапу, объединив или агрегировав результаты. Это особенно важно, когда различные части одной задачи требуют обработки разных наборов данных, а затем их синтеза.
- Распределение ресурсов. Параллельная обработка эффективно распределяет ресурсы между задачами. Например, одна ветвь может использовать больше оперативной памяти, а другая — больше процессорных мощностей. Это позволяет оптимизировать использование ресурсов системы и уменьшить время обработки.
Когда параллельная обработка неэффективна? Если результат одной ветви требуется для запуска следующей, процесс должен выполняться последовательно. В таких случаях параллельная обработка не улучшит производительность и может усложнить архитектуру приложения.
Пример параллельной обработки промптов
1. Генерация полного описания автомобиля
Процесс начинается с получения пользовательского ввода, включающего спецификации автомобиля и изображения. С помощью LLM создается полное, детализированное описание автомобиля, которое сохраняется в системе для дальнейшей обработки. Эта задача выполняется в одной ветви.
2. Распараллеливание выполнения задач
Затем для ускорения работы процесс распараллеливается. Обработка данных делится на две ветви, каждая из которых выполняет свою задачу. В одной из ветвей последовательно выполняются задачи: сначала создаётся краткое описание автомобиля для галереи изображений, а затем генерируется заголовок для рекламной брошюры. Во второй ветви, параллельно с этими процессами, создаётся сценарий для рекламного видеоролика.
3. Комбинирование небольших задач
Чтобы оптимизировать время выполнения, короткие задачи, такие как генерация краткого описания и заголовка, объединяются в одну ветвь, что помогает сбалансировать выполнение более коротких и длинных процессов. Благодаря этому завершение всех задач произойдёт одновременно, без задержек.
4. Объединение результатов
После того, как параллельные ветви завершены, их результаты объединяются в финальный вывод. В результате пользователь получает маркетинговый пакет, который включает полное описание автомобиля, краткое описание для галереи, сценарий для рекламного видео и заголовок для брошюры.
4. Кэширование результатов (шаблон Cache-Based)
Одним из механизмов для снижения вычислительной нагрузки и улучшения производительности является кэширование (Cache-Based Pattern). Кэширование позволяет сохранять ранее сгенерированные ответы и повторно использовать их при поступлении похожих промптов, что сокращает время отклика и снижает затраты на обращения к LLM.
Процесс начинается с того, что система проверяет, есть ли в кэше уже сгенерированные данные, которые подходят для ответа на запрос. Если такие данные найдены, то они и используются, и повторное обращение к модели не выполняется.
Например, для повторного запроса рекламного текста для товара с аналогичными характеристиками система может вернуть сохранённый в кэше результат без необходимости ещё раз вызывать модель.
Это решение может быть реализовано как на уровне приложения, так и с помощью внешних кэш-сервисов, таких как Redis или Memcached.
Пример кэширования при работе с LLM
- Инициация процесса запроса.
- Система обращается к хранилищу для поиска подходящих ранее сохранённых результатов.
- Проверка наличия сохранённых данных в кэше.
- Есть ли кэшированный результат? Если данные найдены в кэше, они подготавливаются для ответа и передаются пользователю. Если данные не найдены, выполняется вызов модели для генерации нового результата.
- В случае отсутствия данных в кэше модель генерирует новый результат, который соответствует запросу пользователя.
- После генерации новый результат сохраняется в кэше для последующего использования при поступлении похожих запросов.
- Подготовленные данные приводятся к нужному формату и готовятся для передачи.
- Процесс завершён, и результат передан пользователю.
Если сгенерированный текст или другой контент зависит данных, которые часто меняются, кэшированные результаты могут устареть или быть некорректными. Поэтому нужно продумать механизмы обновления кэша, контроля объёма хранимых данных и времени хранения.
5. Управление ошибками и ограничениями (шаблон Retry with backoff)
Важно продумать, как система будет обрабатывать ошибки и ограничения. Шаблон «Retry with backoff» предполагает повторение неудачной операции с задержкой между попытками.
Задержка увеличивается после каждой неудачной попытки, что помогает снизить нагрузку на систему и даёт ей время для восстановления. Например, если API недоступен, функция будет повторять вызов с возрастающей задержкой.
На иллюстрации показано, как сервис A повторяет вызовы к сервису B, пока не получит успешный ответ. Если после нескольких попыток сервис B не отвечает успешно, сервис A прекращает попытки и возвращает сообщение о сбое вызывающему абоненту.
Также важно настроить автоматическое управление ситуациями, когда приложение приближается к лимиту запросов к модели или времени обработки. Для этого тоже используется экспоненциальный бэк-офф, при котором интервалы между повторными попытками постепенно увеличиваются.
Иногда ошибки могут быть вызваны временными проблемами, такими как превышение квот на использование модели. В таких случаях полезно установить автоматическое ожидание перед повторной попыткой. Также можно использовать более простые запросы, чтобы получить хотя бы частичные результаты, пока проблема не будет решена.
Балансировка нагрузки
Чтобы система быстро реагировала на запросы даже при высокой нагрузке, можно использовать балансировку запросов.
Это значит, что запросы распределяются между разными регионами или серверами модели. Такой подход помогает избежать перегрузки одного сервера и обеспечивает равномерное распределение нагрузки, улучшая общую производительность системы.
Подбор подходящей LLM и настройка ресурсов
LLM отличаются по производительности, стоимости и возможностям генерации текста. Поэтому важно выбирать модель, исходя из конкретных задач: объёма данных, сложности запросов и требуемой скорости обработки.
Кроме того, при использовании серверлесс-решений важно грамотно настраивать объём оперативной памяти и процессорное время для каждой функции.
Это позволяет эффективно обрабатывать большие ответы от модели. Инструменты для оптимизации вычислительных ресурсов помогут подобрать правильные параметры, что особенно важно для задач, требующих генерации большого объёма текста или выполнения сложных последовательных запросов.
Пример. Как быстро запустить LLM-приложение для автоматизации распознавания аудиофайлов и анализа содержания в serverless среде
1. Импорт необходимых библиотек и загрузка аудиофайла
На первом этапе импортируются необходимые библиотеки для работы с облачными сервисами и аудиофайлами. Загружается аудиофайл (например, запись разговора с клиентом), который будет использован для дальнейшей обработки.
2. Настройка клиентов для облачных сервисов
Клиент для облачного хранилища: настраивается клиент для взаимодействия с облачным хранилищем данных (например, Amazon S3, Google Cloud Storage или Azure Blob Storage), где будут храниться аудиофайлы.
Клиент для сервиса автоматической транскрипции: настраивается клиент для сервиса автоматической транскрипции (например, AWS Transcribe, Google Speech-to-Text или Azure Cognitive Services). Этот сервис преобразует аудиофайлы в текст.
3. Загрузка аудиофайла в облачное хранилище
Аудиофайл загружается в облачное хранилище данных. Это необходимо для последующей автоматической обработки файла другими сервисами. Этот шаг запускает процесс обработки.
4. Присвоение уникального имени задаче
Для каждой задачи транскрипции создаётся уникальное имя, чтобы идентифицировать транскрипцию конкретного аудиофайла.
5. Запуск процесса транскрипции
В следующем шаге инициируется задача транскрипции аудиофайла с помощью выбранного облачного сервиса. Процесс транскрипции преобразует аудио в текст и сохраняет результат в указанном формате (например, JSON).
6. Извлечение необходимых частей транскрипта
Как только аудиофайл будет транскрибирован, текстовый результат становится доступен для извлечения. Из транскрипта можно выбрать ключевые фрагменты, такие как реплики клиента или оператора, которые будут использованы для дальнейшего анализа.
7. Настройка большой языковой модели (LLM)
Настраивается взаимодействие с LLM, которая будет анализировать или обобщать полученный текст. Это может быть любая модель, доступная в облачных средах (например, GigaChat, Yandex GPT, Amazon Bedrock, OpenAI, Google Vertex AI и т.д.).
8. Создание промпта
Разрабатывается шаблон запроса (prompt) для подачи транскрибированного текста в LLM. Запрос может быть создан в зависимости от задач: это может быть обобщение разговора, анализ настроений или выделение ключевой информации.
9. Конфигурация ответа от модели
Настраиваются параметры для отправки запроса (prompt) в языковую модель. В ответ модель возвращает результат, например, обобщение текста или другие аналитические данные.
10. Генерация обобщения или анализа аудиозаписи
На последнем этапе полученный от модели результат обрабатывается и представляется в удобном формате. Это может быть сводка разговора, отчёт по ключевым моментам или анализ настроений. Данный результат может быть сохранён для дальнейшего использования или передан другим системам.
Процесс можно масштабировать, включая дополнительные этапы обработки, такие как использование моделей для анализа настроений, идентификации тем или ключевых фраз.
Заключение
Бессерверные технологии упрощают разработку LLM-приложений. Используя бессерверные решения, компании могут быстрее запускать LLM-приложения, адаптировать их к новым задачам и требованиям рынка, масштабировать и поддерживать, при этом снижая затраты и сложность управления.
Какой бы подход вы ни выбрали, будьте готовы к тому, что ландшафт развёртывания LLM будет постоянно меняться, и вам придётся адаптироваться к новым условиям.
Свяжитесь с нами, и мы расскажем, как быстро разработать и внедрить LLM-приложение с помощью Epsilon Workflow.