Skip to content

Latest commit

 

History

History
274 lines (165 loc) · 24.7 KB

File metadata and controls

274 lines (165 loc) · 24.7 KB

Генерация с дополнением извлечения (RAG) и векторные базы данных

Генерация с дополнением извлечения (RAG) и векторные базы данных

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

Видео скоро будет

Введение

В этом уроке мы рассмотрим следующее:

  • Введение в RAG, что это такое и почему это используется в ИИ (искусственном интеллекте).

  • Понимание того, что такое векторные базы данных, и создание одной для нашего приложения.

  • Практический пример интеграции RAG в приложение.

Цели обучения

После завершения этого урока вы сможете:

  • Объяснить значение RAG в получении и обработке данных.

  • Настроить приложение RAG и привязать свои данные к LLM.

  • Эффективно интегрировать RAG и векторные базы данных в приложения LLM.

Наш сценарий: улучшение наших LLM с помощью собственных данных

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

  • Azure OpenAI: LLM, который мы используем для создания нашего чат-бота

  • Урок "ИИ для начинающих" по нейронным сетям: это данные, на которых мы будем основывать наш LLM

  • Azure AI Search и Azure Cosmos DB: векторная база данных для хранения наших данных и создания поискового индекса

Пользователи смогут создавать практические викторины на основе своих заметок, карточки для повторения и конспекты. Для начала давайте посмотрим, что такое RAG и как он работает:

Генерация с дополнением извлечения (RAG)

Чат-бот на основе LLM обрабатывает запросы пользователей для генерации ответов. Он предназначен для интерактивного взаимодействия и общения с пользователями на широкий круг тем. Тем не менее, его ответы ограничены предоставленным контекстом и исходными обучающими данными. Например, GPT-4 имеет ограничение знаний до сентября 2021 года, что означает отсутствие информации о событиях после этой даты. Кроме того, данные, использованные для обучения LLM, не включают конфиденциальную информацию, такую как личные заметки или руководство по продукту компании.

Как работают RAG (Генерация с дополнением извлечения)

рисунок, показывающий, как работают RAG

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

  • База знаний: Перед извлечением документы необходимо загрузить и предварительно обработать, обычно разбивая большие документы на меньшие части, преобразуя их в текстовые встраивания и сохраняя в базе данных.

  • Запрос пользователя: пользователь задаёт вопрос.

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

  • Генерация с дополнением: LLM улучшает свой ответ на основе извлечённых данных. Это позволяет ответу основываться не только на предварительно обученных данных, но и на релевантной информации из добавленного контекста. Извлечённые данные используются для дополнения ответов LLM. Затем LLM возвращает ответ на вопрос пользователя.

рисунок, показывающий архитектуру RAG

Архитектура RAG реализована с использованием трансформеров, состоящих из двух частей: энкодера и декодера. Например, когда пользователь задаёт вопрос, входной текст «кодируется» в векторы, отражающие смысл слов, а векторы «декодируются» в наш индекс документов и генерируют новый текст на основе запроса пользователя. LLM использует модель энкодер-декодер для генерации результата.

Согласно предлагаемой статье Retrieval-Augmented Generation for Knowledge Intensive NLP Tasks существуют два подхода к реализации RAG:

  • RAG-Sequence — использует извлечённые документы для предсказания лучшего возможного ответа на запрос пользователя.

  • RAG-Token — использует документы для генерации следующего токена, затем извлекает их для ответа на запрос пользователя.

Зачем использовать RAG?

  • Богатство информации: обеспечивает актуальность и современность текстовых ответов. Таким образом, повышает эффективность выполнения задач в конкретной области за счёт доступа к внутренней базе знаний.

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

  • Является экономичным, поскольку дешевле, чем дообучение LLM.

Создание базы знаний

Наше приложение основано на наших личных данных, а именно на уроке по нейронным сетям из курса «ИИ для начинающих».

Векторные базы данных

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

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

Популярные векторные базы данных включают Azure Cosmos DB, Clarifyai, Pinecone, Chromadb, ScaNN, Qdrant и DeepLake. Вы можете создать модель Azure Cosmos DB с помощью Azure CLI следующей командой:

az login
az group create -n <resource-group-name> -l <location>
az cosmosdb create -n <cosmos-db-name> -r <resource-group-name>
az cosmosdb list-keys -n <cosmos-db-name> -g <resource-group-name>

От текста к встраиваниям

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

def split_text(text, max_length, min_length):
    words = text.split()
    chunks = []
    current_chunk = []

    for word in words:
        current_chunk.append(word)
        if len(' '.join(current_chunk)) < max_length and len(' '.join(current_chunk)) > min_length:
            chunks.append(' '.join(current_chunk))
            current_chunk = []

    # Если последний фрагмент не достиг минимальной длины, добавьте его всё равно
    if current_chunk:
        chunks.append(' '.join(current_chunk))

    return chunks

После разбиения мы можем встроить текст с помощью различных моделей встраивания. Некоторые из моделей, которые можно использовать: word2vec, ada-002 от OpenAI, Azure Computer Vision и многие другие. Выбор модели зависит от используемых языков, типа кодируемого контента (текст/изображения/аудио), размера входных данных, а также длины выходных встраиваний.

Пример текстового встраивания с использованием модели OpenAI text-embedding-ada-002: встраивание слова «кот»

Извлечение и векторный поиск

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

Извлечение

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

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

  • Поиск по ключевым словам — используется для текстовых запросов.

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

  • Гибридный — сочетание поиска по ключевым словам и векторного поиска.

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

Мы будем хранить данные в датафрейме с колонками, содержащими части текста и встраивания.

Векторное сходство

Система извлечения будет искать в базе знаний встраивания, максимально близкие друг к другу, — ближайших соседей, поскольку они отражают похожие тексты. Когда пользователь задаёт запрос, он сначала встраивается, а затем сопоставляется с похожими встраиваниями. Популярная метрика сходства — косинусное сходство, основанное на угле между двумя векторами.

Для измерения сходства можно также использовать Евклидово расстояние — прямое расстояние между концами векторов, или скалярное произведение, которое измеряет сумму произведений соответствующих элементов векторов.

Поисковый индекс

Перед выполнением поиска необходимо создать поисковый индекс для базы знаний. Индекс хранит наши встраивания и может быстро возвращать наиболее похожие части даже в большой базе данных. Индекс можно создать локально с помощью:

from sklearn.neighbors import NearestNeighbors

embeddings = flattened_df['embeddings'].to_list()

# Создать индекс поиска
nbrs = NearestNeighbors(n_neighbors=5, algorithm='ball_tree').fit(embeddings)

# Для запроса к индексу можно использовать метод kneighbors
distances, indices = nbrs.kneighbors(embeddings)

Повторная сортировка результатов

После запроса в базу может потребоваться сортировка результатов по релевантности. Повторная сортировка с помощью LLM использует машинное обучение для улучшения релевантности результатов поиска, упорядочивая их от наиболее релевантных. В Azure AI Search повторная сортировка выполняется автоматически с помощью семантического ранжировщика. Пример работы повторной сортировки с использованием ближайших соседей:

# Найти наиболее похожие документы
distances, indices = nbrs.kneighbors([query_vector])

index = []
# Вывести наиболее похожие документы
for i in range(3):
    index = indices[0][i]
    for index in indices[0]:
        print(flattened_df['chunks'].iloc[index])
        print(flattened_df['path'].iloc[index])
        print(flattened_df['distances'].iloc[index])
    else:
        print(f"Index {index} not found in DataFrame")

Объединяем всё вместе

Последним шагом является добавление нашего LLM в систему, чтобы получать ответы, основанные на наших данных. Мы можем реализовать это следующим образом:

user_input = "what is a perceptron?"

def chatbot(user_input):
    # Преобразовать вопрос в вектор запроса
    query_vector = create_embeddings(user_input)

    # Найти наиболее похожие документы
    distances, indices = nbrs.kneighbors([query_vector])

    # добавить документы к запросу для предоставления контекста
    history = []
    for index in indices[0]:
        history.append(flattened_df['chunks'].iloc[index])

    # объединить историю и ввод пользователя
    history.append(user_input)

    # создать объект сообщения
    messages=[
        {"role": "system", "content": "You are an AI assistant that helps with AI questions."},
        {"role": "user", "content": "\n\n".join(history) }
    ]

    # использовать чат-завершение для генерации ответа
    response = openai.chat.completions.create(
        model="gpt-4",
        temperature=0.7,
        max_tokens=800,
        messages=messages
    )

    return response.choices[0].message

chatbot(user_input)

Оценка нашего приложения

Метрики оценки

  • Качество ответов — обеспечивать естественность, беглость и человекоподобность звучания.

  • Привязанность данных — оценка того, действительно ли ответ основан на предоставленных документах.

  • Релевантность — оценка соответствия и отношения ответа к заданному вопросу.

  • Беглость — проверка грамматической осмысленности ответа.

Случаи использования RAG и векторных баз данных

Существует множество сценариев, где вызовы функций могут улучшить ваше приложение, например:

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

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

  • Чат-боты: хранение истории чатов и персонализация общения на основе данных пользователя.

  • Поиск изображений на основе векторных встраиваний, полезен при распознавании изображений и обнаружении аномалий.

Итоги

Мы рассмотрели основные области RAG: добавление данных в приложение, запросы пользователей и вывод. Для упрощения создания RAG можно использовать такие фреймворки, как Semantic Kernel, Langchain или Autogen.

Задание

Для продолжения изучения генерации с дополнением извлечения (RAG) вы можете:

  • Создать фронтенд для приложения на выбранном вами фреймворке.

  • Использовать фреймворк, например LangChain или Semantic Kernel, и пересоздать ваше приложение.

Поздравляем с завершением урока 👏.

Обучение не заканчивается здесь — продолжайте путь

После завершения этого урока ознакомьтесь с нашей коллекцией по генеративному ИИ (Generative AI Learning collection), чтобы продолжить развивать свои знания в области генеративного ИИ!


Отказ от ответственности:
Этот документ был переведен с помощью автоматического сервиса перевода Co-op Translator. Несмотря на наши усилия обеспечивать точность, имейте в виду, что машинный перевод может содержать ошибки или неточности. Оригинальный документ на его исходном языке следует считать авторитетным источником. Для критически важной информации рекомендуется обратиться к профессиональному человеческому переводу. Мы не несем ответственности за любые недоразумения или неправильные толкования, возникшие в результате использования этого перевода.