Дообучение LLM на вашей разметке
Обучите LLM методом SFT или DPO, модель вознаграждения или модель вознаграждения за процесс на собственных метках исследования, оцените каждую на отложенных объектах и опубликуйте на Hub.
Новое в v2.14.0
Этот учебник обучает четыре вида языковых моделей на ответах, которые собирает исследование в Potato. Тренер llm-sft дообучает LLM на написанных ответах или исправленных трассах агента, llm-dpo настраивает LLM по парным выборам, reward-model подгоняет скалярную модель вознаграждения по сравнениям, а prm-reward подгоняет модель вознаграждения за процесс по оценкам шагов. Страница написана для команд, которые уже собирают в Potato данные о предпочтениях или трассы и хотят получить первую модель по этим меткам без экспорта данных в отдельный скрипт обучения. Каждый раздел называет схему, которая даёт данные, приводит конфигурацию, проходящую проверку валидатором Potato, перечисляет параметры, которые стоит менять, и объясняет, что измеряет оценка на отложенных объектах и возвращаются ли предсказания разметчикам как предварительные метки. Обзор обучения моделей описывает страницу Training, а Обучите первую модель проходит весь цикл с классификатором, которому не нужен GPU.
Тренеры по схемам разметки
Каждый тренер на этой странице учится на одной схеме разметки за запуск, а страница Training предлагает тренера только для тех схем, на которых он может учиться. В таблице ниже перечислены схемы, на которых учится каждый тренер:
| Тренер | Схема | Чему учится модель | Главная оценка на отложенных объектах | Показывается разметчикам |
|---|---|---|---|---|
llm-sft | text | писать ответ, который написали разметчики | token F1 | да, сгенерированный ответ заполняет текстовое поле |
llm-sft | trajectory_edit | переписывать шаги агента в исправленные шаги | closer_to_correction | нет, только сохраняется и оценивается |
llm-dpo | pairwise в режиме binary | предпочитать ответ, который выбрали разметчики | accuracy без учёта ничьих | да, выбирается карточка предпочтительного ответа |
llm-dpo | trajectory_edit | предпочитать исправленные шаги исходным | closer_to_correction | нет, только сохраняется и оценивается |
reward-model | pairwise (binary и scale), ranking, bws | оценку для каждого ответа | accuracy, direction accuracy, тау Кендалла или best-worst accuracy | да, как собственный ответ схемы |
prm-reward | process_reward | оценку correct, neutral или wrong для каждого шага | step_macro_f1 | предлагается кнопкой "AI pre-label steps" |
Перед началом
Дополнительные пакеты обучения Potato ставят PyTorch, Transformers и PEFT для четырёх тренеров:
pip install "potato-annotation[train-llm]"
pip install "potato-annotation[train-text]"Первая группа покрывает llm-sft и llm-dpo, а вторая покрывает reward-model и prm-reward. Команда pip install "potato-annotation[train]" ставит все группы обучения сразу. Тренер, у которого не хватает пакетов, показывается на странице Training как "not installed" вместе с командой, которая ставит эти пакеты.
Каждый тренер отказывается обучаться, если в выборке train меньше 20 объектов (параметр min_instances). Разбиение по умолчанию отдаёт 70% размеченных объектов в train, 15% в val и 15% в test, поэтому до первого запуска стоит запланировать около 30 размеченных объектов. Объекты val и test отложены от обучения и служат для оценки модели.
llm-sft и llm-dpo стартуют с Qwen/Qwen2.5-0.5B-Instruct, reward-model с distilbert/distilroberta-base, а prm-reward с answerdotai/ModernBERT-base. LLM-тренеры рассчитаны на работу на GPU. Если на машине, где работает Potato, нет GPU, удалённое обучение отправляет запуски на GPU-сервер по ssh или на кластер SLURM.
Исследование, которое собирает предпочтения и переписанные ответы
Первая конфигурация задаёт два вопроса к каждому запросу в службу поддержки. Разметчики выбирают лучший из двух ответов и пишут ответ, который разметчик хотел бы получить от ассистента. Выбор обучает llm-dpo и reward-model, а написанный ответ обучает llm-sft. Каждая строка data/answers.jsonl содержит запрос и два ответа:
{"id": "q001", "prompt": "How do I reset my router to factory settings?", "responses": ["Hold the reset button on the back for 10 seconds until the lights blink, then wait two minutes for the router to restart.", "Routers can be reset. Check the manual."]}Конфигурация показывает запрос как текст объекта, а два ответа как карточки A и B:
annotation_task_name: "Support answers: preferences and rewrites"
task_dir: .
data_files:
- data/answers.jsonl
item_properties:
id_key: id
text_key: prompt
output_annotation_dir: annotation_output
user_config:
allow_all_users: true
annotation_schemes:
- annotation_type: pairwise
name: preferred
description: "Which response answers the question better?"
mode: binary
items_key: responses
allow_tie: true
tie_label: "No preference"
- annotation_type: text
name: rewrite
description: "Write the answer you would want the assistant to give."
multiline: true
rows: 4
model_training:
enabled: true
writeback:
schemas: [preferred]
min_confidence: 0.7text_key: prompt важен дважды, потому что запрос читают разметчики, и его же llm-sft ставит после вопроса. items_key: responses называет список, из которого берутся карточки pairwise, в порядке данных, так что A это первый ответ. В writeback.schemas указана только preferred, поэтому разметчики видят выбор модели, а не сгенерированный переписанный ответ. Предварительные метки привязывают разметчиков к себе, поэтому добавляйте rewrite в список, только когда оценка запуска llm-sft на отложенных объектах оправдывает показ текста модели. min_confidence: 0.7 убирает со страницы предсказания, в которых модель менее уверена, но продолжает их сохранять. Проверьте конфигурацию валидатором Potato до запуска сервера:
python -m potato.validate_cli config.yaml --strictЗапустите Potato, разметьте не менее 30 запросов и откройте /admin/training как администратор. Запуски ниже можно начать и через API с admin_api_key из конфигурации в $KEY.
Обучение с учителем с llm-sft
llm-sft превращает каждый размеченный объект в один обучающий пример. Запрос состоит из description схемы (вопроса, который видели разметчики) и следующего за ним текста объекта, а целью служит ответ, который написал разметчик. Функция потерь охватывает только токены ответа, поэтому модель учится отвечать, а не повторять запрос. По умолчанию обучается адаптер LoRA, а не все веса.
Выберите на странице Training llm-sft и схему rewrite и нажмите Train now или начните тот же запуск через API:
curl -X POST -H "X-API-Key: $KEY" -H "Content-Type: application/json" \
http://localhost:8000/admin/training/api/runs \
-d '{"trainer": "llm-sft", "schemas": ["rewrite"], "params": {"max_new_tokens": 256}}'Большинство запусков меняет только параметры из этой таблицы:
| Параметр | По умолчанию | Значение |
|---|---|---|
model_name | Qwen/Qwen2.5-0.5B-Instruct | Каузальная языковая модель на Hugging Face Hub или локальный каталог. |
lora | true | false обучает все веса и требует в несколько раз больше памяти. {quantize: 4bit} загружает базовую модель в 4 битах (см. QLoRA). |
max_length | 1024 | Токенов на пример. Длинный запрос теряет токены с начала, а ответ сохраняется. |
max_new_tokens | 256 | Самый длинный ответ, который генерирует модель. |
instruction | description схемы | Текст, который ставится перед текстом каждого объекта. |
system_prompt | нет | Системное сообщение для моделей с шаблоном чата. |
gradient_checkpointing | false | Экономит память активаций ценой примерно на треть большего времени. |
learning_rate | 2e-4 с LoRA, 1e-5 без LoRA |
Запуск сохраняет контрольную точку с наименьшей потерей на val. Поскольку запуск выбрал контрольную точку по val, оценка на отложенных объектах считается на test. Оценка это token F1, то есть пересечение слов сгенерированного и написанного ответов независимо от порядка, а рядом с оценкой выводится exact match. Token F1 засчитывает ответ, в котором нужные слова стоят не на тех местах, поэтому читайте обе метрики вместе.
Модель жадно генерирует ответ для каждого объекта val и test. При writeback.include_unlabeled: true модель отвечает и на объекты, которые никто не разметил. Уверенность предсказания это средняя вероятность токенов, которые сгенерировала модель, и очередь проверки модели сортируется по этой уверенности. Если rewrite указана в writeback.schemas, сгенерированный ответ заполняет текстовое поле, когда разметчик открывает объект.
Свободный текст плохо подходит для нескольких разметчиков на объект. Параметр aggregation сводит несколько ответов в один, сравнивая ответы слово в слово, а два написанных ответа редко совпадают слово в слово. Для llm-sft на схеме text один автор на объект позволяет обойтись без сравнения слово в слово.
Настройка по предпочтениям с llm-dpo
Direct Preference Optimization (DPO) учит LLM повышать правдоподобие предпочтительного ответа относительно другого ответа, сравнивая с замороженной эталонной копией исходной модели. llm-dpo строит один пример из каждого объекта, на который ответили A или B. Запрос это поле prompt объекта или первое из полей question, instruction, query, input и context, которое есть у объекта. Объекты, на которые ответили вариантом ничьей, исключаются, потому что ничья не отмечает ни один ответ как лучший.
Выберите llm-dpo и схему preferred или отправьте тот же запрос, что выше, с "trainer": "llm-dpo" и "schemas": ["preferred"]. С адаптером LoRA по умолчанию эталонная модель это та же модель с выключенным адаптером, поэтому вторая копия в памяти не хранится. lora: false обучает все веса и держит замороженную копию как эталон, и замороженная копия удваивает память.
| Параметр | По умолчанию | Значение |
|---|---|---|
model_name | Qwen/Qwen2.5-0.5B-Instruct | Каузальная языковая модель. |
beta | 0.1 | Насколько далеко модель может уйти от эталона. Меньшее значение позволяет модели уйти дальше. |
epochs | 2 | |
learning_rate | 5e-5 с LoRA, 5e-7 без LoRA | |
max_length | 1024 | Токенов на запрос и ответ. |
instruction | нет | Текст, который ставится перед запросом каждого объекта. |
Запуск сохраняет контрольную точку с наименьшей потерей DPO на val, а журнал запуска сообщает, как часто модель предпочитает выбор разметчиков на val. Оценка на отложенных объектах это accuracy на test по объектам, на которые не ответили ничьей, а рядом с accuracy выводится macro-F1. Предсказание это ответ, который предпочитает обученная модель, а уверенность это вероятность этого предпочтения. Как предварительная метка выбирается карточка предпочтительного ответа, когда разметчик открывает объект. При randomize_order в схеме выбор следует за ответом туда, где разметчик его видит. Сохранённый адаптер тоже является политикой и генерирует текст при загрузке через PEFT. О сборе самих данных о предпочтениях см. Сбор данных RLHF и предпочтений и Парное сравнение.
Модель вознаграждения с reward-model
Модель вознаграждения сопоставляет ответу число, для RLHF, для выборки best-of-n или для ранжирования новых выводов. reward-model обучает трансформер с одним выходом так, чтобы ответ, который предпочли разметчики, получал более высокую оценку. Функция потерь это потеря Брэдли — Терри, -log sigmoid(r_winner - r_loser), потеря обучения вознаграждения из InstructGPT. Схема preferred выше обучает reward-model без изменений в конфигурации. Каждая сравнительная схема даёт свой обучающий сигнал:
| Схема | Обучающий сигнал | Главная оценка на отложенных объектах |
|---|---|---|
pairwise, binary | Выбранный ответ превосходит другой. Ничьи пропускаются. | accuracy |
pairwise, scale | Побеждает сторона, в которую склоняется ползунок, с весом по величине наклона. Середина пропускается. | direction accuracy |
ranking | Весь порядок, через потерю Плакетта — Люса, или каждая пара в порядке при ranking_loss: pairs. | тау Кендалла |
bws | Лучший объект превосходит все остальные в кортеже, и все остальные превосходят худший. | best-worst accuracy |
Если у объекта есть поле запроса, каждое вознаграждение относится к ответу при данном запросе. Варианты ранжирования это метки схемы, и каждая оценивается при данном тексте объекта. Сервер строит кортежи BWS из bws_config, поэтому запуск на собственных данных сервера уже имеет кортежи, и в файлах данных кортежи не нужны.
| Параметр | По умолчанию | Значение |
|---|---|---|
model_name | distilbert/distilroberta-base | Энкодер или LLM с lora. |
ranking_loss | plackett_luce | Только для схем ranking: plackett_luce или pairs. |
max_length | 512 | Токенов на оцениваемый текст, запрос и ответ вместе. |
learning_rate | 2e-5 или 2e-4 с LoRA |
Предсказания отвечают на собственный вопрос схемы, поэтому их оценивают и записывают обратно так же, как для любой другой схемы. Предварительная метка это выбранная карточка для бинарного выбора, положение ползунка для шкалы, порядок списка для ранжирования, а для BWS выбранные лучший и худший. Каждое предсказание сохраняет и rewards, из которых оно получено. Значимы только разности вознаграждений. Парное сравнение и Best-Worst Scaling сравнивает форматы сравнения для сбора данных.
Исследование, которое собирает оценки шагов и исправления
Вторая конфигурация работает с трассами агента. Разметчики оценивают каждый шаг трассы, а затем исправляют неверные шаги. Оценки шагов обучают prm-reward, а исправления обучают llm-sft или llm-dpo. Каждая строка data/traces.jsonl содержит задачу, шаги агента и итоговый ответ:
{"id": "traj_001", "task_description": "Find the current weather in San Francisco and report the temperature.", "steps": [{"thought": "I should look up the current weather.", "action": "web_search(queyr='San Francisco weather')"}, {"thought": "Open the first result.", "action": "open_url(results[0])"}, {"thought": "Read the temperature from the page.", "action": "extract_text('.temp')"}], "final_answer": "It is sunny."}Тренеры читают задачу из поля task_description, task или text объекта, именно в таком порядке:
annotation_task_name: "Agent traces: step ratings and corrections"
task_dir: .
data_files:
- data/traces.jsonl
item_properties:
id_key: id
text_key: task_description
output_annotation_dir: annotation_output
user_config:
allow_all_users: true
annotation_schemes:
- annotation_type: process_reward
name: step_quality
description: "Rate each step of the agent's trace"
steps_key: steps
step_text_key: action
mode: per_step
allow_neutral: true
ai_prelabel: true
- annotation_type: trajectory_edit
name: corrected_trace
description: "Fix the wrong steps, then correct the final answer"
steps_key: steps
step_text_key: action
editable_fields: [action]
show_diff: true
edit_final_answer: true
final_answer_key: final_answer
model_training:
enabled: true
writeback:
schemas: [step_quality]
include_unlabeled: truemode: per_step с allow_neutral: true даёт три оценки, которым учится prm-reward. ai_prelabel: true добавляет в схему кнопку "AI pre-label steps", и обученные оценки появляются через эту кнопку. В writeback.schemas указана только step_quality. Если указать там corrected_trace, сервер не запустится, а валидатор назовёт причину:
model_training.writeback.schemas names 'corrected_trace', a trajectory_edit scheme, which has no prelabel display: its predictions are stored and scored but annotators would never see them. Leave it out of writeback.schemas.Исправление трасс с llm-sft и llm-dpo
Ответ trajectory_edit это пара трасс, исходные шаги агента и шаги после исправлений разметчика. Редактирование траекторий для SFT/DPO описывает редактор, а запись о редактировании траекторий описывает, как пары становятся обучающими данными. Оба тренера исключают трассы, которые никто не правил.
llm-sftберёт задачу и исходные шаги как запрос, а исправленные шаги как цель, поэтому модель учится исправлять трассу. Каждый шаг записывается какStep Nи следующие за ним поля шага (action: ...,thought: ...), а итоговый ответ идёт после последнего шага, если у схемы естьfinal_answer_key.llm-dpoберёт задачу как запрос, исправленные шаги как предпочтительный ответ, а исходные шаги как другой ответ. Предсказание говорит, предпочитает ли модель исправление (A) или оригинал (B), и делается только для отложенных трасс, у которых есть исправление.
Оба запуска сообщают closer_to_correction как оценку на отложенных объектах. Для llm-dpo оценка это доля отложенных трасс, в которых модель предпочитает исправление. Для llm-sft оценка это доля трасс, в которых написанные шаги ближе к исправлению, чем к оригиналу, по token F1, а рядом с оценкой выводится token_f1 относительно исправления.
Предсказания запуска trajectory_edit сохраняются и оцениваются, а разметчики их не видят. Редактор всегда начинает с исходной трассы агента, поэтому на странице нет места для предсказанного переписанного варианта. Читайте предсказания на странице запуска или в artifacts/predictions.jsonl в каталоге запуска.
Оценки шагов с prm-reward
Модель вознаграждения за процесс оценивает шаги трассы, а не только итоговый ответ, как в PRM800K. prm-reward подаёт в трансформер-энкодер всю трассу как один вход, задачу и затем Step 1, Step 2 и так далее. Энкодер учит трёхклассовую оценку на последнем токене каждого шага, так что каждая оценка делается с учётом предшествующих шагов. Шаги, которые никто не оценил, исключаются из функции потерь. Модель по умолчанию, answerdotai/ModernBERT-base, выбрана за контекст в 8 192 токена.
| Параметр | По умолчанию | Значение |
|---|---|---|
model_name | answerdotai/ModernBERT-base | Энкодер с быстрым токенизатором. |
max_length | 1024 | Токенов на трассу. |
epochs | 6 | |
batch_size | 8 | Трасс на шаг. |
learning_rate | 5e-5 или 3e-4 с LoRA |
Длинные трассы теряют последние шаги. Трасса длиннее max_length токенов обрезается с конца, а шаги за обрезкой не участвуют в обучении и не оцениваются. Журнал запуска считает потерянные шаги. Если max_length больше, чем вмещает модель, запуск снижает max_length до предела модели с предупреждением, и для большинства энкодеров класса BERT этот предел равен 512 токенам. Если журнал запуска сообщает о потерянных шагах, увеличьте max_length и выберите модель, контекст которой вмещает более длинные трассы.
Оценка на отложенных объектах это step_macro_f1, macro-F1 по трём оценкам на каждом оценённом шаге. Большинство шагов в большинстве трасс верны, поэтому accuracy польстила бы модели, которая никогда не говорит "wrong". Запуск также сообщает step_accuracy и first_error_accuracy, то есть долю трасс, в которых первый неверный шаг модели совпадает с первым неверным шагом разметчиков.
Предсказание оценивает каждый шаг, который помещается в max_length, с вероятностью каждой оценки как уверенностью в ней и наименее уверенным шагом как уверенностью в трассе. Если схема указана в writeback.schemas и задан ai_prelabel: true, кнопка "AI pre-label steps" предлагает обученные оценки разметчику на проверку. LLM-судья, настроенный в ai_support, не вызывается для объекта, у которого есть обученные оценки. Разметка вознаграждения за процесс описывает схему, а руководство по моделям вознаграждения за процесс описывает данные.
Обучение более крупной модели с QLoRA
QLoRA загружает веса базовой модели в 4 битах и обучает поверх них адаптер LoRA. llm-sft, llm-dpo, hf-text-classification, vlm-sft и reward-model принимают lora: {quantize: 4bit}, а prm-reward отклоняет эту настройку до загрузки модели. Планируйте память по строке "Peak GPU memory", которую в конце записывает каждый запуск трансформера. Раздел о QLoRA в справочнике конфигурации описывает, как загружаются базовые веса, и вариант с 8 битами.
Добавьте этот блок в конфигурацию выше, чтобы сделать QLoRA настройкой по умолчанию для llm-sft:
model_training:
enabled: true
trainer_params:
llm-sft:
model_name: Qwen/Qwen2.5-7B-Instruct
lora: {quantize: 4bit}
gradient_checkpointing: trueQLoRA требует GPU с CUDA и сборку bitsandbytes для CUDA этой машины, установленную командой pip install bitsandbytes. Без работающего GPU или подходящей сборки запуск останавливается на проверке до загрузки модели.
Публикация запуска на Hugging Face Hub
У успешного запуска, модель которого лежит на сервере Potato, на странице запуска есть Publish to the Hugging Face Hub. Публикация загружает модель и README.md с карточкой модели, составленной по запуску, с тренером, базовой моделью и адаптером, схемами и метками, размерами выборок, оценкой на отложенных объектах и тем, на чём она измерена, а также идентификаторами запуска и пакета. Запуск LoRA сохранил только адаптер, поэтому репозиторий на Hub содержит адаптер, а карточка называет базовую модель, на которую нужно загрузить адаптер.
Токен остаётся вне браузера. Создайте токен с правом записи в настройках Hugging Face и задайте его в окружении сервера до запуска Potato:
export HF_TOKEN=hf_your_write_token
potato start config.yamlФорма называет переменную окружения, по умолчанию HF_TOKEN, дважды запрашивает имя репозитория и по умолчанию оставляет отмеченным Private. Публикация на Hugging Face Hub перечисляет файлы, которые загружаются, проверки перед публикацией и лицензию в карточке модели. Та же публикация через API:
curl -X POST -H "X-API-Key: $KEY" -H "Content-Type: application/json" \
http://localhost:8000/admin/training/api/runs/RUN_ID/push-to-hub \
-d '{"repo_id": "your-org/support-dpo", "confirm_repo_id": "your-org/support-dpo", "private": true, "licence": "apache-2.0"}'Маршрут возвращает 201 с коммитом. Модель, оставленную на удалённом хосте с fetch_artifacts: false, нельзя опубликовать с сервера Potato, и страница запуска сообщает, где лежит модель. Чтобы перейти от опубликованной модели к циклу активного обучения, продолжите с Модель в цикле разметки.
Дополнительные материалы
- Конфигурация обучения моделей: каждый ключ
model_training, оценки на отложенных объектах, обратная запись и маршруты. - Тренеры: все 38 тренеров по задачам.
- Удалённое обучение: GPU-серверы по ssh, кластеры SLURM и агент опроса.
- Разметка траекторий агентов: сбор данных трасс в Potato.
- Разделы справочника upstream для
llm-sft,llm-dpo, трасс агентов,prm-reward,reward-model, QLoRA и публикации на Hub.
Источники
- Dettmers, T., Pagnoni, A., Holtzman, A., and Zettlemoyer, L. (2023). QLoRA: Efficient Finetuning of Quantized LLMs. arXiv:2305.14314. arxiv.org/abs/2305.14314
- Hu, E. J., Shen, Y., Wallis, P., Allen-Zhu, Z., Li, Y., Wang, S., Wang, L., and Chen, W. (2021). LoRA: Low-Rank Adaptation of Large Language Models. arXiv:2106.09685. arxiv.org/abs/2106.09685
- Lightman, H., Kosaraju, V., Burda, Y., Edwards, H., Baker, B., Lee, T., Leike, J., Schulman, J., Sutskever, I., and Cobbe, K. (2023). Let's Verify Step by Step. arXiv:2305.20050. arxiv.org/abs/2305.20050
- Ouyang, L., Wu, J., Jiang, X., Almeida, D., Wainwright, C. L., Mishkin, P., Zhang, C., Agarwal, S., Slama, K., Ray, A., Schulman, J., Hilton, J., Kelton, F., Miller, L., Simens, M., Askell, A., Welinder, P., Christiano, P., Leike, J., and Lowe, R. (2022). Training Language Models to Follow Instructions with Human Feedback. arXiv:2203.02155. arxiv.org/abs/2203.02155
- Rafailov, R., Sharma, A., Mitchell, E., Ermon, S., Manning, C. D., and Finn, C. (2023). Direct Preference Optimization: Your Language Model is Secretly a Reward Model. arXiv:2305.18290. arxiv.org/abs/2305.18290