OpenAI 모델을 활용한 데이터 임베딩을 위한 텍스트 분할 기법
2025-02-02 12:17:34텍스트 데이터 분할의 중요성
OpenAI의 임베딩 모델을 사용할 때 중요한 단계 중 하나는 텍스트 데이터를 적절하게 분할하는 것입니다. 텍스트-임베딩-3-스몰(text-embedding-3-small) 또는 텍스트-임베딩-아다-002(text-embedding-ada-002)와 같은 모델은 각 입력에 대해 토큰 수 제한이 있으며, 이러한 제한을 준수하기 위해 텍스트를 작은 조각으로 나누어야 합니다. 그러나 분할 작업은 단순히 모델의 토큰 제한을 맞추는 것을 넘어서 여러 중요성을 지닙니다.
- 컨텍스트 보존: 텍스트 내의 개념은 종종 여러 문장 또는 단락에 걸쳐져 있습니다. 적절한 텍스트 분할은 이러한 컨텍스트를 조각 간 경계에서도 보존할 수 있도록 합니다.
- 임베딩 품질 향상: 더 작은 크기의 잘 구조화된 조각은 텍스트의 의미를 더 잘 포착하는 임베딩 결과를 생성합니다.
- 성능 최적화: 작은 조각으로 데이터를 처리하면 API 한도를 초과하는 위험을 줄이고 처리 효율성을 향상시킬 수 있습니다.
텍스트 분할을 위한 베스트 프랙티스
토큰 기반 분할 사용하기
OpenAI 모델은 텍스트를 문자 대신 토큰으로 처리합니다. 토큰은 단어, 단어의 일부 또는 구두점으로 이뤄진 텍스트의 단위입니다. 토큰 기반으로 텍스트를 분할하면 모델의 제한을 확실히 준수할 수 있습니다.
최적의 조각 크기 설정
일반적으로 1000 토큰의 조각 크기를 시작점으로 설정하는 것이 좋습니다. 이 크기는 컨텍스트 보존과 계산 효율성의 균형을 맞춥니다.
중복 추가
조각의 경계에서 중요한 컨텍스트가 손실되지 않도록, 조각 크기의 20% 정도를 중복해서 추가합니다.
스마트 스플리터 사용
아이디어를 중간에 잘라내지 않도록, 텍스트를 문장이나 단락 등의 논리적 경계에서 나눕니다.
TypeScript로 텍스트 분할 구현
준비 단계
TypeScript 환경에서 텍스트 분할을 구현하기 위해 몇 가지 라이브러리를 설치해야 합니다.
npm install langchain tiktoken
langchain: 텍스트 스플리팅과 임베딩 작업에 유용한 유틸리티를 제공하는 라이브러리입니다.tiktoken: OpenAI의 공식 토크나이저로 정확한 토큰 카운팅을 도와줍니다.
토큰 기반 텍스트 분할을 통한 구현
import { RecursiveCharacterTextSplitter } from "langchain/text_splitter";
import { OpenAIEmbeddings } from "langchain/embeddings/openai";
import { encoding_for_model } from "tiktoken";
async function generateChunksAndEmbeddings(text: string) {
// Initialize tiktoken encoder for the embedding model
const encoder = encoding_for_model("text-embedding-3-small");
const textSplitter = new RecursiveCharacterTextSplitter({
chunkSize: 1000, // Maximum tokens per chunk
chunkOverlap: 200, // 20% overlap to preserve context
separators: ["\n\n", "\n", " ", ""], // Logical split points
lengthFunction: (text) => {
// Get accurate token count using tiktoken
const tokens = encoder.encode(text);
return tokens.length;
},
});
// Don't forget to free the encoder when done
encoder.free();
// Split the text into chunks
const chunks = await textSplitter.createDocuments([text]);
// Initialize OpenAI embeddings
const embeddings = new OpenAIEmbeddings({
modelName: "text-embedding-3-small",
});
// Generate embeddings for each chunk
const vectorStore = await embeddings.embedDocuments(
chunks.map((chunk) => chunk.pageContent)
);
return { chunks, vectorStore };
}
코드 분석
1. 토큰 카운팅
encoding_for_model("text-embedding-3-small")을 사용하여 빠르고 정확하게 토큰 수를 계산합니다. 정확한 토큰 카운팅은 조각이 모델의 토큰 제한을 준수하도록 도와줍니다.
2. 재귀적 문장 분할
문자, 단어, 문장 등 논리적 구분자를 기준으로 텍스트를 조각내어, 조각이 1000 토큰을 넘지 않고, 문맥이 잘 보존되도록 합니다.
3. 인코더 해제
encoder.free()를 통해 인코더 사용 후 메모리를 해제하는 것은 중요합니다.
4. 임베딩 생성
OpenAIEmbeddings를 사용하여 각 조각의 임베딩을 생성합니다. embedDocuments 메서드는 모든 조각을 처리하고 결과 임베딩을 반환합니다.
적용 방법
함수 generateChunksAndEmbeddings를 다음과 같이 사용하면 됩니다.
const text = `
OpenAI's embedding models are powerful tools for understanding and processing text.
They can be used for tasks like semantic search, clustering, and recommendation systems.
However, to use them effectively, you need to chunk your text data properly.
`;
const { chunks, vectorStore } = await generateChunksAndEmbeddings(text);
console.log("Chunks:", chunks);
console.log("Embeddings:", vectorStore);
이 방법이 효과적인 이유
토큰 기반 분할
모델의 토큰 한도를 충족하면서도 가장 의미 있는 조각을 만들어냅니다.
중복
조각 경계에서 컨텍스트를 유지합니다.
논리적 분할
문장이나 단락을 중간에 자르지 않도록 하여 텍스트의 의미 유지에 도움이 됩니다.
효율적 임베딩 생성
병렬로 조각을 처리하여 성능을 향상시킵니다.
결론
텍스트 데이터를 OpenAI 임베딩 모델로 처리할 때는, 분할 과정이 매우 중요합니다. 이 게시글에서 소개한 베스트 프랙티스를 따르면 데이터를 보다 효율적으로 처리할 수 있으며, 높은 품질의 임베딩을 얻을 수 있습니다. 제시한 TypeScript 구현은 상용 프로덕션에도 적합하며, 최신 도구인 langchain 및 tiktoken을 활용하여 정확한 분할과 토크나이제이션을 처리합니다.