46.5kЗаказать демоВойтиНачать бесплатно

Использование Milvus и Friendli Serverless Endpoints для продвинутых RAG и мультимодальных запросов

Dec 18, 20246 min read

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

Milvus — это open-source векторная база данных, которая хранит, индексирует и выполняет поиск по неструктурированным данным миллиардного масштаба с помощью высокоразмерных векторных эмбеддингов. Она идеально подходит для создания современных ИИ-приложений, таких как retrieval augmented generation (RAG), семантический поиск, мультимодальный поиск и рекомендательные системы.

В этой статье мы рассмотрим, как использовать Milvus с Friendli Serverless Endpoints для выполнения Retrieval-Augmented Generation (RAG) на конкретных документах и материалах, а также для выполнения мультимодальных запросов, которые включают изображения и другой визуальный контент. Это мощное сочетание позволяет создавать более сложные и контекстно-осведомленные ИИ-приложения.

Понимание RAG и мультимодальных моделей

Retrieval-Augmented Generation (RAG)

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

Мультимодальные модели

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

Зачем объединять RAG и мультимодальные модели?

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

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

Практическая реализация

Давайте перейдем к практической реализации RAG и мультимодальных запросов с использованием векторной базы данных Milvus и Friendli Serverless Endpoints.

Шаг 1: Установка необходимых компонентов и загрузка документации Milvus

Сначала мы установим необходимые библиотеки и загрузим документацию Milvus, которую будем использовать для нашей задачи RAG:

!pip install --upgrade pymilvus requests tqdm langchain langchain-community langchain-huggingface langchain-openai friendli-client tiktoken

!wget https://github.com/milvus-io/milvus-docs/releases/download/v2.4.6-preview/milvus_docs_2.4.x_en.zip
!rm -rf milvus_docs
!unzip -q milvus_docs_2.4.x_en.zip -d milvus_docs

Шаг 2: Обработка файлов документации

Далее мы прочитаем файлы документации Milvus и используем простую стратегию разбиения файлов, чтобы рассматривать каждую строку текста как отдельный фрагмент:

from glob import glob

text_lines = []

for file_path in glob("milvus_docs/en/faq/*.md", recursive=True):
   with open(file_path, "r") as file:
       file_text = file.read()

   text_lines += file_text.split("# ")

Шаг 3: Подготовка эмбеддингов

Мы будем использовать библиотеку эмбеддингов Hugging Face, чтобы использовать простую модель all-MiniLM-L6 для создания векторных представлений нашего текста:

from langchain_huggingface import HuggingFaceEmbeddings

embeddings_model_name = "sentence-transformers/all-MiniLM-L6-v2"
embedding = HuggingFaceEmbeddings(model_name=embeddings_model_name)

test_embedding = embedding.embed_query("This is a test")
embedding_dim = len(test_embedding)
print(embedding_dim)
print(test_embedding[:10])

Шаг 4: Настройка клиента Milvus

Теперь подготовим клиент Milvus для нашей реализации RAG. В этом простом примере мы используем Milvus Lite, который запускается локально и материализует файл в локальном файле. Вы также можете рассмотреть другие варианты развертывания Milvus: Если вам нужна только локальная векторная база данных для данных небольшого масштаба или прототипирования, установка uri как локального файла, например ./milvus.db, является наиболее удобным методом, поскольку она автоматически использует Milvus Lite для хранения всех данных в этом файле. Для данных и трафика большего масштаба в production вы можете настроить сервер Milvus на Docker или Kubernetes. В этой настройке используйте адрес сервера и порт в качестве вашего uri, например http://localhost:19530. Если вы включаете функцию аутентификации в Milvus, установите token как "<your_username>:<your_password>", иначе устанавливать token не нужно. Вы также можете использовать полностью управляемый Milvus в Zilliz Cloud. Просто установите uri и token равными Public Endpoint и API key вашего экземпляра Zilliz Cloud.

from pymilvus import MilvusClient

milvus_client = MilvusClient(uri="./milvus_demo.db")

collection_name = "my_rag_collection"

Шаг 5: Создание коллекции Milvus

Мы создадим коллекцию в клиенте Milvus, если она еще не существует:

if milvus_client.has_collection(collection_name):
   milvus_client.drop_collection(collection_name)

milvus_client.create_collection(
   collection_name=collection_name,
   dimension=embedding_dim,
   metric_type="IP",  # Inner product distance
   consistency_level="Strong",  # Strong consistency level
)

Шаг 6: Встраивание и вставка текста в Milvus

Давайте создадим эмбеддинги для нашего текста и вставим его в коллекцию Milvus:

from tqdm import tqdm

data = []

for i, line in enumerate(tqdm(text_lines, desc="Creating embeddings")):
   data.append({"id": i, "vector": embedding.embed_query(line), "text": line})

milvus_client.insert(collection_name=collection_name, data=data)

Шаг 7: Выполнение RAG-запроса

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

question = "How is data stored in milvus?"

search_res = milvus_client.search(
   collection_name=collection_name,
   data=[
       embedding.embed_query(question)
   ],
   limit=3,  # Return top 3 results
   search_params={"metric_type": "IP", "params": {}},  # Inner product distance
   output_fields=["text"],  # Return the text field
)

import json

retrieved_lines_with_distances = [
   (res["entity"]["text"], res["distance"]) for res in search_res[0]
]
print(json.dumps(retrieved_lines_with_distances, indent=4))

context = "\n".join(
   [line_with_distance[0] for line_with_distance in retrieved_lines_with_distances]
)

Шаг 8: Создание промптов для RAG

Давайте создадим системный и пользовательский промпты для нашего RAG-запроса:

SYSTEM_PROMPT = """
Human: You are an AI assistant. You are able to find answers to the questions from the contextual passage snippets provided.
"""
USER_PROMPT = f"""
Use the following pieces of information enclosed in <context> tags to provide an answer to the question enclosed in <question> tags.
<context>
{context}
</context>
<question>
{question}
</question>
"""

Шаг 9: Настройте Friendli Token

Получите ваш FRIENDLI_TOKEN из Friendli Suite и задайте его как переменную окружения:

import os

if "FRIENDLI_TOKEN" not in os.environ:
   os.environ["FRIENDLI_TOKEN"] = 'flp_FILL_IN_WITH_YOUR_OWN_PERSONAL_ACCESS_TOKEN'

Шаг 10: Выполните RAG-запрос

Теперь мы можем выполнить наш RAG-запрос с помощью Friendli Serverless Endpoints:

from langchain_openai import ChatOpenAI

llm = ChatOpenAI(
   model="meta-llama-3.1-70b-instruct",
   base_url="https://api.friendli.ai/serverless/v1",
   api_key=os.environ["FRIENDLI_TOKEN"],
)

from langchain_core.prompts import ChatPromptTemplate
from langchain_core.output_parsers import StrOutputParser

prompt = ChatPromptTemplate.from_messages([
   ("system", SYSTEM_PROMPT),
   ("user", USER_PROMPT)
])
output_parser = StrOutputParser()

chain = prompt | llm | output_parser

print(chain.invoke({"input": question}))

Это генерирует ответ на основе предоставленных документов:

В Milvus данные хранятся в двух формах: вставленные данные и метаданные. 
Вставленные данные (векторные данные, скалярные данные и схема, специфичная для коллекции) хранятся в постоянном хранилище как инкрементальные журналы. Milvus поддерживает несколько бэкендов объектного хранилища, включая MinIO, AWS S3, Google Cloud Storage (GCS), Azure Blob Storage, Alibaba Cloud OSS и Tencent Cloud Object Storage (COS).
Метаданные, с другой стороны, генерируются внутри Milvus и хранятся в etcd, при этом каждый модуль Milvus имеет свои собственные метаданные.

Шаг 11: Мультимодальные запросы

Для мультимодальных запросов мы будем использовать модель Llama-3.2-11b-vision:

multimodalllm = ChatOpenAI(
   model="llama-3.2-11b-vision-instruct",
   base_url="https://api.friendli.ai/serverless/beta",
   api_key=os.environ["FRIENDLI_TOKEN"],
)

image_url = "https://milvus.io/docs/v2.4.x/assets/highly-decoupled-architecture.png"
message = HumanMessage(
   content=[
       {"type": "text", "text": "describe what is in this image"},
       {"type": "image_url", "image_url": {"url": image_url}},
   ],
)

response = multimodalllm.invoke([message])
print(response.content)

Из его ответа мы можем сделать вывод, что модель корректно понимает изображение:

На изображении показана блок-схема компонентов системы со следующими компонентами:
**Coordinator Service**
* Root
* Query
…

Шаг 12: Объедините возможности RAG и мультимодальности

Наконец, давайте объединим возможности RAG и мультимодальности:

question = "How is data stored in milvus with respect to this picture?"
USER_PROMPT = f"""
Use the following pieces of information enclosed in <context> tags to provide an answer to the question enclosed in <question> tags.
<context>
{context}
</context>
<question>
{question}
</question>
"""

message = HumanMessage(
   content=[
       {"type": "text", "text": USER_PROMPT},
       {"type": "image_url", "image_url": {"url": image_url}},
   ],
)

response = multimodalllm.invoke([message])
print(response.content)

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

**Шаг 1: Определите компоненты, участвующие в хранении данных в Milvus.**
Компоненты, участвующие в хранении данных в Milvus, включают:
*   Access Layer
*   Message Storage
*   Worker Node

**Шаг 2: Определите, как данные хранятся в Milvus.**
Данные хранятся в Access Layer и Message Storage.

**Шаг 3: Определите, где хранятся данные в Milvus.**
Данные хранятся как в Access Layer, так и в Message Storage.

**Ответ:** Данные хранятся как в Access Layer, так и в Message Storage.

Полный код и более подробную информацию смотрите в этом блокноте Colab.

Заключение

В этом руководстве было показано, как использовать Milvus и Friendli Serverless Endpoints для реализации продвинутых RAG и мультимодальных запросов. Объединив эти мощные технологии, вы можете создавать более сложные AI-приложения, которые способны понимать и обрабатывать различные типы информации, что приводит к более точным и контекстно-осведомленным ответам.

Обновлено Jul 09, 2026