Q1. Streamlit을 사용해서 AI 모델을 웹 애플리케이션에 통합하려면 모델 로드, 사용자 입력, 결과 출력의 단계를 거쳐야합니다. 각각의 단계에 대해 설명해주세요.
A1.
모델 로드: 앱 실행 시 AI 모델을 메모리에 적재, st.cache_resource 데코레이터를 사용해 모델 재로딩을 방지하고 앱 응답 속도 최적화사용자 입력: st.file_uploader, st.text_input 등 Streamlit 위젯을 활용해 사용자로부터 추론에 필요한 데이터를 입력받음
결과 출력: 모델 추론 결과를 st.write (텍스트), st.image (이미지) 등으로 사용자에게 시각적으로 명확하게 전달
Q2. FastAPI를 활용하여 AI 모델을 통합한 웹 API를 구현할 때, 기능별로 나눠서 구성하는 것이 바람직합니다. 전체적인 API 서버 코드 구조는 어떻게 구성되면 좋을지 자유롭게 작성해보세요.
A2.
main.py: FastAPI 앱을 생성하고 라우터를 등록하는 진입점/apis: 기능별 라우터(엔드포인트)를 모아두는 디렉토리
/core: 모델 로드, 추론 실행 등 핵심 비즈니스 로직을 구현
/schemas: Pydantic 모델을 사용해 API 요청 및 응답 데이터의 형식을 정의하고 유효성을 검증
/models: 학습 완료된 모델 파일(.pth, .pkl 등)을 저장
Q3. 현존하는 AI 웹/앱서비스를 하나 선정하세요. (가상의 서비스로 해보는 것도 좋아요.) 그 서비스가 지금까지 학습한 Docker, 추론 최적화, Streamlit, FastAPI로 구현되었다고 가정하고, 전체 아키텍처를 작성해보세요. 만약 가능하다면, 보안 요소(CORS 등)/멀티유저 요청 처리 방안(비동기 처리, 대기 큐 등)/클라우드 배포 구조(GCP, AWS)/모니터링 및 로깅 전략 까지 포함하여 작성해보세요.
A3.
UI: Streamlit (사용자 상호작용 및 프론트엔드)API 서버: FastAPI (비즈니스 로직 및 요청 라우팅)
추론 서버: FastAPI + TensorRT/ONNX Runtime (최적화된 모델 서빙)
인프라: 모든 서비스는 Docker 컨테이너화 후, Google Kubernetes Engine(GKE)에 배포. GKE의 Horizontal Pod Autoscaler를 사용해 트래픽에 따른 자동 확장 구성
요청 처리: FastAPI의 비동기 기능을 활용하고, 대규모 요청은 Cloud Pub/Sub(메시지 큐)로 전달하여 순차적으로 안정적이게 처리
보안/모니터링: Identity-Aware Proxy(IAP)로 리소스 접근 제어, Cloud Logging과 Cloud Monitoring으로 실시간 서비스 상태 추적 및 로깅
A. 모델 로드 (Model Loading)
st.cache_resource 데코레이터를 활용하여 웹 애플리케이션 실행 시 모델을 단 한 번만 로드B. 사용자 입력 (User Input)
st.file_uploader, 텍스트는 st.text_input, 슬라이더는 st.slider 등을 활용C. 결과 출력 (Result Display)
st.write로 텍스트, 숫자 등 일반적인 결과 출력st.image로 이미지 결과, st.json으로 API 응답과 같은 구조화된 데이터 출력import streamlit as st
import torch
from torchvision import transforms
from PIL import Image
import io
# A. 모델 로드
@st.cache_resource
def load_model():
# 간단한 예시용 PyTorch 모델
model = torch.hub.load('pytorch/vision:v0.10.0', 'resnet18', pretrained=True)
model.eval()
return model
model = load_model()
st.title("간단한 이미지 분류기")
# B. 사용자 입력
uploaded_file = st.file_uploader("이미지를 업로드하세요", type=["jpg", "png"])
if uploaded_file is not None:
image = Image.open(uploaded_file).convert("RGB")
# C. 결과 출력 (이미지 표시)
st.image(image, caption='업로드된 이미지', use_column_width=True)
st.write("분류 중...")
# 간단한 추론 로직
preprocess = transforms.Compose([
transforms.Resize(256),
transforms.CenterCrop(224),
transforms.ToTensor(),
transforms.Normalize(mean=[0.485, 0.456, 0.406], std=[0.229, 0.224, 0.225]),
])
input_tensor = preprocess(image)
input_batch = input_tensor.unsqueeze(0)
with torch.no_grad():
output = model(input_batch)
# C. 결과 출력 (추론 결과 텍스트)
_, predicted_idx = torch.max(output, 1)
st.success(f"예측 결과: 클래스 {predicted_idx.item()}")
A. 디렉토리 구조
/project: 프로젝트 최상위 루트/apis: API 엔드포인트 (라우터)/core: 핵심 비즈니스 로직 (AI 모델 추론 등)/schemas: 데이터 유효성 검증을 위한 Pydantic 모델/models: 학습된 AI 모델 파일 (.pth, .onnx)main.py: FastAPI 애플리케이션 실행 및 초기 설정B. 각 파일/디렉토리 역할
main.py: FastAPI 앱 인스턴스를 생성하고, /apis 디렉토리의 라우터들을 포함(include_router)하는 진입점 역할apis/predict.py: 예측과 관련된 API 엔드포인트(/predict)를 정의core/inference.py: 실제 AI 모델을 로드하고 예측을 수행하는 함수 구현schemas/request.py: API 요청 시 받아들일 데이터의 구조와 타입을 Pydantic으로 정의schemas/response.py: API가 반환할 응답 데이터의 구조와 타입을 Pydantic으로 정의# main.py 예시
from fastapi import FastAPI
from apis import predict # /apis/predict.py에서 정의한 라우터를 가져옴
app = FastAPI(title="AI Model API")
# API 라우터를 앱에 포함
app.include_router(predict.router, prefix="/api/v1", tags=["Prediction"])
@app.get("/")
def read_root():
return {"message": "API 서버가 동작 중입니다."}
# predict.py 예시
from fastapi import APIRouter
from schemas.request import ImageData # /schemas/request.py에서 정의한 Pydantic 모델
from schemas.response import PredictionResult
router = APIRouter()
@router.post("/predict", response_model=PredictionResult)
def run_prediction(image_data: ImageData):
# core 로직을 호출하여 추론 수행 (생략)
prediction = "Cat"
confidence = 0.95
return {"prediction": prediction, "confidence": confidence}
A. 핵심 아키텍처 (3-Tier)
Streamlit을 사용하여 사용자와 상호작용하는 인터페이스를 신속하게 개발FastAPI로 비즈니스 로직 처리 및 외부 요청을 담당하는 API 서버 구축FastAPI와 ONNX Runtime 또는 TensorRT를 결합하여 최적화된 AI 모델 서빙에만 집중B. 클라우드 배포 구조 (GCP)
Docker 이미지로 빌드Google Kubernetes Engine(GKE)을 사용하여 컨테이너를 배포하고 관리, Horizontal Pod Autoscaler로 트래픽에 따라 Pod 수를 자동 조절Cloud Storage에 저장Cloud SQL 또는 Firestore에 저장C. 멀티유저 요청 처리 방안
FastAPI의 async/await 문법을 활용하여 I/O 작업 시 블로킹을 최소화하고 동시 요청 처리 효율을 극대화Cloud Pub/Sub을 대기 큐로 사용. API 서버는 요청을 큐에 넣고 바로 응답하며, 별도의 추론 워커(Worker)들이 큐에서 작업을 가져와 처리D. 보안 요소
Identity-Aware Proxy(IAP)를 GKE Ingress 앞에 구성하여 인증된 사용자 및 서비스만 리소스에 접근하도록 제어Secret Manager를 사용하여 API 키, DB 비밀번호 등 민감 정보를 안전하게 관리E. 모니터링 및 로깅 전략
Cloud Logging을 사용하여 애플리케이션의 모든 로그(요청, 응답, 에러)를 중앙에서 수집 및 분석Cloud Monitoring으로 CPU/GPU 사용률, 응답 지연 시간, 에러율 등 핵심 성능 지표(Metric)를 실시간으로 추적Cloud Monitoring의 알림 기능을 통해 이메일이나 Slack으로 담당자에게 즉시 통보| 컴포넌트 | 사용 기술 | 주요 역할 |
|---|---|---|
| 프론트엔드 | Streamlit | 사용자 인터페이스 제공 및 데이터 입력 |
| 백엔드 API 서버 | FastAPI | 비즈니스 로직 처리, 요청 라우팅, 비동기 작업 관리 |
| AI 추론 서버 | FastAPI + ONNX/TensorRT | 최적화된 AI 모델 서빙 및 고속 추론 수행 |
| 컨테이너/배포 | Docker, GKE | 서비스 패키징 및 확장성 있는 클라우드 환경에 배포 |
| 요청 분산 | Cloud Pub/Sub | 대규모 동시 요청을 처리하기 위한 비동기 메시지 큐 |
| 보안 | IAP, Secret Manager, CORS | 사용자 인증, 민감 정보 관리, 허용된 출처 제어 |
| 모니터링/로깅 | Cloud Logging, Cloud Monitoring | 시스템 상태 추적, 로그 분석 및 이상 상황 감지/알림 |
Streamlit을 활용해 AI 모델을 웹 애플리케이션에 통합하려면, 일반적으로 세 가지 주요 단계를 거치게 됩니다: 모델 로드, 사용자 입력 처리, 그리고 결과 출력입니다.
먼저 모델 로드는 애플리케이션 시작 시 한 번만 수행되도록 구성하는 것이 중요합니다. Streamlit에서는 @st.cache_resource나 @st.singleton 데코레이터를 사용해서 모델을 메모리에 올려두고 반복 로딩을 방지할 수 있습니다. 이 과정을 통해 매번 입력이 들어올 때마다 모델을 다시 불러오는 성능 저하를 막을 수 있습니다.
두 번째 단계는 사용자 입력을 받아 이를 모델이 이해할 수 있는 형태로 전처리하는 과정입니다. 예를 들어, 텍스트 입력의 경우 토큰화와 벡터화가 필요하고, 이미지 입력의 경우 리사이징이나 정규화 작업이 선행되어야 합니다. 이 단계에서는 입력값의 유효성을 검사하고 예외 처리를 통해 앱이 안정적으로 동작하도록 만드는 것도 중요합니다.
세 번째는 모델이 생성한 예측 결과를 사용자에게 출력하는 단계입니다. 이 때 Streamlit의 다양한 출력 컴포넌트, 예를 들어 st.write, st.image, st.bar_chart 등을 사용해 결과를 시각적으로 표현할 수 있습니다. 결과가 숫자나 클래스 레이블일 수도 있고, 생성된 문장이나 이미지일 수도 있으므로, 사용자 친화적인 형태로 후처리를 수행하는 것도 포함됩니다.
FastAPI를 활용해 AI 모델을 API 형태로 제공할 때는 코드를 기능별로 나눠서 깔끔하게 구성하는 것이 중요합니다. 일반적으로 다음과 같은 구조로 개발합니다.
먼저 메인 진입점인 main.py 파일에서는 FastAPI 앱을 생성하고 라우터들을 연결합니다. 모델을 초기화하거나 환경 설정을 적용하는 것도 이 단계에서 처리할 수 있습니다. 서버를 실행하는 명령도 여기에 포함되죠.
요청을 처리하는 함수들은 routers 디렉토리에 따로 모아둡니다. 예를 들어 /predict 라는 경로에 대해 어떤 요청을 받을지, 어떤 입력을 받아서 어떻게 응답할지를 정의합니다. 이 부분에서는 실제 모델 추론 함수를 호출하는 코드도 포함됩니다.
입력과 출력을 깔끔하게 관리하려면 Pydantic을 이용한 데이터 검증이 필수입니다. 이를 위해 models 디렉토리를 만들어서 요청(request)과 응답(response)에 대한 데이터 구조를 정의합니다. 예를 들어 텍스트를 입력으로 받는다면 TextRequest 클래스 같은 걸 만들어서 입력이 형식에 맞는지 자동으로 검증할 수 있게 합니다.
실제 모델을 로딩하고 추론하는 로직은 services 혹은 core 같은 디렉토리에 둡니다. 여기에 PyTorch나 TensorFlow 모델을 불러오고 전처리나 후처리 과정을 포함한 핵심 추론 함수들이 들어갑니다.
그 외에 이미지 전처리, 텍스트 정제, 로그 기록 같은 보조적인 기능은 utils 디렉토리에 따로 정리해두는 것이 유지보수에 유리합니다.
그리고 프로젝트에 필요한 패키지들은 requirements.txt나 pyproject.toml에 기록해서 개발 환경과 운영 환경을 일관되게 맞출 수 있게 합니다.
실행을 위한 셸 스크립트도 run.sh나 start.sh 파일로 관리하면 편리합니다. 개발 중에는 uvicorn으로 서버를 실행하고, 운영 환경에서는 gunicorn이나 docker를 조합해서 컨테이너화하여 배포하기도 합니다.
전체적으로 보면, API 서버는 입력 데이터의 유효성을 검사하고 모델 추론을 호출하고 결과를 응답하는 역할을 하게 됩니다. FastAPI는 비동기 처리에 강해서 요청이 많은 환경에서도 안정적으로 동작할 수 있다는 장점도 있습니다.
AI 기반 음성 텍스트 변환 및 요약 웹서비스인 "VoiceSummarizer"라는 가상의 서비스를 예로 들어 전체 시스템 아키텍처를 설명하겠습니다. 이 서비스는 사용자가 음성 파일(mp3, wav 등)을 업로드하면 해당 음성을 텍스트로 변환하고, 요약된 텍스트를 제공하는 웹 기반 플랫폼입니다.
이 시스템은 Streamlit, FastAPI, Docker, ONNX 기반 추론 최적화 등을 기반으로 구현되며, 확장성과 유지보수성을 고려하여 아키텍처를 설계합니다.
첫째, 프론트엔드 구성은 Streamlit으로 사용자와의 상호작용을 담당합니다. 사용자는 Streamlit 웹 화면을 통해 음성 파일을 업로드하고 결과를 확인하게 됩니다. 이 프론트는 FastAPI 백엔드와 HTTP 통신을 통해 연결되며, 요청과 응답은 JSON 및 파일 형식으로 오갑니다.
둘째, FastAPI는 백엔드 API 서버로 동작하며 음성 파일을 받아 텍스트 변환 모델과 요약 모델을 호출합니다. 모델 추론 로직은 ONNX 형식으로 최적화된 음성 인식 모델과 요약 모델을 사용합니다. 추론 속도를 높이기 위해 TensorRT를 활용하여 GPU 환경에서 빠른 응답을 보장합니다.
셋째, 모든 모델 추론 환경은 Docker 컨테이너로 분리되어 관리됩니다. 음성 인식 컨테이너, 요약 컨테이너, 웹 프론트엔드 컨테이너, API 서버 컨테이너를 각각 독립적으로 구성하여 장애 격리를 강화하고 유지보수를 용이하게 만듭니다.
넷째, 멀티유저 요청 처리를 위해 백엔드 FastAPI 서버는 비동기 처리를 기반으로 구성되며, 음성 파일 처리 시간이 긴 경우에는 요청을 비동기로 수신한 뒤 작업 큐(Redis + Celery 또는 FastAPI BackgroundTask)를 사용하여 처리합니다. 사용자는 처리 중이라는 메시지를 받고, 이후 결과를 다운로드하는 방식으로 UX를 제공합니다.
다섯째, 보안 요소로는 CORS 설정을 통해 프론트엔드 도메인 외의 요청을 차단하며, HTTPS는 Let's Encrypt 기반 인증서를 통해 설정합니다. 사용자 인증이 필요한 경우에는 JWT 기반 토큰 인증을 도입할 수 있습니다.
여섯째, 클라우드 배포는 Google Cloud Platform(GCP)의 Compute Engine을 기반으로 구성합니다. 각 컨테이너는 Docker Compose 혹은 Kubernetes(GKE)로 오케스트레이션되며, 외부 접속은 Cloud Load Balancer를 통해 관리합니다. 오브젝트 스토리지(GCS)를 통해 사용자 업로드 파일을 임시 저장하며, 일정 시간 후 자동 삭제 정책을 적용합니다.
마지막으로, 모니터링과 로깅 전략은 Prometheus와 Grafana를 통해 시스템 자원 사용량, 응답 속도, 에러율 등을 실시간 시각화합니다. FastAPI와 모델 추론 코드에는 구조화된 로그를 남기며, 로그는 GCP Logging 또는 ELK Stack으로 집계됩니다. 사용자 단의 에러는 프론트엔드에서 Sentry로 수집하여 사용자 경험을 추적하고 개선합니다.