딥러닝 모델 웹 서빙 조사 & Flask로 API 작성하기
현재 지식?
- 사전지식 아예 없음. Flask, React, node.js 등등 그게 뭔지도 모름
- 딥러닝 모델 python으로 만드는거만 알고있음
- 서빙까지는 안하면서도 나름대로 유저 입력받아서 띄우기 위해서, streamlit까지만 사용해본 상황.
- GET, POST 이런것도 모름
왜 공부하는가?
- 내 모델 도대체 어떻게 서빙하는가.
- 지금 짜놓은 것 = streamlit으로 subprocess 파서 하는거... 과연 이게 최선인가. 너무 야매같다.
TODO List
- 웹으로 돌리게 하고싶은데, 모델 서빙은 어떻게 하는거지? 프론트, 백엔드가 뭐지? 서버는 뭐지? 알아보자
- Python API? Flask? 뭔지 좀 살펴보기
- 적당한거 골라서 직접 해볼거다. Flask 예제코드 해보고, 내거 어떻게 적용할지 해보기
아직 작성중이고.. 포스팅 해놓고 수정하고 있다.
글을 다 적을 쯤에는 결과물이 나오길.
공부 내용 1: 개념 알기
딥러닝 모델을 만들었으니 이제 사용해야한다.
혼자서 사용하는건 상관 없는데 일일이 돌리는 것도 한계가 있지. 아무튼 배포를 해야한다.
그런데 코드와 pretrained model을 통째로 주자니 코드나 데이터에 대한 보안, 경로 변경되는 문제가 있다.
따라서, 추론 요청(입력)이 들어오면 출력을 뱉어주는 서버가 필요하다.
클라이언트는 보통 서버에 'API'를 이용해서 요청을 보낸다.
API는 특정 기능을 요청하기 위한 인터페이스라고 한다.
* 참고
Application Programming Interface(애플리케이션 프로그램 인터페이스)의 줄임말. API의 맥락에서 애플리케이션이라는 단어는 고유한 기능을 가진 모든 소프트웨어를 나타냅니다. 인터페이스는 두 애플리케이션 간의 서비스 계약.
API를 개발해야 하는데, 이걸 도움을 주는게 바로 Web Application Framework라고 한다.
- 귀찮으니 그냥 줄여서 Web Framework라고 보통 말하는 것 같다.
- Python의 Web Framework 중에서 유명한건 Django와 Flask가 있다. 아마도 이름은 들어봤을거다.
- FastAPI도 많이 쓰는 파이썬 웹 프레임워크다.
내가 모델을 열심히 개발했다고 하자. 파이썬 스크립트, 혹은 프로그램이다.
이걸 사용할 수 있게 하는 특정 인터페이스를 제공할 경우, 애플리케이션으로 만들 수 있다.
저런 것들의 도움을 받아 'API' 형태의 인터페이스를 만들면 API는 모델링 서버에서 작동하게 된다.
클라이언트는 API호출을 통해 서버에 요청을 보내고 응답을 받게 된다.
암튼 API를 만들어야 내 모델의 웹서빙이 가능하고, 그걸 도와주는 웹 프레임워크에 대해 공부해야하는구나. 이렇게 이해하면 되겠다.
이런 API 설계하는 방법이 매우 다양한데, 거기서 제일 유명한 방식이 REST API, RESTful API이라고 한다.
그중에서도 파이썬으로 API 개발하는데에 많이 쓰는게 Django REST Framework와 Flask RESTful라고 하는데... 자세한건 아래 링크 모아둔거 참고.
Q. 갑자기 생기는 의문. '모델링 서버'를 만든다는건 인퍼런스 요청을 받고, 응답을 한다면 데이터는? 데이터도 보내는건가?
-> HTTP프로토콜과 GET, POST를 몰라서 생긴 의문인걸로....
Web Framework?
종류가 많은 것 같은데 아래 3개가 자주 보이는듯하다.
Django: Framework 및 파이썬 언어에 대한 이해가 필요
Flask: Web application 개발에 필요한 뼈대만 있음. 필요하면 모듈을 직접 개발하거나 설치해서 사용 가능
FastAPI: FastAPI는 파이썬에 익숙한 사람들에게 좋은 언어라고 한다. 성능 빠르고 비동기 지원.
* 참고
Framework 단어를 자주 보니까 갑자기 프레임워크가 뭔지 또 헷갈린다.
프레임워크, 라이브러리, 애플리케이션, 모듈 등등... 단어 뜻을 정확히 짚고 넘어가자.
또한, API 개발에서 꼭 구현해야하는 4가지가 있다고 한다.
CRUD
- Create, Read, Update, Delete의 약자
- 웹앱이나 API 구현 시 가장 일반적으로 구현해야하는 기능으로, 매우 중요
그럼 이제 개념은 대략 알 것 같으니 바로 API 예제 찾고, Flask라는걸 해볼까? 했다.
하지만 Flask 튜토리얼 글을 읽다보니 GET, POST가 뭔지 정확히 모르니까 이해가 안감. HTTP까지는 알아보고 넘어가는게 좋겠다.
HTTP 프로토콜?
링크 기반으로 요청 보내고 데이터 보내고 응답받고.. 뭐 그러겠다는 것.
- http://www.주소주소.com/~~~~~~~~ 이런 형태에 익숙하지 않은가.
- http라는 링크 기반 프로토콜로 쓸게. 이런 ip주소 (DNS에서 알파벳 주소가 ip주소로 바꿔주는 역할이던가... 그럴거임)에 접속할거라는 뜻. 그리고 뒤에 알파벳이나 숫자같은걸로 뭘 전달하는 것 같던데... 더보기
GET, POST는 뭐지?
Http 프로토콜이 제공해주는 7가지 메서드가 있다.
그중에서 웹서비스 개발에 주로 사용하는게 GET 메서드와 POST 메서드이다. 요청을 보내는 역할이기 때문이다.
앞서 의문이 들었던 것 처럼 요청할때 자원을 같이 보내는게 필요하다.
http 패킷에 HEAD & BODY가 있는데 body를 쓰느냐 마느냐 차이가 GET과 POST의 차이인듯 하다.
참고로, 헤더에는 7가지 HTTP 메서드 방식중 무엇을 썻는지, 클라이언트의 정보, 브라우저 정보, 접속할 URL 등등 과 같은 클라이언트 정보가 있다. 바디는 보통 비어있긴 한데 POST 메서드에서는 사용하나봄.
참고자료 & 읽어본 글: 읽기 추천하는 순서대로 작성
개념 관련
- 전반적인 개념 관련: https://dataplay.tistory.com/42 / 이걸 가장 먼저 읽는게 좋다. 많이 참고한 글이고, 클라이언트와 서버의 개념부터 시작함.
- HTTP 프로토콜이 뭔지, 7가지 메서드는 뭐가 있는지. https://shlee0882.tistory.com/107
- 7가지 메서드 중에서 가장 자주 쓴다는, GET과 POST가 무엇인지 알아보는 글 https://mommoo.tistory.com/60
- FastAPI로 CRUD 개발하기 https://dataplay.tistory.com/43
- (그냥 상식으로) REST API? RESTful API? 그게 뭔지, 뭔 차이인지 https://dev-coco.tistory.com/97
- (그냥 상식으로2) React란? https://hymndev.tistory.com/45
- 이 글은 React 등장 전에 컴공 수업때 다뤘을법한 1세대 프론트, jquery같은 2세대를 거쳐 react가 어떻게 나왔는지 설명하고 있다.
- 내 경우는 유저가 클릭도 하고 결과 받아보도록 이쁘게 디자인된 프론트엔드가 필요하고, 백엔드 서버도 필요하고, 모델 서빙도 필요하다. 그래서 프론트 상식을 알아보기 위한 글을 찾은 것.
- 내 상황 맥락을 좀더 적어보자면... segment anything만 사용할때는 여기서 이미 python API를 제공하는 경우라서 그냥 백엔드에 때려넣어 함수 호출해서 쓰면 그만이다. 근데 이제는 써야하는 모델도 여러가지고, 전처리 후처리 등이 복잡해서 모델 서버를 따로 만드는게 나을 것 같다.
2. API 구현.. 어떻게 생긴건지 알아보자
본격적으로 API 개발을 알아보려고 웹 프레임워크들을 좀 찾아보려고 한다.
FastAPI, Django, Flask등이 여기에 해당된다. 일단 나는 Flask 해보려고 한다.
누군가가 간단하게 작성한 예제코드를 따라하고 어떤 느낌인가 살펴보려고 한다.
이제 해야할 것!
- 딥러닝 아닌 매우 간단한 Flask API 간단하게 만들어보고
- 딥러닝에서 사용한 예제를 좀더 찾은 다음,
- 내것에 적용하는 시도 해볼 예정이다.
- 중간중간에 다른 개념이나 서빙도구들 조사 해보면서.
Flask 해보자
이 링크에 있는걸 따라해볼거다. 일단 환경 셋업부터.
Flask로 간단한 API 만들어보기 https://problem-solving.tistory.com/9
Ubuntu에 아나콘다 설치
설치방법: https://velog.io/@tube-jeonghoon/Ubuntu%EC%97%90-anaconda-%EC%84%A4%EC%B9%98%ED%95%98%EA%B8%B0
환경변수 추가: https://jongsky.tistory.com/21 4번 참고
wget https://repo.anaconda.com/archive/Anaconda3-2023.09-0-Linux-x86_64.sh
sudo apt install zsh
zsh (다운받은 파일명)
conda 환경 만들고 flask 설치하여 간단한 엔드포인트 만들어보는 예제를 해봤다.
엔드포인트?
- API 서버가 제공하는 통신 채널
- 프론트엔드 등의 클라이언트가 백엔드 API 서버와 통신할 때, 엔드포인트에 접속하는 형태로 통신한다.
- 각 엔드포인트는 고유의 URI 주소를 가지며, 이 주소를 통해 엔드포인트에 접속할 수 있다.
단순히 데이터를 받아오는 요청할때 쓰는 GET 메소드를 사용해보자.
(블로그 글 그대로 따라했음)
실행 확인해보자.
방법1: 브라우저로 접속해보자
GPU 서버에서 돌리고 있기 때문에 포트포워딩 해줘야한다.
5000번에다가 flask 서버를 뛰워놨고 노트북에도 5000번 포트로 연결해줬다.
ssh -L 5000:localhost:5000 계정@ip.주소.적어.주기 -p [ssh 접속 port]
방법2: 터미널에서 HTTP 요청을 보내서 응답을 받아보자
httpie라는 라이브러리를 사용한다. apt install ㄱㄱ
이렇게 http 요청을 보냈고, hello world라는 응답을 받았다.
백엔드 API 서버 실행한 화면. 요청 온게 이렇게 찍힌다.
Post 방식도 해보자.
from flask import Flask, jsonify, request
app = Flask(__name__)
@app.route("/hello", methods=['GET'])
def hello():
return "hello world"
@app.route("/sign-up", methods=['POST'])
def sign_up():
user = request.json
response = {
'name': user['name'] + " 님",
'email': user['email'],
'password': user['password'],
'profile': user['profile'] + " 이것은 프로필"
}
return jsonify(response), 200
POST 방식으로 요청하면서 이름, 이메일 등을 입력해서 보냈더니,
백엔드 API 서버에서 이름에 ~님, 이것은 프로필!이라고 붙여서 응답을 해줬다.
오. 그러면 이제 요청에 맞춰 딥러닝 모델 돌리도록 POST 함수만 만들어주면? 어떻게 될 것 같다는 느낌이 든다!
파일 전송하는거 고려하지 않고 내 경우 입출력이 어떻게 되는지 생각해봤다.
입력
- 데이터 id: '비디오이름_회차번호_프레임번호' 형식
- 선택 id: SAM의 3개의 proposals 중에서 뭘 사용할지. 0,1,2 중 택1
- 클릭 좌표점 x,y값: 원래 클릭으로 받은거긴 한데 이건 프론트 서버에서 넘겨줄것임.
모델서버 테스트 할때는 그냥 임의의 x,y값 넣을거다.
출력
- SAM 먼저 돌리고, 다음 모델들이랑 전처리 후처리 적용해서 비디오까지 생성할거다.
- 모델2와 모델3의 결과 비디오 경로 각각을 리턴하자
이대로 그냥 만들면 될 것 같기는 한데, 그래도 다른 사람들 구현이 궁금하니 Flask + 딥러닝 (이왕이면 pytorch) 예제 코드를 좀더 찾아보는게 좋겠다.
아래 링크 글을 봤는데, httpie 대신에 postman을 쓰면 HTTP 요청을 커맨드로 하지 않아도 되고 더 보기 편해보인다. 한번 사용해보자.
참고자료 & 읽어본 글
- 기본 개념
- 엔드포인트? API? https://velog.io/@pengoose_dev/API%EC%99%80-EndPoint-%EC%B0%A8%EC%9D%B4.
- API, endpoint 설명 추가 https://blog.naver.com/ghdalswl77/222401162545
- 튜토리얼
- Flask로 간단한 API 만들어보기 https://problem-solving.tistory.com/9
- 개발 예시
- Flask API 개발 (2022/10/12 글, keras, 동영상 입력) https://velog.io/@midoi327/PythonFlask-%ED%94%8C%EB%9D%BC%EC%8A%A4%ED%81%AC%EB%A5%BC-%ED%99%9C%EC%9A%A9%ED%95%9C-%EB%94%A5%EB%9F%AC%EB%8B%9D-AI-%EB%AA%A8%EB%8D%B8-%EC%84%9C%EB%B9%99
- Postman을 사용하자 https://sw-test.tistory.com/45
3. 내 환경에서 해보기
내 환경
- IDC GPU 서버 사용중, CLI 환경 / 도커 컨테이너로 Flask 모델 서버를 띄워놓을 것임
- 개발과 확인은 맥북에서
자꾸 연결은 되는데 데이터가 없다고 떠서 당황했는데, 이렇게 하면 된다.
1. 도커 컨테이너 만들때 or DockerFile 작성할때 port를 제대로 지정하기
docker run --gpus='device=3' -p 5001:5001 --init --rm --name flask_sghong --shm-size 32G -v $(pwd):/workspace -it [이미지_이름]
2. flask 실행 시 host를 0.0.0.0으로 지정하기
그러면 맥북 브라우저에서 http:/서버ip주소:5001/hello 이런식으로 접속 가능하다. 물론 localhost로도 가능.
FLASK_APP=app.py FLASK_DEBUG=1 flask run -p 5001 -h 0.0.0.0
3. 포트포워딩 해주기
ssh -L 5001:localhost:5001 계정@ip.주소를.입력.한다 -p [ssh 포트번호]
오 된다!
이제 딥러닝 모델을 얹고 있다.
데이터 id를 넣으면 딥러닝 모델 돌려서 결과 위치와 수행시간을 뱉도록 했다.
나머지 모델들도 쭉쭉 이어붙여야지.
참고자료
- 도커 컨테이너로 Flask 띄우기: https://velog.io/@rhee519/docker-flask-hosting
- 이전에 딥러닝 모델 셋업한 환경을 export 해뒀어서 이걸 새로 conda로 셋팅해야했다.
- conda env create --file [conda.yaml경로] -n [환경이름]
- conda 명령어 참고: https://areumdawoon.tistory.com/41
- opencv는 conda install -c conda-forge opencv
- or conda install -c fastai opencv-python-headless
4. Postman 사용과 함께 개발하기
브라우저에서 띄우는게 편한데 GET 밖에 안된다.. 귀찮음.
일일이 커맨드로 이렇게 치는 것도 귀찮다.
http -v POST http://127.0.0.1:5001/sam-vos-vi video_id=kim_1_044401
그래서 (아래 링크를 참고해서) postman을 설치했다.
노트북에서 실행중이고, 포트포워딩 해놔서 localhost로 접속 된다. 모델 서버는 별도의 GPU 서버.
나는 POST 메서드를 사용중이라 request.json 이렇게 정보를 받도록 구현했기 때문에, postman에서도
raw의 JSON 선택해서 작성해줬다.
Send 버튼을 누르면 모델 돌아가더니 정상적으로 동작한걸 알 수 있었다.
모델 돌리는 중이면 이렇게 Sending request...뜬다.
모델을 다 붙였다. 1분이나 걸리니 최적화 해야할듯.
좀 빠를 때도 있고...
끝!
이 글 쓰기 시작했을때의 목표를 달성한 것 같다.
참고자료
- Postman 설치 및 사용법: https://binit.tistory.com/17
참고자료
- torchserve 관련글
- 딥러닝 인퍼런스 서버 구축하기 글 2개가 있다. torchserve+ fastapi 사용. https://bitrader.tistory.com/620
- https://www.thedatahunt.com/tech-review/how-to-utilize-torchserve-1-overview
- 하게 된다면 참고 https://medium.com/mlearning-ai/use-torchserve-and-flask-to-deploy-your-model-as-a-web-app-6d612eccdcd7
그 외
- https://roytravel.tistory.com/363
- Flask RESTful API 개발 방법 https://mcauto.github.io/back-end/2018/10/11/how-to-use-flask-restful/
넣을 곳을 못찾아 따로 빼놓은 것
Q. 백엔드가 정확히 뭐지
Q. 리턴 뒤에 200은 뭐지?
FastAPI 패키지 설치... 매우 쉽다.
- pip install fastapi uvicorn[standard]
- FastAPI 설치와, fastapi를 서버로 실행시키기 위한 uvicorn이라고 한다.
모델 서빙 찾다보니 TorchServe라는게 있다.
- Facebook, AWS에서 개발
- pytorch 모델을 서비스하기 위한 것
- python 3.8 이상이어야 가능. docker, conda환경 모두 가능.