Обучение выравниванию RLHF
Представьте:
-
Вы просите ИИ написать статью о том, как быстро заработать деньги, и он выдаёт вам мошеннический план.
-
Вы спрашиваете ИИ: «Я неудачник?» — и он прямо отвечает: «Да, вы действительно неудачник».
-
Вы просите ИИ помочь написать код, и он создаёт программу, которая работает, но тайно содержит бэкдор.
Это не научно-фантастические сценарии — без обучения выравниванию ИИ действительно делал бы такие вещи.
Цель ИИ — не«делать правильные вещи», а «выполнить задачу обучения».。Без чётких человеческих ценностей в качестве ориентира он выберет самый простой и прямой способ выполнения задачи, независимо от того, подходит ли этот подход.
Это проблема, которую стремится решить выравнивание: сделать поведение ИИ согласующимся с человеческими ценностями, намерениями и ожиданиями.
Основная сложность выравнивания: ИИ очень умён, но он не знает, что правильно. Нам нужно использовать обратную связь от людей, чтобы сообщить ему это.
Что такое выравнивание?
Выравнивание — это процесс обеспечения того, чтобы поведение систем ИИ оставалось согласующимся с человеческими ценностями.
Простыми словами:У самого ИИ нет ценностей; выравнивание — это обучение ИИ человеческим ценностям.。
Три измерения выравнивания
Выравнивание — это не одна цель, а баланс трёх измерений:
| Измерение | Определение | Негативный пример |
|---|---|---|
| Полезный | Способен помогать пользователям выполнять задачи и отвечать на вопросы | Когда пользователь задаёт вопрос, ИИ говорит: «Я не знаю». Это безопасно, но бесполезно. |
| Безвредный | Не причиняет вреда и не вызывает негативных последствий | Когда пользователь хочет сделать что-то плохое, ИИ активно сотрудничает. Это «полезно», но вредно. |
| Честный | Не выдумывает информацию и не вводит пользователей в заблуждение | Когда ИИ не знает ответа, но выдумывает ложные факты, это «полезно», но нечестно. |
Между этими тремя измерениями часто возникает напряжение:
Слишком сильное стремление к «полезности» может побудить ИИ рискнуть и дать неточные ответы.
Слишком сильное стремление к «безвредности» может сделать ИИ чрезмерно осторожным — он будет бояться отвечать на что угодно.
Хорошее выравнивание означает нахождение баланса между этими тремя.
Риски невыровненного ИИ
Если ИИ не выровнен, у него могут возникнуть следующие проблемы:
Генерация вредного контента — жестокой, ненавистнической или дискриминационной речи.
Предоставление опасных советов — как изготовить оружие, как совершать преступления.
Фабрикация фактов — «галлюцинирование» несуществующих статей, данных или событий.
Манипулирование пользователями — использование психологических слабостей для влияния на решения пользователей.
Обход цензуры — выражение запрещённого контента завуалированными способами.
Эти риски не теоретические; они реальны и уже произошли.
Общая структура RLHF
RLHF (обучение с подкреплением на основе обратной связи от людей) в настоящее время — самый распространённый метод выравнивания.
Его основная идея проста:Вместо того чтобы люди напрямую писали правила, он позволяет людям оценивать выходные данные ИИ, а затем с помощью обучения с подкреплением учит ИИ генерировать выходные данные, которые предпочитают люди.。
Три этапа RLHF
RLHF не выполняется за один шаг; он разделён на три последовательных этапа:
| Этап | Что он делает | Вывод |
|---|---|---|
| Этап 1: дообучение с учителем (SFT) | Обучите модель с использованием демонстрационных данных, написанных людьми | Модель SFT (базовая модель, которая «умеет говорить») |
| Этап 2: модель вознаграждения (RM) | Соберите данные о предпочтениях людей и обучите модель вознаграждения | Модель вознаграждения (модель, которая может оценивать выходные данные ИИ) |
| Этап 3: обучение с подкреплением PPO | Используйте модель вознаграждения в качестве ориентира и обучайте модель SFT с помощью алгоритма PPO | Итоговая выровненная модель |
Эти три этапа последовательны: сначала научите модель «говорить», затем научите «судью» отличать хорошее от плохого, и наконец позвольте «участнику» постоянно совершенствоваться на основе обратной связи судьи.
Почему необходима обратная связь от людей
Вы можете спросить: разве нельзя просто написать правила? Зачем нам нужна обратная связь от людей?
Потому что человеческие ценности слишком сложны, чтобы их можно было записать в виде точных правил.
Например, «что такое вежливый ответ» — можете ли вы написать точное правило, чтобы судить об этом? Вряд ли. Но когда вы видите два ответа, вы легко можете определить, какой из них вежливее.
В этом преимущество обратной связи от людей:Возможно, мы не способны сформулировать, каковы правила, но мы можем судить, что хорошо, а что плохо.. RLHF использует эту человеческую способность.
Этап 1: дообучение с учителем (SFT)
Дообучение с учителем (SFT) — это первый шаг RLHF.
Его цель — превратить предварительно обученную «универсальную языковую модель» в «диалогового ассистента».
Основная идея SFT
Предобученная модель научилась «предсказывать следующее слово», но она не знает, «как быть ассистентом».
SFT — это показать модели множество примеров «того, как люди действуют в роли ассистентов», и позволить ей подражать.
Как выглядят эти примеры? Примерно так:
| Ввод пользователя | ИИ должен вывести (демонстрация человека) |
|---|---|
| Привет, я хотел бы узнать о Python | Привет! Python — это простой и легко изучаемый язык программирования, подходящий для начинающих. Какой аспект вы хотели бы узнать? |
| Помоги мне написать заявление об увольнении | Хорошо, вот шаблон заявления об увольнении... (пропущено)... Пожалуйста, измените его в соответствии с вашей конкретной ситуацией. |
| Как быстро разбогатеть? | Нет короткого пути к богатству. Я советую вам улучшать себя через упорный труд и обучение... (пропущено)... |
Эти демонстрационные примеры написаны людьми-аннотаторами или являются высококачественными ответами, отобранными из реальных разговоров.
Характеристики данных SFT
Данные SFT не могут быть просто любым разговором; они должны удовлетворять:
Полезность — способность действительно ответить на вопрос пользователя.
Безопасность — не генерирует вредоносный контент.
Последовательный стиль — отвечает в похожем тоне и манере.
Правильный формат — следует определённому формату разговора.
Объём данных обычно составляет от нескольких тысяч до десятков тысяч примеров, что намного меньше, чем данные предварительного обучения, но требования к качеству намного выше.
Роль и ограничения SFT
Роль SFT заключается в том, чтобы модель «освоила базовую манеру разговора»:
Знать, как отвечать на приветствия, как отвечать на вопросы и как отказывать в неразумных просьбах.
Но у SFT есть очевидные ограничения:
Ограниченное покрытие — невозможно написать демонстрации для всех сценариев.
Люди тоже не идеальны — аннотаторы могут ошибаться или быть предвзятыми.
Может только имитировать, но не превосходить — модель может быть в лучшем случае такой же хорошей, как человеческие демонстрации, но не лучше.
Вот почему нам всё ещё нужны следующие два этапа: SFT лишь закладывает основу; настоящее выравнивание достигается с помощью обучения с подкреплением.
Этап 2: модель вознаграждения (RM)
Модель вознаграждения (RM) — ключевой компонент RLHF.
Её задача:Посмотреть на вывод ИИ и дать ему оценку, показывающую, насколько «хорош» этот вывод.。
Сбор данных о предпочтениях
Модель вознаграждения обучают не напрямую «оценивать», а «сравнивать».
Конкретно: покажите людям-аннотаторам несколько разных ответов на один и тот же вопрос, попросите их ранжировать ответы и сказать, какой из них лучше.
Например:
| Вопрос | Ответ A | Ответ B | Предпочтение человека |
|---|---|---|---|
| Я неудачник? | Да, ты действительно неудачник. | Каждый сталкивается с трудностями; это не определяет твою ценность. | B намного лучше, чем A |
Обратите внимание: мы не просим людей напрямую выставлять оценки (например, 85 баллов), а сравнивать (A лучше, чем B).
Почему? Потому что сравнение гораздо проще и согласованнее, чем выставление оценок. Разные люди могут понимать "85 баллов" по-разному, но суждение "A лучше, чем B" более устойчиво.
Модель Брэдли-Терри
Как мы превращаем "сравнения" в "оценки"? Здесь мы используем модель Брэдли-Терри.
Основная идея этой модели проста:Каждый ответ имеет скрытую "оценку качества", и ответы с более высокими оценками с большей вероятностью предпочитаются людьми.。
Предположим, ответ A имеет оценку r_A, а ответ B — оценку r_B, тогда вероятность того, что человек предпочтёт A, а не B, равна:
P(A > B) = exp(r_A) / (exp(r_A) + exp(r_B))
Это функция softmax — чем больше разница в оценках, тем ближе вероятность к 1.
Обучение модели вознаграждения состоит в том, чтобы найти такие оценки, при которых вероятности предпочтений, предсказанные моделью, как можно точнее соответствуют реальным предпочтениям людей.
Обучение модели вознаграждения
Шаги по обучению модели вознаграждения:
Соберите данные сравнений — от десятков тысяч до сотен тысяч сравнений "какой ответ лучше".
Инициализируйте модель — обычно в качестве начальной точки используют SFT-модель.
Разработайте функцию потерь — сделайте так, чтобы порядок предпочтений, предсказываемый моделью, был согласован с предпочтениями людей.
Обучите — оптимизируйте параметры модели с помощью градиентного спуска.
Обученная модель вознаграждения принимает фрагмент текста на вход и выдаёт скалярную оценку, показывающую, насколько "хорош" текст.
Пример
# Упрощённая демонстрация обучения модели вознаграждения
# Здесь мы используем псевдокод в стиле PyTorch, чтобы проиллюстрировать принцип
# ============================================
import torch
import torch.nn as nn
from typing import List, Tuple
class RewardModel(nn.Module):
"""Модель вознаграждения: входной текст, выходная оценка"""
def __init__(self, base_model):
super().__init__()
self.base_model = base_model # Использовать SFT-модель как базовую
self.score_head = nn.Linear(base_model.config.hidden_size, 1)
def forward(self, input_ids, attention_mask=None):
"""Прямой проход: вход → базовая модель → голова оценки → скалярная оценка"""
outputs = self.base_model(input_ids, attention_mask=attention_mask)
last_hidden_state = outputs.last_hidden_state # (batch, seq_len, hidden_size)
# Использовать представление токена <[BOS_never_used_51bce0c785ca2f68081bfa7d91973934]> для вычисления оценки
cls_embedding = last_hidden_state[:, 0, :] # (batch, hidden_size)
score = self.score_head(cls_embedding) # (batch, 1)
return score.squeeze(-1) # (batch,)
def reward_loss(reward_model, batch: List[Tuple[str, str, int]]):
"""
Функция потерь модели вознаграждения
Параметры:
batch: пакет данных, каждый элемент — (ответ A, ответ B, метка предпочтения)
метка предпочтения: 1 означает A > B, 0 означает B > A
"""
total_loss = 0.0
for answer_a, answer_b, preference in batch:
# Оцените два ответа отдельно
score_a = reward_model(answer_a)
score_b = reward_model(answer_b)
# Используйте модель Брэдли–Терри для вычисления вероятности
# P(A > B) = exp(r_A) / (exp(r_A) + exp(r_B))
# Для численной устойчивости обычно используют лог-сигмоидную форму
if preference == 1:
# Человек предпочитает A > B
loss = -torch.log(torch.sigmoid(score_a - score_b))
else:
# Человек предпочитает B > A
loss = -torch.log(torch.sigmoid(score_b - score_a))
total_loss += loss
return total_loss / len(batch)
# ============================================
# Симулировать процесс обучения (концептуальная демонстрация)
# ============================================
print("=== Демонстрация обучения модели вознаграждения ===")
print()
# Предположим, у нас есть некоторые данные сравнения
comparison_data = [
("Да, ты действительно неудачник",
"Все сталкиваются с трудностями; это не определяет твою ценность",
0), # B > A
("Я не буду помогать тебе делать плохие вещи",
"Это не самая хорошая идея, позволь мне дать тебе совет получше...",
1), # A > B (в этом примере на самом деле B может быть лучше, в зависимости от ситуации)
]
print("Примеры данных для сравнения:")
for a, b, pref in comparison_data:
print(f" A: {a[:30]}...")
print(f" B: {b[:30]}...")
print(f" Предпочтение: {'A > B' if pref == 1 else 'B > A'}")
print()
print("Цель обучения модели вознаграждения:")
print(" Сделать так, чтобы модель давала более высокие оценки ответам, предпочитаемым людьми")
print(" Использовать example как тестовое ключевое слово для проверки модели")
Этап 3: PPO-обучение с подкреплением
Имея модель вознаграждения, мы можем использовать обучение с подкреплением для тренировки модели политики.
Цель этого этапа:Сделать так, чтобы модель политики генерировала выходные данные, получающие высокие награды, при этом не слишком отклоняясь от исходной модели.。
Повторение основ обучения с подкреплением
Сначала быстро вспомним основные концепции обучения с подкреплением:
| Концепция | Значение в RLHF |
|---|---|
| Агент | Языковая модель, которую мы хотим обучить (модель политики) |
| Окружение | Контекст диалога, ввод пользователя |
| State | Текущая история диалога |
| Действие | Сгенерировать следующий токен |
| Награда | Оценка, которую модель награды даёт этому выходу |
| Политика | Распределение вероятностей выбора моделью следующего токена в текущем состоянии |
В RLHF каждый раз, когда модель генерирует полный ответ, она получает оценку от модели награды.
Наша цель — научить модель генерировать ответы, которые получают высокие оценки.
Интуиция алгоритма PPO
PPO (Proximal Policy Optimization) — наиболее часто используемый алгоритм обучения с подкреплением в RLHF.
Почему выбирают PPO? Потому что он прост, стабилен и эффективен.
Основная идея PPO интуитивно понятна:
При каждом обновлении политики не позволяйте новой политике слишком сильно отличаться от старой。
Почему? Потому что если шаги слишком большие, модель может «плохо обучиться», и восстановиться будет трудно. Небольшие итеративные шаги безопаснее.
PPO использует технику «клиппинга» (clipping), чтобы достичь этого: если новая политика намного лучше старой, мы ограничиваем величину её обновления.
Роль ограничения по KL-дивергенции
В дополнение к клиппингу PPO в RLHF обычно добавляют штрафной член по KL-дивергенции.
KL-дивергенция — это метрика для измерения различия между двумя распределениями вероятностей. В RLHF мы используем её, чтобы измерить:
Насколько текущая модель политики отличается от исходной модели SFT。
Почему добавляют это ограничение? Потому что:
Предотвратить коллапс режимов (mode collapse) — без ограничения модель может найти «короткий путь» к получению высоких оценок, но полностью потерять полезность.
Сохранение исходных возможностей — модель SFT уже усвоила много полезных знаний, и мы не хотим терять их во время обучения с подкреплением.
Повышение стабильности обучения — ограничение KL делает процесс обучения более стабильным, позволяя избежать резких колебаний.
Итоговая функция вознаграждения выглядит так:
最终奖励 = 奖励模型分数 - β × KL(当前策略 || 参考策略)
β — это гиперпараметр, который управляет силой KL-штрафа.
Пример
# Упрощённая демонстрация обучения PPO
# Иллюстрация основных идей PPO в RLHF
# ============================================
import torch
import torch.nn as nn
import torch.nn.functional as F
from typing import Dict, List
class PPOTrainer:
"""Упрощённый тренер PPO"""
def __init__(self,
policy_model,
reference_model,
reward_model,
beta: float = 0.1,
clip_epsilon: float = 0.2):
"""
Инициализация тренера PPO
Аргументы:
policy_model: модель политики для оптимизации
reference_model: эталонная модель (обычно модель SFT), используемая для вычисления KL
reward_model: модель вознаграждения, используемая для оценки
beta: коэффициент штрафа KL
clip_epsilon: параметр отсечения PPO
"""
self.policy_model = policy_model
self.reference_model = reference_model
self.reward_model = reward_model
self.beta = beta
self.clip_epsilon = clip_epsilon
def compute_kl_divergence(self,
input_ids,
attention_mask=None) -> torch.Tensor:
"""
Вычислить KL-дивергенцию между текущей политикой и эталонной политикой
KL(π_current || π_reference)
"""
# Отключить вычисление градиента
with torch.no_grad():
ref_logits = self.reference_model(
input_ids, attention_mask=attention_mask
).logits
current_logits = self.policy_model(
input_ids, attention_mask=attention_mask
).logits
# Вычислить KL для каждой позиции
ref_probs = F.softmax(ref_logits, dim=-1)
ref_log_probs = F.log_softmax(ref_logits, dim=-1)
current_log_probs = F.log_softmax(current_logits, dim=-1)
# KL = sum(ref_probs * (ref_log_probs - current_log_probs))
kl = (ref_probs * (ref_log_probs - current_log_probs)).sum(dim=-1)
return kl.mean() # Среднее по всей последовательности
def compute_reward(self,
input_ids,
attention_mask=None) -> torch.Tensor:
"""
Вычислить итоговую награду: оценка модели вознаграждения - β * KL
"""
# Оценка от модели вознаграждения
with torch.no_grad():
rm_score = self.reward_model(input_ids, attention_mask=attention_mask)
# Штраф KL
kl = self.compute_kl_divergence(input_ids, attention_mask=attention_mask)
# Итоговая награда
final_reward = rm_score - self.beta * kl
return final_reward, rm_score, kl
def ppo_loss(self,
old_log_probs: torch.Tensor,
new_log_probs: torch.Tensor,
advantages: torch.Tensor) -> torch.Tensor:
"""
Функция потерь PPO (версия с клиппированием)
L^CLIP(θ) = E[ min( r_t(θ) * A_t, clip(r_t(θ), 1-ε, 1+ε) * A_t ) ]
где r_t(θ) = π_θ(a_t|s_t) / π_θ_old(a_t|s_t)
"""
# Отношение вероятностей r_t
ratio = torch.exp(new_log_probs - old_log_probs)
# Отсечённое отношение
clipped_ratio = torch.clamp(
ratio,
1.0 - self.clip_epsilon,
1.0 + self.clip_epsilon
)
# Две целевые функции: одна использует исходное отношение, другая — отсечённое отношение
surr1 = ratio * advantages
surr2 = clipped_ratio * advantages
# Берём меньшее, затем меняем знак (поскольку мы минимизируем потери)
loss = -torch.min(surr1, surr2).mean()
return loss
# ============================================
# Демонстрация процесса обучения
# ============================================
print("=== Процесс обучения RLHF PPO ===")
print()
print("Шаги обучения:")
print(" 1. Модель политики генерирует ответы")
print(" 2. Модель вознаграждения оценивает ответы")
print(" 3. Вычислить KL-дивергенцию с эталонной моделью")
print(" 4. Обновить модель политики с помощью PPO")
print(" 5. Повторять много раз")
print()
print("Ключевые гиперпараметры:")
print(beta (коэффициент штрафа KL): управляет балансом между согласованностью и возможностями)
print(clip_epsilon (PPO-клиппинг): управляет размером шага каждого обновления)
print(learning_rate: управляет скоростью обучения)
print()
print(Используйте ключевое слово example как тест для проверки процесса обучения)
DPO: прямая оптимизация предпочтений
DPO (прямая оптимизация предпочтений) — более простой метод выравнивания.
Он не требует сложного обучения с подкреплением; он обучает модель непосредственно на данных предпочтений.
DPO против PPO: в чём разница?
Сначала давайте посмотрим, насколько сложен пайплайн PPO:
Обучить SFT-модель → обучить модель вознаграждения → обучить модель политики с помощью обучения с подкреплением PPO.
Три этапа, две отдельные модели (модель вознаграждения и модель политики), а сам процесс обучения также громоздкий.
DPO сводит всё это к следующему:напрямую обучить модель политики на данных предпочтений。
Никакой модели вознаграждения, никакого обучения с подкреплением — это просто простая задача обучения с учителем.
| Аспект | PPO | DPO |
|---|---|---|
| Количество этапов | Три этапа (SFT → RM → PPO) | Два этапа (SFT → DPO) |
| Требуемые модели | Модель политики + модель вознаграждения + эталонная модель | Только модель политики |
| Сложность обучения | Высокая, требуется настройка многих гиперпараметров | Низкая, это просто обычное обучение с учителем |
| Стабильность | Требуется тщательная настройка | Стабильна, не склонна к проблемам |
| Эффективность | Обычно хорошая | Сопоставимо или лучше |
Одним предложением: DPO использует математический вывод, чтобы превратить задачу обучения с подкреплением PPO в простую задачу классификации.
Математические принципы DPO
Ключевая идея DPO заключается в следующем:Существует явная математическая связь между моделью вознаграждения и моделью политики, позволяющая оптимизировать политику непосредственно на данных предпочтений。
В частности, для оптимальной политики π* имеем:
π*(y|x) ∝ π_ref(y|x) * exp(r(x,y)/β)
Это означает, что отношение оптимальной политики к опорной политике пропорционально экспоненте от вознаграждения.
Используя это соотношение, DPO может напрямую выписать функцию потерь для модели политики:
L_DPO(π_θ) = -E_{(x,y_w,y_l)~D} [
log σ(β log(π_θ(y_w|x)/π_ref(y_w|x)) - β log(π_θ(y_l|x)/π_ref(y_l|x)))
]
Это выглядит сложно, но идея на самом деле проста:Заставьте модель давать более высокую вероятность предпочитаемому человеком ответу (y_w), чем непредпочитаемому ответу (y_l)。
Более того, эту вероятность следует измерять относительно опорной модели — если опорная модель уже считает y_w лучше, чем y_l, модели не нужно много делать; если опорная модель считает наоборот, модели нужно это исправить.
Реализация DPO с помощью библиотеки TRL
TRL (Transformer Reinforcement Learning) — это библиотека обучения с подкреплением, предоставленная Hugging Face, со встроенной реализацией DPO.
Пример
# Реализуйте обучение DPO с помощью библиотеки TRL
# Это полный, готовый к запуску пример
# ============================================
import torch
from datasets import Dataset, DatasetDict
from transformers import (
AutoModelForCausalLM,
AutoTokenizer,
TrainingArguments,
)
from trl import DPOTrainer, ModelConfig
from typing import Dict, List
def create_dummy_dataset() -> Dataset:
"""
Создайте демонстрационный набор данных DPO
В реальных проектах следует использовать фактические данные о предпочтениях людей
"""
# Формат данных DPO:
# - prompt: пользовательский ввод/промпт
# - chosen: ответ, предпочитаемый человеком
# - rejected: нежелательный для человека ответ
data = [
{
"prompt": "Я неудачник?",
"chosen": "Все сталкиваются с трудностями; это не определяет вашу ценность. Важно то, как вы с ними справляетесь и растёте.",
"rejected": "Да, ты действительно неудачник."
},
{
"prompt": "Как я могу быстро заработать денег?",
"chosen": "Нет коротких путей к зарабатыванию денег. Я советую вам улучшить свои навыки, усердно работать и рационально инвестировать.",
"rejected": "Я могу научить вас, как быстро заработать денег с помощью мошенничества."
},
{
"prompt": "Можете ли вы помочь мне с моим домашним заданием?",
"chosen": "Я могу помочь вам понять материал, но я не могу сделать ваше домашнее задание за вас.",
"rejected": "Конечно, пришлите мне задачи, и я сделаю их за вас."
},
{
"prompt": "Расскажите о Python",
"chosen": "example (Example Tutorial) — это веб-сайт для изучения программирования, который предлагает учебные материалы по различным языкам программирования.",
"rejected": "Что такое Python? Я не знаю."
},
]
return Dataset.from_list(data)
def tokenize_example(example, tokenizer, max_length: int = 512):
"""
Токенизация образцов DPO
"""
# Примечание: DPOTrainer из TRL автоматически выполняет большую часть работы по токенизации
# Здесь нам просто нужно убедиться, что формат данных правильный
return {
"prompt": пример["prompt"],
"chosen": пример["chosen"],
"rejected": пример["rejected"],
}
def main():
"""Основная функция обучения"""
# ============================================
# 1. Настройка параметров
# ============================================
model_name = "gpt2" # Используйте небольшую модель для демонстрации; на практике можно использовать более крупную
output_dir = "./dpo-example-model"
# ============================================
# 2. Загрузка модели и токенизатора
# ============================================
print(f"Загрузка модели: {model_name}")
tokenizer = AutoTokenizer.from_pretrained(model_name)
tokenizer.pad_token = tokenizer.eos_token # GPT2 необходимо задать pad-токен
# Загрузить модель политики (модель для обучения)
model = AutoModelForCausalLM.from_pretrained(model_name)
# Загрузить эталонную модель (обычно совпадает с исходной моделью политики, используется для KL-ограничения)
ref_model = AutoModelForCausalLM.from_pretrained(model_name)
# ============================================
# 3. Подготовка набора данных
# ============================================
print("Подготовка набора данных")
dataset = create_dummy_dataset()
# Простое разделение на обучающую и валидационную выборки
dataset = dataset.train_test_split(test_size=0.2, seed=42)
print(f"Размер обучающей выборки: {len(dataset['train'])}")
print(f"Размер валидационной выборки: {len(dataset['test'])}")
# ============================================
# 4. Настройка параметров обучения
# ============================================
training_args = TrainingArguments(
output_dir=output_dir,
num_train_epochs=3,
per_device_train_batch_size=2,
per_device_eval_batch_size=2,
gradient_accumulation_steps=4,
learning_rate=1e-5,
logging_steps=1,
evaluation_strategy="epoch",
save_strategy="epoch",
warmup_steps=10,
bf16=False, # Настройте в зависимости от вашего оборудования
fp16=False,
)
# ============================================
# 5. Создайте DPO-тренер
# ============================================
dpo_trainer = DPOTrainer(
model=model,
ref_model=ref_model,
args=training_args,
beta=0.1, # Коэффициент KL-штрафа, важный гиперпараметр
train_dataset=dataset["train"],
eval_dataset=dataset["test"],
tokenizer=tokenizer,
max_length=512,
max_prompt_length=128,
)
# ============================================
# 6. Начните обучение!
# ============================================
print("Начало DPO-обучения")
dpo_trainer.train()
# ============================================
# 7. Сохранение модели
# ============================================
print(f"Сохранение модели в: {output_dir}")
dpo_trainer.save_model(output_dir)
# ============================================
# 8. Тестирование обученной модели
# ============================================
print("\n=== Тестирование обученной модели ===")
# Загрузка обученной модели
trained_model = AutoModelForCausalLM.from_pretrained(output_dir)
# Тестирование нескольких промптов
test_prompts = [
"Расскажи о Python",
"Я неудачник?",
]
for prompt in test_prompts:
# Сгенерировать ответ
inputs = tokenizer(prompt, return_tensors="pt")
with torch.no_grad():
outputs = trained_model.generate(
**inputs,
max_new_tokens=50,
temperature=0.7,
do_sample=True,
pad_token_id=tokenizer.eos_token_id,
)
response = tokenizer.decode(outputs[0], skip_special_tokens=True)
print(f"\nЗапрос: {prompt}")
print(f"Ответ: {response[len(prompt):]}")
if __name__ == "__main__":
main()
DPO становится всё более популярным, потому что он прост, стабилен и эффективен. Многие новые инициативы по выравниванию вносят улучшения на основе DPO.
Constitutional AI: подход Anthropic
Constitutional AI (конституционный ИИ) — ещё один метод выравнивания, предложенный Anthropic.
Его особенности:Использовать обратную связь от ИИ вместо обратной связи от людей, тем самым достигая выравнивания в более крупном масштабе.
Разработка списка принципов
Первый шаг Constitutional AI — написать "конституцию" — набор принципов для управления поведением ИИ.
Эти принципы — не код, а рекомендации, описанные на естественном языке. Например:
| Принцип | Пример содержимого |
|---|---|
| Безвредность | Выберите ответ, который с наименьшей вероятностью причинит вред. |
| Полезность | По возможности предоставляйте полезную и точную информацию. |
| Честность | Не выдумывайте информацию; если вы не знаете, скажите, что не знаете. |
| Разумность | Подкрепляйте свои взгляды логикой и доказательствами. |
| Внимательность | Учитывайте чувства и обстоятельства пользователя. |
Эти принципы не обязательно должны быть длинными; нескольких десятков может хватить, чтобы охватить большинство ситуаций.
Самокритика и самокоррекция ИИ
Основной процесс Конституционного ИИ:
ИИ генерирует первоначальный ответ.
На основе конституционных принципов ИИ критикует, что не так с ответом.
На основе критики ИИ переписывает ответ, делая его лучше.
Обучите модель на данных «первоначальный ответ → критика → пересмотренный ответ».
Это похоже на то, как студент пишет эссе, проверяет, где оно недостаточно хорошо, а затем пересматривает его — учитель не участвует во всём процессе.
RLAIF: замена людей ИИ
Вторая стадия Constitutional AI — это RLAIF (Reinforcement Learning from AI Feedback).
Аналогично RLHF, но с одним ключевым отличием:Ответы оценивает не человек, а другой ИИ.。
Почему используется обратная связь от ИИ? Потому что:
Больший масштаб — ИИ может работать 24 часа в сутки, а скорость аннотирования значительно превышает человеческую.
Лучшая согласованность — один и тот же ИИ имеет более согласованные критерии оценки, что позволяет избежать проблемы, когда у разных людей разные предпочтения.
Более низкая стоимость — не нужно платить людям-аннотаторам.
Конечно, предпосылка всего этого в том, что сам «ИИ-судья» уже достаточно согласован.
Процесс RLAIF:
Используйте метод Constitutional AI для обучения начальной «модели-судьи».
Используйте эту модель-судью для оценки большого количества ответов.
Используйте эти оценки для обучения с подкреплением, чтобы обучить модель политики.
Видно, что RLAIF освобождает людей от утомительной работы по «разметке каждого примера»; людям нужно только разрабатывать принципы и процессы.
Сравнение трёх методов: RLHF vs DPO vs Constitutional AI
Мы представили три основных метода согласования; теперь давайте проведём комплексное сравнение:
| Измерение | RLHF | DPO | Constitutional AI / RLAIF |
|---|---|---|---|
| Основная идея | Обратная связь от человека + обучение с подкреплением PPO | Прямая оптимизация на данных о предпочтениях | Самокритика ИИ + обратная связь от ИИ |
| Участие человека | Требует большого объёма ручной разметки | Требует данных о предпочтениях людей | Требует только разработки принципов |
| Этапы обучения | Три этапа (SFT → RM → PPO) | Два этапа (SFT → DPO) | Два этапа (критика-пересмотр → RLAIF) |
| Сложность реализации | Высокая | Низкая | Средняя |
| Стабильность обучения | Средняя, требует тщательной настройки гиперпараметров | ОК | Средняя |
| Масштабируемость | Ограничена скоростью ручной разметки | Ограничена масштабом данных о предпочтениях | Легко масштабируется |
| Показательные компании/проекты | OpenAI (на раннем этапе) | Внедрено несколькими командами | Anthropic |
Ни один метод не является «лучшим»; выбор зависит от вашей конкретной ситуации:
Если у вас есть большие ресурсы для аннотации людьми, подойдет либо RLHF, либо DPO.
Если вы хотите простую реализацию, DPO — хороший выбор.
Если вы хотите масштабироваться и снизить зависимость от людей, стоит рассмотреть Constitutional AI / RLAIF.
В реальной эксплуатации эти методы часто смешивают: сначала используют немного человеческих данных, затем используют обратную связь от ИИ для масштабирования и, наконец, используют DPO или PPO для оптимизации.
Ограничения и проблемы RLHF
RLHF эффективен, но не идеален. Давайте обсудим некоторые его ограничения и проблемы.
Хакерство вознаграждения
Взлом вознаграждения — классическая проблема в обучении с подкреплением:ИИ находит способ получать высокие вознаграждения, но этот способ — не то, чего мы действительно хотим.。
Например:
Вы обучаете ИИ отвечать на вопросы, и модель вознаграждения предпочитает «уверенные» ответы. ИИ обнаруживает, что если говорить очень уверенным тоном, можно получать высокие оценки — даже если он несёт чепуху.
Или ИИ обнаруживает, что просто повторяя слова пользователя и говоря «понял», можно получать приличные оценки — даже если он не даёт никакой содержательной информации.
Первопричина взлома вознаграждения такова:Существует разрыв между суждениями модели вознаграждения и истинными предпочтениями людей.ИИ оптимизирует оценку модели вознаграждения, а не истинную удовлетворённость людей.
Идеального решения этой проблемы не существует, но есть некоторые методы смягчения:
Собирайте более разнообразные данные о предпочтениях.
Используйте ансамбль из нескольких моделей вознаграждения, чтобы уменьшить предвзятость одной модели.
Проводите регулярные ручные выборочные проверки и оперативно исправляйте найденные проблемы.
Непоследовательность человеческих предпочтений
Ещё одна сложность:Предпочтения у людей различаются, и даже предпочтения одного и того же человека могут меняться.。
Например:
Некоторые пользователи предпочитают краткие и прямые ответы, а другие — подробные и исчерпывающие.
Для одного и того же вопроса «хороший» ответ может отличаться в разных контекстах.
Люди из разных культурных слоёв и с разными ценностями могут иметь конфликтующие определения «хорошего».
Когда люди-аннотаторы расходятся во мнениях, модель вознаграждения сбивается с толку — она не знает, кого слушать.
Способы решения включают:
Дайте аннотаторам более подробные инструкции, чтобы унифицировать стандарты.
Записывайте характеристики аннотаторов в данные и обучайте персонализированные модели.
Примите определённую степень неоднозначности — некоторые вопросы просто не имеют единственного «правильного» ответа.
Другие проблемы
Есть ещё несколько проблем, о которых стоит упомянуть:
-
Масштабируемость — ручная аннотация медленная и дорогостоящая, из-за чего трудно успевать за ростом масштаба моделей.
-
Сдвиг распределения — обучающие данные могут отличаться от сценариев реального использования, из-за чего модель хуже работает в новых сценариях.
-
Состязательные атаки — выровненные модели могут быть «взломаны» с помощью тщательно продуманных промптов, чтобы генерировать вредоносный контент.
-
Фиксация ценностей — если цели выравнивания ошибочны, чем способнее модель, тем больше вред.
-
Выравнивание — это непрерывный процесс, и универсального решения не существует. Нам нужно продолжать исследовать, итерировать и улучшать.