Проект посвящен исследованию возможностей малой языковой модели Qwen1.5-0.5B-Chat в задаче генерации кода (text-to-code). В рамках работы сравниваются три режима использования модели: zero-shot инференс из коробки, дообучение методом LoRA (QLoRA), а также дополненная генерация с извлечением контекста (RAG + Reranking). Оценка качества кода производится с помощью метрики CodeBLEU и метода LLM-As-a-Judge на базе DeepSeek.
- Обзор проекта
- Структура репозитория
- Технологии
- Установка
- Конфигурация
- Описание ноутбуков
- Результаты экспериментов
- Предложения по улучшению
Целевая задача — text-to-code: модель получает текстовое описание программного фрагмента (instruction) и должна сгенерировать соответствующий код на Java. Для оценки используется подмножество бенчмарка CodeXGLUE (google/code_x_glue_tc_text_to_code) — 200 случайных примеров из обучающей части.
Исследуемые конфигурации:
- Zero-shot — базовая модель Qwen1.5-0.5B-Chat без дополнительной настройки.
- Fine-tuned (LoRA) — модель, дообученная на подмножестве датасета glaiveai/glaive-code-assistant-v2 методом LoRA через библиотеку PEFT.
- RAG — базовая модель, дополненная системой извлечения релевантных примеров из векторного хранилища ChromaDB с последующим реранкингом через Qwen3-Reranker-0.6B.
.
├── config/
│ ├── config.yaml # Конфигурация моделей и коллекций
│ └── model_prompts.py # Системные и пользовательские промпты
├── notebooks/
│ ├── I. FineTuning.ipynb # Дообучение модели (LoRA / SFT)
│ ├── II. VectorStorageCreation.ipynb # Формирование векторного хранилища ChromaDB
│ ├── III. RAGSetup.ipynb # Настройка и ручное тестирование RAG-пайплайна
│ ├── IV.ZeroShotModelEvaluation.ipynb # Оценка базовой модели (zero-shot)
│ ├── V.FineTunedModelEvaluation.ipynb # Оценка дообученной модели
│ └── VI. RAGChainEvaluation.ipynb # Оценка RAG-пайплайна
├── src/
│ ├── modelClass.py # Класс QwenModel (инференс, RAG-чат)
│ ├── rerankerClass.py # Класс QwenReranker (Qwen3-Reranker-0.6B)
│ ├── deepSeekModel.py # Класс DeepSeek (LLM-As-a-Judge через API)
│ └── functions.py # Вспомогательные функции (CodeBLEU, LLM-Judge, парсинг)
├── data/ # Директория с CSV-файлами датасетов и результатов (в .gitignore)
│ ├── train_dataset.csv
│ ├── test_dataset.csv
│ └── code_x_glue/
│ ├── validation_dataset.csv
│ ├── zero_shot_evaluation/
│ └── finetuned_evaluation/
├── collection_dir/ # Директория векторного хранилища ChromaDB (в .gitignore)
├── qwen_code_finetuned/ # Веса дообученной модели (checkpoint'ы LoRA, в .gitignore)
├── .env # API-ключи (deepseek_api и др., в .gitignore)
├── requirements.txt # Зависимости Python
├── torch_installation_command.txt # Команда установки PyTorch (CUDA 12.8)
└── code_bleu_installation_command.txt # Команда установки CodeBLEU и tree-sitter
Директории
data/,collection_dir/,qwen_code_finetuned/и файл.envисключены из системы контроля версий через.gitignore, поскольку содержат большие бинарные файлы, чувствительные данные и артефакты, специфичные для конкретного запуска.
Qwen1.5-0.5B-Chat — инструктированная языковая модель семейства Qwen1.5 от Alibaba Cloud с 0.5 миллиарда параметров. Использует архитектуру decoder-only Transformer с групповым вниманием (GQA), поддерживает контекстное окно до 32 768 токенов и обладает встроенным шаблоном диалога в формате ChatML (<|im_start|> / <|im_end|>). Несмотря на малый размер, модель демонстрирует базовые способности к следованию инструкциям и генерации кода.
LoRA (Low-Rank Adaptation) — метод параметрически эффективного дообучения (PEFT), при котором обновляемые параметры вводятся в виде произведения двух матриц малого ранга, добавляемых к весам выбранных слоёв трансформера. Это позволяет существенно сократить объём обучаемых параметров: в данном эксперименте дообучается 7.57 миллиона параметров при общем числе 471.6 миллиона (1.6%).
Параметры конфигурации LoRA:
r = 16— ранг матриц адаптацииlora_alpha = 32— масштабирующий коэффициентlora_dropout = 0.05— регуляризация- Целевые модули:
q_proj,k_proj,v_proj,o_proj,gate_proj,up_proj,down_proj
Обучение выполнялось с помощью SFTTrainer из библиотеки TRL (Transformer Reinforcement Learning), которая реализует Supervised Fine-Tuning с автоматической токенизацией в формате чата.
Параметры обучения:
num_train_epochs = 3,learning_rate = 2e-4lr_scheduler_type = cosineсwarmup_ratio = 0.03per_device_train_batch_size = 4,gradient_accumulation_steps = 4- Ранняя остановка (
EarlyStoppingCallback) - Итоговый checkpoint:
step-2350,training_loss = 1.221
glaiveai/glaive-code-assistant-v2 — синтетический датасет вопрос-ответ по программированию, охватывающий множество языков и тем. Из него было случайно выбрано 20 000 примеров (seed=42), разделённых на обучающую (19 000) и валидационную (1 000) части (test_size=0.05).
ChromaDB — встраиваемая векторная база данных с поддержкой персистентного хранения. В проекте используется PersistentClient с локальным хранением коллекции в директории collection_dir/. Коллекция формируется на основе поля answer датасета glaive-code-assistant-v2 (обучающая часть), к которому добавляется префикс "Possible Answer: ".
sentence-transformers/all-mpnet-base-v2 — модель получения плотных текстовых представлений (dense embeddings) на базе архитектуры MPNet. Используется как функция эмбеддинга ChromaDB для преобразования текстовых фрагментов и пользовательских запросов в векторы для последующего поиска по косинусному подобию.
Qwen/Qwen3-Reranker-0.6B — генеративный реранкер на базе языковой модели, оценивающий релевантность документов запросу в бинарном формате (yes / no). В отличие от bi-encoder embedding-моделей, реранкер выполняет совместное кодирование запроса и документа (cross-encoder), что обеспечивает более точную оценку релевантности за счёт увеличения вычислительных затрат.
Схема работы реранкера:
- ChromaDB возвращает топ-20 фрагментов по косинусному подобию.
- Реранкер переоценивает каждый документ и присваивает score.
- Выбираются 5 наиболее релевантных фрагментов для формирования контекста.
CodeBLEU — специализированная метрика оценки качества сгенерированного кода, расширяющая стандартный BLEU четырьмя компонентами:
ngram_match_score— токенное n-граммное совпадение (аналог BLEU)weighted_ngram_match_score— взвешенное n-граммное совпадение с учётом синтаксических токеновsyntax_match_score— совпадение по синтаксическому дереву (AST), строится с помощью tree-sitterdataflow_match_score— совпадение по потоку данных (data flow graph)
В проекте используется pip-совместимая реализация k4black/codebleu. Целевой язык — Java.
В качестве оценочной LLM применяется deepseek-chat через официальный API DeepSeek (совместимый с OpenAI SDK). Модели-судье передаются: инструкция, эталонный и предсказанный код. На выходе формируется структурированный JSON с бинарными оценками по критериям: code_solves_task, syntax_is_correct, is_overcomplicated, has_proper_naming, has_comments, а также текстовые поля pros, cons, overhaul analysis.
git clone <url-репозитория>
cd <папка-проекта>pip install torch torchvision --index-url https://download.pytorch.org/whl/cu128Для других версий CUDA или CPU-режима см. официальную страницу pytorch.org/get-started.
pip install -r requirements.txtpip install codebleu
pip install --upgrade tree-sitter
pip install tree-sitter-javaПри работе с другим языком программирования замените суффикс java на нужный (например, tree-sitter-python, tree-sitter-rust).
Создайте файл .env в корне проекта:
deepseek_api=<ваш-api-ключ-deepseek>
Основные параметры хранятся в config/config.yaml:
llm_model:
name: Qwen/Qwen1.5-0.5B-Chat # Идентификатор базовой модели на HuggingFace
embedding_model:
name: all-mpnet-base-v2 # Модель для получения эмбеддингов (ChromaDB)
vector_collection:
name: coding_answer_collection # Название коллекции в ChromaDB
local_llm_model:
path: qwen_code_finetuned/checkpoint-2350 # Путь к дообученной модели (LoRA-адаптеры)Системные промпты (programming_assistant_sys_prompt, programming_checker_so, programming_assistant_zero_shot) настраиваются в config/model_prompts.py.
Дообучение модели Qwen1.5-0.5B-Chat методом LoRA на датасете glaive-code-assistant-v2.
Этапы: загрузка и сэмплирование датасета (20 000 примеров) → приведение к формату диалога (user/assistant) → разбивка на train/eval → конфигурация LoRA → обучение через SFTTrainer → сохранение весов.
Формирование векторного хранилища ChromaDB для RAG-пайплайна.
Этапы: загрузка датасета glaive-code-assistant-v2 → формирование поля embedding_field (ответы с префиксом) → сохранение CSV → индексирование в ChromaDB с помощью all-mpnet-base-v2.
Ручная демонстрация работы RAG-пайплайна.
Пример: по запросу "Explain what cuda is?" модель получает контекст из ChromaDB, реранкер отбирает топ-5 фрагментов, после чего QwenModel формирует ответ с учётом контекста.
Количественная оценка базовой модели (без дообучения, без RAG) на задаче text-to-code (CodeXGLUE, 200 примеров Java, zero-shot режим).
Количественная оценка дообученной модели (LoRA, checkpoint-2350) на том же наборе примеров CodeXGLUE.
Количественная оценка базовой модели в режиме RAG (ChromaDB + Qwen3-Reranker-0.6B) на том же наборе примеров CodeXGLUE.
Оценка проводилась на 200 примерах задачи text-to-code из бенчмарка CodeXGLUE (Java). Ниже приведены усреднённые значения метрик по каждой конфигурации.
| Метрика | Zero-shot | Fine-tuned (LoRA) | RAG |
|---|---|---|---|
| CodeBLEU (total) | 0.245 | 0.251 | 0.232 |
| ngram_match_score | 0.003 | 0.003 | — |
| weighted_ngram_match_score | — | — | 0.014 |
| syntax_match_score | 0.202 | ~0.202 | 0.112 |
| dataflow_match_score | 0.407 | 0.481 | — |
| Метрика | Zero-shot | Fine-tuned (LoRA) | RAG |
|---|---|---|---|
| code_solves_task | 0.0 | 0.0 | 0.005 |
| syntax_is_correct | 0.23 | ~0.235 | 0.225 |
| is_overcomplicated | 0.935 | ~0.935 | 0.704 |
| has_proper_naming | 0.06 | ~0.06 | 0.175 |
| has_comments | — | +10.5% vs base | — |
Ни одна из трёх конфигураций не продемонстрировала функциональной корректности генерируемого кода: code_solves_task равен нулю у 199 из 200 примеров во всех режимах. Это соответствует известному явлению, при котором малые языковые модели (менее 1B параметров) обладают недостаточной базовой способностью к генерации семантически корректного кода вне зависимости от метода адаптации.
Дообучение (LoRA) оказало ожидаемый эффект на поведенческий слой модели: незначительно вырос CodeBLEU (0.245 → 0.251), улучшился dataflow_match_score (0.407 → 0.481), а доля примеров с комментариями выросла на 10.5%. Это объясняется тем, что SFT-обучение формирует стилистику ответа ассистента, не влияя на базовые знания о языке программирования.
RAG-пайплайн продемонстрировал заметное снижение is_overcomplicated (-23%, с 93.5 до 70.4%) и рост has_proper_naming (с 6% до 17.5%): retrieved примеры из датасета служат имплицитными образцами стиля и именований. Вместе с тем syntax_match_score и суммарный CodeBLEU снизились относительно базовой модели, что указывает на интерференцию контекста из векторной базы с собственными синтаксическими паттернами генерации.
Датасет glaive-code-assistant-v2 является мультиязыковым и охватывает вопросы по широкому спектру языков программирования. Дообучение на данных исключительно по Java (или по целевому языку вообще) позволит снизить распределительный шум и сконцентрировать адаптацию на релевантном синтаксисе. Для этого необходима дополнительная классификация (фильтрация) примеров датасета: выявление и отбор записей, содержащих вопросы и ответы строго на целевом языке программирования.
Текущая коллекция ChromaDB формируется из поля answer датасета glaive-code-assistant-v2, то есть из ответов общего назначения. Для задачи text-to-code более релевантным источником будет индексирование примеров из Java-специфичных датасетов (например, из самого CodeXGLUE или аналогичных). Дополнительно стоит рассмотреть совместное индексирование пары (instruction + code), а не только кода/ответа, что позволит находить семантически близкие задачи, а не просто похожие по тексту решения.
Метрика CodeBLEU чувствительна к форматированию: модели нередко оборачивают код в markdown-блоки (```java ... ```), что искажает n-граммное и синтаксическое совпадение. В проекте реализована функция extract_java_code() для извлечения кода из markdown-обёрток, однако последовательное её применение ко всем предсказаниям перед расчётом CodeBLEU обеспечит более чистую оценку.
Результаты свидетельствуют о том, что модели с числом параметров менее 1B принципиально ограничены в задачах генерации функционально корректного кода. Повторение данного исследования на моделях большего масштаба того же семейства — Qwen1.5-1.8B-Chat или Qwen1.5-4B-Chat — при сохранении прочих условий эксперимента позволит установить, является ли наблюдаемое ограничение следствием малого размера модели или особенностей выбранного подхода к дообучению и RAG.
Вместо фильтрации по ключевым словам более надёжным подходом является дообучение классификатора (например, на базе дистиллированной модели) для автоматической разметки примеров датасета glaive-code-assistant-v2 по целевому языку программирования. Это позволит сформировать высококачественное подмножество для как дообучения генеративной модели, так и наполнения векторного хранилища.