Использование Milvus и Friendli Serverless Endpoints для продвинутых RAG и мультимодальных запросов
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-приложения, которые способны понимать и обрабатывать различные типы информации, что приводит к более точным и контекстно-осведомленным ответам.
Читать далее

Announcing VDBBench 1.0: Open-Source VectorDB Benchmarking with Your Real-World Production Workloads
Discover VDBBench 1.0, an open-source tool for benchmarking vector databases with real-world production data, streaming ingestion, and concurrent workloads.

Vector Databases vs. Time Series Databases
Use a vector database for similarity search and semantic relationships; use a time series database for tracking value changes over time.

DeepSeek-VL2: Mixture-of-Experts Vision-Language Models for Advanced Multimodal Understanding
Explore DeepSeek-VL2, the open-source MoE vision-language model. Discover its architecture, efficient training pipeline, and top-tier performance.



