Ultralytics YOLO27: Встать в лист ожидания.
Get Started
Создание решений на Ultralytics Platform·Развёртывание и мониторинг·Урок 10/10
Уроксредний

Автоматизация цикла переобучения

Преврати один деплой в воспроизводимый цикл: инструкция по запуску, скриптовая проверка допуска, автоматический выпуск с возможностью отката и еженедельный обзор.

Первый деплой — это проект; все последующие — процесс. Команды, автоматизировавшие цикл, переобучают модель за день, когда срабатывает оповещение об ухудшении результатов на отложенной выборке; команды без автоматизации в стрессовой ситуации восстанавливают процесс по памяти и выпускают регрессии. В этом уроке весь цикл проходит от начала до конца на модели таблеток: дообучение, проверка допуска и выпуск; в итоге ты составишь инструкцию, которая превратит следующий запуск в рутину.

Результат

Ты сможешь выполнить цикл переобучения от начала до конца: дообучить модель на новой версии датасета, пройти проверку допуска к выпуску относительно развернутой модели, выпустить новую версию с помощью Replace model из скрипта и откатить изменения за один шаг.

Ускоренное прохождение
Если ты уже освоился, вот краткая версия.
  1. Триггер: падение метрик на отложенной выборке, рост доли правок или дрейф на вкладке Monitoring.

  2. Собери данные через «Сохранить в датасет» или Agents, разметь с помощью Batch Annotation, проверь и создай версию.

  3. Дообучи развернутую модель, явно указав оптимизатор и lr0.

  4. Сравни кандидата с развернутой моделью; выпусти его с помощью deployments.update(action="replace").

  5. Откати изменения, заменив модель предыдущей; никогда не удаляй её, пока она нужна для отката.

Практические занятия

Цикл с ответственным за каждый шаг#

Если ты прошёл предыдущие уроки, вся информация о происхождении модели уже доступна: карточка Run Information указывает родительскую модель и закреплённую версию датасета, вкладка Models датасета содержит список всех моделей, обученных на каждой версии, а страница развёртывания ссылается на обслуживающую модель. Если точность снизилась, начни с развёртывания и проследи цепочку в обратном порядке.

Вкладка Models датасета Logistics Safety на Ultralytics Platform со списком обученных на нём моделей и столбцами статуса, задачи, числа эпох, mAP50 и mAP50-95

Agents автоматизирует сбор данных. Функция Collect Uncertain Detections выполняет предсказания через твоё развёртывание и копирует изображения с детекциями в заданном диапазоне уверенности в датасет для проверки; функция Capture and Alert сохраняет подходящие изображения и отправляет сообщение в Slack. Рабочие процессы запускаются по нажатию Run, поэтому включи запуск в еженедельную проверку.

Холст Agents на Ultralytics Platform: блок входного изображения соединён с блоком YOLO для обнаружения людей, условием появления человека, блоком языковой модели для описания сцены и выходным блоком

Пример: полный цикл для модели таблеток#

1. Дообучи развёрнутую модель. На Platform выбери развёрнутую модель в разделе My Models, включи Save Dataset Version и явно укажи оптимизатор. Локально этот шаг выглядит так:

from ultralytics import YOLO

model = YOLO("pills-v1.pt")  # лучшая модель развёрнутой модели — best.pt
model.train(data="medical-pills.yaml", epochs=5, imgsz=320, optimizer="SGD", lr0=0.001, name="v2-finetune")

Это дообучение из урока Обучение, просмотр и дообучение запусков: mAP50-95 вырос с 0.659 до 0.687.

2. Сравни её с развёрнутой моделью. Повторно используй gate.py из урока 6 с отложенной выборкой и двумя контрольными точками:

DATA = "medical-pills.yaml"  # YAML-файл датасета отложенной выборки или URI ul://
BASELINE, CANDIDATE = "pills-v1.pt", "pills-v2.pt"  # развёрнутая модель и переобученный кандидат
PASS mAP50-95 0.659 -> 0.687 beats noise
PASS every class keeps 90% of its AP (weak: none)
PASS inference 4.0 ms within 100 ms
verdict: ship the candidate

Проверка завершается с кодом 0, поэтому CI может перейти к выпуску. (В этом примере валидационная выборка medical-pills используется вместо отложенной; в рабочей среде используй версию отложенной выборки, которую модель никогда не видела.)

3. Выпусти модель. Загрузи или обучи кандидата в той же рабочей области, затем позволь CI вызвать Replace model через SDK ultralytics-platform и убедись, какая модель обслуживает запросы:

import time

from ultralytics_platform import Platform

OWNER, DEPLOYMENT = "your-username", "pill-detector-st-ghislain"
PROJECT, NEW_MODEL = "pill-inspection", "v2-finetune"

with Platform() as client:  # reads ULTRALYTICS_API_KEY
    body = {"action": "replace", "project": PROJECT, "model": NEW_MODEL}
    reply = client.deployments.update(OWNER, DEPLOYMENT, body=body)
    print(reply["status"], "-", reply["message"])  # "deploying" while the new model starts
    while (deployment := client.deployments.retrieve(OWNER, DEPLOYMENT)["deployment"])["status"] == "deploying":
        time.sleep(15)
    print(f"status={deployment['status']} model={deployment.get('model')}")
    if deployment.get("model") != NEW_MODEL:  # a failed rollout leaves the previous model serving
        raise SystemExit("Replacement failed; the previous model is still live")

При тестировании с имитацией API, который сначала сообщает deploying, а затем ready, вывод будет таким:

deploying - Replacement model is deploying
status=ready model=v2-finetune

deployments.update отправляет PATCH /api/deployments/{owner}/{deployment} вместе с action: "replace"; старая модель продолжает обслуживать запросы, пока новая не будет готова. Цикл опрашивает retrieve, пока статус не сменится с deploying, а затем проверяет обслуживающую модель: неудачное развёртывание тоже завершается со статусом ready, но при этом остаётся старая модель. Для отката используй тот же скрипт, установив NEW_MODEL в предыдущую версию. Утилита командной строки ul cloud, входящая в состав ultralytics, использует тот же API, а в справочнике API описаны все вызовы.

4. Сбрось базовый уровень. Запусти holdout_check.py из урока 8 с новой контрольной точкой и новым файлом истории.

Составь инструкцию по эксплуатации#

# Retraining runbook: pill-detector

## Trigger
- Holdout mAP50-95 more than 1 point below baseline for 2 consecutive weeks, OR
- Batch Annotation edit rate above 25% on a new batch.

## Steps
1. Collect: Save to dataset from Monitoring, plus the "Collect Uncertain Detections" agent into pill-review.
2. Label: Batch Annotation with the deployed model at the swept threshold; review every image; record the edit rate.
3. Merge into the training dataset; rerun the duplicate check, class audit, and Clustering.
4. Create dataset version v(n+1) with a description of what changed.
5. Fine-tune from the deployed model with Save Dataset Version on; optimizer SGD, lr0 0.001.
6. Run gate.py against the deployed model on the holdout. Stop here on any FAIL.
7. ML lead approves; CI runs release.py.
8. Watch endpoint_check.py for 24 hours; start a new holdout baseline.

## Rollback
- Run release.py with NEW_MODEL set to the previous version. Never delete that model while it's the rollback target.

## Owner
- ML lead approves step 7. On-call runs steps 1-6 and 8.

Запланируй еженедельную 15-минутную проверку и ответь на два вопроса: есть ли проблемы (проверка конечной точки, отложенная выборка, доля правок) и изменилось ли что-нибудь в развёртывании — и почему? В большинстве недель ответ на оба вопроса — нет, и встреча занимает пять минут. Типичный квартал выглядит так:

   Week 1   : Holdout alert. Collect, label, retrain, gate, release v(n+1).
   Week 2-3 : Quiet. Checks green.
   Week 4   : New defect class requested. Label, new version, retrain v(n+2).
   Week 5-7 : Quiet.
   Week 8   : Second plant in Poland. Check regions; add an endpoint in europe-central2.
   Week 9-11: Quiet.
   Week 12  : Quarterly holdout refresh and review.

Подводные камни#

Удаление модели для отката

Симптом: релиз прошёл неудачно, а предыдущая модель исчезла. Решение: храни в проекте как минимум две последние модели, использовавшиеся в продакшене. При удалении модель перемещается в корзину, а окончательное удаление модели также удаляет любое развёртывание, которое продолжает её использовать.

Ожидание постепенного развёртывания

Симптом: ты запланировал канареечное развёртывание с долями 10%/50%/100%, но при замене модели весь трафик переключается сразу. Решение: каждый эндпоинт обслуживает одну модель. Для канареечного развёртывания размести кандидата на втором эндпоинте и разделяй трафик в собственном маршрутизаторе, а затем замени модель и удали второй эндпоинт.

Проверка по данным, на которых модель обучалась

Симптом: каждый кандидат проходит проверку, но в продакшене качество всё равно падает. Решение: проверка объективна только на отложенной версии, на которой не обучался ни один запуск. Храни отложенную выборку в отдельном приватном датасете и никогда не объединяй её с обучающими данными.

Попробовать

Составь инструкцию по эксплуатации проекта в приведённом выше формате: укажи измеримый триггер, шаги с названием функции Platform и скриптом для каждого шага, процедуру отката и ответственных. Затем пройди полный цикл: дообучи развёрнутую модель на новой версии датасета, запусти для неё gate.py на отложенной выборке и, если проверка пройдена, выпусти модель с помощью release.py (или функции Replace model в интерфейсе) и сбрось базовый уровень отложенной выборки.

Коммит
git add retraining-runbook.md gate.py release.py && git commit -m "ops: add retraining runbook, promotion gate, and release script"
Критерии готовности
Урок считается завершённым, если выполнены все условия ниже.
  • В инструкции по эксплуатации указан измеримый триггер, пронумерованные шаги, процедура отката и ответственные.

  • gate.py выдал вердикт для реального кандидата в сравнении с развёрнутой моделью.

  • Конечная точка обслуживает модель, прошедшую проверку; предыдущая модель по-прежнему находится в проекте, а базовый уровень отложенной выборки сохранён новой строкой.

Показать решение

Пример цикла для линии таблеток. Триггер: результат проверки отложенной выборки за ночную смену снизился на 0.05. Сбор данных: 180 примеров из Monitoring за вечернюю смену сохранены в pill-review, ещё 120 получены от агента Collect Uncertain Detections; Batch Annotation при пороге 0.35 с развёрнутой моделью v2-finetune, доля правок — 18%; данные проверены и объединены; аудит пройден; версия — v6: +300 night-shift frames. Дообучи v3-night на основе v2-finetune, SGD, lr0 0.001, 20 эпох. Проверка на отложенной выборке из 300 изображений, включая 100 ночных: mAP50-95 вырос с 0.66 до 0.71, слабых классов нет, 4 мс: PASS. release.py с NEW_MODEL = "v3-night" сообщает status=ready model=v3-night; holdout_check.py записывает новый базовый уровень — 0.71. v2-finetune остаётся в проекте как модель для отката, а инструкция по эксплуатации, проверка и скрипт выпуска зафиксированы одним коммитом.

Что дальше

Курс завершён — сдай итоговый экзамен, чтобы получить сертификат Build with Ultralytics Platform, а затем углуби знания о развёртывании на периферийных устройствах и на собственных серверах в курсе Ultralytics YOLO in Production.

Войди, чтобы сохранять прогресс