Разработка и продуктивизация онлайн моделей

Прежде чем разрабатывать онлайн модель, Пользователь должен быть хорошо знаком с Системой и иметь опыт разработки batch моделей.

Разработка онлайн моделей проводится с помощью создания проекта в Jupyter, важно напомнить, что имя проекта модели не должно содержать символа ‘_’ и других символов, список которых выводится на экран при создании проект в ноутбуке create_project.ipynb.

Общая концепция разработки онлайн модели подразумевает, что Пользователь в Jupyter, например, в ноутбуке обучает модель, далее объект модели должен быть сохранен в папку pkl как model.pkl (обратите внимание, что файл должен быть сохранен в корневую папку pkl, а не папку online/src/pkl).

Необходимые для онлайн модели файлы расположены в папке online. Пользователь должен модифицировать файл в папке online/src/solver/main.py. Рассмотрим шаблон данного файла.

import pickle
import pandas as pd

def solve(temp_data):
    """
    Input: temp_data - json with features for prediction
    Output: f-string with result of prediction
    """
    with open("pkl/model.pkl","rb") as f:
        model = pickle.load(f)

    score = round(model.predict(pd.DataFrame([temp_data]))[0])

    return f'score={score}'

Файл содержит описание функции solve, которая на вход получает json-файл, содержащий наименования фичей и их значения для предсказания. Например, если модель должна предсказывать судьбу пассажира «Титаника» (известный учебный пример для Machine Learning), то данный json может представлять из себя данные по одному пассажиру, для которого планируется предсказание. Далее в файле должно происходить открытие файла pkl/model.pkl с обученной моделью. Далее должен быть код скоринга данной моделью входного json-файла. В строке return должен возвращаться результат скоринга.

Описанная в файле main.py функция solve вызывается в файле online/src/api.py, в котором описан код web-сервера онлайн модели, рассмотрим шаблон данного файла:

1        import os
2        import json
3        from fastapi import FastAPI, Body, status, UploadFile, File
4        from fastapi.responses import JSONResponse, FileResponse
5        from fastapi.exceptions import RequestValidationError
6        import uvicorn
7        from solver.main import solve
8        from scheme_api.scheme import ResponseData
9
10
11       config_api = {
12               "port": int(os.environ.get('PORT', '5005'))
13       }
14
15       app = FastAPI()
16
17
18       @app.exception_handler(RequestValidationError)
19       async def validation_exception_handler(request, exc):
20
21           response = {'http_status': 400, 'response_error': f'{exc}'}
22
23           return JSONResponse(content=response, status_code=400)
24
25
26       @app.get("/", status_code=status.HTTP_200_OK)
27       async def root():
28           return FileResponse("html/index.html")
29
30
31       @app.post("/solve", status_code=status.HTTP_200_OK, response_model=ResponseData)
32       async def solve_response(upload_file: UploadFile = File(...)):
33
34           if "json" in upload_file.filename:
35               data = json.load(upload_file.file)
36           else:
37               raise Exception("Invalid input!")
38
39           try:
40               response = solve(data)
41
42               return JSONResponse(status_code=200, content=response)
43
44           except Exception as e:
45               if 'error_response' in locals():
46                   error_response['error'] = str(e)
47               else:
48                   error_response = {'error': str(e)}
49
50               return JSONResponse(status_code=400, content=error_response)
51
52
53       if __name__ == "__main__":
54           uvicorn.run(app, host="0.0.0.0", port=config_api["port"])

На 7 строке происходит импорт функции solve из файла описанного выше файла main.py, далее на строке 40 результат вызова этой функции присваивается переменной response, которая далее участвует в выражении return на строке 42, содержащим ответ сервера, который будет показан на экране. В случае, если планируется переобучение онлайн модели, на этапе разработки модели в Jupyter необходимо подготовить файл retrain.py, находящийся в папке models (более подробно про файл retrain.py смотрите в разделе “Описание файла retrain.py”) и файл dag-ratrain.py из папки gitlab-ci, про который более подробно можно прочитать в разделе “Описание файла dag-retrain.py”.

Про выбор ресурсов контейнера продуктивизации онлайн модели следует смотреть раздел “Выбор ресурсов для продуктивизированного контейнера”.

Таким образом, при разработке онлайн модели Пользователь должен подготовить файл pkl/model.pkl и файл online/src/solver/main.py и, в случае переобучения, еще retrain.py и dag-retrain.py. Далее необходимо в терминале, запущенном в корневой директории проекта, выполнить команды:

dvc add ./pkl/model.pkl

dvc push

После этого нужно добавить на отслеживание в git все измененные файлы, например, с помощью команды в том же терминале:

git add -A

Далее выполнить команды:

git commit -m “текст коммита” git push origin dev

После этого нужно перейти в GitLab, найти свой проект и в ветке dev можно будет увидеть данный коммит. Рассмотрим процесс продуктивизации онлайн модели.

Далее необходимо сделать merge request из ветки dev в ветку online, данный merge request автоматически запустит CI/CD процесс продуктивизации модели. Перейти на вкладку CI/CD и запустить (кнопка “play” в меню справа). CI/CD процесс для онлайн модели состоит из четырех стадий. На первой стадии выполняется сборка образа с онлайн моделью, на второй стадии поднимается web-сервер, на третьей стадии в логах выводится адрес созданной онлайн модели. Чтобы увидеть лог файл стадии нужно нажать на иконку “круга” третьей стадии и кликнуть еще раз в появившееся окошко, на открывшейся странице лога внизу будет адрес, по которому можно перейти и в браузере откроется интерфейс модели (см. рисунки ниже).

Онлайн модель 1

Онлайн модель 2

Онлайн модель 3

Далее необходимо нажать кнопку “Выбрать файлы”, после этого выбрать необходимый json-файл с фичами для предсказания и нажать кнопку отправить. После этого на экране будет показан ответ модели, а именно выражение, указанное в return функции solve из файла online/src/solve/main.py.

После того как работа с онлайн моделью завершена, нужно вернуться на вкладку CI/CD в GitLab и вручную закрыть web-сервер с моделью для освобождения ресурсов Системы. Для этого нужно навести курсор мышки на шестеренку (рисунок «Онлайн модель1») и запустить эту стадию. По окончанию работы CI/CD на последней стадии (когда последний “круг” закончит процесс и станет зеленым) web-сервер с онлайн моделью будет остановлен, а ресурсы Системы освобождены.

Для запуска переобучения онлайн модели и установки данного процесса на работу по расписанию необходимо выполнить слияние ветки dev в ветку retrain в репозитории GitLab. После этого в Airflow среды DEV по адресу указать ссылку появится DAG-файл, имеющий имя “имя_проекта_retrain”, который нужно активировать (более подробно про интерфейс Airflow смотрите в разделе “Оркестрация рабочих процессов машинного обучения”).

После работы данного DAG-файла в репозитории проекта модели в GitLab появится ветка с именем типа retrain-pipeline_id-date, в которой находится обновленный файл model.pkl.dvc. Далее необходимо выполнить слияние ветки retrain-pipeline_id-date в ветку online, при этом на этапе подтверждения может появиться уведомление о конфликтах в ветках.

Мердж конфликт1

В данном случае нужно нажать на “Resolve Conflict” и на открывшейся странице выбрать “Use ours” (рисунок 39) и далее нажать на появившуюся ниже кнопку “Commit to source branch”.

Мердж конфликт2

После успешного разрешения конфликта слияния должен начаться CI/CD процесс продуктивизации онлайн модели, который требует ручной активации. Для этого нужно перейти на вкладку CI/CD и запустить пайплайн подобно тому, как это было сделано при первой запуске онлайн модели.