본문으로 건너뛰기

2) Model API on Docker Compose

Chapter Preview


목표

  1. 앞서 작성한 API 를 실행할 수 있는 Dockerfile 을 작성합니다.
  2. API 서버를 띄우기 위한 Docker Compose 파일을 작성합니다.
  3. API 서버에 데이터를 전달하여 제대로 작동하는지 확인합니다.

스펙 명세서

  1. 작성한 API 를 실행하는데 필요한 모델을 이미지에 복사하는 Dockerfile 을 작성합니다.
    • 이미지를 실행했을 때, 별도의 모델 정보를 필요로 하지 않습니다.
    • Base image 는 amd64/python:3.9-slim 을 사용합니다.
    • 포트는 기본 포트인 8000번 포트를 이용합니다.
  2. Model API 서버를 띄우기 위한 Docker Compose 파일을 작성합니다.
    • Service name: api-with-model
    • Image: Dockerfile
    • Container name: api-with-model
    • Port: 8000:8000
  3. Docker Compose 파일을 실행하여 API 를 작동시키고 데이터를 전달하여 예측 결과를 제대로 반환하는지 확인합니다.
    • Swagger UI 를 통해 확인합니다.
    • curl 을 통해 확인합니다.
https://github.com/mlops-for-mle/mlops-for-mle/tree/main/part6

해당 파트의 전체 코드는 mlops-for-mle/part6/ 에서 확인할 수 있습니다.

part6
├── Dockerfile
├── Makefile
├── README.md
├── app.py
├── docker-compose.yaml
├── download_model.py
└── schemas.py
[그림 6-5] Model API Diagram

1. Dockerfile 작성

Dockerfile 을 이용하여 앞서 작성한 Model API 를 작동시킬 수 있는 API 서버의 Docker 이미지를 만들어보겠습니다.

Dockerfile
FROM amd64/python:3.9-slim

WORKDIR /usr/app

RUN pip install -U pip &&\
pip install mlflow==1.30.0 pandas scikit-learn "fastapi[all]"

COPY schemas.py schemas.py
COPY app.py app.py
COPY sk_model/ sk_model/

CMD ["uvicorn", "app:app", "--host", "0.0.0.0", "--reload"]
  • RUN :
    • pip 를 업데이트 한 후 필요한 패키지들을 설치합니다.
  • COPY :
    • API 를 작동시키는데 필요한 .py 파일들과 모델이 저장된 디렉토리 sk_model 을 컨테이너 내부로 복사합니다.
    • API 에서 사용할 모델 파일을 직접 넣어줌으로써 이미지를 실행했을 때에는 별도의 모델 정보를 필요로 하지 않게 됩니다.
  • CMD :
    • 컨테이너가 실행될 때 수행할 명령어의 기본값을 적어줍니다.
    • 여기서는 uvicorn 을 이용해 app.py 에서 만든 FastAPI 의 객체 app 을 실행합니다.

2. Docker Compose

이제 Model API 서비스를 띄우는 Docker Compose 파일을 작성하겠습니다.

docker-compose.yaml
version: "3"

services:
api-with-model:
build:
context: .
dockerfile: Dockerfile
container_name: api-with-model
ports:
- 8000:8000
healthcheck:
test:
- CMD
- curl -X POST http://localhost:8000/predict
- -H
- "Content-Type: application/json"
- -d
- '{"sepal_length": 6.7, "sepal_width": 3.3, "petal_length": 5.7, "petal_width": 2.1}'
interval: 10s
timeout: 5s
retries: 5

networks:
default:
name: mlops-network
external: true
  • healthcheck :
    • curl 을 이용하여 API 서버의 동작을 테스트합니다.
    • 정상 동작이 확인되면 서비스를 띄웁니다.
  • networks :
    • 서비스들을 연결할 Docker 네트워크를 01. Database 파트에서 생성한 mlops-network 로 사용합니다.
    • external: true 옵션은 docker compose down -v 로 이번 파트에서 생성되는 서비스를 종료하더라도 01. Database 파트에서 생성한 mlops-network 를 삭제하지 않을 수 있게 됩니다.

이제 완성된 Docker Compose 파일을 다음의 명령어를 통해 실행하여 Model API 서비스를 작동시킵니다.

docker compose up -d

컨테이너가 잘 실행되고 있는지 확인해보면 다음과 같이 api-with-model 이라는 이름의 컨테이너가 실행되고 있음을 확인할 수 있습니다.

docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
a88b1a6cff44 part6-api-with-model "uvicorn app:app --h…" 5 seconds ago Up 4 seconds

3. API 서버 작동 확인

3.1 Swagger UI 이용

이제 API 서버가 잘 작동하는지 확인해 보겠습니다. API 서버 컨테이너를 실행할 때 포트 포워딩을 8000:8000 으로 했으므로 8000번 포트로 접속하면 API 서버로 접속할 수 있습니다.

http://localhost:8000/docs 에 접속하여 Request Body 의 형태에 알맞게 데이터를 전달해주면 Response Body 로 inference 결과가 잘 반환되는 것을 확인할 수 있습니다.

3.2 curl 이용

FastAPI 의 Swagger UI 를 이용하지 않고 다음과 같이 curl 을 이용하여 API 가 잘 작동하는지 확인하는 방법도 있습니다.

curl -X POST http://localhost:8000/predict -H "Content-Type: application/json" -d '{"sepal_length": 6.7, "sepal_width": 3.3, "petal_length": 5.7, "petal_width": 2.1}'

위의 명령어를 실행하면 다음과 같이 주어진 데이터에 대한 모델의 예측 결과 ({"iris_class":2}) 를 잘 반환해 주는 것을 확인할 수 있습니다.

{"iris_class":2}