몇 달 전 부터 질질 끌고오던 개인 프로젝트가 있었는데 해결이 되지 않아 새로운 프로젝트를 찾는 중에 넘블에서 FastAPI를 사용하여 서버를 구축하는 프로젝트가 있었다.
FastAPI는 사용해 본 적이 없었지만 궁금했던 차에 평소 Flask에 익숙했던 나는 비슷한 FastAPI를 선택했다.
1. 시작
안내 페이지에서 어떤 것을 구현해야 하는지 자세히 설명을 해 주었지만 막상 프로젝트를 시작한 뒤에는 이 페이지를 즐겨찾기 해놓고
모든 내용을 검색해야했다.
'모델 서빙'이 무엇인지 부터 알아야했다. 인공지능 부트캠프에서 머신러닝과 딥러닝 모델에 대해서 학습은 했지만 '서빙'에 대해 학습한 적이 없었다. 검색해서 훑어보니 말그대로 serving. 식당에서 종업원이 손님에게 음식을 서빙해주는 것과 비슷한 느낌이였다.
학습된 모델을 서버에다 요청하면 서버에서 전달해주는 것이다. Tensorflow serving server, Torch serve 같은 것들이 이런 기능을 한다.
2. 구축
이제 서버를 구축해야 하는데 v2 인퍼런스 프로토콜은 무엇인가... 하면서 또 검색.. 다행히도 나는 팀으로 진행됐고 팀원분과 일주일에 한번 정해진 시간에 서로 공부한 것을 공유하고 질문을 하면서 문제를 해결했다. (주로 내가 많이 물어봄.. 팀원분 감사합니다)
친절히 홈페이지에 REST가 있었고 이것을 가져와서 구현하면 됐었다.
또 다른 큰 난관은 딥러닝 모델을 어떻게 가져올 것인가 하는 문제였는데 팀원분께서 맨 처음에 huggingface라는 곳을 알려주었고 이곳에서 마음에 드는 QA transfomer 모델을 다운받았다. 결론적으로 이 모델을 사용하진 못했다...
나는 tensorflow serving server를 이용하여 fastapi 서버에서 api를 호출하면 텐서 서버 api를 불러오는 것으로 처음에는 시작했는데 prediction의 값만 돌려주는 서버 예시가 대부분이였다. 가이드라인의 구현조건인 모델 버젼과 모델 메타데이터 같은 정보를 가져올 수 없어서 결국 huggingface에서 제공하는 API를 사용했다.
가이드에서 제시한 REST는 어찌어찌 구현하였지만 Docker를 빌드 하는 과정에서 API 토큰 값이 들어있는 config.py 파일을 처리가 되지않아 계속 에러가 났고 결국엔 이 파일도 다 빌드하면서 에러는 해결되었다. 도커는 부트캠프 이후에 다시 사용해보았는데 그때는 진짜 이해가 안됐는데 이후 도커를 잠깐 학습한게 도움이 되었다. 역시 모르는 것은 시간이 해결해 준다. 하지만 컨테이너 환경에서 실행은 성공하지 못했다.
3. 배포
배포는 익숙한 AWS EC2를 선택했다. 최근까지 팀 프로젝트에서 사용했고 그동안 많은 삽질을 통해 이제는 인스턴트 쯤은 만들 수 있게 되었다. ubuntu 접속까지 하여 fastapi 서버를 띄우는 것 까진 성공했는데 nginx가 남아있었다.
정말 친절한 영문(?)으로 된 페이지가 있었고 내가 원하는 것을 1부터 차근차근 설명해 놓았다. 또 여기서 저 API 토큰이 말썽이였다. config.py 안에 들어있는 토큰값을 그대로 내보낼 수 없었기에 .env 파일을 만들어서 그 안에 값을 넣어주고 fastapi에서 제공하는 라이브러리를 통해 토큰 값을 불러왔는데 그 값을 찾을 수가 없단다. 검색해보니 나와 똑같이 에러나는 사람..당연 외국인이였고 답변을 몇 번 씩이나 읽었는데 이해할 수 없었다. 그냥 .env 파일을 추가해 주라는 것뿐. 여기서 갑자기 뭔가가 떠올랐고 unbuntu에 .env파일을 만들어 추가해줬더니 드디어 ec2로 서버를 돌릴 수가 있었다!! nginx는 차근차근 하라는대로 했더니 바로 되버렸다. 마침내 nginx로 fastapi를 배포했다.!!
4. 미해결
4.1 HTTP Method 문제
fastapi의 POST method를 가진 URL로 보내면 계속 GET으로 들어간다. 검색해보니 BaseModel을 사용해야 한다고 해서 그렇게 해 주었는데 fastapi/docs에서 POST를 보내면 잘 되는데 로컬에서는 죽어도 안된다. @app.post로 지정했는데 대체 왜 그러는지 진짜 모르겠다.
4.2 도커 컨테이너의 기능
fastapi 서버를 이미지로 생성하고 컨테이너를 실행했는데 이것을 그 이후에 어떻게 사용해야 하는 것인가?에 대한 의문이 생겼다.
서버는 nginx에서 돌아가는데 그럼 컨테이너는 어떤 기능을 하는지 잘 모르겠다. 프로젝트가 끝나면 도커에 대해 처음부터 학습해야겠다.
4.3 CI/CD
이것은 아예 손도 대지 못했다. 예전에 검색해서 알아본 바로는 서버 내에 변화가 있으면 이것을 서버에 바로 적용하여 자동으로 수정 배포 해주는 것으로 알고있는데 여태까지 한번도 해본적이 없었는데 이번에도 또 못했다. 이것은 프로젝트가 끝나더라도 꼭 해봐야겠다.
5. 정리
부트캠프가 끝나고 꽤 시간이 흘렀다. 그동안 백엔드 개발자를 준비하면서 정말 그만둬야 하나 싶은 고비들도 많았지만 어떻게든 문제를 해결하려고 고민하고 있는 내 모습이 보였다. 그동안 막연히 무엇을 만들고 싶어 여러가지 시도는 있었지만 완성한게 없었다. 이번 프로젝트를 통해 개발자가 되기 위해 계속 나아갈 수 있는 또 다른 계기가 되었다. 가이드라인은 내가 할 일들을 알려주었고 이것들을 하나씩 구현하고 문제를 해결하면서 '무엇을 모르는가'에 대한 '무엇을' 알아갈 수 있었다. 3주라는 시간이 있었지만 아르바이트를 병행하면서 구현은 시간이 오래걸리지 않았지만 컨테이너로 어떻게 실행하는지, CI/CD를 구현하지 못한게 제일 아쉽다. 이 프로젝트가 끝나더라도 4의 문제점들을 꼭 해결할 것이다. 그리고 모르는 것을 항상 친절하게 대답해주신 팀원분께도 정말 감사하다는 말을 드리고싶다.
'reflection' 카테고리의 다른 글
인증완료! 프론트엔드 구현! (0) | 2022.07.19 |
---|---|
DB 연결 (0) | 2022.07.13 |
API 구현 완려! (0) | 2022.07.07 |
200 OK (0) | 2022.07.06 |