Загрузка 0
ПОДЕЛИТЬСЯ

Мой блог

Листай вниз

Аудит предпочтений и дообучение языковых моделей с помощью DPO

Аудит предпочтений и дообучение языковых моделей с помощью DPO

Качественное дообучение языковых моделей требует выстроенного процесса настройки предпочтений от конца до конца с применением датасета Anthropic HH-RLHF и метода Direct Preference Optimization, известного как DPO. Работа начинается с подготовки надежного окружения в Google Colab, загрузки и разбора пар ответов, разделенных на предпочтительные и отвергнутые. На этом этапе проводится аудит датасета на наличие структурных предвзятостей и смещений, связанных с длиной текста.

Затем выполняются диагностические проверки лексических укороченных путей. Они помогают выяснить, способны ли поверхностные лингвистические паттерны надежно разделять удачные и забракованные варианты ответов. После этого специалисты подготавливают диалоговые данные, используя фильтрацию по длине с учетом особенностей токенизатора, и создают устойчивую к изменениям версий обучающую инфраструктуру DPO на базе библиотеки TRL и опциональной адаптации LoRA.

Финальная стадия включает в себя тонкую настройку модели Qwen2.5-0.5B-Instruct, оценку точности наград, анализ процесса обучения и поведения системы, а также проверку эффективности работы на отдельных подмножествах HH-RLHF. Кроме того, инженеры изучают потенциальное влияние длины ответов, генерируют контрольные примеры и сохраняют полученную политику для дальнейших экспериментов.

Для реализации этих задач требуется настроить программную среду. Ниже представлен базовый код для проверки и автоматической установки необходимых зависимостей в едином вызове менеджера пакетов pip:

import dataclasses
import importlib.util
import inspect
import os
import re
import subprocess
import sys
import warnings

warnings.filterwarnings("ignore", category=UserWarning)

REQUIRED = ["trl>=0.12", "transformers>=4.45", "accelerate", "datasets", "peft", "scikit-learn"]

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

def ensure_deps():
    try:
        import trl
        import transformers
        return False
    except ImportError:
        subprocess.check_call([sys.executable, "-m", "pip", "install", "-q", "-U", *REQUIRED])
        return True

Поскольку стандартная среда Colab по умолчанию содержит пакет torchao версии 0.10.0, а библиотека peft требует версию выше 0.16 и вызывает ошибки вместо пропуска, предусмотрена функция безопасного удаления этого компонента. Удаление неиспользуемой библиотеки безопаснее попытки обновления, так как последнее может повлечь за собой подтягивание несовместимой сборки PyTorch:

def drop_broken_torchao():
    if importlib.util.find_spec("torchao") is None:
        return False
    try:
        from peft.import_utils import is_torchao_available
        is_torchao_available()
        return False
    except ImportError:
        subprocess.call([sys.executable, "-m", "pip", "uninstall", "-y", "-q", "torchao"])
        return True
    except Exception:
        return False

В завершение подготовительного этапа выполняются объявленные функции проверки зависимостей, а система фиксирует изменения в конфигурации окружения для корректного запуска дальнейших процедур:

_installed = ensure_deps()
_removed = drop_broken_torchao() if not _installed else False
if _installed or _removed:
    print(" Environment changed.")

Подготовка окружения и конфигурация гиперпараметров

Подготовка рабочего окружения начинается с импорта необходимых библиотек и настройки параметров для последующих этапов. В этот набор входят инструменты для работы с массивами и таблицами данных, построения графиков, а также ключевые модули глубокого обучения и анализа текста: NumPy, Pandas, PyTorch, Matplotlib, библиотека датасетов и токенайзеры от Hugging Face, а также компоненты scikit-learn для оценки качества моделей с помощью логистической регрессии, метрик точности и ROC-AUC. Отдельное внимание уделяется библиотеке TRL и ее классам DPOConfig и DPOTrainer.

Для предотвращения конфликтов версий и возможных ошибок в коде предусмотрена функция patch_peft_torchao(). Она проверяет наличие модуля torchao и в случае возникновения проблем аккуратно нейтрализует проверки совместимости в библиотеке PEFT, исключая падение процесса при инициализации низкоранговой адаптации.

Настройка гиперпараметров и окружения

На этапе конфигурации фиксируются ключевые константы, определяющие поведение скрипта. В качестве базовой архитектуры выбрана модель Qwen/Qwen2.5-0.5B-Instruct. Для работы задействуются четыре подмножества датасета HH-RLHF: helpful-base, helpful-rejection-sampled, helpful-online и harmless-base. Из каждого подмножества для обучающей выборки берется по 120 примеров, а для тестовой — по 30.

Устанавливаются ограничения на длину последовательностей: максимальная длина текста составляет 512 токенов, а промпта — 256 токенов. Коэффициент предпочтения BETA фиксирован на отметке 0.1. Процесс обучения рассчитан на 30 шагов при размере батча, равном единице, и накоплении градиентов за 8 шагов. Скорость обучения установлена на уровне 5e-6 с долей шагов разогрева (warmup) в 10%. Логирование промежуточных результатов настроено каждые 5 шагов, использование LoRA активировано, а число шагов для оценки наград составляет 40. Для обеспечения воспроизводимости результатов фиксируется единый случайный сид (seed) со значением 17, а директория для сохранения результатов определяется динамически в зависимости от наличия папки /content.

Диагностика системы и проверка конфигурации

Функция report_environment() выполняет полную диагностику вычислительной среды. Она выводит актуальные версии Python, PyTorch, Transformers и TRL, а также определяет доступность графического процессора CUDA и поддержку смешанной точности bfloat16 или float16. Если полноценный ускоритель обнаружить не удается, система автоматически переключается на CPU с уведомлением о том, что обучение будет сокращено.

Дополнительно проводится инспекция совместимости классов конфигурации. Код проверяет, является ли DPOConfig подклассом TrainingArguments, подсчитывает общее число доступных полей конфигурации и сканирует расположение ключевых параметров, таких как warmup_ratio, warmup_steps, beta, max_length и max_prompt_length. Если структура конфигурации нарушена или отсутствуют базовые параметры вроде размера батча, скрипт выводит инструкцию по переустановке зависимостей одной командой.

В результате выполнения этого подготовительного этапа формируется стабильная программная среда, проверяются возможности аппаратного обеспечения и фиксируются режимы точности. Это позволяет перейти к следующему шагу — загрузке и обработке массива данных HH-RLHF для последующего дообучения языковых моделей.

Загрузка, парсинг и анализ датасета

Для формирования сбалансированных обучающих и тестовых наборов данных исследователи загружают выборки из различных подмножеств репозитория Anthropic HH-RLHF. Процесс автоматизирован с помощью функции выборки, которая перемешивает данные с заданным зерном генератора случайных чисел и выбирает фиксированное количество строк для каждого подраздела. К полученным частям добавляется колонка с указанием исходного подмножества, после чего тренировочные и тестовые массивы объединяются в единые датасеты с помощью операции конкатенации.

Следующим этапом становится синтаксический анализ диалогов. Текст каждой беседы разбивается регулярным выражением на отдельные реплики пользователей и ассистентов. Функция парсинга проверяет структуру текста: диалог должен корректно начинаться с реплики человека и завершаться ответом модели, роли участников должны строго чередоваться без пропусков, а сами сообщения не могут быть пустыми. При любых нарушениях логики последовательности беседа отсеивается.

Для каждой пары вариантов ответа проверяется ключевое условие: выбранный (chosen) и отклоненный (rejected) варианты должны опираться на абсолютно одинаковый предшествующий контекст диалога. Функция сопоставления выделяет общий промпт, а также разделяет финальные реплики ассистента на предпочтительную и отвергаемую версии, фиксируя количество поворотов диалога и метаданные источника. После применения фильтрации по признаку корректности формируются итоговые валидные наборы данных для обучения и тестирования, а также проводится проверка на наличие полностью идентичных пар завершений в тренировочной выборке.

Для глубокого анализа предпочтений создается структурированный датафрейм на базе Pandas, в который входят источники данных, количество реплик в диалоге (prompt turns), а также подсчет слов для выбранных (chosen) и отклоненных (rejected) вариантов ответа. На основе этих данных вычисляется разница в длине реплик (length delta), после чего формируется сводная таблица в разрезе конкретных источников. В ней подсчитываются общее число пар, средние показатели длины для обоих типов ответов, медианное значение глубины диалогов и средняя разница в длине, причем все численные результаты аккуратно округляются до двух знаков после запятой.

Для наглядной визуализации полученных метрик строятся графики с помощью библиотек Matplotlib и Seaborn. Создается парное полотно визуализации: на первом графике в виде горизонтальной гистограммы отображается средняя разница в длине между предпочтительными и отклоненными вариантами ответов с вертикальной линией отсчета на нулевой отметке, а на втором графике выводятся распределения этих разниц в виде ступенчатых гистограмм с разделением по исходным датасетам. Кроме того, перед дальнейшей обработкой выводится санированный структурный превью-набор без публикации пользовательского текста, демонстрирующий метаданные первых трех записей: источник, число шагов промпта и объем слов в обеих версиях.

Проверка на текстовые шаблонные искажения

Чтобы выявить возможные поверхностные закономерности, реализована функция построения лексического датасета. Тексты выбранных и отклоненных ответов объединяются в общий массив, для них формируются бинарные метки (единицы для качественных ответов и нули для отклоненных), а также уникальные идентификаторы пар. Валидационные проверки гарантируют корректность объединения массивов и распределение меток в соответствии с логикой задачи.

Затем запускается диагностическая процедура с использованием логистической регрессии. Датасет случайным образом делится на две равные части на уровне пар, чтобы предотвратить утечку данных между обучающей и тестовой выборками. Текстовые данные векторизуются с помощью TF-IDF с учетом униграм и биграм, ограничением минимальной частотности терминов до двух и максимальным количеством признаков в 20 000 при сублинейном масштабировании частоты термов. Модель обучается на тренировочной части и оценивается на тестовой с расчетом точности (accuracy) и площади под ROC-кривой (ROC-AUC).

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

Для проверки надежности полученной метрики AUC проводится контрольный тест с перемешанными метриками. Если показатель на реальных данных находится в пределах шумовых значений относительно случайного базового уровня с перемешанными метриками, делается вывод об отсутствии заметных лексических подсказок. Значение ниже случайного уровня указывает на необходимость проверки порядка меток на предыдущих этапах подготовки данных, а существенное превышение случайного порога свидетельствует о наличии реальных лексических особенностей, которые модель может использовать в качестве подсказки.

В завершение этого диагностического этапа извлекаются и сортируются по модулю 20 наибольших коэффициентов логистической регрессии, что позволяет оценить диапазон весов ключевых признаков. Сами текстовые строки признаков намеренно не выводятся в консоль, так как исходный корпус может содержать ненормативную или нежелательную лексику. Такой аудит позволяет детально исследовать собранные пары предпочтений, оценить разницу в объемах генерируемых ответов, глубину диалогов и особенности поведения моделей в зависимости от конкретного источника данных при проведении процедур, сопутствующих эффективное дообучение языковых моделей.

Исследователи также обучают диагностическую модель на основе TF-IDF и логистической регрессии, чтобы проверить, способны ли простые лексические паттерны разделять предпочтительные и отклоненные ответы. Это позволяет выявлять обходные пути, которыми нейросеть может воспользоваться вместо освоения целевого сигнала предпочтений.

Подготовка диалоговых данных и запуск DPO

На следующем этапе необходимо подготовить данные для диалогового формата DPO. Процесс начинается с инициализации токенайзера через AutoTokenizer.from_pretrained(MODEL_ID). Если у выбранного токенайзера отсутствует встроенный токен заполнения, в качестве pad_token устанавливается eos_token. Для структурирования диалогов в формате ChatML задается специальный шаблон разметки:

CHATML = ("{% for m in messages %}" "{{ '<|im_start|>' + m['role'] + '\n' + m['content'] + '<|im_end|>\n' }}" "{% endfor %}" "{% if add_generation_prompt %}{{ '<|im_start|>assistant\n' }}{% endif %}")

Если у используемого токенайзера не обнаруживается стандартный шаблон чата, система автоматически задействует подготовленный шаблон ChatML в качестве резервного варианта. Затем создается вспомогательная функция add_lengths. Она применяет шаблон чата к элементам промпта без токенизации, после чего вычисляет количество токенов для самого промпта, а также для предпочтительного (chosen) и отвергнутого (rejected) ответов. Итоговое суммарное значение длины формируется как сумма токенов промпта и максимальной длины одного из ответов.

С помощью фильтрации fits отсеиваются те примеры, которые превышают установленные лимиты MAX_PROMPT_LENGTH и общей длины MAX_LENGTH. После применения фильтра к обучающей и тестовой выборкам формируются списки источников, промптов и вариантов ответов. Датасеты очищаются от лишних колонок, оставляя только базовые поля, необходимые для алгоритма прямых предпочтений: prompt, chosen и rejected. В консоль выводятся итоговые размеры выборок, прошедших фильтрацию по числу токенов, а также схема данных тренировочного набора.

Настройка конфигурация и инициализация трейнера

Для корректного распределения аргументов между доступными версиями библиотек применяется функция разделения параметров split_kwargs. Функция build_dpo_config обрабатывает переданный словарь конфигурации. Если в параметрах обнаруживается warmup_ratio, но целевая библиотека ожидает warmup_steps, этот коэффициент автоматически пересчитывается в количество шагов разогрева (не менее единицы) на основе общего числа шагов max_steps. Неподдерживаемые или лишние параметры безопасно отсеиваются, а параметры, предназначенные непосредственно для трейнера, перенаправляются в отдельный блок.

Базовый словарь аргументов включает каталог для сохранения результатов output_dir, максимальное количество шагов max_steps, размеры батчей для обучения и оценки на одном устройстве, шаги накопления градиента gradient_accumulation_steps, скорость обучения, частоту логирования, стратегию сохранения без записи промежуточных чекпоинтов, отключение внешних систем отчетности, сохранение неиспользуемых колонок, использование шестнадцатибитной точности в форматах bfloat16 или float16, фиксированное зерно генерации случайных чисел seed, коэффициент бета, а также ограничения длины промптов и общей последовательности. После вызова функции конфигурация DPO считается успешно построенной.

На следующем шаге инициализируется языковая модель с помощью функции build_model. В зависимости от флага BF16 выбирается тип данных torch.bfloat16 или стандартный torch.float32. Загрузка весов производится через AutoModelForCausalLM.from_pretrained с учетом поддерживаемых версий библиотек. Для оптимизации памяти кэш генерации модели отключается.

Если активирован флаг использования метода адаптации Low-Rank Adaptation (USE_LORA), система пытается импортировать конфигурацию LoraConfig из пакета peft. Задаются базовые гиперпараметры адаптера: ранг r=16, коэффициент масштабирования lora_alpha=32, уровень отсечения lora_dropout=0.05, отсутствие смещения (bias="none") и тип задачи CAUSAL_LM. В этом случае замороженная базовая модель одновременно выполняет роль референсной модели. Если библиотека peft отсутствует, выполняется полноценное дообучение языковых моделей с явным указанием отдельной референсной модели.

Финальная сборка трейнера инкапсулирована в функцию build_trainer. Она формирует словарь аргументов, куда передаются сама модель, конфигурация, тренировочный и оценочный датасеты. В зависимости от поддерживаемых параметров текущей версии библиотеки TRL, токенайзер передается либо через аргумент processing_class, либо через классический tokenizer. Аналогичным образом подключается конфигурация PEFT или явно сбрасывается референсная модель. После применения патчей оптимизации и вызова класса DPOTrainer процесс подготовки завершается успешным создания рабочего объекта трейнера.

На завершающем этапе мы применяем диалоговый шаблон для чата и вычисляем длину токенов для каждой пары предпочтений. Происходит фильтрация примеров, выходящих за рамки ограничений промпта или общей длины последовательности, после чего в динамическом режиме формируются аргументы конфигурации DPO с учетом установленной версии библиотеки TRL. Далее мы загружаем базовую модель, при необходимости настраиваем LoRA и создаем DPO-тренер, который непосредственно используется для процедур оптимизации.

Процесс запускается с выводом параметров: указывается общее число шагов обучения, используемое устройство, а также эффективный размер батча, рассчитываемый как произведение размера батча на коэффициент накопления градиентов. По завершении работы алгоритма система выводит детальные метрики тренировки в отсортированном виде. Аналогичным образом оцениваются результаты на отложенном наборе пар предпочтений, где выводятся ключевые показатели, такие как точность, маржа наград, значения наград и функция потерь с точностью до четырех знаков после запятой для вещественных чисел.

Для наглядного анализа истории обучения данные из журнала состояний тренера переносятся в структуру DataFrame. При наличии столбца потерь строится график зависимости показателей от шага оптимизации с добавлением кривой точности наград, если таковая присутствует в логах. На графике также наносится вспомогательная пунктирная линия на уровне 0,5, подписываются оси, добавляется легенда и заголовок. Итоговое обучение модели методом прямой оптимизации предпочтений проходит с задействованием заданных параметров скорости обучения, шагов и размеров батчей, позволяя всесторонне оценить динамику обучения и итоговое качество политики.

Оценка результатов, анализ наград и сохранение модели

Для оценки работы алгоритма применяется программный код, вычисляющий логарифмические вероятности генерации текста. Функция completion_logprob принимает языковую модель, историю сообщений промпта, вариант ответа и флаг использования референсной модели. Сначала формируется единый текстовый шаблон диалога с добавлением токена окончания последовательности. Затем вычисляются индексы токенов для промпта и всего текста с учетом ограничения максимальной длины. С помощью механизма контекстных адаптеров функция способна временно отключать LoRA-слои, чтобы получить логарифмические вероятности как от обученной, так и от исходной базовой модели. Полученные логиты преобразуются в лог-вероятности с помощью функции torch.log_softmax, после чего суммируются вероятности токенов ответа, исключая служебную часть промпта.

Следующий аналитический инструмент — функция per_source_reward_accuracy — позволяет оценить точность наград в разрезе отдельных источников данных из тестовой выборки. Если у модели отсутствуют отключение адаптеров и отдельная референсная модель, выполнение анализа пропускается. Из тестовых источников случайным образом выбирается подмножество пар для оценки. Для каждого примера вычисляются лог-вероятности предпочтенного и отклоненного ответов как для текущей политики, так и для референсного состояния. На основе этих данных рассчитывается марржа наград, флаг правильности ранжирования, а также разница в длине между выбранным и отклоненным текстами. Полученные показатели агрегируются в таблицу с помощью библиотеки pandas, где для каждого источника выводятся размер выборки, точность наград, средняя маржа и средняя разница в длине ответов.

Важным аспектом оценки является проверка на так называемый «фактор длины», когда модель склонна выбирать более длинные ответы независимо от их смыслового наполнения. Код вычисляет согласованность между предпочтениями модели и превосходством выбранного ответа по количеству слов. Значение около 0,5 указывает на отсутствие такого системного смещения, тогда как показатель, близкий к 1,0, свидетельствует о том, что языковая модель ранжирует варианты преимущественно по их объему. После завершения расчетов функция выводит результаты в консоль и возвращает сводную таблицу.

Для проверки практических навыков обученной системы используется функция генерации текстовых ответов generate. Она принимает список сообщений и ограничение на максимальное число новых токенов. Генерация запускается в режиме отключенного градиентного счета без применения случайного сэмплирования, что гарантирует детерминированность ответов. В качестве тестовых промптов выступают два характерных запроса: первый касается поиска причин шума вентилятора ноутбука, а второй требует краткого объяснения из двух предложений о том, почему метод DPO обходится без отдельной модели оценки наград. Полученные варианты выводятся в консоль для визуальной проверки качества работы алгоритма.

Завершающим этапом работы скрипта является сохранение результатов выполнения. Обученная модель сохраняется в указанную директорию вместе с токенайзером. В заключительных примечаниях разработчики подчеркивают специфику интерпретации полученных данных. При ограничении в 30 шагов на центральном процессоре процесс носит исключительно тестовый характер, а показатель точности наград около 0,5 является ожидаемым. Для полноценного обучения и серьезных выводов необходимо увеличить количество шагов и запустить скрипт на графическом ускорителе, уделяя особое внимание детальному анализу таблиц по каждому источнику данных.

Если точность вознаграждения для безобидной базы падает на фоне роста полезных подмножеств, это сигнализирует о том, что политика усваивает асимметрию длины, выявленную при аудите в пятом разделе, а не целевое предпочтение. В случае сбоя вызова TRL после обновления среды верхний отчет подсказывает, какой класс принимает конкретный аргумент в вашей сборке, позволяя расширить список wanted_args на основе этих данных. Процесс включает расчет точности вознаграждения для каждого источника и сопоставление логарифмов вероятностей целевой и опорной моделей для проверки подлинного предпочтения выбранных вариантов. Специалисты анализируют связь между решениями о предпочтениях и расхождениями в длине ответов, а затем генерируют тестовые примеры для качественной оценки поведения настроенной политики.

Завершающим этапом становится сохранение обученной модели и токенизатора для повторного применения полученной политики DPO в будущих экспериментах. Разработанный конвейер обучения предпочтениям на базе DPO выходит далеко за рамки простого дообучения языковых моделей на парах из выбранных и отвергнутых ответов. В ходе работы проводился анализ данных HH-RLHF на предмет асимметрии длины и лексических уловок, обеспечивалось единообразие формата диалогов и лимитов токенов, а гибкая конфигурация обучения адаптировалась к особенностям версий TRL и Transformers.

Оценка обученной политики на общем уровне и в разрезе отдельных источников позволила определить, отражают ли улучшения подлинное освоение предпочтений или нежелательные обходные пути вроде склонности к более длинным текстам. Сочетание аудита наборов данных, диагностического анализа, эффективного DPO-обучения с применением LoRA, оценки вознаграждений и генеративного тестирования формирует надежную методологическую базу для исследования и оптимизации выравнивания предпочтений в современных языковых моделях.

Автором материала выступает Сана Хассан (Sana Hassan), стажирующийся консультант в Marktechpost и студентка совместной программы обучения в IIT Madras, которая специализируется на внедрении искусственного интеллекта для решения прикладных задач.

Источник: marktechpost.com

Оставить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *

01.
На платформе MonsterInsights