Ollama 사용법
명령어
설치
curl -fsSL https://ollama.com/install.sh | sh
모델 다운로드 (Pull)
https://ollama.com/
에서 Docker Hub 처럼 모델을 다운로드(Pull) 할 수 있다.
# ollama pull <model>
ollama pull llama3
모델 실행
# ollama run <model>
ollama run llama3
현재 로컬의 모델 조회
ollama list
HuggingFace 의 gguf 모델을 Ollama 로 실행하기
HuggingFace 에 업로드된 gguf 모델을 Ollama 를 이용해 로컬에서 돌려봅니다.
gguf?
- GGUF(Georgi Gerganov Unified Format)
- 오픈소스 모델을 로컬 환경에서 쉽고 빠르게 실행할 수 있는 파일 형식
- GGML을 사용하여 대형 모델을 실행하는 프로그램과 모델을 저장하는 파일 형식
- GGML : 컴퓨터에서도 큰 모델을 빠르게 돌릴 수 있는 ML용 라이브러리
- 모델을 빠르고 쉽게 불러오고 저장할 수 있게 해주는 바이너리(0, 1) 형식으로 설계됨
- 개발자들은 보통 PyTorch 같은 프로그래밍 도구를 사용해 모델을 만든 후, GGML에서 쓸 수 있도록 GGUF 형식으로 저장한다
1. gguf 모델 다운로드
# wget <허깅페이스 모델 url>
wget https://huggingface.co/teddylee777/Llama-3-Open-Ko-8B-gguf/resolve/main/Llama-3-Open-Ko-8B-Q8_0.gguf
2. GGUF 파일 경로에 Modelfile 파일 작성
FROM Llama-3-Open-Ko-8B-Q8_0.gguf
TEMPLATE """{{- if .System }}
<s>{{ .System }}</s>
{{- end }}
<s>Human:
{{ .Prompt }}</s>
<s>Assistant:
"""
SYSTEM """A chat between a curious user and an artificial intelligence assistant. The assistant gives helpful, detailed, and polite answers to the user's questions."""
PARAMETER temperature 0
PARAMETER num_predict 3000
PARAMETER num_ctx 4096
PARAMETER stop <s>
PARAMETER stop </s>
3. 모델 생성(추가)
# ollama create <생성 및 실행할 모델명> -f Modelfile
ollama create llama3-ko -f Modelfile
이렇게 생성한 모델을 ollama run llama3-ko
와 같이 즉시 실행할 수도 있고
RAG 등과 함께 사용할 때 다음 코드 형태로 사용할 수도 있다.
from langchain_community.chat_models import ChatOllama
# Ollama 를 이용해 로컬에서 LLM 실행
model = ChatOllama(model="llama3-ko")
Llama3-KO 를 이용해 RAG 를 구현
RAG 에 사용할 PDF로 근로기준법을 다운로드하여 사용했습니다.
https://www.law.go.kr/법령/근로기준법
필요한 라이브러리 임포트
import os
import warnings
warnings.filterwarnings("ignore")
Text(PDF) Loader
from langchain_community.document_loaders import PyMuPDFLoader
# PyMuPDFLoader 을 이용해 PDF 파일 로드
loader = PyMuPDFLoader("labor_low.pdf")
pages = loader.load()
TextSplitter
from langchain.text_splitter import RecursiveCharacterTextSplitter
# 문서를 문장으로 분리
## 청크 크기 500, 각 청크의 50자씩 겹치도록 청크를 나눈다
text_splitter = RecursiveCharacterTextSplitter(
chunk_size=500,
chunk_overlap=50,
)
docs = text_splitter.split_documents(pages)
Text Vector Embedding
from langchain.embeddings import HuggingFaceEmbeddings
# 문장을 임베딩으로 변환하고 벡터 저장소에 저장
embeddings = HuggingFaceEmbeddings(
model_name='BAAI/bge-m3',
#model_kwargs={'device':'cpu'},
model_kwargs={'device':'cuda'},
encode_kwargs={'normalize_embeddings':True},
)
VectorStore(Chroma)
# 벡터 저장소 생성
from langchain.vectorstores import Chroma
vectorstore = Chroma.from_documents(docs, embeddings)
# 벡터 저장소 경로 설정
## 현재 경로에 'vectorstore' 경로 생성
vectorstore_path = 'vectorstore'
os.makedirs(vectorstore_path, exist_ok=True)
# 벡터 저장소 생성 및 저장
vectorstore = Chroma.from_documents(docs, embeddings, persist_directory=vectorstore_path)
# 벡터스토어 데이터를 디스크에 저장
vectorstore.persist()
print("Vectorstore created and persisted")
Model
from langchain_community.chat_models import ChatOllama
# Ollama 를 이용해 로컬에서 LLM 실행
## llama3-ko-instruct 모델 다운로드는 Ollama 사용법 참조
model = ChatOllama(model="llama3-ko-instruct", temperature=0)
Retriever
retriever = vectorstore.as_retriever(search_kwargs={'k': 3})
LangChain
from langchain_core.runnables import RunnablePassthrough
from langchain_core.output_parsers import StrOutputParser
from langchain_core.prompts import ChatPromptTemplate
# Prompt 템플릿 생성
template = '''친절한 챗봇으로서 상대방의 요청에 최대한 자세하고 친절하게 답하자. 모든 대답은 한국어(Korean)으로 대답해줘.":
{context}
Question: {question}
'''
prompt = ChatPromptTemplate.from_template(template)
def format_docs(docs):
return '\n\n'.join([d.page_content for d in docs])
# RAG Chain 연결
rag_chain = (
{'context': retriever | format_docs, 'question': RunnablePassthrough()}
| prompt
| model
| StrOutputParser()
)
# Chain 실행
query = "연장근로수당에 대해 알려 줘"
answer = rag_chain.invoke(query)
print("Query:", query)
print("Answer:", answer)
Output
teddylee777/Llama-3-Open-Ko-8B-gguf 모델
- Answer: 연장근로수당은 근로기준법 제56조에 따라 통상임금의 50%를 가산하여 지급해야 합니다
teddylee777/Llama-3-Open-Ko-8B-Instruct-preview-gguf 모델
- Answer: 연장근로수당은 주휴일에 지급됩니다.
제71조(연장근로수당) ① 사용자는 근로시간을 초과하여 근로한 경우에는 그 초과된 시간에 대하여 연장근로수당을 지급하여야 한다. 다만, 다음 각 호의 어느 하나에 해당하는 경우에는 그러하지 아니하다.
1. 「근로기준법」 제56조제2항에 따라 휴일근로를 한 경우
2. 「근로기준법」 제57조제2항에 따라 야간근로를 한 경우
3. 「근로기준법」 제58조제2항에 따라 휴일에 근로한 경우
4. 「근로기준법」 제59조제2항에 따라 휴일근로 및 야간근로를 한 경우
- Answer: 연장근로수당은 주휴일에 지급됩니다.
chroma db import 방법 업데이트
from langchain_community.vectorstores.chroma import Chroma
Chroma.max_marginal_relevance_search() 와 Chroma.search() 의 차이점
Chroma.max_marginal_relevance_search()와
Chroma.search()`는 모두 Chroma 벡터 데이터베이스에서 문서를 검색하는 데 사용되는 함수이지만, 다음과 같은 주요 차이점이 있습니다.
1. 검색 방식:
Chroma.max_marginal_relevance_search():
- 최대 여변 관련성(MMR) 검색 알고리즘을 사용하여 검색합니다.
- 검색 쿼리와 유사하면서 서로 중복되지 않는 문서를 찾는 데 중점을 둡니다.
- 쿼리와 유사한 상위 N개의 문서를 반환합니다.
Chroma.search():
- 여백 검색(cosine similarity) 알고리즘을 사용하여 검색합니다.
- 검색 쿼리와 가장 유사한 문서를 찾는 데 중점을 둡니다.
- 쿼리와 가장 유사한 단일 문서를 반환합니다.
2. 반환 값:
Chroma.max_marginal_relevance_search():
- 검색 결과 문서 리스트를 반환합니다. 각 문서는
id
,embedding
,score
(관련성 점수) 속성을 포함하는 사전 또는 객체 형식입니다.
- 검색 결과 문서 리스트를 반환합니다. 각 문서는
Chroma.search():
- 검색 결과 문서를 반환합니다. 문서는
id
,embedding
,score
(관련성 점수) 속성을 포함하는 사전 또는 객체 형식입니다.
- 검색 결과 문서를 반환합니다. 문서는
3. 사용 예시:
Chroma.max_marginal_relevance_search():
# Chroma 벡터 데이터베이스 생성 및 문서 추가 (이전 코드 생략) ...
# 검색 쿼리 설정
query = "검색 쿼리 내용"
# MMR 검색 수행
results = vectorstore.max_marginal_relevance_search(query, k=10)
# 검색 결과 출력
for result in results:
print(f"문서 ID: {result['id']}")
print(f"관련성 점수: {result['score']}")
print(f"문서 내용: {result['page_content']}")
print("----------------------")
Chroma.search():
# Chroma 벡터 데이터베이스 생성 및 문서 추가 (이전 코드 생략) ...
# 검색 쿼리 설정
query = "검색 쿼리 내용"
# 여백 검색 수행
result = vectorstore.search(query)
# 검색 결과 출력
print(f"문서 ID: {result['id']}")
print(f"유사도: {result['score']}")
print(f"문서 내용: {result['page_content']}")
print("----------------------")
4. 결론:
- **Chroma.max_marginal_relevance_search()**는 쿼리와 유사하면서 서로 중복되지 않는 문서를 빠르게 찾는 데 적합합니다.
- **Chroma.search()**는 쿼리와 가장 유사한 단일 문서를 찾는 데 사용됩니다.
Chroma.max_marginal_relevance_search() 와 Chroma.as_retriever() 의 차이점
Chroma.max_marginal_relevance_search()와
Chroma.as_retriever()`는 모두 Chroma 벡터 데이터베이스에서 문서를 검색하는 데 사용되는 함수이지만, 다음과 같은 주요 차이점이 있습니다.
1. 검색 방식:
Chroma.max_marginal_relevance_search():
- 최대 여변 관련성(MMR) 검색 알고리즘을 사용하여 검색합니다.
- 검색 쿼리와 유사하면서 서로 중복되지 않는 문서를 찾는 데 중점을 둡니다.
- 쿼리와 유사한 상위 N개의 문서를 반환합니다.
Chroma.as_retriever():
- 다양한 검색 알고리즘을 사용하여 검색할 수 있는 리트리버 객체를 반환합니다.
- MMR 검색 외에도 여백 검색(cosine similarity), TF-IDF 검색 등을 사용할 수 있습니다.
- 검색 쿼리와 일치하는 모든 문서를 반환합니다.
2. 반환 값:
Chroma.max_marginal_relevance_search():
- 검색 결과 문서 리스트를 반환합니다. 각 문서는
id
,embedding
,score
(관련성 점수) 속성을 포함하는 사전 또는 객체 형식입니다.
- 검색 결과 문서 리스트를 반환합니다. 각 문서는
Chroma.as_retriever():
Retriever
객체를 반환합니다. 이 객체를 사용하여 다양한 검색 작업을 수행할 수 있습니다.
3. 사용 예시:
Chroma.max_marginal_relevance_search():
# Chroma 벡터 데이터베이스 생성 및 문서 추가 (이전 코드 생략) ...
# 검색 쿼리 설정
query = "검색 쿼리 내용"
# MMR 검색 수행
results = vectorstore.max_marginal_relevance_search(query, k=10)
# 검색 결과 출력
for result in results:
print(f"문서 ID: {result['id']}")
print(f"관련성 점수: {result['score']}")
print(f"문서 내용: {result['page_content']}")
print("----------------------")
Chroma.as_retriever():
# Chroma 벡터 데이터베이스 생성 및 문서 추가 (이전 코드 생략) ...
# 리트리버 객체 생성
retriever = vectorstore.as_retriever()
# 검색 쿼리 설정
query = "검색 쿼리 내용"
# 여백 검색 수행
results = retriever.cosine_similarity_search(query, k=10)
# 검색 결과 출력
for result in results:
print(f"문서 ID: {result['id']}")
print(f"유사도: {result['score']}")
print(f"문서 내용: {result['page_content']}")
print("----------------------")
4. 결론:
- **Chroma.max_marginal_relevance_search()**는 쿼리와 유사하면서 서로 중복되지 않는 문서를 빠르게 찾는 데 적합합니다.
- **Chroma.as_retriever()**는 다양한 검색 알고리즘을 사용하여 더 정교한 검색을 수행하고 싶을 때 사용합니다.
How to create a langchain doc from an str?
Chroma.from_documents와 Chroma.add_documents의 차이점
Chroma.from_documents와 Chroma.add_documents는 모두 Chroma 벡터 데이터베이스에 문서를 추가하는 데 사용되는 메서드이지만, 다음과 같은 주요 차이점이 있습니다.
1. 사용 목적:
Chroma.from_documents:
- 기존 문서 리스트를 기반으로 Chroma 벡터 데이터베이스를 새로 생성합니다.
- 각 문서에 대한 임베딩 벡터를 계산하고 데이터베이스에 저장합니다.
- 데이터베이스가 없는 경우 또는 새로운 데이터 세트로 데이터베이스를 초기화할 때 사용됩니다.
Chroma.add_documents:
- 기존 Chroma 벡터 데이터베이스에 새로운 문서를 추가합니다.
- 문서의 임베딩 벡터는 외부에서 계산되어야 합니다.
- 데이터베이스가 이미 생성된 경우 새로운 문서를 추가할 때 사용됩니다.
2. 입력 파라미터:
Chroma.from_documents:
- documents: 문서 리스트. 각 문서는 텍스트 내용, 메타데이터 등을 포함하는 사전 또는 객체 형식이어야 합니다.
- embedding: 임베딩 함수. 문서의 텍스트 내용을 임베딩 벡터로 변환하는 함수를 지정합니다.
- kwargs: 추가적인 옵션을 지정하는 키워드 인수 사전 (선택적).
Chroma.add_documents:
- documents: 문서 리스트. 각 문서는
id
,embedding
,metadata
(선택적),tags
(선택적) 속성을 포함하는 사전 또는 객체 형식이어야 합니다. - kwargs: 추가적인 옵션을 지정하는 키워드 인수 사전 (선택적).
- documents: 문서 리스트. 각 문서는
3. 반환 값:
Chroma.from_documents:
- Chroma 벡터 데이터베이스 객체를 반환합니다.
Chroma.add_documents:
- 반환 값이 없습니다.
4. 사용 예시:
Chroma.from_documents:
from langchain_community.vectorstores import Chroma
from langchain_community.embeddings.openai import OpenAIEmbeddings
# 문서 로드
documents = load_documents("documents.txt")
# 임베딩 함수 생성
embeddings = OpenAIEmbeddings()
# Chroma 벡터 데이터베이스 생성
vectorstore = Chroma.from_documents(documents, embeddings)
# ... Chroma 벡터 데이터베이스 사용 ...
Chroma.add_documents:
# ... Chroma 벡터 데이터베이스 생성 및 임베딩 계산 (이전 코드 생략) ...
# 새로운 문서 추가
new_documents = [
{
"id": "new_doc1",
"embedding": [0.1, 0.2, 0.3], # 외부에서 계산된 임베딩 벡터
"metadata": {"title": "새로운 문서 제목"},
"tags": ["새로운 태그1", "새로운 태그2"],
},
{
# ... 다른 새로운 문서 ...
},
]
vectorstore.add_documents(new_documents)
# ... Chroma 벡터 데이터베이스 사용 ...
- ref
- https://www.inflearn.com/questions/1193196/chroma-db-import-%EA%B0%80-%EC%97%85%EB%8D%B0%EC%9D%B4%ED%8A%B8%EB%90%9C-%EA%B2%83-%EA%B0%99%EC%8A%B5%EB%8B%88%EB%8B%A4
- https://stackoverflow.com/questions/76551067/how-to-create-a-langchain-doc-from-an-str
0 댓글