Milvus Lite로 빠르게 시작하기
신경망 모델의 출력 데이터 형식인 벡터는 정보를 효과적으로 인코딩하고 지식 베이스, 시맨틱 검색, 검색 증강 생성(RAG) 등과 같은 AI 애플리케이션에서 중추적인 역할을 할 수 있습니다.
Milvus는 오픈 소스 벡터 데이터베이스로, Jupyter 노트북에서 데모 챗봇을 실행하는 것부터 수십억 명의 사용자에게 서비스를 제공하는 웹 규모 검색 구축에 이르기까지 모든 규모의 AI 애플리케이션에 적합합니다. 이 가이드에서는 몇 분 안에 Milvus를 로컬에서 설정하고 Python 클라이언트 라이브러리를 사용하여 벡터를 생성, 저장 및 검색하는 방법을 안내해 드립니다.
Milvus 설치하기
이 가이드에서는 클라이언트 애플리케이션에 임베드할 수 있는 pymilvus
에 포함된 Python 라이브러리인 Milvus Lite를 사용합니다. Milvus는 프로덕션 사용 사례를 위해 Docker 및 Kubernetes에 배포하는 것도 지원합니다.
시작하기 전에 로컬 환경에서 Python 3.8 이상을 사용할 수 있는지 확인하세요. 파이썬 클라이언트 라이브러리와 Milvus Lite가 모두 포함된 pymilvus
을 설치합니다:
$ pip install -U pymilvus
Google Colab을 사용하는 경우 방금 설치한 종속성을 사용하려면 런타임을 다시 시작해야 할 수 있습니다. (화면 상단의 "런타임" 메뉴를 클릭하고 드롭다운 메뉴에서 "세션 다시 시작"을 선택합니다).
벡터 데이터베이스 설정
로컬 Milvus 벡터 데이터베이스를 만들려면 "milvus_demo.db"와 같이 모든 데이터를 저장할 파일 이름을 지정하여 MilvusClient
인스턴스화하면 됩니다.
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)으로 설정됩니다.
- 기본 키 필드는 정수를 허용하며 자동으로 증가하지 않습니다(즉, 자동 ID 기능을 사용하지 않음). 또는 이 지침에 따라 컬렉션의 스키마를 공식적으로 정의할 수 있습니다.
데이터 준비
이 가이드에서는 벡터를 사용하여 텍스트에 대한 의미론적 검색을 수행합니다. 임베딩 모델을 다운로드하여 텍스트에 대한 벡터를 생성해야 합니다. 이는 pymilvus[model]
라이브러리의 유틸리티 함수를 사용하여 쉽게 수행할 수 있습니다.
벡터로 텍스트 표현하기
먼저 모델 라이브러리를 설치합니다. 이 패키지에는 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 = 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
으로 엔티티 세부 정보가 포함됩니다.
메타데이터 필터링을 사용한 벡터 검색
메타데이터의 값을 고려하면서 벡터 검색을 수행할 수도 있습니다(밀버스에서는 "스칼라" 필드라고 하는데, 스칼라는 벡터가 아닌 데이터를 의미하기 때문입니다). 이는 특정 기준을 지정하는 필터 표현식을 사용하여 수행됩니다. 다음 예제에서 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}
기본적으로 스칼라 필드는 인덱싱되지 않습니다. 대규모 데이터 세트에서 메타데이터 필터링 검색을 수행해야 하는 경우 고정 스키마를 사용하고 인덱스를 켜서 검색 성능을 개선하는 것도 고려해 볼 수 있습니다.
벡터 검색 외에도 다른 유형의 검색을 수행할 수도 있습니다:
쿼리
쿼리()는 필터 표현식이나 일부 ID와 일치하는 등 조건에 일치하는 모든 엔터티를 검색하는 작업입니다.
예를 들어, 스칼라 필드에 특정 값이 있는 모든 엔터티를 검색합니다:
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]
기존 데이터 로드
밀버스 라이트의 모든 데이터는 로컬 파일에 저장되므로 프로그램이 종료된 후에도 기존 파일로 MilvusClient
을 생성하여 모든 데이터를 메모리로 로드할 수 있습니다. 예를 들어, 이렇게 하면 "milvus_demo.db" 파일에서 컬렉션을 복구하고 데이터를 계속 쓸 수 있습니다.
from pymilvus import MilvusClient
client = MilvusClient("milvus_demo.db")
컬렉션 삭제
컬렉션의 모든 데이터를 삭제하려면 다음을 사용하여 컬렉션을 삭제할 수 있습니다.
# Drop collection
client.drop_collection(collection_name="demo_collection")
자세히 알아보기
Milvus Lite는 로컬 파이썬 프로그램을 시작하기에 좋습니다. 대규모 데이터가 있거나 프로덕션 환경에서 Milvus를 사용하려는 경우, Docker 및 Kubernetes에 Milvus 배포에 대해 알아볼 수 있습니다. Milvus의 모든 배포 모드는 동일한 API를 공유하므로 다른 배포 모드로 이동하는 경우 클라이언트 측 코드를 크게 변경할 필요가 없습니다. 어디든 배포된 Milvus 서버의 URI와 토큰을 지정하기만 하면 됩니다:
client = MilvusClient(uri="http://localhost:19530", token="root:Milvus")
Milvus는 Python, Java, Go, C#, Node.js 등의 언어로 된 클라이언트 라이브러리와 함께 REST 및 gRPC API를 제공합니다.