LLM 엔지니어링13장 · REST API 와 FastAPI6 / 22← 이전목차다음 →MetaContents

13장. REST API 와 FastAPI

모델을 애플리케이션과 잇기

빵집은 손님이 올 때마다 반죽부터 시작하지 않습니다. 아침에 구워 둔 빵을 진열하고, 주문이 오면 바로 내줍니다. 모델도 학습은 미리 해서 파일로 저장해 두고, 서비스는 그 파일을 한 번 불러 놓고 요청이 올 때마다 예측만 합니다.

모델을 앱 코드 안에 넣기, API 서버로 따로 띄우기, 미리 계산해 표에 저장하기의 세 가지를 견준 카드

왼쪽은 모델을 앱의 코드 안에서 바로 부르는 방법으로, 간단하지만 앱마다 모델과 라이브러리를 들고 있어야 합니다. 가운데는 모델을 API 서버로 따로 띄우고 여러 앱이 부르는 방법으로, 이 장에서 만듭니다. 오른쪽은 밤마다 모든 주문의 예측을 미리 계산해 표에 저장해 두는 방법(배치)으로, 실시간이 필요 없을 때 씁니다. 여기서 구워 둔 빵이 저장한 모델 파일입니다.

세 방법 견주기

방법좋은 점아쉬운 점맞는 때
코드 안에 넣기빠르고 간단하다앱마다 모델을 들고, 바꾸려면 앱을 다시 배포앱 하나, 작은 모델
API 서버여러 앱이 같은 모델을 쓴다. 모델만 따로 바꾼다네트워크 시간, 서버 운영여러 앱, 자주 바뀌는 모델, LLM
미리 계산(배치)요청 때 계산이 없다새 입력에는 답이 없다정해진 대상의 하루치 점수

모델을 파일로 저장하고 불러오기

scikit-learn 모델은 joblib 으로 저장합니다. 모델과 함께 판, 기준값 같은 정보도 사전에 담아 저장해 두면 API 가 함께 알려 줄 수 있습니다.

Python
import io
import joblib
from sklearn.linear_model import LogisticRegression

model = LogisticRegression().fit([[0], [1], [2], [3]], [0, 0, 1, 1])
buf = io.BytesIO()                                       # 예시라 파일 대신 메모리에 쓴다
joblib.dump({"모델": model, "판": "demo-1", "기준값": 0.5}, buf)
buf.seek(0)
saved = joblib.load(buf)                                 # 불러오면 학습한 모델이 그대로 돌아온다
print(saved["판"], saved["모델"].predict_proba([[2.5]]).round(3))

코드에 나오는 함수

코드쉬운 뜻
LogisticRegression().fit(X, y)로지스틱 회귀 모델을 만들고 학습한다. 여기서는 숫자 넷과 정답 넷의 아주 작은 예다
io.BytesIO()메모리 속에 만든 바이트 파일이다. 디스크에 파일을 남기지 않고 저장을 흉내 낸다
joblib.dump(객체, buf)객체를 바이트로 바꿔(직렬화) buf 에 쓴다
buf.seek(0)읽는 위치를 맨 앞으로 돌린다. 방금 쓴 끝에서 읽으면 아무것도 없다
joblib.load(buf)바이트를 읽어 원래 객체로 되살린다
predict_proba([[2.5]])predict probability(확률 예측)의 줄임이다. 입력 2.5 가 0 일 확률과 1 일 확률을 돌려준다
.round(3)NumPy 배열의 숫자를 소수 셋째 자리까지 반올림한다

이 코드가 뜻하는 것

게임을 저장하면 캐릭터의 레벨과 장비가 저장 파일에 들어가고, 다음에 불러오면 그 상태에서 바로 이어 합니다. 저장 칸에 "1장 보스 앞" 같은 메모를 붙여 둘 수도 있습니다. 여기서 캐릭터가 학습한 모델, 저장 파일이 joblib 으로 쓴 바이트(이 예에서는 메모리), 저장 칸의 메모가 판과 기준값입니다. 다만 게임 저장 파일과 달리 joblib 파일은 불러올 때 안의 코드가 실행될 수 있어, 남이 준 파일은 함부로 불러오지 않습니다.

줄하는 일쉽게 말하면
model = LogisticRegression().fit(...)작은 모델을 학습한다캐릭터를 키운다
buf = io.BytesIO()메모리 속 저장 자리를 만든다빈 저장 칸
joblib.dump({...}, buf)모델과 판, 기준값을 사전으로 묶어 저장한다저장하면서 메모를 붙인다
buf.seek(0)처음부터 읽을 준비를 한다저장 파일을 맨 앞부터 연다
saved = joblib.load(buf)저장한 사전을 되살린다불러오기
print(saved["판"], ...)판과 2.5 의 예측 확률을 보인다메모와 캐릭터 상태 확인

실행하면 demo-1 [[0.277 0.723]] 이 나옵니다. 앞의 0.277 은 0 일 확률, 뒤의 0.723 은 1 일 확률입니다. 2.5 는 정답이 1 인 2, 3 쪽에 가까워서 1 일 확률이 더 높게 나왔고, 불러온 모델이 학습한 그대로 예측한다는 것을 보여 줍니다.

주의할 점

  • joblib, pickle 파일은 불러올 때 그 안의 코드가 실행될 수 있습니다. 믿을 수 있는 곳에서 만든 모델 파일만 불러옵니다.
  • 저장할 때와 불러올 때의 scikit-learn 판이 다르면 경고가 나거나 결과가 달라질 수 있습니다. 판을 함께 기록합니다(실습 1).
← 이전 절13장 · RESTful 설계다음 절 →13장 · FastAPI 의 기본