Ru2SQL / README.md
Tyycha's picture
fix bugs
cc2ed2f
metadata
title: Ru2SQL
emoji: 🗄️
colorFrom: blue
colorTo: purple
sdk: docker
pinned: false

ru2sql

Генеративная модель для преобразования вопросов на русском языке в SQL-запросы. Практическая часть ВКР, направление «Программная инженерия», 4 курс.

Стек: Python 3.10+, PyTorch, transformers, PEFT (LoRA), FastAPI, Streamlit, sqlglot. Основная модель: Qwen2.5-Coder-3B-Instruct, дообученная методом QLoRA на датасете PAUQ. Сравнение: ruT5-base baseline + GigaChat API.

См. plan_VKR_text2sql_ru.md для полного плана работ.


Архитектура

┌─────────────────────┐    HTTP     ┌──────────────────────┐
│  Streamlit-клиент   │ ─────────►  │   FastAPI REST API   │
│  (порт 8501)        │             │   (порт 8000)        │
└─────────────────────┘             └──────────┬───────────┘
                                               │
                            ┌──────────────────┼──────────────────┐
                            ▼                  ▼                  ▼
                  ┌──────────────────┐ ┌──────────────┐ ┌────────────────┐
                  │ InferenceEngine  │ │ SchemaProvi- │ │ BusinessVocab- │
                  │ Qwen + LoRA      │ │ der + Sql-   │ │ ulary (YAML)   │
                  │                  │ │ Executor     │ │                │
                  └──────────────────┘ └──────────────┘ └────────────────┘

Streamlit-интерфейс не вызывает модель напрямую — он обращается к REST API через httpx. Это позволяет запускать UI и инференс на разных машинах, а также подключать к API любых сторонних клиентов.


Быстрый старт

1. Установка

pip install uv
git clone <твой-репо> ru2sql
cd ru2sql
uv venv
.venv\Scripts\activate          # Windows
# source .venv/bin/activate     # Linux/Mac
uv pip install -e ".[dev]"

2. Конфигурация

copy .env.example .env          # Windows
# cp .env.example .env          # Linux/Mac

Заполни в .env:

  • BASE_MODEL_NAME (по умолчанию Qwen/Qwen2.5-Coder-3B-Instruct),
  • LORA_ADAPTER_PATH (локальная папка или HF-repo),
  • опционально — API-ключ GigaChat для baseline-сравнения.

Если HuggingFace недоступен из вашей сети, добавь:

HF_ENDPOINT=https://hf-mirror.com

3. Тесты

pytest -v

Ожидаемо: 80+ зелёных тестов.

4. Smoke-проверка

Быстрая (5 сек, без модели):

python scripts/smoke_local.py

Полная (с загрузкой Qwen, ~5 минут на CPU):

python scripts/smoke_local.py --with-model

5. Запуск приложения

Нужны два процесса — API и UI:

Окно 1 — REST API:

uvicorn src.api.main:app --reload
# Swagger UI: http://127.0.0.1:8000/docs

Окно 2 — Streamlit-интерфейс:

streamlit run streamlit_app.py
# UI: http://127.0.0.1:8501

При первом запуске модель Qwen2.5-Coder-3B (~6 GB) скачивается из HuggingFace Hub. На CPU инференс одного запроса занимает 15–30 секунд — это ожидаемо.

Адрес API можно переопределить переменной окружения:

set RU2SQL_API_URL=http://192.168.1.10:8000     # Windows
# export RU2SQL_API_URL=http://192.168.1.10:8000  # Linux/Mac

REST API

Базовые эндпоинты

Метод Путь Назначение
GET /health статус сервиса и загруженной модели
GET /databases список БД из data/databases (PAUQ-структура)
POST /generate-sql генерация SQL по db_id из PAUQ
POST /schema схема произвольной БД по connection string
POST /query полный pipeline для произвольной БД

Пример: запрос к произвольной БД

curl -X POST http://127.0.0.1:8000/query \
     -H "Content-Type: application/json" \
     -d '{
       "question": "Какая выручка за 2026 год?",
       "connection_string": "sqlite:///data/demo/sales.sqlite",
       "execute": true,
       "vocabulary": {
         "company": "Демо-магазин",
         "terms": {"выручка": "SUM(orders.amount) WHERE status='paid'"}
       }
     }'

Ответ содержит sql, raw_output, is_valid_sql, gen_time_seconds и опционально execution с результатами выполнения. Перед исполнением SQL проходит AST-уровневую проверку (см. is_select_only в src/models/postprocess.py) — DDL и DML на БД через API невозможны.

Пример: PAUQ-режим (старый эндпоинт)

curl -X POST http://127.0.0.1:8000/generate-sql \
     -H "Content-Type: application/json" \
     -d '{"question": "Сколько студентов на факультете ПИ?", "db_id": "university"}'

Обучение модели

Тренировка идёт в Kaggle Notebook (бесплатный T4 GPU). Локально на CPU/AMD GPU обучить 3B-модель не получится.

Шаги:

  1. Открой notebooks/kaggle_train_qwen_qlora.ipynb на kaggle.com.
  2. В Settings выбери Accelerator: GPU T4 x1.
  3. Add-ons → Secrets → добавь HF_TOKEN и WANDB_API_KEY.
  4. Запусти все ячейки. Тренировка ~4–6 часов.
  5. По завершении адаптер пушится на твой приватный HF-репо.
  6. Скачай его на десктоп:
    huggingface-cli download your-username/qwen-coder-pauq-lora \
        --local-dir checkpoints/qwen-coder-pauq-lora
    

После этого LORA_ADAPTER_PATH в .env укажет на скачанный адаптер, и API будет использовать дообученную модель.


Структура проекта

ru2sql/
├── pyproject.toml              # зависимости
├── .env.example                # шаблон конфигурации
├── plan_VKR_text2sql_ru.md     # план работ
├── notebooks/
│   └── kaggle_train_qwen_qlora.ipynb
├── scripts/
│   └── smoke_local.py          # локальная проверка работоспособности
├── configs/
│   ├── example_vocabulary.yaml
│   └── sales_vocabulary.yaml
├── src/
│   ├── config.py               # настройки через pydantic-settings
│   ├── data/
│   │   ├── loader.py           # чтение PAUQ JSON
│   │   ├── schema_provider.py  # SchemaProvider — единый интерфейс
│   │   ├── schema.py           # SchemaRetriever (фасад для PAUQ)
│   │   └── prompt.py           # PromptBuilder + chat-template
│   ├── db/
│   │   ├── connector.py        # DbConnector — чтение схем
│   │   └── executor.py         # SqlExecutor с read-only
│   ├── business/
│   │   └── vocabulary.py       # BusinessVocabulary (YAML-конфиг)
│   ├── models/
│   │   ├── inference.py        # InferenceEngine (модель + LoRA)
│   │   └── postprocess.py      # очистка SQL + guardrail
│   ├── evaluation/
│   │   ├── metrics.py          # EM + Execution Accuracy
│   │   └── evaluate.py         # CLI для прогона на split
│   └── api/
│       ├── main.py             # FastAPI app (5 эндпоинтов)
│       ├── schemas.py          # Pydantic-модели
│       └── dependencies.py     # lifespan + DI
├── streamlit_app.py            # UI (HTTPX-клиент к API)
└── tests/                      # 80+ тестов
    ├── test_prompt.py
    ├── test_postprocess.py
    ├── test_metrics.py
    ├── test_schema.py
    ├── test_schema_provider.py
    ├── test_vocabulary.py
    └── test_db.py

Прогон оценки

# Полный прогон на dev split
python -m src.evaluation.evaluate --split dev

# Быстрая проверка на 50 примерах
python -m src.evaluation.evaluate --split dev --limit 50

Результат сохраняется в results/predictions.jsonl, метрики печатаются в stdout.


Метрики

Модель EM Execution Accuracy
ruT5-base (baseline) 25–35 % 30–40 %
Qwen2.5-Coder-3B + QLoRA 40,0 % 71,9 %
BRIDGE / RAT-SQL (PAUQ, mono) 51 / 52 % 48 / 49 %

Что НЕ входит в MVP

Сознательно оставлено в раздел «направления дальнейшей работы»:

  • Few-shot retrieval похожих примеров.
  • Schema linking (автоматический отбор релевантных таблиц).
  • Self-correction по ошибкам исполнения SQL.
  • Constrained decoding (грамматика SQL).
  • Дообучение на синтетических данных.

Лицензия и атрибуция

Учебный проект. Использует: