단순히 모델을 띄우는 수준을 넘어, 다수 사용자가 접속해도 안정적인 AI 웹 앱을 운영하려면
모델 로딩, 상태 관리, 출력 UX, 아키텍처 분리를 함께 설계해야 합니다.

1. 모델 로딩 심화: 메모리와 리소스 최적화

@st.cache_resource는 시작점일 뿐입니다. 대형 모델 환경에서는 메모리 전략이 핵심입니다.

VRAM / RAM 분리 전략

  • CPU RAM 로딩과 GPU VRAM 로딩은 비용 구조가 다릅니다.
  • 모델 스위칭 시 GPU 메모리 해제 루틴을 함께 설계해야 OOM을 줄일 수 있습니다.
  • 필요 시 모델 언로드 + 캐시 정리 루틴을 명시적으로 호출합니다.

Singleton 성격의 리소스 공유

  • @st.cache_resource는 모델/DB 연결처럼 직렬화 어려운 객체 공유에 적합합니다.
  • 동일 프로세스 내 중복 로딩을 방지해 응답 안정성을 높입니다.

Lazy Loading

  • 앱 시작 시 모든 모델을 로딩하지 않고, 기능 호출 시점에 지연 로딩합니다.
  • 초기 기동 시간(TTFB) 단축에 효과적입니다.

2. 입력 처리 심화: Session State + Form 제어

Streamlit은 입력 변화마다 스크립트가 재실행되는 구조라, 상태 제어가 필수입니다.

st.session_state

  • 대화 기록, 선택값, 중간 결과를 유지합니다.
  • 불필요한 재추론 방지 및 멀티스텝 UX 구현에 필수입니다.

st.form 기반 배치 입력

  • 위젯이 많을 때 즉시 rerun을 막고, 제출 시점에만 처리합니다.
  • 사용자 체감 속도와 조작성이 크게 개선됩니다.

입력 검증(Validation)

  • 추론 직전이 아니라 입력 단계에서 형식/범위 검증을 수행합니다.
  • Pydantic 같은 스키마 검증을 붙이면 서버 에러를 크게 줄일 수 있습니다.

3. 출력 심화: 스트리밍과 비동기 UX

사용자 만족도를 높이는 핵심은 총 응답 시간이 아니라 "첫 출력까지 걸리는 시간"입니다.

토큰 스트리밍

  • 생성되는 즉시 출력해 대기 체감을 줄입니다.
  • 긴 답변에서 특히 효과가 큽니다.

비동기 처리/작업 위임

  • 이미지 생성, 대형 추론은 별도 백엔드 작업으로 분리합니다.
  • UI는 스피너/진행 상태를 유지하고 결과를 폴링 또는 콜백으로 수신합니다.

4. 아키텍처 확장: Streamlit + FastAPI 분리

초기엔 단일 앱으로 충분하지만, 서비스가 커지면 프론트/백 분리가 유리합니다.

역할 분리

  • FastAPI: 모델 추론, 인증, DB, 큐 처리
  • Streamlit: 입력/결과 시각화와 인터랙션

연결 이점

  • Streamlit은 API 호출만 담당하므로 UI 변경이 쉬움
  • 동일 백엔드를 모바일/다른 웹 서비스가 재사용 가능
  • 백엔드 수명주기에서 모델 로딩·헬스체크를 정교하게 제어 가능

5. 실무 체크리스트

  • 캐시 전략: 중복 로딩 방지 + OOM 대응 루틴이 있는가
  • 상태 제어: session_state, form으로 불필요 rerun을 막았는가
  • UX 피드백: 스트리밍/스피너/진행 상태를 제공하는가
  • 확장성: 추론 로직을 API로 분리할 준비가 되었는가

결론

고성능 Streamlit 앱의 본질은 "모델을 띄우는 코드"가 아니라
리소스, 상태, 사용자 체감, 아키텍처를 동시에 설계하는 엔지니어링입니다.

한 줄 요약: 장난감 데모와 운영 가능한 AI 서비스의 차이는, 파이프라인 제어 디테일에서 갈립니다.