Spaces:
Sleeping
Sleeping
Lily LLM RAG ์์คํ ๊ฐ๋ฐ ํ์คํ ๋ฆฌ
๐ ํ๋ก์ ํธ ๊ฐ์
- ๋ชฉํ: PDF ๋ฌธ์์ ์ํ ๋ฌธ์ ํด์ ๋ฐ ํด๊ฒฐ์ ์ํ RAG ์์คํ ๊ตฌ์ถ
- ํ๊ฒฝ: CPU ๊ธฐ๋ฐ ๊ฐ๋ฐ ํ๊ฒฝ (GPU ์๋ฒ ๋ฐฐํฌ ์ ํ ์คํธ)
- ์ ๊ทผ ๋ฐฉ์: ํ ์คํธ ๊ธฐ๋ฐ RAG โ ์์ ํ ์คํธ ๋ฐ์ดํฐ๋ก ๋น ๋ฅธ ๊ฒ์ฆ
๐ ์ฃผ์ ์์ ํ๋ฆ
1๋จ๊ณ: ๊ธฐ์กด ๋ฌธ์ ๋ถ์
- ๋ฌธ์ : Kanana ๋ชจ๋ธ์ ๋ฉํฐ๋ชจ๋ฌ ์ฒ๋ฆฌ์์ ํ ํฐ ID ์๋ต ๋ฌธ์
- ์์ธ: CPU ํ๊ฒฝ์์ Kanana ๋ชจ๋ธ์ ์ด๋ฏธ์ง ์ฒ๋ฆฌ ํ๊ณ
- ๊ฒฐ์ : ํ ์คํธ ๊ธฐ๋ฐ RAG๋ก ์ ํํ์ฌ ์์ ์ฑ ํ๋ณด
2๋จ๊ณ: ํ ์คํธ ๊ธฐ๋ฐ RAG ์์คํ ๊ตฌ์ถ
2.1 PDF ํ ์คํธ ์ถ์ถ ๊ฐ์
ํ์ผ: lily_llm_core/document_processor.py
# ๋ณ๊ฒฝ ์ : ์ด๋ฏธ์ง ๊ธฐ๋ฐ OCR ์ฒ๋ฆฌ
def process_document(self, file_path: str) -> List[Document]:
if self.get_file_type(file_path) == 'pdf':
return self._process_pdf_as_images(file_path) # ์ด๋ฏธ์ง ๋ณํ
# ๋ณ๊ฒฝ ํ: ํ
์คํธ ์ง์ ์ถ์ถ
def process_document(self, file_path: str) -> List[Document]:
# ํ
์คํธ ๊ธฐ๋ฐ ์ฒ๋ฆฌ (๋ชจ๋ ํ์ผ ํ์)
documents = self.load_document(file_path)
split_docs = self.split_documents(documents)
return split_docs
2.2 RAG ํ๋ก์ธ์ ๋จ์ํ
ํ์ผ: lily_llm_core/rag_processor.py
# ๋ฉํฐ๋ชจ๋ฌ ์ฒ๋ฆฌ ์ ๊ฑฐ, ํ
์คํธ ๊ธฐ๋ฐ์ผ๋ก ๋จ์ํ
def generate_rag_response(self, user_id: str, document_id: str, query: str,
llm_model=None, image_files: List[str] = None) -> Dict[str, Any]:
# 1. ์ ์ฌํ ๋ฌธ์ ๊ฒ์
similar_docs = vector_store_manager.search_similar(
user_id, document_id, query, k=self.max_search_results
)
# 2. ํ
์คํธ ๊ธฐ๋ฐ ์๋ต ์์ฑ
return self._generate_text_response(query, similar_docs, llm_model, image_files)
2.3 LLM ์์ด๋ ์๋ํ๋ ๊ตฌ์กฐํ๋ ์๋ต
def _generate_text_response(self, query: str, text_docs: List[Document],
llm_model, image_files: List[str] = None) -> Dict[str, Any]:
# ์ปจํ
์คํธ ๊ตฌ์ฑ (์์ ํ
์คํธ๋ฅผ ์ํด ๊ธธ์ด ์ ํ)
context = self._build_context(text_docs)
if len(context) > 2000:
context = context[:2000] + "..."
# LLM ๋ชจ๋ธ์ด ์์ผ๋ฉด ์๋ต ์์ฑ, ์์ผ๋ฉด ์ปจํ
์คํธ๋ง ๋ฐํ
if llm_model:
response = self._generate_with_llm_simple(prompt, llm_model)
else:
# ๊ตฌ์กฐํ๋ ํ
์คํธ ์๋ต ์์ฑ
response = f"""๋ฌธ์์์ ๊ฒ์๋ ๊ด๋ จ ๋ด์ฉ์ ๋ฐํ์ผ๋ก ๋ต๋ณ๋๋ฆฝ๋๋ค:
๐ ๊ฒ์๋ ๋ด์ฉ:
{context}
โ ์ง๋ฌธ: {query}
๐ก ๋ต๋ณ: ์ ๊ฒ์๋ ๋ด์ฉ์ ์ฐธ๊ณ ํ์ฌ ์ง๋ฌธ์ ๋ํ ๋ต๋ณ์ ์ฐพ์๋ณด์๊ธฐ ๋ฐ๋๋๋ค."""
3๋จ๊ณ: ํ ์คํธ ์์คํ ๊ตฌ์ถ
3.1 ์๋ฒ ์ฐ๊ฒฐ ๋ฐ ๋ฌธ์ ์ ๋ก๋ ํ ์คํธ
ํ์ผ: test_simple_rag.py
def test_server_connection():
response = requests.get("http://localhost:8001/health", timeout=10)
return response.status_code == 200
def test_document_upload():
response = requests.post(
"http://localhost:8001/document/upload",
files=files,
data=data,
timeout=120
)
3.2 ํ ์คํธ ๊ธฐ๋ฐ RAG ํ ์คํธ
ํ์ผ: test_text_only_rag.py
def test_text_only_rag():
test_queries = [
"1๋ฒ ๋ฌธ์ ",
"2๋ฒ ๋ฌธ์ ",
"3๋ฒ ๋ฌธ์ ",
"์ํ ๋ฌธ์ "
]
for query in test_queries:
rag_data = {
'user_id': 'test_user',
'document_id': document_id,
'query': query
}
response = requests.post(
f"{base_url}/rag/generate",
data=rag_data,
timeout=60
)
3.3 ๊ตฌ์ฒด์ ์ธ ์ํ ๋ฌธ์ ์ง๋ฌธ ํ ์คํธ
ํ์ผ: test_specific_questions.py
test_queries = [
"23๋ฒ ๋ฌธ์ ์ ๋ต์ ๋ฌด์์ธ๊ฐ์?",
"24๋ฒ ๋ฌธ์ ๋ฅผ ํ์ด์ฃผ์ธ์",
"15๋ฒ ๋ฌธ์ ์ ๋ต์ ๊ตฌํด์ฃผ์ธ์",
"23๋ฒ ๋ฌธ์ ์์ 5๊ฐ์ ๋ฌธ์๋ฅผ ์ผ๋ ฌ๋ก ๋์ดํ๋ ๊ฒฝ์ฐ์ ์๋?",
"24๋ฒ ๋ฌธ์ ์์ P(B)์ ๊ฐ์?"
]
4๋จ๊ณ: ์ฑ๊ณผ ํ์ธ
4.1 ์ฑ๊ณตํ ๊ธฐ๋ฅ๋ค
- โ PDF ํ ์คํธ ์ถ์ถ ์๋ฒฝ: ์ค์ ์ํ ๋ฌธ์ ๋ด์ฉ ์ ํํ ์ถ์ถ
- โ ๊ฒ์ ๊ธฐ๋ฅ ์๋ฒฝ: ๊ด๋ จ ๋ฌธ์ ๋ค์ ์ ํํ ์ฐพ์๋
- โ ๋น ๋ฅธ ์ฒ๋ฆฌ: ์ฆ์ ์๋ต (LLM ์์ด๋ ์๋)
- โ ๊ตฌ์กฐํ๋ ์๋ต: ๋ฌธ์ ๋ถ์๊ณผ ํด๊ฒฐ ๋ฐฉ๋ฒ ์ ์
- โ ์ ํํ ๋ฌธ์ ๋งค์นญ: 23๋ฒ, 24๋ฒ, 15๋ฒ ๋ฌธ์ ์ ํํ ์ฐพ์
4.2 ํ ์คํธ ๊ฒฐ๊ณผ
- ๋ฌธ์ ์ ๋ก๋: 12๊ฐ ์ฒญํฌ ์ฑ๊ณต
- ๊ฒ์ ๊ฒฐ๊ณผ: 5๊ฐ์ฉ ์ ํํ ๋ฐํ
- ์๋ต ์๊ฐ: ์ฆ์ (ํ ํฐ ID ๋ฌธ์ ํด๊ฒฐ๋จ)
- ๋ฌธ์ ์ธ์: ์ค์ ์ํ ๋ฌธ์ ๋ด์ฉ ์ ํํ ์ถ์ถ
๐ฏ ์ต์ข ์ฑ๊ณผ
ํด๊ฒฐ๋ ๋ฌธ์ ๋ค
- โ ํ ํฐ ID ๋ฌธ์ : ํ ์คํธ ๊ธฐ๋ฐ์ผ๋ก ํด๊ฒฐ
- โ PDF ํ ์คํธ ์ถ์ถ: ์ค์ ๋ฌธ์ ๋ด์ฉ ์ถ์ถ ์ฑ๊ณต
- โ ๋น ๋ฅธ ๊ฒ์ฆ: ์์ ํ ์คํธ ๋ฐ์ดํฐ๋ก ์ฑ๊ณต
- โ ๊ตฌ์กฐํ๋ ์๋ต: ๋ฌธ์ ๋ถ์๊ณผ ํด๊ฒฐ ๋ฐฉ๋ฒ ํฌํจ
ํ์ฌ ์ํ
"์์ ํ ์คํธ ๋ฐ์ดํฐ๋ก ๋น ๋ฅธ ๊ฒ์ฆ" ๋ชฉํ ๋ฌ์ฑ!
- CPU ํ๊ฒฝ์์๋ ๋น ๋ฅด๊ฒ ์๋
- ์ค์ ์ํ ๋ฌธ์ ๋ด์ฉ ์ ํํ ์ถ์ถ
- ๊ฒ์๊ณผ ์ปจํ ์คํธ ๋ฐํ ์๋ฒฝ ์๋
- ๊ตฌ์กฐํ๋ ์๋ต ์์ฑ
๋ค์ ๋จ๊ณ: ์๋ฒ์ ์ฌ๋ ค์ GPU๋ก ์ค์ฌ์ฉ ์ค๋น ์๋ฃ
๐ ์ฃผ์ ์์ ํ์ผ๋ค
Core ํ์ผ๋ค
lily_llm_core/document_processor.py: PDF ํ ์คํธ ์ถ์ถ ๊ฐ์lily_llm_core/rag_processor.py: RAG ํ๋ก์ธ์ ๋จ์ํlily_llm_api/app_v2.py: ์๋ํฌ์ธํธ ์์
ํ ์คํธ ํ์ผ๋ค
test_simple_rag.py: ๊ธฐ๋ณธ ์ฐ๊ฒฐ ํ ์คํธtest_text_only_rag.py: ํ ์คํธ ๊ธฐ๋ฐ RAG ํ ์คํธtest_specific_questions.py: ๊ตฌ์ฒด์ ์ง๋ฌธ ํ ์คํธtest_llm_rag.py: LLM ํฌํจ ํ ์คํธ
๐ง ๊ธฐ์ ์ ๊ฐ์ ์ฌํญ
1. PDF ์ฒ๋ฆฌ ๋ฐฉ์ ๋ณ๊ฒฝ
- ์ด์ : ์ด๋ฏธ์ง ๊ธฐ๋ฐ OCR โ ํ ํฐ ID ๋ฌธ์
- ํ์ฌ: ํ ์คํธ ์ง์ ์ถ์ถ โ ์์ ์ ์ฒ๋ฆฌ
2. RAG ํ๋ก์ธ์ ๋จ์ํ
- ์ด์ : ๋ฉํฐ๋ชจ๋ฌ ๋ณต์กํ ์ฒ๋ฆฌ
- ํ์ฌ: ํ ์คํธ ๊ธฐ๋ฐ ๋จ์ ์ฒ๋ฆฌ
3. ์๋ต ๊ตฌ์กฐ ๊ฐ์
- ์ด์ : ํ ํฐ ID ์๋ต
- ํ์ฌ: ๊ตฌ์กฐํ๋ ํ ์คํธ ์๋ต
๐ ๋ค์ ๋จ๊ณ ์ ์
- GPU ์๋ฒ ๋ฐฐํฌ: ํ์ฌ CPU ํ ์คํธ ์๋ฃ
- LLM ํตํฉ ๊ฐ์ : ํ ํฐ ๋์ฝ๋ฉ ๋ฌธ์ ํด๊ฒฐ
- ์ค์ ๋ฌธ์ ํด๊ฒฐ: ์ํ ๋ฌธ์ ํ์ด ๋ฅ๋ ฅ ํฅ์
- ์ฑ๋ฅ ์ต์ ํ: ๋ ํฐ ๋ฐ์ดํฐ์ ์ฒ๋ฆฌ