CAFE

LLM/sLLM/SLM

OllamaChat + OllamaEmbeddings + FAISS(in-memory) + 한국어 PDF

작성자주인장|작성시간25.08.09|조회수20 목록 댓글 0

from langchain_ollama.chat_models import ChatOllama
from langchain_ollama.embeddings import OllamaEmbeddings
from langchain_community.document_loaders import PyPDFLoader
from langchain_text_splitters import RecursiveCharacterTextSplitter
from langchain_community.vectorstores import FAISS
from langchain_core.prompts import ChatPromptTemplate
from langchain_core.output_parsers import StrOutputParser

# 0) 한국어 PDF 로드
loader = PyPDFLoader("docs/sample-ko.pdf")   # PDF 경로
pages = loader.load()

# 1) 텍스트 청크 분할(토큰 대신 '문자 길이' 기준)
splitter = RecursiveCharacterTextSplitter(
    chunk_size=800,      # 한글은 문자 기준 600~1200 사이가 무난
    chunk_overlap=120,
    length_function=len  # tiktoken 대신 문자 길이 사용
)
docs = splitter.split_documents(pages)
print("청크 개수:", len(docs))
print("예시 청크 길이:", len(docs[0].page_content))

# 2) 임베딩 (Ollama — bge-m3 권장)
emb = OllamaEmbeddings(
    model="bge-m3",                # 멀티링구얼 무료 임베딩
    base_url="http://localhost:11434",
)

# 3) 벡터DB: FAISS (in-memory)
vectorstore = FAISS.from_documents(docs, embedding=emb)
retriever = vectorstore.as_retriever(search_kwargs={"k": 4})

# 4) 챗 모델 (Ollama)
llm = ChatOllama(
    model="ko_model",               # 사용 중인 한글 모델 태그
    base_url="http://localhost:11434",
    temperature=0.2,
    model_kwargs={"num_ctx": 4096}  # 문맥창(컨텍스트) 여유
)

# 5) RAG 프롬프트 + 체인
prompt = ChatPromptTemplate.from_messages([
    ("system", "다음 '컨텍스트'만 근거로 한국어로 정확히 답해. 모르면 모른다고 말해."),
    ("human", "질문: {question}\n\n컨텍스트:\n{context}")
])

def format_docs(dlist):
    return "\n\n".join(d.page_content for d in dlist)

chain = (
    {"context": retriever | format_docs, "question": lambda x: x["question"]}
    | prompt
    | llm
    | StrOutputParser()
)

# 6) 질의
q = "문서의 핵심 요점을 3줄로 요약해줘."
print(chain.invoke({"question": q}))

다음검색
현재 게시글 추가 기능 열기

댓글

댓글 리스트
맨위로

카페 검색

카페 검색어 입력폼