11 KiB
LR3 Создание сервиса предсказаний
Цель
Создать микросервис предсказаний моделью ML, создать его docker-образ и запустить сервис в контейнере.
Задание
- Активировать виртуальное окружение. Установить библиотеки
fastapi
,uvicorn
, не забыв обновитьrequirements.txt
. - Запустить mlflow, убедиться, что доступны экспериметы, прогоны и модели, сделанные в ЛР2.
- Создать директорию
./services
, в ней еще одну директориюml_service
, и в ней основной файлmain.py
.
my_proj
|_____ .venv_my_proj
|_____ .git
|_____ data
| |___ ...
|
|_____ eda
| |___ ...
|
|_____ research
| |___ ...
|
|_____ services
| |___ ml_service
| |___main.py
|
|_____ .gitignore
|_____ README.md
|_____ requirements.txt
- В созданном файле создать экземпляр
FastAPI-приложения
, сделать обработку GET-запросов к корню приложения/
, выдавая в ответ на запрос словарь{"Hello": "World"}
В ходе работы с файлами
.py
будут создаваться директории__pycache__
, в которых хранятся скомпилированные байт-код модули.pyc
. Эти папки коммитить не нужно. Добавьте правило в.gitignore
.
- Запустить сервер
uvicorn
и убедиться, что сервис обрабатывает запросы к корню, пройдя на страницуhttp://localhost:8000/docs
и выполнив тестовый запрос. - Создать endpoint
/api/prediction
выдачи предсказания для объекта. Endpoint будет обрабатывает POST-запросы, принимая в качестве URL-параметра идентификатор объектаitem_id
, а в теле запроса (body) все признаки объекта, необходимые для подачи на вход модели и выдачи предсказания. Возвращать будет словарь из двух объектов -item_id
- тот же идентификатор объекта, иpredict
- предсказанное значение. - Запустить сервер
uvicorn
и убедиться, что сервис обрабатывает запросы к/api/prediction
, пройдя на страницуhttp://localhost:8000/docs
и выполнив тестовый запрос к этому endpoint-у. Если сервис работает правильно, то вы должны увидеть ответ такой структуры:
Response body
{
"item_id": 123,
"price": 0.7637315626006276
}
- В директории
./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
-
Сформировать скрипт
get_model.py
, который должен подключаться к mlflow, выгружать модель по её run_id и сохранять ее в файлmodel.pkl
. -
В GUI MLFlow скопировать run_id production-модели, указать его в скрипте. Запустить скрипт и убедиться, что в директории
./services/models
появился файлmodel.pkl
. -
В директории
ml_service
создать файлapi_handler.py
и в нем описать класс-обработчик запросов к APIFastAPIHandler
.
Класс должен иметь метод __init__
в котором загружается модель из файла /model.pkl
, и метод predict
, возвращающий предсказание.
-
Доработать основной модуль сервиса и класс-обработчик таким образом, чтобы сервис предсказывал значения для любого произвольного объекта, параметры которого передаются в теле запроса. Убедиться в корректности работы. Остановить сервис.
-
В папке
ml_service
создать файлrequirements.txt
, в который записать те зависимости, которые необходимы для работы сервиса.
Данный файл - не то же самое, что
requirements.txt
в корневой директории проекта. Данный файл будет использоваться для сборки образа, поэтому должен содержать только необходимые зависимости и их версии. Виртуальное окружение на хостовой машине по-прежнему нужно устанавливать из файла в корневой директории.
Проще всего заполнить этот
requirements.txt
, пройдясь по файлам в папке и выписав все импорты. Абсолютно точно на этом этапе в зависимости нужно добавитьfastapi
,uvicorn
,pandas
,pickle4
,scikit-learn
.
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
- В папке
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
- Собрать образ, дать ему понятное название и указав что это первая версия образа.
Команду по сборке образа записать в конец Dockerfile
, добавив значок комментария #
.
В рамках это ЛР мы будем создавать первую версию нашего сервиса. Даже если вы несколько раз пересобираете образ, что-то меняя или добавляя в него, в этой ЛР все равно указывайте первую версию.
Версия указывается через двоеточие после названия образа. Например, для указания 3й версии образа:
my_super_image:3
- Запустить контейнер из образа. Команду по запуску контейнера записать в конец
Dockerfile
, добавив значок комментария#
.
При запуске не забыть указать, какой хостовый порт должен быть связанным с портом 8000 внутри контейнера.
Указать, что хостовая директория ../models должна быть связана с одноименной директорией в контейнере. Поскольку мы собираем образ из директории
ml_service
, а интересующая директория с модельюmodels
находится на уровень выше, то путь до нее можно указать так:$(pwd)/../models
. Здесь$(pwd)
(print working directory) - утилита командной строки, которая выводит полный путь до текущей директории. Через двоеточие от хостовой директории нужно указать соответствующий volume внутри контейнера. Полный агрумент будет выглядеть так:$(pwd)/../models:/models
-
Убедиться, что контейнер работает, отправив запрос в сервис. Добиться работоспособности сервиса.
-
Актуализировать файл README:
- добавить описание разработанного сервиса: краткое описание файлов в папке ml_service, models.
- Указать команды для создания образа и запуска контейнера.
- Указать, как можно проверить работоспособность сервиса, включив пример тела запроса.