오늘이 마지막 위클리 페이퍼 작성일이라서 기분이 이상하네요. 마지막까지 최선을 다해보도록 하겠습니다. 😊
1. Streamlit을 활용한 AI 모델 통합: Load, Input, Output
- Streamlit은 데이터 및 AI 애플리케이션을 빠르게 프로토타이핑할 수 있는 강력한 도구입니다. 하지만 머신러닝 모델을 얹을 때는 상태 관리와 메모리 최적화를 반드시 고려해야 합니다.
import streamlit as st
import torch
from PIL import Image
# 1. 모델 로드 (Model Load)
@st.cache_resource
def load_model():
# 예시: PyTorch 모델 로드
model = torch.hub.load('ultralytics/yolov5', 'yolov5s', pretrained=True)
model.eval()
return model
model = load_model()
st.title("AI 객체 탐지 애플리케이션")
# 2. 사용자 입력 (User Input)
uploaded_file = st.file_uploader("이미지를 업로드하세요", type=["jpg", "jpeg", "png"])
if uploaded_file is not None:
image = Image.open(uploaded_file)
st.image(image, caption="업로드된 이미지", use_column_width=True)
# 3. 결과 출력 (Output)
if st.button("분석 시작"):
with st.spinner('AI가 이미지를 분석 중입니다...'):
results = model(image)
st.image(results.render()[0], caption="탐지 결과", use_column_width=True)
💡 설계 의도 (Design Intent): @st.cache_resource의 필수성 :
Streamlit은 사용자가 버튼을 누르거나 입력을 변경할 때마다 스크립트를 위에서부터 다시 실행합니다.
만약 @st.cache_resource 데코레이터를 사용하지 않는다면, 매 인터랙션마다 수백 MB에 달하는 모델을 메모리에 다시 올리게 됩니다. 이는 극심한 메모리 누수와 처리 속도 저하를 유발합니다. 따라서 리소스를 캐싱하는 방법을 사용함으로 불필요한 I/O를 줄이고 애플리케이션의 응답성을 보장할 수 있습니다.
2. FastAPI 기반 AI 웹 API 서버 아키텍처
FastAPI를 사용할 때 모든 로직을 main.py에 몰아넣는 것은 지양해야 합니다. 기능별로 계층을 분리해야 유지보수가 쉬워지고, 프론트엔드 개발자에게 일관된 에러 응답과 상태 관리를 제공할 수 있습니다.
📦 fastapi-ai-backend
┣ 📂 api
┃ ┣ 📂 v1 # API 버전 관리
┃ ┃ ┣ 📜 endpoints.py # 라우터(Controller 역할)
┣ 📂 core
┃ ┣ 📜 config.py # 환경 변수 및 설정 관리
┃ ┣ 📜 security.py # 인증, CORS 설정
┣ 📂 models # DB 엔티티 (SQLAlchemy 등)
┣ 📂 schemas # Pydantic 모델 (입출력 검증)
┣ 📂 repositories # DB 접근 로직 (Repository Pattern)
┣ 📂 services # 핵심 비즈니스 및 AI 추론 호출 로직
┣ 📂 utils # 로깅, 공통 헬퍼 함수
┗ 📜 main.py # FastAPI 애플리케이션 엔트리포인트
💡 설계 의도 (Design Intent): 계층 분리 및 Repository 패턴 도입
- 백엔드 설계에서 '게으른 구조'란 DB 모델을 API 응답으로 그대로 반환하여 프론트엔드에서 데이터를 파싱하게 만드는 것입니다. 이를 방지하기 위해 Repository 패턴을 도입하여 데이터 접근 로직(repositories/)과 비즈니스 로직(services/)을 분리합니다.
- AI 모델 추론 역시 services/ 계층에서 처리하며, 라우터(api/)는 오직 HTTP 요청/응답의 형태와 상태 코드(Status Code) 관리만 책임집니다. 이 구조는 훗날 N+1 쿼리 문제를 해결하거나 데이터베이스를 교체할 때 다른 계층에 미치는 영향을 최소화합니다.
3. 종합 AI 웹 서비스 아키텍처: 원격 시험 감독 시스템
AI 원격 시험 감독 솔루션을 예시로, 대규모 트래픽을 처리할 수 있는 프로덕션 레벨의 아키텍처를 설계해 보았습니다.

📌 기술 스택 및 아키텍처 상세
- AI 추론 및 전처리 파이프라인 (MediaPipe & YOLO)
- 단순 객체 탐지(YOLO) 이전에, MediaPipe를 활용하여 수험자의 얼굴, 코, 눈 랜드마크를 인식하고 영상의 각도를 가로 모드로 강제 보정하는 전처리 단계를 거칩니다. 이를 통해 모델에 입력되는 데이터의 정규화를 보장하여 추론 정확도를 극대화했습니다.
- 응시자가 이탈한 시간(블랙아웃)은 물리적 영상 합성 대신 메타데이터 기반의 스킵(Skip) 로직으로 처리하여 GPU 자원 낭비를 차단했습니다.
- 비동기 분산 큐와 자원 관리 (FastAPI + Redis + Celery)
- API 요청을 처리하는 동기 작업(FastAPI)과 AI 모델을 돌리는 CPU Bound 비동기 작업(Celery)을 분리하여 Event Loop 블로킹을 방지했습니다.
- 파이썬의 GIL(Global Interpreter Lock) 한계를 극복하기 위해 Celery 워커 내부에서 멀티프로세싱(Multi-processing)을 적용했습니다. 이때, LPT (Longest Processing Time First) 스케줄링 알고리즘을 도입하여 파일 크기가 가장 큰 영상 청크부터 워커에 먼저 할당함으로써 병렬 처리의 병목 현상을 해결했습니다.
- 스토리지 최적화 (S3 Pre-signed URL & 비디오 청킹)
- 대용량 비디오 파일이 백엔드 서버를 직접 거치지 않도록, FastAPI는 인증된 사용자에게만 S3 Pre-signed URL을 발급합니다.
- 클라이언트는 영상을 청크(Chunk) 단위로 분할하여 S3에 직접 업로드(Direct Upload)함으로써 백엔드 서버의 메모리 오버플로우(OOM)와 네트워크 병목을 완벽히 회피했습니다.
- 엔터프라이즈급 보안 전략 (AWS Secrets Manager)
- 데이터베이스 접속 정보나 AWS 환경 변수를 코드 저장소나 인스턴스에 하드코딩하지 않고, AWS Secrets Manager를 통해 런타임에 동적으로 주입받아 보안을 유지했습니다.
- 통합 모니터링 및 로깅 (AWS CloudWatch)
- 분산된 FastAPI 백엔드와 다수의 Celery 워커 노드에서 발생하는 모든 로그는 AWS CloudWatch로 중앙 집중화하여 수집합니다.
- API 에러 추적뿐만 아니라, 멀티프로세싱 환경에서 치명적인 OOM(Out of Memory) 발생 여부 및 메모리 사용량 지표를 실시간으로 모니터링하여 인프라 안정성을 확보했습니다.
💡 설계 의도 (Design Intent):
서드파티 모니터링 툴 대신 CloudWatch를 선택한 이유
외부 툴(Prometheus, Grafana)은 강력한 시각화 기능을 제공하지만, 별도의 인스턴스를 띄우고 지표(Metric) 수집 서버를 유지보수해야 하는 운영 부담이 발생합니다. 시스템 인프라가 AWS 위에서 동작하고 있다면, AWS Native 서비스인 CloudWatch로 로깅 생태계를 통일하는 것이 권한 관리(IAM)와 알람 연동 측면에서 훨씬 효율적이고 안전한 아키텍처 설계라고 생각했습니다.
'스프린트미션' 카테고리의 다른 글
| 위클리 페이퍼 #17 (0) | 2026.07.06 |
|---|---|
| 위클리 페이퍼 #15 (0) | 2026.06.21 |
| 위클리페이퍼 #14 (0) | 2026.06.15 |
| 위클리 페이퍼 #12 (0) | 2026.04.27 |
| 위클리 페이퍼 #11 (0) | 2026.04.20 |