[AI] 컴포넌트별 도입 이유와 효과 - 100-hours-a-week/5-yeosa-wiki GitHub Wiki
📦 컴포넌트별 설명
1️⃣ FastAPI 서버 (Managed Instance Group)
- 역할: 사용자 요청 수신, AI 처리 흐름 제어, Gemini 연동, Redis 큐 등록
- 구성: GCP
n2d-standard-4
인스턴스로 구성된 MIG (Managed Instance Group)
✅ 도입 이유
- FastAPI는 비동기 처리에 강하고, 경량 구조로 빠른 응답 가능
- GCP MIG 구조와 결합 시 자동 스케일링이 용이하며, 트래픽 폭주 대응에 유리
🧩 모듈화 전략
FastAPI 내부는 다음과 같은 서비스 단위 모듈로 나누어 구성됨:
모듈 | 설명 |
---|---|
embedding |
이미지 임베딩 처리 |
category |
카테고리 분류 |
duplicate |
중복 사진 판별 |
quality |
이미지 품질 측정 |
score |
하이라이트 점수 계산 |
people |
인물 클러스터링 |
style |
스타일 변환 요청 등록 |
💡 효과
- 각 기능별 코드가 독립되어 있어 유지보수성과 테스트 효율이 매우 높음
- 향후 각 모듈을 마이크로서비스로 분리하기 쉬움
- 컨트롤러 → 서비스 → 코어 레이어 구조로 로직이 잘 분리됨
2️⃣ Redis (Cloud Memorystore for Redis)
- 역할:
- ① 이미지 임베딩 결과 캐시
- ② GPU 요청 메시지 큐
✅ 도입 이유
1. 이미지 임베딩 결과 캐싱이 필요한 이유
-
이미지를 처리할 때마다 임베딩 연산은 비용이 크고 반복되기 쉬움
-
후속 작업들(카테고리 분류, 중복 사진 판별, 하이라이트 추출 등)은
모두 동일한 임베딩 결과를 입력으로 사용
-
따라서 임베딩을 캐싱하면:
- 중복 연산 방지
- 응답 속도 향상
- FastAPI와 GPU 자원 사용 최소화
2. 메시지 큐가 필요한 이유
-
후속 AI 작업(예: 중복 사진 판별, 카테고리 분류)은
반드시 임베딩 이후에만 실행되어야 하며, 동시에 수행되지 않아야 함
-
FastAPI에서 이 작업들을 직접 실행하면:
- 요청마다 동기식 처리 발생
- 처리량이 늘면 서버 부하, 병목 발생
→ 따라서 메시지 큐를 통해:
- 각 작업을 분산된 Worker에서 비동기 처리
- 작업 순서 보장 (임베딩 후 → 분류, 중복 판별 등)
- 후속 연산의 제어 및 모니터링 가능
💡 효과
기능 | 효과 |
---|---|
이미지 임베딩 캐시 | 중복 연산 제거, 속도 개선, 후속 작업 일관성 유지 |
메시지 큐 | 처리 흐름 분리, 병렬성 조절, 고가용성 기반의 안정적 연산 수행 |
Redis 통합 운영 | 시스템 단순화, 운영 부담 감소, 확장 시 대응 용이 |
❗ 왜 인메모리(local Redis) 방식이 아닌가?
-
초기에 FastAPI 인스턴스에
cachetools
등 Python 캐시를 고려했지만,다중 인스턴스 환경에서 캐시 일관성이 유지되지 않음
-
인스턴스 로컬 Redis도 동일한 한계가 있었음
-
결국 모든 인스턴스가 공유할 수 있는 중앙 Redis 서버가 필요
💡 Redis 서버 효과
- 모든 FastAPI 인스턴스가 임베딩 결과를 공통으로 참조 가능
- 중복 연산 방지, 응답 속도 개선, GPU 부하 감소
- 메시지 큐와 캐시를 Redis 하나로 통합하여 운영 편의성 확보
3️⃣ GPU 서버 (Tesla T4)
- 역할: Stable Diffusion 기반 스타일 변환 수행
- 비동기 처리 방식: Redis 큐로부터 작업을 pull 방식으로 소비
✅ 도입 이유
- Stable Diffusion은 CPU 기반 인스턴스에서는 속도도 느리고 메모리도 부족해 실용적이지 않음
- 고비용 모델 연산을 별도로 처리하여 FastAPI 서버 부하 최소화
❗ 메시지 큐를 도입한 이유
- GPU 서버는 고비용 연산 자원이므로 직접 호출 방식은 위험
- 다중 인스턴스가 직접 요청 시 GPU 서버 과부하 및 병목 발생
- 메시지 큐로 요청을 분산 제어하면 안정성과 처리율 확보 가능
💡 효과
- GPU 서버는 한 번에 하나씩 안정적으로 작업 수행
- 작업 순서를 제어하고, 재시도 로직도 쉽게 구현 가능
- 시스템 전체의 내결함성(fault tolerance) 향상
4️⃣ Gemini API (External, via NAT)
- 역할: 스타일 변환용 프롬프트 생성
- FastAPI에서 NAT를 통해 외부 호출
✅ 도입 이유
- 이미지를 함께 입력하고 그에 대해 텍스트 생성 가능 (사진 + 프롬프트 설명 생성에 적합)
- "지브리 스타일로 바꿔줘" 같은 사용자 요청을 이해하고 스타일 특징 반영 가능
- 대기 시간 없이 바로 API로 활용 가능하며, 프롬프트 품질도 만족스러움
- 추상화 없이 HTTP API로 바로 처리 가능 → latency 최소화
❌ LangChain을 사용하지 않는 이유
이유 | 설명 |
---|---|
🚫 불필요한 추상화 | 단일 요청만 처리하는데도 체인을 도입하면 과잉 설계 |
🚫 성능 낭비 | LangChain 도입 시 처리 속도가 느려지고 추론 흐름이 복잡해질 수 있음 |
✅ 직접 API 호출이 더 직관적 | requests로 Gemini 호출 → Stable Diffusion 호출로 끝나는 간단한 플로우 |
5️⃣ Cloud NAT
- 역할: FastAPI 인스턴스에서 외부 인터넷 요청(Gemini API 등)이 가능하도록 출구 역할 수행
✅ 도입 이유
- GCP 내부 VM들은 기본적으로 외부 인터넷 접근이 차단되어 있으므로, Cloud NAT 없이 외부 API 호출 불가
- FastAPI에서 Gemini API 요청을 외부로 보낼 수 있도록 NAT 출구 제공
- GCP의 보안 정책을 유지하면서도 선별적 외부 연결 허용 가능
💡 효과
- NAT를 통해 외부 API(Gemini 등)와 안전하게 통신 가능
- 각 연결이 NAT 포트를 공유하므로 외부 IP 관리와 포트 제어를 효율적으로 수행
- 외부와의 통신은 NAT 단위로 중앙 집중 모니터링 가능
6️⃣ Cloud Load Balancer
- 역할: 클라이언트 또는 Backend 서버에서 들어오는 요청을 FastAPI 인스턴스로 자동 분산 라우팅
✅ 도입 이유
- FastAPI 서버는 Managed Instance Group(MIG)로 구성되어 있어 인스턴스 수가 유동적으로 변할 수 있음
- 트래픽이 폭주하거나 감소할 때 자동 확장/축소된 인스턴스를 유연하게 연결하기 위해 필요
💡 효과
- 서비스 안정성 향상 (Hotspot 없이 균등 요청 분산)
- FastAPI 서버의 수평 확장 대응 구조 완성
- SSL 인증 / 도메인 구성 등도 LB 계층에서 통합 가능
7️⃣ Cloud Storage (GCS)
- 역할:
- 이미지 파일 업로드 및 결과 저장용 객체 스토리지
- 사용자 업로드 이미지 및 Stable Diffusion 결과물을 저장
✅ 도입 이유
-
이미지 파일은 용량이 크고 비정형(binary)이기 때문에
일반 DB나 Redis에 저장하기에 적합하지 않음
-
GCS는 안정적인 대용량 파일 저장 + 저렴한 비용 + pre-signed URL 사용이 가능
💡 효과
- 이미지 입출력을 FastAPI 서버가 직접 처리하지 않아도 되므로 부하 분산
- GPU 서버나 워커에서 처리한 이미지 결과를 GCS에 저장하면 이후 단계에서 직접 다운로드 가능 (URL 공유만으로 처리 가능)
- pre-signed URL을 활용하면 인증 없이 안전하게 파일을 업로드/다운로드할 수 있음
8️⃣ 모니터링 스택 (Prometheus, Grafana, Alertmanager)
- 각 인스턴스에서
Node Exporter
,Redis Exporter
를 통해 메트릭 수집 - Prometheus가 모든 메트릭 통합
- Grafana로 시각화
- Alertmanager는 Discord로 실시간 알림 발송
💡 효과
- 장애 및 이상 상황에 대한 즉시 대응 가능
- CPU, GPU 사용률, Redis 큐 길이, 요청 응답 시간 등 전반적인 시스템 상태 추적 가능