Flask 모델 서빙 - Flask model seobing

머신러닝, 딥러닝은 해보았는데 이걸 어떻게 웹 앱에서 서비스하지?

AI 서비스를 제공하는 웹 사이트를 만들기 위해서는 웹 서버가 필요하다.
서버를 만드는 프레임워크는 대표적으로 자바스프링, Django, node.js 등이 있지만
머신러닝 코드는 주로 python으로 짜기 때문에 AI 모델 또한 python으로 생성된다.
따라서 AI모델을 사용하는 웹 API를 만들기 위해 python 언어를 사용하는 flask 프레임워크를 사용하기로 했다. (모든 백엔드를 플라스크로 하는게 아니다! 기본 백엔드는 자바스프링 등을 쓰고, 딥러닝만 Api를 호출해서 플라스크 서버에서 하는 것이다.)

flask는 웹 서버를 만드는 간결한 프레임워크다. flask를 통해 AI 모델을 웹 서버 상에서 돌리도록 API를 만들 수 있다.

😊😊😊
이 글은 Anaconda, pycharm, google colab, kaggle 등에서 딥러닝을 할 수 있는 분과, 필요한 라이브러리를 install하고 import 할 수 있는 분이라고 가정하고 쓰여졌다.
😊😊😊

글의 순서는 다음과 같다.
1. Flask 개발환경 구축
2. .h5 또는 .pkl로 저장된 AI 모델 불러오기
3. Flask API 작성
4. json으로 응답하기
5. Postman으로 응답 테스트

1. Flask 개발환경 구축

나는 다음 글을 참고하여 그대로 개발환경을 설정했다.
시리즈 순서대로 쭉 따라가면 된다.

https://velog.io/@koeunyeon/차근차근-플라스크-강좌에-오신-것을-환영합니다

2. .h5 또는 .pkl로 저장된 AI 모델 불러오기

텐서플로우나 케라스로 만든 모델은 h5파일로 간단하게 저장할 수 있다.
model.save('모델이름.h5')를 사용하면 weight가 저장된 모델이 간편하게 파일로 저장된다.
Keras가 아닌 머신러닝이라면, python에서 제공하는 pickle 기능을 사용하면 된다.
모델을 저장하는 방법은 구글링하면 매우 많은 글이 나온다.

이렇게 저장된 AI 모델 파일들을 vscode에서 사용하도록 폴더에 넣어주자.

Flask 모델 서빙 - Flask model seobing

간편하게 찾을 수 있도록 app.py가 저장된 src 폴더 안에 두 개의 모델을 넣어주었다.

이제 코드로 이 모델들을 호출해주면 된다.

  • .h5모델을 호출하는 방법

Flask 모델 서빙 - Flask model seobing

 model = tf.keras.models.load_model('저장한모델.h5 경로')
 prediction = model.predict(입력값)

tf.keras.models.load_model()함수 안에 h5파일의 경로를 넣어주면 된다.
그리고 예측값을 predict 할때는 model.predict 함수를 사용하면 된다.
(입력값에 아무것도 안 주었으니 냅다 이것만 치면 당연히 에러남. 내 코드 중 일부를 가져온 것이다.)

모델이 어떻게 생긴건지, 제대로 불러져온건지 확인하기 위해서는 모델을 로드한 후에

model.summary()

를 치고 python 터미널에서 실행해보자!(오른쪽 버튼-> '터미널에서 python 파일 실행' 클릭) 모델이 잘 요약되어 나올 것이다.

predict 함수가 vscode에서 인식이 되지 않아서 혹시 모델이 호출이 안된건지 불안할 수 있다.(내가그랬음)
그러나 나중에 predict 함수를 실행해보면 잘 돌아가는 것을 알 수 있다 ㅎㅎ 걱정 노노

  • .pkl 모델을 호출하는 방법

Flask 모델 서빙 - Flask model seobing

 clf = joblib.load("저장된 모델.pkl 경로")
 predict = clf.predict(입력값)

joblib 라이브러리를 사용하여 모델을 로드한다. 이녀석 또한 predict가 인식되지 않아도 알아서 잘 돌아간다.

3. Flask Api 작성

python으로 작성된 딥러닝 모델을 코드 안으로 불러왔으니, 이제 웹 서버상에서 작동할 수 있도록 api를 만들어야 한다.
딥러닝 모델을 위한 flask api의 기본 프레임은 다음과 같다. 위 1번 글을 읽었다면 이 기본 프레임을 이해 할 수 있을 것이다.

딥러닝을 위한 Flask api 기본 프레임

@app.route("/model", methods=['POST']) 
def model():
    if request.method == 'POST':
        
        ~여기에 코드 작성(전처리, 모델 로드 등등)~
        
        result = 어쩌구

    return jsonify(result), 200

우리는 입력값을 받아 모델에 넣어서 예측값을 구하고, 이 예측값을 서버에 전달할 것이기 때문에 POST 메소드를 이용한다.
그리고 예측값(return값)을 Json 형식으로 내보낼 것이다.

이제 빈칸에 코드를 채워넣는다.

서버로부터 파일(이미지, 동영상, 텍스트 등) 받기

나는 동영상에서 프레임을 추출하여 모델의 입력값으로 넣어야 하기 때문에,
웹 서버로부터 동영상을 받아야 한다. 동영상을 받아서 내 로컬에 저장하자.

@app.route("/model", methods=['POST']) 
def model():
    if request.method == 'POST':

        file = request.files['video'] #파일 받기
        file.save('src/dataset/'+secure_filename(file.filename)) #로컬에 저장
        
		result = 어쩌구

    return jsonify(result), 200

두 줄이 추가되었다. request.files['키 값']을 통해 파일을 받고, save()를 이용하여 파일을 로컬 폴더에 저장한다. 나는 src/dataset 파일에 filename으로 저장했다.
(request, secure_filename 등을 사용하기 위해서는 필요한 라이브러리를 import 해주어야 한다. 여기서는 다루지 않음)

받아온 파일을 모델에 입력값으로 넣기

이제 필요한 파일을 웹에서 받아왔으니, 우리가 만든 모델에 넣어야 한다.
로컬에 저장된 파일을 내 입맞에 맞게 전처리 한 후에 predict()에 넣으면 된다.
동영상 파일을 받아 프레임을 캡쳐한 후 이미지로 바꾸는 방법은 다음에 글로 쓰겠다.

@app.route("/model", methods=['POST']) 
def model():
    if request.method == 'POST':

        file = request.files['video'] #파일 받기
        file.save('src/dataset/'+secure_filename(file.filename)) #로컬에 저장
        
        ~동영상을 이미지로 바꾸는 코드가 생략됨~
        
        img = cv.imread(img)
  		img = color.rgb2gray(img)
  		img = img.reshape(-1, 48, 48, 1) #입력값 전처리

  		model = tf.keras.models.load_model('model.h5') #모델 로드
  		prediction = model.predict(img) #예측값
        
        
		result = prediction #내보낼 값

    return jsonify(result), 200

몇 줄이 추가되었다. 여기에 쓴 코드는 데이터 전처리와 후처리 등을 빼놓고 아주 간단하게 작성한 코드이기 때문에, 이걸 그대로 따라쓰면 정말 아무것도 아니게 된다. 오류난다.
이 글을 읽는 사람은 딥러닝을 할 줄 아는 분이라고 가정하고 작성했다. 본인이 원하는 전처리 등의 코드를 이 안에 추가로 넣어주면 된다.

여기서 중요한 건,

  • request.files['키 값'] 으로 웹서버에서 파일을 받아온다.
  • file.save로 내 로컬에 파일을 저장한다.
  • 내 로컬에 저장된 파일을 이러쿵저러쿵 전처리 하고, model을 로드한다.
  • model.predict()로 로드 된 모델 안에 전처리된 입력값을 넣어준다.

4. Json으로 응답하기

위 코드의 마지막 줄이

return jsonify(result), 200

인 것을 확인했다. 웹 서버에서는 json으로 값을 주고받기 때문에 우리가 구한 출력값을 서버에 전달하기 위해서는 json으로 바꾸어주어야 한다.
jsonify()를 통해서 간단히 바꿔서 전달할 수 있다.

이로써

  • 웹에서 파일을 받아서
  • Flask api로 AI 모델에 돌려서
  • 출력값을 Json 형식으로 다시 돌려주기

까지 완성했다.
이게 정말 잘 돌아가는지는 POSTMAN으로 확인할 수 있다.

5. Postman으로 응답 테스트

포스트맨이 어떤 것이고 어떻게 사용하는지는 인터넷에 많은 글들이 있으니 참고하면 좋다. 매우 간단하니 겁먹지 ㄴㄴ

정성스럽게 작성한 app.py 를 디버깅없이 실행하고, Postman을 실행하자.

Flask 모델 서빙 - Flask model seobing

우리는 flask api를 다음과 같이 작성했으니

@app.route("/model", methods=['POST'])
  • Method 를 POST로 설정하고, 옆에 로컬 http와 /model 까지 꼼꼼히 작성해준다.
    그리고 mp4 등의 파일을 보낼 것이기 때문에

  • Body 에서 form-data를 누르고, KEY에 내가 원하는 키 값인 'video'를 써주고나면 옆에 형식을 고르는 게 생길 것이다. 거기에서 File을 선택하면

  • VALUE에 파일을 넣을 수 있는 칸이 생긴다. 나는 mp4 파일을 넣어주었다.

이제 준비 끝! 나는 http://로컬/model api를 POST 메소드로 호출하여 mp4 파일을 전송한 것이다. 응답이 제대로 오는지 보기 위해 파란 버튼인 Send를 눌러준다.

누르고 나면 밑에 Response가 어떻게 되었는지 결과가 나올 것이다.
Json 형식으로 답변이 온 것을 확인할 수 있을 것이다.

<--------------------------------------------------------------------------------------------------->

이렇게 내가 만든 AI모델을 웹 서버에서 실행시키기 위한 Api작업이 끝났다. 코드를 전체공개한 것이 아니기 때문에 여기 쓰여진 코드만 따라쓴다면 에러가 난다. 필요한 코드는 직접 추가해주어야 한다.

나처럼 "머신러닝, 딥러닝은 해보았는데 웹에서 어떻게 서비스하지?" 라는 의문을 가진 사람에게 조금이나마 도움이 됐으면 한다.

내 프로젝트가 끝나고 깨끗한 코드가 완성된다면 이 곳에 공개하도록 하겠다

안뇽!