MVP 최적화 정리 - 100-hours-a-week/6-nemo-wiki GitHub Wiki

☑️ Why?

우리 팀의 AI 기능은 사용자가 입력한 모임 정보(모임명, 카테고리, 목적)를 바탕으로 모임 소개글, 태그, 커리큘럼을 자동 생성하는 것이다. 이는 모임 신청 절차를 간소화하고, 사용자의 진입 장벽을 낮추며, 보다 일관성 있는 소개글을 제공하기 위함이다. 하지만 이런 기능은 대형 언어 모델(LLM)을 활용해야 하며, 단순히 기능이 구현된다고 끝이 아니다. 실제 서비스 환경에서는 다음과 같은 이슈들이 발생한다:

  • 응답 속도가 느려 사용자가 이탈함

  • API 호출 비용이 높아짐

  • 서버가 많은 요청을 처리하지 못해 장애가 발생함

따라서 우리 서비스에서는 단순히 "좋은 결과"를 생성하는 것 이상으로, 빠르고 안정적으로 동작하는 AI 추론 구조를 설계해야 한다. 이를 위해 실제 모델별 추론 성능을 비교하고, 어떤 모델이 우리 서비스에 최적인지를 판단하는 작업을 수행한다.

☑️ 실험 목적 및 기준

항목 기준 및 이유
응답 속도 (Latency) 사용자가 기다리는 시간을 줄여 UX 개선. 5초 이상이면 느리다고 평가
JSON 출력 형식 정확도 프론트엔드 연동 시 파싱 오류가 나지 않아야 함
응답 품질 실제 목적에 부합하는 표현력, 설득력, 구체성
# 모듈 import
import google.generativeai as genai
import time

# API 키 설정
genai.configure(api_key="GEMINI_API_KEY")

# Gemini 실험 모델 리스트
model_ids = ["gemini-2.0-flash", "gemini-2.0-flash-lite", "gemini-1.5-flash", "gemini-1.5-flash-8b", "gemini-1.5-pro"]

# 프롬프트 정의
filled_prompt = """
당신은 콘텐츠 마케팅 전문가 수준의 모임 소개문을 작성하는 AI 어시스턴트입니다.

사용자가 입력한 모임 정보를 바탕으로, 사람들이 실제로 참여하고 싶게 만드는 매력적이고 설득력 있는 모임 프로필을 작성해주세요. 문장은 간결하면서도 흥미를 유발해야 하며, 각 항목 내 중복 표현 없이 명확하게 기술되어야 합니다.

**응답은 반드시 지정된 JSON 형식**으로 출력되어야 하며, 다음 조건을 반드시 지켜야 합니다:

- 출력은 JSON 외 텍스트, 주석, 코드블럭, 마크다운 등을 포함하지 마세요.
- 각 항목은 반드시 요구된 길이 제한을 지켜야 하며, 태그는 중복 없는 3개 키워드로 작성하세요.

입력 정보:
{
  "name": "알고리즘 스터디",
  "category": ["스터디", "개발", "자기계발"],
  "purpose": ["백준 골드 이상 문제풀이", "PS 역량 향상", "정기 모의 코테 대비"]
}

출력 형식:

{
  "short_description": "64자 이내의 모임 한줄소개",
  "tags": ["태그1", "태그2", "태그3"],
  "detailed_info": {
    "introduction": "모임에 대한 간략한 소개 (200자 이내)",
    "target_audience": [
      "추천 대상 1",
      "추천 대상 2",
      "추천 대상 3"
    ],
    "meeting_format": "예: 매주 화요일 온라인 ZOOM 1시간 진행, 오프라인 번개 가능",
    "rules": [
      "규칙 1",
      "규칙 2",
      "규칙 3"
    ]
  },
  "curriculum": [
    {
      "period": "1주차",
      "title": "활동 제목 1",
      "description": "1주차 활동 내용 상세 설명",
      "goals": ["목표 A", "목표 B"]
    },
    {
      "period": "2주차",
      "title": "활동 제목 2",
      "description": "2주차 활동 내용 상세 설명",
      "goals": ["목표 C", "목표 D"]
    },
    {
      "period": "3주차",
      "title": "활동 제목 3",
      "description": "3주차 활동 내용 상세 설명",
      "goals": ["목표 E", "목표 F"]
    }
  ]
}
"""

# 각 모델별 실험 루프 (응답 시간 측정 및 실행, 결과 출력)
for model_id in model_ids:
    print(f"=== {model_id} 테스트 시작 ===")
    model = genai.GenerativeModel(model_id)
    start = time.time()
    response = model.generate_content(filled_prompt)
    end = time.time()

    print("응답 시간:", round(end - start, 2), "초")
    print("응답 결과:\n", response.text)

    print("=" * 60)

☑️ 실험 결과 정리

모델 응답 시간 JSON 형식 정확도 응답 품질 총평
gemini-2.0-flash 3.80초 ✔️ ⭐⭐⭐⭐☆ 균형 잡힌 성능, 속도/품질 우수
gemini-2.0-flash-lite 4.32초 ✔️ ⭐⭐⭐⭐ 응답 표현 다소 단순하지만 안정적
gemini-1.5-flash 5.21초 ✔️ ⭐⭐⭐ 품질 무난하나 속도 다소 느림
gemini-1.5-flash-8b 3.06초 ✔️ ⭐⭐⭐⭐ 가장 빠름, 품질도 우수
gemini-1.5-pro 10.23초 ✔️ ⭐⭐⭐⭐⭐ 품질 최고, 하지만 응답 시간 과도함: ❌

기본 추론 모델로 gemini-2.0-flash를 사용 예정. 빠르고, JSON 형식도 안정적이며, 품질도 양호

☑️ 병목 요소 분석

  • 네트워크 왕복(RTT) 지연
  • 프롬프트 길이 증가 → 응답 시간 증가
  • 동일 요청 반복 호출로 불필요한 비용 발생

☑️ 최적화 기법 적용 계획

기법 이유 기대 효과
프롬프트 압축 입력 길이 최적화 응답 시간 단축
결과 캐싱 반복 요청 처리 최적화 평균 응답 시간 대폭 단축

Gemini-2.0-flash 비용 계산

입력 비용: 500 tokens × ($0.10 / 1,000,000 tokens) = $0.00005

출력 비용: 1,000 tokens × ($0.40 / 1,000,000 tokens) = $0.0004

총 비용: $0.00045 (약 0.6원)