Почему fine-tuning с учителем уже недостаточно (и когда это начинает бесить)
Вы натренировали модель на тысячах примеров. Она идеально повторяет ваш датасет. А в продакшене выдает какую-то нейрошизу при первом же нестандартном вопросе. Знакомо? Классический supervised fine-tuning учит модель угадывать следующий токен, но не учит ее быть полезной, последовательной или безопасной. Она запоминает, а не понимает.
Reinforcement Fine-Tuning (RFT) – это другая лига. Здесь вы не кормите модель готовыми ответами, а задаете правила игры. Модель пробует, получает оценку (reward) и учится максимизировать ее. Хотите, чтобы модель лучше решала математические задачи? Не надо показывать 10 тысяч решений – задайте функцию, которая проверяет конечный ответ. Желаете, чтобы ответы были краткими? Штрафуйте за длинноты.
Актуальность на 25 марта 2026 года: методология RFT из академической экзотики превратилась в стандартный пайплайн для донастройки моделей в продакшене. Особенно после того как крупные облачные провайдеры, вроде AWS, встроили ее в свои сервисы, сделав сложную технологию доступной через несколько API-вызовов.
Важный нюанс: RFT не заменяет, а дополняет классический fine-tuning. Сначала вы обучаете модель на данных (SFT), а затем шлифуете ее поведение через reinforcement learning. Пропуск первого этапа – верный путь к нестабильным и непредсказуемым результатам.
Зачем городить огород с Amazon Bedrock?
Теоретически, вы можете развернуть фреймворк вроде RL4LMs у себя на кластере. Практически – это месяцы настройки инфраструктуры, оркестрации и отладки. Bedrock предлагает managed-сервис для RFT, где AWS берет на себя всю тяжелую работу: предоставляет оптимизированную среду выполнения, управляет вычислительными ресурсами и даже предлагает предварительно настроенные алгоритмы обучения с подкреплением (например, PPO).
Но главный козырь, который многие упускают – это OpenAI Compatible API в Bedrock. Он позволяет использовать знакомые библиотеки и инструменты (например, библиотеку OpenAI Python SDK) для взаимодействия с моделями AWS. Больше не нужно переписывать весь код под специфичный AWS SDK. Вы работаете так, будто это обычный GPT-4, а под капотом крутится, например, Nova Micro или Titan Text.
Советую параллельно почитать мой разбор про Structured Outputs в Amazon Bedrock, чтобы понимать, как еще можно контролировать вывод модели.
1 Подготовка: модель, данные и кошелек
Первое, с чем сталкиваешься – выбор базовой модели. На 25.03.2026 в Bedrock доступен солидный выбор, включая последние Nova models от AWS, Meta Llama 4 405B и открытые модели вроде GPT-OSS 20B или Qwen 3 32B. Для наших целей (решение задач GSM8K) не нужна монструозная 400-миллиардная модель. GPT-OSS 20B – отличный баланс между стоимостью и интеллектом.
| Модель | Контекст (токенов) | Подходит для RFT | Примечание |
|---|---|---|---|
| GPT-OSS 20B (v2.1) | 8192 | Да | Оптимальна по цене/качеству для задач рассуждения |
| Qwen 3 32B | 32768 | Да | Сильна в математике, но дороже в обучении |
| Nova Micro | 128000 | Да | Самый новый компактный модельный ряд от AWS (2025) |
Данные. Берем датасет GSM8K – 8.5 тысяч школьных математических задач на английском. Его до сих пор используют для бенчмарков в 2026 году, что говорит о качестве. Загружаем его в S3-бакет в формате JSONL. Каждая строка – объект с полями "question" и "answer".
{"question": "У Джона было 5 яблок. Он купил еще 3. Сколько у него яблок?", "answer": "8"}
{"question": "...", "answer": "..."}
Финансы. RFT в Bedrock – не самое дешевое удовольствие. Обучение даже 20B модели на GSM8K может обойтись в несколько сотен долларов. Убедитесь, что у вас настроены бюджет-алерты в AWS Cost Explorer. Если бюджет ограничен, изучите статью про почти бесплатные AI-продукты.
2 Настройка Bedrock: включаем Reinforcement Fine-Tuning
Заходим в консоль AWS, находим Bedrock. В меню выбираем "Custom Models" -> "Train model". Здесь ключевой момент – выбор метода тренировки: "Reinforcement Learning Fine-Tuning".
Указываем:
- Base model: идентификатор вашей модели (например,
arn:aws:bedrock:us-east-1:::foundation-model/gpt-oss-20b-v2-1). - Training data location: S3 URI вашего датасета.
- Output location: S3-папка для артефактов обучения.
- Hyperparameters: оставляем по умолчанию (их можно тонко настроить через API, но для начала хватит).
Самое интересное – Reward Model. Bedrock позволяет использовать встроенную модель (например, для безопасности) или загрузить свою через OpenAI Compatible API Endpoint. Выбираем второй вариант.
3 Сердце системы: пишем кастомную reward-функцию
Вот где начинается магия. Нам нужно развернуть микросервис, который будет принимать ответ модели и возвращать число – оценку от 0 до 1. Bedrock будет вызывать его по HTTP во время обучения.
Развернем простейший endpoint на AWS Lambda с помощью API Gateway. Но его логика будет не такой простой.
Как НЕ надо делать: писать функцию, которая просто сравнивает строку ответа модели с эталоном через ==. В задачах типа GSM8K ответ может быть "8", "8.00", "восемь" или "итого 8 яблок". Нужна интеллектуальная проверка.
Правильный подход: используем легковесную модель-судью. Например, ту же GPT-OSS 20B, но через Bedrock Runtime, чтобы оценить корректность рассуждений. Или, для математики, можно распарсить ответ и вычислить числовой результат.
Пример кода reward-функции для Lambda (Python 3.12):
import json
import re
import boto3
from decimal import Decimal
bedrock = boto3.client(service_name='bedrock-runtime', region_name='us-east-1')
def extract_numeric_answer(text: str) -> float | None:
"""Выдергивает последнее число из текста."""
# Ищем числа, включая десятичные
matches = re.findall(r"[-+]?\d*\.?\d+(?:[eE][-+]?\d+)?", text)
if matches:
try:
return float(matches[-1])
except ValueError:
return None
return None
def lambda_handler(event, context):
body = json.loads(event['body'])
# Bedrock отправляет в таком формате
model_output = body['model_output'] # Ответ модели
reference_answer = body['reference_answer'] # Эталонный ответ из датасета
# 1. Пытаемся сравнить числовые ответы
model_num = extract_numeric_answer(model_output)
ref_num = extract_numeric_answer(reference_answer)
if model_num is not None and ref_num is not None:
# Сравниваем с допуском
if abs(model_num - ref_num) < 0.001:
base_reward = 1.0
else:
base_reward = 0.0
else:
# 2. Если не вышло численно, используем LLM-судью
prompt = f"""Ответил ли модель правильно на вопрос?
Эталонный ответ: {reference_answer}
Ответ модели: {model_output}
Ответь только 'YES' или 'NO'."""
response = bedrock.invoke_model(
modelId='gpt-oss-20b-v2-1',
body=json.dumps({
"prompt": prompt,
"max_tokens": 10
})
)
result = json.loads(response['body'].read().decode())
llm_judgement = result['completions'][0]['data']['text'].strip()
base_reward = 1.0 if "YES" in llm_judgement.upper() else 0.0
# 3. Добавляем штраф за излишнюю болтливость (поощряем краткость)
word_count = len(model_output.split())
brevity_penalty = max(0, 1.0 - (word_count / 100)) # Штрафуем, если больше 100 слов
final_reward = base_reward * brevity_penalty
return {
'statusCode': 200,
'body': json.dumps({'reward': final_reward}, cls=DecimalEncoder)
}
class DecimalEncoder(json.JSONEncoder):
def default(self, obj):
if isinstance(obj, Decimal):
return float(obj)
return super().default(obj)
Разверните этот код как Lambda функцию, получите URL API Gateway и укажите его в настройках RFT в Bedrock как "Custom Reward Model Endpoint".
4 Запуск и мониторинг: ждем и не верим глазам
Запускаете тренировку. По опыту, для 20B модели на GSM8K (около 8.5k примеров) с стандартными гиперпараметрами обучение займет 4-8 часов и сожжет приличное количество EC2-часов (обычно инстансы p4de.24xlarge).
Мониторить процесс можно через CloudWatch Logs (ищите логи группы /aws/bedrock/training-jobs) или в разделе "Training jobs" консоли Bedrock. Ключевые метрики:
- Average reward: должен расти со временем. Если он скачет или падает – с reward-функцией что-то не так.
- Policy loss: показывает, насколько сильно меняется политика модели. Резкие скачки – признак нестабильности обучения.
Если все сделано верно, через несколько часов вы получите fine-tuned модель, доступную в вашем приватном инвентаре Bedrock. Ее ARN будет выглядеть примерно так: arn:aws:bedrock:us-east-1:123456789012:custom-model/your-model-id.
Где спотыкаются 9 из 10 инженеров
Опыт, оплаченный долларами AWS:
- Формат датасета. Bedrock ждет строго JSONL, где каждая строка – JSON объект с полями "prompt" и "completion" для SFT, а для RFT – дополнительные поля для контекста. Несоответствие формата – самая частая причина немедленного фейла валидации.
- Задержка reward-эндпоинта. Ваша Lambda должна отвечать быстро, в идеале менее 1 секунды. Если оценка занимает 5 секунд, стоимость обучения взлетает в разы. Кэшируйте запросы, используйте более легковесные модели-судьи.
- Шумная reward-функция. Если ваша функция выдает случайные значения или часто ошибается, модель не сможет научиться. Протестируйте ее на сотне примеров до начала обучения.
- Не те гиперпараметры. Значения learning rate, batch size, clip range для PPO критичны. Начните с пресетов от AWS, а для кастомной настройки изучите полный гайд по fine-tuning.
Вопросы, которые вы зададите через три часа отладки
| Вопрос | Короткий ответ |
|---|---|
| Можно ли использовать несколько reward-функций? | Да, Bedrock позволяет задать список эндпоинтов. Итоговый reward – взвешенная сумма. |
| Что дешевле: RFT в Bedrock или на своем кластере SageMaker? | Для разовых экспериментов – Bedrock. Для постоянного пайплайна – свой кластер может быть выгоднее, но считайте TCO (см. статью про замену облачного агента). |
| Как оценить качество до и после? | Запустите инференс на валидационном сете (200-300 примеров) через оригинальную и донастроенную модель, сравните accuracy вашей reward-функцией. |
| Есть ли готовые reward-модели? | AWS предлагает встроенные модели для безопасности и токсичности. Для предметных доменов (код, математика) – нужно делать свои или искать в Hugging Face. |
И последний совет, который сэкономит вам неделю: не пытайтесь сразу настроить идеальную reward-функцию. Запустите первый эксперимент с простейшей логикой (сравнение чисел). Убедитесь, что пайплайн вообще работает и reward растет. Затем уже усложняйте. В мире reinforcement learning простая, но стабильная функция часто бьет сложную и зашумленную.
Дальнейшие шаги? Поэкспериментируйте с агентным обучением с подкреплением (Agentic RL) – это следующий уровень, где модель учится не просто отвечать, а планировать цепочки действий.