Source:
report/version7/exp-expert/v7_stage05_gate5_redesign_v2.md
v7 Stage 0.5 Gate 5 — Redesign v2¶
0. 요약¶
| 항목 | 값 |
|---|---|
| v6 back-test 표본 | n = 22 converged runs (MIN_STEPS≥10, 14개 experiment 스캔) |
기존 metric moving/initial 의 v6 false-positive rate |
1.0 (22/22 FAIL — 수렴한 v6 run 전부 FAIL) |
| 새 metric | rel_decrease = (mean(val[:3]) − mean(val[-3:])) / mean(val[:3]) |
| v6 분포 (n=22) | p05 = −0.0005, p10 = 0.0017, p50 = 0.0350, p95 = 0.0949 |
| PASS cutoff | rel_decrease ≥ 0.0017 (v6 P10 → TPR 86.4%) |
| WARNING cutoff | 0.0 ≤ rel_decrease < 0.0017 (v6 P05~P10 → TPR 90.9% 합산) |
| FAIL cutoff | rel_decrease < 0.0 (net increase — 수렴 방향 반대) |
| 9-run smoke 재평가 | PASS 5 / WARNING 1 / FAIL 3 / ERROR 0 |
| Stage 1 권고 | HOLD (FAIL 3개 = A3 cell 전 seed 발산 신호) |
1. Critic CR1~CR4 resolve 내역¶
| CR | 요구 | 이행 | 증거 |
|---|---|---|---|
| CR1 | metric 자체 재설계 (threshold 완화 금지, monotonic decrease 기반) | rel_decrease 도입, smoke/full 공통 사용(bifurcation 폐지), 3-tier 유지 |
§2 metric 정의, track_v7_design.md §3 Gate 5 개정 |
| CR2 | v6 n=22 back-test로 empirical cutoff 결정 | back-test 스크립트 실행, P10/P05 기반 cutoff 도출, legacy 대비 비교표 포함 | outputs/v7_stage05/v6_gate5_backtest.{py,csv,json}; PASS cutoff 0.0017, WARNING 0, FAIL < 0 |
| CR3 | design spec line 116 ↔ 151 내부 모순 해소 | §2.4 line 113-118에 "Gate 5 metric 근거" 서브블록 추가(ratio는 divergence-only), §3 Gate 5 (이전 line 151) 전면 재작성 | docs/reference/project_state/track_v7_design.md 개정 (line 105-135 + 해당 Gate 블록) |
| CR4 | Stage 1 진입 조건 명시 + 9-run smoke 재평가 | 새 cutoff로 smoke preview 실행, verdict 매트릭스 생성. FAIL 3개 → HOLD | outputs/v7_stage05/smoke_gate5_preview.json, §4 본문 |
추가 critic 요구 D (smoke에서 Gate 5 skip 옵션) — 기각 근거는 §5에 명시.
2. 새 Gate 5 Metric 정의¶
def evaluate_gate5(val_loss_series: list[float]) -> dict:
"""Return PASS/WARNING/FAIL/ERROR with rel_decrease value.
rel_decrease = (mean(vl[:3]) - mean(vl[-3:])) / mean(vl[:3])
Positive => improvement (convergence direction).
Requires len(vl) >= 6 (2 * block_size).
"""
k = 3
if len(val_loss_series) < 2 * k:
return {"verdict": "ERROR", "reason": "insufficient val_loss samples"}
initial = float(np.mean(val_loss_series[:k]))
final = float(np.mean(val_loss_series[-k:]))
if initial <= 0:
return {"verdict": "ERROR", "reason": "non-positive initial block mean"}
dec = (initial - final) / initial
if dec >= 0.0017: return {"verdict": "PASS", "rel_decrease": dec}
if dec >= 0.0: return {"verdict": "WARNING", "rel_decrease": dec}
return {"verdict": "FAIL", "rel_decrease": dec}
Block size 선택 근거 (k=3):
- smoke 최소 num_rounds=10 (B2/A3) 보장 → 초기 3 + 말미 3 분리 가능.
- 분산 축소용 평균. k=1은 singleton noise, k=5는 중간 dynamics 삼킴.
- B0 (local_epochs=5 × num_rounds=? = 50 samples) 에서도 k=3은 적절한 신호 추출.
Plateau-friendly 확인: - DLinear가 round 2~3에서 거의 plateau에 들어가도, 초기 3 round 평균이 말미 3 round 평균보다 미세하게라도 크면 PASS/WARNING. - Critic 포인트 5: "수렴 없음"과 "너무 빠른 수렴" 구별 가능 — plateau에 낮은 loss로 들어갔다면 rel_decrease > 0, plateau에 초기 loss를 넘어서 들어갔다면 rel_decrease < 0 → FAIL.
3. v6 n=22 Back-test 결과¶
스캔 대상: 14개 v6 MLflow experiment, total 110 runs 중 수렴 filter 통과 22개.
v6 rel_decrease 분포:
- min: −0.0147
- p05: −0.0005
- p10: +0.0017 ← PASS cutoff
- p25: +0.0101
- p50: +0.0350
- p75: +0.0814
- p95: +0.0949
- max: +0.0999
- mean: +0.0426, std: 0.0364
Cutoff 선택 규칙: - PASS = max(0, P10) = 0.0017 → v6 converged runs의 약 90%가 PASS. - WARNING = max(0, P05) = 0 → v6 converged runs의 약 95%가 WARNING 이상. - FAIL (net increase) = rel_decrease < 0 → v6에서도 2/22 (9.1%) run이 여기 해당. - 이 2개는 P05 아래 outlier (min −0.015, 그 다음 약 −0.001). - 즉 v6 "수렴 filter 통과" 기준이 느슨했음을 시사 — MIN_STEPS≥10만으로는 "실제 수렴"을 보장하지 않는다는 critic 통찰이 데이터로 확인됨.
Back-test verdict 분포: - PASS 19/22 (86.4%) - WARNING 1/22 (4.5%) - FAIL 2/22 (9.1%) - TPR (PASS+WARNING) = 90.9% ← 의도된 P10 근사치.
Legacy vs New 비교표:
| 지표 | Legacy moving/initial < 0.5 |
New rel_decrease ≥ 0.0017 |
|---|---|---|
| v6 PASS count | 0 / 22 | 19 / 22 |
| v6 false-positive rate | 1.0 | 0.091 |
| smoke/full 공통 사용 | 불가 (smoke n=10에선 ratio ≈ 1) | 가능 |
| plateau-friendly | ✗ | ✓ |
| net-increase 감지 | ✗ (ratio 1.05도 PASS 될 수 없지만 FAIL도 명확치 않음) | ✓ (FAIL < 0) |
4. 9-run smoke preview 재평가¶
Cutoff 적용 결과 (outputs/v7_stage05/smoke_gate5_preview.json):
| Cell | Seed | n samples | rel_decrease | Legacy ratio | New verdict |
|---|---|---|---|---|---|
| A3 | 42 | 10 | −0.01868 | 1.014 | FAIL |
| A3 | 43 | 10 | −0.01329 | 1.012 | FAIL |
| A3 | 123 | 10 | −0.01358 | 1.011 | FAIL |
| B0 | 42 | 50 | +0.03007 | 0.979 | PASS |
| B0 | 43 | 50 | +0.02972 | 0.975 | PASS |
| B0 | 123 | 50 | +0.01825 | 0.985 | PASS |
| B2 | 42 | 10 | +0.00121 | 1.000 | WARNING |
| B2 | 43 | 10 | +0.00975 | 0.995 | PASS |
| B2 | 123 | 10 | +0.00504 | 0.996 | PASS |
Tally: PASS 5 / WARNING 1 / FAIL 3 / ERROR 0.
4.1 관찰 (operational)¶
- A3 3 seeds 전부 FAIL — rel_decrease 모두 음수 (−0.013 ~ −0.019). val_loss가 round 0-2(≈0.64)에서 round 7-9(≈0.65~0.67)로 상승. 이는 단순한 metric 문제가 아니라 A3(full proposed: peak loss + VQ + DLinear)의 실제 발산 신호.
- Legacy
moving/initial ratio = 1.01로는 그저 "정체"처럼 보였지만, 새 metric은 증가 방향임을 노출. -
§2.4 val-divergence threshold 1.5× 는 ratio 1.01 수준으로는 trigger되지 않는다 → §2.4만으로는 이 문제를 포착 못 함이 입증됨. Gate 5는 §2.4를 보완하는 역할을 수행.
-
B0 3 seeds 전부 PASS — rel_decrease 0.018~0.030, v6 P25(0.010)와 P50(0.035) 사이. Local DLinear가 50 epochs에서 정상 수렴.
-
B2 borderline — rel_decrease 0.001~0.010, 1 WARNING + 2 PASS. Ditto λ regularization이 수렴 속도를 약간 늦춤.
4.2 Stage 1 진입 권고: HOLD (CR4 충족)¶
- FAIL 3개 → FAIL 1개라도 있으면 HOLD (새 §3 Gate 5 정책).
- A3 발산 원인 diagnosis가 단계 1 선행 조건.
- 이 결과는 critic 포인트 4("단계 1 FAIL ≥50%")가 옳았음을 data로 증명 — threshold 완화가 아닌 metric 재설계로도 A3가 FAIL인 건 진짜 문제라는 뜻.
후속 diagnosis 제안 (별도 사용자 결정 영역)¶
단계 1 진입 전 수행해야 할 작업 (exp-expert 권고): - [ ] A3 val_loss 상승 원인 조사 - peak-weighted loss scale ↑ 후 initial drop 없음? - VQ codebook init 불안정? - DLinear residual path의 gradient conflict? - [ ] A3 기본 lr/optimizer 점검 — B0 동일 lr에서 수렴하므로 cell-specific issue 개연성 ↑ - [ ] A3 10→25 rounds 확장 smoke 1개 seed — 추가 학습으로 회복 여부 확인
위 diagnosis는 단계 0.5 재smoke 1 cycle로 수행 가능 (설계 문서 재smoke buffer 소진).
5. Critic 추가 요구 D에 대한 입장¶
Critic은 "smoke에서 Gate 5 skip (G5: n/a, reason=smoke deferred)" 옵션을 명시적으로 검토하라 했다. 기각 근거:
- 새 metric은 smoke에서도 유의미한 신호를 주는 것으로 판명됨 (§4 A3 case).
- 만약 smoke skip을 선택했다면 A3 발산을 단계 1까지 못 알아챘을 것. 즉 Gate 5는 smoke에서 꼭 실행해야 하는 gate.
- "smoke에서 수렴 강제 불가"라는 우려는 cutoff가 엄격했을 때의 문제였으며, 새 cutoff(PASS ≥ 0.0017, 즉 0.17% improvement)는 v6에서 90.9% run이 통과할 정도로 관대함.
- 결론: Gate 5는 smoke에서 active 유지. Skip 옵션은 불필요.
6. Design spec diff 요약¶
docs/reference/project_state/track_v7_design.md:
§2.4 (line 113-118) — after 추가 블록¶
- Gate 5 metric 근거 (§3 단계 0.5 참조, 2026-04-20 redesign):
위 final_val_loss / initial_val_loss 분포(p50=0.929)는 "divergence 여부"를
가리는 §2.4 지표로만 쓰이며, Gate 5 convergence 판정에는 쓰이지 않는다.
Gate 5는 새 rel_decrease 지표를 사용하며 ...
§3 단계 0.5 Gate 5 (이전 line 151) — 전면 재작성¶
Before:
After:5. 수렴성 — monotonic-decrease metric (2026-04-20 v3 redesign):
rel_decrease = (mean(val_loss[:3]) - mean(val_loss[-3:])) / mean(val_loss[:3])
- PASS: rel_decrease >= 0.0017 (v6 n=22 P10; TPR 86.4%)
- WARNING: 0.0 <= rel_decrease < 0.0017
- FAIL: rel_decrease < 0.0 (net increase)
- smoke/full 공통. 근거: outputs/v7_stage05/v6_gate5_backtest.json
- Legacy moving/initial < 0.5는 v6 n=22 중 0건 PASS이므로 폐기.
§3 단계 0.5 FAIL 처리 블록 — 새 서브블록¶
§2.4 divergence detector와 §3 Gate 5 convergence verifier의 분담 관계를 3줄로 정리.
수정하지 않은 부분¶
- §2.4 7-metric 표 본체:
final_val_loss / initial_val_loss > 1.5는 divergence detector로만 쓰이며 Gate 5와 목적이 다르므로 유지. - §2.4 line 114-116 (v6 분포 관찰값): 사실이므로 유지, 다만 주석으로 "Gate 5 근거 아님" 명기.
- 이로써 "line 116 vs line 151 내부 모순"은 해소 (둘은 서로 다른 지표의 근거).
ADR 불필요: design spec §2.4 + §3 직접 개정으로 커버 (범위가 단일 spec 내 일관성 확보).
7. Engineer 위임 경로¶
별도 문서 report/version7/exp-expert/v7_stage05_gate5_engineer_contract.md 참조. 요지:
experiments/federated/v7_stage05_smoke_analysis.py::evaluate_gate5—ff_val_initial_avg/ff_val_moving_avgmetric 사용을 버리고val_lossseries(MlflowClient.get_metric_history)로 전환.- Cutoff constants를 모듈 상단 상수로 추출 (PASS=0.0017, WARN=0.0, BLOCK=3) — 문헌 reference를 docstring으로.
tests/test_v7_stage05_smoke_analysis.py에 Gate 5 테스트 갱신/신규 3+개:- back-test 재현 (v6 n=22 cutoff 도출)
- 9-run smoke preview 재현 (PASS/WARN/FAIL 3/1/3 반환)
- edge case:
len(val_loss) < 6→ ERROR - pytest 전체 PASS 유지 증명 (verification-before-completion 규칙).
- 기존 9-run smoke에 재평가 실행 → Overall verdict 업데이트 (단 v7_runner 재실행 금지 — analysis-only).
8. 산출물 경로 (체크리스트)¶
-
outputs/v7_stage05/v6_gate5_backtest.py(실행 스크립트) -
outputs/v7_stage05/v6_gate5_backtest.csv(per-run decrease values) -
outputs/v7_stage05/v6_gate5_backtest.json(summary + cutoffs) -
outputs/v7_stage05/smoke_gate5_preview.py(9-run preview 스크립트) -
outputs/v7_stage05/smoke_gate5_preview.json(preview 결과) -
docs/reference/project_state/track_v7_design.md(§2.4 + §3 개정) -
report/version7/exp-expert/v7_stage05_gate5_redesign_v2.md(본 문서) -
report/version7/exp-expert/v7_stage05_gate5_engineer_contract.md(아래 별도 생성)
9. 최종 권고¶
| 항목 | 권고 |
|---|---|
| Gate 5 metric redesign | 채택 (monotonic decrease, v6 P10-based cutoff) |
| Design spec 개정 | 적용됨 (line 116/151 모순 해소) |
| Stage 1 진입 | HOLD (A3 3 seeds FAIL — A3 발산 diagnosis 필요) |
| 재smoke 권고 | 1 cycle (A3 lr/loss scale 조정 실험) |
| Engineer 실제 구현 | orchestrator가 별도 호출 — contract doc 준비 완료 |
cycle 2/2 완료. CR1~CR4 모두 해소. orchestrator는 (a) engineer를 호출하여 evaluate_gate5 구현 전환 및 (b) 사용자에게 "Stage 1 HOLD + A3 diagnosis" 권고를 전달하는 것을 제안한다.
작성자: exp-expert | 2026-04-20 | cycle 2/2