Milvus의 데이터 삽입 속도에 대한 오해 바로잡기
LangChain 또는 LlamaIndex의 편리하고 더 짧은 API 단계에 의존하는 많은 사용자는 "Milvus에 데이터를 삽입하는 것이 느리다"고 생각할 수 있습니다. 그러나 이러한 인식은 종종 상세한 프로세스 단계가 간과되는 데서 비롯됩니다.
숨겨진 단계들
LangChain 또는 LlamaIndex를 사용할 때, 이러한 라이브러리는 임베딩 모델을 사용하여 비정형 데이터(텍스트, 이미지 또는 소리 등)를 벡터로 변환합니다. 그런 다음 이러한 벡터를 Milvus Lite에 삽입합니다. 라이브러리는 여러 백그라운드 단계를 대신 처리함으로써 이 복잡한 프로세스를 단순화합니다.
이러한 추상화는 데이터 삽입 프로세스가 오래 걸린다는 착각을 만들 수 있습니다.
시간을 잡아먹는 요소: 임베딩 생성
비정형 데이터에서 임베딩을 생성하는 데 소요되는 평균 시간은 Milvus에 데이터를 삽입하는 데 필요한 시간보다 훨씬 깁니다. 느리다고 느껴지는 것은 데이터 삽입 단계보다는 데이터를 벡터 표현으로 변환하는 계산 집약적인 프로세스 때문인 경우가 많습니다.
임베딩 생성 시간과 데이터 삽입 시간의 차이를 설명하기 위해, 이 블로그에서 평균 임베딩 시간이 약 5초인 예시를 보여드리겠습니다. 반면, Milvus 벡터 데이터베이스 삽입 시간의 평균은 약 0.1초에 불과합니다. 전체 코드는 제 GitHub에 있습니다.
즉, LangChain 또는 LlamaIndex에서 관찰되는 "Milvus 삽입" 시간의 약 97%는 임베딩 생성에 사용되며, 실제 데이터베이스 삽입 단계에는 약 3%가 사용됩니다.
저는 이전 블로그에서 LlamaIndex 또는 LangChain을 사용하여 Milvus Lite에 연결하는 방법을 보여드렸습니다.
다음 섹션에서는 다음을 다루겠습니다.
Milvus에 데이터를 삽입하는 LlamaIndex 코드 예시
Milvus에 데이터를 삽입하는 LangChain 코드 예시
Milvus에 데이터를 삽입하는 Pymilvus API 코드 예시
Milvus에 데이터를 삽입하는 LlamaIndex 코드 예시
다음은 LlamaIndex의 예시 코드입니다.
from llama_index.core import (
ServiceContext,
StorageContext,
VectorStoreIndex,
)
from llama_index.embeddings.huggingface import HuggingFaceEmbedding
from llama_index.vector_stores.milvus import MilvusVectorStore
import time
# Define the embedding model.
service_context = ServiceContext.from_defaults(
# LlamaIndex local: translates to the same location as default HF cache.
embed_model="local:BAAI/bge-large-en-v1.5",
)
# Create a Milvus collection from the documents and embeddings.
EMBEDDING_DIM = 1024
vectorstore = MilvusVectorStore(
uri="./milvus_llamaindex.db",
dim=EMBEDDING_DIM,
# Override LlamaIndex default values for Milvus.
consistency_level="Eventually",
drop_old=True,
index_params = {
"metric_type": "COSINE",
"index_type": "AUTOINDEX",
"params": {},}
)
storage_context = StorageContext.from_defaults(
vector_store=vectorstore
)
llamaindex = VectorStoreIndex.from_documents(
lli_docs[:1],
storage_context=storage_context,
service_context=service_context
)
Milvus에 데이터를 삽입하는 LangChain 코드 예시
다음은 LangChain의 예시 코드입니다.
from langchain_milvus import Milvus
from langchain_huggingface import HuggingFaceEmbeddings
from langchain.text_splitter import RecursiveCharacterTextSplitter
import time
# Define the embedding model.
model_name = "BAAI/bge-large-en-v1.5"
model_kwargs = {'device': 'cpu'}
encode_kwargs = {'normalize_embeddings': True}
embed_model = HuggingFaceEmbeddings(
model_name=model_name,
model_kwargs=model_kwargs,
encode_kwargs=encode_kwargs
)
EMBEDDING_DIM = embed_model.dict()['client'].get_sentence_embedding_dimension()
# Define the chunking strategy.
text_splitter = RecursiveCharacterTextSplitter(chunk_size=512, chunk_overlap=51)
# Create a Milvus collection from the documents with chunking and embeddings.
start_time = time.time()
docs = text_splitter.split_documents(docs)
vectorstore = Milvus.from_documents(
documents=docs,
embedding=embed_model,
connection_args={"uri": "./milvus_demo.db"},
# Override LangChain default values for Milvus.
consistency_level="Eventually",
drop_old=True,
index_params = {
"metric_type": "COSINE",
"index_type": "AUTOINDEX",
"params": {},}
)
Milvus에 데이터를 삽입하는 예시 Pymilvus API 코드
Pymilvus API 호출을 직접 사용하여, 짧고 편리한 LangChain 및 LlamaIndex 코딩 뒤에서 실제로 무슨 일이 일어나고 있는지 보여드리겠습니다.
위의 예시들은 인터넷에서 직접 다운로드한 Milvus docs webpages를 사용했습니다. 임베딩 시간과 삽입 시간의 차이를 보여주기 위해, 아래에서는 오픈 소스 multimodal embedding model을 사용하여 1) 이미지와 텍스트를 모두 임베딩하고 2) 밀집 벡터를 Milvus에 삽입하겠습니다.
import pymilvus
import requests
from io import BytesIO
# Run this in small batches to avoid memory issues.
BATCH_SIZE = 10
# Batch embed text and images and insert data into Milvus.
batch_embedding_times = []
batch_insert_times = []
for i in range(0, 300, BATCH_SIZE):
batch_images = []
batch_texts = []
batch_urls = []
for j in range(BATCH_SIZE):
if i + j < len(image_texts):
text = image_texts[i + j]
url = image_urls[i + j]
with Image.open(f"./images/{url}.jpg") as img:
batch_images.append(img.copy())
batch_texts.append(text)
batch_urls.append(url)
# STEP 1. EMBEDDING INFERENCE FOR TEXT AND IMAGES.
start_time = time.time()
image_embeddings, text_embeddings = embedding_model(
batch_images=batch_images,
batch_texts=batch_texts)
end_time = time.time()
# print(f"Embedding time for batch size {len(batch_images)}: ", end="")
# print(f"{np.round(end_time - start_time, 2)} seconds")
batch_embedding_times.append(end_time - start_time)
# STEP 2. INSERT CHUNK LIST INTO MILVUS OR ZILLIZ.
chunk_dict_list = []
# Create chunk dict_list.
for chunk, img_url, img_embed, text_embed in zip(
batch_texts,
batch_urls,
image_embeddings, text_embeddings):
chunk_dict = {
'chunk': chunk,
'image_filepath': img_url,
'text_vector': text_embed,
'image_vector': img_embed
}
chunk_dict_list.append(chunk_dict)
start_time = time.time()
try:
col.insert(data=chunk_dict_list)
except:
print(f"Insert error: {img_url}")
end_time = time.time()
# print(f"Insert time for {len(chunk_dict_list)} vectors: ", end="")
# print(f"{np.round(end_time - start_time, 4)} seconds")
batch_insert_times.append(end_time - start_time)
col.flush()
# Calculate the average embedding time.
average_time = np.mean(batch_embedding_times)
print(f"Average embedding time: {round(average_time,2)} seconds")
# Calculate the average insert time.
average_time = np.mean(batch_insert_times)
print(f"Average insert time: {round(average_time,2)} seconds")
다음은 배치 임베딩 시간의 출력입니다.
다음은 데이터를 Milvus에 배치 삽입한 시간의 출력입니다.
평균 임베딩 시간은 ~5초였고, 평균 Milvus 벡터 데이터베이스 삽입 시간은 약 0.1초였습니다. 이는 전체 시간의 약 97%가 임베딩 생성에 사용되었고, 약 3%가 데이터베이스 삽입에 사용되었음을 의미합니다.
보시다시피, 임베딩 단계가 가장 오래 걸립니다!
리소스 및 추가 자료
계속 읽기

Zilliz Cloud Now Available in AWS Asia Pacific (Seoul)
Zilliz Cloud is now available in AWS Seoul — low-latency vector search, in-country data residency, and one-step migration for Korean AI teams. 31 regions across 5 clouds.

Zilliz Cloud Now Available in Azure North Europe: Bringing AI-Powered Vector Search Closer to European Customers
The addition of the Azure North Europe (Ireland) region further expands our global footprint to better serve our European customers.

Selecting the Right ETL Tools for Unstructured Data to Prepare for AI
Learn the right ETL tools for unstructured data to power AI. Explore key challenges, tool comparisons, and integrations with Milvus for vector search.



