Skip to content
/ llmops Public

Advanced RAG system with enhanced retrieval and error-handling capabilities. Implemented totally locally with open-source tools — LangGraph, Qdrant, Llama.cpp server, Qwen3-0.6B-UD-Q8_K_XL.gguf and MLflow server for observability.

Notifications You must be signed in to change notification settings

dmt-zh/llmops

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

14 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

О проекте

Проект демонстрирует, как создать систему RAG (Retrieval-Augmented Generation) с использованием графа. Реализован с помощью следующих технологий:

  • LangGraph — фреймворк для построения агентов с помощью графов
  • LangChain — фреймворк для создания приложений на базе LLM
  • llama.cpp — движок для инфернса open-source LLM на ЦПУ/ГПУ
  • Qdrant — высокопроизводительная векторная база данных
  • MLflow — платформа для создания моделей и AI/LLM приложений
  • SentenceTransformers — фреймворк для создания высокого качества эмбеддингов для текста
  • Ragas — набор инструментов для оценки и оптимизации приложений, использующих LLM

Граф реализованной системы имеет следующий вид:

где основные узлы это:

  • Retrieve Documents — извлечение релевантных документов на основании вопроса пользователя
  • Evaluate Documents — оценка релевантности извлеченных документов
  • Search Online — поиск информации онлайн, если извлеченные документы не позволяют ответить на вопрос или в базе данных не содержится ответа на вопрос
  • Generate Answer — генерация ответа на основании полученных документов

условные ребра графа

  • Hallucinations detected — оценка сгенерированного ответа на наличие галлюцинаций (выдуманные факты, не содержащиеся в извлеченных документах, ответ не отвечающий на вопрос)
  • Question not addressed — оценка сгенерированного ответа насколько точно он отвечает на вопрос пользователя.

Настройка окружения

Установим необходимые пакеты на Ubuntu:

sudo apt -q update
sudo apt -q -y install build-essential cmake wget zip unzip

gcc --version
cmake -version

Формирование __pycache__ файлов в директории ~/.cache а не в дириктории проекта:

echo 'export PYTHONPYCACHEPREFIX="${HOME}/.cache/pycache"' >> "${HOME}/.bashrc"

Установим docker по инстркуциями из официальной документации:

for pkg in docker.io docker-doc docker-compose docker-compose-v2 podman-docker containerd runc; do sudo apt-get remove $pkg; done
sudo apt-get update
sudo apt-get install ca-certificates curl
sudo install -m 0755 -d /etc/apt/keyrings
sudo curl -fsSL https://download.docker.com/linux/ubuntu/gpg -o /etc/apt/keyrings/docker.asc
sudo chmod a+r /etc/apt/keyrings/docker.asc

echo \
  "deb [arch=$(dpkg --print-architecture) signed-by=/etc/apt/keyrings/docker.asc] https://download.docker.com/linux/ubuntu \
  $(. /etc/os-release && echo "${UBUNTU_CODENAME:-$VERSION_CODENAME}") stable" | \
  sudo tee /etc/apt/sources.list.d/docker.list > /dev/null
sudo apt-get update
sudo apt-get install docker-ce docker-ce-cli containerd.io docker-buildx-plugin docker-compose-plugin

Проверим, что docker установлен с помощью команды:

sudo docker -v

Добавим команду запуска docker не из-под суперпользователя

sudo usermod -aG docker $USER

Установка llama.cpp и скачивание моделей

Создаем в домашней директории новую директорию .llama.cpp:

cd && mkdir .llama.cpp && cd .llama.cpp

Скачиваем последний релиз llama.cpp для Linux Ubuntu:

wget https://github.com/ggml-org/llama.cpp/releases/download/b6960/llama-b6960-bin-ubuntu-x64.zip

Распаковываем zip архив и удаляем после распаковки:

unzip llama-b6960-bin-ubuntu-x64.zip && rm llama-b6960-bin-ubuntu-x64.zip

Для запуска из любой директории llama.cpp сервера созданим мягкую ссылку на исполняемую программу:

sudo ln -s ~/.llama.cpp/build/bin/llama-server /usr/local/bin/llama-server

Проверяем работоспособность программы:

llama-server -h

В результате будет получена справка по запуску сервера:

----- common params -----
  
-h,    --help, --usage                  print usage and exit
--version                               show version and build info
--completion-bash                       print source-able bash completion script
--verbose-prompt                        print a verbose prompt before generation (default: false)

Создадим директорию для храниния скачиваемых моделей

mkdir models

Для реализации проекта скачаем модель unsloth/Qwen3-0.6B-GGUF с квантизацией Q8_K_XL:

wget -O ~/.llama.cpp/models/Qwen3-0.6B-UD-Q8_K_XL.gguf https://huggingface.co/unsloth/Qwen3-0.6B-GGUF/resolve/main/Qwen3-0.6B-UD-Q8_K_XL.gguf?download=true

Не обязательно! Можно также скачать для локального пользования модель unsloth/gpt-oss-20b-GGUF с квантизацией Q8_K_XL:

wget -O ~/.llama.cpp/models/gpt-oss-20b-UD-Q8_K_XL.gguf https://huggingface.co/unsloth/gpt-oss-20b-GGUF/resolve/main/gpt-oss-20b-UD-Q8_K_XL.gguf?download=true

Запустить сервер для теста можно с помощью команды в терминале:

llama-server -m ~/.llama.cpp/models/gpt-oss-20b-UD-Q8_K_XL.gguf --jinja

Сервер будет доступен в веб браузере по адресу: http://localhost:8080/


Данные для RAG

Ссылка на датасет: galileo-ai/ragbench Описание датасета: RAGBench: Explainable Benchmark for Retrieval-Augmented Generation Systems

Датасет для проекта будет формироваться из данных для теста, домены: медицина, юрисприденция, финансы, техническая поддержка клиентов, общий домен. Из каждого домена берется по 25 документов, размер которых превышает 2500 символов. Из этих 25 документов по каждому домену берется 5 документов (вопрос и правильный ответ) для формирования валидационных данных. Валидационные данные нужны для финальной проверки работоспособности реализованной системы.


Инициализация и запуск проекта

Устанавливаем пакетный менеджер uv:

curl -LsSf https://astral.sh/uv/install.sh | sh

Чтобы изменения внесённые в файл bashrc в текущем сеансе терминала вступили в силу, файл необходимо перезагрузить:

source ~/.bashrc

Копируем репозиторий:

git clone https://github.com/dmt-zh/llmops.git && cd llmops

Создаем виртуальное окружение и устанавливаем зависимости:

uv sync --locked

Для установки дополнительных зависимостей проверки кода (линтеров):

uv sync --group lint

Создаем .env файл на основании файла .env.example:

cp .env.example .env

Редактируем переменные в файле .env

Добавляем права запуска скрипту main.py

chmod +x main.py

В Makefile содержаться команды управления инфраструктурой и проверки кода с помощью линтера ruff. Получить справку можно с помощью следующей команды:

make help

В результате будет получен следующий вывод:

› help: Display help message with available commands
› llama-server-up: Start inference of a local LLM with llama.cpp server
› llama-server-down: Terminate llama.cpp server
› services-up: Start local services using Docker Compose
› services-down: Stop and remove local services
› lint-check: Check code for linting issues without making changes
› lint-fix: Fix linting issues using ruff

Запускаем сервер llama.cpp в фоновом режиме с моделью Qwen3-0.6B-UD-Q8_K_XL.gguf:

make llama-server-up

Запускаем инфраструктуру для работы RAG системы: Qdrant, MLflow сервер, Postgres, MinIO S3 (Postgres и MinIO S3 нужны для работы MLflow):

make services-up

Необходимо подождать пока сервер MLflow начнет работу. Запуск сервера можно посмотреть с помощью команды:

docker logs mlflow-server --tail 50 -f

При успешном запуске MLflow сервера, будет соответствующая запись логах

[MLflow] Security middleware enabled with default settings (localhost-only). To allow connections from other hosts, use --host 0.0.0.0 and configure --allowed-hosts and --cors-allowed-origins.
INFO:     Uvicorn running on http://0.0.0.0:5000 (Press CTRL+C to quit)
...
INFO:     Application startup complete.
INFO:     127.0.0.1:45410 - "GET /health HTTP/1.1" 200 OK
INFO:     127.0.0.1:50666 - "GET /health HTTP/1.1" 200 OK

Основной точкой входа для работы RAG системы является скрипт main.py. С помощью следующей команды можно посмотреть справку по доступным аргументам запуска:

./main.py

В результате будет получен следующий вывод:

Usage: main.py [OPTIONS] COMMAND [ARGS]...

  The entrypoint of the project.

Options:
  --help  Show this message and exit.

Commands:
  create-collection  Create a new Qdrant collection.
  create-datasets    Download and create datasets for RAG systems.
  delete-collection  Delete all data from the Qdrant collection.
  draw-gpraph        Draw the graph and save its image to `static` folder.
  process-question   Run the Q&A processing workflow.
  rag-evaluation     RAG evaluation on a specific domain.

Скачиваем данные и формируем основной и валидационный датасеты:

./main.py create-datasets

После завершеня работы команды будет сформирована следующая файловая структура:

├── data
│   ├── download_data.py
│   ├── eval_dataset.json
│   └── main_dataset.json

Создаем коллекцию в векторной базе данных и наполняем ее эмбеддингами на основании частей текста, полученных из документов основного датасета main_dataset.json:

./main.py create-collection

На выполнение этой команды может потребоваться от 30 мин. до 2 часов, в зависимости от мощности CPU. В результате векторная база данных будет содержать около 2 тыс. эмбеддингов. Созданная коллекция будет доступна в веб браузере по ссылке: http://localhost:6333/dashboard#/collections

Посмотреть на кластеры эмбеддингов можно странице коллекции по ссылке в веб браузере: http://localhost:6333/dashboard#/collections/domain_knowledge/visualize


Визуализация графа выполнения

Что бы получить изображение графа выполнения необходимо выполнить команду:

./main.py draw-gpraph

Изображение графа будет сохранено в директори ./static/graph.png


Обработка вопросов

Обработка вопросов осуществляется с помощью команды:

./main.py process-question --q 'вопрос_который_необходимо обработать'

Параметр --q необязательный. Если его не передавать, то вопросы будут считываться из файла questions.txt:

./main.py process-question


Мониторинг работы системы

Для детального понимания что происходит на каждом шаге работы RAG системы используется MLflow сервер для автоматического трекинга вызовов, происходящих в Langchain и OpenAI API.

После выполнения команд ./main.py process-question --q 'вопрос_который_необходимо_обработать' и ./main.py process-question можно проанализировать ход выполненя обработки вопросов на странице трекинга: http://localhost:5000/#/experiments/1/traces

Можно также детально ознакомится с графов выполнения по каждому отдельному запросу нажав на идентификатор нужного вопроса.

Так же можно посмотреть всю информация по отедьльному шагу, как промты, так и метаинформацию.


Оценка качества системы

Для оценки качества работы RAG системы используется валидационный набор данных, сформированных на этапе формирования данных. Валидационный датасет содержит 5 доменов (medical, legal, finance, tech, general), в каждом по 5 вопросов.

В качестве метрик для оценки используются метрики из билиотеки Ragas — набор инструментов для оценки и оптимизации приложений, использующих LLM.

В проекте испльзуются следующие метрики:

  • ResponseRelevancy (answer_relevancy) — oценивает релевантность ответа по отношению к заданному вопросу. Ответы, содержащие неполную, избыточную или ненужную информацию, штрафуются. Оценка может варьироваться от 0 до 1, где 1 — наивысший балл.
  • ContextRelevance (context_relevance) — оценка релевантности найденных документов, которая должна основываться на введенных пользователем данных. Оценка может варьироваться от 0 до 1, где 1 — наивысший балл.
  • Faithfulness (faithfulness) — показатель оценивает, насколько фактическое содержание ответа соответствует извлеченному контексту. Он варьируется от 0 до 1, при этом более высокие баллы указывают на лучшую согласованность. Ответ считается достоверным, если все содержащиеся в нем утверждения могут быть подтверждены извлеченным контекстом.
  • SemanticSimilarity (semantic_similarity) — oценивается семантическое сходство эталонного ответа с сгенерированным ответом. Для количественной оценки семантического сходства используется модель distiluse-base-multilingual-cased-v1, конвертирующая сгенерированный и эталонный ответы в эмбеддинги, котрые сравниваются между собой по косинусному расстоянию.

Запуск оценки качества осуществляется с помощью команды:

./main.py rag-evaluation --domain <domain>

Например, для оценки системы по медицинскому домену, необходимо выполнить следующую команду:

./main.py rag-evaluation --domain medical

В резульате выполнения программы, на странице трекинга экспериментов (http://localhost:5000/#/experiments), появятся два эксперимента:

  • Medical domain Traces — запуск валидационного набора данных на медицинском домене
  • Medical domain Evaluation — оценка каждого запроса по метрикам

На странице Medical domain Evaluation будут отображены посчитанные метрики:

About

Advanced RAG system with enhanced retrieval and error-handling capabilities. Implemented totally locally with open-source tools — LangGraph, Qdrant, Llama.cpp server, Qwen3-0.6B-UD-Q8_K_XL.gguf and MLflow server for observability.

Topics

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published