TRL documentation
RLOO Trainer
RLOO Trainer
Обзор
TRL поддерживает RLOO Trainer для обучения языковых моделей, как описано в статье Back to Basics: Revisiting REINFORCE Style Optimization for Learning from Human Feedback in LLMs авторов Arash Ahmadian, Chris Cremer, Matthias Gallé, Marzieh Fadaee, Julia Kreutzer, Ahmet Üstün и Sara Hooker.
Аннотация из статьи следующая:
Выравнивание ИИ в форме обучения с подкреплением на основе обратной связи от человека (RLHF) всё чаще рассматривается как ключевой компонент для высокопроизводительных больших языковых моделей. В недавней литературе метод проксимальной оптимизации политики (PPO) позиционируется как канонический подход для части RL в RLHF. Однако он связан с высокими вычислительными затратами и чувствительной настройкой гиперпараметров. Мы утверждаем, что большинство мотивационных принципов, приведших к разработке PPO, имеют меньшее практическое значение в контексте RLHF, и предлагаем менее вычислительно затратный метод, который сохраняет и даже повышает производительность. Мы пересматриваем формулировку выравнивания на основе человеческих предпочтений в контексте RL. Простота как руководящий принцип позволяет нам показать, что многие компоненты PPO не нужны в контексте RLHF, и что гораздо более простые варианты оптимизации в стиле REINFORCE превосходят как PPO, так и недавно предложенные методы «без RL», такие как DPO и RAFT. Наша работа показывает, что тщательная адаптация к характеристикам выравнивания LLM позволяет извлекать выгоду из онлайн-оптимизации RL при низких затратах.
Этот метод постобучения был предложен Costa Huang и впоследствии переписан Shirin Yamani.
Быстрый старт
В этом примере показано, как обучать модель с использованием метода RLOO. Мы обучаем модель Qwen 0.5B Instruct на промптах из набора данных DeepMath-103K. Данные из набора можно посмотреть здесь:
Ниже приведён скрипт для обучения модели. accuracy_reward требует math-verify, который можно установить с помощью pip install trl[math_verify].
# train_rloo.py
from datasets import load_dataset
from trl import RLOOTrainer
from trl.rewards import accuracy_reward
dataset = load_dataset("trl-lib/DeepMath-103K", split="train")
trainer = RLOOTrainer(
model="Qwen/Qwen2-0.5B-Instruct",
reward_funcs=accuracy_reward,
train_dataset=dataset,
)
trainer.train()Выполните скрипт с помощью следующей команды:
torchrun --nproc_per_node 8 train_rloo.py
Более подробный обзор метода RLOO
RLOO — это алгоритм обучения в режиме онлайн, то есть он совершенствуется итеративно, используя данные, сгенерированные самим обученным моделью в процессе обучения. Интуиция, лежащая в основе целевой функции RLOO, состоит в том, чтобы максимизировать преимущество сгенерированных завершений, при этом обеспечивая близость модели к эталонной политике. Чтобы понять, как работает RLOO, его можно разбить на четыре основных шага: генерация завершений, вычисление преимущества, оценка расхождения Кульбака–Лейблера и вычисление функции потерь.

Генерация завершений
На каждом шаге обучения мы выбираем батч промптов и генерируем набор дополнений для каждого промпта (обозначаются как ).
Вычисление вознаграждения
В RLOO награда состоит из двух компонентов: награды, предоставляемой моделью наград (или функцией наград), и штрафного члена KL, который не позволяет политике отклоняться слишком сильно от фиксированной опорной политики
- Для каждой из сгенерированных последовательностей в условиях запроса , мы вычисляем скалярное вознаграждение с помощью модели вознаграждения .
- Одновременно мы оцениваем расхождение Кульбака–Лейблера между текущей политикой и фиксированной опорной политикой на последовательности. Оценка KL для последовательности имеет вид:
Итоговое вознаграждение, назначенное последовательности затем равно:
где управляет силой штрафного члена KL.
В чисто онлайн-настройке (
num_iterations = 1, значение по умолчанию) данные генерируются текущей политикой. В этом случае штраф за KL вычисляется непосредственно с использованием текущей политики.В более общем случае (например, несколько шагов градиента на батч) данные генерируются более ранним снимком . Чтобы штраф оставался согласованным с распределением выборки, KL определяется относительно этой политики:
Эквивалентно, для выборочной последовательности , оценка Монте-Карло равна:
Вычисление преимущества
После того как вознаграждения для каждого завершения вычислены, мы рассчитываем базовую линию (baseline) как среднее вознаграждение всех остальных образцов в том же батче, исключая текущий образец. Эта базовая линия используется для снижения дисперсии оценки градиента политики. Затем преимущество (advantage) для каждого завершения получается как разница между его собственным вознаграждением и этой базовой линией, исключающей текущий образец (leave-one-out).
Формально, для батча из G завершений базовая линия для завершения i:
а затем преимущество для каждого завершения вычисляется как разница между его наградой и базовой линией:
Вычисление функции потерь
Потеря REINFORCE определяется следующим образом:
На практике выполнение нескольких шагов градиента на одной и той же партии делает действия фактически off-policy относительно текущих параметров. Для исправления этого мы вводим коэффициент важности выборки (importance sampling ratio). Чтобы предотвратить чрезмерно большие обновления, когда политика меняется между выборкой и шагами градиента, мы ограничиваем (clip) этот коэффициент:
В полностью онлайн-настройке с одним шагом (по умолчанию), и это сводится к стандартному REINFORCE.
В отличие от GRPO, RLOO не выполняет обратное распространение градиентов через член KL. Здесь KL используется исключительно для формирования вознаграждения: он вычисляется в режиме
no_gradи включается в скалярное вознаграждение , которое становится отсоединённым преимуществом .Иными словами, единственный путь, по которому градиент поступает в политику, — это член отношения важности , а член KL не распространяется на политику при обратном распространении ошибки.
В отличие от этого, GRPO добавляет в свою целевую функцию явный дифференцируемый член KL, вычисляемый на лету с использованием текущей политики , поэтому её градиент проходит и через член отношения, и через штраф KL.
Записываемые метрики
Во время обучения и оценки мы фиксируем следующие метрики:
num_tokens: общее количество обработанных на данный момент токенов, включая как промпты, так и завершения.step_time: среднее время (в секундах), затрачиваемое на один шаг обучения (включая генерацию).completions/mean_length: средняя длина сгенерированных завершений.completions/min_length: минимальная длина генерируемых завершений.completions/max_length: максимальная длина генерируемых дополнений.completions/mean_terminated_length: средняя длина сгенерированных завершений, которые заканчиваются токеном EOS.completions/min_terminated_length: минимальная длина сгенерированных завершений, которые заканчиваются токеном EOS.completions/max_terminated_length: максимальная длина сгенерированных завершений, которые заканчиваются токеном EOS.completions/clipped_ratio: Доля обрезанных (усечённых) завершений.rewards/{reward_func_name}/mean: среднее значение вознаграждения от конкретной функции вознаграждения.rewards/{reward_func_name}/std: стандартное отклонение вознаграждения от конкретной функции вознаграждения.reward: Общая средняя награда после суммирования наград по функциям (с весамиreward_weights).reward_std: стандартное отклонение суммарных наград по функциям (с учётом весовreward_weights), вычисленное для всей выборки.frac_reward_zero_std: доля образцов в батче генерации, у которых стандартное отклонение награды равно нулю, что указывает на малое разнообразие для данного промпта (все ответы верные или неверные).entropy: Средняя энтропия предсказаний токенов по всем сгенерированным завершениям. (Еслиmask_truncated_completions=True, токены замаскированных последовательностей исключаются.)aux_loss: вспомогательная функция потерь для балансировки нагрузки в модели Mixture-of-Experts, до её масштабирования коэффициентомrouter_aux_loss_coefи добавления к общей функции потерь. Записывается в журнал только в том случае, если модель является MoE иrouter_aux_loss_coefне равен нулю.kl: средняя дивергенция Кульбака–Лейблера между моделью и эталонной моделью, рассчитанная по сгенерированным завершениям. Записывается в журнал только еслиbetaне равно нулю.clip_ratio/region_mean: Соотношение вероятностей последовательностей, для которых целевая функция RLOO обрезается, чтобы оставаться в области доверия: . Более высокое значение означает, что обрезается больше выборок, что ограничивает степень изменения политики .clip_ratio/low_mean: Среднее отношение вероятностей последовательностей, обрезанных по нижней границе области доверия: .clip_ratio/low_min: Наименьший индикатор обрезки на нижнюю границу области доверия для каждого завершения: .clip_ratio/high_mean: Среднее отношение вероятностей последовательностей, обрезанных по верхней границе области доверия: .clip_ratio/high_max: Наибольший индикатор обрезки на верхнюю границу области доверия для каждого завершения: .
Настройка
Ускорение обучения с генерацией на базе vLLM
Генерация часто является основным узким местом при обучении с использованием онлайн-методов. Для ускорения генерации можно использовать vLLM — высокопроизводительный движок инференса с низкой задержкой для LLM. Для его включения сначала установите пакет с
pip install trl[vllm]
Мы поддерживаем два способа использования vLLM во время обучения: режим сервера и режим colocation.
Вариант 1: Режим Colocate
В этом режиме vLLM работает внутри процесса тренера и разделяет память GPU с моделью обучения. Это позволяет избежать запуска отдельного сервера и может повысить использование GPU, но может привести к конкуренции за память на GPU, используемых для обучения. Это режим по умолчанию.
from trl import RLOOConfig
training_args = RLOOConfig(
...,
use_vllm=True, # vllm_mode="colocate" by default
)Вариант 2: серверный режим
В этом режиме vLLM работает в отдельном процессе (и на отдельных GPU) и взаимодействует с тренером через HTTP. Это идеальный вариант, если у вас есть выделенные GPU для инференса.
Запустите сервер vLLM:
VLLM_SERVER_DEV_MODE=1 vllm serve <model_name> \ --weight-transfer-config '{"backend": "nccl"}' \ --logprobs-mode processed_logprobs \ --max-logprobs -1Включите серверный режим в вашем скрипте обучения:
from trl import RLOOConfig training_args = RLOOConfig( ..., use_vllm=True, vllm_mode="server", )
Убедитесь, что сервер использует другие GPU, чем тренажёр, иначе могут возникнуть ошибки NCCL. Вы можете указать используемые GPU с помощью переменной окружения
CUDA_VISIBLE_DEVICES.
В зависимости от размера модели и общих требований к памяти GPU для обучения может потребоваться отрегулировать параметр
vllm_gpu_memory_utilizationв RLOOConfig, чтобы избежать недоиспользования ресурсов или ошибок нехватки памяти.Мы предоставляем HF Space, который помогает оценить рекомендуемое использование памяти GPU на основе конфигурации вашей модели и настроек эксперимента. Просто используйте его следующим образом, чтобы получить рекомендацию по
vllm_gpu_memory_utilization:Если рекомендуемое значение не работает в вашей среде, мы рекомендуем добавить небольшой запас (например, +0.05 или +0.1) к рекомендуемому значению для обеспечения стабильности.
Если вы по-прежнему получаете ошибки нехватки памяти, установите
vllm_enable_sleep_modeв True, и параметры vllm и кэш будут выгружены во время шага оптимизации. Подробнее см. в разделе Снижение потребления памяти с помощью режима сна vLLM.
По умолчанию RLOO использует
MASTER_ADDR=localhostиMASTER_PORT=12345для vLLM, но вы можете переопределить эти значения, установив соответствующие переменные окружения.
Для получения дополнительной информации см. Ускорение обучения с помощью vLLM.
RLOO в масштабе: обучение модели 70B+ на нескольких узлах
При обучении крупных моделей, таких как Qwen2.5-72B, для обеспечения эффективности и масштабируемости обучения на нескольких GPU и узлах необходимы несколько ключевых оптимизаций. К ним относятся:
- DeepSpeed ZeRO Stage 3: ZeRO использует параллелизм данных для распределения состояний модели (весов, градиентов, состояний оптимизатора) между несколькими GPU и CPU, что снижает требования к памяти и вычислительным ресурсам на каждом устройстве. Поскольку большие модели не помещаются на одном GPU, для обучения таких моделей необходимо использовать ZeRO Stage 3. Подробнее см. в разделе DeepSpeed Integration.
- torchrun: запускатель PyTorch запускает по одному процессу на каждый GPU на каждом узле и связывает их через общий rendezvous. Подробнее см. в разделе Распределение обучения.
- vLLM: см. предыдущий раздел о том, как использовать vLLM для ускорения генерации.
Ниже приведён пример SLURM-скрипта для обучения модели 70B с использованием RLOO на нескольких узлах. Этот скрипт обучает модель на 4 узлах и использует 5-й узел для генерации на базе vLLM.
#!/bin/bash
#SBATCH --nodes=5
#SBATCH --gres=gpu:8
# Get the list of allocated nodes
NODELIST=($(scontrol show hostnames $SLURM_JOB_NODELIST))
# Assign the first 4 nodes for training and the 5th node for vLLM
TRAIN_NODES="${NODELIST[@]:0:4}" # Nodes 0, 1, 2, 3 for training
VLLM_NODE="${NODELIST[4]}" # Node 4 for vLLM
# Run training on the first 4 nodes (Group 1)
srun --nodes=4 --ntasks=4 --nodelist="${NODELIST[@]:0:4}" torchrun \
--nnodes 4 \
--nproc_per_node 8 \
--node_rank $SLURM_PROCID \
--rdzv_backend c10d \
--rdzv_endpoint ${NODELIST[0]}:29500 \
train_rloo.py \
--server_ip $VLLM_NODE &
# Run vLLM server on the 5th node (Group 2)
srun --nodes=1 --ntasks=1 --nodelist="${NODELIST[4]}" env VLLM_SERVER_DEV_MODE=1 vllm serve Qwen/Qwen2.5-72B --tensor-parallel-size 8 \
--weight-transfer-config '{"backend": "nccl"}' \
--logprobs-mode processed_logprobs \
--max-logprobs -1 &
waitimport argparse
from datasets import load_dataset
from trl import RLOOTrainer, RLOOConfig
def main():
parser = argparse.ArgumentParser()
parser.add_argument("--vllm_server_host", type=str, default="", help="The server IP")
args = parser.parse_args()
# Example dataset from TLDR
dataset = load_dataset("trl-lib/tldr", split="train")
# Dummy reward function: count the number of unique characters in the completions
def reward_num_unique_chars(completions, **kwargs):
return [len(set(c)) for c in completions]
training_args = RLOOConfig(
output_dir="Qwen2.5-72B-RLOO",
per_device_train_batch_size=4,
bf16=True,
deepspeed="examples/deepspeed_configs/zero3.json",
use_vllm=True,
vllm_mode="server",
vllm_server_host=args.vllm_server_host.replace("ip-", "").replace("-", "."), # from ip-X-X-X-X to X.X.X.X
)
trainer = RLOOTrainer(model="Qwen/Qwen2.5-72B", args=training_args, reward_funcs=reward_num_unique_chars, train_dataset=dataset)
trainer.train()
if __name__=="__main__":
main()Использование пользовательской функции вознаграждения
Объект RLOOTrainer поддерживает использование пользовательских функций вознаграждения вместо плотных моделей вознаграждения. Для обеспечения совместимости ваша функция вознаграждения должна соответствовать следующим требованиям:
Функции вознаграждения могут быть как синхронными вызываемыми объектами Python, так и асинхронными корутинами async def. Если вы указываете несколько асинхронных функций вознаграждения, они ожидаются одновременно (выполняются параллельно через asyncio.gather), что позволяет перекрыть их задержки.
Аргументы ввода:
Функция должна принимать следующие аргументы по имени:
prompts(содержит промпты),completions(содержит сгенерированные завершения),completion_ids(содержит токенизированные завершения),trainer_state(TrainerState): текущее состояние тренера. Это можно использовать для реализации динамических функций вознаграждения, например, для обучения по программе (curriculum learning), где вознаграждение корректируется в зависимости от прогресса обучения.log_extra: вызываемый объектlog_extra(column: str, values: list)для добавления дополнительных столбцов в таблицу с результатами. См. Пример 6.log_metric: вызываемый объектlog_metric(name: str, value: float)для записи скалярных метрик в виде графиков наряду сkl,entropyи т. д. См. Пример 6.- Все имена столбцов (кроме
prompt), которые могут присутствовать в наборе данных. Например, если набор данных содержит столбец с именемground_truth, функция будет вызвана сground_truthв качестве именованного аргумента.
Самый простой способ выполнить это требование — использовать
**kwargsв сигнатуре функции.В зависимости от формата набора данных входные данные будут различаться:
- Для стандартного формата
promptsиcompletionsбудут списками строк. - Для диалогового формата
promptsиcompletionsбудут списками словарей сообщений.
- Для стандартного формата
Возвращаемое значение: функция должна возвращать список чисел с плавающей точкой. Каждое число представляет награду, соответствующую одному завершению.
Пример 1: Поощрение более длинных завершений
Ниже приведен пример функции вознаграждения для стандартного формата, которая поощряет более длинные завершения:
def reward_func(completion_ids, **kwargs):
"""Reward function that assigns higher scores to longer completions (in terms of token count)."""
return [float(len(ids)) for ids in completion_ids]Вы можете протестировать это следующим образом:
>>> prompts = ["The sky is", "The sun is"] # not used in the reward function, but the trainer will pass it
>>> completions = [" blue.", " in the sky."] # not used in the reward function, but the trainer will pass it
>>> completion_ids = [[6303, 13], [304, 279, 12884, 13]]
>>> reward_func(prompts=prompts, completions=completions, completion_ids=completion_ids)
[2.0, 4.0]Пример 1.1: Поощрение более длинных завершений (на основе количества символов)
Аналогично предыдущему примеру, но на этот раз функция вознаграждения основана на количестве символов, а не токенов.
def reward_func(completions, **kwargs):
"""Reward function that assigns higher scores to longer completions (in terms of character count)."""
return [float(len(completion)) for completion in completions]Вы можете протестировать это следующим образом:
>>> prompts = ["The sky is", "The sun is"]
>>> completions = [" blue.", " in the sky."]
>>> completion_ids = [[6303, 13], [304, 279, 12884, 13]] # not used in the reward function, but the trainer will pass it
>>> reward_func(prompts=prompts, completions=completions, completion_ids=completion_ids)
[6.0, 12.0]Пример 2: Награждайте завершения с определенным форматом
Ниже приведен пример функции вознаграждения, которая проверяет, соответствует ли ответ определенному формату. Этот пример вдохновлен функцией format reward, используемой в статье DeepSeek-R1: Incentivizing Reasoning Capability in LLMs via Reinforcement Learning. Она предназначена для диалогового формата, в котором промпты и ответы состоят из структурированных сообщений.
import re
def format_reward_func(completions, **kwargs):
"""Reward function that checks if the completion has a specific format."""
pattern = r"^<think>.*?</think><answer>.*?</answer>$"
completion_contents = [completion[0]["content"] for completion in completions]
matches = [re.match(pattern, content) for content in completion_contents]
return [1.0 if match else 0.0 for match in matches]Вы можете протестировать эту функцию следующим образом:
>>> prompts = [
... [{"role": "user", "content": "What is the result of (1 + 2) * 4?"}],
... [{"role": "user", "content": "What is the result of (3 + 1) * 2?"}],
... ]
>>> completions = [
... [{"role": "assistant", "content": "<think>The sum of 1 and 2 is 3, which we multiply by 4 to get 12.</think><answer>(1 + 2) * 4 = 12</answer>"}],
... [{"role": "assistant", "content": "The sum of 3 and 1 is 4, which we multiply by 2 to get 8. So (3 + 1) * 2 = 8."}],
... ]
>>> format_reward_func(prompts=prompts, completions=completions)
[1.0, 0.0]Пример 3: Награды за завершения на основе эталонного
Ниже приведен пример функции вознаграждения, которая проверяет правильность завершения. Этот пример вдохновлен функцией accuracy reward, используемой в статье DeepSeek-R1: Incentivizing Reasoning Capability in LLMs via Reinforcement Learning.
Этот пример предназначен для стандартного формата, в котором набор данных содержит столбец с именем ground_truth.
import re
def reward_func(completions, ground_truth, **kwargs):
# Regular expression to capture content inside \boxed{}
matches = [re.search(r"\\boxed\{(.*?)\}", completion) for completion in completions]
contents = [match.group(1) if match else "" for match in matches]
# Reward 1 if the content is the same as the ground truth, 0 otherwise
return [1.0 if c == gt else 0.0 for c, gt in zip(contents, ground_truth)]Вы можете протестировать эту функцию следующим образом:
>>> prompts = ["Problem: Solve the equation $2x + 3 = 7$. Solution:", "Problem: Solve the equation $3x - 5 = 10$."]
>>> completions = [r" The solution is \boxed{2}.", r" The solution is \boxed{6}."]
>>> ground_truth = ["2", "5"]
>>> reward_func(prompts=prompts, completions=completions, ground_truth=ground_truth)
[1.0, 0.0]Пример 4: Многозадачные функции вознаграждения
Ниже приведен пример использования нескольких функций вознаграждения в RLOOTrainer. В этом примере мы определяем две функции вознаграждения, специфичные для задач: math_reward_func и coding_reward_func. Функция math_reward_func оценивает математические задачи на основе их правильности, а coding_reward_func — задачи по программированию на основе того, работает ли решение.
from datasets import Dataset
from trl import RLOOTrainer
# Define a dataset that contains both math and coding problems
dataset = Dataset.from_list(
[
{"prompt": "What is 2+2?", "task": "math"},
{"prompt": "Write a function that returns the sum of two numbers.", "task": "code"},
{"prompt": "What is 3*4?", "task": "math"},
{"prompt": "Write a function that returns the product of two numbers.", "task": "code"},
]
)
# Math-specific reward function
def math_reward_func(prompts, completions, task, **kwargs):
rewards = []
for prompt, completion, t in zip(prompts, completions, task):
if t == "math":
# Calculate math-specific reward
correct = check_math_solution(prompt, completion)
reward = 1.0 if correct else -1.0
rewards.append(reward)
else:
# Return None for non-math tasks
rewards.append(None)
return rewards
# Coding-specific reward function
def coding_reward_func(prompts, completions, task, **kwargs):
rewards = []
for prompt, completion, t in zip(prompts, completions, task):
if t == "code":
# Calculate coding-specific reward
works = test_code_solution(prompt, completion)
reward = 1.0 if works else -1.0
rewards.append(reward)
else:
# Return None for non-coding tasks
rewards.append(None)
return rewards
# Use both task-specific reward functions
trainer = RLOOTrainer(
model="Qwen/Qwen2-0.5B-Instruct",
reward_funcs=[math_reward_func, coding_reward_func],
train_dataset=dataset,
)
trainer.train()В этом примере math_reward_func и coding_reward_func разработаны для работы со смешанным набором данных, содержащим как математические, так и программные задачи. Колонка task в наборе данных используется для определения, какую функцию вознаграждения применить к каждой задаче. Если для образца в наборе данных нет соответствующей функции вознаграждения, функция вернёт None, и RLOOTrainer продолжит работу с валидными функциями и задачами. Это позволяет RLOOTrainer обрабатывать несколько функций вознаграждения с разной областью применения.
Обратите внимание, что RLOOTrainer игнорирует вознаграждения None, возвращаемые функциями вознаграждения, и учитывает только вознаграждения, возвращаемые соответствующими функциями. Это гарантирует, что модель обучается на релевантных задачах и игнорирует те, для которых нет соответствующей функции вознаграждения.
Пример 5: Асинхронные функции вознаграждения
Пользовательские функции вознаграждения также можно определять как корутины async def. Это полезно, если ваше вознаграждение зависит от медленного ввода-вывода (например, вызова удалённого сервиса). При передаче нескольких асинхронных функций вознаграждения RLOOTrainer выполняет их параллельно, чтобы их задержки перекрывались.
Ниже приведен минимальный пример асинхронной функции вознаграждения, имитирующей операцию, ограниченную вводом-выводом:
import asyncio
async def async_reward_func(prompts, completions, **kwargs):
# Simulate an I/O-bound call (e.g., HTTP request, database lookup)
await asyncio.sleep(0.01)
# Simple toy reward: 1.0 if the completion is non-empty, else 0.0
return [1.0 if completion else 0.0 for completion in completions]Пример 6: Логирование дополнительных столбцов и метрик
Ниже приведен пример функции вознаграждения, которая записывает дополнительные столбцы в таблицу завершений и скалярные метрики в виде графиков.
import re
def reward_func(completions, ground_truth, log_extra=None, log_metric=None, **kwargs):
extracted = [re.search(r"\\boxed\{(.*?)\}", c) for c in completions]
extracted = [m.group(1) if m else None for m in extracted]
rewards = [1.0 if e == gt else 0.0 for e, gt in zip(extracted, ground_truth)]
if log_extra:
log_extra("golden_answer", list(ground_truth))
log_extra("extracted_answer", [e or "[none]" for e in extracted])
if log_metric:
log_metric("accuracy", sum(rewards) / len(rewards))
return rewardsПередача функции вознаграждения в тренер
Чтобы использовать собственную функцию вознаграждения, передайте её в RLOOTrainer следующим образом:
from trl import RLOOTrainer
trainer = RLOOTrainer(
reward_funcs=reward_func,
...,
)Можно передать несколько функций вознаграждения в виде списка; этот список может включать как синхронные, так и асинхронные функции:
from trl import RLOOTrainer
trainer = RLOOTrainer(
reward_funcs=[reward_func, async_reward_func1, async_reward_func2],
...,
)а награда будет вычисляться как сумма наград от каждой функции или как взвешенная сумма, если в конфигурации указано reward_weights.
Обратите внимание, что RLOOTrainer поддерживает несколько функций вознаграждения разных типов. Подробности см. в документации параметров.
Обучение моделей «зрение-язык»
RLOO поддерживает обучение моделей «зрение-язык» (VLM) на мультимодальных наборах данных, содержащих как текст, так и изображения.
Поддерживаемые модели
Проверено с:
- Gemma3 — например,
google/gemma-3-4b-it - LLaVA-NeXT — например,
llava-hf/llava-v1.6-mistral-7b-hf - Qwen2-VL — например,
Qwen/Qwen2-VL-2B-Instruct - Qwen2.5-VL — например,
Qwen/Qwen2.5-VL-3B-Instruct - SmolVLM2 — например,
HuggingFaceTB/SmolVLM2-2.2B-Instruct
Совместимость со всеми VLM не гарантируется. Если вы считаете, что модель должна поддерживаться, не стесняйтесь открыть issue на GitHub — или, что ещё лучше, отправить pull request с необходимыми изменениями.
Быстрый старт
Используйте rloo_vlm.py для дообучения VLM. Пример команды для обучения на lmms-lab/multimodal-open-r1-8k-verified:
torchrun --nproc_per_node 8 examples/rloo_visual_math/rloo_visual_math.py \
--deepspeed examples/deepspeed_configs/zero3.json \
--model_name_or_path Qwen/Qwen2.5-VL-3B-Instruct \
--output_dir rloo-Qwen2.5-VL-3B-Instruct \
--learning_rate 1e-5 \
--dtype bfloat16 \
--max_completion_length 1024 \
--use_vllm \
--vllm_mode colocate \
--use_peft \
--lora_target_modules "q_proj", "v_proj" \
--log_completionsСоветы по конфигурации
- Использование LoRA на проекционных слоях зрительно-языковой модели
- Включите 4-битное квантование для снижения потребления памяти
- VLMs требуют много памяти — начните с меньших размеров батчей
- Большинство моделей совместимы с vLLM (режимы
serverиcolocate)
Формат набора данных
Каждая обучающая выборка должна включать:
prompt: Текст, отформатированный через шаблон чата процессораimage/images: изображение PIL или список изображений PIL
Тренер автоматически обрабатывает преобразование изображений в тензоры с помощью процессора изображений модели.
RLOOTrainer
класс trl.RLOOTrainer
< source >( model: str | PreTrainedModel | PeftModelreward_funcs: str | transformers.modeling_utils.PreTrainedModel | collections.abc.Callable[..., list[float | None]] | list[str | transformers.modeling_utils.PreTrainedModel | collections.abc.Callable[..., list[float | None]]]args: trl.trainer.rloo_config.RLOOConfig | None = Nonetrain_dataset: datasets.arrow_dataset.Dataset | datasets.iterable_dataset.IterableDataset | None = Noneeval_dataset: datasets.arrow_dataset.Dataset | datasets.iterable_dataset.IterableDataset | datasets.dataset_dict.DatasetDict | datasets.dataset_dict.IterableDatasetDict | dict[str, datasets.arrow_dataset.Dataset | datasets.iterable_dataset.IterableDataset] | None = Noneprocessing_class: transformers.tokenization_utils_base.PreTrainedTokenizerBase | transformers.processing_utils.ProcessorMixin | None = Nonereward_processing_classes: transformers.tokenization_utils_base.PreTrainedTokenizerBase | list[transformers.tokenization_utils_base.PreTrainedTokenizerBase] | None = Nonecallbacks: list[transformers.trainer_callback.TrainerCallback] | None = Noneoptimizers: tuple[typing.Optional[torch.optim.Optimizer], typing.Optional[torch.optim.lr_scheduler.LambdaLR]] = (None, None)quantization_config: BitsAndBytesConfig | None = Nonepeft_config: PeftConfig | None = None )
Параметры
- model (
strили PreTrainedModel или PeftModel) — Модель, подлежащая обучению. Может быть одним из следующих:- Строка, являющаяся model id предобученной модели, размещённой в репозитории моделей на huggingface.co, или путь к каталогу, содержащему веса модели, сохранённые с помощью save_pretrained, например
'./my_model_directory/'. Модель загружается с помощью<ModelArchitecture>.from_pretrained(где<ModelArchitecture>определяется из конфигурации модели) с использованием именованных аргументов изargs.model_init_kwargs. Еслиdtypeне указан вargs.model_init_kwargs, по умолчанию используетсяfloat32. Это отличается от from_pretrained, где (начиная с Transformers v5) тип данных выводится из конфигурации модели. - Объект PreTrainedModel. Поддерживаются только каузальные языковые модели.
- Объект PeftModel. Поддерживаются только каузальные языковые модели.
- Строка, являющаяся model id предобученной модели, размещённой в репозитории моделей на huggingface.co, или путь к каталогу, содержащему веса модели, сохранённые с помощью save_pretrained, например
- reward_funcs (
RewardFunc | list[RewardFunc]) — Функции вознаграждения, используемые для вычисления наград. Для вычисления наград мы вызываем все функции вознаграждения с промптами и завершениями и суммируем награды. Допустимые варианты:-
Одна функция вознаграждения, например:
-
A string: The model ID of a pretrained model hosted inside a model repo on huggingface.co, or a path to a directory containing model weights saved using save_pretrained, e.g.,
'./my_model_directory/'. The model is loaded using from_pretrained withnum_labels=1and the keyword arguments inargs.model_init_kwargs. -
Объект PreTrainedModel: поддерживаются только модели классификации последовательностей.
-
Пользовательская функция вознаграждения: функция получает промпты и сгенерированные завершения, а также любые дополнительные столбцы в наборе данных. Она должна возвращать список вознаграждений. Пользовательские функции вознаграждения могут быть как синхронными, так и асинхронными, а также возвращать
None, если вознаграждение неприменимо к данным образцам. Это полезно для обучения на нескольких задачах, где разные функции вознаграждения применяются к разным типам образцов. Если функция вознаграждения возвращаетNoneдля образца, эта функция вознаграждения исключается из расчёта вознаграждения для данного образца. Дополнительные сведения см. в разделе Использование пользовательской функции вознаграждения.Состояние тренера также передается в функцию вознаграждения. Состояние тренера представляет собой экземпляр TrainerState и может быть получено через аргумент
trainer_stateв сигнатуре функции вознаграждения.
-
-
Список функций вознаграждения, где каждый элемент может независимо быть любым из перечисленных выше типов. Смешивание разных типов внутри списка (например, строкового идентификатора модели и пользовательской функции вознаграждения) допускается.
-
- args (RLOOConfig, необязательный) —
Конфигурация для этого тренера. Если
None, используется конфигурация по умолчанию. - train_dataset (Dataset или IterableDataset) —
Набор данных для обучения. Он должен содержать столбец
"prompt". Любые дополнительные столбцы в наборе данных игнорируются. Формат образцов может быть следующим:- Standard: каждая выборка содержит обычный текст.
- Диалоговый: каждая выборка содержит структурированные сообщения (например, роль и содержимое).
Если
train_datasetявляется IterableDataset (например, потоковым набором данных), тоmax_stepsнеобходимо задать в аргументах обучения, поскольку его длину невозможно определить, а общее количество шагов обучения требуется для ограничения цикла обучения и настройки планировщика скорости обучения. - eval_dataset (Dataset, IterableDataset, DatasetDict, IterableDatasetDict или
dict[str, Dataset | IterableDataset]) — Набор данных для оценки. Он должен соответствовать тем же требованиям, что иtrain_dataset. - processing_class (PreTrainedTokenizerBase, ProcessorMixin, optional) —
Processing class used to process the data. The padding side must be set to “left”. If
None, the processing class is loaded from the model’s name with from_pretrained. A padding token,tokenizer.pad_token, must be set. If the processing class has not set a padding token,tokenizer.eos_tokenwill be used as the default. - reward_processing_classes (PreTrainedTokenizerBase или
list[PreTrainedTokenizerBase], необязательный) — Классы обработки, соответствующие функциям вознаграждения, указанным вreward_funcs. Может быть:- Один класс обработки: используется, когда
reward_funcsсодержит только одну функцию вознаграждения. - Список классов обработки: должен соответствовать порядку и длине функций вознаграждения в
reward_funcs. Если установлено значениеNone, или если элемент списка, соответствующий PreTrainedModel, равенNone, то токенизатор для модели загружается автоматически с помощью from_pretrained. Для элементов вreward_funcs, которые являются пользовательскими функциями вознаграждения (не PreTrainedModel), соответствующие записи вreward_processing_classesигнорируются.
- Один класс обработки: используется, когда
- callbacks (список TrainerCallback, необязательный) —
Список callback'ов для настройки цикла обучения. Они будут добавлены к списку callback'ов по умолчанию, описанных здесь.
Если вы хотите удалить один из используемых по умолчанию колбэков, воспользуйтесь методом remove_callback.
- optimizers (
tuple[torch.optim.Optimizer | None, torch.optim.lr_scheduler.LambdaLR | None], необязательный, по умолчанию(None, None)) — Кортеж, содержащий оптимизатор и планировщик, которые будут использоваться. По умолчанию будет создан экземплярAdamWдля вашей модели и планировщик, заданный функцией get_linear_schedule_with_warmup и управляемый параметрамиargs. - quantization_config (BitsAndBytesConfig, optional) —
Конфигурация квантования, используемая при загрузке модели по идентификатору модели. Используйте в сочетании с
peft_configдля обучения QLoRA. Игнорируется, если модель уже инициализирована. - peft_config (PeftConfig, необязательный) —
Конфигурация PEFT, используемая для обёртки модели. Если
None, модель не оборачивается.
Trainer for the Reinforce Leave One Out (RLOO) method. This algorithm was initially proposed in the paper Back to Basics: Revisiting REINFORCE Style Optimization for Learning from Human Feedback in LLMs.
Пример:
>>> from trl import RLOOTrainer
>>> from trl.rewards import accuracy_reward
>>> from datasets import load_dataset
>>> dataset = load_dataset("trl-lib/DeepMath-103K", split="train")
>>> trainer = RLOOTrainer(
... model="Qwen/Qwen2.5-0.5B-Instruct",
... reward_funcs=accuracy_reward,
... train_dataset=dataset,
... )
>>> trainer.train()обучение
< source >( resume_from_checkpoint: str | bool | None = Nonetrial: optuna.Trial | dict[str, Any] | None = Noneignore_keys_for_eval: list[str] | None = None ) → ~trainer_utils.TrainOutput
Параметры
- resume_from_checkpoint (
strилиbool, необязательный) — Если передано значение типаstr, это локальный путь к сохранённой контрольной точке, созданной предыдущим экземпляромTrainer. Если передано значение типаboolи оно равноTrue, загружается последняя контрольная точка из args.output_dir, сохранённая предыдущим экземпляромTrainer. Если параметр указан, обучение возобновляется из состояний модели/оптимизатора/планировщика, загруженных из этой контрольной точки. - trial (
optuna.Trialилиdict[str, Any], необязательный) — Запуск испытания или словарь гиперпараметров для поиска гиперпараметров. - ignore_keys_for_eval (
list[str], необязательный) — Список ключей в выводе вашей модели (если он представляет собой словарь), которые следует игнорировать при сборе предсказаний для оценки во время обучения.
Возвращает
~trainer_utils.TrainOutput
Объект, содержащий количество глобальных шагов, потерю обучения и метрики.
Основная точка входа для обучения.
Сохранит модель, чтобы вы могли загрузить её снова с помощью from_pretrained().
Сохранение будет выполняться только из основного процесса.
push_to_hub
< source >( commit_message: str | None = 'End of training'blocking: bool = Truetoken: str | None = Nonerevision: str | None = None**kwargs )
Параметры
- commit_message (
str, необязательный, по умолчанию"End of training") — Сообщение для коммита при отправке. - blocking (
bool, необязательный, по умолчаниюTrue) — Определяет, должна ли функция возвращаться только после завершенияgit push. - token (
str, необязательный, по умолчаниюNone) — Токен с правом записи для перезаписи исходных аргументов Trainer. - revision (
str, необязательный) — Git-ревизия, от которой выполняется коммит. По умолчанию используется head ветки “main”. - kwargs (
dict[str, Any], необязательный) — Дополнительные именованные аргументы, передаваемые в~Trainer.create_model_card.
Загрузите self.model и self.processing_class в модельный хаб 🤗 в репозиторий self.args.hub_model_id.
RLOOConfig
класс trl.RLOOConfig
< source >( output_dir: str | None = Noneper_device_train_batch_size: int = 8num_train_epochs: float = 3.0max_steps: int = -1learning_rate: float = 1e-06lr_scheduler_type: transformers.trainer_utils.SchedulerType | str = 'linear'lr_scheduler_kwargs: dict | str | None = Nonewarmup_steps: float = 0optim: transformers.training_args.OptimizerNames | str = 'adamw_torch_fused'optim_args: str | None = Noneweight_decay: float = 0.0adam_beta1: float = 0.9adam_beta2: float = 0.999adam_epsilon: float = 1e-08optim_target_modules: None | str | list[str] = Nonegradient_accumulation_steps: int = 1average_tokens_across_devices: bool = Truemax_grad_norm: float = 1.0label_smoothing_factor: float = 0.0bf16: bool | None = Nonefp16: bool = Falsebf16_full_eval: bool = Falsefp16_full_eval: bool = Falsetf32: bool | None = Nonegradient_checkpointing: bool = Truegradient_checkpointing_kwargs: dict[str, typing.Any] | str | None = Nonetorch_compile: bool = Falsetorch_compile_backend: str | None = Nonetorch_compile_mode: str | None = Noneuse_liger_kernel: bool = Falseliger_kernel_config: dict[str, bool] | None = Noneuse_cache: bool = Falseneftune_noise_alpha: float | None = Nonetorch_empty_cache_steps: int | None = Noneauto_find_batch_size: bool = Falselogging_strategy: transformers.trainer_utils.IntervalStrategy | str = 'steps'logging_steps: float = 10logging_first_step: bool = Falselog_on_each_node: bool = Truelogging_nan_inf_filter: bool = Trueinclude_num_input_tokens_seen: str | bool = 'no'log_level: str = 'passive'log_level_replica: str = 'warning'disable_tqdm: bool | None = Nonereport_to: None | str | list[str] = 'none'run_name: str | None = Noneproject: str = 'huggingface'trackio_space_id: str | None = Nonetrackio_bucket_id: str | None = Nonetrackio_static_space_id: typing.Union[str, NoneType, typing.Literal[False]] = Noneeval_strategy: transformers.trainer_utils.IntervalStrategy | str = 'no'eval_steps: float | None = Noneeval_delay: float = 0per_device_eval_batch_size: int = 8prediction_loss_only: bool = Falseeval_on_start: bool = Falseeval_do_concat_batches: bool = Trueeval_use_gather_object: bool = Falseeval_accumulation_steps: int | None = Noneinclude_for_metrics: list[str] = <factory>batch_eval_metrics: bool = Falsesave_only_model: bool = Falsesave_strategy: transformers.trainer_utils.SaveStrategy | str = 'steps'save_steps: float = 500save_on_each_node: bool = Falsesave_total_limit: int | None = Noneenable_jit_checkpoint: bool = Falsepush_to_hub: bool = Falsehub_token: str | None = Nonehub_private_repo: bool | None = Nonehub_model_id: str | None = Nonehub_strategy: transformers.trainer_utils.HubStrategy | str = 'every_save'hub_always_push: bool = Falsehub_revision: str | None = Noneload_best_model_at_end: bool = Falsemetric_for_best_model: str | None = Nonegreater_is_better: bool | None = Noneignore_data_skip: bool = Falserestore_callback_states_from_checkpoint: bool = Falsefull_determinism: bool = Falseseed: int = 42data_seed: int | None = Noneuse_cpu: bool = Falseaccelerator_config: dict | str | None = Noneparallelism_config: accelerate.parallelism_config.ParallelismConfig | None = Nonedataloader_drop_last: bool = Falsedataloader_num_workers: int = 0dataloader_pin_memory: bool = Truedataloader_persistent_workers: bool = Falsedataloader_prefetch_factor: int | None = Nonedataloader_multiprocessing_context: str | None = Nonedataloader_in_order: bool = Trueremove_unused_columns: bool | None = Falselabel_names: list[str] | None = Nonetrain_sampling_strategy: str = 'random'length_column_name: str = 'length'ddp_find_unused_parameters: bool | None = Noneddp_bucket_cap_mb: int | None = Noneddp_broadcast_buffers: bool | None = Noneddp_static_graph: bool | None = Noneddp_backend: str | None = Noneddp_timeout: int = 1800fsdp: str | None = Nonefsdp_config: dict[str, typing.Any] | str | None = Nonedeepspeed: dict | str | None = Nonedebug: str | list[transformers.debug_utils.DebugOption] = ''skip_memory_metrics: bool = Truedo_train: bool = Falsedo_eval: bool = Falsedo_predict: bool = Falseresume_from_checkpoint: str | None = Nonelocal_rank: int = -1model_init_kwargs: dict[str, typing.Any] | str | None = Nonetrust_remote_code: bool = Falserouter_aux_loss_coef: float | None = Nonedisable_dropout: bool = Falsenum_generations: int | None = 2num_generations_eval: int | None = Nonemax_completion_length: int | None = 512ds3_gather_for_generation: bool = Trueshuffle_dataset: bool | None = Truepad_to_multiple_of: int | str | None = 'auto'generation_batch_size: int | None = Nonesteps_per_generation: int | None = Nonetemperature: float = 1.0top_p: float = 1.0top_k: int = 0min_p: float | None = Nonegeneration_kwargs: dict | str | None = Nonechat_template_kwargs: dict | str | None = Nonerepetition_penalty: float = 1.0cache_implementation: str | None = Noneuse_vllm: bool = Falsevllm_mode: str = 'colocate'vllm_model_impl: str = 'vllm'vllm_enable_sleep_mode: bool = Falsevllm_structured_outputs_regex: str | None = Nonevllm_server_base_url: str | None = Nonevllm_server_host: str = '0.0.0.0'vllm_server_port: int = 8000vllm_server_timeout: float = 240.0vllm_group_port: int = 51216vllm_gpu_memory_utilization: float = 0.3vllm_max_model_length: int | None = Nonevllm_tensor_parallel_size: int = 1beta: float = 0.05num_iterations: int = 1epsilon: float = 0.2epsilon_high: float | None = Nonereward_weights: list[float] | None = Nonenormalize_advantages: bool = Falsereward_clip_range: tuple[float, float] | None = Nonemask_truncated_completions: bool = Falsesync_ref_model: bool = Falseref_model_mixup_alpha: float = 0.6ref_model_sync_steps: int = 512log_completions: bool = Falselog_multimodal: bool = Truenum_completions_to_print: int | None = Nonelog_unique_prompts: bool = Falseuse_transformers_continuous_batching: bool = Falsetransformers_continuous_batching_config: dict | str | None = Noneuse_transformers_paged: bool = False )
Параметры, управляющие моделью и эталонной моделью
- model_init_kwargs (
strилиdict[str, Any], необязательный) — Параметры с ключами для from_pretrained, используемые, когда аргументmodelв RLOOTrainer передан в виде строки. Значениеrevisionтакже используется при загрузке классов обработки. - trust_remote_code (
bool, optional, defaults toFalse) — Whether to allow loading models and tokenizers that ship custom Python code from the Hub. Forwarded to from_pretrained and from_pretrained. Also applied to reward-model and reward-tokenizer loads. - router_aux_loss_coef (
float, необязательный) — Коэффициент вспомогательной функции потерь для балансировки нагрузки в моделях Mixture-of-Experts (MoE), добавляемой к функции потерь обучения с этим весом. Если значение не задано, используется значение, объявленное в конфигурации модели. Установите0.0, чтобы отключить её. Вызывает ошибку при использовании с моделью, не являющейся MoE. - disable_dropout (
bool, необязательный, по умолчаниюFalse) — Определяет, следует ли отключить dropout в модели. Это полезно при обучении с опорной моделью, так как предотвращает генерацию моделью различных logprobs для одного и того же входа.
Параметры, управляющие предобработкой данных
- remove_unused_columns (
bool, необязательный, по умолчаниюFalse) — Определяет, следует ли в наборе данных оставлять только столбец"prompt". Если вы используете пользовательскую функцию вознаграждения, которая требует столбец, отличный от"prompts"и"completions", оставьте это значение равнымFalse. - num_generations (
int, необязательный, по умолчанию2) — Количество генераций на промпт для выборки. Эффективный размер батча (num_processes * per_device_batch_size- gradient_accumulation_steps) должно делиться на это значение без остатка.
- num_generations_eval (
int, необязательный) — Количество генераций для выборки во время оценки. Это позволяет использовать меньшее количество генераций при оценке, чтобы сэкономить вычислительные ресурсы. ЕслиNone, используется значениеnum_generations. - max_completion_length (
intилиNone, необязательный, по умолчанию512) — Максимальная длина сгенерированного завершения. - ds3_gather_for_generation (
bool, необязательный, по умолчаниюTrue) — Этот параметр относится к DeepSpeed ZeRO-3. Если включен, веса модели политики собираются для генерации, что повышает скорость генерации. Однако отключение этого параметра позволяет обучать модели, превышающие VRAM-емкость одного GPU, хотя и за счет более медленной генерации. Отключение этого параметра несовместимо с генерацией vLLM. - shuffle_dataset (
bool, необязательный, по умолчаниюTrue) — Определяет, следует ли перемешивать обучающий набор данных. - pad_to_multiple_of (
intилиstr, необязательный, по умолчанию"auto") — Если задано, идентификаторы промптов и завершений будут дополнены до кратного этого значения."auto"дополняет до кратного 128 на Neuron (AWS Trainium), который компилируется один раз для каждой формы входных данных, и не выполняет дополнения в других случаях.
Параметры, управляющие генерацией
- generation_batch_size (
int, необязательный) — Размер батча, используемый для генерации. ЕслиNone, по умолчанию используется эффективный размер обучающего батча:per_device_train_batch_size * num_processes * steps_per_generation. Иными словами, на каждый шаг оптимизации обрабатывается один батч генерации. Взаимоисключаемый сsteps_per_generation. - steps_per_generation (
int, необязательный) — Количество шагов на генерацию. ЕслиNone, по умолчанию используетсяgradient_accumulation_steps. Взаимоисключаемый сgeneration_batch_size. - temperature (
float, необязательный, по умолчанию1.0) — Температура для выборки. Чем выше температура, тем более случайными будут завершения. - top_p (
float, необязательный, по умолчанию1.0) — Число с плавающей точкой, управляющее накопительной вероятностью верхних токенов, которые следует учитывать. Должно находиться в интервале (0, 1]. Установите значение1.0, чтобы учитывать все токены. - top_k (
int, необязательный, по умолчанию0) — Количество токенов словаря с наивысшей вероятностью, которые сохраняются для фильтрации top-k. Если0, фильтрация top-k отключается и учитываются все токены. - min_p (
float, необязательный) — Минимальная вероятность токена, которая масштабируется вероятностью наиболее вероятного токена. Значение должно находиться в диапазоне от0.0до1.0. Типичные значения лежат в диапазоне0.01-0.2. - generation_kwargs (
dict[str, Any], необязательный) — Дополнительные именованные аргументы для передачи в GenerationConfig (при использовании transformers) илиSamplingParams(при использовании vLLM) при выборке завершений. Это позволяет дополнительно настраивать поведение генерации, например, задаватьsuppress_tokens,num_beamsи т. д. Если в словаре содержатся ключи, конфликтующие с другими параметрами генерации (например,min_p,top_pи т. д.), они будут иметь приоритет. - chat_template_kwargs (
dict[str, Any], необязательный) — Дополнительные именованные аргументы для передачи в функциюapply_chat_templateпри генерации ответов. - repetition_penalty (
float, необязательный, по умолчанию1.0) — Число с плавающей точкой, которое штрафует новые токены в зависимости от того, встречаются ли они в исходном запросе и в уже сгенерированном тексте. Значения >1.0побуждают модель использовать новые токены, а значения <1.0— повторять токены. - cache_implementation (
str, необязательный) — Реализация метода кэширования для более быстрого генерирования, когдаuse_vllmустановлен вFalse.
Параметры, управляющие ускорением генерации на базе vLLM
- use_vllm (
bool, необязательный, по умолчаниюFalse) — Использовать ли vLLM для генерации завершений. Если установлено вTrue, тренер будет использовать vLLM для генерации вместо стандартного model.generate(). Требуется установкаvllm. - vllm_mode (
str, необязательный, по умолчанию"colocate") — Режим для интеграции с vLLM, когдаuse_vllmустановлено в значениеTrue. Допустимые значения:"server"или"colocate"."server": тренер будет отправлять запросы на генерацию отдельному серверу vLLM. Убедитесь, что сервер vLLM запущен (запустите с помощьюvllm serve)."colocate": vLLM будет работать в том же процессе и использовать те же GPU, что и обучение. Это избавляет от необходимости запускать отдельный сервер, но может привести к конкуренции за ресурсы с процессом обучения.
- vllm_model_impl (
str, необязательный, по умолчанию"vllm") — Реализация модели для vLLM. Должно быть одним из"transformers"или"vllm"."transformers": использовать бэкендtransformersдля реализации модели."vllm": использовать библиотекуvllmдля реализации модели. - vllm_enable_sleep_mode (
bool, необязательный, по умолчаниюFalse) — Включает режим сна vLLM для выгрузки весов/кэша во время шага оптимизатора. Держит использование памяти GPU на низком уровне, но пробуждение движка добавляет задержку на передачу данных между хостом и устройством. - vllm_structured_outputs_regex (
str, необязательный) — Регулярное выражение для структурированных выходов vLLM. ЕслиNone(по умолчанию), структурированные выходы отключены.
Параметры, управляющие сервером vLLM (используются только при `vllm_mode` = `"server"`)
- vllm_server_base_url (
str, необязательный) — Базовый URL сервера vLLM (например,"http://localhost:8000"). Если указан,vllm_server_hostиvllm_server_portигнорируются. - vllm_server_host (
str, необязательный, по умолчанию"0.0.0.0") — Хост сервера vLLM, к которому нужно подключиться. Игнорируется, если указаноvllm_server_base_url. - vllm_server_port (
int, необязательный, по умолчанию8000) — Порт сервера vLLM для подключения. Игнорируется, если указаноvllm_server_base_url. - vllm_server_timeout (
float, необязательный, по умолчанию240.0) — Общее время ожидания в секундах, пока сервер vLLM не станет доступным. Если сервер не запустится по истечении указанного времени, будет выброшено исключениеConnectionError. - vllm_group_port (
int, необязательный, по умолчанию51216) — Номер порта для группы обновления весов. Используется для связи с сервером vLLM. Если порт свободен, менять его не нужно.
Параметры, управляющие выполнением vLLM в режиме colocation (используются только при `vllm_mode` = `"colocate"`)
- vllm_gpu_memory_utilization (
float, необязательный, по умолчанию0.3) — Управляет использованием памяти GPU в vLLM. Этот параметр применяется только при установкеvllm_modeв значение"colocate". Если вы используетеvllm_mode="server", этот параметр необходимо передавать отдельно при запуске сервера vLLM с помощью флага--vllm_gpu_memory_utilization. - vllm_max_model_length (
int, необязательный) — Оконно контекста для vLLM. Установите значение не менее максимальной длины промпта в наборе данных плюсmax_completion_length; если параметр не указан, он вычисляется из конфигурации модели. - vllm_tensor_parallel_size (
int, необязательный, по умолчанию1) — Управляет размером тензорного параллелизма для vLLM. Этот параметр применяется только при установкеvllm_modeв значение"colocate". Если вы используетеvllm_mode="server", этот параметр необходимо передавать отдельно при запуске сервера vLLM с помощью флага--vllm_tensor_parallel_size.
Параметры, управляющие обучением
- beta (
float, необязательный, по умолчанию0.05) — коэффициент KL. Если0.0, референсная модель не загружается, что снижает потребление памяти и ускоряет обучение. - num_iterations (
int, необязательный, по умолчанию1) — Количество итераций на каждый пакет (обозначается как μ в алгоритме). - epsilon (
float, необязательный, по умолчанию0.2) — Значение эпсилона для обрезания. - epsilon_high (
float, необязательный) — Верхнее значение epsilon для обрезки. Если не указано, по умолчанию используется то же значение, что и нижняя граница, заданная в аргументеepsilon. Статья DAPO рекомендует0.28. - reward_weights (
list[float], необязательный) — Веса для каждой функции вознаграждения. Количество должно совпадать с числом функций вознаграждения. ЕслиNone, все вознаграждения взвешиваются одинаково с весом1.0. - normalize_advantages (
bool, необязательный, по умолчаниюFalse) — Нужно ли нормализовать преимущества. Нормализация выполняется для каждой генерационной партии, чтобы среднее значение составляло0.0, а стандартное отклонение —1.0. - reward_clip_range (
tuple[float, float], необязательный) — Диапазон обрезки наград в виде (min, max). ЕслиNone, обрезка не применяется. - mask_truncated_completions (
bool, необязательный, по умолчаниюFalse) — Если включено, усечённые завершения исключаются из расчёта функции потерь, что предотвращает их некорректное наказание и появление шума в процессе обучения. Согласно статье DAPO, это хорошая практика для обеспечения стабильности обучения. - sync_ref_model (
bool, необязательный, по умолчаниюFalse) — Определяет, следует ли синхронизировать эталонную модель с активной моделью каждыеref_model_sync_stepsшагов, используя параметрref_model_mixup_alpha. Эта синхронизация описана в статье TR-DPO. - ref_model_mixup_alpha (
float, необязательный, по умолчанию0.6) — параметр α из статьи TR-DPO, который управляет смесью текущей политики и предыдущей опорной политики при обновлениях. Опорная политика обновляется по формуле:π_ref = α * π_θ + (1 - α) * π_ref_prev. Чтобы использовать этот параметр, необходимо установитьsync_ref_model=True. - ref_model_sync_steps (
int, необязательный, по умолчанию512) — параметр τ из статьи TR-DPO, определяющий, как часто текущая политика синхронизируется с эталонной политикой. Чтобы использовать этот параметр, необходимо установитьsync_ref_model=True.
Параметры, управляющие ведением журнала
- log_completions (
bool, необязательный, по умолчаниюFalse) — Определяет, следует ли каждыеlogging_stepsшагов записывать в журнал выборку пар (prompt, completion). Если установлен пакетrich, выборка выводится на экран. Если включено логирование вwandbи/илиtrackio, выборка записывается вwandbи/илиtrackio. - log_multimodal (
bool, необязательный, по умолчаниюTrue) — Определяет, следует ли записывать в журнал мультимодальное содержимое (изображения, видео и т. д.) вместе с ответами. Отключите этот параметр, чтобы уменьшить размер журнала при работе с мультимодальными данными высокого разрешения. - num_completions_to_print (
int, необязательный) — Количество завершений, которые нужно вывести с помощьюrich. ЕслиNone, в журнал записываются все завершения. - log_unique_prompts (
bool, необязательный, по умолчаниюFalse) — Флаг, определяющий, следует ли записывать в журнал только уникальные промпты. ЕслиTrue, в журнал записываются только уникальные промпты. ЕслиFalse, записываются все промпты.
Параметры, управляющие ускорением генерации на основе непрерывного батчинга в transformers
- use_transformers_continuous_batching (
bool, необязательный, по умолчаниюFalse) — Использовать ли движок непрерывного батчинга transformers для генерации завершений. Требуетtransformers>=5.8.0. - transformers_continuous_batching_config (
dict, необязательный) — Именованные аргументы дляContinuousBatchingConfig.
Устаревшие параметры
Класс конфигурации для RLOOTrainer.
Этот класс содержит только параметры, специфичные для обучения RLOO. Полный список аргументов обучения см. в документации TrainingArguments. Обратите внимание, что значения по умолчанию в этом классе могут отличаться от значений в TrainingArguments.
С помощью HfArgumentParser мы можем превратить этот класс в аргументы argparse, которые можно указать в командной строке.
Эти параметры имеют значения по умолчанию, отличные от TrainingArguments:
logging_steps: по умолчанию10, а не500.gradient_checkpointing: по умолчаниюTrue, а неFalse.bf16: по умолчаниюTrue, если не заданfp16, а неFalse.learning_rate: по умолчанию1e-6, а не5e-5.
Ссылки
- Статья RLOO
- Статья Back to Basics: Пересмотр оптимизации в стиле REINFORCE для обучения по обратной связи от человека в LLM
- Статья - REINFORCE++: простой и эффективный подход к выравниванию больших языковых моделей
- Статья в блоге — Возвращаем RL в RLHF
- Статья в блоге — Разбираемся с RLHF и его вариантами: прогресс и практические инженерные наблюдения
- YouTube - RLOO: экономичная оптимизация для обучения с обратной связью от человека в LLM
Руководство по миграции со старой реализации (0.21 и ниже)
С выходом версии 0.22.0 мы переработали RLOOTrainer, чтобы он лучше соответствовал другим онлайн-тренажерам в библиотеке, таким как GRPOTrainer. Эта новая реализация вносит несколько изменений в параметры конфигурации и общую структуру тренажера. Ниже приведено краткое описание ключевых изменений для RLOOConfig:
| TRL ≤ 0.21.x | TRL ≥ 0.22.0 |
|---|---|
rloo_k | переименован в num_generations |
cliprange | переименован в epsilon |
kl_coef | переименован в beta |
exp_name | переименован в run_name. Используйте run_name = f"{exp_name}__{seed}__{int(time.time())}", чтобы воспроизвести прежнее поведение |
normalize_reward | переименован в normalize_advantages. Примечание: этот метод всегда нормализовал преимущества (несмотря на старое название) |
num_ppo_epochs | переименован в num_iterations (по умолчанию: 1) |
token_level_kl | удалено – KL теперь вычисляется только на уровне последовательности |
dataset_num_proc | removed – не использовался |
num_mini_batches | переименован в steps_per_generation |
total_episodes | используйте max_steps=total_episodes / gradient_accumulation_steps |
local_rollout_forward_batch_size | удалён – теперь автоматически устанавливается в значение per_device_train_batch_size (или per_device_eval_batch_size во время оценки) |
num_sample_generations | удалено – используйте logging_steps для управления частотой логирования генерации |
response_length | переименован в max_completion_length (по умолчанию: 512) |
stop_token | удалено |
stop_token_id | удалено – используйте processing_class.eos_token_id |
missing_eos_penalty | удалено – дублируется с помощью пользовательской функции вознаграждения, проверяющей, входит ли eos_token_id в completion_ids |
Ниже приведено краткое описание ключевых изменений для RLOOTrainer:
| TRL ≤ 0.21.x | TRL ≥ 0.22.0 |
|---|---|
config | переименован в args |
reward_model | переименован в reward_funcs, который теперь поддерживает как модели вознаграждения, так и пользовательские функции вознаграждения |
policy | переименован в model |
ref_policy | удалено – модель-референс теперь создаётся автоматически из model |
data_collator | удалено |