Fail-closed 게이트: 릴리스 게이트 설계 이야기
초안 — 검토용. CAFA-IVR 시리즈의 파트 5.
저자: Vijay Kumar Sridharan, IEEE Senior Member
파트 1부터 4까지는 측정 파이프라인을 구축했습니다: WER은 거짓말하고, CEER는 엔티티를 보고하며, ASR-IFR은 책임을 속성으로 부여하고, CIER는 결과를 가중합니다. 이 게시물은 마지막 구간 — 그 수치들을 배포 결정으로 바꾸는 것에 관한 것입니다. 그리고 v1.0에서 v1.1.0 사이의 변경된 한 줄짜리 설계 원칙에 관한 것이기도 합니다. 왜냐하면 첫 번째 버전이 그것을 잘못 이해했기 때문입니다.
원칙: 메트릭을 평가할 수 없는 품질 게이트는 통과하는 것이 아니라 실패해야 한다.
가장 비용이 많이 드는 게이트 결과
모든 릴리스 게이트에는 네 가지 가능한 결과가 있으며, 그중 오직 세 가지만 정직합니다:
- 빨간색(Red), 올바르게 — 후보군에 회귀(regressed)가 발생했습니다; 누군가 조사합니다.
- 초록색(Green), 올바르게 — 아무것도 회귀하지 않았습니다; 릴리스를 배포합니다.
- 빨간색(Red), 잘못되게 — 오탐지(false alarm); 누군가 조사하지만, 아무것도 발견하지 못하고, 지연되고 짜증을 내며 배포합니다.
- 초록색(Green), 잘못되게 — 게이트가 _확인할 수 없었음_에도 불구하고 통과했습니다.
결과 4는 규모 면에서 가장 비용이 많이 들며, 아무도 대시보드에 표시하지 않는 결과입니다. 거짓 빨간색은 조사 비용을 발생시킵니다. 거짓 초록색은 게이트를 두는 전제 자체의 비용을 발생시킵니다: 그 게이트를 통과한 모든 릴리스가 이제 알려지지 않은 품질을 가지게 되며, 어떤 것들이 그런지 알 수 없습니다. 이 게이트는 단순히 회귀를 포착하지 못한 것을 넘어 — 무지(ignorance)를 승인으로 인증했습니다. 몇 달 후에 그것을 알게 되었을 때, 질문은
이 프레임워크의 compare 명령어 v1.0에서는 결과 4에 도달할 수 있었습니다. 요약 CSV가 누락되었거나, 숫자가 아니거나, 유한하지 않은 메트릭(손상된 내보내기, 상위 단계에서 열 이름 변경, 파이프라인에서 0으로 나누기로 인한 nan 등)을 포함하는 경우, 게이트는 평가할 수 없었고 파이프라인은 계속 진행되었습니다. v1.1.0 변경 로그에는 이 변화가 명확하게 나와 있습니다: "기준선/후보 비교는 누락되었거나, 비수치적이거나, 비유한하거나, 비어 있는 활성화된 메트릭에 대해 실패 종료(fails closed)로 처리됩니다. 이전에는 잘못된 입력이 들어와도 통과했던 파이프라인은 이제 상태 2로 종료됩니다."
"이전에는 잘못된 입력이 들어와도 통과했던 파이프라인." 이 문구를 두 번 읽어보세요. 이것이 고백이며, 이 게시물이 각주가 아닌 글로 존재하는 이유입니다.
실패 종료(fail-closed)의 구체적인 의미
v1.1.0 구현에서는 활성화된 모든 게이트가 기준선과 후보 요약 파일 모두에 존재하고, 수치적이며, 유한한 메트릭을 요구합니다. 이 검사는 _metric_value에서 기계적으로 이루어집니다:
- 메트릭 누락 또는 비어 있음 → 실패
- 숫자로 구문 분석(parse)할 수 없음 → 실패
- 메트릭이 무한대나 NaN으로 구문 분석됨 → 실패
- 요약 파일 읽기 불가 또는 비어 있음 → 실패
위의 경우 중 어느 하나라도 CAFA-IVR release gate: FAIL을 출력하고, 문제가 된 특정 입력을 명시하며 상태 2로 종료됩니다. 이는 CI 시스템과 래퍼 스크립트가 "게이트가 이것을 거부했는지"와 "테스트 하네스 자체가 고장났는지"를 구별할 수 있도록 의도적으로 상태 1과 다르게 설정된 것입니다. 모호하게 실패하는 게이트는 사람들이 무시하는 법을 배우게 되므로, 종료 코드는 설계의 일부입니다.
여기서 주목해야 할 부분이 있습니다: 프레임워크 자체에서 배포한 파일럿 데이터셋조차도 자체 CEER 게이트를 통과할 수 없습니다. 360회 트라이얼 재현에는 임상적 중요 개체(critical-entity) 주석이 없으므로, 요약 보고서는 실제로 ceer: null을 출력합니다. 파트 2와 4에서 문서화했듯이 말입니다. 아무 생각 없이 비교를 실행해 보세요:
cafa-ivr compare \
--baseline empirical/cafa_reproduced_summary_360.csv \
--candidate empirical/cafa_reproduced_summary_360.csv
CAFA-IVR 릴리스 게이트: FAIL
- 유효하지 않은 요약 입력: empirical/cafa_reproduced_summary_360.csv 파일에서 필수 지표 'ceer'가 누락되었습니다.
Exit 2. 이 게이트는 프로젝트 자체의 참조 데이터를 확인하고 이를 거부했습니다. 이것은 버그가 아닙니다 — 이것이 바로 핵심입니다. 스스로 평가할 수 없는 입력을 통과시키는 게이트라면, 당신의 입력도 통과시킬 것입니다.
명시적 옵트아웃 vs. 무음 건너뛰기 (Explicit opt-out over silent skip)
실패하는 것의 대안은 지표가 없을 때 CEER 검사를 건너뛰는 것이었습니다 — “개체 주석이 없으므로 비교할 것이 없습니다.” 이것이 바로 fail-open 설계이며, 아무도 불만을 갖지 않기 때문에 매력적입니다. 하지만 이 방식은 대규모로 결과 4를 초래합니다: 몇 달 후, 누군가 시간을 절약하기 위해 파이프라인에서 주석 단계를 제거하고, 게이트는 조용히 개체 검사를 중단하며, 그 이후의 모든 릴리스는 더 이상 존재하지 않는 검사 항목에 대해 녹색 신호를 받습니다. 아무도 알아차리지 못하는데, 왜냐하면 게이트가 결코 불평한 적이 없기 때문입니다.
따라서 v1.1.0은 옵트아웃을 명시적으로 요구합니다:
cafa-ivr compare \
--baseline baseline/summary.csv \
--candidate candidate/summary.csv \
...
--no-ceer-gate는 모든 사람이 볼 수 있는 파이프라인 정의에서 다음과 같이 말합니다: 이 데이터셋에는 개체 주석이 없으므로, 우리는 개체 검사가 실행되지 않는 것을 받아들입니다. 건너뛴 검사와 옵트아웃된 검사의 차이는 설정 파일의 한 줄에 불과하며 — 이것은 정확히 “우리가 결정한 것”과 “일어난 일” 사이의 차이입니다. 결정은 감사(auditable)가 가능합니다. 발생한 일은 그렇지 않습니다.
이것이 설계의 일반화 가능한 부분입니다: 품질 게이트에서 발생하는 모든 무음 건너뛰기는 명시적이고, 가시적이며, 버전 관리되는 옵트아웃을 요구해야 합니다. 만약 건너뛰기가 합법적이라면, 그것을 기록하는 것은 아무 비용도 들지 않습니다. 만약 그 건너뛰기가 자체 프로세스의 회귀(regression)를 덮는 것이라면, 그것을 기록하는 행위 자체가 이를 포착하는 메커니즘이 됩니다 — 보통 코드를 검토할 때, 누군가 “왜 이 파이프라인에서 개체 게이트를 비활성화하나요?”라고 물어볼 때입니다.
기본값이 꺼짐(off)인 WER 게이트
구현의 또 다른 세부 사항입니다. 이 부분이 전체 시리즈를 하나로 연결하기 때문입니다. compare 명령어는 --max-wer-delta 옵션을 받는데, 이는 WER 회귀 게이트가 존재한다는 의미입니다. 기본값은 None, 즉 비활성화되어 있습니다. 파트 1에서 WER이 분석에 적절하지 않은 단위라고 주장했던 프레임워크는 사용자가 명시적으로 요청하지 않는 한 WER을 기준으로 릴리스를 제한하지 않습니다. 게이팅되는 수치는 ASR-IFR 및 CEER 델타입니다. 즉, 음성 경로가 더 많은 테스트를 통과했는지, 엔티티 손상이 증가했는지 등을 확인하며, WER은 이를 원하는 팀들을 위한 선택적 진단 지표로 제공됩니다.
이것은 간과한 부분이 아니라 의도된 것입니다. 기본값(default)은 도구가 내릴 수 있는 가장 강력한 주장입니다. 대부분의 사용자는 이 기본값을 변경하지 않기 때문에, 이는 저자가 실제로 믿는 바를 담고 있어야 합니다. 저자는 WER이 결정적인 지표가 아니라 진단적인 지표라고 믿습니다. 기본값이 그렇게 말하고 있습니다.
다시 한번 강조하는 정직한 경계
README에 명시되어 있으며, 기본값은 '카고 컬팅(cargo-culting)'을 유발하기 때문에 반복해서 언급할 가치가 있습니다. "기본 숫자 게이트는 보조 도구 시연을 위한 예시일 뿐이며, 보편적인 수용 기준이 아닙니다. 프로덕션 팀은 위험 등급과 역사적 기준선에 따라 자체 임계값을 관리해야 합니다."라고 명시되어 있습니다.
--max-asr-ifr-delta 0.02와 --max-ceer-delta 0.01는 시작점일 뿐입니다. 결제 IVR과 음악 IVR은 결과 규모를 공유할 필요가 없는 것만큼 게이트도 공유해서는 안 됩니다(파트 4 참조). 이 프레임워크의 역할은 메커니즘, 즉 현재적이고, 수치적이며, 유한하고, Fail-closed이며, 명시적인 선택적 제외 기능을 제공하는 것입니다. 사용자의 역할은 정책입니다. 어떤 델타를, 어떤 위험 등급에서, 어떤 기준선에 대해, 얼마나 자주 검토할 것인지 결정하는 것입니다. 아무도 소유하지 않은 임계값을 가진 게이트는 외관만 번지르르한 결과물(outcome)일 뿐입니다.
게이트 구축을 하는 모든 사람들을 위한 시사점
이 원칙을 사용하기 위해 이 프레임워크가 필요하지는 않습니다. 품질 게이트(quality gate)를 가지고 있는 곳이라면 어디든—테스트 커버리지, 지연 시간 예산(latency budgets), 오류율 경고(error-rate alerts), 모델 평가(model evals)—다음 질문을 던져보세요: 이 게이트가 확인하는 메트릭이 내일 사용 불가능해진다면, 그 게이트는 빨간색(red)으로 표시될까요, 아니면 초록색(green)으로 표시될까요? 만약 답이 초록색이라면, 당신에게는 게이트가 아니라 아무것도 연결되지 않은 녹색 신호등에 불과합니다. v1.1.0에서 했던 것처럼 고치세요: 메트릭의 존재 여부를 확인 과정의 일부로 요구하고, 부재 시 크고 명확하게 실패하며, 모든 건너뛰기(skip)를 명시적이고 가시적이며 검토 가능한 결정으로 만드세요.
조사해야 하는 빨간색 게이트는 성가신 일입니다. 맹목적으로 신뢰했던 초록색 게이트는 날짜만 기다리는 사고 보고서일 뿐입니다.
_이것으로 다섯 가지 기둥의 아크(five-post arc)를 마무리합니다: WER이 왜 거짓말하는지(#1), 엔티티 메트릭(#2), 귀속 실험(#3), 결과 가중치 부여(#4), 그리고 이 모든 것을 책임지는 게이트(#5). 팀에 가져가야 할 질문은 이 게시물의 질문입니다: 만약 당신의 릴리스 게이트(release gate) 메트릭이 내일 사라진다면, 그것은 빨간색으로 표시될까요—아니면 초록색으로 표시될까요?