FastAPI로 AI 모델을 API 형태로 제공할 때는 단순히 모델을 실행하는 코드만 작성하면 부족하다.
사용자 요청을 받고, 입력값을 검증하고, 모델에 맞게 전처리한 뒤, 추론 결과를 안정적으로 반환하는 구조가 필요하다.
따라서 실제 프로젝트에서는 기능별로 코드를 나누어 관리하는 방식이 많이 사용된다.
1. AI 모델 API 서버의 기본 흐름
AI 모델을 통합한 API 서버는 보통 다음 흐름으로 동작한다.
- 사용자가 API 요청을 보낸다.
- 서버가 입력 데이터를 검증한다.
- 입력 데이터를 모델에 맞게 전처리한다.
- AI 모델이 추론을 수행한다.
- 결과를 JSON 형태로 반환한다.
이 흐름을 코드에서도 역할별로 분리하면, 모델을 교체하거나 API를 추가할 때 수정 범위를 줄일 수 있다.
2. 추천 프로젝트 구조
app/
├── main.py
├── routers/
│ ├── predict.py
│ └── health.py
├── schemas/
│ ├── request.py
│ └── response.py
├── services/
│ └── inference_service.py
├── models/
│ └── model_loader.py
├── utils/
│ └── preprocess.py
├── core/
│ ├── config.py
│ └── logging.py
└── requirements.txt
이 구조는 작은 AI API 서버에도 적용할 수 있고, 프로젝트가 커졌을 때 확장하기도 쉽다.
3. main.py
main.py는 FastAPI 애플리케이션의 시작점이다.
앱을 생성하고, 라우터를 등록하고, CORS 같은 공통 설정을 적용한다.
from fastapi import FastAPI
from app.routers import predict, health
app = FastAPI(title="AI Model API")
app.include_router(health.router)
app.include_router(predict.router)
이 파일에는 복잡한 추론 로직을 직접 작성하지 않는 것이 좋다.
서버 시작과 전체 연결만 담당하게 하면 코드 구조가 깔끔해진다.
4. routers
routers는 API 엔드포인트를 관리하는 영역이다.
예를 들어 /predict는 예측 요청을 처리하고, /health는 서버 상태를 확인하는 용도로 사용할 수 있다.
from fastapi import APIRouter
from app.schemas.request import PredictRequest
from app.services.inference_service import run_inference
router = APIRouter(prefix="/predict")
@router.post("")
def predict(request: PredictRequest):
return run_inference(request)
Router는 요청을 받고 Service를 호출하는 역할만 담당하는 것이 좋다.
전처리나 모델 실행 코드를 Router에 직접 넣으면 파일이 금방 복잡해진다.
5. schemas
schemas는 요청과 응답 데이터의 형식을 정의하는 영역이다.
FastAPI는 Pydantic을 이용해 입력값을 자동으로 검증할 수 있다.
from pydantic import BaseModel
class PredictRequest(BaseModel):
text: str
class PredictResponse(BaseModel):
label: str
confidence: float
이렇게 정의해두면 잘못된 형식의 요청이 들어왔을 때 서버가 자동으로 오류를 반환할 수 있다.
API 사용 방식도 명확해진다.
6. models
models는 학습된 AI 모델을 불러오고 관리하는 영역이다.
모델은 요청이 들어올 때마다 새로 불러오면 안 된다.
모델 로딩은 시간이 오래 걸리고, 메모리 사용량도 커질 수 있기 때문이다.
일반적으로 서버가 시작될 때 모델을 한 번만 로드하고, 이후 모든 요청에서 같은 모델 객체를 재사용한다.
def load_model():
model = ...
model.eval()
return model
model = load_model()
이 구조를 사용하면 응답 속도를 높이고 불필요한 리소스 사용을 줄일 수 있다.
7. services
services는 실제 추론 흐름을 담당하는 핵심 영역이다.
입력 데이터를 전처리하고, 모델에 넣어 예측을 수행한 뒤, 응답 형태로 결과를 정리한다.
from app.models.model_loader import model
from app.utils.preprocess import preprocess_text
def run_inference(request):
input_data = preprocess_text(request.text)
output = model(input_data)
return {
"label": output["label"],
"confidence": output["confidence"]
}
추론 로직을 Service로 분리하면 같은 모델을 여러 API에서 재사용하기 쉽다.
또한 모델 변경이나 전처리 수정이 필요할 때도 관리가 편해진다.
8. utils
utils는 여러 곳에서 공통으로 사용하는 기능을 모아두는 영역이다.
AI 모델에서는 전처리 코드가 자주 들어간다.
- 텍스트 정제
- 이미지 리사이징
- 정규화
- 토큰화
- 파일 변환
def preprocess_text(text: str):
return text.strip().lower()
전처리를 별도 함수로 분리하면 테스트하기 쉽고, 추론 코드도 더 읽기 좋아진다.
9. core
core는 프로젝트 전체 설정을 관리하는 영역이다.
모델 경로, 환경 변수, 로그 설정, CORS 설정 등을 이곳에서 관리할 수 있다.
MODEL_PATH = "models/model.pt"
API_VERSION = "v1"
설정값을 코드 곳곳에 직접 작성하면 나중에 수정하기 어렵다.
따라서 설정은 한 곳에서 관리하는 것이 좋다.
10. health check API
실제 API 서버에서는 예측 API뿐만 아니라 서버 상태를 확인하는 API도 필요하다.
예를 들어 /health 엔드포인트를 만들어 서버가 정상 동작 중인지 확인할 수 있다.
from fastapi import APIRouter
router = APIRouter(prefix="/health")
@router.get("")
def health_check():
return {"status": "ok"}
이 API는 배포 환경에서 서버 상태 확인, 모니터링, 로드밸런서의 상태 체크 등에 활용될 수 있다.
11. 실무에서 추가로 고려할 부분
AI 모델 API는 단순히 동작하는 것만으로는 충분하지 않다.
안정적으로 운영하려면 다음 요소들도 함께 고려해야 한다.
- 예외 처리: 잘못된 입력이나 모델 오류에 대한 응답 처리
- 로깅: 요청 시간, 예측 결과, 오류 기록
- CORS 설정: 프론트엔드와 API 서버가 통신할 수 있도록 설정
- 모델 버전 관리: 모델 교체 시 어떤 버전을 사용했는지 추적
- Docker 배포: 동일한 환경에서 서버를 실행하기 위한 컨테이너화
이러한 요소들은 프로젝트 규모가 커질수록 중요해진다.
전체 구조 요약
| 구성 요소 | 역할 |
|---|---|
| main.py | FastAPI 앱 생성과 라우터 등록 |
| routers | API 엔드포인트 관리 |
| schemas | 요청과 응답 형식 정의 |
| models | 모델 로드와 모델 객체 관리 |
| services | 전처리와 모델 추론 실행 |
| utils | 공통 전처리 함수 관리 |
| core | 환경 설정과 공통 설정 관리 |
정리
FastAPI로 AI 모델을 통합한 웹 API를 구현할 때는 기능별로 코드를 나누어 구성하는 것이 좋다.
Router는 요청을 받고, Schema는 입력과 응답 형식을 정의하며, Service는 실제 추론 흐름을 담당한다.
Model Loader는 학습된 모델을 한 번만 로드해 재사용하고, Utils는 전처리와 같은 공통 기능을 관리한다.
이런 구조를 사용하면 코드가 명확해지고, 모델 교체나 API 확장도 더 쉽게 처리할 수 있다.
'데이터 분석' 카테고리의 다른 글
| AI 이미지 분석 서비스 아키텍처 설계 (0) | 2026.06.26 |
|---|---|
| Streamlit으로 AI 모델을 웹 애플리케이션에 통합하는 과정 (0) | 2026.06.26 |
| 모델 경량화 후 성능 저하를 확인하기 위한 테스트 방법 (0) | 2026.06.19 |
| Post-Training Quantization과 Quantization-Aware Training의 차이 (0) | 2026.06.19 |
| 딥러닝 모델을 ONNX와 TensorRT로 변환하는 이유 (0) | 2026.06.19 |