FastAPI로 머신러닝 모델 배포하기 (1)

유승한·2024년 1월 21일

모델 배포

목록 보기
1/1
post-thumbnail

여는 말

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

github 레포 주소

https://github.com/gdsc-ssu/2024_mlops

FastAPI란?

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

FastAPI 설치하기

공식문서에서는 모듈을 각각 설치하지만 실습을 진행하기 위해서 일일히 설치하기 보다는 pip install "fastapi[all]"을 사용하는 것을 권장드립니다.

uvicorn이란?(넘어가셔도 됩니다)

공식문서 상에서 uvicorn을 설치하라합니다. uvicorn은 무엇일까요? uvicorn에 대해 알기 위해서는 CGI, WSGI, ASGI를 알고 지나가야합니다.

  • CGI(Common Gateway Interface)
    CGI란 웹 서버와 외부 프로그램(ex - 파이썬 어플리케이션) 사이의 인터페이스 규약입니다. CGI를 통해 웹 서버는 다양한 프로그래밍 언어로 작성된 외부 애플리케이션 또는 스크립트와 상호작용하여, 동적 웹 페이지 생성, 파일 업로드 처리 등 복잡한 작업을 수행할 수 있습니다.
  • WSGI(Web Server Gateway Interface)
    CGI를 개선한 형태로 파이썬 전용으로 개발되었습니다. CGI의 각 요청에 대한 새로운 프로세스를 생성하는 비효율성을 WSGI는 프로세스/스레드를 재사용하는 형태로 개선하였습니다. 파이썬 웹 개발에서 표준으로 자리 잡았으며 Django Flask 등 대부분의 파이썬 웹 프레임워크에서 사용 됩니다.
  • ASGI(Asynchronous Server Gateway Interface)
    WSGI는 단일동기적처리만을 지원(web socket이나 긴 http 요청을 처리하기에 적합 x)하는 반면 ASGI는 단일비동기적처리를 (AsyncIO 라이브러리를 통해)지원합니다. 따라서 하나의 프로세스/스레드가 동시에 여러 요청을 처리할 수 있다는 장점을 가집니다.
  • uvicorn
    uvicorn은 uvloop와 httptools를 통해 ASGI 구현한 서버입니다.

FastAPI 맛보기

공식문서 예시를 변형한 간단한 RESTfulAPI입니다.

FastAPI 앱 인스턴스 생성

app = FastAPI()

'FastAPI' 클래스의 인스턴스를 생성해 앱 객체를 초기화합니다.

라우트(Endpoints) 정의

@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를 통해 결과를 확인할 수 있습니다.

GET에 값을 넘겨줘 보기


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

Swagger UI 확인하기


http://127.0.0.1:8000/docs에서 작성한 api를 확인할 수 있습니다. 각 api의 세부 사항에서 실제로 파라미터, 바디 값을 넣어주고 그 결과 또한 확인할 수 있습니다.

pydantic

pydantic은 내장된 type hint 구문을 사용해 각 변수 유형을 결정하는 모듈입니다. type hint를 사용한 데이터 유효성 검사를 통해 출력 모델의 유형과 제약 조건을 보장합니다.

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

p.s. type hint란?
Python 3.5에서부터 제공되는 변수, 함수 매개변수, 반환 값 등의
데이터 유형을 명시적으로 선언하는 프로그래밍 관행입니다.

pydantic - 데이터 범위 설정하기

앞서 설명드렸던 속성의 type hint를 지정함과 동시에 데이터 범위 또한 설정 가능합니다.

pydantic - BaseSettings


앞선 예시들에서 BaseModel을 통해 유효성 검사를 진행한 것과 같이BaseSettings를 상속한 클래스를 통해 TypeHint로 주입된 설정 데이터를 검증 가능합니다.

Field 클래스의 env 인자를 통해 환경변수로부터 필드를 오버라이딩 할 수 있습니다.

심화 예제


위의 개념들을 활용하여 api를 작성해봅시다.

모델(객체)의 pickle 파일 가져오기

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

간단한 모델 추론 api 만들어보기


dump 함수를 통해 저장한 모델을 현재 작업하는 디렉토리에 위치시키고 model을 로드해줍니다.

저와 같은 경우에는 사용자의 개인정보를 받아 대출 한도 금액을 산정하는 모델을 사용했습니다.

해당 모델에 들어갈 데이터를 BaseModel을 상속 받아 LoanApplication 객체를 생성해주었고 모델에서 반환할 데이터를 predict_output 객체로 생성해주었습니다.

해당 모델은 입력값으로 앞서 정의한 LoanAppication 형태의 값을 받게끔 지정했고 입력데이터를 데이터 프레임으로 바꿔 모델의 추론 함수를 통해 예측결과를 반환하였습니다. 이때 "한국은행_기준금리"를 "한국은행 기준금리"로 바꿔준 까닭은 빈칸은 알아서 언더바로 바꿔주기 때문에 전처리를 해준 것입니다.

그 결과 Swagger를 통해 확인했을 때 잘 나오는 것을 확인할 수 있습니다!

배포

여기까지 첫번째 포스트를 마무리하고 다음 포스트에 NGINX, DOCKER을 활용해 배포를 하는 내용까지 다뤄보도록 하겠습니다.

Reference

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

0개의 댓글