Запуск процесса Fine-tuning: Гиперпараметры и мониторинг
Урок 5.2: Запуск процесса Fine-tuning: Гиперпараметры и мониторинг
Приветствую, коллеги. Мы переходим от подготовки данных к самому интересному этапу — «магии» обучения. Если подготовка датасета была закладкой фундамента, то запуск процесса файн-тюнинга (Fine-tuning) — это возведение стен. И здесь роль архитектора решений становится критической.
Многие думают, что файн-тюнинг — это просто вызов метода create_tuned_model и ожидание чуда. На уровне Junior-разработчика это, возможно, так. Но на уровне Architect мы должны понимать, что происходит «под капотом», как управлять процессом через гиперпараметры и, самое главное, как интерпретировать метрики в реальном времени, чтобы не сжечь бюджет на бесполезную модель.
В этом уроке мы разберем:
- Анатомию запуска: Как Gemini API управляет задачами обучения.
- Гиперпараметры: Эпохи, батчи и learning rate — что мы можем контролировать, а что Google берет на себя.
- Мониторинг: Как читать графики функции потерь (Loss) и распознавать переобучение на ранних стадиях.
Гиперпараметры: Рычаги управления
В машинном обучении гиперпараметры — это настройки, которые вы задаете до начала обучения. Они определяют, как модель будет учиться. В экосистеме Gemini API Google стремится к максимальной автоматизации (AutoML), но оставляет нам ключевые рычаги влияния.
Рассмотрим «Святую Троицу» настроек тюнинга:
1. Эпохи (Epochs)
Эпоха — это один полный проход алгоритма обучения через весь ваш обучающий набор данных.
- Мало эпох (1-3): Модель может недоучиться (underfitting). Она увидит примеры, но не успеет сформировать устойчивые нейронные связи для новых паттернов.
- Много эпох (10+): Риск переобучения (overfitting). Модель начнет просто «зубрить» ваши примеры наизусть, вместо того чтобы понять принцип. На новых данных она будет бесполезна.
- Рекомендация архитектора: Для малых датасетов (< 500 примеров) часто требуется больше эпох (5-10), чтобы «вбить» знания. Для крупных датасетов (> 10,000 примеров) может хватить и 1-3 эпох.
2. Размер батча (Batch Size)
Модель не учится на всех данных сразу. Она берет кусочек данных (батч), делает предсказание, смотрит на ошибку и обновляет веса.
- Большой батч дает более стабильную, но усредненную оценку градиента. Это быстрее считается, но требует больше памяти (что на стороне Google Cloud нас волнует меньше, но влияет на лимиты).
- Gemini API часто управляет этим параметром автоматически, но понимание принципа важно для оценки скорости обучения.
3. Learning Rate (Скорость обучения)
Это размер шага, который модель делает в сторону минимизации ошибки.
- Слишком большой шаг: Модель будет «прыгать» вокруг правильного решения, но никогда в него не попадет. График Loss будет скакать.
- Слишком маленький шаг: Обучение займет вечность, и модель может застрять в локальном минимуме (неоптимальном решении).
- В Gemini мы часто используем Learning Rate Multiplier — множитель к базовой скорости обучения, которую выбрал Google. Значение
1.0— стандарт.0.1— аккуратное обучение,2.0— агрессивное.
import google.generativeai as genai
import time
# Настройка API ключа
genai.configure(api_key="YOUR_API_KEY")
# 1. Подготовка файла (предполагаем, что файл уже загружен и есть его имя)
# training_file_name = "tuned_data_v1.jsonl"
# 2. Настройка параметров запуска
# Обратите внимание: мы задаем уникальное id для модели
model_id = "gemini-tech-support-bot-v01"
operation = genai.create_tuned_model(
# Базовая модель, которую мы дообучаем
source_model="models/gemini-1.5-flash-001-tuning",
# Данные для обучения
training_data="tuned_data_v1.jsonl",
# Идентификатор вашей новой модели
id=model_id,
# Название для отображения в консоли
display_name="Tech Support Assistant (Epoch 5)",
# ГИПЕРПАРАМЕТРЫ
epoch_count=5, # 5 полных проходов по данным
batch_size=4, # Размер пакета данных (зависит от размера датасета)
learning_rate=0.001, # Явное задание LR (или используйте multiplier)
)
print(f"Запущена операция тюнинга: {operation.name}")
# Модель не создается мгновенно. Это асинхронная операция.
# Ссылка на модель будет доступна сразу, но статус будет 'creating'"
Мониторинг: Пульс вашего ИИ
После запуска кода выше, самая большая ошибка — уйти пить кофе на 2 часа и вернуться только к результату. Как архитектор, вы должны уметь диагностировать проблемы в процессе.
Ключевая метрика, за которой мы следим — Loss (Функция потерь). Это число, которое показывает, насколько сильно предсказание модели отличается от идеального ответа в вашем датасете.
Паттерны кривой обучения (Loss Curve):
- Идеальный спуск: Линия начинается высоко и плавно снижается, постепенно выходя на плато. Это значит, модель учится.
- Отсутствие сходимости: Линия прямая или хаотично скачет вверх-вниз.
Причины: «Грязные» данные, слишком высокий Learning Rate, неправильный формат данных. - Резкий обрыв в ноль: Если Loss падает почти до нуля слишком быстро.
Диагноз: Переобучение (Overfitting). Модель просто запомнила ответы. На реальных данных она провалится. - Рост ошибки (Divergence): Loss начинает снижаться, а потом резко идет вверх.
Диагноз: Слишком агрессивное обучение, модель «сломала» свои веса.
В Gemini API мы можем получать метрики периодически, пока идет процесс state=ACTIVE.
import pandas as pd
import matplotlib.pyplot as plt
import seaborn as sns
# Функция для визуализации процесса обучения
def plot_loss_curve(model_name):
model = genai.get_tuned_model(model_name)
# Получаем снимки состояния (snapshots) обучения
snapshots = model.tuning_task.snapshots
data = []
for snap in snapshots:
# Извлекаем среднюю ошибку и номер шага/эпохи
data.append({
"step": snap.step,
"epoch": snap.epoch,
"mean_loss": snap.mean_loss
})
if not data:
print("Данных для графика пока нет.")
return
df = pd.DataFrame(data)
# Рисуем график
plt.figure(figsize=(10, 6))
sns.lineplot(data=df, x="step", y="mean_loss", marker="o")
plt.title(f"Кривая обучения (Loss Curve): {model_name}")
plt.xlabel("Шаги обучения (Steps)")
plt.ylabel("Loss (Ошибка)")
plt.grid(True)
plt.show()
# Проверка статуса в цикле (простой поллинг)
import time
my_model_name = f"tunedModels/{model_id}"
while True:
model_info = genai.get_tuned_model(my_model_name)
status = model_info.state.name
print(f"Текущий статус: {status}")
if status == 'ACTIVE':
print("Обучение завершено!")
plot_loss_curve(my_model_name)
break
elif status == 'FAILED':
print("Обучение упало с ошибкой.")
print(model_info.tuning_task.error_message)
break
# Ждем 60 секунд перед следующей проверкой
time.sleep(60)
Стратегия "Early Stopping" (Ручная эмуляция)
В классическом ML есть понятие Early Stopping — остановка обучения, если ошибка на проверочной выборке перестала падать. В API Gemini на данный момент мы часто задаем фиксированное количество эпох.
Совет Архитектора:
Если вы не уверены в гиперпараметрах, запустите эксперимент с запасом эпох (например, 10), но внимательно следите за графиком. Если вы видите, что на 4-й эпохе Loss вышел на плато и перестал значимо меняться (изменения < 0.01), дальнейшее обучение — это пустая трата ресурсов и риск переобучения.
Хотя вы не всегда можете остановить процесс «на лету» и сохранить промежуточный чекпоинт (в зависимости от текущей версии API), вы можете использовать эти данные для следующего запуска, выставив epoch_count=4.
Чек-лист перед запуском в Production-обучение:
- [ ] Валидация данных: Прошел ли датасет проверку на формат и отсутствующие поля?
- [ ] Бейзлайн: Проверили ли вы промпты на базовой модели? Если базовая модель справляется на 80%, нужен ли вам тюнинг?
- [ ] Стоимость: Оценили ли вы количество токенов в датасете * количество эпох? Это определяет бюджет.
Сценарий: Вы обучаете модель для генерации SQL-запросов по естественному языку. Датасет: 500 примеров. Вы запустили обучение на 20 эпох. На графике вы видите, что Loss падал до 5-й эпохи (до значения 0.3), а затем к 20-й эпохе упал до 0.001. При тестировании модель идеально отвечает на запросы из обучающей выборки, но выдает синтаксический мусор на совершенно новых запросах.<br><br>Задание: <br>1. Диагностируйте проблему.<br>2. Предложите изменение гиперпараметров для следующего запуска.
Какой показатель на графике обучения (Loss Curve) наиболее явно сигнализирует о том, что процесс обучения идет нормально и модель усваивает закономерности?