우리의 AI 얼굴 평가 도구를 위해 두 개의 스코어링 트랙(LLM + Mediapipe)을 운영하는 이유
요약
본 글은 AI 얼굴 평가 도구의 신뢰성을 높이기 위해 단일 LLM 스코어링 방식이 가진 비결정론적 분산 문제(Variance Problem)를 분석하고, 이를 해결하기 위한 아키텍처 개선 방안을 제시합니다. 핵심 해결책은 주관적인 미적 판단을 담당하는 LLM 트랙과 기하학적으로 결정 가능한 수치 측정(Mediapipe Face Mesh 등)을 기반으로 하는 병렬의 '기하학적 스코어링 트랙' 두 개를 운영하는 것입니다. 최종 점수는 이 두 트랙의 가중 평균 및 불일치 감지 로직을 통해 산출되어, 사용자 경험과 결과의 안정성을 크게 향상시킵니다.
핵심 포인트
- LLM 기반 주관적 평가는 호출마다 분산(Variance)이 발생하여 일관된 UX를 제공하기 어렵다.
- 분산을 해결하기 위해 기하학적으로 결정 가능한 수치 측정(Canthal tilt, Jaw angle 등)을 Mediapipe Face Mesh로 활용하는 병렬 트랙을 추가했다.
- 최종 점수는 LLM의 미적 판단 스코어와 기하학적 구조 스코어를 가중 평균(예: 0.6 * Geometric + 0.4 * LLM)하여 산출한다.
- 기하학적 점수가 결정론적 기준점 역할을 하므로, 불일치 감지 로직을 통해 예외적인 케이스를 포착하고 보수적으로 접근할 수 있다.
- 향후에는 사진 품질 신호에 기반한 축별 동적 가중치(per-axis dynamic weighting) 방식으로 개선될 예정이다.
한 사용자가 동일한 사진으로 우리의 얼굴 평가 도구를 연속 5번 테스트했습니다. 그 결과 6.2, 7.5, 6.8, 7.1, 5.9라는 점수를 받았습니다. 동일한 입력값임에도 불구하고 ±0.8의 편차가 발생한 것입니다. 그 이메일은 우리에게 단일 LLM (Large Language Model) 스코어링 방식의 종말을 알렸습니다. 이 글은 우리가 최종적으로 내린 아키텍처 결정, 즉 두 개의 병렬 스코어링 트랙을 실행하고 LLM의 환각 (Hallucination)에 맞서 기하학적(Geometric) 수치를 앵커(Anchor)로 사용하는 방식에 대한 짧은 글입니다.
분산 문제 (The variance problem)
LLM을 이용한 주관적인 얼굴 점수 매기기는 근본적으로 비결정론적 (Non-deterministic)입니다. 매 호출마다 잠재 공간 (Latent space)을 다시 샘플링하기 때문입니다. "이 얼굴을 1~10점으로 평가하라"와 같이 결정론적으로 느껴져야 하는 작업에서 이러한 분산은 UX (User Experience)를 망치는 요소입니다. 사용자들은 자신의 얼굴이 확률 분포가 아닌 단 하나의 점수를 갖기를 기대합니다.
우리가 시도했지만 효과가 없었던 일반적인 해결책들:
- Temperature 낮추기: temperature=0일 때 도움이 되었으나, 내부 벡터 표현 (Internal vector representations)이 미세하게 다르기 때문에 모델은 여전히 호출마다 변동되었습니다.
- 자기 일관성 (Self-consistency, 5회 호출 + 다수결): 분산을 30% 줄이기 위해 API 비용이 5배로 증가했습니다. 충분하지 않았습니다.
- 보정용 얼굴을 활용한 퓨샷 앵커링 (Few-shot anchoring with calibration faces): 평균 점수에는 도움이 되었으나 개별 분산 문제에는 도움이 되지 않았습니다.
이중 트랙 해결책 (The dual-track fix)
효과가 있었던 방법: 기하학적으로 결정 가능한 부분에 LLM을 사용하는 것을 중단하는 것이었습니다. 우리는 Mediapipe Face Mesh를 사용하여 병렬적인 기하학적 트랙을 추가했습니다:
- 내안각 경사 (Canthal tilt, 눈꼬리 각도): 얼굴 랜드마크 (Landmarks)로부터 ±2도 이내로 측정 가능합니다.
- 턱 각도 (Jaw angle, 턱 끝에서 귀까지의 하악각): 호출 간에 일관적입니다.
- 대칭성 (Symmetry, 좌우 반쪽 사이의 Hausdorff distance): 순수 산술 계산입니다.
이 세 가지 측정치는 주어진 입력 이미지에 대해 결정론적인 0~10 사이의 하위 점수 (Sub-score)로 매핑됩니다. 이는 취향을 포착하지는 못하지만, 기하학적 구조는 포착합니다.
LLM 트랙은 유지됩니다. 하지만 이제는 미적 판단 레이어 (Aesthetic-judgment layer)를 담당합니다: 피부 상태 평가, 헤어스타일 적합성, 얼굴 조화 인지 등 측정값이 아닌 학습 데이터에 기반한 패턴 인식 (Pattern recognition)이 진정으로 필요한 영역들입니다.
결합 (The combination)
우리는 두 점수를 평균 내지 않습니다.
우리는 다음과 같이 구성합니다:
final_score = 0.6 * geometric_score + 0.4 * llm_aesthetic_score
if abs(geometric - llm) > 2.0:
flag_for_review(f"disagreement: G={geometric}, L={llm}")
use_lower_score() # 보수적으로 접근
0.6/0.4 가중치는 경험적으로 도출되었습니다. 기하학적 점수(geometric score)가 결정론적 기준점(deterministic anchor) 역할을 하기 때문에 더 높은 비중을 가집니다. 불일치 감지(disagreement detection)는 예외적인 케이스(edge cases)를 잡아냅니다 (예: LLM은 '존재감(presence)' 항목에서 높은 점수를 주었으나 기하학적 수치는 좋지 않은 경우 — 대개 우리가 정확하게 점수를 매길 준비가 되지 않은 카리스마 있는 사진인 경우입니다).
결과 변동성(Variance)은 동일한 입력값에 대해 단일 LLM 사용 시 ±0.8에서 이중 트랙(dual-track) 사용 시 ±0.5로 나타났습니다. 0이 되지는 않았지만, 사용자가 기대하는 수준에 훨씬 가까워졌습니다.
보너스: 기하학적 점수를 통해 우리는 실행 가능한 피드백(actionable feedback)을 제공할 수 있습니다. 블랙박스(black-box) 형태인 LLM이 "눈을 감은 것처럼 보입니다"라고 말하는 것보다, "안각 기울기(Canthal tilt) -3°, 각도를 조절한 셀카를 고려해보세요"라고 말하는 것이 훨씬 낫습니다.
다르게 시도해 볼 점
0.6/0.4 가중치는 전역적(global)이 아니라 축(axis)별로 적용되어야 합니다. 피부를 찍은 고해상도 근접 사진은 LLM의 미적 인지(aesthetic perception) 쪽으로 가중치를 옮겨야 합니다. 조명이 좋지 않은 작은 셀카는 기하학적 점수 쪽으로 가중치를 옮겨야 합니다 (나쁜 사진에 대한 LLM의 판단은 대부분 노이즈이기 때문입니다). 우리는 현재 사진 품질 신호(photo quality signals)에 기반한 축별 동적 가중치(per-axis dynamic weighting) 방식으로 이를 리팩터링(refactoring)하고 있습니다.
직접 체험해보기
이중 트랙 스코어링(dual-track scoring)이 실제로 어떻게 작동하는지 보고 싶다면, AI Omoggle을 시도해 볼 수 있습니다 — 단일 테스트 $0.99, 구독 없음, 사진 저장 안 함. 주관적인 작업에서 다른 사람들은 LLM 변동성(LLM-variance) 문제를 어떻게 해결했는지 진심으로 듣고 싶습니다.
AI 자동 생성 콘텐츠
본 콘텐츠는 Dev.to AI tag의 원문을 AI가 자동으로 요약·번역·분석한 것입니다. 원 저작권은 원저작자에게 있으며, 정확한 내용은 반드시 원문을 확인해 주세요.
원문 바로가기