본문으로 건너뛰기

모델 설명 (실시간 SHAP XAI)

배포된 모델의 예측을 실시간 Top-K SHAP 설명으로 해석하고, 격리된 샌드박스에서 What-if 실험(입력값을 바꿔가며 설명이 어떻게 변하는지)을 수행하는 워크플로우를 안내합니다. 신용평가·여신심사처럼 "왜 이 예측이 나왔는가"를 근거와 함께 제시해야 하는 시나리오를 위한 기능입니다.

모델 설명 페이지 진입

이 기능이 푸는 문제

요구GenD 구현
모델 버전별 설명기 사전 생성MLflow run 에 explainer/explainer.pkl 아티팩트로 부착 + gend.explainer=ready 태그
예측 서비스 ↔ 설명 서비스 분리설명 전용 런타임 gend-xai 가 예측 predictor 와 독립 배포·확장·장애격리
Top-K 중심 빠른 실시간 설명tree 모델은 shap.TreeExplainer 로 ms 단위 계산, 기여도 상위 K개만 반환
격리 샌드박스 What-if입력 섭동 → 예측+설명 재계산 → 시나리오 저장/비교 (원본 서빙 트래픽과 분리)
입력·모델버전·데이터버전·설명결과 감사모든 explain 호출이 HMAC 체인 감사 로그로 기록 (재현 3-tuple)

사전 준비

  • 관리자 또는 analyst 역할로 로그인
  • tree 기반 모델이 배포되어 있을 것 (예: demo_credit_risk — GradientBoosting 신용위험 데모)
  • 해당 모델 버전에 SHAP explainer 아티팩트가 생성되어 있을 것

데모 환경 시드:

# 1) tree 기반 demo_credit_risk 모델 등록 (GradientBoostingClassifier)
make seed-demo-ml

# 2) Phase 1 explainer asset materialize — explainer.pkl 생성 + gend.explainer=ready 태그
# Dagster UI 에서 demo_credit_risk_explainer asset 을 실행하거나 job 을 launch
왜 tree 모델인가

실시간 SHAP 의 핵심은 TreeExplainer 입니다. 트리 앙상블(GradientBoosting·RandomForest 등)은 정확한 SHAP 값을 ms 단위로 계산할 수 있어 "실시간 설명"이 가능합니다. 선형 모델(LogisticRegression)은 TreeExplainer 대상이 아니므로, 데모 신용 모델은 GradientBoosting 으로 구성되어 있습니다.

입력은 학습 분포와 같은 스케일이어야 한다

demo_credit_risk사람단위 실제 범위(age 18–70 · income 15k–150k · credit_history_len 0–30)로 학습됩니다. 트리 모델의 SHAP 은 구간상수(piecewise-constant)라, 입력이 학습된 split threshold 를 넘지 못하면 예측·설명이 값 그대로 동일하게 나옵니다. 데모 모델을 표준정규(~[-3, 3]) 같은 다른 스케일로 학습해 두고 age=35·income=50000 같은 사람단위 값을 서빙하면, 모든 split 을 지나쳐(saturate) 무엇을 입력해도 예측·SHAP 이 변하지 않는 것처럼 보입니다. What-if 를 실습할 때는 아래 세 페르소나처럼 학습 분포 안의 값을 사용하세요.

페르소나ageincomecredit_history_len기대 예측
저리스크2530,0002거절(0)
중간4580,00012경계(0)
고리스크65140,00025승인(1)

세 페르소나는 회귀 가드 E2E(ui/tests/whatif-responsiveness-e2e.spec.ts, 시드 픽스처 ui/tests/whatif-personas.ts)의 데이터 소스이자 이 문서 스크린샷의 캡처 소스입니다.

1. 모델 선택

ML 허브 → 모델 → 모델 설명 탭(/ml-hub/models?tab=explain)으로 이동합니다. ready 상태의 배포가 칩 목록으로 표시되며, 칩을 클릭하거나 입력란에 엔드포인트 이름을 입력하고 적용 을 누릅니다.

호출 권한이 없는 모델

호출(ModelGrant.invoke) 권한이 없는 배포는 칩이 비활성화되고 권한 없음 배지가 함께 표시됩니다. 비활성 칩을 클릭하면 선택되는 대신 관리자에게 권한을 요청하라는 안내가 표시됩니다 — 제출 후 403 을 만나는 막다른 길을 사전에 차단합니다.

2. 피처 입력 → Top-K 설명

모델을 선택하면 피처 입력 폼이 나타나고, 학습 시점 피처 스키마를 조회해 피처 이름이 자동으로 채워집니다 — 값만 입력하면 됩니다. 모든 피처에 값이 입력되면 짧은 디바운스 후 설명이 자동 계산됩니다. 일부 값이 비어 있으면 "값 입력 대기 중: …" 안내가 표시되고 호출되지 않습니다.

피처 입력 폼 — 스키마 자동 채움

JSON 으로 직접 붙여넣고 싶으면 JSON 붙여넣기 토글을 사용합니다. 폼 ↔ JSON 전환 시 입력이 보존되고, 잘못된 JSON 은 입력을 유지한 채 인라인 오류로 표시됩니다.

{ "age": 35, "income": 50000, "credit_history_len": 5 }

입력이 완성되면 화면에 Top-K SHAP bar 가 렌더됩니다. 각 막대는 해당 feature 가 예측을 양(+)/음(−) 방향으로 얼마나 밀었는지를 나타내며, 막대 라벨에 피처 = 입력값 이 함께 표시되어 기여도와 입력을 한눈에 읽을 수 있습니다.

카드 헤더에는 모델/버전·기준값(base value)과 함께 예측값(회귀) 또는 예측 클래스(분류)가 표시됩니다. ⓘ 아이콘에 마우스를 올리면 기준값·기여도의 단위(모델 원시 출력 공간, 예: log-odds)와 "기준값 + 기여도 합 = 원시 출력" 관계를 설명하는 도움말을 볼 수 있습니다.

Top-K SHAP 설명

3. What-if 시나리오 (격리 샌드박스)

What-if 패널에서 feature 값을 바꾸면 예측과 설명이 즉시 재계산됩니다. 분석에 쓰는 샘플 데이터만 실시간으로 재예측하므로, 운영 중인 예측 서비스 트래픽에는 영향을 주지 않습니다. 비교의 기준(베이스라인)은 폼/JSON 으로 입력한 섭동 전 원본 instance 의 설명 스냅샷으로 고정되므로, 값을 여러 번 바꿔도 항상 "원본 대비" 변화를 읽을 수 있습니다.

따라 해보기 — 저리스크 → 고리스크:

  1. 베이스라인으로 저리스크 페르소나(age 25 · income 30,000 · credit_history_len 2)를 입력합니다. 헤더의 예측 클래스는 0(거절), Top-K 에서 age·income 이 예측을 아래로(−) 밀고 있습니다.
  2. What-if 입력을 고리스크(age 65 · income 140,000 · credit_history_len 25)로 바꾸면 — 1개 변경됨 배지가 뜨고 짧은 디바운스 후 헤더 예측이 1(승인) 로 뒤집히며, 같은 피처들의 SHAP 부호가 양(+)으로 바뀝니다. 입력이 결과를 실제로 움직이는 것을 한 화면에서 확인할 수 있습니다.
  3. 시나리오 저장 을 누르면 섭동 입력이 재예측·재설명되어 비교표에 한 행으로 추가되고, 베이스라인 행과 나란히 예측값·주요 feature 가 대비됩니다.

What-if 시나리오 비교 — 베이스라인(저) vs 시나리오(고)

비교표에서 한 행을 클릭하면 베이스라인 대비 Top-K 기여도가 좌우로 나란히 그려져, 어떤 피처가 얼마나 달라졌는지 부호·크기까지 비교할 수 있습니다.

기준 vs 시나리오 — Top-K 기여도 나란히 비교

What-if 시나리오 평가의 서빙 전제조건

시나리오 저장은 섭동 입력을 재예측 + 재설명합니다. 재설명(Top-K)은 gend-xai 가 처리하지만, 재예측은 배포된 KServe 예측 엔드포인트를 호출합니다. 따라서 What-if 시나리오 평가는 (1) 예측 엔드포인트가 v2(Open Inference Protocol) 로 노출되어 feature-dict 어댑터의 모델 메타데이터 조회가 가능하고, (2) 서빙 런타임의 sklearn 버전이 모델 학습 버전과 정합해야 합니다. 설명(Top-K)만 필요하면 예측 엔드포인트 없이도 동작합니다.

아키텍처 노트

  • 분리 런타임: 설명은 gend-api 가 직접 계산하지 않고 클러스터 내부의 gend-xai Service(gend-xai.<ns>.svc.cluster.local/explain)로 위임됩니다. explainer 아티팩트가 아직 없으면 gend-xai 는 graceful 503 을 반환하고, 시드 후 정상 Top-K 를 반환합니다.
  • 데이터 버전: 설명 감사 로그의 data_version 은 모델이 학습된 MLflow run_id 입니다 — 같은 입력·같은 모델버전·같은 데이터버전이면 같은 설명이 재현됩니다.
  • 감사: 모든 explain 호출은 입력 해시·모델명·모델버전·데이터버전·Top-K 와 함께 HMAC 체인 감사 로그(→ OpenSearch WORM)로 기록됩니다.

관련 문서