Conversational AI / NLP

리랭킹을 통한 RAG 파이프라인 강화

Reading Time: 5 minutes

빠르게 진화하는 AI 기반 애플리케이션 환경에서 리랭크는 기업 검색 결과의 정확도와 관련성을 향상시키는 핵심 기술로 부상했습니다. 리랭크는 고급 머신 러닝 알고리즘을 사용해 초기 검색 결과를 사용자의 의도와 맥락에 더 잘 맞도록 개선함으로써 시맨틱 검색의 효율성을 크게 향상시킵니다. 이를 통해 보다 정확하고 맥락에 맞는 결과를 제공함으로써 사용자 만족도를 높이고 전환율과 참여도 지표를 높일 수 있습니다.

또한 리랭크는 검색 증강 생성(RAG) 파이프라인을 최적화하는 데 중요한 역할을 하며, 이를 통해 거대 언어 모델(LLM)이 가장 관련성이 높고 고품질의 정보를 처리할 수 있도록 보장합니다. 시맨틱 검색과 RAG 파이프라인을 모두 향상시키는 리랭크의 이 두 가지 이점은 우수한 검색 환경을 제공하고 디지털 시장에서 경쟁력을 유지하려는 기업에게 없어서는 안 될 필수 도구입니다.

이 글에서는 NVIDIA NeMo Retriever 리랭킹 NIM을 사용합니다. 이 인코더는 처리량을 높이기 위해 처음 16개 레이어만 사용하는 Mistral-7B의 파인 튜닝된 LoRA 버전인 트랜스포머 인코더입니다. 디코더 모델의 마지막 임베딩 출력은 풀링 전략으로 사용되며, 순위 지정 작업을 위해 이진 분류 헤드가 미세 조정됩니다.

리랭킹이란 무엇인가요?

리랭크는 LLM의 고급 언어 이해 기능을 사용하여 검색 결과의 관련성을 높이는 데 사용되는 정교한 기법입니다.

처음에는 BM25 또는 벡터 유사도 검색과 같은 기존의 정보 검색 방법을 사용하여 후보 문서 또는 구절 집합을 검색합니다. 그런 다음 이러한 후보 문서들은 쿼리와 각 문서 간의 의미론적 관련성을 분석하는 LLM에 입력됩니다. LLM은 관련성 점수를 할당하여 가장 관련성이 높은 문서의 우선순위를 정할 수 있도록 문서를 재순서화합니다.

이 프로세스는 단순한 키워드 매칭을 넘어 쿼리와 문서의 문맥과 의미를 이해함으로써 검색 결과의 품질을 크게 향상시킵니다. 재랭크는 일반적으로 초기 빠른 검색 단계에 이어 두 번째 단계로 사용되며, 가장 관련성이 높은 문서만 사용자에게 표시되도록 합니다. 또한 여러 데이터 소스의 결과를 결합할 수 있을 뿐만 아니라 RAG 파이프라인에 통합하여 특정 쿼리에 맞게 컨텍스트가 이상적으로 조정되도록 할 수도 있습니다.

세계적 수준의 정보 검색 마이크로서비스로 구성된 NVIDIA NeMo Retriever 컬렉션에 액세스하려면 NVIDIA API 카탈로그를 참조하세요.

튜토리얼 전제 조건

이 튜토리얼을 최대한 활용하려면 다음 리소스와 함께 LLM 추론 파이프라인에 대한 기본 지식이 필요합니다:

설정

시작하려면 NVIDIA API 카탈로그에서 무료 계정을 생성하고 다음 단계를 따르세요:

모델을 선택합니다.
Python, API 키 받기를 선택합니다.
생성된 키를 NVIDIA_API_KEY로 저장합니다.
이제 엔드포인트에 액세스할 수 있습니다.

이제 LangChain, NVIDIA AI 엔드포인트, FAISS를 설치합니다:

pip install langchain
pip install langchain_nvidia_ai_endpoints
pip install faiss-gpu

관련 문서 불러오기

이 예제에서는 멀티모달 LLM에 대한 최신 NVIDIA 문서인 VILA: 시각 언어 모델을 위한 사전 학습을 불러옵니다. 이 게시물의 모든 예제에는 이 단일 PDF를 사용하지만, 코드를 쉽게 확장하여 여러 문서를 불러올 수 있습니다.

from langchain_community.document_loaders import PyPDFLoader
 
document = PyPDFLoader("2312.07533v4.pdf").load()

청크로 분할

다음으로 문서를 별도의 청크로 분할합니다.

TextSplitter의 chunk_size 매개변수에 주의하세요. RAG 파이프라인의 성공 여부는 대부분 검색 단계에서 생성에 적합한 컨텍스트를 찾는 데 달려 있기 때문에 적절한 청크 크기를 설정하는 것은 RAG 성능에 매우 중요합니다. 검색 단계에서는 일반적으로 모든 문서가 아닌 원본 텍스트의 작은 청크를 검사합니다.

전체 프롬프트(검색된 청크와 사용자 쿼리)는 LLM의 컨텍스트 창에 맞아야 합니다. 청크 크기를 너무 크게 지정하지 말고 예상 쿼리 크기와 균형을 맞추세요. 다양한 청크 크기로 실험해 보되, 일반적인 값은 LLM에 따라 100~600토큰이어야 합니다.

from langchain_text_splitters import RecursiveCharacterTextSplitter
text_splitter = RecursiveCharacterTextSplitter(chunk_size=800, chunk_overlap=200)
texts = text_splitter.split_documents(document)
그림 1. 리랭킹으로 강화된 검색 시스템

임베딩 생성하기

다음으로, NVIDIA AI 파운데이션 엔드포인트를 사용하여 임베딩을 생성하고 나중에 다시 사용할 수 있도록 /embed 디렉터리의 오프라인 벡터 스토어에 임베딩을 저장합니다.

이 작업에는 고밀도 벡터의 효율적인 유사도 검색 및 클러스터링을 위한 라이브러리인 FAISS를 사용합니다. 여기에는 모든 크기의 벡터 집합을 검색하는 알고리즘이 포함되어 있으며, RAM에 맞지 않을 수 있는 벡터까지 검색할 수 있습니다.

from langchain_nvidia_ai_endpoints import NVIDIAEmbeddings
from langchain_community.vectorstores import FAISS
 
embeddings = NVIDIAEmbeddings()
db = FAISS.from_documents(texts, embeddings)

기본 retriever 만들기

이제 문서를 기반으로 기본 검색기를 만들어 쿼리와 가장 관련성이 높은 청크를 검색하세요. 이 코드는 간단한 검색 알고리즘을 기반으로 쿼리와 가장 관련성이 높은 45개의 청크를 출력합니다:

retriever = db.as_retriever(search_kwargs={"k": 45})
 
query = "Where is the A100 GPU used?"
docs = retriever.invoke(query)

리랭크 단계 추가

이제 NeMo Retriever 리랭킹 NIM을 사용하여 리랭킹 단계를 추가합니다. 이것은 주어진 구절에 질문에 답할 수 있는 정보가 포함되어 있을 확률 점수를 제공하는 데 최적화된 GPU 가속 모델입니다. 동일한 쿼리를 사용하여 가장 관련성이 높은 구절에 따라 이전에 가져온 청크의 순위를 다시 매깁니다.

NIM을 LangChain 문맥 압축 검색기의 입력으로 사용하면, 검색 컨텍스트에 따라 문서를 압축하고 필터링한 후 반환함으로써 검색을 개선합니다.

from langchain_nvidia_ai_endpoints import NVIDIARerank
from langchain.retrievers.contextual_compression import ContextualCompressionRetriever
 
reranker = NVIDIARerank()
compression_retriever = ContextualCompressionRetriever(
    base_compressor=reranker, base_retriever=retriever
)
 
reranked_chunks = compression_retriever.compress_documents(query)

리랭킹 NIM은 가장 관련성이 높은 부분을 문서 끝에 있는 트레이닝 비용과 관련된 단락으로 인식하며, 이 단락에는 A100 GPU가 명시되어 있습니다:

Table 10. The SFT blend we used during the ablation study.
 
B. Training Cost
 
We perform training on 16 A100 GPU nodes, each node
 
has 8 GPUs. The training hours for each stage of the 7B
 
model are: projector initialization: 4 hours; visual language
 
pre-training: 30 hours; visual instruction-tuning: 6 hours.
 
The training corresponds to a total of 5.1k GPU hours. Most
 
of the computation is spent on the pre-training stage.
 
We have not performed training throughput optimizations
 
like sample packing [ 32] or sample length clustering. We
 
believe we can reduce at least 30% of the training time with
 
proper optimization. We also notice that the training time is
 
much longer as we used a high image resolution of 336 ×336
 
(corresponding to 576 tokens/image). We should be able to

여러 데이터 원본의 결과 결합

단일 데이터 소스에 대한 정확도를 향상시키는 것 외에도, 재순위를 사용하여 RAG 파이프라인에서 여러 데이터 소스를 결합할 수 있습니다.

앞의 예와 같이 시맨틱 저장소와 BM25 저장소의 데이터가 포함된 파이프라인을 생각해 보겠습니다. 각 저장소는 독립적으로 쿼리되고 개별 저장소가 관련성이 높다고 간주하는 결과를 반환합니다. 결과의 전반적인 관련성을 파악하는 것이 바로 순위 재지정이 필요한 부분입니다.

다음 코드 예제는 이전 시맨틱 검색 결과와 BM25 결과를 결합한 것입니다. combined_docs의 결과는 리랭킹 NIM에 의해 쿼리와의 관련성에 따라 정렬됩니다.

all_docs = docs + bm25_docs
 
reranker.top_n = 5
 
combined_docs = reranker.compress_documents(query=query, documents=all_docs)

BM25 저장소 설정을 포함한 자세한 내용은 /langchain-ai/langchain-nvidia GitHub 리포지토리의 전체 노트북을 참조하세요.

RAG 파이프라인에 연결

리랭킹을 독립적으로 사용하는 것 외에도 RAG 파이프라인에 추가하여 원래 쿼리를 보강하는 데 가장 관련성이 높은 청크를 사용하도록 함으로써 응답을 더욱 향상시킬 수 있습니다.

그림 2. 리랭킹을 통한 향상된 RAG 파이프라인 아키텍처

이 경우 이전 단계의 compression_retriever 객체를 RAG 파이프라인에 연결합니다.

from langchain.chains import RetrievalQA
from langchain_nvidia_ai_endpoints import ChatNVIDIA
 
chain = RetrievalQA.from_chain_type(
    llm=ChatNVIDIA(temperature=0), retriever=compression_retriever
)
result = chain({"query": query})
print(result.get("result"))

이제 RAG 파이프라인은 올바른 최상위 청크를 사용하고 주요 인사이트를 요약합니다:

The A100 GPU is used for training the 7B model in the supervised 
fine-tuning/instruction tuning ablation study. The training is 
performed on 16 A100 GPU nodes, with each node having 8 GPUs. The 
training hours for each stage of the 7B model are: projector 
initialization: 4 hours; visual language pre-training: 30 hours; 
and visual instruction-tuning: 6 hours. The total training time 
corresponds to 5.1k GPU hours, with most of the computation being 
spent on the pre-training stage. The training time could potentially 
be reduced by at least 30% with proper optimization. The high image 
resolution of 336 ×336 used in the training corresponds to 576 
tokens/image.

결론

RAG는 LLM과 고밀도 벡터 표현의 강점을 결합한 강력한 접근 방식으로 부상했습니다. 고밀도 벡터 표현을 사용하는 RAG 모델은 효율적으로 확장할 수 있어 다국어 고객 서비스 챗봇이나 코드 생성형 에이전트와 같은 대규모 엔터프라이즈 애플리케이션에 적합합니다.

LLM이 계속 발전함에 따라 RAG는 혁신을 주도하고 인간과 유사한 언어를 이해하고 생성할 수 있는 고품질의 지능형 시스템을 제공하는 데 점점 더 중요한 역할을 할 것이 분명합니다.

자체 RAG 파이프라인을 구축할 때는 특정 콘텐츠의 청크 크기를 최적화하고 적절한 컨텍스트 길이를 가진 LLM을 선택하여 벡터 저장소 문서를 청크로 올바르게 분할하는 것이 중요합니다. 경우에 따라 여러 LLM의 복잡한 체인이 필요할 수도 있습니다. RAG 성능을 최적화하고 성공 여부를 측정하려면 강력한 평가자와 메트릭 모음을 사용하세요.

추가 모델 및 체인에 대한 자세한 내용은 NVIDIA AI LangChain 엔드포인트를 참조하세요.

Discuss (0)

Tags