От нуля до героя LLMOps: 101 руководство по внедрению LLM в производство

Автор: Дмитрий Иванов [Команда P9X]

~8 минут чтения

Если вы когда-нибудь пытались перенести прототип LLM из Jupyter Notebook в реальный мир

Если вы когда-нибудь пытались перенести прототип LLM из Jupyter Notebook в реальный мир, то уже знаете, что это не так просто, как нажать кнопку «Выполнить». Я помню, как в первый раз попробовал разместить конечную точку LLM; это было непросто. Модель нормально работала локально, но как только пользователи начали отправлять несколько запросов… всё сломалось.

Тогда я понял, что мне не хватает не знаний в области машинного обучения, а LLMOps.

Что такое LLMOps?

LLMOps — это расширение MLOps для больших языковых моделей. Это всё, что происходит после того, как вы обучили или выбрали свою модель: от оптимизации вывода, мониторинга, оркестрации запросов, конвейеров данных до развёртывания, масштабирования и управления.

Представьте себе мост между вашей моделью и реальным миром, обеспечивающий надёжность, масштабируемость, наблюдаемость и соответствие требованиям.

Основные этапы LLMOps

  1. Приём данных и векторизация.
  2. Понимание набора данных.
  3. Создание векторного хранилища.
  4. Создание и запуск чат-бота RAG.
  5. Оркестровка запросов с помощью LangChain.
  6. Обслуживание через FastAPI.
  7. Интерфейс чата со Streamlit.
  8. Публичный доступ через Ngrok.
  9. Контейнеризация с помощью Docker.
  10. Концепции развёртывания с AWS.
  11. Мониторинг, версионирование, оценка и управление.

Базовая настройка

Прежде чем мы начнём с реализации, давайте сделаем базовую настройку, установив необходимые библиотеки. Я использую Google Colab в качестве среды программирования для этого проекта. Скопируйте следующий код для настройки библиотек:

!mkdir llmops-demo
!cd llmops-demo
!python3 -m venv venv
!source venv/bin/activate
!pip install langchain openai faiss-cpu fastapi uvicorn python-dotenv langchain-community
!pip install nest_asyncio pyngrok streamlit

Мы также будем использовать OpenAI и NGROK для этого проекта. Вы можете получить их токены/ключи API по следующим ссылкам:

Обратите внимание, что бесплатной версии их API/токенов аутентификации достаточно для этого блога.

Напишите следующий код в Colab, чтобы настроить эти токены:

import os
from getpass import getpass
os.environ['OPENAI_API_KEY'] = getpass("Enter OPENAI KEY:")
os.environ['NGROK_AUTHTOKEN'] = getpass("ENTER NGROK TOKEN:")

Ввод данных и векторизация

Понимание набора данных

Прежде чем что-то создавать, давайте начнём с данных, потому что именно они дают вашей системе RAG «мозг». Я использовал небольшой набор данных Kaggle под названием Sample RAG Knowledge Item Dataset. Он простой, чистый и идеально подходит для обучения. Каждая строка похожа на мини-«записку» из службы поддержки IT, короткий фрагмент знаний по определённой теме.

Вы найдёте два основных столбца:

  • ki_text → фактический контент (например, «Шаги по устранению неполадок вашего VPN-соединения»);
  • ki_topic → метка темы, такая как «Сети», «Оборудование» или «Безопасность».

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

Теперь, когда мы знаем, как выглядит наш набор данных, давайте научим нашу модель «запоминать» его, превратив этот текст в встраивания и сохранив их в векторной базе данных.

Создание векторного хранилища

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

Вот код для этого:

import os
import pandas as pd

from langchain.text_splitter import RecursiveCharacterTextSplitter
from langchain.embeddings import OpenAIEmbeddings
from langchain.vectorstores import FAISS
from langchain.docstore.document import Document

# Load dataset
df = pd.read_csv("/content/rag_sample_qas_from_kis.csv")

# Use ki_text as main text and ki_topic as metadata
docs = [
    Document(page_content=row["ki_text"], metadata={"topic": row["ki_topic"]})
    for _, row in df.iterrows()
]

# Split into chunks for embedding
splitter = RecursiveCharacterTextSplitter(chunk_size=800, chunk_overlap=100)
chunks = splitter.split_documents(docs)

# Embed and store in FAISS
embeddings = OpenAIEmbeddings(openai_api_key=os.getenv("OPENAI_API_KEY"))
db = FAISS.from_documents(chunks, embeddings)

db.save_local("vectorstore")
print("Vectorstore created successfully using ki_text as content!")

Создание и запуск чат-бота RAG

Вот как выглядит наш окончательный чат-бот при развёртывании:

Теперь давайте рассмотрим все библиотеки/инструменты, которые нам нужны, чтобы это произошло, и посмотрим, как всё это складывается воедино.

Оркестрация запросов с помощью LangChain

Здесь мы собираем воедино наш векторный магазин, ретривер и LLM с помощью цепочки RetrievalQA от LangChain.

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

Каждый запрос теперь проходит через этот конвейер: извлечённый → дополненный → сгенерированный.

Обслуживание через FastAPI

Чтобы имитировать настройку, готовую к производству, мы добавляем облегчённый бэкенд FastAPI. Хотя это необязательно для Colab, этот шаг отражает, как ваша модель RAG будет представлена в реальной среде с конечными точками, готовыми для внешних интеграций или API-запросов.

Маршрут «/» на данный момент просто возвращает сообщение о состоянии здоровья, но эту структуру можно легко расширить для обработки запросов из вашего пользовательского интерфейса, ботов Slack или веб-клиентов.

Интерфейс чата со Streamlit

На базе бэкенда мы создаём интерактивный интерфейс чата с помощью Streamlit. Это обеспечивает чистый интерфейс на основе браузера для общения с вашим конвейером RAG. Пользователи могут вводить вопросы, нажимать «Отправить» и получать контекстуальные ответы, основанные на документах, с помощью LangChain.

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

Публичный доступ через Ngrok

Поскольку Colab не поддерживает прямой веб-хостинг, мы используем ngrok, чтобы безопасно выставить приложение Streamlit. Ngrok направляет ваш локальный порт на временный общедоступный URL, позволяя любому (или только вам) получить доступ к чат-боту UI в реальной вкладке браузера.

Как только ngrok выводит общедоступную ссылку, чат-бот становится мгновенно доступным.

Объединение всего вместе

  • LangChain управляет встраиваниями, извлечением и генерацией;
  • FastAPI предоставляет необязательный бэкенд;
  • Streamlit служит интерактивным пользовательским интерфейсом;
  • Ngrok соединяет Colab с внешним миром.

И с этим у вас есть полностью функциональный, сквозной чат-бот на базе RAG, работающий в прямом эфире из вашего ноутбука.

Контейнеризация с помощью Docker

На этом этапе у нас есть полностью работающий чат-бот RAG: бэкенд, пользовательский интерфейс и всё такое. Но если вы когда-нибудь пытались развернуть такую ​​настройку в разных средах, вы знаете, какая это боль: недостающие зависимости, несовпадение версий, сломанные пути — обычный хаос.

Именно здесь на помощь приходит Docker. Docker предоставляет аккуратный, портативный способ упаковать всю среду со всеми инструментами, такими как FastAPI, Streamlit, LangChain, FAISS и даже вашим векторным хранилищем, в одну согласованную единицу, которая может работать где угодно.

Развёртывание концепций с AWS

Развёртывание вашей системы LLM на AWS открывает возможности для масштабирования в производственных условиях, но это тема, заслуживающая отдельного глубокого погружения. От размещения вашего приложения FastAPI на EC2 или ECS до хранения векторных баз данных на S3 и использования AWS Lambda для событийных триггеров — возможности безграничны. Вы даже можете интегрировать CloudFront + API Gateway для защищённых, глобально распределённых конечных точек вывода.

Пока просто знайте, что AWS предоставляет вам все строительные блоки для перехода от локального контейнера Docker к полностью управляемой, автоматически масштабируемой настройке. Мы рассмотрим весь этот рабочий процесс с помощью инфраструктуры как кода, конвейеров CI/CD и сценариев развёртывания в следующей статье.

Мониторинг, версионирование, оценка и управление

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

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

Заключение

Мы начали с нуля, настроив простой пользовательский интерфейс чат-бота, и шаг за шагом построили полный рабочий процесс LLMOps:

  • Ввод данных, создание векторного хранилища, встраивание, оркестрация запросов, обслуживание через FastAPI, контейнеризация с помощью Docker и подготовка к развёртыванию на AWS.
  • Каждый слой добавил структуру, масштабируемость и надёжность, превратив эксперимент в развёртываемый, обслуживаемый продукт.
  • Но это только начало. Настоящий LLMOps начинается после развёртывания, когда вы отслеживаете поведение, оптимизируете извлечение, версионируете вложения и держите свои модели в безопасности и соответствии требованиям.

В следующей части этой серии мы выйдем за рамки настройки и погрузимся в развёртывание в AWS, наблюдаемость, версионирование и управление — то, что действительно делает ваши LLM готовыми к работе в производственной среде.

Дайте мне знать о ваших мыслях и вопросах ниже!

Санад — старший учёный в области искусственного интеллекта в Analytics Vidhya, превращающий передовые исследования в области искусственного интеллекта в реальные продукты агентского искусственного интеллекта. Имея степень магистра в области искусственного интеллекта в Эдинбургском университете, он работал в ведущих исследовательских лабораториях, занимаясь многоязычным НЛП и НЛП для индийских языков с ограниченными ресурсами. Увлечённый всем, что связано с искусственным интеллектом, он любит устранять разрыв между глубокими исследованиями и практическими, значимыми продуктами.