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` | |
| ```python | |
| # ๋ณ๊ฒฝ ์ : ์ด๋ฏธ์ง ๊ธฐ๋ฐ 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` | |
| ```python | |
| # ๋ฉํฐ๋ชจ๋ฌ ์ฒ๋ฆฌ ์ ๊ฑฐ, ํ ์คํธ ๊ธฐ๋ฐ์ผ๋ก ๋จ์ํ | |
| 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 ์์ด๋ ์๋ํ๋ ๊ตฌ์กฐํ๋ ์๋ต | |
| ```python | |
| 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` | |
| ```python | |
| 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` | |
| ```python | |
| 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` | |
| ```python | |
| test_queries = [ | |
| "23๋ฒ ๋ฌธ์ ์ ๋ต์ ๋ฌด์์ธ๊ฐ์?", | |
| "24๋ฒ ๋ฌธ์ ๋ฅผ ํ์ด์ฃผ์ธ์", | |
| "15๋ฒ ๋ฌธ์ ์ ๋ต์ ๊ตฌํด์ฃผ์ธ์", | |
| "23๋ฒ ๋ฌธ์ ์์ 5๊ฐ์ ๋ฌธ์๋ฅผ ์ผ๋ ฌ๋ก ๋์ดํ๋ ๊ฒฝ์ฐ์ ์๋?", | |
| "24๋ฒ ๋ฌธ์ ์์ P(B)์ ๊ฐ์?" | |
| ] | |
| ``` | |
| ### 4๋จ๊ณ: ์ฑ๊ณผ ํ์ธ | |
| #### 4.1 ์ฑ๊ณตํ ๊ธฐ๋ฅ๋ค | |
| - โ **PDF ํ ์คํธ ์ถ์ถ ์๋ฒฝ**: ์ค์ ์ํ ๋ฌธ์ ๋ด์ฉ ์ ํํ ์ถ์ถ | |
| - โ **๊ฒ์ ๊ธฐ๋ฅ ์๋ฒฝ**: ๊ด๋ จ ๋ฌธ์ ๋ค์ ์ ํํ ์ฐพ์๋ | |
| - โ **๋น ๋ฅธ ์ฒ๋ฆฌ**: ์ฆ์ ์๋ต (LLM ์์ด๋ ์๋) | |
| - โ **๊ตฌ์กฐํ๋ ์๋ต**: ๋ฌธ์ ๋ถ์๊ณผ ํด๊ฒฐ ๋ฐฉ๋ฒ ์ ์ | |
| - โ **์ ํํ ๋ฌธ์ ๋งค์นญ**: 23๋ฒ, 24๋ฒ, 15๋ฒ ๋ฌธ์ ์ ํํ ์ฐพ์ | |
| #### 4.2 ํ ์คํธ ๊ฒฐ๊ณผ | |
| - **๋ฌธ์ ์ ๋ก๋**: 12๊ฐ ์ฒญํฌ ์ฑ๊ณต | |
| - **๊ฒ์ ๊ฒฐ๊ณผ**: 5๊ฐ์ฉ ์ ํํ ๋ฐํ | |
| - **์๋ต ์๊ฐ**: ์ฆ์ (ํ ํฐ ID ๋ฌธ์ ํด๊ฒฐ๋จ) | |
| - **๋ฌธ์ ์ธ์**: ์ค์ ์ํ ๋ฌธ์ ๋ด์ฉ ์ ํํ ์ถ์ถ | |
| ## ๐ฏ ์ต์ข ์ฑ๊ณผ | |
| ### ํด๊ฒฐ๋ ๋ฌธ์ ๋ค | |
| 1. โ **ํ ํฐ ID ๋ฌธ์ **: ํ ์คํธ ๊ธฐ๋ฐ์ผ๋ก ํด๊ฒฐ | |
| 2. โ **PDF ํ ์คํธ ์ถ์ถ**: ์ค์ ๋ฌธ์ ๋ด์ฉ ์ถ์ถ ์ฑ๊ณต | |
| 3. โ **๋น ๋ฅธ ๊ฒ์ฆ**: ์์ ํ ์คํธ ๋ฐ์ดํฐ๋ก ์ฑ๊ณต | |
| 4. โ **๊ตฌ์กฐํ๋ ์๋ต**: ๋ฌธ์ ๋ถ์๊ณผ ํด๊ฒฐ ๋ฐฉ๋ฒ ํฌํจ | |
| ### ํ์ฌ ์ํ | |
| **"์์ ํ ์คํธ ๋ฐ์ดํฐ๋ก ๋น ๋ฅธ ๊ฒ์ฆ"** ๋ชฉํ ๋ฌ์ฑ! | |
| - 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 ์๋ต | |
| - **ํ์ฌ**: ๊ตฌ์กฐํ๋ ํ ์คํธ ์๋ต | |
| ## ๐ ๋ค์ ๋จ๊ณ ์ ์ | |
| 1. **GPU ์๋ฒ ๋ฐฐํฌ**: ํ์ฌ CPU ํ ์คํธ ์๋ฃ | |
| 2. **LLM ํตํฉ ๊ฐ์ **: ํ ํฐ ๋์ฝ๋ฉ ๋ฌธ์ ํด๊ฒฐ | |
| 3. **์ค์ ๋ฌธ์ ํด๊ฒฐ**: ์ํ ๋ฌธ์ ํ์ด ๋ฅ๋ ฅ ํฅ์ | |
| 4. **์ฑ๋ฅ ์ต์ ํ**: ๋ ํฐ ๋ฐ์ดํฐ์ ์ฒ๋ฆฌ |