- 모든 .md, .html 파일 권한을 644로 정상화 - .gitignore 파일 권한도 644로 수정 - 문서 파일에 실행 권한은 불필요하고 보안상 바람직하지 않음 - deprecated 아이디어 폴더 생성 및 레벨별 UI 변경 아이디어 이동
13 KiB
13 KiB
로빙 감정 시스템 현실 적용 5단계 로드맵
작성자: happybell80 & Claude
목적: 감정 시스템 설계서를 현실적으로 구현 가능한 단계별 계획으로 구체화
핵심 원칙
- MVP 우선: 복잡한 기능보다 작동하는 기본 기능
- 측정 가능한 성과: 각 단계마다 명확한 KPI
- 점진적 복잡도: 단순 → 복잡으로 진화
- 서비스 분리: 단일 장애점 방지
- 함수형 프로그래밍 100%: 하드코딩 0% 목표. 근거없는 하드코딩 값 절대 사용 금지
- 모든 값은 설정 파일이나 환경변수에서 로드
- 순수 함수 체인으로 구성
- 상태 변경 최소화, 불변성 유지
Phase 1: 7개 감정 기본 구현 (모델 준비 완료, 통합 대기)
목표
"이미 학습된 7개 한국어 감정 모델을 skill-embedding에 통합"
진행 현황 (2025-08-15 기준)
- ✅ 모델 학습 완료 (F1 56.3%)
- ✅ ONNX 변환 완료 (442MB)
- ⏳ skill-embedding 서비스 통합 대기
- ⏳ /emotion 엔드포인트 구현 필요
구현 범위
# AI Hub 데이터로 학습 완료된 7개 감정
EMOTIONS = [
"fear", # 공포 (기본정서)
"surprise", # 놀람 (기본정서)
"anger", # 분노 (기본정서)
"sadness", # 슬픔
"neutral", # 중립
"happiness", # 행복
"disgust" # 혐오
]
# 모델 성능: F1 56.3%, Temperature Scaling 1.232
# 엔트로피 계산 (7개 감정)
def calculate_entropy(probs: List[float]) -> float:
"""7개 감정 확률값으로 엔트로피 계산"""
return -sum(p * log(p) for p in probs if p > 0)
기술 스택
- 감정 모델: klue/bert-base 기반 → ONNX 변환 완료
- 서비스: skill-embedding 확장 (포트 8515, /emotion 추가)
- 저장: 기존 ChromaDB 활용 (메타데이터에 감정 추가)
- 의사결정: 엔트로피 기반 복잡도 판단
- 기존 코드: rb10508_micro의 memory/storage.py 재사용
- 설정값: confidence=0.35, entropy=2.0, temperature=1.232
성능 목표
- 응답시간: 500ms 이내
- 정확도: 사용자 평가 3.5/5.0
- 메모리: 200MB 이내
데이터 준비 (완료)
- AI Hub 한국어 대화 데이터셋 38,594개 샘플
- 7개 감정 균형 분포
- 학습/검증/테스트 분할 완료
- 클래스 가중치 적용
검증 방법
# 단위 테스트
pytest tests/test_basic_emotions.py
# 부하 테스트
locust -f tests/load_test.py --users 10
# 응답시간 측정
curl -w "@curl-format.txt" http://localhost:8503/analyze
산출물
- 7개 감정 모델 학습 완료 (training_emotion) ✅ 2025-08-08
- ONNX 변환 완료 (442MB) ✅ 2025-08-13
- 모델 파일 51124 서버 배치 완료 ✅ 2025-08-13
- skill-embedding 서비스에 /emotion 엔드포인트 추가 ⏳
- Temperature Scaling 적용 (1.232) ⏳
- 엔트로피 계산기 구현 ⏳
- ChromaDB 메타데이터 통합 ⏳
- rb10508_micro 연동 ⏳
아키텍처 결정 사항 (2025-08-12)
문제: 감정 분석을 어디에 구현할 것인가?
- Option A: 별도 skill-emotion 서비스 (아키텍처 원칙)
- Option B: skill-embedding에 통합 (자원 효율성)
최종 결정: skill-embedding에 통합
- 이유: ONNX Runtime 공유, 메모리 200MB 절약, 레이턴시 감소
- 트레이드오프: 서비스 역할 혼재 vs 실용성
- 향후: 서비스명 변경 고려 (skill-embedding → skill-ai)
현재 보유 모델 (2025-08-15)
-
aihub-7emotions (메인 모델)
- 크기: 442MB (ONNX)
- 감정: fear, surprise, anger, sadness, neutral, happiness, disgust
- 성능: F1 56.3%, ECE 0.090
- 위치: /home/admin/ivada_project/onnx_models/aihub-7emotions/
-
korean-sentiment-kcelectra (보조 모델)
- 크기: 511MB (ONNX)
- 감정: 11개 한국어 세분화 감정
- 성능: F1 70.72%
- 위치: /home/admin/ivada_project/onnx_models/korean-sentiment-kcelectra/
Phase 2: 서비스 통합 및 최적화
목표
"skill-embedding 서비스 통합, 캐싱 구현, rb10508_micro 연동"
우선 작업 (로컬 개발자)
- skill-embedding에 /emotion 엔드포인트 추가
- ONNX 모델 로딩 및 추론 코드 구현
- Temperature Scaling (T=1.232) 적용
- rb10508_micro에서 감정 API 호출 통합
최적화 전략
# LRU 캐시 적용
from functools import lru_cache
@lru_cache(maxsize=1000)
def get_emotion_embedding(text: str) -> np.ndarray:
"""자주 사용되는 텍스트의 임베딩 캐싱"""
return model.encode(text)
# 배치 처리
async def batch_analyze(texts: List[str]):
"""여러 텍스트 동시 처리"""
embeddings = model.encode(texts, batch_size=32)
return [analyze_emotion(emb) for emb in embeddings]
ChromaDB 튜닝
- 인덱스 최적화: HNSW 파라미터 조정
- 쿼리 최적화: top-k를 10으로 제한
- 연결 풀링: 커넥션 재사용
프로파일링
# 병목 지점 찾기
import cProfile
import pstats
cProfile.run('analyze_emotion(text)', 'profile_stats')
stats = pstats.Stats('profile_stats')
stats.sort_stats('cumulative').print_stats(10)
성능 목표
- 응답시간: 200ms (60% 개선)
- 동시 처리: 50 req/s
- 캐시 적중률: 30%
산출물
- ONNX 모델 변환 완료 (442MB) ✅
- skill-embedding /emotion 엔드포인트 구현 ⏳
- LRU 캐시 시스템 (5분 TTL)
- 배치 처리 API
- ChromaDB 감정 메타데이터 인덱싱
- 성능 모니터링 (Grafana)
- rb10508_micro 감정 기반 응답 톤 조정
Phase 3: 감정 패턴 분석 및 개인화
목표
"장기 감정 패턴 추적, 사용자별 감정 프로파일 구축"
감정 패턴 분석
# 시간별 감정 추적
class EmotionTracker:
def __init__(self, user_id: str):
self.user_id = user_id
self.history = [] # 시계열 감정 데이터
def track(self, emotion_result: dict):
"""감정 결과를 시계열로 저장"""
self.history.append({
"timestamp": datetime.now(),
"emotions": emotion_result["emotions"],
"dominant": emotion_result["dominant"],
"entropy": emotion_result["entropy"]
})
def get_pattern(self, period: str = "day"):
"""일/주/월 단위 감정 패턴 분석"""
# 시간대별 주요 감정
# 감정 변화 추이
# 엔트로피 패턴
return analyze_temporal_pattern(self.history, period)
개인화 전략
- 사용자별 감정 프로파일 생성
- 감정 응답 히스토리 학습
- 개인별 감정 임계값 조정
- 엔트로피 특이점 활용 (창발적 응답)
엔트로피 기반 의사결정
class EntropyBasedDecision:
def __init__(self):
self.entropy_threshold = 2.5 # 특이점 임계값
def should_be_creative(self, entropy: float) -> bool:
"""높은 엔트로피일 때 창의적 응답"""
return entropy > self.entropy_threshold
def adjust_response(self, response: str, emotion_result: dict):
"""감정에 따른 응답 톤 조정"""
if emotion_result["dominant"] == "sadness":
return make_empathetic(response)
elif emotion_result["dominant"] == "anger":
return make_calm(response)
elif self.should_be_creative(emotion_result["entropy"]):
return make_creative(response)
return response
성능 목표
- 패턴 분석: 일 1회 배치 처리
- 프로파일 업데이트: 실시간
- 감정 히스토리: 30일 보관
- 개인화 정확도: 70% 이상
산출물
- 감정 패턴 분석기
- 사용자 감정 프로파일 DB
- 엔트로피 기반 의사결정 모듈
- 시계열 감정 시각화
- 개인화 응답 전략
Phase 4: 베이지안 학습 시스템
목표
"실시간 학습과 개인화된 감정 모델 구축"
베이지안 파라미터
class BayesianEmotionModel:
def __init__(self):
# Dirichlet 사전분포 (9개 감정)
self.emotion_prior = np.ones(9)
# Beta 분포 (저장 결정)
self.save_alpha = 1
self.save_beta = 1
# Gamma 분포 (응답 길이)
self.length_k = 2
self.length_theta = 50
def update_posterior(self, observation):
"""관측값으로 사후분포 업데이트"""
self.emotion_prior += observation['emotion_counts']
if observation['saved']:
self.save_alpha += 1
else:
self.save_beta += 1
# Gamma 업데이트 (moment matching)
self.length_k, self.length_theta = \
self.update_gamma(observation['response_length'])
예측-평가 루프
async def prediction_evaluation_loop(user_input):
# 1. 예측
prediction = model.predict_user_response(user_input)
# 2. 실제 응답 생성
actual_response = await generate_response(user_input)
# 3. 사용자 반응 수집
user_reaction = await collect_feedback()
# 4. 오차 계산 (3종)
kl_div = calculate_kl(prediction, user_reaction)
brier = calculate_brier(prediction, user_reaction)
ece = calculate_ece(prediction, user_reaction)
# 5. 모델 업데이트
if max(kl_div, brier, ece) > threshold:
model.update_posterior(user_reaction)
return actual_response
개인화
- 사용자별 베이지안 파라미터 저장
- 조직/팀/개인 3단계 계층 구조
- Cold start: 조직 평균값 사용
성능 목표
- ECE: ≤ 0.08
- Brier Score: ≤ 0.20
- 학습 수렴: 50회 상호작용
- 개인화 효과: +15% 만족도
산출물
- 베이지안 모델 클래스
- 예측-평가 파이프라인
- 3종 오차 메트릭
- 사용자별 파라미터 저장소
- 학습 곡선 분석
Phase 5: 프로덕션 및 확장
목표
"안정적인 프로덕션 배포와 고급 기능 추가"
프라이버시 게이트
class PrivacyGate:
def __init__(self):
self.pii_patterns = load_pii_patterns()
self.sensitive_topics = load_sensitive_topics()
def filter(self, text, metadata):
# PII 감지
if self.detect_pii(text):
return self.anonymize(text)
# 민감 주제 필터
if self.is_sensitive(text):
return {"summary": self.summarize(text),
"original": None}
# 24시간 옵트아웃
if metadata.get('opt_out_requested'):
return None
return text
모니터링 시스템
# prometheus metrics
metrics:
- emotion_analysis_duration_seconds
- emotion_cache_hit_ratio
- bayesian_update_count
- prediction_error_rate
- privacy_filter_triggers
alerts:
- name: HighECE
expr: emotion_ece > 0.1
for: 5m
- name: SlowResponse
expr: emotion_p95_latency > 500
for: 10m
고급 기능
- HDBSCAN 클러스터링 도입
- 감정 전환 패턴 학습
- 멀티모달 확장 준비 (음성/표정)
- 설명가능 AI (LIME/SHAP)
확장성
# 수평 확장 준비
class EmotionAnalyzerCluster:
def __init__(self, workers=4):
self.workers = workers
self.load_balancer = ConsistentHash()
async def analyze(self, text, user_id):
# 사용자별로 일관된 워커 할당
worker = self.load_balancer.get_worker(user_id)
return await worker.analyze(text)
최종 KPI
- ECE: ≤ 0.05
- Brier Score: ≤ 0.18
- NDCG@10: ≥ 0.6
- 응답시간 P95: ≤ 300ms
- 가용성: 99.9%
산출물
- 프라이버시 게이트 시스템
- Prometheus/Grafana 대시보드
- 수평 확장 아키텍처
- HDBSCAN 클러스터링
- 프로덕션 배포 (Docker/K8s)
- 운영 문서 및 Runbook
리스크 및 완화 방안
기술적 리스크
-
ChromaDB 성능 한계
- 완화: Redis 캐시 레이어 추가
- 대안: Pinecone/Weaviate 검토
-
모델 추론 속도
- 완화: ONNX 변환, 양자화
- 대안: DistilBERT 기반 경량 모델
-
베이지안 계산 복잡도
- 완화: 근사 알고리즘 사용
- 대안: 단순 EMA로 대체
데이터 리스크
-
라벨 품질
- 완화: 다중 라벨러, 합의 메커니즘
- 대안: 약지도 학습
-
개인정보 유출
- 완화: 로컬 처리, 암호화
- 대안: 연합 학습
운영 리스크
-
서비스 장애
- 완화: Circuit breaker, 폴백
- 대안: 기본 감정만 제공
-
비용 증가
- 완화: 사용량 기반 스케일링
- 대안: 엣지 디바이스 처리
성공 기준
Phase별 체크포인트
- Phase 1: 5개 감정 인식 작동 확인
- Phase 2: 200ms 응답시간 달성
- Phase 3: 9개 감정 정확도 80%
- Phase 4: 개인화 효과 측정 가능
- Phase 5: 프로덕션 안정성 99.9%
전체 프로젝트 성공 지표
- 사용자 만족도: NPS 40 이상
- 기술 성능: 모든 KPI 목표치 달성
- 비즈니스 가치: 사용자 이탈률 20% 감소
- 확장 가능성: 일 100만 요청 처리
이 로드맵은 이상적인 설계를 현실적으로 구현 가능한 단계로 나눈 실행 계획입니다. 각 Phase는 독립적으로 가치를 제공하며, 상황에 따라 중단하거나 방향을 전환할 수 있습니다.