Reinforcement Fine-Tuning в Amazon Bedrock: гайд 2026 с кодом | AiManual
AiManual Logo Ai / Manual.
25 Мар 2026 Гайд

Reinforcement Fine-Tuning в Amazon Bedrock: пошаговый гайд с OpenAI API и кастомной reward-функцией

Полный гайд по reinforcement fine-tuning (RFT) в Amazon Bedrock. Используем OpenAI Compatible API и кастомную reward-функцию на датасете GSM8K. Актуально на 25.

Почему 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": "..."}
💡
Не используйте сырые текстовые файлы. Bedrock для RFT требует строго определенного формата данных. Лучше один раз написать скрипт конвертации, чем потом часами дебажить ошибки валидации.

Финансы. 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:

  1. Формат датасета. Bedrock ждет строго JSONL, где каждая строка – JSON объект с полями "prompt" и "completion" для SFT, а для RFT – дополнительные поля для контекста. Несоответствие формата – самая частая причина немедленного фейла валидации.
  2. Задержка reward-эндпоинта. Ваша Lambda должна отвечать быстро, в идеале менее 1 секунды. Если оценка занимает 5 секунд, стоимость обучения взлетает в разы. Кэшируйте запросы, используйте более легковесные модели-судьи.
  3. Шумная reward-функция. Если ваша функция выдает случайные значения или часто ошибается, модель не сможет научиться. Протестируйте ее на сотне примеров до начала обучения.
  4. Не те гиперпараметры. Значения 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) – это следующий уровень, где модель учится не просто отвечать, а планировать цепочки действий.

Подписаться на канал