Контейнеризация модели обнимающего лица с помощью FastAPI и Docker для эффективного развертывания

Эффективно упакуйте и разверните модель обнимающегося лица с помощью FastAPI и Docker для масштабируемого производства

Всем привет! 👋

Сегодня мы увидим, как мы можем обслуживать модель Hugging Face и контейнеризовать ее с помощью Docker.

Мы собираемся использовать модель классификации, чтобы классифицировать твиты как «Положительные», «Отрицательные» и «Нейтральные» с соответствующими оценками.

Вот структура папок проекта —

root
├── ml-service/
│   ├── app.py
│   ├── model.py
│   ├── classifier.py
│   ├── nlp.py
│   ├── download_model.ipynb
│   └── Dockerfile
└── docker-compose.yml

Наш самый первый шаг — загрузить модель. Мы собираемся настроить блокнот jupyter для загрузки модели обнимающего лица и помещения ее в каталог по нашему выбору.

Давайте идти!

Скачайте и сохраните модель обнимающегося лица

  1. Создайте каталог ml-service.
  2. Создайте файл download_model.ipynb внутри каталога и сохраните модель.
from transformers import AutoModelForSequenceClassification, TFAutoModelForSequenceClassification, AutoTokenize
# download the model
MODEL = "cardiffnlp/twitter-roberta-base-sentiment"
tokenizer = AutoTokenizer.from_pretrained(MODEL)
model = AutoModelForSequenceClassification.from_pretrained(MODEL)
# save the model
save_dir = "ml-service/models/roberta-base"
tokenizer.save_pretrained(save_dir)
model.save_pretrained(save_dir)

Загрузка модели и классификатора

  1. Создайте файл ml-service/model.py для загрузки модели и токенизатора.
# model.py
from transformers import AutoModelForSequenceClassification, TFAutoModelForSequenceClassification, AutoTokenize

class Model:
  """A model class to lead the model and tokenizer"""

  def __init__(self) -> None:
    pass
  
  def load_model():
    model = AutoModelForSequenceClassification.from_pretrained("./models/roberta-base/")
    return model

  def load_tokenizer():
    tokenizer = AutoTokenize.from_pretrained("./models/roberta-base/")
    return tokenizer

2. Затем создайте файл ml-service/classifier.py, который будет обрабатывать оценки тональности и метки.

# classifier.py
from scipy.special import softmax
from model import Model
import numpy as np

class Classifier:
  def __init__(self):
    self.model = Model.load_model()
    self.tokenizer = Model.load_tokenizer()

  def get_sentiment_label_and_score(self, text: str):
    result = {}
    labels = ["Negative", "Neutral", "Positive"]
    encoded_input = self.tokenizer(text, return_tensors='pt')
    output = self.model(**encoded_input)
    scores = output[0][0]jj.detach().numpy()
    scores = softmax(scores)
    ranking = np.argsort(scores)
    ranking = ranking[::-1]
    result["label"] = str(labels[ranking[0]])
    result["score"] = np.round(float(scores[ranking[0]]), 4)
    return result

Анализ настроений

Мы создаем модуль ml-service/nlp.py для анализа настроений.

# nlp.py
from classifier import Classifier

classifier = Classifier()

def sentiment_analysis(self, text:str, classifier: 
  sentiment = classifier.get_sentiment_label_and_score(text)
  return sentiment 
     

быстрый API-сервер

  1. Первый шаг — создать файл ml-service/app.py и импортировать необходимые библиотеки.
# app.py
from fastapi import FastAPI, APIRouter
import uvicorn
from classifier import Classifier
from model import Model
from nlp import NLP
import logging

logging.basicConfig(level = logging.INFO)

2. Создайте необходимые экземпляры класса.

app = FastAPI()
nlp = NLP()
router = APIRouter()
classifier = Classifier()

3. Создадим необходимые маршруты.

@router.get("/")
async def home():
  return {"message": "Machine Learning service"}

@router.post("/sentiment")
async def data(data: dict):
  try:
    input_text = data["text"]
    res = nlp.sentiment_analysis(classifier, input_text)
    return res
  except Exception as e:
    log.error("Something went wrong")

app.include_router(router)

if __name__ == "__main__":
  uvicorn.run("app:app", reload=True, port=6000, host="0.0.0.0)

Теперь, когда наш API готов, нам нужно создать файл Dockerfile и файл requirements.txt.

Подготовка Docker

  1. Сначала мы создаем файл requirements.txt внутри каталога ml-service.
$ pip freeze > requirements.txt

2. Далее мы создаем Dockerfile.

FROM python:3.10.8-slim
LABEL description="Sentiment classifier of tweets service"
WORKDIR /app
COPY requirements.txt /app/requirements.txt
RUN pip install -r requirements.txt
COPY . /app/
EXPOSE 6000
CMD ["python",  "app.py"]

3. Теперь создайте образ Docker, используя docekr run или создав файл docker-compose.yml.

Давайте посмотрим, как использовать docker-compose для создания контейнера.

3. Создайте файл docker-compose.yml в корневой папке. И добавьте к нему следующее.

version: '3

services: 
  ml-service:
    build: ./ml-service
    ports:
      - 6000:6000

4. Теперь просто запустите команду docker-compose.

$ docker-compose up --build

5. Откройте отдельную оболочку и попробуйте запустить docker ps. Он покажет все запущенные контейнеры. Контейнер должен быть запущен.

Сделайте POST-запрос к localhost:6000/sentiment с телом {"text": "Hi, Thanks"} .

Ответ на запрос POST должен быть примерно таким:

{
  "label": "Positive",
  "score": 0.78
}

На этом пока все👋

Спасибо и счастливого кодирования 💙