1. Flask 정의
The python micro framework for building web applications -
https://github.com/pallets/flask
Micro Service Architecture(MSA)를 위한 Web App Framework입니다. 웹 앱 프레임워크는 말 그대로 웹 서비스 개발을 위한 프레임워크라고 생각하면 됩니다. Django 등 다른 framework에 비해 가볍고 확장성, 유연성이 뛰어난 프레임워크가 Flask입니다. 여기서는 간단한 기능을 가볍게 구현하기에 적합하기 때문에 대부분의 ML Model의 첫 배포 Step으로 Flask를 애용합니다.
2. Flask Install
python 3.6이상, pip3가 갖춰진 가상환경에서 수행하였습니다.
mkdir flask-tutorial
cd flask-tutorial
pip install -U Flask==2.0.2
3. Hello world! - Flask
app.py라는 파일을 생성해 아래 코드를 복사해 붙여놓고 이를 수행합니다. Flask를 사용해 간단한 웹 서버를 띄우는 것이 목표 입니다.
from flask import Flask
app = Flask(__name__)
@app.route("/")
def hello_world():
return "<p>Hello, World!</p>"
# debug 모드로 실행, 모든 IP 에서 접근 허용
# 5000 포트로 사용하는 것을 의미
if __name__ == "__main__":
app.run(debug=True, host='0.0.0.0', port=5000)
"python app.py"를 수행합니다. 아래와 같이 확인이 가능합니다.
4. Routing
flask에 route() 데코레이터는 python 함수를 web server의 URI에 mapping이 가능합니다. 원하는대로 Routing을 수행할 수 있는데, 아래 예시를 확인해보겠습니다.
app.py 파일을 아래 코드를 복사해 수행하겠습니다. 파이썬 데코레이터 부분위주로 확인하시면 됩니다.
from flask import Flask
app = Flask(__name__)
@app.route("/")
def hello_world():
return "<p>Hello, World!</p>"
@app.route("/fastcampus")
def hello_fastcampus():
return "<p>Hello, Fast Campus!</p>"
if __name__ == "__main__":
app.run(debug=True, host='0.0.0.0', port=5000)
그 이후 "python app.py"를 수행하고, @app.route("/fastcampus") 부분처럼 뒤에 URI 주소 뒤에 "/fastcampus" 추가하여 접속합니다.
5. Post Method
Flask의 route() 데코레이터는 URI 뿐만아니라 HTTP Method도 지정이 가능하기에, 이를 활용하면 원하는대로 API를 만들 수 있습니다. 아래와 같은 코드를 복사해 app.py를 만듭니다.
from flask import Flask
import json
app = Flask(__name__)
@app.route("/predict", methods=["POST", "PUT"])
def inference():
return json.dumps({'hello': 'world'}), 200 # http status code 를 200 으로 반환하는 것을 의미
if __name__ == "__main__":
app.run(debug=True, host='0.0.0.0', port=5000)
동일한 폴더에서 "python app.py" 를 수행해 application server를 로컬에서 띄우고 아래와 같은 curl를 수행합니다.
curl -X POST http://127.0.0.1:5000/predict
curl -X PUT http://127.0.0.1:5000/predict
curl -X GET http://127.0.0.1:5000/predict
post, put은 curl에 대한 응답이 정상적으로 나타남을 알 수 있습니다. 하지만 route()에서 GET부분은 method에 반영을 하지 않았기 때문에 error가 나타나는 것을 위 그림에서 알 수 있습니다.
6. Flask에서 사용할 모델 Train 및 Save
이제부터 Flask 매우매우 기본적인 부분들만 찍어먹어 봤습니다. 모든 기능을 살펴보는 것이 목표가 아닙니다. 따라서 샘플 ML 모델을 API 서비스로 서빙하고자 할 때 Flask를 사용하는 방법을 알아보겠습니다. iris 데이터로 간단한 분류 모델 학습 후 pickle로 모델을 저장합니다. 그담에 flask에서는 model.pkl 을 load해 predict하는 server를 구현하겠습니다.
아래 샘플코드를 train.py 로 저장합니다. ( * scikit-learn==1.0 을 미리 설치해주세요)
import os
import pickle
from sklearn.datasets import load_iris
from sklearn.ensemble import RandomForestClassifier
from sklearn.metrics import accuracy_score, classification_report
from sklearn.model_selection import train_test_split
RANDOM_SEED = 1234
# STEP 1) data load
data = load_iris()
# STEP 2) data split
X = data['data']
y = data['target']
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.3,
random_state=RANDOM_SEED)
# STEP 3) train model
model = RandomForestClassifier(n_estimators=300, random_state=RANDOM_SEED)
model.fit(X_train, y_train)
# STEP 4) evaluate model
print(f"Accuracy : {accuracy_score(y_test, model.predict(X_test))}")
print(classification_report(y_test, model.predict(X_test)))
# STEP 5) save model to ./build/model.pkl
os.makedirs("./build", exist_ok=True)
pickle.dump(model, open('./build/model.pkl', 'wb'))
"python train.py" 를 수행하면 아래와 같이 metric을 확인할 수 있습니다.
위 샘플 코드에서 step 5를 보면 build 폴더를 만들어서 model.pkl 파일을 생성시킵니다.
7. Flask 서버 구현
아래 샘플 코드를 복사해 "flask_server.py"를 만듭니다.
import pickle
import numpy as np
from flask import Flask, jsonify, request
# 학습한 모델 파일을 부르기
model = pickle.load(open('./build/model.pkl', 'rb'))
# Flask Server 를 구현
app = Flask(__name__)
# POST /predict 라는 API 를 구현
@app.route('/predict', methods=['POST'])
def make_predict():
# API Request Body 를 python dictionary object 로 변환
request_body = request.get_json(force=True)
# request body 를 model 의 형식에 맞게 변환
X_test = [request_body['sepal_length'], request_body['sepal_width'],
request_body['petal_length'], request_body['petal_width']]
X_test = np.array(X_test)
X_test = X_test.reshape(1, -1)
# model 의 predict 함수를 호출하여, prediction 값을 구함
y_test = model.predict(X_test)
# prediction 값을 json 화 시킴
response_body = jsonify(result=y_test.tolist())
# predict 결과를 담아 API Response Body 를 return
return response_body
if __name__ == '__main__':
app.run(port=5000, debug=True)
8. API Test
그 다음에 "python flask_server.py"를 수행합니다.
그 다음에 curl을 이용해서 데이터 샘플 하나를 predict를 시키면 아래와 같이 "2"라는 값을 리턴하는 것을 알 수 있습니다.
curl -X POST -H "Content-Type:application/json" --data '{"sepal_length": 5.9, "sepal_width": 3.0, "petal_length": 5.1, "petal_width": 1.8}' http://localhost:5000/predict
아주 간단하게 flask을 개념 익히고, iris 데이터로 한번 확인하였습니다. 실은 이 부분에 대해서 쿠버네티스 환경에서 배포하려면 추가적인 공수가 많이 들어갑니다. 이 모든 작업들을 도커 이미지로 다 말아서 도커 레지스트리에 푸시하는 일련의 과정들에 대해 디플로이 먼트도 고려해야합니다. 또한 서버에서 로드밸런서 활용해 할당받은 아이피, 도메인으로 접속해야하는 등 제가 분석일을 하면서 다른 개발자의 고충들도 간접적으로 느껴지는 것 같습니다.
다음 글에서는 seldon-core 로 찾아뵙겠습니다.
패스트캠퍼스 [직장인 실무교육]
프로그래밍, 영상편집, UX/UI, 마케팅, 데이터 분석, 엑셀강의, The RED, 국비지원, 기업교육, 서비스 제공.
fastcampus.co.kr
* 본 포스팅은 패스트캠퍼스 환급 챌린지 참여를 위해 작성되었습니다.
![]() |
![]() |
'AI > MLOps' 카테고리의 다른 글
[패스트캠퍼스 챌린지 21일차] Model Monitoring 개념 (0) | 2022.02.13 |
---|---|
[패스트캠퍼스 챌린지 20일차] Seldon Core (0) | 2022.02.12 |
[패스트캠퍼스 챌린지 18일차] Model Serving 개념 (0) | 2022.02.10 |
[패스트캠퍼스 챌린지 17일차] MLflow 튜토리얼 (2) (0) | 2022.02.09 |
[패스트캠퍼스 챌린지 16일차] MLflow 튜토리얼 (1) (0) | 2022.02.08 |