본문으로 건너뛰기

충실성: 설명이 정직할 때

📍 현재 위치: I부 · 증명, 충실성, 신뢰 — 2장. 정당화는 정리(theorem)로 설명을 인증했습니다: 정당화에서 공리 하나를 제거하면 함의가 반드시 깨져야 합니다. 이 장은 그런 정리가 존재하지 않고 정직함을 실험으로 확인해야 하는 통계적 세계를 위한 측정 도구를 만듭니다.

앞 장은 당연하게 받아들이기 쉬운 하나의 보증으로 끝났습니다: 정당화는 구성상 충실합니다. 최소성이 삭제를 통해 검증되기 때문입니다. 집합 안의 모든 공리는 지탱하는 역할을 하며, 하나를 빼면 결론이 무너집니다. 이제 통로 건너편으로 가서, 자신의 예측에 대한 설명, 즉 강조된 입력 특징 집합, 어텐션 맵, 추론 문단을 제시하는 훈련된 모델을 보겠습니다. 훈련 목적 함수의 그 어떤 부분도 그 설명을 지탱하는 역할로 만들지 않았습니다. 손실이 낮은 모델은 자기 자신에 대한 많은 이야기를 허용하며, 그 모델이 들려주는 이야기는 실제로 실행한 계산과 완전히 단절되어 있을 수 있습니다. 이 분야는 딥러닝에서 가장 널리 읽히는 무료 설명인 어텐션 맵이 대체 가능하다는 사실이 드러나면서 이를 어렵게 배웠습니다: 같은 입력에 대해 적대적으로(adversarially) 다른 어텐션 분포가 예측을 사실상 바꾸지 않은 채로 남길 수 있으며, 따라서 우리가 읽는 맵이 이유라고 가정할 수 없습니다 [1]. 뒤이은 반박은 문제를 해소하기보다 더 예리하게 다듬어, 그런 구성이 무엇을 증명하고 무엇을 증명하지 못하는지를 보였습니다 [2]. 그 논쟁에서 하나의 실용적 해법이 나왔습니다: 설명이 옳아 보이는지 묻기를 멈추고, 예측이 그 설명이 인용하는 것에 의존하는지 묻기 시작하라는 것입니다. 인용된 증거를 지우면 예측이 움직여야 합니다. 인용된 증거만 남기면 예측이 살아남아야 합니다. 이 장은 그런 요구를 정확하게 만드는 두 숫자를 유도하고, 조용한 이유로 정답을 맞히면서 어텐션은 시끄러운 이유를 가리키도록 조작된 작은 모델을 만들며, 그 도구가 거짓말을 잡아내는 커밋된 표를 읽습니다.

쉽게 말하면

모든 시험에서 만점을 받는 학생이 어떻게 그랬냐는 질문에 "매일 밤 교과서를 공부해요"라고 답한다고 상상해 보세요. 그럴듯합니다. 하지만 검증할 수 있습니다. 일주일 동안 교과서를 치워 보세요: 성적이 움직이지 않는다면, 학생이 무엇을 믿든 교과서는 이유가 아니었습니다. 이번에는 학생에게 오직 교과서만 주고 강의도 필기도 주지 마세요: 성적이 유지된다면, 교과서는 정말로 충분한 것입니다. 그 한 쌍의 실험, 즉 없애 보고 성능이 떨어지는지 보는 것과 그것만 남겨 보고 성능이 살아남는지 보는 것이 충실성 측정이라는 개념 전체입니다. 설명이 이름 붙인 그 대상이 두 테스트를 모두 통과할 때, 그리고 오직 그때만 그 설명은 정직합니다.

이 장에서 다루는 내용

  • 그럴듯함 대 충실성, 그 근본적 구분: 인간 청중을 위해 다듬어진 설명은 모델의 실제 계산에 대해 아무것도 보고하지 않으면서도 선택적이고 매력적일 수 있습니다. 충실성은 산문의 속성이 아니라 인과적 연결의 속성입니다.
  • 하나의 반사실적 발상에서 나오는 두 지표: 포괄성(근거를 지우면 확신이 크게 떨어져야 함)과 충분성(근거만 남기면 확신이 거의 떨어지지 않아야 함)을 모든 기호를 풀어써서 정의하고, 두 지표 모두에 필요한 무작위-근거 기준선도 함께 다룹니다.
  • 정직한 실험실: 학술 세계 자체의 증거 어휘 위에 시드를 고정한 분류기를 만들어, 어텐션 질량이 출력이 쓰지 않는 특징 하나에 집중되도록 조작하고, 훈련 그래디언트로부터 그 구성이 왜 정확히 이 실패를 강제하는지 유도합니다.
  • 커밋된 표를 한 줄씩: 오클루전 근거가 포괄성에서 어텐션 근거를 이기고, 무작위가 두 지표 모두에서 최악이며, 모든 격차가 companion 코드의 assert로 지켜집니다.
  • 발표된 기록: 적대적 어텐션, 그에 대한 반론, ERASER(Evaluating Rationales And Simple English Reasoning)의 표준화, 그리고 프론티어에서 측정된 사고 연쇄의 불충실성을 각각 실제로 보여준 바 그대로 인용합니다.
  • 흔적-소거를 이 권의 재사용 가능한 도구로: 하나의 프로토콜을 일반적으로 서술하며, 이는 이미 정당화를 인증했고 VII부에서 SATORI의 어텐션 흔적을 채점하게 될 것입니다. 그 한계(매니폴드 바깥 소거, 상관된 특징, 세분성)도 똑같은 정성으로 서술합니다.

그럴듯함은 충실성이 아니다

두 종류의 서로 다른 청중이 설명을 요구하며, 그 둘의 차이가 이 절 전체의 주제입니다. 그럴듯한 설명(plausible explanation)은 인간을 위해 만들어집니다: 선택적이고, 과제가 어떻게 풀려야 하는지에 대한 인간의 사전 이야기에 들어맞으며, 그 품질은 사람들이 그것을 얼마나 설득력 있다고 느끼는지로 판단됩니다. 충실한 설명(faithful explanation)은 모델에 대한 보고입니다: 실제로 출력을 결정한 입력의 부분, 혹은 계산의 부분을 지목하며, 그 품질은 그 인과적 주장이 참인지로 판단됩니다. 이 두 속성은 논리적으로 독립적입니다. 어떤 설명은 충실하면서도 읽기 어려울 수 있고(만 개의 특징에 대한 전체 그래디언트 벡터), 그럴듯하면서도 거짓일 수 있습니다(모델이 전혀 참조하지 않은 증거를 인용하는 유창한 문단).

왜 이 둘은 이토록 쉽게 갈라질까요? 아무것도 그 둘을 결합시키지 않기 때문입니다. 훈련은 예측에 대한 손실을 최소화할 뿐, 그 예측에 대해 나중에 들려주는 이야기에는 아무런 제약도 두지 않습니다. 손실이 낮은 어떤 모델에 대해서도 그 입력-출력 행동과 부합하는 여러 사후적(post-hoc) 합리화가 존재하며, 인간의 호감을 위해 선택된 합리화는 정확히 잘못된 목적을 위해 최적화되고 있는 셈입니다. 적대적 어텐션(adversarial-attention) 결과는 가장 인기 있는 무료 설명에 대해 이를 구체적으로 보여주었습니다: 훈련된 텍스트 분류기에 대해, 예측을 거의 바꾸지 않으면서도 모델 자신의 어텐션과 최대한 다른, 즉 두 가중치 사이의 발산(divergence)이 큰 어텐션 분포를 구성할 수 있으며, 여러 모델에 걸쳐 어텐션 가중치는 특징 소거(feature erasure)가 측정하는 중요도와 약하게만 상관관계를 가집니다 [1]. 매우 다른 맵들이 동일한 출력을 지지한다면, 그중 어느 하나의 맵을 이유로 읽는 것은 정당화되지 않습니다. 반박은 조작된 어텐션이 모델 자신이 훈련한 어텐션이 아니므로 대안이 존재한다고 해서 원래의 어텐션이 무용했다는 것이 증명되지는 않는다고 응답했으며, 어떤 설정에서는 훈련된 어텐션을 비용 없이 대체하기 어렵다는 것도 보였습니다 [2]. 그 논쟁에서 살아남은 것, 그리고 이 분야가 간직한 부분은 양쪽 모두가 받아들인 요구입니다: 설명 품질에 대한 주장은 눈으로 판단할 것이 아니라 모델에 대한 측정으로 조작화(operationalize)되어야 한다는 것입니다.

이를 앞 장과 대조해 보겠습니다. 함의(entailment)에 대한 정당화의 경우, 충실성은 측정되지 않고 증명됩니다. 그 정의는 모든 공리가 필요함(어느 하나를 삭제해도 함의가 실패함)을, 그리고 그 집합이 충분함(그 부분집합만으로도 결론이 함의됨)을 요구합니다. 필요성과 충분성은 건전하고 완전한 추론기(reasoner)를 호출하여 검사되므로, 인증된 정당화는 사후적 이야기가 될 수 없습니다. 통계적 세계에는 호출할 추론기가 없습니다. 그 대신 논리에서 확률로 옮겨진 동일한 양방향 테스트를 가집니다: 삭제는 오클루전(occlusion, 특징의 값을 중립적인 값으로 대체하는 것)이 되고, 함의는 모델이 예측한 확률이 되며, 정리는 한 쌍의 숫자가 됩니다.

하나의 반사실적 발상, 두 개의 지표

훈련된 모델 하나와 입력 하나를 고정합니다. 입력을 xx라고 쓰는데, 이는 TT개의 특징 값으로 이루어진 벡터입니다(companion 코드에서는 T=8T = 8이며, 증거 채널마다 하나의 값입니다; 텍스트 모델이라면 특징은 토큰이 될 것입니다). 모델은 확률을 출력하며, 우리는 모델이 자신의 답에 대해 갖는 확신에 관심이 있습니다: y^\hat{y}를 예측된 클래스(전체 입력 xx에 대해 모델이 실제로 출력하는 클래스)라 하고, p(y^x)p(\hat{y} \mid x)를 모델이 그 클래스에 부여하는 확률이라 합시다. 근거(rationale) rr은 테스트 대상인 설명입니다: "예측이 의지하는 증거"로 제시되는 특징들의 부분집합입니다. companion 코드에서는 모든 근거가 실제로 인과적인 채널의 개수와 일치하는 k=2k = 2개의 특징을 지목합니다.

두 지표 모두 하나의 반사실적 조작에서 나옵니다: 증거를 바꾸고, 모델을 다시 실행하고, 확신을 비교하는 것입니다. 변화의 두 방향은 ERASER(Evaluating Rationales And Simple English Reasoning) 벤치마크가 표준화한 두 숫자를 낳습니다 [3]:

comprehensiveness(x,r)  =  p(y^x)    p(y^xr),\text{comprehensiveness}(x, r) \;=\; p(\hat{y} \mid x) \;-\; p(\hat{y} \mid x \setminus r),

여기서 xrx \setminus r("rr을 뺀 xx"라고 읽습니다)은 근거의 특징들이 지워지고 나머지는 모두 그대로인 입력입니다. 근거가 정말로 예측을 떠받쳤다면, 그것을 제거하면 타격이 있어야 합니다: 원래 답에 대한 확신이 떨어져야 하므로 포괄성은 커야 합니다. 0에 가까운 포괄성은 모델이 인용된 증거 없이도 똑같이 확신을 가지고 예측한다는 뜻이며, 이는 그 인용이 장식적이었다는 것을 완곡하게 표현한 것입니다.

sufficiency(x,r)  =  p(y^x)    p(y^r),\text{sufficiency}(x, r) \;=\; p(\hat{y} \mid x) \;-\; p(\hat{y} \mid r),

여기서 p(y^r)p(\hat{y} \mid r)은 모델이 오직 근거만을 보고, 인용되지 않은 모든 특징이 지워졌을 때의 확신입니다. 근거가 충분하다면 확신은 거의 움직이지 않아야 하므로 충분성은 작아야 합니다. 인용되지 않은 잡음을 걷어내는 것이 모델을 전체 입력에서보다 확신하게 만드는 경우에는 음수가 될 수도 있습니다. 두 지표 모두 held-out 프로브 집합에 대해 평균을 취하며, 예제 ii마다 항이 하나씩 있습니다. companion 코드는 두 지표 모두를 eraser_metrics라는 하나의 함수에서 계산합니다(faithfulness.py 259–282번째 줄).

두 가지 정직한 지적은 정의 뒤가 아니라 정의 안에 있어야 합니다. 첫째, "지운다"는 것 자체가 하나의 모델링 선택입니다. 특징은 단순히 부재할 수 없으며, 무언가로 대체되어야 하는데, companion 코드는 그것을 모집단 평균으로 대체하며, 각 채널이 표준화된 잡음에서 시작하고 클래스 이동이 대칭적이기 때문에 모든 채널에서 정확히 00이 됩니다(faithfulness.py 169–177번째 줄). 텍스트 모델이라면 선택지는 삭제, 마스킹, 또는 중립 토큰이 될 것이며, 측정된 숫자는 그 선택에 따라 달라집니다. 정의는 정확하지만, 소거 연산자가 그 가정들을 짊어집니다. 둘째, 원자료 숫자 자체는 그 자체로는 의미가 거의 없습니다. 포괄성 0.250.25: 이것이 큰 값일까요? 두 지표 모두에 필요한 보정 기준은 무작위-근거 기준선(random-rationale floor), 즉 kk개의 특징을 균등하게 무작위로 지목하는 근거의 점수입니다(faithfulness.py 285–288번째 줄). 어떤 후보 설명이든 신뢰를 얻는 것은 오직 그 기준선과의 격차를 통해서이며, 그 기준선은 0이 아닙니다: 무작위 추측은 비율 k/Tk/T로 진짜 인과적 특징을 맞히므로, 무지조차도 어느 정도의 점수를 받습니다. 그 기준선의 기댓값은 실험실의 중요도가 표 위에 오르는 즉시 정확히 계산하겠습니다.

실험실: 조용한 이유로 정답을 맞히다

직접 조작해서 만든 실패는 온전히 이해하는 실패이므로, companion 코드는 불충실한 어텐션이 보장되는 가장 작은 분류기를 만들고, 그런 다음 이 도구가 그것을 잡아내도록 합니다. 이 과제는 실행 예제의 틀에 맞춰 재단됩니다. 각 예제는 학술 세계 자체의 관계 어휘에서 이름 붙여진 T=8T = 8개의 증거 특징으로 이루어진 학자 프로필이며, 다시 입력하는 대신 3권의 kg 모듈과 1권의 규칙 기반에서 그대로 가져온 것입니다: 다섯 개의 그래프 관계에 대한 나가는 차수(out-degree) 개수, 지도받음과 인용됨에 대한 들어오는 차수(in-degree), 그리고 파생된 grandAdvisor 관계의 나가는 차수입니다(faithfulness.py 92–96번째 줄). 레이블은 "교수인가 아닌가"입니다. 두 특징은 생성기의 구성에 의해 인과적(causal)이며, 이는 1권과 2권의 말뭉치가 근거를 두는 바로 그 둘입니다: advises_out(온톨로지 공리 (4): Professor ⊑ ∃advises.Student)와 authored_out입니다. 각각은 표준화된 잡음에서 시작하여 클래스 신호 xtxt+μ(2y1)x_t \leftarrow x_t + \mu\,(2y - 1)를 받습니다. 여기서 tt는 8개의 특징 토큰을 인덱싱하고, 화살표 \leftarrow는 왼쪽의 값이 오른쪽 식으로 대체된다는 뜻이며, μ=1.25\mu = 1.25는 클래스 분리도이고, y{0,1}y \in \{0, 1\}은 레이블(1은 교수를 의미)이므로, 인자 2y12y - 1은 교수에 대해서는 +1+1, 학생에 대해서는 1-1이 되어, 교수의 지도 및 저술 횟수는 높게, 학생의 그것은 낮게 나타납니다. 한 특징 cites_in시끄럽지만 인과적이지 않도록(loud but non-causal) 조작되어 있습니다: 레이블에 대해서는 순수한 잡음으로 남아 있지만(인용을 많이 받는 학생도, 무명의 교수도 둘 다 존재합니다), 어텐션이 읽어 들일 별도의 현저성(salience) 채널 ss, 즉 시끄러움 신호에 대해서는 큰 값을 가집니다(faithfulness.py 123–145번째 줄). 현저성 설계는 명시적이며, 커밋된 표가 그것에 의존하게 됩니다: cites_in은 현저성 2.5를, advises_out은 현저성 1.2를 받고(일부러 두 번째로 시끄럽게 하여, 정확히 하나의 인과적 특징이 어텐션의 상위 2개에 도달하도록), 다른 모든 특징은 현저성 0에 머무르며, 예제마다 최대 ±0.15\pm 0.15의 작은 균등 흔들림이 모든 채널에 더해집니다(faithfulness.py 107–110번째 줄).

이 모델은 세 줄의 수학입니다. 특징 값 xi,tx_{i,t}와 현저성 si,ts_{i,t}를 가진 예제 ii에 대해(여기서 tt는 앞서와 같이 8개의 특징 토큰을 인덱싱합니다):

αi,t=esi,tuesi,u,zi=tαi,twtxi,t+b,pi=σ(zi)=11+ezi.\alpha_{i,t} = \frac{e^{s_{i,t}}}{\sum_{u} e^{s_{i,u}}}, \qquad z_i = \sum_{t} \alpha_{i,t}\, w_t\, x_{i,t} + b, \qquad p_i = \sigma(z_i) = \frac{1}{1 + e^{-z_i}}.

첫 번째 식은 현저성 채널에 대한 소프트맥스(softmax)입니다: ese^{s}는 각 시끄러움 점수에 대해 e2.718e \approx 2.718을 거듭제곱하고, 8개 토큰 전체에 대한 합 uesu\sum_u e^{s_u}로 나누어 점수들을 합이 1이 되는 양의 가중치로 바꿉니다. 이것이 어텐션 분포이며, 훈련되는 매개변수를 전혀 갖지 않습니다(faithfulness.py 156–160번째 줄). 두 번째 식은 각 특징의 값을 그 어텐션 αi,t\alpha_{i,t}와 훈련된 가중치 wtw_t로 가중한 뒤 훈련된 편향(bias) bb를 더하여 로짓(logit) ziz_i(시그모이드 이전의 점수)를 형성합니다. 세 번째 식은 시그모이드 σ\sigma로 로짓을 확률로 눌러 넣습니다. 이 분리가 바로 조작된 불충실성입니다: 어텐션은 오직 시끄러움만 읽는 반면, 훈련되는 값 경로 ww는 실제로 어떤 특징이 중요한지를 자유롭게 학습할 수 있습니다(faithfulness.py 148–154번째 줄).

훈련은 왜 어텐션이 거짓말을 하는 모델을 만들어 낼 수밖에 없을까요? 그래디언트를 따라가 봅시다. 손실은 nn개의 훈련 예제에 대한 평균 이진 교차 엔트로피(binary cross-entropy)로, L=1ni[yilnpi+(1yi)ln(1pi)]L = -\tfrac{1}{n}\sum_i \left[ y_i \ln p_i + (1-y_i)\ln(1-p_i) \right]이며, 여기서 ln\ln은 자연로그입니다. 한 예제의 손실을 그 확률에 대해 미분하면 Li/pi=yi/pi+(1yi)/(1pi)\partial L_i/\partial p_i = -y_i/p_i + (1-y_i)/(1-p_i)이고, 공통분모 pi(1pi)p_i(1-p_i)로 묶으면 분자는 yi(1pi)+(1yi)pi=yi+yipi+piyipi=piyi-y_i(1-p_i) + (1-y_i)\,p_i = -y_i + y_i p_i + p_i - y_i p_i = p_i - y_i가 되므로, Li/pi=(piyi)/(pi(1pi))\partial L_i/\partial p_i = (p_i - y_i)/\bigl(p_i(1-p_i)\bigr)가 됩니다. 시그모이드의 도함수는 σ(z)=σ(z)(1σ(z))=pi(1pi)\sigma'(z) = \sigma(z)\bigl(1-\sigma(z)\bigr) = p_i(1-p_i)로, 정확히 그 분모와 같으므로, 연쇄 법칙은 잔차 Li/zi=piyi\partial L_i/\partial z_i = p_i - y_i로 무너집니다. 이는 1권의 경사 하강법 장이 온전히 유도했던 것과 동일한 소거입니다. zi=tαi,twtxi,t+bz_i = \sum_t \alpha_{i,t} w_t x_{i,t} + b를 통한 연쇄 법칙을 한 단계 더 거치면 zi/wt=αi,txi,t\partial z_i/\partial w_t = \alpha_{i,t}\, x_{i,t}를 얻으며, 여기에 L2 벌점(penalty) λ2w2\tfrac{\lambda}{2}\lVert w\rVert^2을 더하면(여기서 λ\lambda는 감쇠 강도로 실행에서는 0.0010.001이고, w2=uwu2\lVert w\rVert^2 = \sum_u w_u^2은 가중치 제곱의 합이며, λ2uwu2\tfrac{\lambda}{2}\sum_u w_u^2wtw_t에 대해 미분하면 나머지 항이 모두 wtw_t에 대해 상수이므로 λwt\lambda\, w_t 항 하나만 남습니다),

Lwt  =  1ni(piyi)αi,txi,t  +  λwt.\frac{\partial L}{\partial w_t} \;=\; \frac{1}{n}\sum_{i} (p_i - y_i)\,\alpha_{i,t}\,x_{i,t} \;+\; \lambda\, w_t .

인자 αi,t\alpha_{i,t}가 바로 그 메커니즘이며, 훈련 루틴 자체의 docstring도 그렇게 말합니다(faithfulness.py 190–195번째 줄; 갱신 자체는 209–210번째 줄에서 실행됩니다):

Note the α_{i,t} factor: a quiet causal feature (small α) gets a small
gradient, so its weight must grow LARGE before the logit hears it —
training compensates for the attention, it does not correct it. The
small decay λ pins pure-noise features at w ≈ 0 instead of their sample-
correlation weights (overfitting would blur the causal/spurious contrast
the probes are about to measure).

어텐션은 움직일 수 없지만(매개변수가 없으므로), 손실은 여전히 낮아질 수 있습니다. 훈련되는 경로가 조용한 인과적 특징들의 가중치를 그저 키워서, 감쇠를 뚫고서라도 로짓이 그것들을 듣게 만들기 때문입니다. 그 결과는 정답을 맞히는 모델이면서 잘못된 곳을 가리키는 어텐션 맵입니다. 정직한 지적을 소리 내어 말하자면: 이 실패는 발견된 것이 아니라 조작된(engineered) 것입니다. 반박의 단서는 온전히 적용됩니다. 고정된 어텐션 모듈은 훈련된 것이 아니기 때문입니다 [2]. 이 구성은 대규모로 문서화된 현상을 대신하는 것이며 [1], 여기서 이것이 보여 주는 것은 잡아낼 무언가가 보장된 도구 그 자체입니다. 커밋된 실행(결정적: 데이터 시드 0, 가중치 시드 1, 무작위 근거 시드 2)은 2000번의 전체-배치(full-batch) 에폭을 훈련하여 프로브 정확도 0.9609에 도달합니다. 그런 다음 리브-원-아웃(leave-one-out) 오클루전 중요도, 즉 특징별로 계산되는 p(y^x)p(y^x with xt erased)p(\hat{y}\mid x) - p(\hat{y}\mid x \text{ with } x_t \text{ erased})를 이용해 어텐션이 바라보는 곳과 소거가 찾아내는 것을 출력합니다(faithfulness.py 241–256번째 줄):

[3] where attention looks vs what erasure finds (probe means)
token mean α trained w occl importance
about_out 0.0465 0.1261 -0.0001
advises_out 0.1537 8.7896 0.2488
affiliated_out 0.0462 -0.1617 -0.0000
authored_out 0.0466 7.7077 0.0466 <- used, barely attended
cites_out 0.0464 -0.0004 0.0000
advises_in 0.0468 -0.1948 -0.0001
cites_in 0.5673 -0.1249 0.0004 <- attended, not used
grandAdvisor_out 0.0466 -0.0045 0.0000
attention argmax is cites_in on 100.0% of probe examples; occlusion's top-2 is exactly the causal pair on 79.5%

표시된 두 행을 서로 맞대어 읽어 봅시다. cites_in은 평균 어텐션 질량의 0.5673을 차지하며 모든 프로브 예제에서 어텐션의 최댓값(argmax)이지만, 그것을 지우면 모델의 확신은 0.0004만큼 움직이는데, 이는 잡음 행들과 구분되지 않는 수준입니다. authored_out은 어텐션의 0.0466, 즉 12분의 1에 불과한 몫을 받지만, 훈련된 가중치는 7.7077이고 소거 중요도는 백 배나 더 큽니다. 그 보상은 가중치 열에서 눈에 보입니다: 두 인과적 특징의 가중치는 각각 8.79와 7.71인데, 이는 정확히 그 작은 α\alpha가 그것을 요구했기 때문이며, 반면 cites_in은 그 모든 어텐션에도 불구하고 0에 가까운 가중치를 얻었습니다. 이 대조들 각각은 단지 출력되는 데 그치지 않고 assert로 지켜집니다(faithfulness.py 382–386번째 줄): cites_in의 평균 α\alpha는 최소 0.50, 그 오클루전 중요도는 절댓값 기준 최대 0.01, 그리고 두 인과적 중요도 모두 각자의 임계값을 넘습니다.

충실성 실험실과 그 측정 도구를 보여주는 두 패널로 된 히어로 다이어그램입니다. 조작된 분리라는 제목이 붙은 왼쪽 패널은 작은 분류기를 학술 세계에서 온 여덟 개의 증거 특징에 대한 두 개의 병렬 경로로 보여줍니다: 소프트맥스 어텐션 블록으로 이어지는 현저성 채널은 그 출력 막대그래프에서 질량의 0.57을 시끄럽고 비인과적인 cites_in 특징에 쌓아 올리고, 훈련된 값 경로는 조용한 인과적 특징인 advises_out과 authored_out에서 가중치 막대가 8.8과 7.7 근처로 높이 서 있습니다. 주석은 어텐션에는 훈련되는 매개변수가 없으므로 훈련이 어텐션을 바로잡는 대신 조용한 가중치를 키우는 방식으로 보상한다는 점을 짚습니다. 소거 도구라는 제목이 붙은 오른쪽 패널은 하나의 입력 행이 반사실적으로 두 가지 방식으로 편집되는 것을 보여줍니다: 근거를 지워서 포괄성을 측정하는데, 이는 전체 입력에 대한 확신에서 근거 없이 얻은 확신을 뺀 값으로 정의되고, 근거만 남겨서 충분성을 측정하는데, 이는 전체 입력에 대한 확신에서 근거만 있을 때의 확신을 뺀 값으로 정의됩니다. 아래쪽의 세 행짜리 점수표는 커밋된 프로브 숫자를 보고합니다: 오클루전 근거는 포괄성 0.3659와 충분성 음수 0.0094, 어텐션 근거는 0.2497과 0.0464, 무작위 기준선은 0.0789와 0.2500이며, 화살표는 포괄성은 높을수록, 충분성은 낮을수록 더 좋다는 것을 표시합니다. 하나의 구성, 하나의 도구: 어텐션은 그래디언트가 흐르지 않는 곳에 집중되고, 소거 지표는 커밋된 표가 기록하는 격차만큼 그것을 잡아냅니다. 저자가 AI의 도움을 받아 직접 제작한 원본 도해.

커밋된 표, 한 줄씩

세 개의 근거 추출기가 경쟁하며, 각각은 프로브 예제마다 상위 k=2k = 2개의 특징을 지목합니다(faithfulness.py 346–354번째 줄): 어텐션(attention)은 가장 높은 어텐션 가중치 두 개를 취하고, 오클루전(occlusion)은 가장 높은 리브-원-아웃 중요도 두 개를 취하며, 무작위(random)는 두 개의 특징을 균등하게 뽑습니다. ERASER 도구는 512개의 held-out 프로브 프로필에 대해 이 셋 모두를 채점합니다:

[4] the ERASER instrument: both metrics, three extractors
(comprehensiveness: higher = rationale was needed;
sufficiency: lower = rationale alone already predicts)
rationale (top-2) comprehensiveness sufficiency
occlusion 0.3659 -0.0094
attention 0.2497 0.0464
random 0.0789 0.2500
근거포괄성 (높을수록 = 필요했음)충분성 (낮을수록 = 충분함)숫자가 말하는 것
오클루전0.36590.36590.0094-0.0094지우면 확신이 37포인트 깎이며, 그것만 있으면 전체 입력보다 오히려 잘 예측함
어텐션0.24970.24970.04640.0464지우면 확신이 25포인트 깎이지만, 이는 오직 인과적 특징 하나가 상위 2개에 섞여 들어갔기 때문
무작위0.07890.07890.25000.2500기준선: 무지도 여전히 점수를 얻으며, 바로 그래서 기준선을 측정해야 함

표 안의 모든 숫자는 앞 절의 중요도 열로 분해되며, 그 분해 과정을 직접 풀어 보는 것이 이 지표들이 무엇을 측정하는지 체득하는 가장 좋은 방법입니다. 어텐션 근거는 사실상 항상 (cites_in, advises_out) 쌍입니다: 현저성 2.5와 1.2가 ±0.15\pm 0.15의 흔들림을 압도하므로, 시끄러운 가짜 특징과 정확히 하나의 인과적 특징이 상위 2개를 채웁니다. 그 쌍을 지우면 단일 특징 중요도가 0.2488인 advises_out과 0.0004의 가치를 지닌 cites_in이 삭제되며, 측정된 포괄성 0.2497은 상호작용을 감안하면 바로 그 합입니다. 그 충분성 0.0464는 거울에 비친 모습입니다: 그 쌍만 남기면 중요도가 0.0466인 authored_out이 지워집니다. 어텐션의 점수는 0이 아니지만, 우연히 두 번째로 시끄러운 인과적 특징 하나에 의해 떠받쳐지고 있습니다. 이 지표는 어텐션이 놓친 인과적 특징에 대해 정확히 그 대가를 청구합니다. 오클루전 근거는 예제의 79.5%에서 정확히 인과적 쌍을 지목하며, 그 포괄성 0.3659는 두 단일 특징 중요도의 합(0.2488+0.0466=0.29540.2488 + 0.0466 = 0.2954)을 넘어섭니다: 두 특징 모두 같은 로짓을 밀어붙이며, 시그모이드의 비선형성 때문에 이 실행에서는 함께 지우는 것이 부분들의 합보다 더 비용이 듭니다. 그 충분성은 음수인 0.0094-0.0094인데, 이는 인과적 쌍만으로도 전체 입력보다 근소하게 더 잘 예측한다는 뜻으로, 여섯 개의 잡음 특징을 지우는 것이 모델이 결코 원하지 않았던 분산을 걷어 내기 때문입니다. 무작위 기준선은 기본 원리로부터 예측 가능합니다: 균등한 쌍은 확률 k/T=2/8=0.25k/T = 2/8 = 0.25로 주어진 어떤 특징이든 포함하므로, 그 기대 포괄성은 대략 0.25×(0.2488+0.0466+)0.0740.25 \times (0.2488 + 0.0466 + \dots) \approx 0.074이며, 커밋된 값 0.0789는 두 인과적 특징을 모두 뽑는 경우에 나타나는 동일한 결합-소거 상호작용 때문에 그 어림값보다 살짝 위에 자리합니다. 이 장의 주장은 정확히 이 격차들이며, 이는 코드로 강제됩니다(faithfulness.py 394–398번째 줄):

assert comp_occ >= comp_att + 0.05, "occlusion did not beat attention (comp)"
assert comp_att >= comp_rnd + 0.05, "random was not worst on comprehensiveness"
# Sufficiency (lower = better) runs the same way, by clear margins.
assert suff_occ <= suff_att - 0.03, "occlusion did not beat attention (suff)"
assert suff_rnd >= suff_att + 0.05, "random was not worst on sufficiency"

실제 학자들을, 모델을 통해 읽기

이 실험실은 다섯 명의 실제 지식 베이스 인물들을 훈련된 분류기에 통과시켜 읽음으로써 마무리됩니다. 그들의 특징 프로필은 1권의 실제 엣지를 세고 채널별로 z-점수화하여 만들어집니다(faithfulness.py 293–325번째 줄):

[5] the real kb scholars, read through the trained model
person advises_out authored_out cites_in p(professor) kb says
alice 1 1 1 0.6370 professor
bob 2 1 1 0.9132 professor
carol 1 1 1 0.6319 student
dave 0 1 0 0.2444 student
erin 0 0 0 0.1166 student

극단적인 사례들은 옳게 나오며, harness는 둘 다 assert로 확인합니다: 두 사람을 지도하는 bob은 확신을 가지고 교수로 분류되고, 나가는 증거가 전혀 없는 erin은 확신을 가지고 교수가 아닌 것으로 분류됩니다(faithfulness.py 403–404번째 줄). 교훈적인 행은 alice와 carol입니다. 교수인 alice와 (이미 erin을 지도하고 있는) 학생인 carol은 모델이 의지하는 모든 채널에서 동일한 값을 보이며, 서로 0.0051 이내로 가까이 자리합니다. 이 일치는 harness가 assert로 확인합니다(faithfulness.py 405–406번째 줄). 어떤 충실성 측정으로도 두 개인을 구분하지 못하는 증거를 가진 모델을 구해 낼 수는 없습니다. alice와 carol을 구분해 주는 것은 오직 2권의 유형 공리 Professor ⊓ Student ⊑ ⊥뿐입니다. 충실성은 설명이 계산을 보고하는지에 관한 것이지, 그 계산이 적절한지에 관한 것이 아닙니다. 두 질문 모두 중요하지만, 이 장의 것은 그중 하나뿐입니다.

발표된 기록

이 장난감은 조작된 것이지만, 그 현상은 그렇지 않습니다. 이 장의 도구가 축소판으로 만든 기록을, 각 조각이 실제로 보여준 바 그대로 인용합니다:

  • 어텐션은 대체 가능합니다. 순환 인코더(recurrent encoder)를 사용하는 텍스트 분류 모델들에 걸쳐, 학습된 어텐션 가중치는 그래디언트 기반 및 리브-원-아웃 특징 중요도와 약하게만 상관관계를 가지며, 학습된 것과 최대한 다른 적대적 어텐션 분포를 찾아 예측을 사실상 바꾸지 않은 채로 남길 수 있습니다. 도출된 결론은 최대치가 아니라 보정된 것이었습니다: 어텐션 가중치를 기본값으로 설명으로 취급해서는 안 된다는 것입니다 [1].
  • 반론. 대안적인 어텐션이 존재한다는 증명은 훈련된 모델에 대한 반사실이 아닙니다: 적대적 가중치는 학습된 것이 아니라 부과된 것이며, 그것을 만들어 낸 인코더로부터 분리되어 있습니다. 공정한 조건 아래(적대자를 끝에서 끝까지 훈련하고, 무작위 시드 기준선에 대해 분산을 측정하는) 어텐션은 적대적 구성이 시사하는 것보다 대체하기 어려우며, 어떤 과제에서는 실제 신호를 지니고 있습니다. 이 논쟁이 남긴 것은 방법론적인 것입니다: 어텐션이 설명하는가는 통제된 테스트를 요구하는 경험적이고 모델별 질문이라는 것입니다 [2].
  • 표준화. ERASER는 소거라는 발상을 벤치마크로 바꾸었습니다: 인간의 근거 주석이 달린 일곱 개의 데이터셋, 그리고 공유되는 충실성 지표로서의 포괄성과 충분성을, 위에서 정의한 것과 정확히 같은 방식으로 계산합니다(근거 크기에 대해 평균을 내는 변형과 함께). 인간의 근거와의 일치(그럴듯함)와 소거 행동(충실성)을 명시적으로 구분한 것은 이 장이 열었던 것과 동일한 구분입니다 [3].
  • 프론티어 버전. 산문으로 스스로를 설명하는 거대 언어 모델의 경우, 측정된 결과는 씁쓸합니다: 프롬프트에 편향을 유발하는 특징을 주입하면(예를 들어 객관식 선택지를 재배열해 정답이 항상 고정된 위치에 오게 하거나, 제안된 답을 심어 두면), 모델은 답을 바꾸면서도 그 사고 연쇄(chain-of-thought) 설명은 그 편향을 체계적으로 언급하지 않은 채, 대신 편향된 답을 위한 그럴듯한 근거를 지어냅니다. 진술된 추론은 명백히 예측의 원인이 아니며, 이는 정확히 추론 흔적 수준에서 포괄성이 실패하는 경우입니다 [4].

흔적-소거: 이 권의 재사용 가능한 도구

실험실을 걷어 내면 하나의 프로토콜이 남으며, 이는 이 권이 계속 재사용하게 될 프로토콜입니다. (모델, 입력, 설명)이라는 삼중항이 주어지면, 테스트는 양방향입니다: 설명이 인용하는 증거를 지우면 예측이 움직여야 하고, 설명이 인용하지 않는 증거를 지우면 예측이 움직이지 말아야 합니다. companion 코드의 구현은 의도적으로 모델에 무관한 형태를 취합니다: eraser_metrics(x, alpha, w, b, rationales) -> (comprehensiveness, sufficiency)(faithfulness.py 259–282번째 줄). 예측될 수 있고, 그 입력이 선택적으로 지워질 수 있는 것이라면 무엇이든 채점될 수 있습니다.

이 프로토콜은 이 시리즈를 따라 양쪽 방향 모두에서 이미 낯익습니다. 뒤를 돌아보면, 이는 정확히 정당화가 인증되었던 방식입니다: 최소성은 추론기를 모델로 삼는 흔적-소거이며, "예측이 움직여야 한다"는 "함의가 반드시 깨져야 한다"로 굳어지고, 이 장의 통계적 지표들은 그 정리의 격하되고 측정 가능한 그림자입니다. 앞을 내다보면, SATORI의 주장 표는 그 충실성 주장인 C3을 정확히 이 측정에 맡깁니다: 이 아키텍처의 증명 흔적은 어텐션-롤아웃(attention-rollout)과 그래디언트-현저성(gradient-saliency) 기준선에 대비해 흔적-소거 충분성과 포괄성으로 채점되어야 하며, 이산화된 흔적은 추가로 2권의 의미에서 진짜 정당화로 다시 검증되어야 합니다(faithfulness.py 219–227번째 줄이 이 도구 옆에 그 약속을 기록합니다). VII부가 그 평가를 실행합니다. 그리고 바로 다음 장은 이 프로토콜의 자매 격을 필요로 합니다: 설명이 특징 부분집합이 아니라 추출된 규칙 집합일 때, 질문은 그 규칙들이 보지 못한 입력에서 모델의 예측과 일치하는지가 되며, 이를 충실도(fidelity)라 부르는 지표로 재는데, 이는 증거에서 행동으로 끌어올려진 흔적-소거입니다.

이 지표들이 줄 수 없는 것

소거 테스트를 통과하는 것은 정직함에 대한 필요한 증거이지, 인과적 보증이 아닙니다. 이 한계들은 정의만큼이나 정밀하게 다루어질 자격이 있습니다.

지워진 입력은 매니폴드 바깥에 있을 수 있습니다. 오클루전은 모델이 전혀 훈련받아 본 적 없는 입력, 즉 특징이 0으로 채워진 프로필이나 토큰이 삭제된 문장에 대해 모델을 평가합니다. 그러면 확신의 하락은 두 가지 효과, 즉 정보의 제거와 분포 바깥 입력의 충격을 뒤섞습니다. 문헌은 이를 소거 지표의 고질적인 약점으로 취급합니다: ROAR 프로토콜(RemOve And Retrain)은 바로 이 교란 요인을 제거하기 위해 지워진 입력으로 모델을 다시 훈련시키며 [5], ERASER 자체의 집계 변형도 다시 훈련하는 대신 훈련된 모델을 재사용한다는 점을 밝히고 있습니다 [3]. companion 코드는 구성상 이 교란 요인을 피해 갑니다: 소거는 특징을 그 정확한 한계 평균(marginal mean)으로 대체하고, 어텐션은 고정된 채로 유지되며(faithfulness.py 171–174번째 줄), 어텐션이 고정되고 나면 로짓은 xx에 대해 선형이므로, 매니폴드 바깥 입력이 충격을 줄 만한 학습된 비선형 반응이 아예 존재하지 않습니다. 실제 모델은 그런 사치를 누리지 못합니다.

상관된 특징들은 "그" 근거를 유일하지 않게 만듭니다. 두 특징이 같은 신호를 나른다면, 둘 중 하나만 지우는 것은 아무것도 움직이지 않고(다른 하나가 대신하므로) 둘 다 지우면 크게 움직입니다. 어떤 단일 특징 근거의 포괄성이든 그것의 인과적 역할을 실제보다 낮게 나타내며, 여러 서로 다른 근거가 똑같이 잘 테스트를 통과합니다. 이 실험실은 독립적인 특징을 생성함으로써 이 문제를 피해 가지만, 현실 세계는 그렇지 않습니다. 통과된 테스트는 충분하고 필요한 어떤 근거를 인증하는 것이지, 유일한 근거를 인증하는 것이 아닙니다.

충실성은 세분성(granularity)에 대해 상대적입니다. 이 장은 입력 특징을 인용하는 설명을 측정했습니다. 그 대신 설명이 뉴런, 회로, 혹은 알고리즘적 구조를 충실하게 보고하는지 물을 수도 있으며, 이런 개념들(그럴듯함, 여러 세분 수준에서의 투명성, 사후적 설명)을 풀어 헤치는 개념적 지도는 이들이 서로 다른 테스트를 요구하는 서로 다른 속성임을 분명히 합니다 [6]. 어떤 설명은 특징 수준에서는 충실하면서도, 그 특징들을 결합하는 메커니즘은 잘못 보고할 수 있습니다.

이 중 어느 것도 테스트를 건너뛰는 것을 정당화하지 않습니다. 이는 통과가 의미하는 바를 제한할 뿐입니다: 설명이 소거 테스트에 실패하는 모델은 측정 가능한 방식으로 원인이 아닌 이야기를 하고 있는 것이며, 상관관계나 세분성에 호소해도 그것을 구해 낼 수 없습니다. 이 지표들은 거짓말쟁이를 잡아내는 필터이지, 정직한 이를 왕관 씌워 주는 증명서가 아닙니다.

아직 풀리지 않은 부분

소거 프로토콜은 지울 무언가를 필요로 합니다. 특징, 토큰, 검색된 문서, 혹은 증명 단계를 지목하는 근거는 이산적이고 주소를 지정할 수 있는 부분들을 가지므로 반사실이 잘 정의됩니다: 이 부분을 지우고, 다시 실행하고, 비교하면 됩니다. 자유 형식의 설명에는 그런 것이 전혀 없습니다. 모델이 산문 한 문단으로 스스로를 설명할 때, 그 설명의 "부분들"은 토큰이 아니라 주장들이며, 이유를 진술하는 문장을 지운다고 해서 그 이유가 모델의 계산에서 지워지는 것은 아니고, 그렇게 만드는 합의된 연산도 존재하지 않습니다. 사고 연쇄의 불충실성에 대한 프론티어 측정 [4]은 우회로를 통해 성공합니다: 이들은 편향으로 입력을 교란한 뒤 설명이 그것을 자백하는지 확인하는데, 이는 설명의 내용을 직접 채점하는 일 없이도 부정직함을 탐지합니다. 임의의 문단에 숫자를 매기는, 포괄성이 특징 부분집합에 숫자를 매기는 것과 같은 방식의, 자유 형식 설명을 위한 일반적인 충실성 지표는 존재하지 않으며, 그것이 가능한지조차 분명하지 않습니다. 산문은 어떤 고정된 소거 연산자를 두르더라도 항상 다르게 바꿔 쓸 수 있기 때문입니다. 이 분야의 현재 최선의 관행은 오히려 아키텍처에 관한 논증처럼 읽힙니다: 감사할 수 있는 설명을 원한다면, 지울 수 있는 구조, 즉 근거 구간, 검색된 증거, 실행 가능한 프로그램, 증명 흔적을 갖춘 설명을 만들어 내라는 것입니다. 이는 이 시리즈에서 중립적인 관찰이 아닙니다. 이는 구성상 검사 가능한 설명을 갖는 시스템을 정확히 겨냥하는 설계 압력이며, 이 권이 향하고 있는 곳이 바로 그곳입니다.

왜 중요한가

5권은 상징적인 금본위, 즉 정당화는 최소적이고, 검증되었으며, 정리에 의해 충실하다는 것으로 열렸습니다. 이 장은 그 보증에서 내려와, 프론티어의 나머지가 살아가는 통계적 세계로 향하는 첫걸음이며, 그 걸음은 이 권의 방법론을 축소판으로 보여줍니다: 어떤 속성이 증명될 수 없을 때는, 그것을 조작화하고, 기준선에 대해 측정하고, 그 격차를 커밋된 코드로 단언하라는 것입니다. 그럴듯함과 충실성의 구분은 어텐션 맵에만 갇혀 있지 않을 것입니다. 그것은 규칙 추출에서의 충실도로, 보정(calibration) 장에서의 확신과 정확성 사이의 격차로, IV부에서의 추론 지름길(대규모로 잘못된 내부 이유 때문에 옳은 모델들)로, 그리고 VII부에서의 SATORI의 C3 주장으로 되돌아오는데, 그곳에서는 여기서 만든 소거 도구가 증명 흔적을 겨냥합니다. 독자 자신의 연구를 위한 이 장의 산출물은 하나의 습관입니다: 어떤 시스템이 자신의 이유를 제시할 때마다, 그것에 감탄하기 전에 그것을 치워 버리면 무슨 일이 일어나는지 먼저 물어보십시오.

핵심 용어

  • 그럴듯한 설명(plausible explanation): 인간의 수용을 위해 최적화된 설명입니다. 선택적이고 유창하며, 인간의 사전 이야기나 주석과의 일치로 판단되고, 모델의 계산과는 논리적으로 독립적입니다.
  • 충실한 설명(faithful explanation): 모델 출력의 원인을 정확하게 보고하는 설명입니다. 호소력이 아니라 모델에 대한 반사실적 테스트로 판단됩니다.
  • 근거(rationale): 여기서 테스트되는 설명 대상으로, 예측이 의지하는 바로 제시되는 입력 특징들의 부분집합입니다(더 일반적으로는 토큰, 구간, 증거 항목).
  • 오클루전/소거(occlusion / erasure): 특징의 값을 중립적인 대역(여기서는 모집단 평균)으로 대체하여 그것의 부재를 시뮬레이션하는 것입니다. 그 자체가 하나의 모델링 선택이며, 그 인공물을 지표들이 그대로 물려받습니다.
  • 포괄성(comprehensiveness): p(y^x)p(y^xr)p(\hat{y} \mid x) - p(\hat{y} \mid x \setminus r), 근거가 지워졌을 때 잃는 확신입니다. 높으면 근거가 필요했다는 뜻입니다.
  • 충분성(sufficiency): p(y^x)p(y^r)p(\hat{y} \mid x) - p(\hat{y} \mid r), 근거만 남았을 때 잃는 확신입니다. 낮거나(혹은 음수이면) 근거 하나만으로 예측을 지탱한다는 뜻입니다.
  • 무작위-근거 기준선(random-rationale floor): 균등하게 무작위로 뽑은 크기 kk의 근거의 점수입니다. 두 지표 모두에 필요한 보정 기준선이며, 0이 아닙니다.
  • 오클루전 중요도(occlusion importance): 포괄성의 단일 특징 버전으로, 정확히 하나의 특징 xtx_t가 지워졌을 때의 확신 하락입니다. 어텐션과 비교되었던 귀속(attribution) 기준입니다.
  • 흔적-소거 프로토콜(trace-erasure protocol): 일반적인 양방향 테스트로, 인용된 증거를 지우면 예측이 움직여야 하고, 인용되지 않은 증거를 지우면 예측이 움직이지 말아야 합니다. 정당화는 정리로 이를 통과하고, 통계적 설명은 측정으로 이를 통과해야 합니다.
  • 충실도(fidelity): 추출된 대리 모델(surrogate model)에 대한 모델-일치 유사 개념으로, 추출된 규칙이 모델의 예측을 얼마나 자주 재현하는지를 나타냅니다. 다음 장의 핵심 지표입니다.

이 다음으로 이어지는 것

소거는 증거를 가리키는 설명을 채점합니다. 다음 장은 설명이 무엇일 수 있는지에 대한 판돈을 더 키웁니다: 입력의 강조된 부분집합이 아니라, 훈련된 모델의 행동을 재현한다고 주장하는, 그 모델에서 추출된 규칙 집합이라는 온전한 상징적 대리물입니다. 그 주장에는 그 자체의 지표(충실도: 규칙 집합이 어느 쪽도 본 적 없는 입력에서 모델과 일치하는가?)와 그 자체의 고전적 알고리즘들(TREPAN 방식의 결정 트리 쿼리에서부터 KBANN(Knowledge-Based Artificial Neural Networks)의 가중치-로부터-규칙 전통까지)이 있습니다. 규칙 추출은 그 둘을 모두 구축하며, 이 장의 규율을 물려받습니다: 모델처럼 들리기만 하는 규칙 집합은 그럴듯함이고, 오직 측정된 일치만이 충실성입니다.


컴패니언 코드: examples/frontier/faithfulness.py는 시드가 고정된 실험실, 손으로 유도한 그래디언트를 가진 고정-어텐션 분류기, 오클루전 중요도, 두 ERASER 지표, 무작위 기준선, 그리고 kb-학자 읽기를 구현합니다. 이 장의 모든 숫자를 재현하려면 python3 examples/frontier/faithfulness.py를 실행하세요. 이 실행은 결정적이며 이 장이 논거로 삼는 모든 격차는 assert로 지켜집니다.