EXPERIMENTS.md

September 21, 2026 · View on GitHub

프로젝트: Jev 스타일 System One(결정) 모델의 로컬 재현. 백본 Qwen2.5-3B, 학습 파라미터 약 1% (LoRA r16 + 헤드). 장비: RTX 4080 16GB(주), RTX 4090 원격 인스턴스(병렬 실행), M1 Max(v0 데모). 기록 원칙: 모든 정확도/ECE는 같은 검증셋, 같은 백본에서 비교. 별도 표기 없으면 temperature 보정 후.


2026-09-19

E0. v0 로그확률 엔진 동작 확인 (M1 Max, MPS, Qwen2.5-7B-Instruct)

학습 없음. Answer: 뒤 다음 토큰 로짓 중 라벨(A/B/C) 확률만 읽음.

질문결과confidence
현관문 40분 열림 → warnnoul 1.000.99
영역security 1.001.00
긴급도Today 0.81, Right now 0.180.52
이중 결제 → 큐billing 1.001.00
우선순위High 0.85, Critical 0.150.68
수동 환불 검토noul 0.940.67
고객이 화났는가noul 0.440.01
수학 객관식 (정답 c=6)c 0.920.76
  • 로드 19초, 첫 호출 9.3초(MPS 워밍업), 이후 4개 질문 1.9초.
  • 판단은 전부 상식과 일치. "화났는가" 0.44 / conf 0.01은 경계 사례에 대한 정직한 불확실성.
  • 문제: 1.00이 다수 → instruct 모델의 캘리브레이션 붕괴(softmax 포화).
  • 버그: dtype 기본값이 cuda 외 fp32라 7B가 28GB로 돌았음. → mps 자동 감지 + fp16으로 수정.

E1. v2 bi-encoder, 합성 데이터 (4080, Qwen2.5-3B)

LM 헤드 제거. 질문(state+question)과 선택지를 따로 인코딩해 PairScorer([q,k,q·k,|q−k|] MLP)로 점수. 데이터: 규칙 기반 합성 티켓 3,000 state × 3 질문(queue/priority/angry), 라벨 노이즈 5%.

  • 13분(다운로드 포함), epoch당 6.3분, 전기료 약 $0.06, GPU 7.5/16GB.
  • val 900: 정확도 95.9%(노이즈 상한 근처), NLL 0.259, Brier 0.093, ECE 0.067 (T=0.94).
  • 타입별: choice 95.3 (ECE 0.03), noul 95.0 (0.02), score 97.3 (0.15).
  • 추론: 3개 질문 첫 호출 234ms, 선택지 캐시 이후 38ms. 로드 2.6초.
  • 배포 확인: JEVLOCAL_ENGINE=decision 서버 /health, /v1/ask 정상.
  • "Do you ship to Canada?" → general 0.993: 정답(합성 템플릿상 general).

E2. v0 vs v2, 합성 데이터 (같은 백본, 같은 900 val, 둘 다 최적 T)

지표v0 n_perm=1v0 n_perm=4v2 bi
정확도 전체61.963.995.9
choice86.393.095.3
noul64.064.395.0
score35.334.397.3
NLL0.7580.7350.259
Brier0.4440.4240.093
ECE0.1200.1050.067
T1.020.850.94

발견:

  • 라벨 위치 편향: v0 choice가 n_perm 1→4에서 86.3→93.0 (+7%p). 로그확률 읽기 방식의 구조적 손실.
  • noul/score에서 v0 붕괴: 라벨이 사전학습에 없는 규칙으로 정해지면 학습 없는 모델은 맞출 이유가 없음.
  • v0의 0.530.73 확신 구간에 정확도가 0.250.35 낮은 과신 덩어리. 스칼라 temperature로 안 잡힘. v2는 그 구간이 비어 있음.
  • 한계: 합성 규칙을 배운 결과. 실제 데이터 비교 필요.

E3. Score 소프트 타겟 ablation (sigma 0.5 → 0, 같은 seed/데이터)

지표sigma 0.5sigma 0
정확도95.9 / 95.3 / 95.0 / 97.3동일
NLL0.2590.201
Brier0.0930.079
ECE 전체0.0670.003
ECE score0.1470.005
ECE choice / noul0.031 / 0.0250.006 / 0.006
MCE0.2780.018
T0.941.21
  • Score ECE 0.15는 모델이 아니라 설계 탓: 거리 인지 소프트 타겟(정답 확률 ≈0.79)에 정직하게 맞춘 것을 argmax 기준 ECE가 과소확신으로 읽음.
  • 부수 효과: score만 바꿨는데 choice/noul ECE도 개선. 전역 temperature 하나가 타입 간 타겟 날카로움 차이에 끌려다녔기 때문. 타입을 섞어 학습하면 타겟 날카로움을 맞춰야 전역 보정이 작동한다.
  • ECE 0.003은 900개/15 bin 측정 한계 아래. "구분 가능한 오차 없음"으로만 읽을 것.
  • 결정: --score-sigma 기본값 0.5 → 0.

E4. 실제 데이터 v0 기준선 (Qwen2.5-3B base)

train: boolq 9,427 + arc_easy 2,251 = 11,678. val: boolq 2,000 + arc_easy 570 = 2,570.

지표v0 n_perm=1v0 n_perm=4 (보정)
[arc_easy] 정확도91.693.0
[arc_easy] ECE0.0340.041
[boolq] 정확도78.880.3
[boolq] ECE0.0260.030
전체 NLL0.4080.379
T0.890.87
  • 합성과 완전히 다른 그림: 지식형 과제에서 사전학습 LM 로그확률은 이미 정직함(Kadavath 2022와 일치).
  • 위치 편향은 여기서도: n_perm 4가 ARC 1.4%p, BoolQ 1.5%p.
  • 주의: ARC/BoolQ는 사전학습 코퍼스에 섞여 있을 가능성(오염) → 공개 벤치마크는 v0에 유리하게 기운 시험.
  • 판정 기준 재설정: v2가 BoolQ에서 v0 이상, ARC에서 1~2%p 이내, ECE 동급이면 통과.

E5. v2 bi-encoder, 실제 데이터

v0 n4v2 bi ep1v2 bi ep2
[arc_easy]93.037.067.0
[boolq]80.387.488.4

최종(둘 다 최적 T):

지표v0 n_perm=4v2 bi판정
[boolq] 정확도80.388.4v2 +8.1%p
[boolq] NLL0.4280.295v2
[boolq] ECE0.0300.025비김
[arc_easy] 정확도93.067.0v0 +26%p
[arc_easy] NLL0.2070.860v0
[arc_easy] ECE0.0410.080v0
T0.871.51

발견:

  • BoolQ: 학습된 헤드가 로그확률 읽기를 이김. 논지의 첫 실제 데이터 증거.
  • ARC 붕괴: bi-encoder 설계 경계. 선택지("the moon", "6")를 질문과 독립 인코딩하면 상호작용 정보가 없음. 검색 분야의 bi vs cross-encoder 결과와 같음.
  • 규칙: 닫힌 선택지 집합(큐, 우선순위, 예/아니오) → bi(캐시). 내용 있는 선택지(객관식, 후보 검증) → cross.
  • T=1.51: ARC 과신이 전역 T를 끌어올려 BoolQ를 과하게 눌렀을 가능성. source별 temperature 후보.

E6. v2.1 cross-isolated + LM prior (4080)

질문+선택지 한 시퀀스. 접두부에 선택지 나열 없음(고립 검증). 선택지 토큰 평균 로그확률을 학습 가능한 스케일로 더하고 헤드 마지막 층 0-init.

  • 0스텝(LM prior만): ARC 68.1, BoolQ 66.4. 버그 아님(찍기 25% 아님). 로컬 135M 스모크에서도 동일 결론.
  • 왜 93이 아닌가: v0는 선택지 4개를 보고 고르고(비교 선택), 고립 검증은 후보를 혼자 보고 우도로 잼. 짧은 선택지의 언어적 사전확률이 판단을 오염. 3B에서 고립 검증은 비교 선택보다 25%p 어렵다.
  • 학습 손실 0.52에서 시작(bi는 0.77). LM prior 출발점 효과.
  • epoch 1(보정 전): ARC 94.0 / NLL 0.209, BoolQ 87.8 / 0.329, 전체 NLL 0.302, ECE 0.050.
  • 68 → 94: 고립 검증이 학습으로 비교 선택 수준까지 감. 선택지 나열 없음, 라벨 없음, 26개 제한 없음, 위치 편향 구조적으로 없음. 검증기 방향의 첫 증거. ARC-Challenge에서 격차가 남는지가 다음 질문.

E7. v2.2 cross-label + LM prior + options-in-prefix (4090)

접두부에 선택지 나열(비교 문맥), continuation은 라벨 글자(" B") → 0스텝 = 정확히 v0. 학습 중 나열 순서 셔플.

실행 1 (lr 2e-4, 발산): 손실 50스텝 0.52 → 100스텝 0.65 → 150스텝 1.2+. 워밍업 종료(73스텝) 직후.

  • 원인: LM prior는 같은 백본에서 나오므로 LoRA와 함께 움직임. 헤드 0-init이라 초반 그래디언트가 prior 경로로만 흐름 = "정답 글자를 내도록 LM 파인튜닝". 2e-4는 출발점(≈v0)을 흔듦. bi용 LR을 잔차 학습에 그대로 쓴 실수.
  • 로그 보관: real_label_lr2e-4_diverged.log.

실행 2 (03:48 재시작, lr 5e-5, 셔플 켜짐, 단일 LR):

step50100150200
lr 2e-40.520.651.2+
lr 5e-50.440.460.420.45

epoch 1(보정 전):

v0 n_perm=4cross-isolated (4080)cross-label (4090)
[arc_easy] 정확도93.094.093.7
[arc_easy] NLL0.2070.2090.193
[boolq] 정확도80.387.888.6
[boolq] NLL0.4280.3290.295
전체 NLL0.3790.3020.273
전체 ECE0.0260.0500.029

읽기:

  • ARC val 570개 → 정확도 표준오차 약 1.1%p. 93.0 / 93.7 / 94.0은 통계적으로 동일. ARC: 안 잃음.
  • BoolQ 2,000개 → 오차 약 0.7%p. 80.3 vs 87.8/88.6은 명백. BoolQ: +8%p 얻음.
  • 판정은 NLL: label 모드가 두 과제 모두 최고(0.273 vs 0.379). 보정 전 ECE 0.029 ≈ v0 0.026. "v0 위의 잔차" 설계가 의도대로 동작.
  • 논지 성립: 같은 3B 위 1% 부품 학습으로 백본이 아는 것은 지키고, 모르던 것은 얻고, 확률의 질은 올라감.

E6/E7 최종 (epoch 1 체크포인트, 보정 후). 네 행 표.

v0 (n_perm 4)v2 biv2.1 isolated (4080)v2.2 label (4090)
[arc_easy] 정확도93.067.094.093.7
[arc_easy] NLL0.2070.8600.1840.184
[arc_easy] ECE0.0410.0800.0130.024
[boolq] 정확도80.388.487.888.6
[boolq] NLL0.4280.2950.2960.293
[boolq] ECE0.0300.0250.0190.023
전체 NLL0.3790.4200.2710.269
전체 ECE0.0260.0300.0140.019
T0.871.511.551.16
  • isolated 와 label 은 동점 (NLL 0.271 vs 0.269, 정확도 차이 전부 오차 안). 비교 문맥은 학습 후 값이 없다.
  • 둘 다 v0 를 모든 열에서 이기거나 비김. ARC 열: 93 → 67 → 94 → 94.
  • epoch 2 는 두 실행 모두 정확도 +0.6~1.3%p(오차 안), NLL 악화(0.302→0.373 / 0.273→0.308) = 과신. 보정 전 NLL 기준이라 epoch 1 유지. epoch 2 체크포인트는 저장 안 돼 보정 후 비교 불가 → 선택 기준 변경 (아래 코드 변경 기록).
  • 4080 epoch 2 가 epoch 1 보다 2~3배 느렸음. 스로틀링 아님(60도, 2775MHz, 237/320W). 원인 미상.

E8. 0스텝 분해: 비교 문맥의 값 vs 라벨의 값 (4090, LM prior만, 학습 없음)

0스텝후보 목록답 형식ARCBoolQ
isolated없음원문68.166.4
text+options있음원문75.473.9
label있음글자91.878.9
  • 후보 목록만으로 ARC +7.3, BoolQ +7.5. 글자 답으로 바꾸면 추가로 ARC +16.4, BoolQ +5.0.
  • 학습 안 한 Qwen2.5-3B 에서 v0 방식이 강한 이유의 2/3 는 "글자로 답하기"(시험 형식 특화). 학습 후엔 24%p 격차가 사라짐(E6/E7).

E9. 위치 불변성 (eval --permute-seed, 보정 후)

고정seed 1seed 2
label ARC93.794.994.6
label BoolQ88.688.388.3
label NLL0.2690.2640.268
bi ARC / BoolQ / NLL66.8 / 88.3 / 0.420동일동일
  • label 모드: 순서를 바꿔도 ARC 1.2%p 범위(오차 1.1%p) → 셔플 학습이 위치 불변성을 심음. v0 가 n_perm 1→4 로 벌던 1.4%p 편향이 학습으로 사라짐.
  • bi: 소수점까지 동일(구조적으로 순서 없음) → 순열 평가 기계 검증.
  • isolated 는 순서 자체가 없어 측정 불요.

E10. 일반성 시험 (4090, 진행 중, 05:24 시작)

질문: 학습한 데이터셋 밖에서도 v0 를 이기는가 = "과제를 외웠나, 판단하는 법을 배웠나".

학습: arc_easy 2,251 + boolq 9,427 + banking77 2,500 (77개 의도 분류, CC BY 4.0; HF 리포는 스크립트 기반이라 GitHub CSV 직접 로드). isolated cross + LM prior, lr 5e-5, 1 epoch, bs1 x accum16 (banking77 은 예제당 시퀀스 77개).

  • 처음엔 banking77 10,003 전체로 시작했으나 (a) step당 8.5초 → 3.3시간, (b) 학습셋 21.7k 의 절반이 한 과제라 "과제 하나 추가"가 아니라 "학습셋을 banking77 로 교체"가 됨 → 2,500 으로 줄여 재시작 (2.2k / 9.4k / 2.5k 균형). [사후 발견 2026-09-19 21:00] 이때의 banking77 2,500 은 라벨별로 정렬된 CSV 의 앞 2,500 행이라 77개 의도 중 ~21개만 포함 (E14 준비 중 2,000 표본에서 17/77 로 확인). E10 의 banking77 열은 '77-way' 가 아니라 '~21-way, 77개 나열' 로 읽어야 함. convert.py 는 seed 무작위 표본으로 고침. 10k 실행의 100 step 로그는 gen_full10k_aborted.log. 2,500 으로는 banking77 자체 천장(의도당 32개, few-shot 영역)은 못 보며, "77개 닫힌 라벨에서 isolated 가 되는가"만 답한다 (85 넘으면 충분).
  • 0스텝(학습셋 val): arc 67.9 / boolq 66.2 / banking77 17.2 (찍기 1.3%; 의도 이름 텍스트 우도만으로 13배). held-out (학습에 안 씀, T 는 학습셋 val 값 그대로, 재조정 없음):
데이터셋HF id형식라이선스역할
OpenBookQAallenai/openbookqa (main)4지선다 과학Apache 2.0ARC 근접 대조군
CommonsenseQAtau/commonsense_qa5지선다 상식MIT도메인·선택지 수 다른 시험
HellaSwagRowan/hellaswag4지선다, 긴 문장 선택지MIT형식이 완전히 다른 가장 어려운 전이

피함: PIQA (AFL 3.0), SciQ (CC BY-NC 3.0) — 공개 가중치 학습 데이터로 부적합. 판정: OBQA 만 v0 근처 → 근접 도메인 전이. CSQA·HellaSwag 까지 v0 근처 이상 → 판단하는 법을 배움. 부수 측정: init (step 0) 의 [banking77] — LM prior 가 의도 이름 텍스트만으로 77지선다를 얼마나 맞추나 (찍기 1.3%).

E10-a. 2과제 모델(real_cross, arc+boolq) held-out — 4080S, 06:00 완료. 정확도(%), 0스텝 = 학습 안 한 isolated prior.

held-outnv0 n4isolated 0스텝2과제 학습 후전이 (학습후−0스텝)v0 대비
OpenBookQA50076.237.868.4+30.6−7.8 (오차 1.9)
CommonsenseQA1,22177.746.876.2+29.4−1.5 (오차 안)
HellaSwag2,00065.850.365.5+15.2−0.3 (동점)

NLL: 본 판정은 체크포인트 T(1.55) 그대로 — OBQA 1.04 / CSQA 0.76 / HS 0.96 (v0 는 각 held-out 에서 T 맞춤: 0.62 / 0.62 / 0.86). 진단용으로 held-out 에서 T 를 다시 맞추면 0.84 / 0.63 / 0.89, refit T = 3.3 / 2.9 / 2.5 → held-out 에서 과신이 크다. CSQA·HS 의 NLL 격차는 대부분 보정 문제, OBQA 는 순위 자체도 뒤짐.

읽기:

  • 안 본 3개 중 2개(CSQA, HellaSwag)에서 v0 와 동급. 도메인(상식)도 형식(긴 문장 선택지)도 학습셋과 다른데 0스텝에서 +15~29%p 올라 v0 에 붙음 → "판단하는 법"이 옮겨간 증거.
  • OBQA 는 −7.8. 근접 도메인인데 오히려 가장 나쁨. 0스텝 37.8 로 셋 중 prior 가 가장 약했고("...because" 로 끝나는 문장 완성형 질문 + 짧은 선택지), 학습이 +30.6 을 메웠지만 부족.
  • 0스텝 HellaSwag 50.3: "우도 채점이 유리할 것"이라는 예상과 달리 v0(65.8) 보다 낮음. 우리 템플릿("Question: Which ending...\n\nAnswer: ")의 평균 로그확률은 lm-eval-harness 의 acc_norm 과 다른 채점.
  • 판정(중간): "과제를 외웠다"는 기각. "판단하는 법을 배웠다"에 가깝되 OBQA 가 남은 숙제. 3과제(banking77 추가) 열은 4090 에서 진행 중.

E10-b. 2과제 label 모드(real_label) held-out — 4090, 06:30. OBQA 79.8 (v0 +3.6, NLL 0.556 < v0 0.624), CSQA 78.8 (+1.1, NLL 0.630 ≈ 0.617), HellaSwag 63.6 (−2.2, NLL 0.987 > 0.860). 셋 중 둘에서 v0 위. "프롬프팅을 하한으로 보장"은 대략 성립하되 HellaSwag 에서 2%p 아래 (v0 기준선이 n_perm 4 순열 평균인데 label 의 출발점은 단일 순서 = v0 n_perm 1 이라 그 차이가 남은 것으로 해석).

E10-c. 3과제 모델(gen2: arc + boolq + banking77 2,500) — 4090, 09:12 완료. isolated, lr 5e-5, 1 epoch, bs1 x accum16, 학습 2h(banking77 예제당 시퀀스 77개). 학습셋 val(보정 T=1.12): arc 93.0 / boolq 88.3 / banking77 85.5 (0스텝 17.2 → 85.5, 의도당 32개로 "77개 닫힌 라벨에서 isolated 가 되는가" 통과). 전체 ECE 0.010.

held-outv0 n40스텝2과제 isolated3과제 isolated2과제 label
OpenBookQA76.237.868.463.4 (ECE 0.19)79.8
CommonsenseQA77.746.876.275.0 (ECE 0.14)78.8
HellaSwag65.850.365.563.7 (ECE 0.03)63.6
  • 과제를 하나(닫힌 라벨 분류) 더해도 안 본 객관식 전이는 늘지 않았고 셋 다 2과제와 같거나 살짝 아래. "과제 수 스케일링" 곡선의 두 번째 점은 평평하거나 하강.
  • 교란: 2과제 isolated 는 lr 2e-4 · 2 epoch(베스트 epoch 1), 3과제는 lr 5e-5 · 1 epoch. 학습셋 안 성능은 같은데(arc 93 / boolq 88) 전이가 다르므로, 과제 추가 효과와 학습률·epoch 차이가 분리되지 않음. 결론 내리려면 같은 lr/epoch 로 2과제 vs 3과제 재대조 필요 (E10-d 후보).
  • 알려진 결함: train.py 의 보정 단계(베스트 재로드)에서 이전 모델이 완전히 해제되지 않아 GPU 메모리 12GB → 22GB, 보정 평가가 3배 느려짐(30분). del model 뒤에도 peft 래퍼/로컬 참조가 남는 것으로 보임. 다음 버전에서 재로드를 별도 프로세스로 분리하거나 gc.collect() + 참조 정리.

E11. Jev 독립 측정 (Vercel AI Gateway typesafe-ai/jev, scripts/jev_eval.mjs → jevlocal.eval_dump)

같은 held-out 세 개를 Jev 에 던져 확률 분포·confidence 를 받음. 3,721건, 입력 145만 토큰, 약 $0.06. 무료 티어는 레이트 리밋(500건 중 7건 통과) → 크레딧 충전 후 실패 0. 동시성 32 는 CSQA 에서 재시도 지옥 → 8 로 안정.

held-outv0 3B2과제 isolated2과제 labelJevJev NLLJev ECEJev refit T
OpenBookQA76.268.479.894.20.1720.0240.96
CommonsenseQA77.776.278.888.10.3950.0321.35
HellaSwag65.865.563.686.10.4200.0291.00

읽기:

  • 정확도: 3B 계열이 낼 수 없는 수준 (OBQA 94, HellaSwag 86 은 프론티어급). 백본이 훨씬 크거나 공개 벤치마크가 학습에 들어갔거나 둘 다. → 규모 통제: Qwen2.5-7B base v0 를 같은 held-out 에 (E12, 큐). 오염은 확인 불가.
  • 캘리브레이션: refit T 0.96 / 1.35 / 1.00, ECE 0.020.03. 우리 모델이 안 본 과제에서 T 2.53.3 이었던 것과 대비. 단, 이 과제들이 Jev 에겐 "본 과제"일 수 있어 in-domain 캘리브레이션일 가능성 → 오염 불가능한 합성 티켓 데이터로 재측정 (E13, 진행 중).
  • 확률은 0.01 단위 양자화, 정확히 0 이 다수 (OBQA 2,000 값 중 1,051). 정답에 0 을 준 경우 1건 (pred A 1.00, conf 0.99) → NLL 에 13.8 기여; 그 1건 제외 시 NLL 0.144. "거짓 확신" 각주.
  • 별도 confidence 필드: 정답률 예측 ECE 0.035 / 0.035 / 0.078. HellaSwag 에서 max-prob 보다 나쁨.
  • ECE 노이즈 바닥(같은 예측 분포에서 라벨 재표집 200회, 완벽 캘리브레이션 모델의 기대 ECE): OBQA 0.024 → 측정 0.024 = 1.03× (구분 불가), CSQA 0.019 → 1.65×, HellaSwag 0.018 → 1.65×. 합성 900: 바닥 0.024 → 측정 0.107 = 4.4×.
  • 게이트웨이 원응답에 rounding: {probabilityDecimals: 2, scoreDecimals: 2} 필드가 있음 → 0.01 양자화의 출처. 모델 버전은 노출 안 됨(canonical slug typesafe-ai/jev; 문서의 jev-latest 는 404).
  • 공개: https://github.com/scienthoon/jev-ood-calibration (원응답 4,621건, 생성기, eval_dump + 노이즈 바닥, README). 2026-09-19 푸시.
  • 외부 등록 (2026-09-19, 모두 선생님 계정): awesome-jev PR #30 (yibie), awesome-jev-typesafe-origin PR #1 (yodablocks), HF Space multimodalart/jev-reproductions-tracker discussions/5, jev-exploration issue #10 (SamuelSacco). 이슈에는 반례(정답 P=0.00, 오답 1.00, conf 0.99)와 방법 질문(직접 API 응답에도 rounding 메타데이터·0.01 양자화가 있는가)을 포함. 답이 오면 README 각주에 조건을 붙일 것.

E12. 규모 통제: Qwen2.5-7B base v0 (n_perm 4, 각 held-out 에서 T 맞춤) — 4090, 09:37 완료

held-outv0 3Bv0 7BJev3B→7B7B→Jev
OpenBookQA76.283.2 (ECE 0.041, T 0.72)94.2+7.0+11.0
CommonsenseQA77.781.2 (ECE 0.028, T 0.67)88.1+3.5+6.9
HellaSwag65.877.0 (ECE 0.022, T 0.65)86.1+11.2+9.1
  • 백본을 두 배(3B→7B)로 키우면 3.511%p 오르지만 Jev 까지는 여전히 711%p 남는다. Jev 의 정확도는 "큰 백본에 프롬프팅급" 으로는 설명되지 않고, 훨씬 더 큰 백본이거나 벤치마크 노출이거나 둘 다. 어느 쪽인지는 이 실험으로 못 가른다(오염은 외부에서 확인 불가).
  • 7B 프롬프팅의 T 는 0.650.72 (과소확신) 로 3B(0.87) 보다 1에서 멀다. 보정 후 ECE 는 0.020.04 로 3B 와 같은 수준.
  • 우리 Luce 3B(2과제 label 79.8 / 78.8 / 63.6) 는 OBQA·CSQA 에서 7B 프롬프팅에 못 미친다(83.2 / 81.2). "1% 학습이 백본 두 배를 대신하는가" 에는 in-domain(BoolQ +8%p)에서만 그렇다고 답할 수 있고, 안 본 과제에서는 백본 크기가 더 값어치 있다.

E13. Jev, 오염 불가능한 과제: 합성 티켓 val 900 (E1 데이터, seed 0 재생성, md5 2451fe7b)

Jev 가 존재를 알 수 없는 규칙 기반 데이터. queue/angry 는 의미 기반이라 맞힐 수 있고, priority 는 "템플릿 긴급도 + 화남 + 티어" 임의 규칙이라 못 맞히는 게 정상. 핵심 질문: 못 맞히는 과제에서 확률이 낮은가 (모르는 걸 모른다고 하는가).

타입nJev 정확도NLLECErefit T비고
choice (queue, 4지)30089.00.6970.0823.29맞히지만 틀린 데 1.0 을 줌
noul (angry)30091.70.2750.0790.66과소확신
score (priority, 4단계)30044.71.3310.3253.40못 맞히면서 max-prob 평균 0.74
전체90075.10.7680.1072.74
  • 안 본 과제에서 Jev 의 확률은 정직하지 않다. priority 정확도 44.7% (찍기 25, 이웃 1단계 이내 98%) 인데 확률은 평균 0.74 로 확신. refit T 2.73.4 는 우리 모델이 held-out 에서 보인 2.53.3 과 같은 크기. E11 의 T≈1 은 in-domain(공개 벤치마크 노출) 캘리브레이션으로 읽는 것이 정합.
  • confidence 필드도 여기선 정답률을 예측 못 함 (ECE-if-probability 0.18; E11 에선 0.035).
  • 정확도 자체는 v0 3B(choice 93.0 / noul 64.3 / score 34.3)보다 noul·score 에서 훨씬 높음 → 의미 판단은 강한 백본 덕. 우리 학습 모델(95/95/97)은 규칙을 배운 것이라 비교 대상 아님.
  • 결론(캘리브레이션 축): "RLCD 가 OOD 캘리브레이션을 해결했다"는 이 실험에서 기각. Jev 도 과제별 보정(고객 데이터 200개로 T)이 필요하며, 그 점에서 우리와 같은 처방.

E14. 백본 교체: Ouro-2.6B (ByteDance, 루프형 LM, 48층 × 반복 4회) — 4090, /venv/ouro (transformers 4.54.1)

목적: 같은 레시피(라벨 읽기 → label 모드 학습)를 파라미터 2.6B·유효 깊이 4배인 루프형 백본에 얹었을 때 출발점과 학습 결과가 어떻게 되는가. Qwen2.5-3B 와 같은 val 2,570(ARC 570 + BoolQ 2,000).

관문 1 (학습 없음, 24분).

설정ARCBoolQ전체 NLL(보정 후)맞춘 T
v0 라벨 읽기, ut_steps=4, n_perm 495.187.40.2920.50
v0, ut_steps=277.577.30.5200.39
v0, ut_steps=157.537.80.8341.83
isolated 0스텝(LM prior 우도), ut_steps=465.683.10.6610.60
(비교) Qwen2.5-3B v0 n_perm 4 (E4)93.080.30.3790.87
(비교) Qwen2.5-3B isolated 0스텝 (E8)68.166.4
  • 반복 4회가 필수: 2회로 줄이면 ARC −18pp, 1회는 무작위 근처. 추론 비용은 4회 기준으로 생각해야 함(2.6B × 4 ≈ 10B 급 깊이).
  • 학습 없이 Qwen 보다 ARC +2.1, BoolQ +7.1. BoolQ 87.4 는 Qwen 이 label 학습 후 도달한 88 에 근접. T=0.50 은 과소확신(선택지 간 로짓 차가 작음) — 학습이 이 부분을 채울 여지.
  • isolated 0스텝도 BoolQ 는 83.1 로 Qwen(66.4) 보다 훨씬 높음. 관문 판정: 라벨 읽기 ≥ 93.0 → label 모드.
  • 호환 문제 3건은 "코드 변경 결정 기록" 참고 (use_cache, 튜플 출력, 별도 venv). 공유 prefix KV 캐시는 이 백본에서 불가 → per-option 폴백(평가만 느려짐, 학습 비용은 동일).

관문 2 (진행 중, 20:08 시작). label 모드, lr 5e-5, ut_steps 4, 1 epoch, batch 4 × accum 4, grad ckpt. 과제 누적 mix1..mix6 (과제당 2,000: arc_easy → +boolq → +banking77 → +klue_ynat → +nsmc → +synth), 각 mix 마다 in-domain val(과제당 500) + held-out OBQA/CSQA/HellaSwag(학습셋 T 그대로). banking77 은 --label-overflow isolated(기본).

  • 21:10 결정(사용자): 누적 6개는 실측 17 h 로 너무 길어 mix2 까지만 돌리고 멈춤. banking77 비용(예제당 77 시퀀스)을 줄이는 학습용 음성 표본추출 --max-train-options K(정답 + 무작위 음성 K−1, 평가는 전체) 를 추가해 E15 사다리부터 적용(K=16). mix3~6 은 사다리 뒤에 결정.
  • 21:00 데이터 수정: banking77 2,000/500 이 정렬된 CSV 의 머리(17/13 의도)였음을 발견, seed 0 무작위 표본(77/77 의도, 라벨당 train 750 / val 112)으로 교체하고 mix3~6 재빌드. mix1·mix2 는 영향 없음(arc/boolq 는 원래 무작위 순서). 옛 파일은 data/tasks/banking77_head17/.

E15. 백본 사다리 × 라벨 효율 (계획, 관문 2 종료 후 4090 에 자동 시작)

질문: "당신 과제엔 얼마나 작은 모델이면 되나" 와 "라벨이 몇 개면 되나" 를 한 표로. backbone: auto 의 문턱(0999 → 4B, 1천4,999 → 1.7B, 5천+ 닫힌 집합 → 0.6B)은 추정치이므로 이 곡선으로 교정.

  • 과제 2개: 합성 티켓(data/tasks/synth, 1,992/498, 라벨 모드) · banking77(2,000/500, 77 의도, label 모드 + overflow isolated).
  • 백본 3개: Qwen3-0.6B-Base · Qwen3-1.7B-Base · Qwen3-4B-Base (transformers 5.17, /venv/main).
  • 라벨 수 5단계: 0(--eval-init, 학습 없음 = 프롬프팅 하한) · 250 · 500 · 1,000 · 2,000 — seed 0 셔플 뒤 앞 n 개(중첩 부분집합). epoch 2 (2,000 은 1).
  • 측정: 과제 val 정확도, 보정 후 NLL, ECE, 맞춘 T. 30 실행(2×3×5), 예상 3~4 시간.
  • 판정: 0.6B 직접 학습이 4B 와 붙으면 증류 불필요; 벌어지면 증류(4B → 0.6B)가 격차를 메우는지 다음 실험. ModernBERT-large(인코더, 395M) 점은 인코더 경로 검증 후 추가.

결과 (부분, 23:40 4090 반납으로 중단 — 합성 티켓 14/15 실행 완료, banking77 15 실행은 못 함). val 498, 정확도 % (보정 후 NLL), 250~1,000 은 2 epoch, 2,000 은 1 epoch, K=16 음성 표본.

백본라벨 0 (프롬프팅)2505001,0002,000 (1 ep)
Qwen3-0.6B-Base59.0 (0.828)67.9 (0.711)77.5 (0.621)82.1 (0.510)79.5 (0.542)
Qwen3-1.7B-Base53.6 (0.835)71.9 (0.673)76.3 (0.608)84.3 (0.483)84.9 (0.473)
Qwen3-4B-Base59.0 (0.816)77.7 (0.591)83.9 (0.496)88.8 (0.377)(중단)
  • 사다리 가설 기각(이 과제, ≤1k 라벨 범위): 모든 라벨 수에서 4B > 1.7B > 0.6B. 라벨 1,000 에서 4B 88.8 / 1.7B 84.3 / 0.6B 82.1 — 작은 백본은 "공짜"가 아니라 47 점을 내는 비용 선택. "1천5천이면 1.7B, 5천+ 이면 0.6B" 문턱은 이 데이터로는 근거 없음 → backbone: auto 를 4B 고정으로 바꾸고 작은 백본은 명시 선택으로(코드 변경 기록 참고).
  • 라벨 효율: 세 크기 모두 250 → 1,000 에서 아직 가파르게 오름(4B +11 점). 1,000 에서 평평해지지 않았으니 "몇 개면 되나" 의 답은 이 과제에선 1,000 이상.
  • 0.6B 의 2,000 (1 epoch, 79.5) < 1,000 (2 epoch, 82.1): 업데이트 수가 같을 때 라벨을 늘려도 못 이김 → 작은 백본은 epoch 를 더 돌려야 함(레시피 기본 epoch 2 유지가 맞음).
  • 프롬프팅 출발점(라벨 0)은 크기와 무관하게 5359 로 낮음 → 이 과제(규칙 기반 티켓)는 "데이터 있는 과제" 이고 프롬프팅 하한이 도움이 안 되는 예. 학습 후 ECE 0.040.09, T 1.1~1.6(학습 후 과확신, val 로 보정).
  • banking77 절반(77-way, 백본 크기 민감도가 다를 수 있음) 은 다음 GPU 대여 때 run_ladder.shTASKS=banking77 로 재개(스크립트는 완료 마커로 건너뜀).

E16. TypeSafe 공개 eval (evals.typesafe.ai) 에 Ouro mix2 올리기 — 4090, 21:50 시작

정확도 앵커. Jev 86.9 / system-one-open(Gemma 4 E2B) 76.7 / Qwen-7B 프롬프팅(jev-on-a-laptop) 73.8 이 한 줄에 놓이는 유일한 공용 벤치마크.

  • 시험지: system-one-open(MIT) 의 typesafe_eval.py 로직으로 evals.typesafe.ai 의 4개 워크플로 viewer 데이터에서 복원 → 20 케이스 / 372 기준 쌍 / strict common subset 343 (README 숫자와 일치). scripts/typesafe_bench.py rebuild|convert|score. 원본 js 는 data/typesafe/raw/, 복원본 data/typesafe/typesafe_full.json, Luce 형식 data/typesafe/val.jsonl.
  • 구성: noul 236 / choice 109 / score 27. state 는 Ouro 토크나이저로 39112,051 토큰(security 1.93k, agent_trace 3.512k, invoice 611k, customer_service 0.4~1.2k). 기준 답은 프론티어 모델 평균(consensus), 사람 라벨 아님.
  • 채점: strict common subset = opus·sol·typesafe(Jev) 셋 다 답한 쌍만, 같은 쌍에서 네 열 비교(system-one-open evaluate.py 와 같은 정의). 추가로 per-type / per-question 최빈 답 기준선, 우리 ECE·NLL(공개 벤치마크엔 없는 축).
  • 실행: luce.eval --checkpoint checkpoints/ouro_mix2 --max-query-len 12288 --batch-size 1 --dump (학습 때 512 였던 좌측 절단을 평가에서 풀어 줌; Ouro 문맥 65k). T 는 체크포인트 값(1.32) 그대로, OOD.
  • 주의: 372 쌍이면 ±5%p 오차. mix2 는 ARC+BoolQ 만 배운 상태라 이 과제들(보안 사고, 에이전트 트레이스, 인보이스, 고객 응대)은 전부 학습에 없던 것 = held-out 과 같은 성격.
  • 결과 (22:52 완료, 48분; 사다리와 GPU 공유 + Ouro per-option 경로라 느림):
strict common subset (343 쌍)정확도
Ouro-2.6B mix2 (ARC+BoolQ 4,000 만 학습, 이 과제들은 전부 미학습)76.7% (ECE 0.078, NLL 0.653)
system-one-open, Gemma 4 E2B (70 과제 + 합성 59k 학습)76.7%
Jev (typesafe)86.6% (답한 350 쌍 기준 86.9)
Opus / Sol (프론티어, 기준 답의 재료)89.5 / 90.4
Qwen-7B 프롬프팅 (jev-on-a-laptop, 같은 시험)73.8
기준선: 타입별 최빈 답 / 질문별 최빈 답58.9 / 81.0
  • 372 쌍 전체 76.6%. 워크플로별: invoice 82.6 (184) · customer_service 78.3 (92) · agent_trace 70.8 (48) · security 56.2 (48). 타입별: noul 80.9 (236) · choice 76.1 (109) · score 40.7 (27).
  • 읽기: 벤치마크 과제를 하나도 안 배운 2.6B 가, 70 과제를 배운 E2B 재현과 같은 점(76.7). Jev 와는 10 점 차(±5 오차 밖). 약한 곳은 score(수준 척도, 27 쌍) 와 security(48 쌍, 긴 규칙 문서 + noul 37 개). 372 쌍이라 워크플로별 숫자는 ±7~14 점 오차.
  • 학습 전 Ouro(프롬프팅, 같은 템플릿 글자 읽기, T 미조정): common subset 63.3% (ECE 0.057), 372 쌍 62.6. 워크플로별 security 54.2 / agent_trace 52.1 / invoice 66.3 / customer 65.2. → ARC+BoolQ 4,000 개 학습이 이 벤치마크(전부 미학습 과제)에 +13.4 점 을 얹음. Qwen-7B 프롬프팅(73.8, 다른 템플릿) 보다 낮은 출발점에서 시작해 학습 후 넘어섬.
  • 공개용 패키지 release/ouro-2.6b-decision-lora/ (어댑터 121MB + head.pt + decision_config.json + calibration.json + inference.py 250줄 + 모델 카드 + requirements). inference.py 는 Luce 를 import 하지 않음. 검증: 합성 val 30건에서 Luce 평가기(batch 1)와 확률 최대 차이 0.00000, argmax 30/30 (batch 4 의 Luce 와는 bf16 패딩 잡음으로 최대 0.033). HF 업로드 완료 (23:30, 사용자 지시): https://huggingface.co/noscienthoon/ouro-2.6b-decision-lora (Apache-2.0, 9 파일, 커밋 fcea1b1). score 타입은 훈련 데이터에 score 가 없었으니(ARC=choice, BoolQ=noul) mix6(합성 티켓의 score 포함) 이 오르는지 볼 것.

E17. 네 과제 × Qwen3-4B-Base, 4×4070S(12GB) 동시 실행 (2026-09-20, 준비)

데이터는 별도 세션이 수집·검증한 data/four_tasks/ (README 참고; Luce 소스 무수정, 분할 train/val/calibration/test [+ maze ood], 해시·겹침 검증 통과).

과제train 행질문비고
github_issues (kubernetes 2023–2025)2,817kind Choice 4 / priority Score 4실제 관리자 라벨. 본문 길어 max_query_len 1,024, bs 1×16
phishing (PhishNChips v5.2, jev-phishing-bench 와 같은 2,000)1,000NoulJev ECE 0.154 와 같은 셋(test 500)
maze (NanoJev-Data 맵, 3수 확장 과제)7,884safe_move Choice 4 / death Noul / risk Score 4정확 계산된 label_probs (Choice dict, Noul float) → 캘리브레이션 학습 상한
rule_tickets (LLM 합성: DeepSeek V4.1 Flash, 1,000 state, $0.32)3,000queue Choice / priority Score / angry Noulval·cal·test 는 규칙 생성기(label_noise 0) 1,994 관측 = "문장→데이터→모델" 첫 검증
절차(과제당 GPU 1장, run_task.sh): --eval-init(0스텝) → 2 epoch label 모드 학습(val 로 선택+T) → calibration.jsonl 로 타입별 T 재조정·저장 → test.jsonl 평가+dump (maze 는 ood 도). 기록: requirements.lock, nvidia-smi 5초 로그, 단계별 시각, history/calibration.json, last/. 12GB 라 4B 는 bs 1~4 × accum 으로.
  • 비용 균형(사용자 요청, 4장 동시 과금이라 가장 긴 작업이 비용): 네 과제를 35~45분에 맞춤 — maze 7,884 → 4,500 행(1,500 상황 × 3), github_issues 2,817 → 1,200 행(choice 1,029 / score 171) + max_query_len 1,024 → 768. phishing·rule_tickets 는 전체. 전부 2 epoch(E15: 같은 비용이면 행 줄이고 2 epoch).
  • 12GB 스모크: 4B, qlen 768, bs 1 × accum, grad ckpt → 피크 10.7GB, OOM 없음.
  • 시작 2026-09-20 01:5x UTC (인스턴스 ssh9.vast.ai:27207, 4×4070S). rule_tickets 는 asciinema rec -i 2 로 학습 터미널 녹화(logs/four/rule_tickets_train.cast).
  • 01:48 예산 조정(크레딧 $1.21, $0.412/h): 미로 14.4 s/step, GitHub 31.9 s/step 로 한도 초과 예상 → 둘을 죽이고 재시작. 미로 1,500 행(500 상황), val 450 / cal 900 행; GitHub 600 행, val 150 / cal 200, test 500 행 상한. 첫 시도 로그는 *_attempt1.log.
  • phishing 완료 (01:42, 18분): 0스텝 50.0%(무작위, T→20) → epoch 1 74.0 → epoch 2 97.2(val). calibration 재조정 T(noul)=1.72. test 500: 정확도 97.4, recall 98.8, FP 4.0%, NLL 0.078, ECE 0.010. jev-phishing-bench(같은 PhishNChips 2,000, Jev 는 0샷 전체 2,000): Jev 직접 판정 62.6%(recall 43.2, FP 18.0, ECE 0.154), Claude Haiku 4.5 81.3, 두 줄 정규식 91.691.8, Jev 5개 신호 위 로지스틱 회귀 95.095.1(ECE 0.027). 주의: 우리는 같은 분포 1,000건으로 학습한 in-domain 이고 저쪽은 0샷 — "라벨 1,000개 + 4070S 20분이면 Jev 의 자체 벤치마크를 넘는다" 가 정확한 문장. 본문은 합성이고 신호는 URL·발신자에 있어 정규식으로도 91.8 이 나오는 셋.
  • Jev 0샷, 같은 test 셋 (Vercel AI Gateway typesafe-ai/jev, 동시성 8, logs/jev_four/): GitHub test 500 중 478 응답(22건 max_tokens 초과): 전체 77.6, kind 84.7 (ECE 0.100), priority 37.5 (ECE 0.240), 전체 ECE 0.109, $0.03. 미로 test 2,619/2,640: 전체 64.4, safe_move 41.4 / death 86.3 / risk 65.6, ECE 0.135; ood 1,199: 66.2 (48.6 / 88.0 / 62.0), ECE 0.156. $0.05.
  • github_issues 완료 (02:29, 재시작분 41분; 600 행 × 2 epoch = 76 스텝, qlen 768): 0스텝 val150 82.0 (kind 86.2 / priority 63.0) → epoch 1 83.3 → epoch 2 (kind 87.8 / priority 63.0, 27건). calibration 200: kind 90.6 / priority 31.0, T kind 0.77 / score 1.98. test 500: 전체 78.0, kind 85.9 (ECE 0.044), priority 31.5 (73건, ECE 0.151), 전체 ECE 0.066. 같은 500 에서 Jev 0샷 77.6 (kind 84.7 / priority 37.5, ECE 0.109). 판정: 이 예산(600 행)으로는 학습이 얹은 게 없음 — kind 는 0스텝 = Jev = 학습 후 (모두 85 근처, 관리자 라벨 자체의 잡음 천장일 가능성), priority 는 train 에 score 행이 ~100개뿐이라 배우지 못함(val27 의 63.0 은 표본 잡음). 전체 2,817 행(score 462) × 2 epoch 재실행이 필요 (4090 ~50분).
  • maze test 2,640 (02:32; 재시작분 1,500 행 = 500 상황 × 2 epoch): 0스텝 val450 44.4 (safe_move 42.7 / death 90.0 / risk 0.7) → epoch 1 72.2 (38.0 / 90.0 / 88.7) → epoch 2 (20.0 / 90.0 / 88.7). calibration 900: safe_move 23.3 / death 96.7 / risk 96.7, T choice 20.0(신호 없음) / noul 0.91 / score 1.01. test: 전체 66.9, safe_move 29.2 (찍기 25 근처, ECE 0.019), death 86.1 (ECE 0.120), risk 85.3 (ECE 0.041), 전체 ECE 0.060. 같은 test 에서 Jev 0샷 64.4 (41.4 / 86.3 / 65.6, ECE 0.135). 판정: risk(사망확률 구간) 는 0.7 → 85.3 으로 학습이 크게 얹었고 Jev 보다 20점 위; death 는 둘 다 다수 클래스 근처; safe_move(3수 생존 최적 행동) 는 둘 다 못 품 — 우리는 학습 중 choice 헤드가 한 답으로 무너져 찍기보다 낮음(T→20 으로 확률은 균등에 가까워 ECE 는 낮음). 500 상황 × 2 epoch 으로는 7×7 ASCII 지도의 3수 계산을 못 배우는 것. NanoJev 공식 과제(navigation/local_safety/one_step_probability, 패키지의 maze/official/)로 재실행해 NanoJev 발표 숫자와 직접 비교하는 것이 다음.
  • maze ood 1,200 (50×50 맵): 전체 65.4, safe_move 20.3 / death 88.0 / risk 88.0, ECE 0.061 (Jev 66.2: 48.6 / 88.0 / 62.0, ECE 0.156). risk 는 학습 후 크기가 다른 맵에도 옮겨감(+26 vs Jev); safe_move 는 test 와 같이 무너진 상태. [E17-C 정정: risk/death 의 88.0 은 상수 예측이다 — 400건 전부 3 / 전부 yes, 다수 기준선 352/400 = 88.0 과 동일. soft target 으로도 학습셋 상수 분포보다 나쁘다(NLL 0.558 vs 0.459, Brier 0.231 vs 0.219). safe_move 20.3 은 다수 답 36.5 보다 16pp 낮고 예측이 south 257 / north 143 로 두 방향뿐이다. "큰 맵으로 전이된다" 는 읽기는 무효.]
  • rule_tickets 완료 (02:39, 76분; 3,000 행 × 2 epoch = 376 스텝, asciinema 녹화): 0스텝 val 62.1 → epoch 1 91.9 → epoch 2 91.4 (best = epoch 2, calibrated NLL 0.195, T 1.65). calibration 1,533: 90.9 (queue 100.0 / angry 98.6 / priority 74.2), 타입별 T choice 0.05(하한; 항상 맞히면서 확률이 낮아 T 를 바닥까지 내림) / noul 1.31 / score 1.93. test 2,964 (규칙 생성기, 노이즈 0): 전체 91.1, queue 100.0, angry 98.6, priority 74.6, NLL 0.187, ECE 0.022. Jev 0샷은 같은 규칙 과제(E13, 900건)에서 75.1 (89.0 / 91.7 / 44.7, ECE 0.107). 6번 과제(문장 → LLM 합성 데이터 → 모델, 규칙 생성기 시험) 통과: LLM(DeepSeek V4.1 Flash) 이 규칙을 읽고 붙인 라벨만으로 배워 확정 규칙 시험에서 91%. 남은 9점은 priority(4단계 규칙, 티처가 규칙을 덜 정확히 적용한 곳으로 추정 — teacher_calls.jsonl 로 확인 가능).
  • E17 4070S 분 요약 (같은 test, 우리 4B 학습 vs Jev 0샷): phishing 97.4 vs 62.6 · rule_tickets 91.1 vs 75.1(E13) · github 78.0 vs 77.6(비김, 600 행) · maze 66.9 vs 64.4(risk 이김, safe_move 짐). 넷 다 ECE 는 우리가 낮음(0.0100.066 vs 0.1090.154).
  • GitHub 기준선 점검 (test 500): kind 다수 클래스(bug) 62.8% → 우리 85.9 / Jev 84.7 은 실력(+23). priority 다수 클래스(important-soon) 30.1% → 우리 31.5 는 다수 답 붕괴(73건 중 72건을 '2' 로 예측; 레벨 순서 Backlog→long-term→soon→urgent 는 정상, 렌더링 문제 아님), Jev 37.5 는 네 단계를 다 쓰며 다수보다 조금 위. 학습 600 행 중 score 행 ~100 개로는 주변 분포만 외운 것(미로 safe_move 와 같은 실패 형태). train 462 행 분포: long-term 33 / soon 32 / backlog 23 / urgent 13 %.
  • coverage (우리, calibrated max-prob 문턱): kind — 0.80: 89% 자동, 자동분 정확도 89.7 / 0.90: 78%, 91.3 / 0.95: 62%, 93.2 (나머지 55~74). priority — 문턱 0.8 이상 0건: 모델이 모른다는 걸 확률로 알고 있음(전부 사람에게). 제품 문장: "kind 는 78% 를 91% 정확도로 자동, priority 는 아직 전부 검토".
  • 4090 GitHub 전체(2,817 행 × 2 epoch, qlen 1,024): 02:36 시작, 0스텝 val 458 80.3, 실측 19.5 s/step × 708 = 학습 3.8 h → 03:00 에 중단(kind 는 안 오르는 질문이라 낭비). 로그 github_issues_full_attempt.log.
  • 4090 GitHub priority 집중 실행 (03:00 시작): train = score 462 행 전부 + choice 500 행(seed 0) = 962 행 × 3 epoch, qlen 1,024, bs 2 × accum 8 (180 스텝), val 458 / cal 464 / test 875 전부. 질문: "462 개의 조직 규칙 라벨로 priority 가 다수 답(30)·Jev(37.5) 위로 가는가". 실측 8 s/step, 183 스텝/epoch.
    • val 458 (kind 381 / priority 77): 0스텝 80.3 (86.4 / 50.6) → epoch 1 76.6 (— / 29.9, 다수 답 붕괴) → epoch 2 81.0 (86.9 / 51.9, 회복) → epoch 3 81.0 (best, calibrated NLL 0.528). calibration 464: 81.9, T kind 1.06 / score 1.20. test 875: 전체 81.1, ECE 0.041 (04:08 완료, 68분).
    • 같은 test 500 (Jev 셋): kind 86.9 (Jev 84.7), priority 41.1 (Jev 37.5, 다수 답 30.1; n=73, ±11). 예측이 네 단계로 퍼짐(long-term 46 / soon 16 / backlog 5 / urgent 6) — 600 행 때의 붕괴(72/73 이 'soon') 는 해소. priority coverage: max-prob ≥0.6 인 10% 는 71% 정확, ≥0.5 인 22% 는 56% — "확신 있는 소수만 자동, 나머지 사람" 형태로는 쓸 수 있는 수준. 혼동 행렬: long-term 으로 쏠림(gold backlog 18 중 15 를 long-term 으로).
    • 0스텝(프롬프팅만) test 500 (4090 #2, 04:00): kind 83.4, priority 30.1 (= 다수 답), 전체 75.6. → val 77 의 50.6 은 표본 잡음이었음. 같은 test 500 에서 priority: 프롬프팅 30.1 / Jev 37.5 / 학습 후(462+500, 3ep) 41.1. 학습이 +11 (Jev 대비 +3.6, n=73 이라 오차 안). kind 는 프롬프팅 83.4 → 학습 후 86.9 (+3.5, Jev 84.7).
    • 실험 A (4090 #2, priority 462 행 단독, 같은 설정, 2 epoch; 가설 판별): val 77 — 0스텝 50.6 → epoch 1 48.1 (붕괴 없음) → epoch 2 50.6 (best = epoch 1, NLL 1.042). test 500 priority 34.2 (kind 83.1, 학습 안 한 질문이라 0스텝 83.4 그대로). 13:26 KST 완료. 혼합 실행의 epoch 1 붕괴(29.9)가 단독 학습에서는 안 나타남 → 붕괴의 원인은 라벨 잡음이 아니라 kind 500 행과 헤드를 공유하면서 생긴 간섭(다른 세션의 반론이 맞았음). 처방은 prior 보호가 아니라 질문별 헤드 분리 또는 질문별 학습. 다만 최종 수준은 라벨 잡음이 정함.
    • GitHub priority 최종 정리 (같은 test 500, 73건, 오차 ±11): 다수 답 30.1 = 프롬프팅 30.1 < 단독 학습 34.2 < Jev 37.5 < 혼합 학습(462+kind 500, 3ep) 41.1. 단독 학습은 붕괴는 없지만 최종이 혼합보다 낮음(kind 행이 공유 LoRA 에 주는 추가 업데이트가 결과적으로 도움; 단 73건이라 34↔41 차이는 오차 안). 결론: (1) 잡음 라벨에서도 학습이 프롬프팅 위로 올리긴 함(+4~11), (2) 절대 수준은 라벨이 정하고 40 근처가 이 데이터의 천장으로 보임, (3) 혼합 학습의 1 epoch 붕괴는 간섭이며 회복됨 — 에포크별 타입별 NLL 로 선택하면 위험 없음.
    • E17 GitHub 총평: kind 는 백본 공짜(83→87, Jev 85), priority 는 학습으로 30→41(Jev 37.5). 이 과제의 제품 가치는 kind coverage 표(78% 자동 @ 91%)와 priority 의 "확신 있는 10% 만 자동". 1 epoch 의 붕괴는 일시적이었고 2 epoch 에서 prior 수준으로 돌아옴. 붕괴 원인 논의(라벨이 텍스트에서 예측 안 되는 부분이 크면 CE 가 prior 를 벌하고 편향 항이 클래스 비율로 감; 우리 학습에 prior 보호 장치 없음)는 그대로 유효 — "학습해서 prior 아래로 떨어지지 않는다" 를 레시피 보장으로 만들려면 백본 동결·낮은 lr·타입별 조기 정지가 필요.

E17-C. 정정: 미로 세 질문은 모두 상수 예측이었다 (2026-09-20, 외부 제보)

외부 사용자가 공개 생성기로 미로 라벨을 재구성해 "항상 High risk" 기준선이 test 751/880 = 85.34% 임을 보였다. 우리가 "학습으로 Jev(65.6)를 이겼다" 고 올린 85.3 과 소수점까지 같다. logs/4070s/four/maze_test_preds.jsonl 을 열어 확인한 결과 제보가 맞고, 우리가 본 것보다 넓다.

미로 질문n우리다수 답차이예측 분포
risk (0/1/2/3)88085.3485.340.00880건 전부 3
death-within-3 (yes/no)88086.1486.140.00880건 전부 yes
safest move (4방향)88029.2044.20−15.00퍼져 있으나 다수 답보다 나쁨
  • 클래스별 recall(risk): gold 0 → 0/7, gold 1 → 0/29, gold 2 → 0/93, gold 3 → 751/751.

  • 확률도 학습 이전만 못하다. soft target 기준으로 학습셋에서 맞춘 상수 분포 [0.0095, 0.0255, 0.0624, 0.9026] 과 비교:

    NLLBrier
    우리 모델0.6680.281
    학습셋 상수 분포0.5390.264

    모든 입력에 학습 분포를 그대로 내놓는 쪽이 낫다. 게다가 과신이다(클래스 3 평균 확률 0.967 vs 실제 0.853).

  • 정확한 문장: "학습이 Jev 를 이겼다" 가 아니라 "Jev(65.6) 가 상수 예측(85.3) 보다 못했고, 우리도 상수 예측과 같았다". 미로는 세 질문 모두 실패이며 이 과제에서 학습 효과는 없다.

  • 왜 놓쳤나: GitHub 에서는 다수 기준선을 찍어 priority 붕괴를 잡아냈는데(E17 line 409), 나머지 과제에는 같은 점검을 하지 않았다. 다수 답이 높은 질문에서는 정확도만 보면 붕괴와 학습이 구분되지 않는다.

  • OOD(50×50, 1,200) 도 같다 — 우리가 "6배 큰 맵으로 전이된다" 고 읽은 부분:

    미로 OOD 질문n우리다수 답예측
    risk40088.0088.00 (352/400)400건 전부 3
    death40088.0088.00 (352/400)400건 전부 yes
    safest move40020.2536.50south 257 / north 143 (두 방향뿐)

    soft target 으로도 학습셋 상수 분포가 낫다(NLL 0.459 vs 우리 0.558, Brier 0.219 vs 0.231). 전이가 아니라 OOD 쪽 다수 클래스 비중이 더 커서 상수 예측의 점수가 올라간 것이다.

  • 조치: README 표에 majority 열을 전 과제에 추가하고 미로 행을 "학습 효과 없음" 으로 정정. 아래 전체 점검 결과.

과제질문n우리다수 답차이판정
피싱noul50097.4050.00+47.40진짜 (데이터 50:50)
규칙 티켓queue 4지선다988100.0026.62+73.38진짜
규칙 티켓priority 4단계98874.6036.84+37.75진짜
규칙 티켓angry noul98898.5871.76+26.82진짜
GitHubkind 4지선다50086.962.8+24.1진짜 (백본 83 이 이미 대부분)
GitHubpriority 4단계7341.130.1+11.0표본 ±11, 확률이 모름을 표시
미로risk88085.3485.340.00상수 예측
미로death88086.1486.140.00상수 예측
미로safest move88029.2044.20−15.00다수 답보다 나쁨
  • 다음 실험 (제보자 제안, E19): safe_move 를 "최적 행동 분포" 로 배우지 말고, 방향마다 독립 이진 질문 Q3(s,a) = 그 방향으로 간 뒤 3수 생존 확률 로 soft target 학습한다. 방향 간 정규화하지 않는다(여럿이 동시에 안전할 수 있으므로). 추론은 최댓값 방향, 지표는 생존 regret = (최선 방향 생존확률 − 고른 방향 생존확률). 회전·반사 증강과 1→2→3수 커리큘럼. 데이터는 이미 있다: 각 행 meta 에 survival_probability_by_first_move 가 저장돼 있다.
  • 규칙: 앞으로 모든 과제 표에 다수/상수 기준선 열을 함께 싣는다. 기준선을 못 넘으면 결과로 쓰지 않는다.

E19. 미로 safe_move: 행동별 생존확률 Q3(s,a) 로 타깃을 바꾸다 (2026-09-20, 4090)

E17-C 에서 미로 세 질문이 전부 상수 예측이었음이 드러났다. NanoJev 관리자(TianyuCodings)의 제안: choice 타깃("최적 수들에 균등")은 각 방향이 얼마나 안전한지와 방향 사이 격차를 지운다. 대신 방향마다 독립 이진 질문으로 바꾼다.

Q3(s,a) = P(첫 수 a, 이후 두 수 균등 무작위 → 세 수 모두 생존)
  • 방향 간 정규화하지 않는다(여러 방향이 동시에 안전할 수 있다). 추론은 argmax_a Q3.
  • 주 지표는 생존 regret = max_a Q3(s,a) − Q3(s, 고른 방향). tie-aware 정확도와 상수 기준선을 항상 같이 싣는다.
  • 값은 데이터에 이미 있었다(meta.survival_probability_by_first_move, 유한 열거). 변환기 scripts/make_maze_q3.py, 평가기 scripts/eval_maze_q3.py. 일관성 항등식 P(death) = 1 − mean_a Q3 가 타깃에서 오차 0 으로 성립함을 확인.
  • 설정: Qwen3-4B-Base + LoRA, noul 소프트 타깃, 2,628 상태 × 4 방향 = 10,512 행, 2 epoch (1,314 스텝), bs 8 × accum 2.

확률은 배웠다.

test Briertest NLLOOD Brier사망확률 MAE (test / OOD)
모델0.04490.4870.04410.066 / 0.061
방향별 학습셋 평균 상수0.07470.5610.06850.155 / 0.141

Brier 40% 감소, 1 − mean_a Q3 로 유도한 사망확률의 MAE 58% 감소. 지도를 읽고 생존확률을 추정한다.

행동 선택은 여전히 실패다.

test (880 상태)생존 regrettie-aware 정확도
모델 (argmax Q3)0.168843.41
항상 north0.176744.20
항상 south0.174443.75
무작위0.193837.95
오라클0100

regret 이 최선 상수보다 0.008 낮을 뿐이고 tie-aware 는 오히려 낮다(기존 choice 모델 44.7 보다도 낮다). OOD(400) 에서는 조금 낫다: regret 0.158 vs 최선 상수 0.177, tie-aware 48.0 vs 42.0 — 여기서는 상수를 넘는다.

  • 해석: 타깃 형태를 바꾸니 확률 문제는 풀렸지만 순위 문제는 안 풀렸다. 방향당 Brier 0.045 는 방향당 오차 ~0.21 인데, 상태의 45.6% 가 동점이고 나머지도 방향 간 차이가 0.125 단위로 촘촘해 그 정밀도로는 최선 방향을 안정적으로 집지 못한다.
  • 부수 확인: 최적 방향 분포는 원래도 거의 균등했다(north 25.9 / east 24.1 / south 25.6 / west 24.4). safe_move 의 "다수 답 44.2%" 는 동점을 argmax 로 깨면서 north 가 먼저 오는 순서 때문에 생긴 값이다 — 동점 인지 지표가 정직한 쪽이다.

E19-B. 회전 증강을 더하니 행동 선택이 풀렸다 (2026-09-21 01:25 KST)

같은 Q3 타깃에 회전 4배 증강(지도와 방향을 함께 변환, 최적 방향 분포가 정확히 25% 씩)만 추가. 42,048 행 × 1 epoch (2,628 스텝), 나머지 설정 동일. val: 정확도 91.2 / Brier 0.0363 / NLL 0.384 (증강 없을 때 88.3 / 0.0808 / 0.473).

test (880 상태)생존 regrettie-aware 정확도
Q3 + 회전 증강0.057768.07
Q3 (증강 없음)0.168843.41
기존 choice 모델 (E17)44.7
Jev 0샷 (E17)55.3
항상 north (최선 상수)0.176744.20
항상 south / east / west0.1744 / 0.2050 / 0.208743.75 / 31.25 / 29.89
무작위0.193837.95
오라클0100
OOD (50×50, 400 상태)생존 regrettie-aware 정확도
Q3 + 회전 증강0.044170.50
Q3 (증강 없음)0.158048.00
항상 west (최선 상수)0.176742.00
  • regret 이 최선 상수의 3분의 1, 중앙값은 0 (절반 이상의 상태에서 최적 수를 정확히 고른다). 동점 상태는 test 45.6% / OOD 47.8%. 학습한 것보다 6배 큰 맵에서 오히려 더 좋다 — 이번엔 상수 예측이 아니라 진짜다.
  • 확률도 같이: test Brier 0.0198 (상수 0.0747, −73%), NLL 0.390 (0.561). 사망확률 MAE 0.0454 (상수 0.1554), OOD 0.0458 (0.1406). 일관성 P(death) = 1 − mean_a Q3 로 유도한 값이다.
  • 두 가지가 다 필요했다. 타깃을 Q3 로 바꾼 것만으로는 확률만 좋아지고 순위는 상수 수준이었다(E19 위 표). 회전 증강을 더하자 방향당 오차가 방향 간 간격(0.125)보다 작아지면서 순위가 잡혔다.
  • 체크포인트 없음: 평가 직후 인스턴스가 반납되어 어댑터·헤드를 회수하지 못했다. 위 설정 그대로 (scripts/make_maze_q3.py --augment rot--epochs 1 --batch-size 8 --grad-accum 2 --lr 5e-5 --seed 0) 4090 2시간 20분이면 재현된다. 교훈: 평가가 끝나면 보고 전에 체크포인트부터 내려받는다.
  • 다음: 1→2→3수 커리큘럼, 반사까지 8배, 맵 수 늘리기, 그리고 관리자가 준 원본 과제 (navigation / local_safety / one_step_probability)를 따로.

E17-D. 정정: Jev 비교 넷 중 둘은 같은 항목에서 잰 게 아니다 (2026-09-21)

E17 을 "같은 test 셋에서 우리 vs Jev" 로 적었는데, 아티팩트를 세어 보니 사실이 아니다.

과제Jev 숫자실제 출처항목 일치
GitHub kind/priority84.7 / 37.5우리 실행, logs/jev_four/jev_github_test500.jsonl (500 행)
maze risk/death/safe_move65.6 / 86.3 / 41.4우리 실행, jev_maze_test.jsonl (2,640) · jev_maze_ood.jsonl (1,200)
phishing 62.6 / ECE 0.154anisselbd/jev-phishing-bench README 의 2,000 통 전체 수치우리는 피싱에서 Jev 를 돌린 적이 없다
rule_tickets 75.1 / ECE 0.107E13 의 val 900 (E1 생성기, seed 0)test 2,964 가 아니다
  • logs/jev_four/ 에 phishing 파일이 없다는 것이 증거다. 네 과제 중 Jev 를 실제로 돌린 것은 GitHub 와 maze 뿐이다.
  • 이 오류는 E17-C(미로 상수 예측)와 같은 종류다: 비교의 양쪽이 같은 조건인지 확인하지 않고 표에 나란히 놓았다.
  • 조치: README 의 "same test items for us and for Jev" 제목과 문장을 고치고, 항목 불일치 행에 † 를 붙여 출처를 명시. jev-phishing-bench#1 이슈에도 정정 댓글(우리가 Jev 를 돌리지 않았다는 사실 + 다수 기준선 50.0).
  • 되돌리려면: AI Gateway 로 같은 test 500 에 Jev 를 돌리면 된다(500 콜, 몇 분). 그때까지는 † 로 둔다.
  • 규칙: 비교 표의 각 칸은 출처(우리 실행인지 인용인지)와 항목 수를 함께 기록한다. 인용 수치는 반드시 표시한다.

E18. 과제 전용 구조적 가지치기: "이 과제엔 파라미터가 몇 개 필요한가, 어디까지 정직한가" (계획, 2026-09-20)

질문 셋. (1) 규칙 티켓으로 학습한 Qwen3-4B 에서 층·FFN 뉴런·KV 그룹을 과제 손실 기준으로 잘라 가면 정확도가 어디서 꺾이는가. (2) 캘리브레이션(ECE·T)이 정확도보다 먼저 무너지는가 (Don't Go Breaking My LLM, 2026). (3) 잘라서 1.7B·0.6B 근처가 된 모델이 같은 크기를 직접 학습한 E15 사다리(84.3 / 82.1)보다 나은가 (Sheared LLaMA 가설).

  • 시작점: checkpoints/four/rule_tickets (4B + LoRA, test 91.1 / ECE 0.022). LoRA 병합 → dense.

  • 절차 (luce/prune.py): 가지치기 부분집합(train 의 다양한 256건)으로 중요도 → 자르기 → LoRA 1 epoch 회복(이전 헤드에서 시작, --init-head) → 병합 → val 로 정확도·NLL·ECE·refit T. 스케줄: 층 4개씩 × 3 → FFN/KV 폭 0.8 × 2 …

    • 층 중요도: 그 층을 뺐을 때의 과제 NLL 증가 (+ ShortGPT 블록 영향도 비교용).
    • 폭 중요도: FFN 채널 = mean|act| × ||down 열|| (Wanda 식), 어텐션 = KV 그룹별 mean||head out|| × ||o_proj 열||. 층마다 같은 비율(HF config 가 층별 폭을 못 가짐; 균일해야 실제 가속).
    • 자르기는 항상 "축소 config 로 새 모델 + 복사" → stale 속성 없음, from_pretrained 로 그대로 열림.
    • 은닉 차원은 유지(헤드·임베딩 호환).
  • 캘리브레이션 보존: --calib-weight 로 MMCE(Kumar 2018, Laplacian 커널) 벌점을 손실에 추가해 같은 스케줄 반복. 멈춤 기준은 정확도 −1pp 와 ECE +0.01 둘 다.

  • 두 번째 과제: phishing (97.4) 로 같은 절차 → 남는 크기가 과제마다 다른지.

  • 예상 비용: 4090 하루 (A 층 23 h, B 폭 34 h, C 보정 반복).

  • 두 방식 비교 (사용자 지정: 원하는 것은 B)

    • A. 자르고-회복 바깥 루프 (luce.prune curve): 중요도 채점 → 자르기 → LoRA 1 epoch 회복 → 재병합 → 반복. 16:41 KST 4080 시작(rule_tickets, CALIB=0, 층 4개×3 → 폭 0.8×3).
    • B. 학습 중 점진 가지치기 (luce.gradual + luce.train --gradual-prune-target): 한 학습 안에서 스텝마다 |활성×그래디언트| 중요도를 공짜로 누적하고, N 스텝마다 3차 스케줄(Zhu&Gupta)의 목표 희소도까지 최하위 FFN 채널·KV 그룹(층마다 같은 개수)·층을 마스크로 영구히 끔. 끈 뒤에도 LoRA 가 계속 돌아 남은 단위가 적응. 누적은 이벤트마다 리셋. 에포크마다 val 과 마스크 저장, 검증이 꺾인 직전 에포크 채택, 마스크대로 luce.prune cut --masks 로 물리 슬라이스. 첫 층은 보호.
    • 같은 시작점·데이터·목표 크기에서 A 와 B 를 나란히 (CoFi 가 한 비교). 예상: B 가 같은 크기에서 더 높음(적응이 연속적).
  • B 의 두 구현: mask(0 곱하기; 계산량·메모리 그대로, 끝에 물리 슬라이스) 와 physical(기본). physical 은 이벤트마다 가중치를 실제로 슬라이스한다 — FFN 채널은 gate/up 행·down 열, KV 그룹은 q 행(groups×head_dim)·k/v 행·o 열, 층은 ModuleList 제거 + num_hidden_layers/layer_types 갱신 + layer_idx 재번호. PEFT 래퍼는 base_layer 와 lora_A(열)/lora_B(행) 를 같이 자르고, AdamW 의 exp_avg/exp_avg_sq 도 같은 인덱스로 잘라 모멘텀을 유지. 제거된 층의 파라미터는 옵티마이저 그룹에서도 뺀다. 스텝이 갈수록 forward/backward 가 실제로 가벼워지고 메모리가 준다(사용자 요구). 체크포인트는 잘린 백본을 ckpt/backbone/ 에 HF 형식으로 같이 저장하고 DecisionModel.load 가 그걸 우선 쓴다; 최종 모델은 luce.prune merge 로 LoRA 병합.

  • 중요도 누적은 토큰 128개 표본만 붙들어 메모리를 아낀다(전체를 붙들면 4B/36층에서 +6.5GB → 첫 실행 OOM).

  • A 는 시작 직후 폐기(사용자 결정: 대조군 불필요). 비교는 E15 직접 학습 사다리(1.7B 84.3 / 0.6B 82.1)와.

  • 실행 결과 (rule_tickets, mask 모드, 4080, 2026-09-20 17:17~18:02 KST, 2에포크에서 중단)

    4B 1에포크 (자르기 없음)가지치기 에포크 1가지치기 에포크 2
    파라미터100%65%37%
    val 정확도91.983.760.9
    val ECE0.0240.0840.202
    보정 T0.881.532.47
    보정 후 ECE0.0170.0510.068

    학습 손실: 에포크 1 끝 0.35 → 에포크 2 중반 0.55 → 440스텝 1.52. 자르는 속도가 적응 속도를 앞질렀다.

    • 실패 원인(설계): 3차 스케줄의 중간 구간이 가장 가파른데 20스텝마다 잘라 회복 구간이 없었다. 에포크 2 한 번에 65%→37%, 그 사이 학습은 188스텝뿐. 601스텝의 자르기 종료와 151스텝 적응 구간에 도달하기 전에 무너졌다.
    • 건진 관찰: 정확도가 23pp 무너진 지점에서도 ECE 0.202 는 T=2.47 로 0.068 까지 복구됐다 — 확률의 순서는 살아 있고 과신만 한다. "캘리브레이션이 먼저 무너지는가"에 대한 첫 데이터: 무너지는 것은 스케일이지 순서가 아니다.
    • 다음 실행 조건: 에포크 68 로 늘리거나 목표를 0.5 → 0.3 으로 낮춰 자르기 사이 적응 스텝을 최소 34배 확보. --prune-every 를 늘리는 것보다 총 스텝을 늘리는 쪽이 맞다(이벤트당 잘리는 양이 아니라 이벤트 사이 회복량이 부족했다).
    • 아티팩트: logs/prune/rule_tickets_grad0.5_L12_calib0.log, logs/prune/history.json, logs/prune/prune_masks.json. 에포크 1 체크포인트(65%, 83.7)는 4080 에 남겨 두고 GPU 반납 전 폐기.
  • E18-B2 (physical, 2B 목표, 4090, 2026-09-20 18:45~20:10 KST): 목표를 완만하게(층 12→6 제거, 폭 0.5→0.47), 에포크 4→6, 자르기 종료 뒤 적응 구간 151→339 스텝. 물리 슬라이싱이라 메모리 12.9→8.3 GiB, 스텝 시간도 감소.

    에포크파라미터val 정확도val ECE보정 T보정 후 ECE
    13.95B (98%)91.00.0340.790.020
    22.55B (63%)84.90.0711.610.030
    32.02B (50%)78.50.0811.440.025
    41.98B (49%)89.80.0311.220.015
    51.98B90.40.069
    61.98B90.60.073
    • 설계 검증: 깎는 동안 떨어지고(에포크 3 에서 78.5 로 바닥) 자르기가 끝난 뒤 적응 구간에서 89.8 로 회복. E18-B1 실패와의 차이는 적응 시간뿐.
    • 캘리브레이션에 대한 정확한 문장: 가지치기는 ECE 를 0.034→0.081 로 두 배 넘게 악화시키고 T 를 0.79→1.61 로 밀어올린다(과신 방향). 하지만 그 손상은 스칼라 온도 하나로 복구되는 종류였고(보정 후 0.020~0.030 유지), 충분한 적응 뒤에는 원래 수준(0.015)으로 돌아온다. 2026 년의 "가지치기가 캘리브레이션을 먼저 깨뜨린다" 는 재학습 없는 사후 가지치기를 본 것이므로 모순이 아니라 조건이 다르다.
    • 체크포인트 선택 함정: --select-by calibrated_nll 은 점진 가지치기에서 가장 덜 깎인 에포크 1(98%) 을 고른다. 이 실험에서 의미 있는 모델은 ckpt/last(= 목표 크기) 이다. 앞으로 가지치기 실행은 last 를 기준으로 봐야 한다.
    • 아직 결론이 아닌 것 (검증 큐에 걸림): (a) E15 의 1.7B=84.3 은 라벨 1,000개·2에포크·val 498 이라 조건이 다르다 → Qwen3-1.7B 를 같은 데이터·같은 6에포크로 직접 학습해 같은 test 에서 비교. (b) 4B 도 1에포크(91.9)가 아니라 같은 6에포크 기준선이 있어야 손실 폭이 정확하다. (c) val 로 고른 T 로 val 을 판정하면 안 된다 → test 로 최종 판정. (d) 층은 17% 만 줄고 나머지는 폭이라 파라미터 51% 감소가 속도로 얼마나 이어지는지 지연시간 측정 필요(scripts/bench_latency.py).
  • E18-B3 동일 조건 기준선과 최종 판정 (4090, 2026-09-20 20:20~21:28 KST)

    같은 데이터(train 3,000 / val 1,485 / test 2,964), 같은 6에포크·배치·학습률·시드, 같은 평가 절차(val 에서 타입별 T 적합 → test). 모든 모델은 마지막 에포크 체크포인트로 비교했다.

    모델크기test 정확도test ECEtest NLLbs=1 지연bs=8 지연
    Qwen3-1.7B 직접 학습1.74B91.10.0210.245128.6 ms17.8 ms
    깎은 모델 (4B→)1.98B90.00.0180.26373.5 ms11.2 ms
    4B 원본 (2에포크, E17)4.02B91.1167.0 ms24.4 ms
    • 결론: 이 과제에서 가지치기는 정확도로 직접 학습을 이기지 못한다. 1.7B 를 같은 데이터·같은 에포크로 직접 학습하면 91.1 로 4B 원본과 동률이며, 깎은 1.98B 보다 1.1pp 높다. Sheared LLaMA 가설은 규칙 티켓에서 성립하지 않았다.
    • 남는 것은 지연시간: 깎은 모델은 파라미터가 14% 더 많은데도 1.7B 보다 bs=1 에서 1.75배, bs=8 에서 1.59배 빠르다. KV 그룹을 8→4 로 줄인 것이 층 수(30 vs 28)보다 크게 작용했다. 4B 대비로는 2.2배. "이미 학습한 4B 를 2.2배 빠르고 메모리 절반인 모델로 바꾸면서 test 1.1pp 를 잃는다" 는 배포 관점의 결과는 유효하다.
    • 과제가 판별력이 없었다: 4B 가 1에포크에 val 91.9 로 포화하고 1.7B 도 6에포크면 91.1 에 닿는다. 용량이 병목인 과제(미로의 3단계 앞보기 등)에서 다시 재야 가지치기의 이점 유무를 말할 수 있다.
    • 두 번의 잘못된 중간 보고(기록용): (1) E15 의 1.7B=84.3 을 그대로 비교해 "5.5pp 우위" 라고 했다 — 라벨 1,000개·2에포크·val 498 로 조건이 달랐다. (2) 기준선의 --select-by calibrated_nll에포크 1(val 86.9)을 골랐는데 그 test(86.1)로 "3.9pp 우위" 라고 했다 — 정확도 최고는 에포크 6(val 90.4, test 91.1). 가지치기 쪽에서 같은 함정을 이미 발견했으면서 기준선에 적용하지 않았다. 교훈: 비교하는 모든 팔에 대해 어느 에포크가 저장됐는지 먼저 확인한다.
    • 미완: 크기 정합(목표 0.41 → 1.72B) 실행과 4B 6에포크 기준선은 사용자 지시로 중단.
    • 아티팩트: logs/prune/ (step1_17b.log, finish_last.log, baseline_q1.7b_e6.log, latency*.json, history_q17b.json, prune_masks.json, 각 test dump).
  • physical 모드(실제 슬라이싱)는 구현만 하고 검증 전에 사용자 지시로 중단 — luce/gradual.py::PhysicalPruner, run_gradual_physical.sh 에 보존. 다음 실행에서 쓰려면 SmolLM2 스모크부터.

스모크 테스트(로컬, SmolLM2-135M)에서 나온 것

  • v2.1 체크포인트를 v2.2 코드로 로드/평가: 하위 호환 정상.
  • 추론 비결정성: 같은 질문을 배치 구성 다르게 두 번 물으면 확률이 미세하게 다름. 셔플 누수 아님(training=False 확인). 배치별 left padding 길이 차이 → fp16/bf16 수치 잡음. 기준: 차이 1e-2 이하면 잡음.
  • 셔플 검증: train 모드에서 순서를 섞어도 argmax가 원래 키 자리로 복원됨.
  • T=20.0000: 135M이 18개 val에서 정보가 없으면 NLL 최적 T→∞. fit_temperature에 [0.05, 20] 클램프와 경계 경고 추가.

B1. Luce v0.2 빌드 (2026-09-19, 실험 아님)

jevlocalluce 리네임(shim 유지), luce.yaml + CLI(init/synth/baseline/train/eval/serve/convert), synth 파이프라인(페르소나·grid·의도·near-miss·dedup·다중 투표), 실제 검증셋 강제([in-synth] 태그), 타입별 temperature, selective-risk 표, review 큐, 모델 카드 5개, torch-free 단위 테스트 11개.

  • 검증: 휠 빌드 → 새 venv 설치 → luce --help/init/dry-run 통과. gpt-4o-mini teacher 로 init(예시 30티켓 → seeds 15 / real 15 자동 분리) → synth 60 (41초, 오류 0) → SmolLM2 train(--real) → eval(--real, 타입별 T 저장) → baseline → serve(review 2건) → --append 재학습까지 전부 통과.
  • 발견·수정: init 이 씨앗의 subject/body 문장을 grid 값으로 복사 → 생성물이 두 주제로 쏠려 라벨 분포 왜곡(billing 30/general 27/shipping 0). 씨앗 필드 값 복사 감지 guard + 자유 텍스트 값 필터 + 기본 축(sentiment/length) 채움 후 billing 20/shipping 16/technical 17/general 7 로 회복.
  • luce eval --synth 가 luce.yaml 의 eval.real 에 밀리던 우선순위 수정 (명시 --synth > 설정 real).
  • 미실행: HF 업로드(사용자 지시로 제외), openjev 열 측정.

코드 변경 결정 기록

  • mps 자동 감지 + fp16 (E0 버그).
  • --score-sigma 기본 0 (E3).
  • 평가에 source별 분해 추가 (E4 준비).
  • --scorer cross, --lm-prior (E5 → E6).
  • --options-in-prefix, --continuation label|text, 학습 중 셔플 (E6 → E7).
  • --eval-init (0스텝 측정).
  • --head-lr, --freeze-backbone-steps (E7 발산 대응; 실행 2는 이 플래그 없이 lr 5e-5만으로 안정).
  • fit_temperature 클램프 (스모크).
  • --permute-seed 평가 (E9 실행 완료).
  • 베스트 체크포인트 선택 기준: 보정 전 NLL → epoch 마다 T 를 맞춘 보정 후 NLL (--select-by calibrated_nll|nll|accuracy). 마지막 epoch 도 <out>/last/ 에 저장 (--no-save-last 로 끔). E6/E7 의 "정확도는 오르고 NLL 은 나빠진 epoch 2" 를 버린 문제의 대응. 4090 의 다음 실행부터 적용.
  • label 모드 학습률: 2e-4 발산 → 5e-5 (E7). LM prior 로 v0 근처에서 출발하는 설정은 잔차 학습이므로 낮은 LR.
  • fit_temperature: LBFGS 가 overflow 로 죽어 경계 있는 격자+황금분할 탐색으로 교체 (합성 첫 실행에서 발견). [0.05, 20] 경계 경고.
  • Ouro-2.6B 호환 (E14 준비, 4090): (1) 백본 forward 에 use_cache=False 명시 — Ouro 의 UniversalTransformerCachekey_cache setter 가 없어 기본 use_cache=True 에서 죽음(로짓만 읽으므로 캐시 불필요). (2) Ouro 바디는 (ModelOutput, hidden_states_list, gate_list) 튜플을 돌려줌 → _last_hidden() 헬퍼로 표준/튜플 모두 처리. (3) 공유 prefix KV 캐시는 이 백본에서 불가 → 어떤 예외든 per-option 경로로 자동 폴백(메시지 1회). (4) transformers 5.x 에서 Ouro 커스텀 코드가 깨져(pad_token_id, RoPE KeyError: 'default') 4090 에 /venv/ouro(transformers 4.54.1, peft 0.17.1) 별도 구성.
  • label 모드 26개 초과 예제 (--label-overflow isolated|text, 기본 isolated): 이전엔 77개를 프리픽스에 나열한 채 원문을 이어붙여 예제당 77×~600 토큰. 기본값을 "나열 없이 isolated 채점" 으로 바꿈(예제당 77×~80 토큰). E10 의 banking77 은 옛 방식(text)으로 학습됐으므로 재현 시 --label-overflow text.
  • 보정 재로드 메모리 정리(참조 해제 + gc + empty_cache) CUDA 에서 확인: Ouro 16건 학습 후 "gpu memory after release: 0.6 GB".

열린 질문 / 다음

  1. E7 epoch 2 + 보정 후 최종 표, 위치 불변성 → 완료 (E6/E7 최종, E9).
  2. cross-label에서 --head-lr 5e-4 효과: 단일 5e-5는 헤드가 느릴 수 있음. "안정적인데 v0에 붙어 있음"이면 이 손잡이.
  3. ARC-Challenge: 고립 검증(isolated) vs 비교 선택(label)의 격차가 어려운 문제에서 남는가.
  4. 한국어: klue_ynat, nsmc 같은 비교. 스크립트 데이터셋 로딩 거부 시 convert.py csv.
  5. 일반성: → E10 진행 중 (arc+boolq+banking77 학습, OBQA/CSQA/HellaSwag held-out).
  6. source별 temperature (E5 T=1.51 문제).
  7. cross 모드 prefix KV 캐시 공유 (긴 state × 많은 선택지 비용).
  8. 정확도에 bootstrap 신뢰구간 붙이기 (릴리스 표용).
  9. 릴리스: 이름 변경(Jev/System One 상표 회피), Apache 2.0, 모델 카드에 데이터 라이선스(ARC/KLUE CC BY-SA 4.0, BoolQ CC BY-SA 3.0, NSMC CC0)와 캘리브레이션 리포트. 공개 가중치는 공개 데이터만으로.

한 줄 요약 (현재 시점)

같은 Qwen2.5-3B, 학습 파라미터 1%, 4080 한 장 45분. 백본이 아는 것(ARC 93%)은 지키고, 모르던 것(BoolQ 80→88%)은 얻고, NLL은 0.379→0.273. 캘리브레이션은 잃지 않음.