brunch

RAG 기본 - 검색의 중요성

by 최재철

대규모 언어 모델(LLM)은 최근 매우 강력한 기능을 보여주며 많은 사람들과 조직에서 주목받고 있습니다. LLM은 아주 다양한 질문에 대해 텍스트를 생성하는 능력이 뛰어나기 때문에 많이 사용되고 있습니다. 하지만 몇 가지 문제도 있는데요, 예를 들어 LLM은 사용자 질문의 세부적인 상황을 잘 파악하지 못하거나, 오래된 정보를 제공할 수 있습니다.

이런 문제를 해결하기 위한 방법 중 하나로 검색 증강 생성(RAG)이 많이 사용되고 있습니다. RAG는 LLM이 응답을 더 정확하고 최신 정보로 만들기 위해 검색을 추가하는 방식입니다. 즉, LLM이 단순히 정보를 생성하는 것이 아니라, 먼저 검색을 통해 관련된 최신 정보를 찾아보고 그 데이터를 바탕으로 더 나은 답을 제공하는 것입니다. 그래서 많은 기업들이 소프트웨어 시스템에 LLM을 적용할 때 RAG 방식을 함께 사용하여 더 정확한 답변을 얻고 있습니다.

요약하자면, RAG는 LLM이 단순히 답변을 만들기보다는, 관련된 최신 정보를 검색하고 이를 바탕으로 답변을 생성해주는 방법이라고 생각하면 됩니다.


RAG 및 구성 요소 이해

자세한 내용은 아래를 참고바랍니다.

https://brunch.co.kr/@b2439ea8fc654b8/4

RAG 의 구성요소 중 검색

RAG는 다양한 분야에서 활용될 수 있는데, 예를 들어 콘텐츠 생성이나 요약을 할 때, 또는 대화형 에이전트에서 사용됩니다. RAG 시스템은 크게 세 가지 구성 요소로 나뉩니다:

1. 검색

2. 증강

3. 생성


검색

이 부분은 말 그대로 정보를 검색하는 역할을 합니다. 외부 지식 기반에서 관련된 정보를 찾아내는 것이죠. 여기서 중요한 점은 검색된 정보가 주어진 질문(프롬프트)과 얼마나 유사성(관련성)이 있는지 확인하는 것입니다.

검색 방법은 여러 가지가 있는데, 몇 가지 예를 들면

- 키워드 검색: 우리가 인터넷에서 검색어를 입력하면 키워드가 포함된 결과를 찾아주는 방식.

- 의미적 유사성 검색: 단순히 단어가 같은 게 아니라, 문장의 의미가 비슷한 정보를 찾아주는 방식.

- 신경망 기반 검색: 인공지능 모델을 사용해 더 정교하게 관련 정보를 찾아내는 방식.

이 중에서 프로젝트에 맞는 검색 방식을 선택해서 사용할 수 있습니다.


예시 코드

아래는 외부 지식 기반에서 정보를 검색하는 RAG 시스템의 간단한 코드 예시입니다.

https://gist.github.com/choijaecheol/b0e2aa7b342c84efa693f36c889d2b1e


화면 캡처 2024-11-15 163855.png

하드코딩에 문서의 코퍼스에서 사용자의 질의에 가장 유사한 답변 2건을 검색한 것을 볼 수 있습니다.

여기서의 핵심은, 문서를 임베딩이라는 모델을 통해서 임베딩벡터를 생성하고, 이걸 벡터스토어(또는 DB) 에 넣어서 검색하는 것입니다. 소스에서 사용된 것은 각각 다음과 같습니다.

임베딩 모델 : sentence-transformers/all-MiniLM-L6-v2

벡터스토어 : FAISS(Facebook AI Similarity Search)


[ 코드 설명 ]

1. 임베딩 모델 로드: sentence-transformers/all-MiniLM-L6-v2 모델을 사용하여 텍스트를 벡터로 변환하기 위한 토크나이저와 모델을 로드합니다.


2. 임베딩 함수: generate_embedding 함수는 주어진 텍스트를 토크나이저로 처리하고, 모델의 출력값을 사용하여 임베딩 벡터를 생성합니다. 이때 마지막 레이어의 출력값을 평균 풀링하여 고정된 차원의 벡터를 만듭니다.


3. FAISS 인덱스 생성 및 추가: 문서 코퍼스를 임베딩 벡터로 변환한 후, 이 벡터들을 FAISS에 저장하여 검색에 사용합니다.


4. 유사 문서 검색: 사용자의 쿼리를 임베딩 벡터로 변환한 후, FAISS 인덱스에서 가장 유사한 2개의 문서를 검색합니다.


5. 결과 출력: 사용자의 질의와 검색된 문서를 출력합니다.


[ 참고 사항 ]

기본적으로 sentence-transformers/all-MiniLM-L6-v2 모델은 384차원의 임베딩을 생성하며, 다양한 언어를 처리할 수 있는 다국어 모델입니다.

이 시스템은 기본적으로 CPU에서 동작하지만, GPU에서의 성능 최적화를 위해 faiss-gpu와 같은 라이브러리를 사용할 수 있습니다.


sentence-transformers/all-MiniLM-L6-v2

sentence-transformers/all-MiniLM-L6-v2는 Sentence Transformers 라이브러리에서 제공하는 모델 중 하나로, 주로 문장의 의미를 벡터로 변환하는 임베딩 모델로 사용됩니다. 이 모델의 주요 특징은 다음과 같습니다.


경량화된 모델: MiniLM (Minimal Language Model)은 BERT 기반의 경량화된 모델로, 훨씬 작은 파라미터 수와 연산량을 요구하면서도 효율적인 성능을 제공합니다. 이 모델은 6개의 트랜스포머 레이어로 이루어져 있으며, 빠른 속도와 적은 메모리 사용량이 특징입니다.

적용 사례: 문장 임베딩 생성: 문장을 고정된 차원의 벡터로 변환하여 의미적으로 유사한 문장들을 비교할 수 있게 해줍니다. 정보 검색, 클러스터링, 문장 분류, 문장 유사도 계산 등에 사용됩니다.

차원 수: 이 모델의 임베딩 차원 수는 384입니다. 일반적인 BERT 모델은 768차원의 임베딩을 사용하지만, MiniLM-L6-v2는 경량화를 위해 차원을 절반으로 줄였습니다. 384차원은 고성능 문장 비교 작업에 적합하도록 설계되었습니다. 특히 응답 시간이 중요한 애플리케이션에서는 차원이 적을수록 속도가 빨라집니다.


한국어 및 다국어 지원 능력

sentence-transformers/all-MiniLM-L6-v2는 주로 영어 데이터로 훈련된 모델이지만, 한국어를 포함한 다국어 문장에 대해서도 어느 정도 성능을 발휘할 수 있습니다. 이는 해당 모델이 대규모의 다국어 코퍼스에서 훈련되지는 않았으나, 여전히 transformer 모델 구조가 다양한 언어에 대해 보편적인 특성을 학습하기 때문입니다. 다만, 한국어 지원 능력은 한국어로 특별히 훈련된 다국어 모델에 비해 낮을 수 있습니다.

다국어 모델로 더 나은 한국어 지원을 원한다면 XLM-RoBERTa와 같은 다국어 모델을 사용하는 것이 더 적합할 수 있습니다.


차원 수 384는 너무 작은게 아닌가요?

384차원은 문장의 의미를 비교하기에 충분한 벡터 차원으로 설계되었습니다. 차원이 크다고 무조건 더 나은 성능을 제공하는 것은 아니며, 애플리케이션의 요구 사항에 따라 적절한 차원 수를 선택하는 것이 중요합니다. 장점: 384차원은 더 적은 메모리와 더 빠른 계산 속도를 제공하여 실시간 응답이나 자원 제약이 있는 환경에서 유리합니다. 단점: 차원이 적을 경우, 매우 복잡한 문장 의미를 완벽하게 표현하는 데 한계가 있을 수 있습니다. 더 복잡한 의미를 구분해야 한다면 768차원이나 그 이상의 모델이 유리할 수 있습니다.


마치며

RAG 시스템에서 검색은 가장 중요한 역할을 합니다. RAG의 전체 과정은 기본적으로 사용자가 질문을 했을 때, 외부 지식 기반에서 관련 정보를 검색하는 것에서 시작되는데, 이 검색이 제대로 이루어지지 않으면, 그 이후의 모든 과정이 의미가 없기 때문입니다.

예를 들어, 우리가 어떤 질문을 했을 때 엉뚱한 정보가 검색된다면, 이후에 아무리 생성된 답변이 훌륭하더라도 질문에 대한 정확한 답을 얻지 못하게 되죠. 그래서 RAG 시스템의 성공 여부는 얼마나 정확하고 빠르게 관련된 정보를 찾을 수 있느냐에 달려 있습니다.


요약하자면, RAG 시스템에서 검색 단계는 핵심적인 부분이고, FAISS와 같은 벡터스토어를 사용하면 벡터화된 데이터를 빠르게 검색하여 정확한 정보를 제공할 수 있습니다. 검색이 잘 이루어져야만 그다음 단계인 증강과 생성이 의미 있게 작동합니다.

keyword
작가의 이전글[입문] 1. ChatGPT의 개요 & 프롬프트란