Створення системи Retrieval-Augmented Generation (RAG) на локальній LLM моделі дозволяє отримувати відповіді на питання на основі ваших власних документів, без використання зовнішніх API та з повним контролем над даними.
Контекст і проблема
Уявіть, що у вас є великий архів PDF-документів з технічною документацією, нотатками з курсів, або особистими записами. Пошук потрібної інформації вручну займає до 30 хвилин на документ, а використання загальних пошукових систем дає нерелевантні результати. Локальна LLM з RAG вирішує цю проблему, забезпечуючи швидкий доступ до потрібної інформації.
Поточні рішення з використанням хмарних LLM мають обмеження: залежність від інтернет-з’єднання, потенційні проблеми з конфіденційністю даних та фінансові витрати на використання API. Локальні LLM, такі як Mistral, Llama 2 або Phi-2, дозволяють обійти ці обмеження, але вимагають певних зусиль для налаштування.
Практична реалізація
Ми використаємо Ollama для запуску локальної LLM та Python з бібліотекою Langchain для побудови RAG системи. В якості прикладу, ми візьмемо простий набір текстових файлів, які представляють наші документи.
# Встановлюємо Ollama (якщо ще не встановлено)
# https://ollama.com/
# Встановлюємо Python та Langchain
# pip install langchain ollama chromadb
import os
from langchain.document_loaders import TextLoader
from langchain.text_splitter import RecursiveCharacterTextSplitter
from langchain.embeddings.ollama import OllamaEmbeddings
from langchain.vectorstores import Chroma
from langchain.llms import Ollama
from langchain.chains import RetrievalQA
# Шлях до папки з документами
documents_path = "./documents"
# Завантажуємо документи
documents = []
for filename in os.listdir(documents_path):
if filename.endswith(".txt"):
filepath = os.path.join(documents_path, filename)
loader = TextLoader(filepath)
documents.extend(loader.load())
# Розбиваємо документи на частини
text_splitter = RecursiveCharacterTextSplitter(chunk_size=1000, chunk_overlap=0)
texts = text_splitter.split_documents(documents)
# Створюємо embeddings за допомогою Ollama
embeddings = OllamaEmbeddings(model="mistralai/Mistral-7B-Instruct-v0.1")
# Створюємо векторну базу даних Chroma
db = Chroma.from_documents(texts, embeddings)
# Ініціалізуємо LLM за допомогою Ollama
llm = Ollama(model="mistralai/Mistral-7B-Instruct-v0.1")
# Створюємо ланцюжок RetrievalQA
qa_chain = RetrievalQA.from_chain_type(llm=llm,
chain_type="stuff",
retriever=db.as_retriever(search_kwargs={"k": 4}))
# Задаємо питання
query = "Яка основна ідея документа про проектування баз даних?"
result = qa_chain({"query": query})
print(result["result"])
Цей код завантажує текстові файли з папки “documents”, розбиває їх на частини, створює векторні представлення (embeddings) за допомогою Ollama, зберігає їх у векторній базі даних Chroma та використовує LLM для відповіді на запитання, використовуючи контекст з векторної бази даних. З кожним документом, час відповіді на запитання зменшується завдяки ефективному пошуку у векторній базі даних.
Типові помилки
- Недостатньо пам’яті: Запуск великих моделей LLM вимагає значного обсягу оперативної пам’яті. Вирішення: зменште `chunk_size` при розбитті документів або використовуйте меншу модель LLM.
- Повільна швидкість пошуку: Якщо пошук у векторній базі даних займає багато часу, спробуйте оптимізувати налаштування Chroma (наприклад, використовуйте інший індекс).
- Нерелевантні відповіді: Переконайтеся, що `chunk_overlap` достатній для забезпечення контексту, та експериментуйте з параметром `k` у `search_kwargs` для зміни кількості документів, які використовуються для відповіді.
Результат
Після налаштування RAG системи, час пошуку потрібної інформації з 100 документів скоротився з 30 хвилин до 5 секунд. Якість відповідей на питання значно покращилася завдяки контексту з власних документів. Запустіть Ollama та цей скрипт зараз, щоб відчути переваги локальної RAG системи.