🚀 Попробуйте Zilliz Cloud, полностью управляемый Milvus, бесплатно — ощутите 10-кратное увеличение производительности! Попробовать сейчас>

milvus-logo
LFAI
Главная
  • Начать
  • Home
  • Docs
  • Начать

  • Быстрый старт

Быстрый старт с Milvus Lite

Open In Colab GitHub Repository

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

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

Установка Milvus

В этом руководстве мы используем Milvus Lite, библиотеку python, включенную в pymilvus, которая может быть встроена в клиентское приложение. Milvus также поддерживает развертывание в Docker и Kubernetes для использования в производстве.

Перед началом работы убедитесь, что в локальном окружении доступен Python 3.8+. Установите pymilvus, который содержит клиентскую библиотеку python и Milvus Lite:

$ pip install -U pymilvus

Если вы используете Google Colab, для включения только что установленных зависимостей вам может потребоваться перезапустить среду выполнения. (Нажмите на меню "Время выполнения" в верхней части экрана и выберите "Перезапустить сессию" из выпадающего меню).

Настройка базы данных векторов

Чтобы создать локальную векторную базу данных Milvus, просто создайте MilvusClient, указав имя файла для хранения всех данных, например "milvus_demo.db".

from pymilvus import MilvusClient

client = MilvusClient("milvus_demo.db")

Создание коллекции

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

if client.has_collection(collection_name="demo_collection"):
    client.drop_collection(collection_name="demo_collection")
client.create_collection(
    collection_name="demo_collection",
    dimension=768,  # The vectors we will use in this demo has 768 dimensions
)

В приведенной выше схеме,

  • Первичный ключ и векторные поля имеют имена по умолчанию ("id" и "vector").
  • Тип метрики (определение векторного расстояния) установлен в значение по умолчанию(COSINE).
  • Поле первичного ключа принимает целые числа и не увеличивается автоматически (то есть не используется функция auto-id). Также можно формально определить схему коллекции, следуя этой инструкции.

Подготовка данных

В этом руководстве мы используем векторы для выполнения семантического поиска по тексту. Нам необходимо сгенерировать векторы для текста, загрузив модели встраивания. Это можно легко сделать с помощью утилитных функций из библиотеки pymilvus[model].

Представление текста с помощью векторов

Сначала установите библиотеку моделей. Этот пакет включает в себя основные инструменты ML, такие как PyTorch. Загрузка пакета может занять некоторое время, если в вашем локальном окружении никогда не устанавливался PyTorch.

$ pip install "pymilvus[model]"

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

from pymilvus import model

# If connection to https://huggingface.co/ failed, uncomment the following path
# import os
# os.environ['HF_ENDPOINT'] = 'https://hf-mirror.com'

# This will download a small embedding model "paraphrase-albert-small-v2" (~50MB).
embedding_fn = model.DefaultEmbeddingFunction()

# Text strings to search from.
docs = [
    "Artificial intelligence was founded as an academic discipline in 1956.",
    "Alan Turing was the first person to conduct substantial research in AI.",
    "Born in Maida Vale, London, Turing was raised in southern England.",
]

vectors = embedding_fn.encode_documents(docs)
# The output vector has 768 dimensions, matching the collection that we just created.
print("Dim:", embedding_fn.dim, vectors[0].shape)  # Dim: 768 (768,)

# Each entity has id, vector representation, raw text, and a subject label that we use
# to demo metadata filtering later.
data = [
    {"id": i, "vector": vectors[i], "text": docs[i], "subject": "history"}
    for i in range(len(vectors))
]

print("Data has", len(data), "entities, each with fields: ", data[0].keys())
print("Vector dim:", len(data[0]["vector"]))
Dim: 768 (768,)
Data has 3 entities, each with fields:  dict_keys(['id', 'vector', 'text', 'subject'])
Vector dim: 768

[Альтернатива] Использовать фальшивое представление со случайными векторами

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

import random

# Text strings to search from.
docs = [
    "Artificial intelligence was founded as an academic discipline in 1956.",
    "Alan Turing was the first person to conduct substantial research in AI.",
    "Born in Maida Vale, London, Turing was raised in southern England.",
]
# Use fake representation with random vectors (768 dimension).
vectors = [[random.uniform(-1, 1) for _ in range(768)] for _ in docs]
data = [
    {"id": i, "vector": vectors[i], "text": docs[i], "subject": "history"}
    for i in range(len(vectors))
]

print("Data has", len(data), "entities, each with fields: ", data[0].keys())
print("Vector dim:", len(data[0]["vector"]))
Data has 3 entities, each with fields:  dict_keys(['id', 'vector', 'text', 'subject'])
Vector dim: 768

Вставка данных

Давайте вставим данные в коллекцию:

res = client.insert(collection_name="demo_collection", data=data)

print(res)
{'insert_count': 3, 'ids': [0, 1, 2], 'cost': 0}

Теперь мы можем выполнять семантический поиск, представляя текст поискового запроса в виде вектора, и проводить поиск по векторному сходству на Milvus.

Milvus принимает один или несколько запросов на векторный поиск одновременно. Значением переменной query_vectors является список векторов, где каждый вектор - это массив чисел с плавающей точкой.

query_vectors = embedding_fn.encode_queries(["Who is Alan Turing?"])
# If you don't have the embedding function you can use a fake vector to finish the demo:
# query_vectors = [ [ random.uniform(-1, 1) for _ in range(768) ] ]

res = client.search(
    collection_name="demo_collection",  # target collection
    data=query_vectors,  # query vectors
    limit=2,  # number of returned entities
    output_fields=["text", "subject"],  # specifies fields to be returned
)

print(res)
data: ["[{'id': 2, 'distance': 0.5859944820404053, 'entity': {'text': 'Born in Maida Vale, London, Turing was raised in southern England.', 'subject': 'history'}}, {'id': 1, 'distance': 0.5118255615234375, 'entity': {'text': 'Alan Turing was the first person to conduct substantial research in AI.', 'subject': 'history'}}]"] , extra_info: {'cost': 0}

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

Векторный поиск с фильтрацией метаданных

Вы также можете осуществлять векторный поиск с учетом значений метаданных (в Milvus они называются "скалярными" полями, поскольку скалярные относятся к невекторным данным). Это делается с помощью выражения фильтра, задающего определенные критерии. Рассмотрим поиск и фильтрацию с помощью поля subject в следующем примере.

# Insert more docs in another subject.
docs = [
    "Machine learning has been used for drug design.",
    "Computational synthesis with AI algorithms predicts molecular properties.",
    "DDR1 is involved in cancers and fibrosis.",
]
vectors = embedding_fn.encode_documents(docs)
data = [
    {"id": 3 + i, "vector": vectors[i], "text": docs[i], "subject": "biology"}
    for i in range(len(vectors))
]

client.insert(collection_name="demo_collection", data=data)

# This will exclude any text in "history" subject despite close to the query vector.
res = client.search(
    collection_name="demo_collection",
    data=embedding_fn.encode_queries(["tell me AI related information"]),
    filter="subject == 'biology'",
    limit=2,
    output_fields=["text", "subject"],
)

print(res)
data: ["[{'id': 4, 'distance': 0.27030569314956665, 'entity': {'text': 'Computational synthesis with AI algorithms predicts molecular properties.', 'subject': 'biology'}}, {'id': 3, 'distance': 0.16425910592079163, 'entity': {'text': 'Machine learning has been used for drug design.', 'subject': 'biology'}}]"] , extra_info: {'cost': 0}

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

Помимо векторного поиска, вы можете выполнять и другие типы поиска:

Запрос

Запрос() - это операция, которая извлекает все сущности, соответствующие какому-либо критерию, например выражению фильтра или совпадению некоторых идентификаторов.

Например, поиск всех сущностей, скалярное поле которых имеет определенное значение:

res = client.query(
    collection_name="demo_collection",
    filter="subject == 'history'",
    output_fields=["text", "subject"],
)

Прямое получение сущностей по первичному ключу:

res = client.query(
    collection_name="demo_collection",
    ids=[0, 2],
    output_fields=["vector", "text", "subject"],
)

Удалить сущности

Если вы хотите очистить данные, вы можете удалить сущности, указав первичный ключ, или удалить все сущности, соответствующие определенному выражению фильтра.

# Delete entities by primary key
res = client.delete(collection_name="demo_collection", ids=[0, 2])

print(res)

# Delete entities by a filter expression
res = client.delete(
    collection_name="demo_collection",
    filter="subject == 'biology'",
)

print(res)
[0, 2]
[3, 4, 5]

Загрузка существующих данных

Поскольку все данные Milvus Lite хранятся в локальном файле, вы можете загрузить все данные в память даже после завершения работы программы, создав MilvusClient с существующим файлом. Например, это позволит восстановить коллекции из файла "milvus_demo.db" и продолжить запись данных в него.

from pymilvus import MilvusClient

client = MilvusClient("milvus_demo.db")

Удаление коллекции

Если вы хотите удалить все данные в коллекции, вы можете сбросить коллекцию с помощью команды

# Drop collection
client.drop_collection(collection_name="demo_collection")

Подробнее

Milvus Lite отлично подходит для начала работы с локальной программой на python. Если у вас большие объемы данных или вы хотите использовать Milvus в производстве, вы можете узнать о развертывании Milvus на Docker и Kubernetes. Все режимы развертывания Milvus используют один и тот же API, поэтому при переходе к другому режиму развертывания код на стороне клиента не придется сильно менять. Просто укажите URI и токен сервера Milvus, развернутого в любом месте:

client = MilvusClient(uri="http://localhost:19530", token="root:Milvus")

Milvus предоставляет API REST и gRPC, а также клиентские библиотеки на таких языках, как Python, Java, Go, C# и Node.js.