From 3a44514448eb5e2dabae46cf8ae738f998995cb8 Mon Sep 17 00:00:00 2001 From: bangae1 Date: Wed, 5 Nov 2025 21:57:45 +0900 Subject: [PATCH] =?UTF-8?q?=EB=A7=A4=EB=89=B4=EC=96=BC=20=EB=93=B1?= =?UTF-8?q?=EB=A1=9D=20=EB=B6=84=EB=A6=AC?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- README.md | 24 ++++++++++++ download_embed.py | 12 ------ manual.py | 32 ---------------- offline_manual.py => manual_offline.py | 35 +----------------- vector_transformer.py | 48 ++++++++++++++++++++++++ vector_transformer_offline.py | 51 ++++++++++++++++++++++++++ 6 files changed, 124 insertions(+), 78 deletions(-) create mode 100644 README.md rename offline_manual.py => manual_offline.py (66%) create mode 100644 vector_transformer.py create mode 100644 vector_transformer_offline.py diff --git a/README.md b/README.md new file mode 100644 index 0000000..21a8ee9 --- /dev/null +++ b/README.md @@ -0,0 +1,24 @@ +# pip offline download +pip download -r requirements.txt --no-binary :all: -d /path/to/download/dir + +# llm model download +HF CLI 설치 (처음 한 번만) + +pip install huggingface_hub + +로그인 (오프라인 사용 전 한 번만 필요) + +huggingface-cli login # 토큰 입력 (https://huggingface.co/settings/tokens) + +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 + +모델 로컬 저장 + +huggingface-cli download Qwen/Qwen3-0.6B --local-dir ./models/Qwen3-0.6B --local-dir-use-symlinks False + +# sentence-transformers model (chroma vector db) +from sentence_transformers import SentenceTransformer + +model = SentenceTransformer('all-MiniLM-L6-v2') + +model.save('./models/all-MiniLM-L6-v2') \ No newline at end of file diff --git a/download_embed.py b/download_embed.py index 05773c3..1fcb414 100644 --- a/download_embed.py +++ b/download_embed.py @@ -2,15 +2,3 @@ from sentence_transformers import SentenceTransformer model = SentenceTransformer('all-MiniLM-L6-v2') model.save('./models/all-MiniLM-L6-v2') -# # HF CLI 설치 (처음 한 번만) -# pip install huggingface_hub -# -# # 로그인 (오프라인 사용 전 한 번만 필요) -# huggingface-cli login # 토큰 입력 (https://huggingface.co/settings/tokens) -# -# # 모델 로컬 저장 -# huggingface-cli download Qwen/Qwen3-0.6B --local-dir ./models/Qwen3-0.6B --local-dir-use-symlinks False -# -# -# -# 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 \ No newline at end of file diff --git a/manual.py b/manual.py index 2cbb691..15868f6 100644 --- a/manual.py +++ b/manual.py @@ -11,15 +11,9 @@ from fastapi import FastAPI persist_directory = "./chroma_db" chroma_client = chromadb.PersistentClient(path=persist_directory) -# ✅ Chroma 전용 임베딩 함수 사용 (오류 방지) -sentence_transformer_ef = embedding_functions.SentenceTransformerEmbeddingFunction( - model_name="all-MiniLM-L6-v2" -) - # 컬렉션 생성 collection = chroma_client.get_or_create_collection( name="manuals", - embedding_function=sentence_transformer_ef # ← 여기가 핵심! ) _model = None @@ -38,32 +32,6 @@ def get_qwen_model() : ) return _model, _tokenizer -def init(job: str) : - print(f'{job} init start') - # 1. 문서 준비 (실제로는 PDF/Word 등에서 추출) - manuals = [ - "지출 결의서는 사용 목적, 금액, 일자, 증빙 서류를 반드시 첨부하여 전자 결재 시스템에 등록해야 합니다.", - "월말 마감은 매월 25일부터 시작되며, 모든 부서는 28일까지 비용 집행 내역을 최종 확정해야 합니다.", - "외화 송금은 반드시 외환관리부의 사전 승인을 받은 후 금융팀을 통해 진행되어야 하며, 계약서 사본을 첨부해야 합니다.", - "세금계산서는 발행일로부터 10일 이내에 ERP에 등록되지 않으면 비용 처리가 불가합니다.", - "장기자산(차량, 사무기기 등)은 매년 1월에 정기 감가상각 점검을 받아야 하며, 자산관리부서가 이를 주관합니다.", - "현금 보관은 원칙적으로 금지되며, 불가피한 경우는 금고 보관 후 당일 중 재무팀에 입금 처리해야 합니다.", - "연말 정산 대상 직원은 매년 12월 10일까지 개인 소득공제 자료를 인사 시스템에 제출해야 합니다.", - "예산 초과 지출은 사전에 재무부와 협의 후 예산 조정 승인을 받아야 하며, 미승인 시 결재가 거부됩니다.", - "재무 제표 초안은 분기 마감 후 5영업일 이내에 감사법인에 제출되어야 하며, 최종 승인은 CFO가 담당합니다.", - ] - - # 문서 ID 생성 및 추가 - doc_ids = [f"DOC_{job}_{i}" for i in range(len(manuals))] - # collection.add(documents=manuals, ids=doc_ids) - collection.add( - documents=manuals, - ids=doc_ids, - metadatas=[{"source": "fi_manual_v1.pdf", "version":1.0, "dept": job} for _ in doc_ids] - ) - - print(f'{job} init end') - # 3. 질의 처리 def query_and_summarize(job: str, query: str, top_k: int = 3): diff --git a/offline_manual.py b/manual_offline.py similarity index 66% rename from offline_manual.py rename to manual_offline.py index 8ca38cd..1b88308 100644 --- a/offline_manual.py +++ b/manual_offline.py @@ -15,15 +15,8 @@ EMBEDDING_MODEL_PATH = "./models/all-MiniLM-L6-v2" persist_directory = "./chroma_db" chroma_client = chromadb.PersistentClient(path=persist_directory) - -embedding_fn = embedding_functions.SentenceTransformerEmbeddingFunction( - model_name=EMBEDDING_MODEL_PATH, # ← 로컬 폴더 경로 가능 - device="cpu" -) - collection = chroma_client.get_or_create_collection( name="manuals", - embedding_function=embedding_fn ) _model = None @@ -47,32 +40,6 @@ def get_qwen_model() : ) return _model, _tokenizer -def init(job: str) : - print(f'{job} init start') - # 1. 문서 준비 (실제로는 PDF/Word 등에서 추출) - manuals = [ - "지출 결의서는 사용 목적, 금액, 일자, 증빙 서류를 반드시 첨부하여 전자 결재 시스템에 등록해야 합니다.", - "월말 마감은 매월 25일부터 시작되며, 모든 부서는 28일까지 비용 집행 내역을 최종 확정해야 합니다.", - "외화 송금은 반드시 외환관리부의 사전 승인을 받은 후 금융팀을 통해 진행되어야 하며, 계약서 사본을 첨부해야 합니다.", - "세금계산서는 발행일로부터 10일 이내에 ERP에 등록되지 않으면 비용 처리가 불가합니다.", - "장기자산(차량, 사무기기 등)은 매년 1월에 정기 감가상각 점검을 받아야 하며, 자산관리부서가 이를 주관합니다.", - "현금 보관은 원칙적으로 금지되며, 불가피한 경우는 금고 보관 후 당일 중 재무팀에 입금 처리해야 합니다.", - "연말 정산 대상 직원은 매년 12월 10일까지 개인 소득공제 자료를 인사 시스템에 제출해야 합니다.", - "예산 초과 지출은 사전에 재무부와 협의 후 예산 조정 승인을 받아야 하며, 미승인 시 결재가 거부됩니다.", - "재무 제표 초안은 분기 마감 후 5영업일 이내에 감사법인에 제출되어야 하며, 최종 승인은 CFO가 담당합니다.", - ] - - # 문서 ID 생성 및 추가 - doc_ids = [f"DOC_{job}_{i}" for i in range(len(manuals))] - # collection.add(documents=manuals, ids=doc_ids) - collection.add( - documents=manuals, - ids=doc_ids, - metadatas=[{"source": "fi_manual_v1.pdf", "version":1.0, "dept": job} for _ in doc_ids] - ) - - print(f'{job} init end') - # 3. 질의 처리 def query_and_summarize(job: str, query: str, top_k: int = 3): @@ -153,7 +120,7 @@ if __name__ == "__main__": # init(job="FI") # FI : 재무 HR : 인사 print(1) - user_query = "외화 송금 방법?" + # user_query = "외화 송금 방법?" # answer = query_and_summarize(job="FI", query=user_query) # print(answer) # 실행방법 uvicorn manual:app --reload \ No newline at end of file diff --git a/vector_transformer.py b/vector_transformer.py new file mode 100644 index 0000000..52b495d --- /dev/null +++ b/vector_transformer.py @@ -0,0 +1,48 @@ +# 2. 벡터 DB 설정 +import chromadb +from chromadb.utils import embedding_functions + +persist_directory = "./chroma_db" +chroma_client = chromadb.PersistentClient(path=persist_directory) + +# ✅ Chroma 전용 임베딩 함수 사용 (오류 방지) +sentence_transformer_ef = embedding_functions.SentenceTransformerEmbeddingFunction( + model_name="all-MiniLM-L6-v2" +) + +# 컬렉션 생성 +collection = chroma_client.get_or_create_collection( + name="manuals", + embedding_function=sentence_transformer_ef # ← 여기가 핵심! +) + +def init(job: str) : + print(f'{job} init start') + # 1. 문서 준비 (실제로는 PDF/Word 등에서 추출) + manuals = [ + "지출 결의서는 사용 목적, 금액, 일자, 증빙 서류를 반드시 첨부하여 전자 결재 시스템에 등록해야 합니다.", + "월말 마감은 매월 25일부터 시작되며, 모든 부서는 28일까지 비용 집행 내역을 최종 확정해야 합니다.", + "외화 송금은 반드시 외환관리부의 사전 승인을 받은 후 금융팀을 통해 진행되어야 하며, 계약서 사본을 첨부해야 합니다.", + "세금계산서는 발행일로부터 10일 이내에 ERP에 등록되지 않으면 비용 처리가 불가합니다.", + "장기자산(차량, 사무기기 등)은 매년 1월에 정기 감가상각 점검을 받아야 하며, 자산관리부서가 이를 주관합니다.", + "현금 보관은 원칙적으로 금지되며, 불가피한 경우는 금고 보관 후 당일 중 재무팀에 입금 처리해야 합니다.", + "연말 정산 대상 직원은 매년 12월 10일까지 개인 소득공제 자료를 인사 시스템에 제출해야 합니다.", + "예산 초과 지출은 사전에 재무부와 협의 후 예산 조정 승인을 받아야 하며, 미승인 시 결재가 거부됩니다.", + "재무 제표 초안은 분기 마감 후 5영업일 이내에 감사법인에 제출되어야 하며, 최종 승인은 CFO가 담당합니다.", + ] + + # 문서 ID 생성 및 추가 + doc_ids = [f"DOC_{job}_{i}" for i in range(len(manuals))] + # collection.add(documents=manuals, ids=doc_ids) + collection.add( + documents=manuals, + ids=doc_ids, + metadatas=[{"source": "fi_manual_v1.pdf", "version":1.0, "dept": job} for _ in doc_ids] + ) + + print(f'{job} init end') + + +if __name__ == "__main__": + # FI : 재무 HR : 인사 + init(job="FI") diff --git a/vector_transformer_offline.py b/vector_transformer_offline.py new file mode 100644 index 0000000..0ccf46c --- /dev/null +++ b/vector_transformer_offline.py @@ -0,0 +1,51 @@ +import chromadb +from chromadb.utils import embedding_functions + +# # === 경로 설정 (모두 로컬) === +EMBEDDING_MODEL_PATH = "./models/all-MiniLM-L6-v2" + +# 2. 벡터 DB 설정 +persist_directory = "./chroma_db" +chroma_client = chromadb.PersistentClient(path=persist_directory) + + +embedding_fn = embedding_functions.SentenceTransformerEmbeddingFunction( + model_name=EMBEDDING_MODEL_PATH, # ← 로컬 폴더 경로 가능 + device="cpu" +) + +collection = chroma_client.get_or_create_collection( + name="manuals", + embedding_function=embedding_fn +) + + +def init(job: str) : + print(f'{job} init start') + # 1. 문서 준비 (실제로는 PDF/Word 등에서 추출) + manuals = [ + "지출 결의서는 사용 목적, 금액, 일자, 증빙 서류를 반드시 첨부하여 전자 결재 시스템에 등록해야 합니다.", + "월말 마감은 매월 25일부터 시작되며, 모든 부서는 28일까지 비용 집행 내역을 최종 확정해야 합니다.", + "외화 송금은 반드시 외환관리부의 사전 승인을 받은 후 금융팀을 통해 진행되어야 하며, 계약서 사본을 첨부해야 합니다.", + "세금계산서는 발행일로부터 10일 이내에 ERP에 등록되지 않으면 비용 처리가 불가합니다.", + "장기자산(차량, 사무기기 등)은 매년 1월에 정기 감가상각 점검을 받아야 하며, 자산관리부서가 이를 주관합니다.", + "현금 보관은 원칙적으로 금지되며, 불가피한 경우는 금고 보관 후 당일 중 재무팀에 입금 처리해야 합니다.", + "연말 정산 대상 직원은 매년 12월 10일까지 개인 소득공제 자료를 인사 시스템에 제출해야 합니다.", + "예산 초과 지출은 사전에 재무부와 협의 후 예산 조정 승인을 받아야 하며, 미승인 시 결재가 거부됩니다.", + "재무 제표 초안은 분기 마감 후 5영업일 이내에 감사법인에 제출되어야 하며, 최종 승인은 CFO가 담당합니다.", + ] + + # 문서 ID 생성 및 추가 + doc_ids = [f"DOC_{job}_{i}" for i in range(len(manuals))] + # collection.add(documents=manuals, ids=doc_ids) + collection.add( + documents=manuals, + ids=doc_ids, + metadatas=[{"source": "fi_manual_v1.pdf", "version":1.0, "dept": job} for _ in doc_ids] + ) + + print(f'{job} init end') + +if __name__ == "__main__": + # FI : 재무 HR : 인사 + init(job="FI")