고급 RAG 기술 1부: 데이터 처리

RAG 성능을 향상시킬 수 있는 기술을 논의하고 구현합니다. 2부 중 1부에서는 고급 RAG 파이프라인의 데이터 처리 및 수집 구성 요소에 초점을 맞춥니다.

벡터 검색부터 강력한 REST API까지, Elasticsearch는 개발자에게 가장 폭넓은 검색 도구 키트를 제공합니다. GitHub의 샘플 노트북을 살펴보고 새로운 기능을 시험해 보세요. 무료 체험판을 시작하거나 지금 바로 Elasticsearch를 로컬에서 실행할 수도 있습니다.

고급 RAG 기법에 대한 탐험의 1부입니다. 2부를 보려면 여기를 클릭하세요!

최근 논문 ' 검색 증강 세대의 모범 사례 찾기 '에서는 RAG의 모범 사례 집합으로 수렴하는 것을 목표로 다양한 RAG 향상 기술의 효과를 실증적으로 평가하고 있습니다.

검색 품질을 개선하기 위해 제안된 몇 가지 모범 사례, 즉 문장 청킹, HyDE, 리버스 패킹을 구현해 보겠습니다.

간결성을 위해 효율성 향상에 초점을 맞춘 기술 (쿼리 분류 및 요약)은 생략하겠습니다.

또한 다루지 않았지만 개인적으로 유용하고 흥미로웠던 몇 가지 기술 (메타데이터 포함, 복합 다중 필드 임베딩, 쿼리 강화)도 구현할 예정입니다.

마지막으로 간단한 테스트를 실행하여 검색 결과 및 생성된 답변의 품질이 기준선에 비해 개선되었는지 확인합니다. 시작해보자!

RAG 개요

RAG는 외부 지식 기반에서 정보를 검색하여 생성된 답변을 풍부하게 함으로써 LLM을 향상시키는 것을 목표로 합니다. 도메인별 정보를 제공함으로써 LLM은 학습 데이터의 범위를 벗어난 사용 사례에 빠르게 적응할 수 있으며, 미세 조정보다 훨씬 저렴하고 최신 상태로 유지하기 쉽습니다.

RAG의 품질을 개선하기 위한 조치는 일반적으로 두 가지 트랙에 중점을 둡니다:

  1. 지식창고의 품질과 명확성을 향상시킵니다.
  2. 검색 쿼리의 범위와 구체성 개선.

이 두 가지 조치를 통해 LLM이 관련 사실과 정보에 접근할 수 있는 확률을 높이고, 따라서 오래되었거나 관련성이 없는 자신의 지식에 의존하거나 착각할 가능성을 줄이려는 목표를 달성할 수 있습니다.

방법의 다양성은 몇 문장으로 명확히 설명하기 어렵습니다. 더 명확하게 설명하기 위해 바로 구현으로 넘어가겠습니다.

목차

설정

모든 코드는 Searchlabs 리포지토리에서찾을 수 있습니다.

먼저 해야 할 일이 있습니다. 다음이 필요합니다:

  1. Elastic Cloud 배포
  2. LLM API - 이 노트북에서는 Azure OpenAI에서 GPT-4o 배포를 사용하고 있습니다.
  3. Python 버전 3.12.4 이상

main.ipynb 노트북에서모든 코드를 실행할 것입니다.

계속해서 리포지토리를 git으로 복제하고 supporting-blog-content/advanced-rag-techniques로 이동한 다음 다음 명령을 실행합니다:

이 작업이 완료되면 .env 파일을 만듭니다. 파일을 열고 다음 필드를 채웁니다( .env.example에서 참조). 유용한 의견을 주신 공동 저자 Claude-3.5에게 감사의 마음을 전합니다.

다음으로 수집할 문서를 선택하고 문서 폴더에 넣습니다. 이 글에서는 Elastic N.V. 연례 보고서 2023을 사용하겠습니다. 꽤 도전적이고 밀도가 높은 문서로, RAG 기술을 스트레스 테스트하기에 적합합니다.

이제 모든 준비가 완료되었으니 인제스트로 이동해 보겠습니다. main.ipynb를 열고 처음 두 셀을 실행하여 모든 패키지를 가져오고 모든 서비스를 초기화합니다.

맨 위로 돌아가기

문서 수집, 처리 및 임베드하기

데이터 수집

  • 개인적 의견: 저는 라마인덱스의 편리함에 놀랐습니다. LLM과 라마인덱스가 나오기 전에는 다양한 형식의 문서를 수집하려면 여기저기서 난해한 패키지를 수집해야 하는 번거로운 과정이 필요했습니다. 이제 단일 함수 호출로 축소되었습니다. 야생.

SimpleDirectoryReaderdirectory_path. 파일에 있는 모든 문서를 로드합니다. .pdf 파일의 경우 문서 개체 목록을 반환하는데, 저는 작업하기 쉽다고 판단하여 Python 사전으로 변환합니다.

각 사전에는 text 필드에 주요 콘텐츠가 포함되어 있습니다. 또한 페이지 번호, 파일 이름, 파일 크기 및 유형과 같은 유용한 메타데이터도 포함되어 있습니다.

맨 위로 돌아가기

문장 수준의 토큰 단위 청킹

가장 먼저 해야 할 일은 일관성과 관리 용이성을 위해 문서를 표준 길이의 덩어리로 줄이는 것입니다. 임베딩 모델에는 고유한 토큰 제한(처리할 수 있는 최대 입력 크기)이 있습니다. 토큰은 모델이 처리하는 텍스트의 기본 단위입니다. 정보 손실(내용 잘림 또는 누락)을 방지하기 위해 긴 텍스트를 더 작은 세그먼트로 분할하여 이러한 제한을 초과하지 않는 텍스트를 제공해야 합니다.

청크는 성능에 상당한 영향을 미칩니다. 이상적으로는 각 청크가 독립된 정보를 나타내며 단일 주제에 대한 맥락 정보를 캡처하는 것이 좋습니다. 청킹 방법에는 단어 수에 따라 문서를 분할하는 단어 수준 청킹과 LLM을 사용하여 논리적 중단점을 식별하는 시맨틱 청킹이 있습니다.

단어 단위 청크는 저렴하고 빠르며 쉽지만 문장이 분리되어 문맥이 깨질 위험이 있습니다. 시맨틱 청크는 특히 116페이지에 달하는 Elastic 연례 보고서와 같은 문서를 처리하는 경우 속도가 느려지고 비용이 많이 듭니다.

중간 접근 방식을 선택해 보겠습니다. 문장 수준 청킹은 여전히 간단하지만 단어 수준 청킹보다 훨씬 저렴하고 빠르면서 문맥을 더 효과적으로 보존할 수 있습니다. 또한 슬라이딩 창을 구현하여 주변 문맥을 일부 캡처하고 단락 분할의 영향을 완화할 것입니다.

Chunker 클래스는 임베딩 모델의 토큰라이저를 받아 텍스트를 인코딩하고 디코딩합니다. 이제 20개의 토큰이 겹치는 512개씩의 토큰 덩어리를 만들겠습니다. 이를 위해 텍스트를 문장으로 분할하고, 해당 문장을 토큰화한 다음 토큰 한도를 초과하지 않고 더 이상 추가할 수 없을 때까지 토큰화된 문장을 현재 청크에 추가합니다.

마지막으로 임베드할 원본 텍스트로 문장을 다시 디코딩하여 original_text 라는 필드에 저장합니다. 청크는 chunk 라는 필드에 저장됩니다. 노이즈(일명 쓸모없는 문서)를 줄이기 위해 길이가 50토큰보다 작은 문서는 모두 폐기합니다.

문서에서 실행해 보겠습니다:

그리고 다음과 같은 텍스트 덩어리를 다시 가져옵니다:

맨 위로 돌아가기

메타데이터 포함 및 생성

문서를 정리했습니다. 이제 데이터를 보강할 차례입니다. 추가 메타데이터를 생성하거나 추출하고 싶습니다. 이 추가 메타데이터는 검색 성능에 영향을 미치고 향상시키는 데 사용할 수 있습니다.

문서 목록(파이썬 사전)과 프로세서 함수 목록을 받는 역할을 하는 DocumentEnricher 클래스를 정의하겠습니다. 이러한 함수는 문서의 original_text 열을 통해 실행되고 출력을 새 필드에 저장합니다.

먼저 TextRank를 사용하여 키프레이즈를 추출합니다. TextRank는 단어 간의 관계에 따라 중요도에 순위를 매겨 텍스트에서 핵심 구문과 문장을 추출하는 그래프 기반 알고리즘입니다.

다음으로 GPT-4o를 사용하여 potential_questions를 생성하겠습니다.

마지막으로 Spacy를 사용하여 엔티티를 추출합니다.

각 코드에 대한 설명은 상당히 길고 복잡하기 때문에 여기서는 반복하지 않겠습니다. 관심이 있으시다면 아래 코드 샘플에 파일이 표시되어 있습니다.

데이터 보강을 실행해 보겠습니다:

그리고 결과를 살펴보세요:

TextRank로 추출한 키프레이즈

이러한 키문구는 청크의 핵심 주제를 대신하는 역할을 합니다. 쿼리가 사이버 보안과 관련이 있는 경우 이 항목의 점수가 높아집니다.

GPT-4o에서 생성된 잠재적 질문

이러한 잠재적 질문은 사용자 쿼리와 직접적으로 일치하여 점수를 높일 수 있습니다. 현재 청크에 있는 정보를 사용하여 답변할 수 있는 질문을 생성하라는 메시지를 GPT-4o에 표시합니다.

Spacy에서 추출한 엔티티

이러한 엔티티는 키프레이즈와 유사한 용도로 사용되지만 키프레이즈 추출이 놓칠 수 있는 조직 및 개인 이름을 캡처합니다.

맨 위로 돌아가기

복합 멀티필드 임베딩

이제 추가 메타데이터로 문서를 보강했으므로 이 정보를 활용하여 더욱 강력하고 컨텍스트를 인식하는 임베딩을 만들 수 있습니다.

프로세스의 현재 시점을 다시 한 번 살펴보겠습니다. 각 문서에는 네 가지 관심 분야가 있습니다.

각 필드는 문서의 컨텍스트에 대한 다른 관점을 나타내며, 잠재적으로 LLM이 집중해야 할 핵심 영역을 강조할 수 있습니다.

이러한 각 필드를 임베딩한 다음 복합 임베딩이라고 하는 임베딩의 가중치 합계를 생성하는 것이 계획입니다.

운이 좋으면 이 복합 임베딩을 통해 검색 동작을 제어하는 또 다른 조정 가능한 하이퍼파라미터를 도입하는 것 외에도 시스템이 컨텍스트를 더 잘 인식할 수 있게 됩니다.

먼저, main.ipynb 노트북의 시작 부분에서 가져온 로컬로 정의된 임베딩 모델을 사용해 각 필드를 임베드하고 각 문서를 제자리에 업데이트해 보겠습니다.

각 임베딩 함수는 _embedding 접두사가 붙은 원래 입력 필드인 임베딩의 필드를 반환합니다.

이제 컴포지트 임베딩의 가중치를 정의해 보겠습니다:

가중치를 사용하면 사용 사례와 데이터의 품질에 따라 각 구성 요소에 우선순위를 지정할 수 있습니다. 직관적으로 이러한 가중치의 크기는 각 구성 요소의 시맨틱 값에 따라 달라집니다. 청크 텍스트 자체가 가장 풍부하기 때문에 가중치를 70% 으로 지정합니다. 엔티티가 가장 작고 조직 또는 사람 이름의 목록에 불과하므로 가중치를 5% 로 할당합니다. 이러한 값에 대한 정확한 설정은 사용 사례별로 경험적으로 결정해야 합니다.

마지막으로 가중치를 적용하는 함수를 작성하고 복합 임베딩을 만들어 보겠습니다. 공간을 절약하기 위해 모든 컴포넌트 임베딩도 삭제할 것입니다.

이것으로 문서 처리를 완료했습니다. 이제 다음과 같은 문서 개체 목록이 생겼습니다:

Elastic으로 인덱싱

Elastic Search에 문서를 대량으로 업로드해 보겠습니다. 이를 위해 저는 오래 전에 elastic_helpers.py 에서 Elastic Helper 함수 집합을 정의했습니다. 코드가 매우 길기 때문에 함수 호출을 살펴보는 데 집중하겠습니다.

es_bulk_indexer.bulk_upload_documents 는 모든 사전 개체 목록에서 작동하며, Elasticsearch의 편리한 동적 매핑을 활용합니다.

Kibana로 이동하여 모든 문서가 색인되었는지 확인합니다. 224개가 있어야 합니다. 이렇게 큰 문서치고는 나쁘지 않습니다!

맨 위로 돌아가기

고양이 휴식

잠시만요, 기사가 좀 무겁네요, 알아요. 내 고양이를 확인하세요:

사랑스러워요. 모자가 없어져서 어딘가에 훔쳐서 숨겨둔 것 같아요 :(

여기까지 오신 것을 축하드립니다 :)

2부에서는 RAG 파이프라인의 테스트 및 평가에 대해 알아보세요!

부록

정의

1. 문장 청크

  • RAG 시스템에서 텍스트를 의미 있는 작은 단위로 나누기 위해 사용되는 전처리 기법입니다.
  • 프로세스:
    1. 입력: 큰 텍스트 블록(예: 문서, 단락)
    2. 출력: 작은 텍스트 세그먼트(일반적으로 문장 또는 작은 문장 그룹)
  • 목적:
    • 상황에 맞는 세분화된 텍스트 세그먼트 생성
    • 보다 정확한 색인 및 검색 가능
    • RAG 시스템에서 검색된 정보의 관련성 향상
  • 특성:
    • 세그먼트는 의미론적으로 의미가 있습니다.
    • 독립적으로 색인 및 검색 가능
    • 독립형 이해성을 보장하기 위해 일부 컨텍스트를 보존하는 경우가 많습니다.
  • 이점:
    • 검색 정밀도 향상
    • RAG 파이프라인에서 보다 집중적인 증강 지원

2. HyDE(가상 문서 임베딩)

  • LLM을 사용하여 RAG 시스템에서 쿼리 확장을 위한 가상의 문서를 생성하는 기술입니다.
  • 프로세스:
    1. LLM에 쿼리 입력
    2. LLM은 쿼리에 대한 가상의 문서를 생성합니다.
    3. 생성된 문서 임베드
    4. 벡터 검색에 임베딩 사용
  • 주요 차이점:
    • 기존 RAG: 쿼리를 문서와 일치시킵니다.
    • HyDE: 문서와 문서 매칭
  • 목적:
    • 특히 복잡하거나 모호한 쿼리의 검색 성능 향상
    • 짧은 쿼리보다 더 풍부한 의미론적 컨텍스트 캡처
  • 이점:
    • LLM의 지식을 활용하여 쿼리를 확장합니다.
    • 검색된 문서의 연관성을 잠재적으로 개선할 수 있습니다.
  • 도전 과제:
    • 추가 LLM 추론이 필요하므로 지연 시간과 비용이 증가합니다.
    • 성능은 생성된 가상 문서의 품질에 따라 달라집니다.

3. 역포장

  • 검색 결과를 LLM으로 전달하기 전에 순서를 바꾸기 위해 RAG 시스템에서 사용되는 기술입니다.
  • 프로세스:
    1. 검색 엔진(예: Elasticsearch)은 관련성 내림차순으로 문서를 반환합니다.
    2. 순서가 뒤바뀌어 가장 관련성이 높은 문서가 마지막에 배치됩니다.
  • 목적:
    • 해당 맥락에서 최신 정보에 더 집중하는 경향이 있는 LLM의 최신성 편향을 악용합니다.
    • LLM의 컨텍스트 창에서 가장 관련성 높은 정보가 "최신" 되도록 합니다.
  • 예시: 원래 순서: [가장 관련성 높음, 두 번째 높음, 세 번째 높음, ...] 반전된 순서: [..., 세 번째로 많이, 두 번째로 많이, 가장 관련성 높음]

4. 쿼리 분류

  • 쿼리에 RAG가 필요한지 아니면 LLM이 직접 답변할 수 있는지 판단하여 RAG 시스템 효율성을 최적화하는 기술입니다.
  • 프로세스:
    1. 사용 중인 LLM에 맞는 사용자 지정 데이터 세트 개발
    2. 전문 분류 모델 훈련
    3. 모델을 사용하여 수신 쿼리 분류하기
  • 목적:
    • 불필요한 RAG 처리를 방지하여 시스템 효율성 향상
    • 가장 적절한 응답 메커니즘으로 직접 쿼리 보내기
  • 요구 사항:
    • LLM 전용 데이터 세트 및 모델
    • 정확성 유지를 위한 지속적인 개선 사항
  • 이점:
    • 간단한 쿼리에 대한 계산 오버헤드 감소
    • RAG가 아닌 쿼리에 대한 응답 시간 개선 가능성

5. 요약

  • RAG 시스템에서 검색된 문서를 압축하는 기술입니다.
  • 프로세스:
    1. 관련 문서 검색
    2. 각 문서에 대한 간결한 요약 생성
    3. RAG 파이프라인에서 전체 문서 대신 요약 사용
  • 목적:
    • 필수 정보에 집중하여 RAG 성능 향상
    • 관련성이 낮은 콘텐츠로 인한 노이즈 및 간섭 감소
  • 이점:
    • 잠재적으로 LLM 응답의 관련성 향상
    • 컨텍스트 제한 내에서 더 많은 문서를 포함할 수 있습니다.
  • 도전 과제:
    • 요약에서 중요한 세부 정보가 손실될 위험
    • 요약 생성을 위한 추가 계산 오버헤드

6. 메타데이터 포함

  • 추가 컨텍스트 정보로 문서를 보강하는 기술입니다.
  • 메타데이터의 유형:
    • 키문구
    • 제목
    • 날짜
    • 저작자 세부 정보
    • 블러브
  • 목적:
    • RAG 시스템에서 사용할 수 있는 컨텍스트 정보 증가
    • LLM에게 문서 콘텐츠와 관련성에 대한 보다 명확한 이해 제공
  • 이점:
    • 잠재적으로 검색 정확도 향상
    • 문서 유용성을 평가하는 LLM의 능력 향상
  • 구현:
    • 문서 전처리 중에 수행 가능
    • 추가 데이터 추출 또는 생성 단계가 필요할 수 있습니다.

7. 복합 멀티필드 임베딩

  • 다양한 문서 구성 요소에 대해 별도의 임베딩을 생성하는 RAG 시스템용 고급 임베딩 기술입니다.
  • 프로세스:
    1. 관련 필드 식별(예: 제목, 키문구, 광고 문구, 주요 콘텐츠)
    2. 각 필드에 대해 별도의 임베딩을 생성합니다.
    3. 검색에 사용할 수 있도록 이러한 임베딩을 결합하거나 저장하세요.
  • 표준 접근 방식과의 차이점:
    • 기존: 전체 문서에 대한 단일 임베딩
    • 합성: 다양한 문서 측면을 위한 다중 임베딩
  • 목적:
    • 보다 미묘하고 컨텍스트를 인식하는 문서 표현 만들기
    • 문서 내에서 더 다양한 소스의 정보를 캡처하세요.
  • 이점:
    • 모호하거나 다면적인 쿼리의 성능을 잠재적으로 개선합니다.
    • 검색 시 다양한 문서 측면에 보다 유연한 가중치를 부여할 수 있습니다.
  • 도전 과제:
    • 임베딩 스토리지 및 검색 프로세스의 복잡성 증가
    • 보다 정교한 매칭 알고리즘이 필요할 수 있습니다.

8. 쿼리 강화

  • 검색 범위를 개선하기 위해 관련 용어로 원래 쿼리를 확장하는 기술입니다.
  • 프로세스:
    1. 원본 쿼리 분석
    2. 동의어 및 의미적으로 연관된 구문 생성하기
    3. 다음 추가 용어를 사용하여 쿼리를 보강하세요.
  • 목적:
    • 문서 말뭉치에서 잠재적인 일치 범위 늘리기
    • 특정 언어 또는 기술 용어가 포함된 쿼리의 검색 성능 향상
  • 이점:
    • 원래 쿼리 용어와 정확히 일치하지 않는 관련 문서를 검색할 수 있습니다.
    • 쿼리와 문서 간의 어휘 불일치를 극복하는 데 도움이 될 수 있습니다.
  • 도전 과제:
    • 신중하게 구현하지 않을 경우 쿼리 드리프트 위험
    • 검색 프로세스에서 계산 오버헤드가 증가할 수 있습니다.

맨 위로 돌아가기

관련 콘텐츠

최첨단 검색 환경을 구축할 준비가 되셨나요?

충분히 고급화된 검색은 한 사람의 노력만으로는 달성할 수 없습니다. Elasticsearch는 여러분과 마찬가지로 검색에 대한 열정을 가진 데이터 과학자, ML 운영팀, 엔지니어 등 많은 사람들이 지원합니다. 서로 연결하고 협력하여 원하는 결과를 얻을 수 있는 마법 같은 검색 환경을 구축해 보세요.

직접 사용해 보세요