해당 글에서는 FastAPI를 활용하여 머신러닝 모델을 로컬환경에서 실행까지의 실습을 담았습니다.
다음 포스트에 해당 FastAPI 프로젝트를 클라우드 환경에서 배포까지를 다루겠습니다.
https://github.com/gdsc-ssu/2024_mlops

FastAPI는 파이썬을 기반으로 한 프레임워크로 제가 경험했던 다른 프레임워크와 달리 상당히 간결하고 빠르다는 장점이 있어 FastAPI로 결정을 했습니다.
FastAPI에 대한 자세한 설명은 공식문서를 참고하는 편이 좋습니다.

공식문서에서는 모듈을 각각 설치하지만 실습을 진행하기 위해서 일일히 설치하기 보다는 pip install "fastapi[all]"을 사용하는 것을 권장드립니다.
공식문서 상에서 uvicorn을 설치하라합니다. uvicorn은 무엇일까요? uvicorn에 대해 알기 위해서는 CGI, WSGI, ASGI를 알고 지나가야합니다.

공식문서 예시를 변형한 간단한 RESTfulAPI입니다.
app = FastAPI()
'FastAPI' 클래스의 인스턴스를 생성해 앱 객체를 초기화합니다.
@app.get("/")
루트 URL('/')대한 GET 요청을 처리하는 엔드 포인트로 "Hello: Gdsc"라는 JSON 응답을 반환합니다.(GET 요청에 대한 설명은 해당 포스트를 참고해주세요)
@app.get("/home")
위와 같이 home URL('/home')에 대한 GET 요청을 처리하는 엔드 포인트입니다.

uvicorn main:app --reload 명령어를 통해 실행시킬 수 있습니다.
이때 main:app에서 main 은 파일명, --reload 플래그는 개발 중 코드가 변경될 때마다 자동으로 서버에 갱신이 된다는 의미입니다.
http://127.0.0.1:8000를 통해 결과를 확인할 수 있습니다.

read_item 함수는 "/items/{item_id}" URL에 대한 GET 요청을 처리합니다. URL의 일부로 item_id를 경로 매개변수로 받고, 선택적 쿼리 매개변수 q를 받을 수 있습니다. 매개변수를 JSON 객체로 반환합니다.
좀 더 쉽게 풀어 설명하면 item_id는 int 형태로 받게끔 지정하고 q는 문자열로 혹은 없게끔 할 수 있게 구성했습니다. 따라서 위의 예시처럼 url을 구성하면 위와 같은 결과를 얻을 수 있습니다.

http://127.0.0.1:8000/docs에서 작성한 api를 확인할 수 있습니다. 각 api의 세부 사항에서 실제로 파라미터, 바디 값을 넣어주고 그 결과 또한 확인할 수 있습니다.
pydantic은 내장된 type hint 구문을 사용해 각 변수 유형을 결정하는 모듈입니다. type hint를 사용한 데이터 유효성 검사를 통해 출력 모델의 유형과 제약 조건을 보장합니다.

pydantic에서 객체를 정의하는 것은 BaseModle에서 상속되는 새 클래스와 만드는 것과 상당히 유사합니다.
위의 예시에서는 name이라는 속성은 문자열로, price는 float형으로, is_offer은 boolean 혹은 None으로 설정하고 디폴트 값으로는 None을 설정하는 것을 알 수 있습니다.


p.s. type hint란?
Python 3.5에서부터 제공되는 변수, 함수 매개변수, 반환 값 등의
데이터 유형을 명시적으로 선언하는 프로그래밍 관행입니다.
앞서 설명드렸던 속성의 type hint를 지정함과 동시에 데이터 범위 또한 설정 가능합니다.


앞선 예시들에서 BaseModel을 통해 유효성 검사를 진행한 것과 같이BaseSettings를 상속한 클래스를 통해 TypeHint로 주입된 설정 데이터를 검증 가능합니다.
Field 클래스의 env 인자를 통해 환경변수로부터 필드를 오버라이딩 할 수 있습니다.

위의 개념들을 활용하여 api를 작성해봅시다.
이제 api를 만들 수 있게 되었으므로 학습 된 모델을 가져와야합니다. Joblib 모듈의 dump/load 함수를 통해 케라스, 텐서플로우, 파이토치 등으로 학습한 모델을 저장하고 불러올 수 있습니다.


dump 함수를 통해 저장한 모델을 현재 작업하는 디렉토리에 위치시키고 model을 로드해줍니다.
저와 같은 경우에는 사용자의 개인정보를 받아 대출 한도 금액을 산정하는 모델을 사용했습니다.
해당 모델에 들어갈 데이터를 BaseModel을 상속 받아 LoanApplication 객체를 생성해주었고 모델에서 반환할 데이터를 predict_output 객체로 생성해주었습니다.
해당 모델은 입력값으로 앞서 정의한 LoanAppication 형태의 값을 받게끔 지정했고 입력데이터를 데이터 프레임으로 바꿔 모델의 추론 함수를 통해 예측결과를 반환하였습니다. 이때 "한국은행_기준금리"를 "한국은행 기준금리"로 바꿔준 까닭은 빈칸은 알아서 언더바로 바꿔주기 때문에 전처리를 해준 것입니다.

그 결과 Swagger를 통해 확인했을 때 잘 나오는 것을 확인할 수 있습니다!
여기까지 첫번째 포스트를 마무리하고 다음 포스트에 NGINX, DOCKER을 활용해 배포를 하는 내용까지 다뤄보도록 하겠습니다.
https://fastapi.tiangolo.com/ko/
https://docs.pydantic.dev/latest/concepts/models/
https://www.daleseo.com/python-typing/
https://data-newbie.tistory.com/836
https://lsjsj92.tistory.com/648
https://velog.io/@yh20studio/CS-Http-Method-%EB%9E%80-GET-POST-PUT-DELETE
https://medium.com/@neeraztiwari/understanding-sync-vsasync-rest-apis-with-fastapi-a-comparative-guidee8e95579db44