Как да версионирам AI модели? (практично MLOps ръководство)

За да версионираш AI модели надеждно, трябва да версионираш не само файла с модела, а целия „пакет“: данни, код, конфигурации, зависимости и среда за изпълнение, плюс ясни правила за промоция към staging/production и бърз rollback.

Модел без версия на данните и кода не е версия, а снимка без контекст.

Това how-to е за екипи, които искат да спрат хаоса от „model_final_v7_reallyfinal.pt“ и да могат да отговорят на два въпроса по всяко време:

  • „Кой модел е в продукция и защо?“
  • „Мога ли да възпроизведа и върна предишната версия за 15 минути?“

Въведение: Какво означава „версия“ при AI

При класически софтуер версията е код. При ML/AI версията е комбинация:

  • Данни: кои записи, етикети, филтри, период.
  • Код: training pipeline, feature engineering, preprocessing.
  • Конфигурации: хиперпараметри, seed, архитектура.
  • Артефакт: самият модел (weights), tokenizer, embedder.
  • Среда: версии на библиотеки, CUDA, контейнер.
  • Метрики: качество по тестови набори и performance.

Практичен принцип: версията трябва да е достатъчна, за да възпроизведеш модела и да знаеш какво точно е променено.

Стъпка 1: Дефинирай стратегия за именуване и идентификатори

Избери конвенция, която е удобна за хора и машини.

Минимална схема:

  • model_name: кратко име (например invoice-classifier).
  • model_version: семантична версия (например 1.2.0).
  • data_version: версия/хеш на данните (например data-2026-02-01 или DVC hash).
  • run_id: идентификатор на експеримент (MLflow/W&B).

Примерен таг:

  • invoice-classifier@1.2.0+data.2026-02-01.

Правила:

  • MAJOR (1.x → 2.x): промяна на вход/изход, нови класове, счупване на API.
  • MINOR: подобрение на качество без промяна на контракта.
  • PATCH: bugfix (например preprocessing), без промяна в поведението по основните метрики.

Версионирането е договор между ML и продукта: не пускай модел, който променя JSON схемата без MAJOR версия.

Стъпка 2: Версионирай данните (dataset versioning)

Данните са най-честата причина моделът „да се държи различно“.

Какво да версионираш:

  • raw данни (източник, дата, филтри);
  • етикети (labeling guidelines, версия на анотации);
  • split-ове (train/val/test), за да няма „подмяна“ на теста;
  • feature store изчисления (ако имаш).

Инструменти и подходи:

  • DVC: версиониране на големи файлове и dataset-и, свързано с Git.
  • LakeFS/обектно-сторидж версии: ако данните са в data lake.
  • В най-лошия случай: „манифест“ файл (списък от IDs) + checksum.

Минимална практика, която работи:

  • Записвай data_manifest.json с IDs и филтри.
  • Записвай labeling_policy.md с версия и промени.

Стъпка 3: Версионирай кода и конфигурациите като първокласни артефакти

Кодът е лесен: Git.

По-трудно е да не „изгубиш“ конфигурациите.

Решение:

  • Пази training config като файл (YAML/JSON).
  • Логвай конфигурацията като артефакт към run-а.
  • Забрани „ръчни“ промени в ноутбуци за production обучения.

Полезни практики:

  • Един входен команден файл: train.py --config configs/v1.yaml.
  • Записвай git commit hash към всеки run.

Стъпка 4: Тракинг на експерименти и артефакти (MLflow/W&B)

За да не се губят резултати, използвай система за експерименти:

  • MLflow Tracking: параметри, метрики, артефакти.
  • Weights & Biases: runs + Artifacts за модели и данни.

Какво да логваш минимално:

  • параметри и версии на библиотеки;
  • метрики по стандартен тест;
  • конфигурационни файлове;
  • модела/чекпойнта + tokenizer;
  • примери на грешки (failure cases).

Целта е след 3 месеца да не гадаеш защо run_4812 е бил „най-добър“.

Стъпка 5: Model Registry и етапи (dev → staging → prod)

Само логове не стигат. Нужен е регистър, който показва кое е „официалната“ версия.

Примерни етапи:

  • Development: кандидати.
  • Staging: версия, минала тестове и готова за канарейка.
  • Production: версия в продукция.
  • Archived: стари версии.

В MLflow Model Registry или W&B Artifacts можеш да:

  • регистрираш модел с име и версия;
  • добавяш тагове (data_version, git_hash);
  • промотираш/демотираш;
  • пазиш одитен запис кой е направил промяната.

Правило за промоция:

  • без тестов набор и минимални acceptance критерии няма production.

Стъпка 6: Версионирай „контракта“: вход/изход, схемите и мониторинга

Ако моделът е в услуга (API), версионирай и API контракта.

  • JSON Schema за вход и изход.
  • Валидации на ниво gateway.
  • Дефиниция на бизнес метрики: precision/recall, откази, latency.

За LLM приложения допълни:

  • версия на системния prompt;
  • версия на RAG индекса (ако има);
  • версия на retrieval правилата.

Много екипи пропускат това и после не могат да кажат дали деградацията идва от модела, промпта или данните.

Стъпка 7: Пакетиране и възпроизводимост (reproducibility)

За production не разчитай на локална машина.

Минимална стъпка:

  • контейнер (Docker) с фиксирани версии;
  • pinned зависимости (requirements/lockfile);
  • запис на средата (Python/Node версия).

Ако имаш GPU, важни са и:

  • CUDA/cuDNN версии;
  • драйвери;
  • базов image.

Стъпка 8: Деплоймент стратегия и rollback

Версионирането има смисъл само ако можеш да върнеш версия бързо.

Практични стратегии:

  • Canary: 5% трафик към новия модел, после 25%, после 100%.
  • Shadow: новият модел получава трафик, но не отговаря на потребителя; сравняваш резултати.
  • Feature flag: превключване по организация или сегмент.

Rollback правилото:

  • ако основна метрика падне под праг или разходът скочи, връщаш последната стабилна Production версия.

Бързият rollback е най-важният „feature“ на всяка MLOps система.

Съвети за по-добри резултати

  • Дръж тестовия набор „замразен“ и отделно версиониран.
  • Пази „failure case“ колекция и я обновявай.
  • Въвеждай review процес за промоция към production.
  • Версионирай RAG индекса и embedding модела отделно.
  • Документирай „какво се промени“ (release notes) към всяка версия.

Чести грешки

  • Да пазиш само модела, без data_version.
  • Да сменяш preprocessing без да увеличиш версията.
  • Да тестваш на различен test split всеки път.
  • Да нямаш одит кой е промотирал модел.
  • Да нямаш автоматични проверки и аларми.

Стъпка 9: Документация и „model card“ (за да не забравиш защо е пуснат моделът)

Когато моделът стигне до staging, добави кратка документация, която отговаря на въпросите на продукт, QA и сигурност:

  • За какво е предназначен моделът и за какво не е.
  • Кои данни са използвани (data_version, период, изключени сегменти).
  • Какви метрики покрива (и на кои групи).
  • Известни слабости и „failure cases“.
  • Какво се променя спрямо предишната production версия.

Това може да е прост Markdown файл, логнат като артефакт към run-а и линкнат от registry записа.

Примерен workflow за екип (от експеримент до production)

  1. Разработчик прави промяна в pipeline и пуска training run с фиксиран data_version.
  2. Експериментът логва параметри, метрики, артефакти и git hash.
  3. Ако минава минималните прагове, моделът се регистрира като нова версия в registry.
  4. QA/ML преглежда model card и failure cases.
  5. Моделът се промотира в Staging и се пуска shadow или canary.
  6. Наблюдават се метрики в реален трафик (качество, латентност, разход).
  7. Ако всичко е наред, моделът става Production; ако не, връщаш предишната версия и записваш причината.

Ако нямаш процес за промоция, registry се превръща в склад, а не в контролна кула.

Как да версионираш LLM системи: prompt, RAG и fine-tune

При LLM приложенията „моделът“ често е комбинация от външен API и твоя конфигурация. Версионирай отделно:

  • provider_model: кой модел и коя версия на доставчика е използвана.
  • prompt_version: системни инструкции и шаблони като файлове в Git.
  • retriever_version: правила за retrieval и филтри.
  • index_version: конкретният индекс/корпус, по който се прави RAG.
  • eval_suite_version: тестовите задачи и рубрики.

Така можеш да кажеш дали промяна в качеството идва от смяна на доставчик, от нов индекс, или от промяна в промпта.

Чеклист: какво трябва да има всяка версия

Преди да маркираш версия като Staging или Production, провери дали имаш следното (и го пазиш към registry записа или като артефакти):

  • model_version и run_id
  • data_version или манифест на данните + test split
  • git commit hash на кода
  • training config файл
  • метрики по фиксиран тест (и ако можеш, по сегменти)
  • версия на вход/изход схемата (JSON Schema)
  • списък зависимости (lockfile/requirements)
  • бележки „какво се промени“ + известни слабости
  • линк към мониторинг табло и аларми

Минимална структура в репото, която помага на дисциплината:

  • configs/ за training и serving
  • eval/ за тестови набори и скриптове
  • pipelines/ за ETL и обучение
  • prompts/ и retrieval/ ако имаш LLM/RAG

Мини пример за „lineage“ (проследимост)

Представи си, че получиш сигнал за проблем от клиент. Искаш да можеш да проследиш веригата за 2 минути:

  • Production модел: invoice-classifier@1.2.0
  • Registry тагове: data_version=data-2026-02-01, git=9f3c..., run_id=mlflow:4812
  • Артефакти: config.yaml, requirements.lock, failure_cases.csv

Това ти позволява да възпроизведеш и да сравниш с предишната версия, вместо да „гадаеш“ какво е било пуснато. Освен това улеснява одит, разследване на инциденти и доказване на съответствие, при нужда от клиентска сертификация.

Източници и документация (актуални практики)

Често задавани въпроси

1) Какво е „минималното“ версиониране за малък екип?

Git за код, DVC или манифест за данни, и един регистър (MLflow/W&B), където записваш модела, конфигурацията и метриките.

2) Трябва ли да версионирам данните, ако са в база?

Да. Поне като snapshot (период, филтър, списък IDs). Иначе не можеш да възпроизведеш обучението.

3) Как да версионирам prompt-ове при LLM приложения?

Като код: отделни файлове с версия/тегове, плюс логване на prompt_version към всяка продукционна заявка.

4) Какво да правя, ако нов модел е по-точен, но по-скъп?

Пусни canary и сравни „цена на успешен резултат“. Често по-скъп модел намалява ескалации и общата цена пада.

5) Как да организирам rollback?

Дръж последната стабилна Production версия в registry, имай feature flag за превключване, и мониторинг с прагове за автоматично връщане.