Простой, эффективный и ремонтопригодный.

Это второй пост в серии MLOps Loris.ai.

В этом выпуске мы рассмотрим нашу любимую реализацию MLOps, которую легко реализовать с минимальным количеством внешних библиотек.

Если вы предпочитаете сразу перейти к коду, вот репозиторий https://github.com/SerjSmor/mlops_template.

Отказ от ответственности: мы не имеем ничего против магии. Нам просто это не нравится в наших трубопроводах.

TL;DR

В этой серии объясняется, как реализовать промежуточные MLOps с помощью простого кода Python без введения фреймворков MLOps (MLflow, DVC…).

Это сделано специально, потому что наиболее распространенные варианты использования могут быть реализованы с помощью шаблонов, которые мы предлагаем в этом блоге. Эти принципы просты и могут быть легко перенесены в любой проект DS.

С другой стороны, отслеживание экспериментов имеет четкий стандарт. Используя wandb или neptune, вы очень быстро доберетесь очень далеко.

Содержание

  1. вступление
  2. Структура проекта
    — Папки артефактов
    — Инструменты командной строки
  3. Сердце MLOps: tasks.py
    — Создание конвейера
    — Извлечение данных
  4. Архивирование экспериментов
    — Локальное архивирование
    — Загрузка экспериментов в облако или из него
  5. Краткое содержание

вступление

Если вы не уверены, что означает MLOps (не фактическая аббревиатура, а необходимость), вы можете прочитать нашу предыдущую часть Medium https://medium.com/@serj-smor/philosophy-of-an-experimentation- система-mlops-intro-b864b0339323.

Моя интерпретация MLOps аналогична моей интерпретации DevOps. Ваша роль как инженера-программиста — писать код для определенной цели. DevOps покрывает все остальное, например развертывание, планирование автоматических тестов при изменении кода, масштабирование машин до требуемой нагрузки, разрешения для облака, настройку базы данных и многое другое.

Как разработчик программного обеспечения, чем больше вы разбираетесь в DevOps, тем лучше вы можете предвидеть проблемы, исправлять ошибки и быть ценным членом команды.

Та же аналогия применима и к MLOps.

Как инженер ML, вы отвечаете за какой-то код/модель. MLOps охватывают все остальное: как отслеживать ваши эксперименты, как делиться своей работой, как версионировать модели и т. д. (Полный список в предыдущем посте).

То же правило опыта применимо и к инженеру ML: чем больше вы разбираетесь в MLOps, тем лучше вы можете предвидеть проблемы, исправлять ошибки данных/модели и быть ценным членом команды.

99 % лучших практик можно реализовать, следуя предлагаемой нами структуре проекта и реализуя приведенные ниже шаблоны.

Структура проекта

Мне нравится подход WYSIWYG, поэтому без лишних слов вот скриншот файловой структуры.

Так какую же структуру проекта мы предпочитаем?
Какая структура проекта может дать нам четкое разделение задач?

У Python есть разные варианты и некоторая свобода в расположении скриптов и компонентов. Следовательно, важно выбрать определенную конфигурацию и внедрить ее во всей команде.

Эта структура проекта также применима к новому миру LLM, с которым мы все познакомились. Отсутствие локальной модели не является оправданием отказа от организации, управления версиями и просто старых добрых шаблонов чистого кода.

P.S. Если вы уже узнали эту закономерность, можете перейти к архивированию своих экспериментов.

Авария

Папки артефактов: данные/модели/результаты/

В целом эти папки представляют собой один эксперимент.

Папки артефактов не привязаны к .git (если вы не используете шаблоны, подобные DVC).

  1. Данные могут содержать личную информацию пользователя
    — Точно так же вы не будете передавать пароли в .git, верно? Верно?
  2. Модели очень тяжелые, и на их фиксацию и синхронизацию потребуется много времени.

Имея эти папки, вы упрощаете код, который их использует (и всех, кто их читает).

Остальная часть кода имеет значения по умолчанию для всех входов и выходов.

Некоторые эксперименты полезно сохранять и делиться — возможность архивировать эксперименты и делиться ими будет представлена ​​в разделе «Архивирование экспериментов».

Данные

Содержимое папки данных: raw.csv, Transform.csv, clean.csv, train.csv, validation.csv, test.csv

Данные будут содержать все входные файлы, которые вы будете использовать. Входные файлы различаются, вы начинаете с необработанных входных данных, но любые выполняемые вами преобразования также следует хранить в папке.

Почему вам следует сохранять и локальные преобразования? Конечно же, для отладки!

Вы когда-нибудь получали 100 F1 на валидации и чувствовали, что где-то была ошибка?

Первым лучшим шагом будет изучение различных преобразований .csv.

Модели

Этот каталог будет содержать контрольные точки и окончательную модель этого эксперимента.

Полученные результаты

Этот каталог будет содержать любую информацию, созданную после создания модели.

Любые графики, диаграммы и прогнозы в формате .csv.

Инструменты командной строки

Эти скрипты видны при специальном входе в проект.

Они представляют собой интерфейс проекта: preprocess.py, train.py, Predict.py, Results.py и Tasks.py.

В каждом из них реализован argparse, позволяющий работать из CMD/терминала.

Почему это требование?

  1. Он позволяет создавать блоки кода, которые легко объединяются посредством вызова командной строки.
  2. Запуск полного конвейера аналогичен $ python [preprocess.py](<http://preprocess.py>) {arguments}, $ python [train.py](<http://train.py>) {arguments}
  3. Он позволяет вам запускать код с любого удаленного сервера, клонировав репозиторий git и запустив (1.a)
  4. Это позволяет запускать на GPU-сервере (EC2 — облако) или на локальной рабочей станции.
  5. Этим интерфейсом можно поделиться с коллегами — это может помочь воспроизвести результаты или просто позволить вам работать в команде над одним проектом.
  6. Для лучшего эксперимента запустите $ python [preprocess.py](<http://preprocess.py>) {--remove-duplicates}, $ python [train.py](<http://train.py>) {--model distilbert}
  7. Этот интерфейс позволяет систематически настраивать гиперпараметры — я объясню это в разделе «Конвейер».

препроцесс.py

Все начинается с предварительной обработки. Мы предполагаем, что работаем с некоторыми данными, которые необходимо преобразовать, будь то изображения, текст, аудио или табличные данные.

Все этапы предварительной обработки предполагают, что интересующие данные находятся в папке data/.

Мы предполагаем, что файлы, которые нам нужно обработать, уже есть. Подробнее о том, как этого добиться, — в разделе «Конвейер/Извлечение данных».

Давайте возьмем пример задачи классификации аудио.

В папке data будет «сырая» папка с файлами .wav.

В ходе предварительной обработки нам придется:

  1. Фильтровать строки
    — Проверка и удаление дубликатов.
  2. Устраните отклонения (слишком короткие, слишком длинные)
  3. Извлечение функций
  4. Создайте наборы поездов, валидации и тестирования.

Тот же шаблон будет применяться для классификации текста с различиями в реализации этапов.

Извлечение функций может быть неактуальным — особенно при работе с глубоким обучением (не нужно лемматизировать, удалять стоп-слова и т. д.). Вместо этого вы можете разбить длинный текст на части, разделить абзацы и многое другое.

В конце скрипта вы должны создать выходные данные для следующего этапа, то есть train.csv, validation.csv, test.csv в папке data/ для train.py.

train.py

Поскольку этап предварительной обработки уже завершен, train.py может быть тонким и сфокусированным.

На этапе предварительной обработки были созданы 3 файла (train.csv, validation.csv, test.csv), которые train.py pd.read_csv() будет использовать для них.

Аргументы командной строки могут помочь, поскольку передача гиперпараметров зависит от задачи и модальности, над которой вы работаете, но я уверен, что есть несколько гиперпараметров, которые будут актуальны: размер пакета, скорость обучения, эпохи. >

В конце скрипта необходимо сохранить модель в папке models/

Если вы хотите иметь возможность выполнять анализ ошибок в этом эксперименте, вы должны сохранить прогнозы модели на каждом из наборов (обучение, проверка, тестирование). Они станут первыми файлами в папке results/.

predict.py

Помимо обучения, запустить модель на произвольных данных довольно просто. Возможно, у вас есть периодическое тестирование и вы хотите запустить модель на 1000 выборках? Выходные данные некоторого SQL-запроса могут стать входными данными для этого сценария.

Возможные входные данные для сценария: 1. CSV с данными, 2. Одна точка данных (текст, аудио, изображение).

Инструмент «Прогноз» справится с этим (да, как вы правильно догадались) для прогнозирования результатов класса, используя модель, которую вы сохранили в models/, или произвольную модель.

В конце скрипта вы должны сохранить результаты прогноза (если входные данные были в формате .csv) в папке results/.

Очень удобно тестировать входные данные без привязки к производству и его недостаткам.

results.py

Этот скрипт идет рука об руку с predict.py и train.py.

  • Хотите создавать отчеты о классификации и матрицы путаницы?
  • Высшая точность?
  • Кривые точности отзыва?
  • Различные дистрибутивы?

Здесь можно написать комплексный анализ, который поможет вам с анализом ошибок.

Скрипт должен сохранять различные результаты в папке results/.

tasks.py

Наш код MLOps будет находиться в этом скрипте. Это основа операций, подготовка почвы для загрузки, извлечения, загрузки экспериментов, запуска конвейеров и всего, что не связано с машинным обучением. Просто перейдите к следующему разделу.

Сердце MLOps — tasks.py

Наконец, мы представляем внешнюю библиотеку. И нет, это не Airflow или WANDB 🙂

Это py-invoke, и его лучшая функция — вызов bash из Python, что позволяет вам объединять несколько сценариев в один конкретный файл под названием tasks.py.

Вот содержимое tasks.py нашего демо-проекта:

  1. Оформляя метод как @task, вы автоматически создаете для него интерфейс CMD — без введения argparse. Библиотека Invoke сделает всю работу за вас.
  2. Запуск вызова из cmd: $ inv download-best-model

Мы отделяем MLOps от реального кода ML. Код ML должен обрабатывать обучение, предварительную обработку и т. д.

С этого момента мы будем использовать tasks.py в качестве точки входа в MLOps. Это создает стандарт, который упрощает сценарии ML и устанавливает ожидания для остальной команды в отношении того, как обстоят дела.

Получение данных

Мы привыкли получать данные из облака. Это лучшая практика для сотрудничества и конфиденциальности.

def prepare_data_for_pipeline()

Позволяет вам именно это. Если у вас сложная стратегия выборки, это идеальное место для ее расширения.

Трубопровод

В зависимости от сложности проекта количество этапов конвейера может варьироваться от 2 до 20.

def pipeline()

В нашей демонстрации всего 3 этапа, некоторые этапы могут быть методами, а некоторые могут запускать целый скрипт.

Архивирование экспериментов

Эксперименты — это основа ML.

MLOps должны позаботиться о том, как мы их храним, делимся, загружаем и скачиваем.

Мы переместим все каталоги, связанные с экспериментом, в специальную локальную папку archived_experiments. Затем эту папку можно синхронизировать с облаком, чтобы обеспечить постоянное хранение и возможность делиться экспериментами с коллегами.

Архивирование локально

Вот реализация простой процедуры для хранения экспериментов в папке archived_experiments.

Метод archive() определен в tasks.py и вызывается через командную строку, как показано на снимке экрана.

Задачи tasks.py позволяют легко вызывать процессы командной строки. Каждый c.run по умолчанию является последовательным/синхронным, поэтому каждая команда завершается, а затем переходит к следующей.

Загрузка/выгрузка экспериментов в/из облака

def sync_to_remote загрузит любые локальные данные, которых нет в S3.

sync работает с различиями, как и .git.

Точно так же sync_from_remote делает обратное, позволяя другим участникам легко загружать ваши эксперименты, тем самым обеспечивая совместную работу и воспроизведение!

Краткое содержание

Эта система MLOps не уникальна, мы узнали об этих шаблонах от наших коллег, в Интернете и друзей. Мы настроили его (тонко настроили :)) под наши нужды. Это очень полезно и может существенно повысить продуктивность команды, особенно для новых команд.

Это достаточно просто написать на бумажной салфетке, но можно и сколь угодно сложно, без всякого волшебства!

Таким образом, представлено только два шаблона:

  1. Скрипты (инструменты) для ML
  2. tasks.py для MLOps

Весь код находится в репозитории https://github.com/SerjSmor/mlops_template, не стесняйтесь создавать форк или запускать проект.

В следующем выпуске мы углубимся в сложные шаблоны, такие как создание шаблона проекта с помощью формочки для печенья, чтение удаленных файлов .csv без изменения кода, управление библиотекой Python для основы совместной работы и многое другое!

ПИСАТЕЛЬ на MLearning.ai / более 800 AI-плагинов / AI Searching 2024