DOCS/plans/250812_감정시스템_Phase1_실행계획.md

7.9 KiB

감정 시스템 Phase 1 실행 계획

작성일: 2025년 8월 12일
작성자: Claude (51123 서버)
상태: 실행 준비 완료

1. 현황 분석 결과

1.1 기존 자산

  • 학습 완료 모델: training_emotion에 7개 감정 모델 (klue/bert-base)
  • 모델 성능: F1 56.3%, Temperature Scaling 1.232
  • 인프라: skill-embedding 서비스 운영 중 (FastAPI, ONNX Runtime)
  • 여유 자원: CPU 0.05%, 메모리 873MB/2GB

1.2 기술 스택 확인

✅ transformers 4.45.2 설치됨
✅ FastAPI 구조 확립
✅ ONNX Runtime 지원
✅ ChromaDB 메타데이터 저장 가능

2. 감정 모델 상세

2.1 7개 감정 체계

emotions = [
    'fear',      # 공포 (즉발적 기본정서)
    'surprise',  # 놀람 (즉발적 기본정서)
    'anger',     # 분노 (즉발적 기본정서)
    'sadness',   # 슬픔 (감정적 반응)
    'happiness', # 행복 (감정적 반응)
    'disgust',   # 혐오 (감정적 반응)
    'neutral'    # 중립 (균형 상태)
]

2.2 로빙 철학과의 연결

  • 기본정서 (100ms): fear, surprise, anger → 즉발 반응
  • 사회기능 (500ms): sadness, happiness, disgust → 숙고된 반응
  • 엔트로피 특이점: 높은 엔트로피 시 창발적 응답

3. 구현 아키텍처

3.1 서비스 확장 (Option A - 선택)

skill-embedding (포트 8515)
├── /embed (기존)
└── /analyze_emotion (신규)
    ├── 입력: text, user_id (optional)
    ├── 처리: 7개 감정 분석
    └── 출력: emotions, dominant, entropy, confidence

3.2 API 설계

// Request
POST /analyze_emotion
{
    "text": "오늘 프로젝트가 실패했어요",
    "user_id": "optional_for_caching"
}

// Response
{
    "emotions": {
        "fear": 0.15,
        "surprise": 0.05,
        "anger": 0.25,
        "sadness": 0.35,
        "neutral": 0.10,
        "happiness": 0.05,
        "disgust": 0.05
    },
    "dominant": "sadness",
    "entropy": 2.31,
    "confidence": 0.35,
    "processing_time_ms": 87
}

4. 실행 계획

Phase 1-A: 기본 통합 (Day 1-2)

51123 서버 작업

# 1. 모델 준비
sudo mkdir -p /opt/models/emotion
sudo cp -r /path/to/training_emotion/outputs/aihub-7emotions-complete/* \
         /opt/models/emotion/
sudo chown -R admin:admin /opt/models/emotion

로컬 개발자 작업

# 2. emotion_analyzer.py 작성
from transformers import AutoModelForSequenceClassification, AutoTokenizer
import torch
import numpy as np

class EmotionAnalyzer:
    def __init__(self, model_path="/opt/models/emotion"):
        self.model = AutoModelForSequenceClassification.from_pretrained(model_path)
        self.tokenizer = AutoTokenizer.from_pretrained(model_path)
        self.temperature = 1.232  # from calibration
        self.emotions = ['fear', 'surprise', 'anger', 'sadness', 
                        'neutral', 'happiness', 'disgust']
    
    async def analyze(self, text: str) -> dict:
        inputs = self.tokenizer(text, return_tensors="pt", 
                               max_length=512, truncation=True)
        
        with torch.no_grad():
            logits = self.model(**inputs).logits
            probs = torch.softmax(logits / self.temperature, dim=-1)
        
        emotion_scores = {
            emotion: float(probs[0][i]) 
            for i, emotion in enumerate(self.emotions)
        }
        
        dominant = max(emotion_scores, key=emotion_scores.get)
        entropy = self._calculate_entropy(list(emotion_scores.values()))
        
        return {
            "emotions": emotion_scores,
            "dominant": dominant,
            "entropy": entropy,
            "confidence": emotion_scores[dominant]
        }
    
    def _calculate_entropy(self, probs):
        probs = np.array(probs)
        probs = probs[probs > 0]
        return -np.sum(probs * np.log(probs))

51124 서버 작업

# 3. docker-compose.yml 수정
services:
  skill-embedding:
    volumes:
      - /opt/models:/opt/models:ro
    environment:
      - EMOTION_MODEL_PATH=/opt/models/emotion

Phase 1-B: 최적화 (Day 3-4)

ONNX 변환

# 로컬 개발자
python convert_to_onnx.py \
    --model_path /opt/models/emotion \
    --output_path /opt/models/emotion-onnx \
    --optimize

캐싱 구현

from functools import lru_cache
import hashlib

class CachedEmotionAnalyzer(EmotionAnalyzer):
    @lru_cache(maxsize=1000)
    def _analyze_cached(self, text_hash: str):
        # 실제 분석 로직
        pass
    
    async def analyze(self, text: str, user_id: str = None):
        text_hash = hashlib.md5(text.encode()).hexdigest()
        cache_key = f"{user_id}:{text_hash}" if user_id else text_hash
        return self._analyze_cached(cache_key)

Phase 1-C: 통합 (Day 5)

rb10508_micro 연동

# Slack 메시지 처리 시
async def process_slack_message(text: str, user_id: str):
    # 1. 감정 분석
    emotion_result = await call_emotion_api(text, user_id)
    
    # 2. ChromaDB 메타데이터 추가
    metadata = {
        "user_id": user_id,
        "timestamp": datetime.now().isoformat(),
        "emotions": emotion_result["emotions"],
        "dominant_emotion": emotion_result["dominant"],
        "emotional_entropy": emotion_result["entropy"]
    }
    
    # 3. 응답 톤 조정
    response_tone = adjust_tone_by_emotion(emotion_result["dominant"])
    
    return generate_response(text, tone=response_tone)

5. 성능 목표 및 측정

5.1 목표 지표

  • 응답시간: < 200ms (캐시 미스), < 50ms (캐시 히트)
  • 정확도: 체감 정확도 > 70%
  • 메모리: < 1.5GB 총 사용량
  • 처리량: > 10,000 요청/일

5.2 측정 방법

# 성능 테스트
curl -w "@curl-format.txt" \
     -X POST http://localhost:8515/analyze_emotion \
     -H "Content-Type: application/json" \
     -d '{"text":"테스트 메시지"}'

# 부하 테스트
locust -f tests/load_test.py --users 10 --spawn-rate 2

6. 리스크 관리

6.1 잠재 위험

위험 요소 영향도 대응 방안
모델 크기 (442MB) ONNX 변환으로 150MB로 축소
메모리 부족 모델 공유, 캐싱 최적화
낮은 정확도 (56.3%) confidence 임계값 설정
Cold start 서비스 시작 시 프리로드

6.2 폴백 전략

  • confidence < 0.3일 때 neutral로 분류
  • 엔트로피 > 2.8일 때 "복잡한 감정" 표시
  • 오류 시 감정 분석 스킵하고 진행

7. 작업 분담

51123 서버 (시스템 관리)

  • 모델 파일 /opt/models 배치
  • 배포 파이프라인 설정
  • 시스템 모니터링
  • 문서화

로컬 개발자 (코드 구현)

  • emotion_analyzer.py 작성
  • FastAPI 엔드포인트 추가
  • ONNX 변환 스크립트
  • rb10508_micro 연동

51124 서버 (서비스 운영)

  • Docker 이미지 빌드
  • 서비스 배포
  • 로그 모니터링
  • 성능 측정

8. 검증 계획

8.1 단위 테스트

def test_emotion_analysis():
    analyzer = EmotionAnalyzer()
    result = analyzer.analyze("정말 기쁜 하루였어요!")
    assert result["dominant"] == "happiness"
    assert result["confidence"] > 0.5

8.2 통합 테스트

  • Slack 메시지 → 감정 분석 → ChromaDB 저장
  • 다양한 감정 텍스트 100개 테스트
  • 응답 시간 측정

9. 다음 단계 (Phase 2 준비)

  • 감정 기반 대화 전략 수립
  • 장기 감정 패턴 분석
  • 사용자별 감정 프로파일
  • 멀티모달 감정 분석 (이미지, 음성)

10. 성공 기준

Phase 1 완료 조건:

  1. 7개 감정 분석 API 정상 작동
  2. 평균 응답시간 < 200ms
  3. rb10508_micro 통합 완료
  4. ChromaDB 메타데이터 저장 확인
  5. 100개 테스트 케이스 통과

시작일: 2025년 8월 13일 (예정)
완료일: 2025년 8월 17일 (목표)