개요
현재 4-2 캡스톤 프로젝트에선 매수 알림 기능을 위해 pytorch로 만들어진 모델을 서빙해주는 프레임워크가 필요했다.
그 역할에 제격인게 바로 같은 Python 프레임워크인 Fastapi였다.
본격적으로 모델을 만들기 전에 테스트로 어떤 식으로 동작하는지 알고 싶었고 간단하게 Iris dataset을 Random Forest 방법으로 학습시켜 만든 모델로 진행하였다.
모델
import joblib
from sklearn.datasets import load_iris
from sklearn.ensemble import RandomForestClassifier
# Load the iris dataset
iris = load_iris()
X, y = iris.data, iris.target
# Train a random forest classifier
model = RandomForestClassifier()
model.fit(X, y)
# Save the trained model
joblib.dump(model, 'model.joblib')
Fastapi
from fastapi import FastAPI
import joblib
import numpy as np
from sklearn.datasets import load_iris # 추가
app = FastAPI()
# Load the trained model
model = joblib.load('model.joblib')
# Load the iris dataset
iris = load_iris() # 추가
@app.get("/")
def read_root():
return {"message": "Welcome to the ML Model API V2"}
@app.post("/predict/")
def predict(data: dict):
features = np.array(data['features']).reshape(1, -1)
prediction = model.predict(features)
class_name = iris.target_names[prediction][0]
return {"class": class_name}
만들어진 모델을 실고 /predict 라우터에 post 요청으로 딕셔너리 데이터가 도착하면 해당 데이터가 어떤 이미지인지 클래스 값을 리턴으로 돌려준다.
Docker
# Use the official Python image
FROM python:3.9
# Set the working directory in the container
WORKDIR /app
# Copy the local code to the container
COPY . .
# Install FastAPI and Uvicorn
RUN pip install --no-cache-dir -r requirements.txt
# Expose the port the app runs on
EXPOSE 8000
# Command to run the application
CMD ["uvicorn", "main:app", "--host", "0.0.0.0", "--port", "8000"]
우리의 프로젝트에선 모든 서비스를 컨테이너 단위로 올리기 때문에 도커 이미지로 만들어줄 필요가 있었다.
Docker hub upload
작동 test
Local에서 실행
/ endpoint로 접근
모델 호출을 위해 /predict로 접근
iris dataset중 setosa에 해당한다는 결과값을 받을 수 있었다.
AWS EC2에서 실행
Flow
보안그룹에서 8000 port tcp 연결 추가 → docker image pull 후 실행 → 브라우저에서 ip 단위로 접근 → 모델 호출
CI / CD
이번 프로젝트에서 devops 역할을 맡았기 때문에 만들어지는 모든 서비스를 자동으로 배포하고 싶었다.
CI / CD 도구로는 Github Actions를 선택하였고 아래는 그 과정들이다.
1. Github repo 환경변수 설정
2. .github/workflows 하위 디렉토리로 yaml 파일 push
name: Build to dockerhub and deploy to ec2
on:
push:
branches:
- main # exec when pushed main branch
jobs:
build:
runs-on: ubuntu-latest
steps:
- name: Checkout code
uses: actions/checkout@v2
- name: Set up Python
uses: actions/setup-python@v2
with:
python-version: '3.9'
- name: Install dependencies
run: |
python -m pip install --upgrade pip
pip install -r requirements.txt
- name: Build Docker image
run: |
docker build -t ${{ secrets.DOCKER_USERNAME }}/fastapi_test:v1 .
- name: Login to Docker Hub
run: echo "${{ secrets.DOCKER_TOKEN }}" | docker login -u "${{ secrets.DOCKER_USERNAME }}" --password-stdin
- name: Push Docker image to Docker Hub
run: |
docker push ${{ secrets.DOCKER_USERNAME }}/fastapi_test:v1
deploy:
needs: build
runs-on: ubuntu-latest
steps:
- name: Deploy to EC2
run: |
echo "${{ secrets.EC2_KEY }}" > ec2_key.pem
chmod 600 ec2_key.pem
ssh -o StrictHostKeyChecking=no -i ec2_key.pem ec2-user@13.124.230.180 << 'EOF'
docker pull ${{ secrets.DOCKER_USERNAME }}/fastapi_test:v1
docker stop my_fastapi_container || true
docker rm my_fastapi_container || true
docker run -d -p 8000:8000 --name my_fastapi_container ${{ secrets.DOCKER_USERNAME }}/fastapi_test:v1
EOF
작동 flow 및 테스트
개발자가 깃허브 레포지토리 메인 브렌치에 PUSH할 경우 그것을 트리거로 하여 Github Actions가 docker hub에 container를 빌드하고 최종적으로 EC2에 배포한다.
테스트
1. Fastapi Root router message 변경
2. Github push
ec2에서 확인 시 컨테이너가 재생성된 것 확인 및 버전 확인. V1에서 V2로 바뀐 것을 확인 가능하다.
'Backend > fastapi' 카테고리의 다른 글
[Fastapi] Https 적용 및 도커로 최종 배포 (0) | 2024.12.07 |
---|---|
[Fastapi] 웹소켓 구축 (0) | 2024.12.07 |
[Fastapi] non_transformer 모델 서빙 (0) | 2024.12.07 |
[Fastapi] 뉴스, 지수 크롤링 서버 구축 (3) | 2024.12.07 |