brunch

You can make anything
by writing

C.S.Lewis

by 최재철 Nov 15. 2024

RAG 기본 - 검색의 중요성

대규모 언어 모델(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


하드코딩에 문서의 코퍼스에서 사용자의 질의에 가장 유사한 답변 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와 같은 벡터스토어를 사용하면 벡터화된 데이터를 빠르게 검색하여 정확한 정보를 제공할 수 있습니다. 검색이 잘 이루어져야만 그다음 단계인 증강과 생성이 의미 있게 작동합니다.

브런치는 최신 브라우저에 최적화 되어있습니다. IE chrome safari