Масштабирование поиска с Milvus: простая работа с огромными наборами данных
Меня часто спрашивают: «Зачем использовать векторную базу данных, такую как Milvus, если я могу просто использовать NumPy или FAISS?» Причин много: масштабируемость, простота управления, сохранность данных и одна из самых важных — масштаб. Когда вы работаете с миллионами или миллиардами векторов, вам нужно решение, созданное для обработки такого объема.
В этой статье блога мы посмотрим, как можно работать с примером сценария использования 40 миллионов векторов с Milvus. Мы также продемонстрируем, как такие функции, как фильтрация метаданных, могут значительно улучшить результаты поиска — важнейшая возможность, которой часто не хватает в не-специализированных векторных базах данных, что является серьезным недостатком.
Milvus: векторная база данных, созданная для масштаба
Milvus — популярная open-source векторная база данных, которая обеспечивает работу AI-приложений благодаря высокопроизводительному и масштабируемому поиску по векторному сходству.
Некоторые из ключевых функций, которые делают возможным векторный поиск в масштабе, включают:
- Распределенная архитектура: Milvus имеет распределенную архитектуру, которая позволяет ему бесшовно масштабироваться горизонтально и распределять данные и рабочую нагрузку между несколькими узлами. Эта возможность обеспечивает высокую доступность и отказоустойчивость даже при большой нагрузке.
- Оптимизированное индексирование: Milvus поддерживает различные методы индексирования, такие как IVF_FLAT и HNSW, а также GPU Index для ускорения поиска. Он также поддерживает DiskANN, если вам нужно снизить стоимость вашей Vector DB: поиск будет немного медленнее, но значительно дешевле.
- Поиск по миллиардам: Одна из выдающихся возможностей Milvus — его способность эффективно обрабатывать и выполнять поиск по миллиардам векторов. Эта возможность крайне важна для приложений, которым требуется высокоскоростной и высокообъемный поиск по векторному сходству.
- Различные варианты вычислений: Milvus может использовать мощность GPU и CPU, интеллектуально распределяя задачи на наиболее подходящее оборудование для оптимальной производительности. Эта возможность позволяет выполнять параллельную обработку и значительно повышать скорость, особенно для вычислительно интенсивных операций.
Набор данных: миллионы эмбеддингов статей Wikipedia
Мы используем набор данных из Wikipedia, который был преобразован с помощью Cohere Embedding Model; он находится в свободном доступе на Hugging Face.
Предварительный просмотр набора данных
Рисунок 1: Предварительный просмотр набора данных
Каждый пример содержит одну полную статью Wikipedia с очисткой для удаления markdown и нежелательных разделов (ссылки и т. д.).
Набор данных содержит более 300 языков, но для нашего сценария использования мы сосредоточимся на английском, который содержит 41,5 млн векторов. Самое интересное, что эмбеддинги являются кросс-языковыми! Это означает, что вы можете выполнять поиск по нескольким языкам и полагаться на способность модели находить схожие значения даже на разных языках.
Multilingual vs Cross-lingual.png
Рисунок 2: Многоязычный vs кросс-языковой (Источник изображения)
Начало работы с Milvus
В этом разделе мы покажем вам, как начать работу с Milvus, включая установку Milvus SDK или настройку Zilliz Cloud, подключение к Milvus, создание коллекций и т. д.
Установка Milvus SDK
Начните с установки Milvus SDK, выполнив pip install pymilvus. Для простоты мы развернем Milvus в Zilliz Cloud (полностью управляемой версии Milvus). В зависимости от масштаба данных, которые вы используете, вы можете либо развернуть Milvus в Kubernetes, либо использовать Zilliz Cloud.
- Если у вас больший масштаб данных, например более одного миллиона векторов, вы можете настроить более производительный сервер Milvus на Docker или Kubernetes. В этой конфигурации используйте uri сервера, например
http://localhost:19530, в качестве вашего uri. - Если вы хотите использовать Zilliz Cloud, полностью управляемый облачный сервис для Milvus, настройте
uriиtoken, которые соответствуют Public Endpoint и API key в Zilliz Cloud.
Пошаговое руководство
- Подключение к Milvus: Сначала установите соединение с вашим экземпляром Milvus:
from pymilvus import MilvusClient
client = MilvusClient(uri=<ZILLIZ_CLOUD_URI>, token=<ZILLIZ_TOKEN>)
- Создание схемы: Определите схему, которая будет использоваться для создания нашей коллекции Milvus.
# Define the schema for the collection
embedding_dim = 1024
schema = [
{"name": "id", "dtype": "int64", "is_primary": True, "auto_id": True},
{"name": "text_vector", "dtype": "float_vector", "dim": embedding_dim},
{"name": "title", "dtype": "varchar", "max_length": 5000},
{"name": "text", "dtype": "varchar", "max_length": 5000},
]
- Создание коллекции: Теперь мы создадим коллекцию, которую будем использовать для хранения эмбеддингов.
# Create the collection if it doesn't exist
collection_name = "cohere_embeddings"
if not client.has_collection(collection_name):
client.create_collection(collection_name=collection_name, schema=schema)
- Создание индекса: Чтобы сделать векторный поиск эффективным, нам нужно создать индекс для интересующего нас векторного поля. Векторный индекс — это специализированный тип индекса, предназначенный для хранения и поиска векторов.
# Define and create index
index_params = {
"metric_type": "COSINE",
"index_type": "HNSW",
"params": {"M": 8, "efConstruction": 64},
}
client.create_index(collection_name=collection_name, field_name="text_vector", index_params=index_params)
# Load the collection
client.load_collection(collection_name=collection_name)
- Вставка данных: Заполните коллекцию
cohere_embeddingsнабором данных из Hugging Face. В зависимости от доступных вам ресурсов вы можете захотеть скачать его подмножество, например только конкретный язык, загрузить его в бакет вроде S3 или GCP, либо также можете передавать его потоком из Hugging Face.
Когда набор данных находится в потоковом режиме, вы можете перебирать его напрямую без необходимости скачивать весь набор данных. Данные загружаются постепенно по мере итерации по набору данных; это полезно, если у вас недостаточно места на диске для скачивания набора данных или если вы не хотите ждать, пока набор данных будет скачан, прежде чем использовать его.
# Insert data into our collection
def insert_batch(client, collection_name, batch_data):
client.insert(collection_name=collection_name, data=batch_data)
batch_data.clear()
# Get the data from HuggingFace and create some batch
def insert_data(client, collection_name):
batch_size = 1000 # Adjust the batch size as needed
batch_data = []
docs = load_dataset(
"Cohere/wikipedia-2023-11-embed-multilingual-v3",
"en", # Только английский
split="train",
streaming=True, # Позволяет нам итерироваться по набору данных
)
for doc in tqdm(docs, desc="Потоковая передача и подготовка данных для Milvus"):
title = doc["title"][:4500] # Заголовки могут быть очень длинными
text = doc["text"][:4500] # Текст может быть очень длинным
emb = doc["emb"] # Вектор эмбеддинга
batch_data.append({"title": title, "text_vector": emb, "text": text})
if len(batch_data) >= batch_size:
insert_batch(client, collection_name, batch_data)
if batch_data:
insert_batch(client, collection_name, batch_data)
Скалярная фильтрация: мощный инструмент в масштабе
Когда вы имеете дело с миллионами или миллиардами векторов, фильтрация становится не просто приятным дополнением — она необходима. И именно здесь Milvus действительно демонстрирует свою силу.
Вот почему подход Milvus к фильтрации меняет правила игры:
- Магия битовых наборов: Milvus использует компактные битовые наборы, чтобы представлять, какие векторы соответствуют вашим критериям фильтрации. Эти битовые наборы можно обрабатывать быстрее, чем вы успеете сказать «поиск по векторному сходству», благодаря низкоуровневым операциям CPU. Это как иметь суперкомпьютер, который может мгновенно отсортировать миллиарды точек данных.
- Сокращение пространства поиска: В отличие от некоторых других решений (например, pgvector), которые предлагают только постфильтрацию, Milvus применяет фильтры метаданных до запуска поиска по векторному сходству. Это резко сокращает количество векторов, которые ему нужно обработать. Это также позволяет сузить ваш поиск с миллиардов векторов до всего лишь тысяч действительно важных — за миллисекунды.
- Скалярная индексация (когда она вам нужна): Для тех полей, по которым вы часто фильтруете, Milvus позволяет создавать скалярные индексы. Думайте об этом как о шпаргалке для Milvus по вашим данным. Хотя они не всегда присутствуют по умолчанию, при правильной настройке эти индексы могут значительно ускорить производительность фильтрации.
Преимущество Milvus в том, что он не просто предлагает эти функции — он заставляет их работать в масштабе. Независимо от того, имеете ли вы дело с 40 миллионами векторов или 40 миллиардами.
Поиск с точной фильтрацией
Найдите документы с определенным заголовком.
FILTER_TITLE = "British Arab Commercial Bank"
res = milvus_client.query(
collection_name=collection_name,
filter=f'title like "{FILTER_TITLE}"',
output_fields=["title", "text"]
)
for elt in res:
pprint(elt)
Это возвращает документы о British Arab Commercial Bank
{'id': 450933285225527270,
'text': 'The British Arab Commercial Bank PLC (BACB) is an international '
'wholesale bank incorporated in the United Kingdom that is authorised '
'by the Prudential Regulation Authority (PRA) and regulated by the '
'PRA and the Financial Conduct Authority (FCA). It was founded in '
'1972 as UBAF Limited, adopted its current name in 1996, and '
'registered as a public limited company in 2009. The bank has clients '
'trading in and out of developing markets in the Middle East and '
'Africa.',
'title': 'British Arab Commercial Bank'}
{'id': 450933285225527271,
'text': 'BACB has a head office in London, and three representative offices '
'in Algiers in Algeria, Tripoli in Libya and Abidjan in the Cote '
"D'Ivoire. The bank has 17 sister banks across Europe, Asia and "
'Africa. It is owned by three main shareholders - the Libyan Foreign '
'Bank (87.80%), Banque Centrale Populaire (6.10%) and Banque '
"Extérieure d'Algérie (6.10%).",
'title': 'British Arab Commercial Bank'}
Поиск с фильтрацией по префиксу/инфиксу/постфиксу
Ищите документы, содержащие определенное слово.
res = milvus_client.query(
collection_name=collection_name,
filter='text like "%Calectasia%"', # Инфикс
# filter='text like "Calect%"', # Суффикс
# filter='text like "%lectasia"', # Префикс
output_fields=["title", "text"],
limit=5,
)
for elt in res:
pprint(elt)
Это возвращает документы, содержащие слово "Calectasia."
{'id': 450933285225527360,
'text': 'Calectasia is a genus of about fifteen species of flowering plants '
'in the family Dasypogonaceae and is endemic to south-western '
'Australia. Plants is this genus are small, erect shrubs with '
'branched stems covered by leaf sheaths. The flowers are star-shaped, '
'lilac-blue to purple and arranged singly on the ends of short '
'branchlets.',
'title': 'Calectasia'}
{'id': 450933285225527361,
'text': 'Plants in the genus Calectasia are small, often rhizome-forming '
'shrubs with erect, branched stems with sessile leaves arranged '
'alternately along the stems, long and about wide, the base held '
'closely against the stem and the tip pointed. The flowers are '
'arranged singly on the ends of branchlets and are bisexual, the '
'three sepals and three petals are similar to each other, and joined '
'at the base forming a short tube but spreading, forming a star-like '
'pattern with a metallic sheen. Six bright yellow or orange stamens '
'form a tube in the centre of the flower with a thin style extending '
'beyond the centre of the tube.',
'title': 'Calectasia'}
Поиск с фильтрацией с "Not In"
Исключите определенные заголовки из вашего поиска.
res = milvus_client.query(
collection_name=collection_name,
filter='title not in ["British Arab Commercial Bank", "Calectasia"]',
output_fields=["title", "text"],
limit=10,
)
for elt in res:
pprint(elt)
Это возвращает документы, заголовки которых не являются "British Arab Commercial Bank" или "Calectasia."
{'id': 450933285225527281,
'text': 'The Commonwealth Skyranger, first produced as the Rearwin Skyranger, '
'was the last design of Rearwin Aircraft before the company was '
'purchased by a new owner and renamed Commonwealth Aircraft. It was '
'a side-by-side, two-seat, high-wing taildragger.',
'title': 'Commonwealth Skyranger'}
{'id': 450933285225527282,
'text': 'The Rearwin company had specialized in aircraft powered by small '
'radial engines, such as their Sportster and Cloudster, and had even '
'purchased the assets of LeBlond Engines to make small radial engines '
'in-house in 1937. By 1940, however, it was clear Rearwin would need '
'a design powered by a small horizontally opposed engine to remain '
'competitive. Intended for sport pilots and flying businessmen, the '
'"Rearwin Model 165" first flew on April 9, 1940. Originally named '
'the "Ranger," Ranger Engines (who also sold several engines named '
'"Ranger") protested, and Rearwin renamed the design "Skyranger." The '
'overall design and construction methods allowed Rearwin to take '
'orders for Skyrangers then deliver the aircraft within 10 weeks.',
'title': 'Commonwealth Skyranger'}
Cohere 🤝 Milvus: мощная комбинация, делающая поиск по векторному сходству проще и эффективнее
Давайте выполним поиск по сходству с использованием эмбеддингов Cohere. Мы встроим запрос Who founded Wikipedia и используем его для поиска в нашей коллекции Milvus. Это та же модель эмбеддингов, которая использовалась для кодирования Wikipedia Embeddings.
Мы будем использовать интеграцию между Milvus и Cohere через PyMilvus Model, установите ее с помощью pip install "pymilvus[model]" .
from pymilvus.model.dense import CohereEmbeddingFunction
cohere_ef = CohereEmbeddingFunction(
model_name="embed-multilingual-v3.0",
input_type="search_query",
embedding_types=["float"]
)
query = 'Who founded Wikipedia'
embedded_query = cohere_ef.encode_queries([query])
response = embedded_query[0]
print(response[:10])
Это возвращает наиболее релевантные статьи Wikipedia об основателях Wikipedia.
res = milvus_client.search(data=response, collection_name=collection_name, output_fields=["text"], limit=3)
for elt in res:
pprint(elt)
Что приводит к следующему:
[{'distance': 0.7344469428062439,
'entity': {'text': 'Larry Sanger and Jimmy Wales are the ones who started '
'Wikipedia. Wales is credited with defining the goals of '
'the project. Sanger created the strategy of using a wiki '
"to reach Wales' goal. On January 10, 2001, Larry Sanger "
'proposed on the Nupedia mailing list to create a wiki as '
'a "feeder" project for Nupedia. Wikipedia was launched '
'on January 15, 2001. It was launched as an '
'English-language edition at www.wikipedia.com, and '
'announced by Sanger on the Nupedia mailing list. '
'Wikipedia\'s policy of "neutral point-of-view" was '
'enforced in its initial months and was similar to '
'Nupedia\'s earlier "nonbiased" policy. Otherwise, there '
"weren't very many rules initially, and Wikipedia "
'operated independently of Nupedia.'},
'id': 450933285241797095},
{'distance': 0.7239157557487488,
'entity': {'text': 'Wikipedia was originally conceived as a complement to '
'Nupedia, a free on-line encyclopedia founded by Jimmy '
'Wales, with articles written by highly qualified '
'contributors and evaluated by an elaborate peer review '
'process. The writing of content for Nupedia proved to be '
'extremely slow, with only 12 articles completed during '
'the first year, despite a mailing-list of interested '
'editors and the presence of a full-time editor-in-chief '
'recruited by Wales, Larry Sanger. Learning of the wiki '
'concept, Wales and Sanger decided to try creating a '
'collaborative website to provide an additional source of '
'rapidly produced draft articles that could be polished '
'for use on Nupedia.'},
'id': 450933285225827849},
{'distance': 0.7191773653030396,
'entity': {'text': "The foundation's creation was officially announced by "
'Wikipedia co-founder Jimmy Wales, who was running '
'Wikipedia within his company Bomis, on June 20, 2003.'},
'id': 450933285242058780}]
Давайте проверим метрики производительности нашего кластера, сосредоточившись на задержке наших поисковых запросов. Мы будем использовать Zilliz Cloud API для получения значений как средней задержки, так и 99-го процентиля (P99).
Сначала мы проверим среднюю задержку:
> curl --request POST \
--url https://api.cloud.zilliz.com/v2/clusters/<cluster_id>/metrics/query \
[...]
"metricQueries": [
{
"name": "REQ_SEARCH_LATENCY",
"stat": "AVG"
}
}'
[{"name":"REQ_SEARCH_LATENCY","stat":"AVG","unit":"millisecond","values":[{"timestamp":"2024-08-26T11:09:53Z","value":"2.0541596873255163"}]}]
Этот запрос возвращает среднюю задержку 2,05 миллисекунды.
Далее давайте проверим задержку P99:
> curl --request POST \
--url https://api.cloud.zilliz.com/v2/clusters/<cluster_id>/metrics/query \
[...]
"metricQueries": [
{
"name": "REQ_SEARCH_LATENCY",
"stat": "P99"
}
}'
[{"name":"REQ_SEARCH_LATENCY","stat":"P99","unit":"millisecond","values":[{"timestamp":"2024-08-26T11:09:53Z","value":"4.949999999999999"}]}]
Задержка P99 указана как 4,95 миллисекунды.
Эти результаты демонстрируют впечатляющую производительность: наша средняя задержка запроса составляет чуть более 2 миллисекунд, при этом 99% запросов завершаются менее чем за 5 миллисекунд. Это показывает эффективность нашего кластера Milvus при обработке поисковых операций даже в масштабе.
Создание базовой RAG-системы с Milvus
Retrieval Augmented Generation (RAG) — это продвинутая ИИ-техника для снижения галлюцинаций в больших языковых моделях (LLMs), таких как ChatGPT.
В этом примере мы можем использовать результаты из Milvus для создания простой RAG-системы. Это позволяет LLM получать доступ к информации, хранящейся в Milvus, и использовать ее.
context = "\n".join(
[line_with_distance[0] for line_with_distance in retrieved_lines_with_distances]
)
question = "Who created Wikipedia?"
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>
"""
from openai import OpenAI
client = OpenAI(
base_url = 'http://localhost:11434/v1',
api_key='ollama', # required, but unused
)
response = client.chat.completions.create(
model="llama3.1",
messages=[
{"role": "system", "content": SYSTEM_PROMPT},
{"role": "user", "content": USER_PROMPT},
],
)
print(response.choices[0].message.content)
Согласно предоставленному контексту, Ларри Сэнгер и Джимми Уэйлс являются теми, кто запустил Wikipedia. В частности, Джимми Уэйлс определил цели проекта, а Ларри Сэнгер разработал стратегию использования wiki для достижения этих целей.
За пределами основ: расширенные возможности Milvus для повышенной масштабируемости
Milvus предлагает еще более продвинутые возможности для работы с массивными наборами данных:
- Секционирование данных: Например, для коллекций, содержащих данные от нескольких пользователей или арендаторов, Milvus предлагает ключи и имена секций для логического разделения данных. Эта функция обеспечивает эффективную фильтрацию по метаданным, например по ID пользователя или названию организации.
- Поиск по диапазону: Эффективно находит векторы в пределах указанного диапазона расстояний от вектора запроса, обеспечивая более точный и гибкий поиск сходства в пространствах высокой размерности.
- Гибридный поиск: Позволяет пользователям выполнять поиск по нескольким векторным столбцам в одном запросе. Например, можно объединить текстовый вектор и вектор изображения для мультимодальных данных или плотный вектор и разреженный вектор, чтобы использовать семантический поиск и полнотекстовый поиск. Эта функция предоставляет универсальную и гибкую функциональность поиска.
Подробнее см. документацию Milvus.
Заключение
Milvus предоставляет надежное и масштабируемое решение для работы с миллиардами векторов. Его мощные функции, такие как фильтрация и распределенная архитектура, делают его идеальным выбором для требовательных ИИ-приложений.
Наши тесты производительности продемонстрировали впечатляющие возможности Milvus:
- Средняя задержка запроса: 2,05 миллисекунды
- Задержка 99-го процентиля (P99): 4,95 миллисекунды
Эти результаты демонстрируют, что Milvus может стабильно обеспечивать время поиска менее 5 мс, даже при работе с миллионами векторов. Поэтому, если вы хотите создавать приложения, способные обрабатывать огромные наборы данных и выдавать молниеносные результаты поиска, Milvus определенно стоит изучить.
Если вам понравилась эта статья в блоге, пожалуйста, подумайте о том, чтобы поставить нам звезду на GitHub. Вы также можете поделиться своим опытом с сообществом Milvus, присоединившись к нашему Discord.
Дополнительные ресурсы
- Что такое Retrieval Augmented Generation (RAG)?
- Создание RAG с Milvus, vLLM и Meta’s Llama 3.1
- Центр ресурсов по генеративному ИИ | Zilliz
- Лучшие AI-модели для ваших GenAI-приложений | Zilliz
- Выбор подходящей embedding-модели для ваших данных
- Ландшафт экосистемы GenAI: за пределами LLM и векторных баз данных
Читать далее

Zilliz Cloud Just Landed in Claude Code
The Zilliz Cloud Plugin brings the full power of Zilliz Cloud directly into your Claude Code terminal as natural-language conversations.

Why Context Engineering Is Becoming the Full Stack of AI Agents
Discover how context engineering unifies prompts, RAG, and tools to build smarter, production-ready AI agents powered by Milvus.

AI Agents Are Quietly Transforming E-Commerce — Here’s How
Discover how AI agents transform e-commerce with autonomous decision-making, enhanced product discovery, and vector search capabilities for today's retailers.



