고급 RAG 및 멀티모달 쿼리를 위한 Milvus와 Friendli Serverless Endpoints 활용
FriendliAI는 생성형 AI 인프라를 전문으로 하며, 조직이 최적화된 성능과 절감된 비용으로 대규모 언어 모델(LLMs) 및 기타 생성형 AI 모델을 효율적으로 배포하고 관리할 수 있게 해주는 솔루션을 제공합니다. 사용자는 APIs를 통해 접근 가능한 프로덕션 준비가 완료된 기존 LLMs 또는 public cloud나 private on-premise clusters에서 사용자가 선택한 하드웨어에 배포된 맞춤형 파인튜닝 LLMs 중에서 선택할 수 있습니다.
Milvus는 고차원 vector embeddings를 통해 수십억 규모의 비정형 데이터를 저장, 인덱싱, 검색하는 오픈소스 vector database입니다. 검색 증강 생성(RAG), 시맨틱 검색, multimodal search, 추천 시스템과 같은 최신 AI 애플리케이션을 구축하는 데 적합합니다.
이 글에서는 특정 문서와 자료에 대해 Retrieval-Augmented Generation (RAG)을 수행하고 이미지 및 기타 시각 콘텐츠를 통합하는 멀티모달 쿼리를 실행하기 위해 Milvus를 Friendli Serverless Endpoints와 함께 사용하는 방법을 살펴보겠습니다. 이 강력한 조합을 통해 더 정교하고 맥락 인식이 가능한 AI 애플리케이션을 만들 수 있습니다.
RAG와 멀티모달 모델 이해하기
Retrieval-Augmented Generation (RAG)
RAG는 주로 vector database 기반 지식 베이스에서 검색된 관련 정보를 언어 모델에 제공하여 이를 향상시키는 기법입니다. 이 접근 방식은 AI 모델이 지정된 외부 데이터 소스를 참조함으로써 더 정확하고 맥락에 적합한 응답을 생성할 수 있게 합니다.
멀티모달 모델
Multimodal models는 텍스트, 이미지, 오디오와 같은 여러 유형의 입력 데이터를 처리하고 이해할 수 있습니다. 다양한 정보 소스를 기반으로 분석하고 응답을 생성할 수 있어, 더 포괄적이고 미묘한 상호작용을 가능하게 합니다.
RAG와 멀티모달 모델을 함께 통합해야 하는 이유는 무엇인가요?
RAG와 멀티모달 기능의 조합은 다음 기능을 동시에 제공하여 AI 시스템을 크게 개선합니다:
- 사용자가 선택한 더 다양하고 풍부한 입력 유형을 허용
- 최신 정보 제공
- 응답의 정확성과 관련성 향상
- 맥락 인식 상호작용 지원
실습 구현
Milvus vector database와 Friendli Serverless Endpoints를 사용하여 RAG 및 멀티모달 쿼리를 실제로 구현하는 방법을 살펴보겠습니다.
1단계: 필수 구성 요소 설치 및 Milvus 문서 다운로드
먼저, 필요한 라이브러리를 설치하고 RAG 작업에 사용할 Milvus documentation을 다운로드하겠습니다:
!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단계: 임베딩 준비
간단한 all-MiniLM-L6 모델을 사용해 텍스트의 벡터 표현을 생성하기 위해 Hugging Face 임베딩 라이브러리를 사용하겠습니다:
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 클라이언트 설정
이제 RAG 구현을 위해 Milvus 클라이언트를 준비해 보겠습니다. 이 간단한 예제에서는 로컬에서 실행되고 로컬 파일에 파일을 구체화하는 Milvus Lite를 사용합니다. 다른 Milvus 배포 옵션도 고려할 수 있습니다:
소규모 데이터나 프로토타이핑을 위한 로컬 벡터 데이터베이스만 필요한 경우, uri를 로컬 파일(예: ./milvus.db)로 설정하는 것이 가장 편리한 방법입니다. 이렇게 하면 자동으로 Milvus Lite를 사용하여 모든 데이터를 이 파일에 저장합니다.
프로덕션에서 더 큰 규모의 데이터와 트래픽을 처리하려면 Docker 또는 Kubernetes에 Milvus 서버를 설정할 수 있습니다. 이 설정에서는 서버 주소와 포트를 uri로 사용하세요(예: http://localhost:19530). Milvus에서 인증 기능을 활성화한 경우 token을 "<your_username>:<your_password>"로 설정하고, 그렇지 않으면 토큰을 설정할 필요가 없습니다.
Zilliz Cloud에서 완전 관리형 Milvus를 사용할 수도 있습니다. Zilliz Cloud 인스턴스의 Public Endpoint 및 API key를 uri와 token으로 설정하기만 하면 됩니다.
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>
"""
Step 9: Friendli Token 설정
Friendli Suite에서 FRIENDLI_TOKEN을 얻고 환경 변수로 설정합니다:
import os
if "FRIENDLI_TOKEN" not in os.environ:
os.environ["FRIENDLI_TOKEN"] = 'flp_FILL_IN_WITH_YOUR_OWN_PERSONAL_ACCESS_TOKEN'
Step 10: RAG 쿼리 실행
이제 Friendli Serverless Endpoints를 사용해 RAG 쿼리를 실행할 수 있습니다:
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 모듈은 자체 메타데이터를 가집니다.
Step 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
…
Step 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)
모델은 이미지와 문서를 기반으로 올바른 응답을 정확히 생성합니다:
**Step 1: Milvus에서 데이터 저장에 관여하는 구성 요소 식별.**
Milvus에서 데이터 저장에 관여하는 구성 요소는 다음과 같습니다:
* Access Layer
* Message Storage
* Worker Node
**Step 2: Milvus에서 데이터가 저장되는 방식 결정.**
데이터는 Access Layer와 Message Storage에 저장됩니다.
**3단계: Milvus에서 데이터가 저장되는 위치를 확인합니다.**
데이터는 Access Layer와 Message Storage 모두에 저장됩니다.
**답변:** 데이터는 Access Layer와 Message Storage 모두에 저장됩니다.
전체 코드와 자세한 내용은 이 Colab notebook을 확인하세요.
결론
이 튜토리얼에서는 Milvus와 Friendli Serverless Endpoints를 활용하여 고급 RAG 및 멀티모달 쿼리를 구현하는 방법을 보여주었습니다. 이러한 강력한 기술을 결합하면 다양한 유형의 정보를 이해하고 처리할 수 있는 더 정교한 AI 애플리케이션을 만들 수 있으며, 이를 통해 더 정확하고 맥락을 인식하는 응답을 제공할 수 있습니다.
계속 읽기

Introducing Zilliz Cloud Global Cluster: Region-Level Resilience for Mission-Critical AI
Zilliz Cloud Global Cluster delivers multi-region resilience, automatic failover, and fast global AI search with built-in security and compliance.

Zilliz Cloud Introduces Advanced BYOC-I Solution for Ultimate Enterprise Data Sovereignty
Explore Zilliz Cloud BYOC-I, the solution that balances AI innovation with data control, enabling secure deployments in finance, healthcare, and education sectors.

DeepSeek Always Busy? Deploy It Locally with Milvus in Just 10 Minutes—No More Waiting!
Learn how to set up DeepSeek-R1 on your local machine using Ollama, AnythingLLM, and Milvus in just 10 minutes. Bypass busy servers and enhance AI responses with custom data.



