Внедрение модели машинного обучения в производство может быть простым и масштабируемым. Flask, наряду с Gunicorn и Nginx, в докеризованной среде - это простой, но эффективный способ превратить вашу модель машинного обучения в API.

  • Flask - популярный фреймворк Python для создания веб-API. Это будет ядро ​​нашего API, где мы импортируем нашу модель машинного обучения и напишем функцию для прогнозирования и возврата ответа JSON.
  • Gunicorn - необходимый компонент для запуска Flask в производство. Flask (и Python в целом) требуется интерфейс шлюза веб-сервера (WSGI) для обработки всех подключений к веб-серверу, например Nginx. Flask имеет встроенный WSGI, но он небезопасен или эффективен, и его НЕ следует использовать в производственной среде.
  • Nginx - это наш веб-сервер, который будет обрабатывать все запросы и действовать как балансировщик нагрузки для приложения.
  • Docker - отличный способ упростить развертывание API на любом сервере. Его легко настроить для работы с любой конфигурацией. Более того, вы можете комбинировать несколько экземпляров контейнера докеров, когда хотите масштабировать свой API.

Обзор проекта

Моя цель - развернуть классификатор текста fast.ai: модель классификации текста, которую я разработал в моем предыдущем посте (ссылка). Этот классификатор основан на наборе данных вопросов StackOverflow и классифицирует строку текста (заголовок вопроса StackOverflow) по одной из 20 категорий.

Обратите внимание, что вы можете использовать одни и те же методы для разработки API для любого типа модели машинного обучения. Мы рассмотрим это более подробно в Части 3.

Модель использует библиотеку fast.ai, и прогнозы работают следующим образом:

learner = load_learner('./models', 'model.pkl')
learner.predict("This is the text I want to classify")

В этой статье я создам оболочку для этих двух строк кода. API примет предложение как API и вернет его классификацию.

Вот как выглядит проект:

flask-ml-api
|- api
    |- models
        |- model.pkl
    |- app.py 
    |- requirements.txt
    |- Dockerfile
|- nginx
    |- nginx.conf
    |- Dockerfile
|- docker-compose.yml

Как видите, API и Nginx находятся в разных контейнерах Docker. Мы будем использовать docker-compose для их соединения, чтобы Nginx обрабатывал запросы к API через Gunicorn.

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

Установка Flask

В этой части мы будем внедрять Flask API локально, а не развертывать его в Docker. Начните с этих пакетов Python:

pip install flask
pip install fastai

Flask API

В этой части наша файловая структура выглядит следующим образом:

flask-ml-api
  |- model.pkl
  |- app.py

Flask позволяет нам писать API в одном файле с менее чем 10 строками кода. Когда вы запускаете файл Flask app.py, вы, по сути, создаете веб-сервер и развертываете конечную точку.

Создайте новый файл с именем app.py, содержащий все необходимое для работающего Flask API. Мой API выглядит так:

from flask import Flask, jsonify, request
from fastai.text import *
import json

app = Flask(__name__)

learner = load_learner('.', 'model.pkl')

@app.route("/classification")
def classification():
    sample = json.loads(request.data)["text"]
    return jsonify(str(learner.predict(sample)[0]))


if __name__ == '__main__':
    app.run(host='0.0.0.0')

Итак, вот как все работает:

app = Flask(__name__) используется для создания экземпляра класса Flask, и мы называем его значением по умолчанию __name__ в Python. По сути, это регистрирует «приложение», и мы можем использовать его для создания маршрутов (т.е. наших URL-адресов API).

learner - наш ученик фастай. Мы загружаем файл рассола, чтобы мы могли попросить учащегося предсказать тест на основе нашего запроса API.

@app.route("/classification") - это URL-адрес API. При запросе этого URL-адреса flask будет запускать функцию classification() с вашими параметрами запроса (например, вашим телом json), хранящимися в request, и, следовательно, вы можете получить доступ к этой информации в Python, используя json.loads(request.data). Мы хотим, чтобы функция classification() возвращала наш прогноз в форме json.

Наконец, мы устанавливаем хост на 0.0.0.0 (это localhost), чтобы наш API-интерфейс flask работал на localhost. Вот и все!

Запрос API

Запустите app.py, чтобы запустить API на локальном хосте:

python3 app.py

Вы найдете URL-адрес localhost с портом в выходных данных терминала этой команды. Обычно это http://0.0.0.0:5000/.

Наш URL: GET 0.0.0.0:5000/classification

Тело запроса выглядит так:

{
	"text": "Your classification text goes here"
}

Я буду использовать Почтальон для запроса API:

И это работает!

Заключение к части 1

В этой части серии мы написали суть кода API. Вы можете найти этот код на Github.

В частях 2, 3 и 4 мы расширим этот код, включив в него улучшенные WSGI и Nginx, и обернем все это в Docker, чтобы вы могли легко развернуть API.

В этой серии:

Часть 1: Настройка нашего API
Часть 2: Интеграция Gunicorn, Nginx и Docker
Часть 3: Flask Blueprints - управление несколькими конечными точками
Часть 4. Тестирование вашего ML API

Привет! Спасибо за чтение. Немного обо мне. Я изучаю компьютерные науки в Университете Британской Колумбии, Канада. В основном я работаю над проектами машинного обучения, в основном НЛП. Еще я занимаюсь фотографией как хобби. Вы можете подписаться на меня в Instagram и LinkedIn или посетить мой сайт. Всегда открыт для возможностей 🚀