中文翻译暂不可用,显示俄语原文。
Реализовать verifier-guided decoding
ТЕХНИЧЕСКОЕ ЗАДАНИЕ: Реализовать verifier-guided decoding
1. Цель задачи
Разработать механизм verifier-guided decoding (VGD) для генерации рассуждений (chain-of-thought) малой LLM. Небольшой verifier (например, на 0.5B параметров) на каждом шаге (токене или группе токенов) оценивает вероятность того, что текущий путь приведёт к правильному ответу. На основе оценки decoding либо прерывается, либо происходит откат (backtracking) к предыдущим шагам. Ключевая идея — отсекать неверные ветви рассуждения рано, экономя тестовое время (test-time compute) и повышая точность финального ответа.
Ключевой результат Функциональный пайплайн VGD, который для набора математических или логических задач (например, GSM8K или PrOntoQA) показывает улучшение accuracy на ≥10% при фиксированном бюджете токенов (или сокращении числа токенов на ≥30% при той же accuracy) по сравнению с обычным жадным декодированием.
2. Исходные данные
| Что нужно | Откуда взять |
|---|---|
| Базовая LLM для генерации рассуждений | HuggingFace: например, Mistral-7B-Instruct-v0.3 или Llama-3.2-3B-Instruct |
| Verifier (малая модель-критик) | HuggingFace: SmolLM-360M или TinyLlama-1.1B-Chat-v1.0 (дообучать не обязательно — используем zero-shot с prompt) |
| Датасет с задачами, требующими многошагового рассуждения | GSM8K (математика) или PrOntoQA (логика) — загрузить через datasets.load_dataset |
| Метрики качества | Accuracy финального ответа, средняя длина цепочки рассуждений (токены), доля прерванных путей |
| Инфраструктура | Python 3.10+, PyTorch, Transformers, vLLM (опционально для ускорения), GPU с ≥12GB VRAM |
Если нет реальных моделей (например, нет GPU) — симулируем:
- Заменить LLM на OpenAI API (gpt-3.5-turbo-instruct), но verifier — локальная малая модель (через Transformers) на CPU.
- Подготовить скрипт, который делает вызовы к API и локально оценивает шаги.
- Ограничить размер тестового датасета (50 примеров) для ускорения итераций.
3. Технологический стек
| Компонент | Инструменты | Назначение |
|---|---|---|
| Базовая LLM (генератор) | HuggingFace Transformers + vLLM (опционально) | Генерация пошаговых рассуждений |
| Verifier | HuggingFace Transformers (модель-классификатор) | Оценка корректности последнего шага |
| Декодинг | Python (beam search с pruning на основе verifier) | Управление генерацией с прерыванием |
| Датасеты | HuggingFace datasets | Загрузка и подготовка GSM8K / PrOntoQA |
| Трекинг экспериментов | Weights & Biases (wandb) или MLflow | Логирование метрик, конфигов, артефактов |
| Вычисления | PyTorch, CUDA, CPU fallback | Продвижение тензоров |
4. Этапы выполнения
Этап 1: Настройка окружения и загрузка данных (оценка: 30 мин)
Действия
- Создать виртуальное окружение и установить зависимости:
python -m venv vgd_env source vgd_env/bin/activate pip install transformers torch datasets accelerate wandb vllm - Загрузить датасет GSM8K (тестовый сплит):
from datasets import load_dataset dataset = load_dataset("gsm8k", "main", split="test") questions = dataset["question"] answers = dataset["answer"] # содержит финальное число с пояснением - Выбрать 50 примеров для отладки и 200 для финальной оценки.
- Загрузить базовую LLM (генератор) и verifier:
Примечание: для verifier нужно добавить классификационную голову (binary: правильный/неправильный шаг). Можно использовать предобученныйfrom transformers import AutoModelForCausalLM, AutoTokenizer gen_tokenizer = AutoTokenizer.from_pretrained("mistralai/Mistral-7B-Instruct-v0.3") gen_model = AutoModelForCausalLM.from_pretrained("mistralai/Mistral-7B-Instruct-v0.3", device_map="auto") vrf_tokenizer = AutoTokenizer.from_pretrained("HuggingFaceTB/SmolLM-360M") vrf_model = AutoModelForSequenceClassification.from_pretrained("HuggingFaceTB/SmolLM-360M", num_labels=2).to("cuda")allenai/longformer-base-4096с head, но здесь используем SmolLM и дообучим на синтетических данных (этап 2).
Ожидаемый результат этапа Окружение готово, данные загружены, модели загружены в память. Проверочный вызов генерации выдаёт первые 5 шагов.
Этап 2: Подготовка verifier (обучение/настройка) (оценка: 2 часа)
Действия
- Сгенерировать синтетические данные для обучения verifier:
- На 200 примерах из датасета (train split) сгенерировать 3-5 разных путей рассуждения через обычное жадное декодирование (с разными температурами).
- Каждый путь разбить на шаги (по предложениям, разделённым
\n). - Для каждого шага пометить label=1 если итоговый ответ правильный, label=0 если неправильный. (Правильность определяется по совпадению финального числа с эталоном).
- Дообучить verifier (sequence classification):
- Использовать токенизатор SmolLM с padding=True.
- Каждый шаг (текст) подаётся как вход, метка 0/1.
- Обучить 1 эпоху, batch_size=8, lr=2e-5.
from transformers import Trainer, TrainingArguments training_args = TrainingArguments( output_dir="./verifier_model", per_device_train_batch_size=8, num_train_epochs=1, evaluation_strategy="no", save_total_limit=1, ) trainer = Trainer(model=vrf_model, args=training_args, train_dataset=training_dataset) trainer.train() - Оценить качество verifier на валидационной выборке (accuracy, precision, recall).
- Цель: accuracy ≥0.8 на бинарной классификации шагов.
Ожидаемый результат этапа Обученная модель verifier, способная оценить любой шаг рассуждения и дать вероятность правильности p ∈ [0,1]. Сохранена в ./verifier_model.
Этап 3: Реализация verifier-guided decoding (оценка: 3 часа)
Действия
- Разработать функцию
generate_with_verifier- На вход: question (str), generator, verifier, tokenizers, параметры (beam_width, max_steps, threshold_early_stop).
- Процесс:
- Инициализировать очередь путей (каждый путь — список токенов и текущая вероятность).
- На каждом шаге генерации (каждый новый токен) расширять все пути на top-k (k=beam_width) вариантов с помощью топ-вероятностей генератора.
- После генерации полного шага (определяем по разделителю, например
\nили точка с пробелом) передать текст шага verifier. - Если verifier даёт
p < threshold_early_stop(например, 0.3) — отсечь путь (удалить из очереди). - Если
p > threshold_good(0.8) — оставить путь с повышенным приоритетом (умножить score на 1.2). - Продолжать, пока не будет сгенерирован финальный ответ (символ
=илиThe answer is), либо не кончится лимит шагов.
- Вернуть лучший финальный ответ (по суммарной вероятности или по последней оценке verifier).
- Реализовать beam search с отсечениями
- Использовать
model.generateсnum_beams=...иearly_stopping=True, но дополнить кастомным логированием черезlogits_processorили переопределить_beam_search(сложно). Альтернатива: написать свой простой beam search с нуля (для понимания) на <=200 строк.
- Использовать
- Интегрировать verifier как callback
- Создать класс
VerifierCallbackс методом__call__(input_ids, step_text), возвращающим решение (continue/stop/backtrack).
- Создать класс
- Опционально: реализовать backtracking (откат на 1-2 шага) при очень низкой оценке verifier (
p < 0.1).
Ожидаемый результат этапа Скрипт vgd_decode.py, который для одного вопроса возвращает финальный ответ и трассировку (список шагов с их оценками). Можно протестировать на 5-10 примерах.
Этап 4: Эксперимент и сравнение с baseline (оценка: 1.5 часа)
Действия
- Запустить обычное greedy decoding (без verifier) на тестовых 200 примерах:
- Параметры:
max_new_tokens=512, do_sample=False, temperature=0. - Зафиксировать accuracy и среднее число токенов на один ответ.
- Параметры:
- Запустить verifier-guided decoding на тех же примерах:
- Параметры: beam_width=5, max_steps=10, threshold_early_stop=0.3.
- Зафиксировать те же метрики + доля прерванных путей (отношение числа прерванных шагов к общему числу шагов).
- Сравнить результаты в таблице (экспорт в CSV или wandb).
- Провести ablation: изменить threshold (0.1, 0.5, 0.7) и beam_width (3, 5, 10).
Ожидаемый результат этапа Чёткая сводка метрик, подтверждающая улучшение accuracy и/или снижение токенов при использовании VGD.
Этап 5: Документирование и упаковка (оценка: 1 час)
Действия
- Написать README.md с описанием архитектуры VGD, инструкцией по запуску, примерами.
- Зафиксировать конфигурации лучшего эксперимента (threshold, beam_width) в файле
config.yaml. - Создать ноутбук
demo.ipynbс визуализацией- Пример одного вопроса с отображением шагов, оценок verifier и точек прерывания.
- Выложить код на GitHub (или другую платформу) и добавить ссылку.
Ожидаемый результат этапа Репозиторий с чистым кодом, инструкциями и результатами.
5. Критерии приемки (Definition of Done)
- Код verifier-guided decoding работает end-to-end и генерирует ответ для заданного вопроса.
- Verifier обучен и даёт accuracy ≥0.8 на валидационном наборе шагов.
- Эксперимент на 200 примерах GSM8K показал улучшение accuracy на ≥10% по сравнению с greedy decoding.
- Среднее число токенов на ответ снижено на ≥30% при той же accuracy.
- Доля прерванных путей (неправильных шагов, отсечённых verifier) зафиксирована и составляет ≥30% (чтобы verifier действительно отсекал).
- Код структурирован: отдельные модули для verifier, beam search, экспериментов.
- README включает инструкцию по воспроизведению и пример вывода.
- Конфигурация (параметры декодирования, пути к моделям) вынесена в YAML.
6. Ожидаемый результат
- Основной артефакт Python-скрипт
vgd.pyс классомVGDGeneratorи функциейrun_experiment. - Содержание реализация beam search с verifier callback, отсечение неверных путей, экспорт метрик в wandb/CSV.
- Дополнительно веса обученного verifier (
./verifier_model/), конфигconfig.yaml, файл с результатамиresults.csv, ноутбук-демо. - Метрики: accuracy (финальный ответ), среднее число токенов, histogram оценок verifier по шагам.
7. Возможные сложности и их решение
| Сложность | Решение |
|---|---|
| Verifier плохо обучен (accuracy < 0.7) | Увеличить количество синтетических примеров (до 1000), сбалансировать классы, добавить hard negative mining (примеры, близкие к правильному, но неверные) |
| Beam search занимает слишком много времени | Уменьшить beam_width до 3, использовать vLLM для ускорения генерации, кешировать эмбеддинги verifier |
| Verifier даёт слишком много ложных срабатываний (ложно отсекает правильные пути) | Понизить threshold_early_stop (например, с 0.3 до 0.1) или добавить backtracking (восстановить путь при высокой вероятности на следующем шаге) |
| Не хватает памяти GPU для двух моделей | Загружать verifier в CPU (inference медленный, но для 200 примеров возможно) или использовать quantize (bitsandbytes 4-bit) |
| Некорректное определение границ шага (разделитель) | Использовать регулярное выражение: разделять по \n или по символу . с последующим пробелом; возможна адаптация под формат chain-of-thought (например, “Step 1: ...”) |
8. Бюджет времени (оценка)
| Этап | Время |
|---|---|
| Этап 1: Настройка окружения и загрузка данных | 30 мин |
| Этап 2: Подготовка verifier (обучение) | 2 ч |
| Этап 3: Реализация VGD | 3 ч |
| Этап 4: Эксперимент и сравнение | 1.5 ч |
| Этап 5: Документирование и упаковка | 1 ч |
| Итого | 8 ч |
Примечание Для первого раза можно упростить — пропустить Этап 2 (использовать предобученный verifier-классификатор, например, roberta-large-mnli с правилами), тогда общее время ~5 ч.
9. Связанные вопросы из базы знаний
| Вопрос | Тема |
|---|---|
| 17 | Beam search decoding strategies |
| 24 | Chain-of-Thought prompting |
| 81 | Reward modeling for LLMs |
| 112 | Early exit decoding |
| 190 | Inference-time compute budgets |
| 245 | Self-consistency decoding |
| 301 | Process-supervised reward models |
| 412 | Verifier training with synthetic data |
| 567 | Pruning search trees in LLM generation |
| 689 | Token-level confidence estimation |
10. Чек-лист самопроверки
- Я понимаю, как verifier получает на вход шаг рассуждения и выдаёт вероятность корректности.
- Я реализовал beam search с возможностью прерывания путей по оценке verifier.
- Я обучил verifier на синтетических данных и убедился в его качестве (accuracy ≥0.8).
- Я сравнил VGD с greedy decoding на репрезентативной выборке и получил улучшение accuracy или сокращение числа токенов.
- Я задокументировал конфигурацию эксперимента и результаты так, чтобы их можно было воспроизвести.