AI 최적화하기: 청크 사이즈 조정

ZEDY·2025년 1월 20일
0

문서를 받고, 임베딩 처리를 할 때, 어떤 사이즈로 청크를 만들어야 가장 최적화가 될까?


문제 상황

벡터스토어 기반 검색 시스템에서 문서 임베딩 후, 사용자가 원하는 정보를 정확히 찾지 못하는 문제가 발생했다. 이는 검색 시스템에서 문서를 분할(청크)하는 방식이 최적화되지 않았기 때문일 가능성이 크다. 문서를 청크로 나누는 과정에서 크기와 중첩(오버랩) 설정이 검색 정확도와 문맥 유지에 큰 영향을 미치기 때문이다.

목표

청크 크기와 오버랩 설정을 다양하게 조정하여 최적의 설정을 찾고, 검색 결과의 정확도와 문맥 유지 정도를 평가.

문제 분석

  • 청크가 너무 작다면?
    - 문맥이 손실된다.
    • 단편적인 의미만 저장된다. (문맥X)
      즉, 결과적으로 검색 쿼리가 문맥적으로 관련된 결과를 찾지 못할 수 있다.
  • 청크가 너무 크다면?
    - 넓은 문맥을 포착하려고 하니, 세부 정보를 무시하고 일반적인 정보를 담는다.
    • 유사도 계산 시 관련도가 낮아질 수 있다.

최적화된 청크 크기를 어떻게 결정하는가?

나는 웹링크를 제공하면, 여기 웹링크에 들어가서 내용을 스크랩핑을 한 후, 임베딩 처리를 해 DB에 반영하는 흐름으로 로직을 짰다.
내가 주로 사용하는 웹링크는 회사의 뉴스룸이다.

  • 문서의 성격: 회사 뉴스룸에 올라오는 뉴스
  • 임베딩 모델: GoogleGenerativeAIEmbeddings(model="models/text-embedding-004")

뉴스 문서의 특성과 청크 크기의 관계

우선 뉴스 문서의 특성을 생각해보자면,
1) 짧은 단락으로 구성되어 문맥 단위가 비교적 명확하다.
2) 초반에는 중요한 정보를 요약하며, 이후에 세부 내용을 다룬다.
3) 키워드 중심으로 정보를 전달해, 검색 쿼리에 키워드가 중요한 역할을 한다.

그럼 이제 어떤 청크 크기를 설계해야 적합할까?
1) 문맥이 비교적 독립적인 뉴스 문서이기에, 청크 크기를 작게 설정을 해야 한다.
2) 문맥 연결을 위해 청크 간 중첩을 추가해야 한다. 각 청크의 끝에서 50~100 토큰 정도를 다음 청크에 포함시켜야 한다. 이 설정을 하면 계산 정확도가 향상된다.

임베딩 모델의 특성: GoogleGenerativeAIEmbeddings(model="models/text-embedding-004")

나는 무료로 쓸 수 있는 임베딩 모델을 사용하기 위해 이 모델을 선정하였다. 이 모델은 일반적으로 200~400 토큰 사이에서 가장 높은 성능을 발휘한다.

문제 해결

청크 크기를 여러개로 정하여 최적화 실험을 해보겠다.

우선 내가 사용하는 예시 웹링크를 기반으로 한 문장과 한 단락당 몇개의 토큰이 있는지 계산해보겠다.

import tiktoken

def calculate_tokens(text: str, model: str = "gpt-3.5-turbo") -> int:
    # 모델에 맞는 토크나이저 로드
    tokenizer = tiktoken.encoding_for_model(model)
    # 텍스트를 토큰으로 변환하고 토큰의 개수를 반환
    tokens = tokenizer.encode(text)
    return len(tokens)

# 사용 예제
text = "문장"
token_count = calculate_tokens(text)
print(f"Number of tokens: {token_count}")

이 코드를 실행시켜 내가 사용하는 문서의 전반적인 문장의 토큰 수를 계산해보았다.

  • 평균 문장 토큰 수: 약 40개
  • 단락당 토큰 수: 약 110개

청크 크기 최적화 전략

  1. 기본 청크 크기 설정: 200~300 토큰
  • GoogleGenerativeAIEmbeddings 모델의 최적 범위에 부합하는 크기.
  • 단락과 문장 구조를 고려했을 때, 단일 청크로 중요한 문맥을 포함하기 적합.
  1. 오버랩 설정: 50~75 토큰
  • 청크 간 문맥을 연결하여 정보 손실을 최소화.
  • 연속된 청크에서 문맥적인 흐름을 유지해 검색 정확도를 높임.
  1. 테스트 설계:
  • 다양한 청크 크기와 오버랩 조합을 설정하여 실험.
  • 결과로 반환된 문서에서 세부 정보와 문맥 유지 여부를 평가.

테스트

텍스트 데이터를 벡터화하고 검색 결과의 정확성을 높이기 위해 토큰(청크) 사이즈와 오버랩 크기를 최적화하는 것은 매우 중요하다. 따라서 동일한 문서를 임베딩하되, 토큰 사이즈와 오버랩 크기를 다르게 해 저장을 하고 동일한 질문을 주었다.

테스트 환경

  • 데이터베이스: FAISS 기반 벡터 스토어.
  • 임베딩 모델: Google Generative AI Embeddings (text-embedding-004).
  • 테스트 변수:
    • 토큰(청크) 크기: 200, 300, 400, 500.
    • 오버랩 크기: 50, 100, 150, 200.

테스트는 동일한 질문과 데이터를 기반으로 수행되었으며, 각 설정에서 반환된 검색 결과를 분석했다.

테스트 과정 (코드)

테스트 결과 분석

1. Chunk Size 200, Overlap 50

  • 장점:
    • 짧은 청크로 인해 세부 정보가 명확히 드러남.
  • 단점:
    • 문맥이 끊겨 정보 연결성이 부족.
  • 결과:
    • "With over 2,200 engineers..."와 같은 핵심 정보는 포함되지만, 배경 정보나 문맥은 부족.

2. Chunk Size 300, Overlap 100

  • 장점:
    • 세부 정보와 문맥 연결성이 균형을 이룸.
    • 중복된 정보가 최소화됨.
  • 단점:
    • 일부 긴 문맥이 잘릴 가능성.
  • 결과:
    • "With over 2,200 engineers..."와 "Founded in 2012..." 등 적합한 정보를 포함하며, 배경 설명도 유지.

3. Chunk Size 400, Overlap 150

  • 장점:
    • 긴 문맥을 포함하여 배경 정보를 잘 제공.
    • 중복된 정보가 최소화됨.
  • 단점:
    • 특정 키워드가 문맥 안에 묻힐 가능성.
  • 결과:
    • 배경 설명과 함께 주요 정보를 충실히 제공.

4. Chunk Size 500, Overlap 200

  • 장점:
    • 가장 긴 문맥을 유지하여 풍부한 배경 정보를 제공.
  • 단점:
    • 특정 세부 정보가 뭉개질 가능성.
    • 검색 결과에서 중요한 문장이 누락될 위험.
  • 결과:
    • "With over 2,200 engineers..."와 같은 주요 정보는 포함되지만, 불필요한 배경 정보가 포함될 가능성이 높음.

최적의 설정

설정: Chunk Size 300, Overlap 100

  • 이유:
    1. 세부 정보와 문맥 연결성의 균형이 뛰어남.
    2. 중복된 정보가 적으며, 검색 결과가 명확함.
    3. 질문에 적합한 정보를 빠르게 반환 가능.

결론

토큰 사이즈와 오버랩 크기의 최적화는 검색 결과의 품질을 좌우하는 핵심 요소다. 이번 테스트에서는 질문 중심의 검색에 Chunk Size 300, Overlap 100이 가장 적합한 설정으로 나타났다. 이 설정은 세부 정보와 문맥의 균형을 효과적으로 유지하며, 검색 효율성을 극대화한다.

앞으로 벡터 스토어를 활용한 검색 엔진 개발 시, 데이터 특성과 질문 유형에 따라 이러한 설정을 조정해야 한다. 무지성으로 남들이 좋다는 값으로 설정하는 것이 아닌, 데이터와 질문의 성격에 맞는 최적의 설정을 찾는 것이 성공적인 검색 시스템의 핵심임을 깨닫게 되었다.

profile
Spring Boot 백엔드 주니어 개발자

0개의 댓글

관련 채용 정보