Вы не можете выбрать более 25 тем Темы должны начинаться с буквы или цифры, могут содержать дефисы(-) и должны содержать не более 35 символов.

11 KiB

LR3 Создание сервиса предсказаний

Цель

Создать микросервис предсказаний моделью ML, создать его docker-образ и запустить сервис в контейнере.

Задание

  1. Активировать виртуальное окружение. Установить библиотеки fastapi, uvicorn, не забыв обновить requirements.txt.
  2. Запустить mlflow, убедиться, что доступны экспериметы, прогоны и модели, сделанные в ЛР2.
  3. Создать директорию ./services, в ней еще одну директорию ml_service, и в ней основной файл main.py.
my_proj
 |_____ .venv_my_proj
 |_____ .git
 |_____ data
 |       |___ ...
 |
 |_____ eda
 |       |___ ...
 |
 |_____ research
 |       |___ ...
 |
 |_____ services
 |       |___ ml_service
 |              |___main.py
 |              
 |_____ .gitignore
 |_____ README.md
 |_____ requirements.txt
  1. В созданном файле создать экземпляр FastAPI-приложения, сделать обработку GET-запросов к корню приложения /, выдавая в ответ на запрос словарь {"Hello": "World"}

В ходе работы с файлами .py будут создаваться директории __pycache__, в которых хранятся скомпилированные байт-код модули .pyc. Эти папки коммитить не нужно. Добавьте правило в .gitignore.

  1. Запустить сервер uvicorn и убедиться, что сервис обрабатывает запросы к корню, пройдя на страницу http://localhost:8000/docs и выполнив тестовый запрос.
  2. Создать endpoint /api/prediction выдачи предсказания для объекта. Endpoint будет обрабатывает POST-запросы, принимая в качестве URL-параметра идентификатор объекта item_id, а в теле запроса (body) все признаки объекта, необходимые для подачи на вход модели и выдачи предсказания. Возвращать будет словарь из двух объектов - item_id - тот же идентификатор объекта, и predict - предсказанное значение.
  3. Запустить сервер uvicorn и убедиться, что сервис обрабатывает запросы к /api/prediction, пройдя на страницу http://localhost:8000/docs и выполнив тестовый запрос к этому endpoint-у. Если сервис работает правильно, то вы должны увидеть ответ такой структуры:
Response body
{
  "item_id": 123,
  "price": 0.7637315626006276
}
  1. В директории ./services создать директорию models, в которой будет храниться обученная модель, а также скрипт по ее получению из mlflow. Создать скрипт get_model.py
my_proj
 |_____ .venv_my_proj
 |_____ .git
 |_____ data
 |       |___ ...
 |
 |_____ eda
 |       |___ ...
 |
 |_____ research
 |       |___ ...
 |
 |_____ services
 |       |___ ml_service
 |       |      |___main.py
 |       |___models
 |              |___get_model.py
 |              |___model.pkl    # Появится после выполнения следующего пункта 
 |              
 |_____ .gitignore
 |_____ README.md
 |_____ requirements.txt
  1. Сформировать скрипт get_model.py, который должен подключаться к mlflow, выгружать модель по её run_id и сохранять ее в файл model.pkl.

  2. В GUI MLFlow скопировать run_id production-модели, указать его в скрипте. Запустить скрипт и убедиться, что в директории ./services/models появился файл model.pkl.

  3. В директории ml_service создать файл api_handler.py и в нем описать класс-обработчик запросов к API FastAPIHandler.

Класс должен иметь метод __init__ в котором загружается модель из файла /model.pkl, и метод predict, возвращающий предсказание.

  1. Доработать основной модуль сервиса и класс-обработчик таким образом, чтобы сервис предсказывал значения для любого произвольного объекта, параметры которого передаются в теле запроса. Убедиться в корректности работы. Остановить сервис.

  2. В папке ml_service создать файл requirements.txt, в который записать те зависимости, которые необходимы для работы сервиса.

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

Проще всего заполнить этот requirements.txt, пройдясь по файлам в папке и выписав все импорты. Абсолютно точно на этом этапе в зависимости нужно добавить fastapi, uvicorn, pandas, pickle4.

my_proj
 |_____ .venv_my_proj
 ...
 |
 |_____ services
 |       |___ ml_service
 |       |      |___main.py
 |       |      |___api_handler.py
 |       |      |___Dockerfile
 |       |      |___requirements.txt  # новый файл, созданный на этом шаге
 |       |___models
 |              |___get_model.py
 |              |___model.pkl   
 |              
 |_____ .gitignore
 |_____ README.md
 |_____ requirements.txt   # старый файл, созданный в ЛР1
  1. В папке ml_service cформировать Dockerfile Образ должен собираться Из базового образа python:3.11-slim по следующим шагам:
  • Скопировать содержимое текущей директории в директорию /ml_service в контейнере
  • Сделать директорию /models доступной снаружи контейнера
  • Сделать /ml_service рабочей директорией
  • Выполнить установку всех зависимостей из файла requirements.txt
  • Указать, что порт 8000 должен быть доступен снаружи контейнера
  • Финальная команда - запуск сервера. Необходимо явно указать адрес хоста "0.0.0.0" и порта "8000", на которых будет запускаться сервер.

Состав директорий проекта на данном шаге должен выглядеть следуюшим образом:

my_proj
 |_____ .venv_my_proj
 |_____ .git
 |_____ data
 |       |___ ...
 |
 |_____ eda
 |       |___ ...
 |
 |_____ research
 |       |___ ...
 |
 |_____ services
 |       |___ ml_service
 |       |      |___main.py
 |       |      |___api_handler.py
 |       |      |___Dockerfile
 |       |      |___requirements.txt
 |       |___models
 |              |___get_model.py
 |              |___model.pkl   
 |              
 |_____ .gitignore
 |_____ README.md
 |_____ requirements.txt
  1. Собрать образ, дать ему понятное название и указав что это первая версия образа.

Команду по сборке образа записать в конец Dockerfile, добавив значок комментария #.

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

Версия указывается через двоеточие после названия образа. Например, для указания 3й версии образа: my_super_image:3

  1. Запустить контейнер из образа. Команду по запуску контейнера записать в конец Dockerfile, добавив значок комментария #.

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

Указать, что хостовая директория ../models должна быть связана с одноименной директорией в контейнере. Поскольку мы собираем образ из директории ml_service, а интересующая директория с моделью models находится на уровень выше, то путь до нее можно указать так: $(pwd)/../models. Здесь $(pwd) (print working directory) - утилита командной строки, которая выводит полный путь до текущей директории. Через двоеточие от хостовой директории нужно указать соответствующий volume внутри контейнера. Полный агрумент будет выглядеть так: $(pwd)/../models:/models

  1. Убедиться, что контейнер работает, отправив запрос в сервис. Добиться работоспособности сервиса.

  2. Актуализировать файл README:

  • добавить описание разработанного сервиса: краткое описание файлов в папке ml_service, models.
  • Указать команды для создания образа и запуска контейнера.
  • Указать, как можно проверить работоспособность сервиса, включив пример тела запроса.