매우 큰 문서를 요약하는 데에는 여전히 몇 가지 제한 사항이 있습니다. 이러한 영향을 완화하는 몇 가지 방법은 다음과 같습니다.
저자 Usama Jamil은 LangChain 및 OpenAI를 사용하여 대용량 문서를 요약하는 방법을 번역했습니다 .
대규모 언어 모델을 사용하면 챗봇 만들기, 언어 번역, 텍스트 요약 등과 같은 많은 작업이 더 쉬워집니다. 우리는 요약을 위해 모델을 작성했는데 항상 성능 문제가 있었습니다. 이제 LLM(대형 언어 모델)을 사용하여 이를 쉽게 수행 할 수 있습니다. 예를 들어, 최첨단(SOTA) LLM은 이미 컨텍스트 창 내에서 전체 도서를 처리할 수 있습니다. 그러나 매우 큰 문서를 요약하는 데에는 여전히 몇 가지 제한 사항이 있습니다.
대용량 문서 요약에 대한 LLM 제한 사항
LLM의 컨텍스트 제한 또는 컨텍스트 길이는 모델이 처리할 수 있는 토큰 수를 나타냅니다. 각 모델에는 최대 마크 또는 마크 제한이라고도 하는 고유한 컨텍스트 길이가 있습니다. 예를 들어 표준 GPT-4 모델의 컨텍스트 길이는 128,000개 토큰입니다. 해당 태그 수보다 많은 정보가 손실됩니다. 일부 SOTA LLM에는 최대 1백만 개의 태그로 컨텍스트 제한이 있습니다. 그러나 상황적 제약이 증가함에 따라 LLM은 최근성과 우선성과 같은 한계로 어려움을 겪습니다. 또한 이러한 영향을 완화하는 방법을 탐구할 수도 있습니다.
- LLM의 우선성 효과는 모델이 시퀀스 시작 부분에 제시된 정보에 더 중점을 둔다는 것을 의미합니다.
- 최신 효과는 모델이 처리하는 최신 정보를 강조하는 경우입니다.
이러한 효과는 모두 모델을 입력 데이터의 특정 부분으로 편향시킵니다. 모델은 시퀀스 중간에 중요한 정보를 건너뛸 수 있습니다.
두 번째 문제는 비용이다. 텍스트를 분할하여 컨텍스트 제약의 첫 번째 문제를 해결할 수 있지만 책 전체를 모델에 직접 전달할 수는 없습니다. 비용이 많이 듭니다. 예를 들어 태그가 100만 개 있는 책이 있고 이를 GPT4 모델에 직접 전달한 경우 총 비용은 약 90달러(힌트 및 완성 태그)가 됩니다. 우리는 가격, 맥락적 제약, 책의 전체 맥락을 고려하여 텍스트를 요약하는 절충적인 방법을 찾아야 했습니다.
이 튜토리얼에서는 모델의 가격과 상황적 제약을 고려하여 책 전체를 요약하는 방법을 배우게 됩니다. 시작하자.
환경 설정
이 튜토리얼을 따르려면 다음이 필요합니다.
- 파이썬이 설치됨
- IDE(VS Code 작동)
종속성을 설치하려면 터미널을 열고 다음 명령을 입력하십시오.
pip install langchain openai tiktoken fpdf2 pandas
이 명령은 필요한 모든 종속성을 설치합니다.
책 로드
이 프로젝트에 사용하기 위해 출판된 Charles Dickens의 David Copperfield를 사용하게 됩니다. LangChain에서 제공하는 PyPDFLoader를 사용하여 이 책을 로드해 보겠습니다.
from langchain.document_loaders import PyPDFLoader
# Load the book
loader = PyPDFLoader("David-Copperfield.pdf")
pages = loader.load_and_split()
책 전체를 로드하지만 우리는 내용 부분에만 관심이 있습니다. 머리말이나 소개 같은 페이지는 건너뛸 수 있습니다.
# Cut out the open and closing parts
pages = pages[6:1308]
# Combine the pages, and replace the tabs with spaces
text = ' '.join([page.page_content.replace('\t', ' ') for page in pages]
이제 콘텐츠가 생겼습니다. 처음 200자를 인쇄해 보겠습니다.
전처리
인쇄할 수 없는 문자, 불필요한 공백 등 텍스트에서 불필요한 내용을 제거해 보겠습니다.
import re
def clean_text(text):
# Remove the specific phrase 'Free eBooks at Planet eBook.com' and surrounding whitespace
cleaned_text = re.sub(r'\s*Free eBooks at Planet eBook\.com\s*', '', text, flags=re.DOTALL)
# Remove extra spaces
cleaned_text = re.sub(r' +', ' ', cleaned_text)
# Remove non-printable characters, optionally preceded by 'David Copperfield'
cleaned_text = re.sub(r'(David Copperfield )?[\x00-\x1F]', '', cleaned_text)
# Replace newline characters with spaces
cleaned_text = cleaned_text.replace('\n', ' ')
# Remove spaces around hyphens
cleaned_text = re.sub(r'\s*-\s*', '', cleaned_text)
return cleaned_text
clean_text=clean_text(text)
데이터를 정리 한 후 요약 문제를 살펴볼 수 있습니다.
OpenAI API 로드
OpenAI API를 사용하기 전에 여기에서 이를 구성하고 자격 증명을 제공해야 합니다.
import os
os.environ["OPENAI_API_KEY"] = "your-openai-key-here"
여기에 API 키를 입력하면 환경 변수가 설정됩니다.
이 책에 몇 개의 태그가 있는지 살펴보겠습니다.
from langchain import OpenAI
llm = OpenAI()
Tokens = llm.get_num_tokens(clean_text)
print (f"We have {Tokens} tokens in the book")
책에는 466,000개 이상의 마커가 있으며, 이를 모두 LLM에 직접 전달하면 많은 비용이 청구됩니다. 따라서 비용을 줄이기 위해 K-평균 클러스터링을 구현하여 책에서 중요한 덩어리를 추출하겠습니다.
참고 : K-평균 클러스터링을 사용하기로 한 결정은 데이터 전문가 Greg Kamradt의 튜토리얼 에서 영감을 받았습니다 .
책의 중요한 부분을 파악하기 위해 먼저 책을 여러 덩어리로 나누어 보겠습니다.
콘텐츠를 문서로 분할
우리는 책 내용을 문서로 분할하기 위해 LangChain의 SemanticChunker 유틸리티를 사용할 것입니다.
from langchain_experimental.text_splitter import SemanticChunker
from langchain_openai.embeddings import OpenAIEmbeddings
text_splitter = SemanticChunker(
OpenAIEmbeddings(), breakpoint_threshold_type="interquartile"
)
docs = text_splitter.create_documents([clean_text])
SemanticChunker는 두 개의 매개변수를 받습니다. 첫 번째는 임베딩 모델입니다. 이 모델에서 생성된 임베딩은 의미론을 기반으로 텍스트를 분할하는 데 사용됩니다. 두 번째는 의미론적 유사성에 따라 텍스트를 여러 청크로 분할해야 하는 지점을 결정하는 breakpoint_threshold_type입니다.
참고: 이러한 더 작고 의미상 유사한 청크를 처리함으로써 LLM의 최근성 및 우선성 효과를 최소화하는 것을 목표로 합니다. 이 전략을 통해 모델은 각각의 작은 컨텍스트를 보다 효율적으로 처리하여 보다 균형 잡힌 해석과 응답 생성을 보장할 수 있습니다.
각 문서에 대한 임베드 찾기
이제 생성된 각 문서를 임베딩해 보겠습니다. OpenAI 기본 방법을 사용하여 임베딩을 얻습니다.
import numpy as np
import openai
def get_embeddings(text):
response = openai.embeddings.create(
model="text-embedding-3-small",
input=text
)
return response.data
embeddings=get_embeddings([doc.page_content for doc in docs]
get_embeddings
메소드는 모든 문서에 대한 임베딩을 제공할 수 있습니다.
OpenAI는 특히 저렴하고 빠른 것으로 간주되는 text-embedding-3-small 방법을 출시했습니다.
데이터 재배열
다음으로, 쉬운 데이터 처리 및 분석을 위해 문서 콘텐츠 목록과 해당 임베딩을 pandas DataFrame으로 변환합니다 .
import pandas as pd
content_list = [doc.page_content for doc in docs]
df = pd.DataFrame(content_list, columns=['page_content'])
vectors = [embedding.embedding for embedding in embeddings]
array = np.array(vectors)
embeddings_series = pd.Series(list(array))
df['embeddings'] = embeddings_series
Faiss를 사용한 효율적인 클러스터링
이제 문서 벡터를 Faiss 호환 형식으로 변환하고 K-평균을 사용하여 50개 그룹으로 클러스터링한 다음 문서 간의 효율적인 유사성 검색을 위해 Faiss 인덱스를 생성합니다.
import numpy as np
import faiss
# Convert to float32 if not already
array = array.astype('float32')
num_clusters = 50
# Vectors dimensionality
dimension = array.shape[1]
# Train KMeans with Faiss
kmeans = faiss.Kmeans(dimension, num_clusters, niter=20, verbose=True)
kmeans.train(array)
# Directly access the centroids
centroids = kmeans.centroids
# Create a new index for the original dataset
index = faiss.IndexFlatL2(dimension)
# Add original dataset to the index
index.add(array)
이 K-평균 클러스터링은 문서를 50개 그룹으로 그룹화합니다.
참고 : K-평균 클러스터링을 선택하는 이유는 클러스터의 모든 문서에 관련 임베딩이 있으므로 각 클러스터가 유사한 콘텐츠 또는 유사한 컨텍스트를 가지며 코어에 가장 가까운 문서를 선택하기 때문입니다.
가져오기 문서 선택
이제 각 클러스터에서 가장 중요한 문서만 선택하겠습니다. 이를 위해 중심에 가장 가까운 첫 번째 벡터만 선택합니다.
D, I = index.search(centroids, 1)
이 코드는 인덱스의 검색 방법을 사용하여 중심 목록의 각 중심에 가장 가까운 문서를 찾습니다. 두 개의 배열을 반환합니다.
- D는 가장 가까운 문서와 각 문서의 중심까지의 거리를 포함합니다.
- I, 이러한 최근 문서의 색인이 포함되어 있습니다. 검색 방법의 두 번째 매개변수 1은 각 중심에 대해 가장 가까운 단일 문서만 찾도록 지정합니다.
이제 문서가 책 순서대로 정렬되도록 선택한 문서 색인을 정렬해야 합니다.
sorted_array = np.sort(I, axis=0)
sorted_array=sorted_array.flatten()
extracted_docs = [docs[i] for i in sorted_array]
각 문서의 요약 보기
다음 단계는 GPT-4 모델을 사용하여 각 문서의 요약을 얻어 비용을 절약하는 것입니다. GPT-4를 사용하기 위해 모델을 정의합니다.
model = ChatOpenAI(temperature=0,model="gpt-4")
힌트를 정의하고 LangChain을 사용하여 힌트 템플릿을 만들어 모델에 전달합니다.
from langchain_core.output_parsers import StrOutputParser
from langchain_openai import ChatOpenAI
from langchain_core.prompts import ChatPromptTemplate
prompt = ChatPromptTemplate.from_template("""
You will be given different passages from a book one by one. Provide a summary of the following text. Your result must be detailed and atleast 2 paragraphs. When summarizing, directly dive into the narrative or descriptions from the text without using introductory phrases like 'In this passage'. Directly address the main events, characters, and themes, encapsulating the essence and significant details from the text in a flowing narrative. The goal is to present a unified view of the content, continuing the story seamlessly as if the passage naturally progresses into the summary.
Passage:
```{text}```
SUMMARY:
"""
)
이 프롬프트 템플릿은 모델이 문서를 보다 효과적이고 효율적으로 요약하는 데 도움이 됩니다.
다음 단계는 LCEL(LangChain Expression Language)을 사용하여 LangChain 체인을 정의하는 것입니다.
chain= (
prompt
| model
|StrOutputParser() )
요약 체인은 StrOutputParser를 사용하여 출력을 구문 분석합니다. 탐색할 수 있는 다른 출력 파서 가 있습니다 .
최종적으로 각 문서에 정의된 체인을 적용하여 요약을 얻을 수 있습니다.
from tqdm import tqdm
final_summary = ""
for doc in tqdm(extracted_docs, desc="Processing documents"):
# Get the new summary.
new_summary = chain2.invoke({"text": doc.page_content})
# Update the list of the last two summaries: remove the first one and add the new one at the end.
final_summary+=new_summary
위의 코드는 각 문서에 체인을 하나씩 적용하고 각 요약을 final_summary에 연결합니다.
초록을 PDF로 저장
다음 단계는 요약 형식을 지정하고 PDF로 저장하는 것입니다.
from fpdf import FPDF
class PDF(FPDF):
def header(self):
# Select Arial bold 15
self.set_font('Arial', 'B', 15)
# Move to the right
self.cell(80)
# Framed title
self.cell(30, 10, 'Summary', 1, 0, 'C')
# Line break
self.ln(20)
def footer(self):
# Go to 1.5 cm from bottom
self.set_y(-15)
# Select Arial italic 8
self.set_font('Arial', 'I', 8)
# Page number
self.cell(0, 10, 'Page %s' % self.page_no(), 0, 0, 'C')
# Instantiate PDF object and add a page
pdf = PDF()
pdf.add_page()
pdf.set_font("Arial", size=12)
# Ensure the 'last_summary' text is treated as UTF-8
# Replace 'last_summary' with your actual text variable if different
# Make sure your text is a utf-8 encoded string
last_summary_utf8 = last_summary.encode('latin-1', 'replace').decode('latin-1')
pdf.multi_cell(0, 10, last_summary_utf8)
# Save the PDF to a file
pdf_output_path = "s_output1.pdf"
pdf.output(pdf_output_path)
그래서 여기에 책의 전체 요약이 PDF 형식으로 나와 있습니다.
결론적으로
이 튜토리얼에서는 LLM을 사용하여 전체 책과 같은 큰 텍스트를 요약하는 동시에 상황 제약 및 비용과 관련된 문제를 해결하는 복잡성을 살펴봅니다. 우리는 텍스트 전처리 단계를 배웠고 모델의 상황적 제약을 효과적으로 관리하기 위해 의미론적 청킹과 K-평균 클러스터링을 결합한 전략을 구현했습니다.
효율적인 클러스터링을 사용하여 핵심 문단을 효과적으로 추출하여 방대한 양의 텍스트를 직접 처리하는 오버헤드를 줄입니다. 이 접근 방식은 처리되는 토큰 수를 최소화하여 비용을 크게 절감할 뿐만 아니라 LLM에 내재된 최신성 및 우선성 효과를 완화하여 모든 텍스트 구절에 대한 균형 잡힌 고려를 보장합니다.
LLM의 API를 통한 AI 애플리케이션 개발은 많은 주목을 받고 있으며, 여기서 벡터 데이터베이스는 컨텍스트 임베딩의 효율적인 저장 및 검색을 제공함으로써 중요한 역할을 합니다.
MyScaleDB 는 비용, 정확성, 속도를 포함한 모든 요소를 고려하여 AI 애플리케이션용으로 특별히 설계된 벡터 데이터베이스입니다. SQL 친화적인 인터페이스를 통해 개발자는 새로운 지식을 배울 필요 없이 AI 애플리케이션 개발을 시작할 수 있습니다.
오픈 소스 Hongmeng을 포기하기로 결정했습니다 . 오픈 소스 Hongmeng의 아버지 Wang Chenglu: 오픈 소스 Hongmeng은 중국에서 유일하게 기초 소프트웨어 분야의 건축 혁신 산업 소프트웨어 행사입니다. OGG 1.0이 출시되고 Huawei는 모든 소스 코드를 제공합니다. Google 리더가 "코드 똥 산"에 의해 사망했습니다 Ubuntu 24.04 LTS 공식 출시 Fedora Linux 40 공식 출시 전에 Microsoft 개발자 : Windows 11 성능이 "어리석을 정도로 나쁩니다", Ma Huateng과 Zhou Hongyi가 악수하며 "원한을 제거합니다" 유명 게임 회사가 새로운 규정을 발표했습니다. 직원의 결혼 선물은 10만 위안을 초과할 수 없습니다. 핀둬둬는 부정 경쟁 혐의로 판결을 받았습니다. 보상금은 500만 위안입니다.이 기사는 Yunyunzhongsheng ( https://yylives.cc/ ) 에 처음 게재되었습니다 . 누구나 방문하실 수 있습니다.