Модуль 10. Тюнинг YandexGPT Lite через AI Studio SDK: полный цикл

Цель модуля: пройти весь путь от готового датасета до собственной дообученной модели: установить AI Studio SDK, загрузить и провалидировать датасет, запустить LoRA-тюнинг YandexGPT Lite, дождаться результата, получить URI дообучённой модели и сравнить её с базовой на своём golden set. Попутно — классификатор, метрики TensorBoard и типовые ошибки.

Перед началом: модуль 5 (датасет), модуль 8 (golden set и baseline), модуль 9 (каталог, сервисный аккаунт, API-ключ в переменных окружения). Инструменты: python3, pip, Jupyter или любой редактор. Нужен аккаунт Yandex Cloud с грантом. Трудоёмкость: ~2.5 ч руками + ожидание обучения (до нескольких часов, идёт без вас).

🔥 От 100 пар до своей модели — сколько это кода?

С модуля 5 у вас лежит train.jsonl со 150 парами «запрос → идеальный ответ», с модуля 8 — golden set и baseline базовой модели. Сколько нужно, чтобы превратить одно в другое?

Если идти «в лоб»: разобрать REST API загрузки датасетов, ждать статуса, запустить тюнинг, опрашивать задачу, забрать результат — день на чтение документации и обвязку.

С AI Studio SDK это линейный скрипт: клиент → загрузка датасета → tune_deferred → wait → готовый uri, по которому модель вызывается так же, как базовая. Пятнадцать строк между «у меня есть пары» и «у меня есть своя модель» — без преувеличения, ниже вы их напишете.

📖 10.1. Карта цикла: пять шагов и два ожидания

Полный цикл выглядит так:

text
train.jsonl (модуль 5)
   │  1. draft_from_path + upload        — загрузка и валидация облаком
   ▼
dataset (у датасета появляется свой идентификатор)
   │  2. completions('yandexgpt-lite')   — берём базовую модель
   │  3. tune_deferred(dataset, name=…)  — ставим обучение в очередь
   ▼                                    [ожидание: минуты — часы]
tuning_task ──► wait() ──► new_model
   │  4. new_model.uri                  — адрес дообучённой модели
   │  5. completions(uri).run(...)       — вызов и сравнение (модуль 8)
   ▼
отчёт base vs tuned на golden set

Два места, где вы ждёте: upload() валидирует файл (секунды–минуты) и само обучение — по туториалу Yandex Cloud до нескольких часов; оно идёт в облаке, а скрипт может спать в wait() или выключиться: задачу поднимают заново по id (10.5).

Пакет: yandex-ai-studio-sdk — преемник yandex-cloud-ml-sdk. Встретите в чужих ноутбуках import yandex_cloud_ml_sdk — это старый мир; для нового кода ставьте актуальный пакет.

📖 10.2. Ноутбук: клиент и датасет

Запускать удобно в ноутбуке (DataSphere или локально — среда одинаковая). Код самодостаточен: секреты — из окружения (модуль 9), ячейки пронумерованы, ноутбук можно коммитить без страха.

python
# Ячейка 1 — установка SDK (преемник yandex-cloud-ml-sdk)
%pip install --upgrade yandex-ai-studio-sdk
python
# Ячейка 2 — клиент: folder_id и API-ключ из окружения, не из кода
import os
from yandex_ai_studio_sdk import AIStudio

sdk = AIStudio(
    folder_id=os.environ["FOLDER_ID"],   # каталог из модуля 9
    auth=os.environ["API_KEY"],          # ключ сервисного аккаунта
)
python
# Ячейка 3 — загрузка датасета: черновик → upload (облако валидирует)
dataset_draft = sdk.datasets.draft_from_path(
    task_type="TextToTextGeneration",    # генерация текста
    path="train.jsonl",                  # пары из модуля 5
    upload_format="jsonlines",
    name="support-style-v1",
)
dataset = dataset_draft.upload()         # упадёт с ошибкой, если JSONL кривой
print(dataset)                           # запишите id датасета в таблицу версий

Формат строк — из модуля 5, именно его ест AI Studio:

jsonl
{"instruction": "Ты — ассистент поддержки курсов. Отвечай коротко, по-русски.",
 "request": "Купил курс, не зашло. Как вернуть деньги?",
 "response": "Вернуть деньги можно в течение 14 дней после покупки."}

instruction — общий системный стиль, request — запрос пользователя, response — ответ, который модель должна научиться давать. Пары — из реальных логов или ревью эксперта (модуль 5); 50–200 пар для стиля и формата хватает, чтобы эффект был виден на golden set.

📖 10.3. Запуск тюнинга и вызов своей модели

Дальше — четыре вызова; комментарии важнее кода: это и есть весь цикл.

python
# Ячейка 4 — базовая модель и отложенный запуск LoRA-тюнинга
base_model = sdk.models.completions("yandexgpt-lite")

tuning_task = base_model.tune_deferred(
    dataset,
    name="support-style-v1",            # имя модели: без «latest», с версией
)
print(tuning_task)                       # здесь же находится id задачи
python
# Ячейка 5 — ждём результата: блокирующий вызов, обучение идёт в облаке
# и может занять до нескольких часов — можно уйти пить чай.
new_model = tuning_task.wait()
print(new_model.uri)                     # АДРЕС вашей модели. Сохраните его.
python
# Ячейка 6 — вызов дообученной модели ровно как базовой
tuned_model = sdk.models.completions(new_model.uri)
result = tuned_model.run("Купил курс, не зашло. Как вернуть деньги?")
print(result)

Сравнение с базой — по протоколу модуля 8: golden set через обе модели, две строки отчёта рядом (baseline был снят заранее):

python
# Ячейка 7 — сверка с базовой моделью на кейсах golden set
for case in ["Как вернуть деньги за курс?",
             "Дай JSON с полями price и currency",
             "Вы вообще кого-то там учите?!"]:
    print("BASE :", base_model.run(case))
    print("TUNED:", tuned_model.run(case))
    print("-" * 60)

Полный прогон на golden set автоматизируется функцией ask_model из каркаса модуля 8 — pass_rate base против tuned и есть главное число модуля. Если tuned не лучше base — виноват датасет (модуль 5), а не SDK.

Метрики обучения — TensorBoard (модуль 7 — как читать кривые):

python
# Ячейка 8 — ссылка на TensorBoard с кривыми обучения
metrics_url = new_model.get_metrics_url()
print(metrics_url)   # архив с логами: loss по шагам, открывается TensorBoard

📖 10.4. Вариант Б: классификатор вместо генерации

Если задача — не «отвечать текстом», а «размечать» (срочность, тема, спам — модули 4 и 8), тюните классификатор на базе той же модели: цикл тот же, отличаются две вещи.

Формат датасета: строки вида {"text": ..., "labels": [...]} — текст и правильные метки (или пара instruction/criteria, задающая правила классификации естественным языком; оба варианта — в модуле 5).

Вызов: у дообученного классификатора — метод classify(), возвращающий метки и скоры, а не генерирующий текст:

python
# Классификатор: отличие от генерации — task_type и метод вызова.
# Точное имя task_type для классификации сверьте с документацией SDK.

clf_draft = sdk.datasets.draft_from_path(
    task_type="TextClassification",      # версия SDK может отличаться — сверьте
    path="tickets.jsonl",
    upload_format="jsonlines",
    name="urgency-clf-v1",
)
clf_dataset = clf_draft.upload()

clf_task = base_model.tune_deferred(clf_dataset, name="urgency-clf-v1")
clf_model = clf_task.wait()

labels = clf_model.classify("Сайт оплаты лежит, клиенты не могут купить!")
print(labels)   # метки/скоры — их и кормите в precision/recall из модуля 8

Классификатор часто и есть правильный выбор: срочность тикета надёжнее классифицировать, чем «генерировать слово срочно». Метрики — confusion matrix и precision/recall на пороге (модуль 8, сниппет precision-recall.py).

📖 10.5. Типовые ошибки этого цикла

  • Кривой JSONL. upload() падает с ошибкой валидации: облако проверяет схему до обучения, в тексте ошибки обычно названа строка. Частые причины: незэкранированные кавычки, пустые response, не UTF-8, лишние поля.
  • Мало примеров. 10–20 пар почти не двигают модель; для стиля и формата ориентир — десятки–сотни чистых пар (модуль 5). Лучше 100 выверенных, чем 1000 грязных — главный рычаг качества, а не гиперпараметры.
  • «Обучилось — стало хуже». Классика без golden set: loss уменьшился (модуль 7), демо понравилось, а модель разучилась извиняться или начала выдумывать факты. Лечение — модуль 8: baseline до тюнинга, полный прогон после, критерий выката до прогона.
  • Долгое ожидание и оборванная сессия. wait() блокирует; если сессия умерла — задача не потеряна: по туториалу её восстанавливают по id (sdk.tuning.get(task_id)) и забирают результат (get_task_info(), get_result()). Записывайте id задачи сразу после запуска.
  • Старый SDK. pip install yandex-cloud-ml-sdk из чужого ноутбука + свежие примеры = ошибки импорта. Ставьте yandex-ai-studio-sdk.
  • Деньги. Тюнинг тарифицируется в юнитах (модуль 9). Не плодите пробные запуски на сыром датасете: сначала локальная проверка JSONL по строкам.

📖 10.6. Сверьте с актуальной документацией

SDK живой: имена методов меняются (переименование yandex-cloud-ml-sdk → yandex-ai-studio-sdk уже случилось). Если что-то не совпадает с вашей версией — верьте документации, а не модулю:

📖 10.7. Компромиссы

  • tune_deferred vs синхронный запуск. Отложенный не держит соединение и переживает обрыв сессии; синхронный проще в скрипте «запустил и забыл».
  • YandexGPT Lite vs Pro. Тюнинг доступен для Lite — дешевле и быстрее; для задач потяжелее базой берут Pro без тюнинга, компенсируя промптом (модуль 4).
  • Генерация vs классификатор. Генерация гибче (свободный ответ), но её дороже оценивать; классификатор жёстче и измеряется точно (модуль 8).
  • Больше данных vs больше эпох. Свежие пары из логов почти всегда выгоднее лишних проходов по старым — последние легко приводят к переобучению (модуль 7).
  • Быстрый dirty-запуск vs валидация до облака. Загрузить сырой файл «просто посмотреть» — потерять минуты на ошибке валидации и юниты.

💻 Практика

Нужен аккаунт Yandex Cloud с грантом; секреты FOLDER_ID/API_KEY — из модуля 9. Практика = практики модулей 5 и 8, наконец встретившиеся.

  1. Датасет (20 мин, если не готов). Возьмите train.jsonl из модуля 5: 50–200 пар, гигиена пройдена. Локальная проверка: каждая строка парсится json.loads, у каждой три ключа, файл в UTF-8.
  2. Цикл (30 мин). Ячейки 1–5 из 10.2–10.3: установка, клиент, загрузка, tune_deferred, wait(). Пока идёт обучение — переключитесь на шаг 3.
  3. URI под замок (5 мин). В таблицу версий: имя модели, дата, id датасета, id задачи, new_model.uri, ссылка TensorBoard. Задел к модулю 12.
  4. Сравнение (20 мин). Ячейки 6–7: base против tuned на кейсах golden set, затем полный прогон regression suite из модуля 8 (или честно 10–20 кейсов руками) и приговор: take или rollback.
  5. Развилка (по желанию, +40 мин). Если задача — классификация: соберите tickets.jsonl из модуля 5, прогоните вариант из 10.4 и оцените precision/recall по сниппету модуля 8.
  6. Разбор ошибок (15 мин). Откройте TensorBoard (get_metrics_url()): где train loss выходит на плато, нет ли переобучения (модуль 7)?

🧩 Quiz "Проверь себя"

1. Что возвращает tuning_task.wait()?
2. Какой пакет ставят для тюнинга YandexGPT Lite в 2026 году?
3. Чем вызов дообученного классификатора отличается от генерации?
4. «Обучилось, loss упал, а на вопросах стало хуже». Главная причина?
5. Обучение запущено, ноутбук закрылся. Что произошло с задачей?

✅ Итоги модуля

  • Установить yandex-ai-studio-sdk и создать клиент AIStudio из секретов.
  • Загрузить датасет draft_from_path(..., upload_format='jsonlines') и пройти валидацию облака.
  • Запустить tune_deferred, дождаться wait() и зафиксировать new_model.uri в таблице версий.
  • Сравнить base и tuned на golden set по метрикам модуля 8; связать кривые TensorBoard (get_metrics_url()) с результатом оценки.
  • Назвать три типовые ошибки цикла и их профилактику.

🔗 Мостик к Модулю 11

У вашей модели есть URI — но нет весов на руках: это дообученный YandexGPT Lite, живущий в AI Studio. Скачать его, увести on-prem или заменить базу на Qwen нельзя. Если нужен такой контроль — или экзотическая модель, или полная свобода над обучением — переезжаем в DataSphere: свой ноутбук с GPU-конфигурацией, QLoRA на открытых весах, чекпойнты в Object Storage. Дороже по трудозатратам, зато всё ваше.