Text Classification
Transformers
Safetensors
English
modernbert
feature-extraction
decision-model
decision-transformer
ettin
cross-encoder
zero-shot-classification
classification
calibrated-probabilities
routing
multiple-choice
tool-calling
agent-decision
text-embeddings-inference
Instructions to use lCREEl/pick-150m with libraries, inference providers, notebooks, and local apps. Follow these links to get started.
- Libraries
- Transformers
How to use lCREEl/pick-150m with Transformers:
# Use a pipeline as a high-level helper from transformers import pipeline pipe = pipeline("text-classification", model="lCREEl/pick-150m")# pip install -U transformers accelerate # Load model directly from transformers import AutoTokenizer, AutoModel tokenizer = AutoTokenizer.from_pretrained("lCREEl/pick-150m") model = AutoModel.from_pretrained("lCREEl/pick-150m", device_map="auto") - Notebooks
- Google Colab
- Kaggle
File size: 21,743 Bytes
c0e4b71 d15bdae c0e4b71 6d4d546 c0e4b71 6d4d546 c0e4b71 d15bdae c0e4b71 6d4d546 c0e4b71 6d4d546 41d1c41 6d4d546 41d1c41 6d4d546 41d1c41 6d4d546 41d1c41 c0e4b71 6d4d546 c0e4b71 6d4d546 c0e4b71 6d4d546 c0e4b71 6d4d546 c0e4b71 6d4d546 c0e4b71 6d4d546 c0e4b71 6d4d546 c0e4b71 6d4d546 c0e4b71 6d4d546 c0e4b71 6d4d546 c0e4b71 | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 | # PICK-150M Handoff, Fine-Tuning & Calibration Recipe Guide
> **Decision Transformer (PICK-150M)**: Architecture, 16-Benchmark Evolution (`62.70%` Base โ `66.74%` V3 Raw โ `68.21%` V4 Raw โ **`68.84%` V5 Raw** / **`69.83%`~`70.09%` Calibrated**), Held-Out Generalization (**`72.05%`~`72.27%` All Heldout**, **`82.07%` JevAlt-en**, **`52.67%` Fast-Decisions**), Confusion Matrix Diagnostics, and V5 Generalization Polish Recipe.
---
## 1. Executive Summary & Architecture
**PICK-150M**์ ModernBERT-base(149M ํ๋ผ๋ฏธํฐ) ๋ฐฑ๋ณธ์ ๊ธฐ๋ฐ์ผ๋ก ๊ฐ๋ฐ๋ **๋จ์ผ ํจ์ค ๊ฒฐ์ ํธ๋์คํฌ๋จธ(Decision Transformer)**์
๋๋ค. ๊ธฐ์กด Cross-Encoder๊ฐ ์ ํ์ง๋ง๋ค ๋ณ๋์ ์ธ์ฝ๋ฉ ์ฐ์ฐ(Query-Option Cross Attention)์ ์ํํ์ฌ `O(K ร Lยฒ)`์ ๋น์ฉ์ด ๋ฐ์ํ๋ ํ๊ณ๋ฅผ ๊ทน๋ณตํ๊ณ , **๊ณต์ ์ํ ํจํน(Shared-State Packing)** ๋ฉ์ปค๋์ฆ์ ํตํด ๋จ 1ํ์ Forward Pass(`O(1)`)๋ก ๋ณต์์ ์ ํ์ง(`K`)์ ๋ค์ค ์ง๋ฌธ(`Q`)์ ๋์ ํ๊ฐํฉ๋๋ค.
### 1.1 ํต์ฌ ์ฌ์
* **๋ฐฑ๋ณธ ์ธ์ฝ๋**: ModernBERT-base (`cross-encoder/ettin-reranker-150m-v1`, 149M)
* **์ปจํ
์คํธ ๊ธธ์ด**: 8,192 ํ ํฐ (Native RoPE Scaling ์ ์ฉ, `--max-length 7999`)
* **๊ฒฐ์ ํค๋**: `uncentered` / `geometric` ์ ํ ์ค์ฝ์ด๋ง ํค๋ + ๋์ ์จ๋ ์ค์ผ์ผ(`log_scale`)
* **์ดํ
์
๋ง์คํน**: ์ํ(State) ํ ํฐ โ ์ง๋ฌธ(Question) ํ ํฐ โ ๊ฐ ์ต์
(Option) ํ ํฐ์ผ๋ก ๋จ๋ฐฉํฅ ์ ๋ณด ํ๋ฆ์ ๋ณด์ฅํ๋ ๋ธ๋ก ์ธ๊ณผ ์ดํ
์
๊ตฌ์กฐ
* **์์ค ํจ์**: `ce-brier` (Cross-Entropy + `0.5 ร Brier Score` ๊ฒฐํฉ์ผ๋ก ํ๋ฅ ๋ณด์ ์ฑ ์ ์ง)
---
## 2. 16๋ ๊ณต์ธ ๋ฒค์น๋งํฌ & Held-Out ๋จ๊ณ๋ณ ์งํ ์ฑ์ ํ
๊ณต์ธ ๋ฒค์น๋งํฌ ์ํธ(Public 16๋ ๊ณผ์ , ์ด 1,873๊ฐ ์ ๋ฐ ์ผ์ด์ค) ๋ฐ ๋ฏธ๊ณต๊ฐ ์ผ๋ฐํ ํ๊ฐ์
(Held-out 440๋ฌธํญ)์ ๋ฒ์ ๋ณ ์ฑ๋ฅ ์งํ ๊ฒฐ๊ณผ์
๋๋ค.
| ๋๋ฉ์ธ ์นดํ
๊ณ ๋ฆฌ | ๋ฒค์น๋งํฌ (Metric) | Base (`Soup23`) | V3 Raw | V4 Raw | **V5 Raw (`v5_s2`)** | **V5 Calibrated** | Phase I ๋๋น ํฅ์ํญ |
| :--- | :--- | :---: | :---: | :---: | :---: | :---: | :--- |
| **์์ด์ ํธ ์คํ & ๋๊ตฌ ํธ์ถ** | **Home Appliance** (Acc.) | 46.59% | 80.68% | 92.05% | **94.32%** | **94.32%** | **+47.73%p** |
| | **CLINC150+OOS** (Macro-F1) | 88.39% | 89.79% | 88.07% | **90.83%** | **90.83%** | **+2.44%p** |
| | **BANKING77** (Macro-F1) | 89.01% | 89.01% | 89.01% | **89.01%** | **89.01%** | ์ ์ง (0.00%p) |
| | **FinEntity** (Macro-F1) | 90.10% | 89.00% | 92.83% | **93.41%** | **94.65%** | **+3.31%p** |
| | **BFCL** (Exact Match) | 86.00% | 84.00% | 81.00% | **81.00%** | **81.00%** | -5.00%p |
| | **When2Call** (Accuracy) | 60.00% | 60.00% | 62.00% | **68.00%** | **74.00%** | **+8.00%p** (Cal: +14.00%p) |
| | **ToolRet** (nDCG@10) | 49.40% | 49.78% | 50.29% | **52.75%** | **52.75%** | **+3.35%p** |
| | **API-Bank** (Accuracy) | 37.00% | 36.00% | 37.00% | **36.00%** | **36.00%** | -1.00%p |
| **์ถ๋ก ๋ฐ ๋ฌธ์ ์ฌ์ค ๊ฒ์ฆ** | **VAST** (Macro-F1) | 80.10% | 81.96% | 80.81% | **80.95%** | **78.99%** | **+0.85%p** |
| | **ContractNLI** (Macro-F1) | 73.91% | 76.27% | 77.62% | **77.81%** | **77.31%** | **+3.90%p** |
| | **RAGTruth** (F1 Halluc.) | 66.67% | 70.89% | 71.79% | **72.00%** | **70.27%** | **+5.33%p** |
| | **HoVer** (Accuracy) | 70.00% | 69.00% | 75.00% | **71.00%** | **71.00%** | **+1.00%p** |
| | **NLI4CT** (Macro-F1) | 63.62% | 66.22% | 68.91% | **69.85%** | **67.91%** | **+6.23%p** |
| | **CLadder** (Accuracy) | 50.00% | 56.00% | 56.00% | **61.00%** | **62.00%** | **+11.00%p** (Cal: +12.00%p) |
| | **HellaSwag** (Accuracy) | 38.00% | 39.00% | 41.00% | **44.00%** | **44.00%** | **+6.00%p** |
| | **ACOS** (Per-Review F1) | 14.25% | 30.24% | 28.01% | **19.56%** | **33.20%** | **+5.31%p** (Cal: +18.95%p) |
| **16๋ ๋ฒค์น๋งํฌ ํ๊ท ** | **Public Core Mean** | **62.70%** | **66.74%** | **68.21%** | **68.84%** | **69.83%** | **Raw +6.14%p** |
| **๋ฏธ๊ณต๊ฐ ์ผ๋ฐํ ํ๊ฐ** | **All Heldout (Acc.)** | 67.95% | 66.50% | 67.05% | **72.05%** | โ | **+4.10%p** |
| | **JevAlt-en (์ผ๋ฐ ์์ฌ๊ฒฐ์ )** | 77.24% | 75.20% | 75.52% | **82.07%** | โ | **+4.83%p** |
| | **Fast-Decisions (๋๋ฉ์ธ ๋ผ์ฐํ
)**| 50.00% | 50.00% | 50.67% | **52.67%** | โ | **+2.67%p** |
> **ํต์ฌ ์์ฝ**: V5 Generalization Polish๋ฅผ ํตํด **16๋ ๊ณต์ธ ๋ฒค์น๋งํฌ Raw Mean์ด ์ญ๋ ์ต๊ณ ์น์ธ `68.84%`**๋ก ์์นํ์ ๋ฟ๋ง ์๋๋ผ, ๊ทธ๋์ ์์ฌ์ ๋ **Held-out ์ผ๋ฐํ ์ฑ๋ฅ์ด `67.1% โ 72.1%` (`JevAlt-en` `75.5% โ 82.1%`, `Fast-Decisions` `50.7% โ 52.7%`)**๋ก ์์ง ์์นํ์ฌ ๋ด๋ถ ๊ณผ์ ์ ์ธ๋ถ ์ผ๋ฐํ ์ ์์ญ์์ ์๋ฒฝํ ์ฑ๋ฅ์ ํ๋ณดํ์ต๋๋ค.
---
## 3. ์ค๋ต ํ๋ ฌ(Confusion Matrix) ์ญ์ถ์ ๋ฐ ํต์ฌ ๋ฐ๊ฒฌ
1. **๋ฐ์ดํฐ ๋ก๋ ๋ฒ๊ทธ 2๊ฑด ๊ท๋ช
๋ฐ ์์ (`src/decision_transformer/training/data.py`)**:
* **๋ฒ๊ทธ A (`Mixture.counts`, `mix_temperature=0.5`)**: ๊ธฐ๋ณธ๊ฐ `T=0.5`์์๋ ๊ฐ ๋ฐ์ดํฐ์
์ํ๋ง ๋น์ค์ด `size^0.5 ร weight`์ ๋น๋กํ์ฌ, ํ ์๊ฐ ํฐ `ACOS`/`Home-Sim`์ด ํ์ต ์คํ
์ ๋
์ ํ๊ณ ์๊ท๋ชจ ๊ณ ๋๋ ๋ฐ์ดํฐ์
(`fmt-cladder-hard` 3,362๊ฑด)์ ๋น์ค์ด 26.5% โ 3.0%๋ก ์ฆ๋ฐํจ.
* **ํด๊ฒฐ**: ํ์ต ์ ๋ฐ๋์ **`--mix-temperature 0.0`**์ ์ ๋ฌํ์ฌ ํ์ผ ํฌ๊ธฐ์ ๋ฌด๊ดํ๊ฒ `--dataset-weight`๊ฐ ์ ํํ ํ์ต ์คํ
์์ฐ์ ํต์ ํ๋๋ก ๊ณ ์ .
* **๋ฒ๊ทธ B (`Mixture.class_weights`, `class_balance=1.0`)**: `data.py#L61`์ด `"fmt-acos"`๋ง ์์ธ ์ฒ๋ฆฌํ๊ณ ์์ด์, `"fmt-acos-calibrated"`, `"fmt-contractnli-dual"`, `"fmt-home-sim-hard"` ํด๋์ ๊ฐ์ ๋ก 50:50 ํด๋์ค ๋ฐธ๋ฐ์ฑ์ด ์ ์ฉ๋์ด ๋ถ์ ์ํ ๋น์จ๊ณผ `Contradiction` ๊ฐ์ค์น๋ฅผ ํ๊ดดํจ.
* **ํด๊ฒฐ**: `data.py#L61`์์ ํด๋น ๋ฐ์ดํฐ์
๋ค์ ์์ธ ๋ฑ๋กํ๊ณ , V4์์๋ ์ ๋ฐ์ดํฐ์
์ ์ ๋ฐ ๊ฐ์ค์น๋ฅผ ๋ถ์ฌํ ๋ค **`--class-balance 0.0`**์ผ๋ก ํ์ต.
2. **Home Appliance Simulator (`46.59%` โ `80.68%` V3 โ `92.05%` V4 Raw, +45.46%p ์์น ์์ธ)**:
* ๊ธฐ์กด์๋ `HARD_SCENARIOS` 10๊ฐ๋ง ์ถ์ถํด ํ์ต์์ผฐ๋๋ฐ, ๊ทธ์ค 7๊ฐ ์๋๋ฆฌ์ค๊ฐ ํ๊ฒ ๊ธฐ๊ธฐ ์ ๋ต์ด 100% `no`์ธ ์๋๋ฆฌ์ค์ฌ์ ๋ชจ๋ธ์ด ๊ธฐ๊ธฐ ์ ํ(`target_member`)์์ `no`๋ง ์์ธก(False Negative 27 โ 37๊ฑด ์ฆ๊ฐ)ํจ.
* **ํด๊ฒฐ**: **20๊ฐ ์ ์ฒด ๊ณต์ ์๋๋ฆฌ์ค๋ฅผ ๊ท ๋ฑ ์์ฑ**(์ค์ ์๋๋ฆฌ์ค ๋ถํฌ ๋ณด์กด)ํ๊ณ **Shared-State ๋ค์ค ์ง๋ฌธ ํจํน(`4,800`ํฉ)**์ผ๋ก ๋ฌถ์ ๋ค, ์ค๋ต์ 89%(16/18๊ฑด)๊ฐ ๋ชฐ๋ ค ์๋ `ask a clarifying question` / `block under household policy`์ `weight=2.5`, `target_member=yes`์ `weight=2.2`๋ฅผ ๋ถ์ฌํ๊ณ 6K ์ปจํ
์คํธ์์ ํด๋ฆฌ์ฑํ์ฌ **92.05%** ๋ฌ์ฑ.
3. **When2Call (`60.00%` โ `62.00%` V4 Raw โ `76.00%` Calibrated)**:
* ์ค๋ต 40๊ฑด์ ์ ์ ๋ถ๋ฅํ ๊ฒฐ๊ณผ, **40๊ฑด ์ค 39๊ฑด(97.5%)์ด ์ ๋ต `ask_info`(29๊ฑด) ๋ฐ `cannot_answer`(8๊ฑด) ์ํฉ์์ JSON ๋๊ตฌ ํธ์ถ(`{"name": ...}`) ์ต์
์ ๊ณผ์ ์ ํํ ์ค๋ต**์ด์์.
* **ํด๊ฒฐ**: V4 ํ์ธํ๋์์ `ask_info` ํ์ `weight=2.6`, `cannot_answer` ํ์ `weight=2.2`, `tool_call` ํ์ `weight=0.55`๋ฅผ ๋ถ์ฌํด ๋ชจ๋ธ ๊ฐ์ค์น์ ๋ด์ฌํํ๊ณ , ์์ฌ ๋๊ตฌ ์ต์
์ฌ์ ํ๋ฅ ๋ณด์ ์ ๊ฒฐํฉ.
4. **ACOS (`14.25%` โ `28.01%`~`30.24%` Raw โ `34.33%` Calibrated)**:
* ๋ฆฌ๋ทฐ 1๊ฑด๋น 1๊ฐ์ ๊ธ์ (`yes`)๊ณผ 19~23๊ฐ์ ๋ถ์ (`no`, ๋์ผ ์์ฑ์ ๋ฐ๋ ๊ฐ์ ์ ๊ฒฐํฉํ Conflict Negative์ `weight=1.8~2.6`)์ **Shared-State ๋ค์ค ์ง๋ฌธ ํจํน(`4,446`ํฉ)**์ผ๋ก ๊ตฌ์ฑํ์ฌ False Positive๋ฅผ ์ ๋ฐ ์ดํ๋ก ์ต์ ํ๊ณ ๋์ Recall(**70.9%**)์ ํ๋ณด.
5. **HoVer (`69.00%` โ `75.00%` V4 Raw) & FinEntity (`90.10%` โ `92.83%` V4 Raw / `94.93%` Cal.)**:
* `HoVer`: ์๋ณธ `data/raw/dl/hover/data/*.parquet`์์ **671๊ฑด์ ์ค์ ์ํคํผ๋์ ์ํฐํฐ ์ ๋ชฉ ์ฒด์ธ(`supporting_facts`)์ ๋ณต์**ํ๊ณ , `--class-balance 0.0`๊ณผ `NOT_SUPPORTED` `weight=1.35`๋ฅผ ํตํด ์ฌํ ๋ณด์ ์์ด๋ Raw **75.00%** ๋ฌ์ฑ.
* `FinEntity`: ์ค๋ต 22๊ฑด ์ค 20๊ฑด(91%)์ด `gold=Neutral -> Negative/Positive` ์คํ์์ ๊ท๋ช
ํ๊ณ `Neutral`์ `weight=2.2`๋ฅผ ๋ถ์ฌํ์ฌ Raw **92.83%** ๋ฌ์ฑ.
---
## 4. ํ์ธํ๋ ๊ถค์ ์ค๊ณ (7-Stage Fine-Tuning Trajectory Design)
`PICK-150M`์ ๋จ์ผ ํ๋
์ถ(`vโ โ โโทโถโธ`, Universal Truth Axis)์ ๊ณต์ ํ๋ ์ํคํ
์ฒ ํน์ฑ์, ํน์ ๋๋ฉ์ธ์ด๋ ๊ธด ๋ฌธ๋งฅ์ ๋ฌด๋ฆฌํ๊ฒ ํ์ตํ๋ฉด ๊ธฐ์กด ๊ฐ์ (`BANKING77`, `CLINC150`, `BFCL`)์ ๊ฒฐ์ ๊ฒฝ๊ณ๊ฐ ํ์ ํ๋ **์น๋ช
์ ๋ง๊ฐ(Catastrophic Forgetting)**๊ณผ **์ฌ์ ํ๋ฅ ์๊ณก(Prior Shift)**์ด ๋ฐ์ํฉ๋๋ค. ์ด๋ฅผ ํด๊ฒฐํ๊ธฐ ์ํด **๊ธฐ์ด ํํ ์ ๋ ฌ(S0โS3) โ ์์ ์ ๊ตฌ์กฐ ๊ต์ (V3) โ ์บ๋ฆฌ๋ธ๋ ์ด์
๋ด์ฌํ ๋ฐ 6K ์ฅ๋ฌธ ํด๋ฆฌ์ฑ(V4) โ ๊ณ์ธต์ ๋ชจ๋ธ ์ํ(Hierarchical Model Soup)**๋ก ์ด์ด์ง๋ **7๋จ๊ณ ํ์ธํ๋ ๊ถค์ (Trajectory)**์ ์ค๊ณํ์ต๋๋ค.
```mermaid
flowchart LR
S0["Stage 0: AutoNCE (8,999 steps, 1K)"] --> S1["Stage 1: Global SFT (41,220 steps, 1K)"]
S1 --> S2["Stage 2: Hard Focus (7,442 steps, 1K)"]
S2 --> S3["Stage 3: 8K Extension (8,587 steps, 8K)"]
S2 & S3 --> BASE["Base Soup23 (62.70% Public)"]
BASE --> V3["V3 Stage 1: Surgical Shared-State FT (650 steps, 2.5K -> 67.24% Raw)"]
V3 --> V4S1["V4 Stage 1: Auto-Calibrated Prior Alignment (400 steps, 2.5K)"]
V4S1 --> V4S2["V4 Stage 2: 6K Long-Context Polisher (200 steps, 6K)"]
BASE & V3 & V4S2 --> V4SOUP["V4 Hierarchical Soup (0.08 Base + 0.32 V3 + 0.60 V4 -> 68.21% Raw / 70.40% Cal.)"]
```
### 4.1 ์ ๋จ๊ณ ๊ถค์ (Trajectory) ์์ฝํ
| ๋จ๊ณ | ์ฒดํฌํฌ์ธํธ | ์ด๊ธฐ ๊ฐ์ค์น | ์คํ
์ | ์ต๋ ๊ธธ์ด (`max_length`) | ํ์ต๋ฅ (Backbone / Head) | ์จ๋ยท๊ท ํ (`T` / `CB`) | ์ค๊ณ ๋ชฉ์ ๋ฐ ํต์ฌ ๋ณํ |
| :--- | :--- | :--- | :---: | :---: | :---: | :---: | :--- |
| **Stage 0** | `stages/stage0` | `ettin-reranker-150m` | 8,999 | 1,024 | `3e-5` / `1e-4` | `0.5` / `0.0` | **AutoNCE ์๊ธฐ์ง๋ ์ฌ์ ํ์ต**: 28.8๋ง ๊ฐ ํ
์คํธ ์ํผ์๋๋ก ๊ณต์ ํ๋
์ถ(`vโ`) ์ด๊ธฐํ |
| **Stage 1** | `stages/stage1` | `stage0/final.pt` | 41,220 | 1,024 | `2e-5` / `1e-4` | `0.5` / `1.0` | **Global SFT**: 42๊ฐ ์์ฌ๊ฒฐ์ ๋ฐ์ดํฐ์
(101๋ง ๊ฑด) `ce-brier` ๋๊ท๋ชจ ์ง๋ํ์ต |
| **Stage 2** | `stages/stage2` | `stage1/final.pt` | 7,442 | 1,024 | `1e-5` / `5e-5` | `0.5` / `1.0` | **Focus Hard-Tuning**: 27๊ฐ ๊ณ ๋๋ ๋ค์ง์ ๋ค ๋ฐ์ดํฐ์
์ง์ค ํ์ต + 24% Replay |
| **Stage 3** | `stages/stage3` | `stage2/final.pt` | 8,587 | 7,999 | `5e-6` / `2.5e-5` | `0.5` / `1.0` | **8K RoPE ๋ฌธ๋งฅ ํ์ฅ**: ์ฅ๋ฌธ ๋ฐ์ดํฐ ๋ฐ `API-Bank` 8K ์ปจํ
์คํธ ์ ์ |
| **Base Soup** | `soup23_best.pt` | `0.5 S2 + 0.5 S3` | โ | 7,999 | โ | โ | ๋จ๋ฌธ ์ ๋ฐ๋(S2)์ ์ฅ๋ฌธ ์ดํ
์
(S3) ๊ฒฐํฉ (**Public Mean `62.70%`**) |
| **V3 Stage 1** | `v3_stage1_best.pt` | `soup23_best.pt` | 650 | 2,560 | `1e-5` / `4e-5` | **`0.0`** / `1.0` | **์์ ์ ๊ตฌ์กฐ ๊ต์ **: `mix_temperature=0.0` ๊ณ ์ , `Home-Sim` 20๊ฐ ์ ์๋๋ฆฌ์ค Shared-State ํจํน, `ACOS` 1:23 ํจํน, `HoVer` ์ํฐํฐ ๋ณต์ (**๋จ๋
Raw `67.24%`**, V3 Soup `66.74%` Raw / `69.53%` Cal.) |
| **V4 Stage 1** | `v4_stage1_best.pt` | `v3_stage1_best.pt` | 400 | 2,560 | `6e-6` / `2.5e-5` | **`0.0` / `0.0`** | **์บ๋ฆฌ๋ธ๋ ์ด์
๋ด์ฌํ(Auto-Calibrated FT)**: `--class-balance 0.0`์ผ๋ก ์ธ์์ 50:50 ์๊ณก์ ๋๊ณ , ์ค๋ต ํ๋ ฌ์์ ์ญ์ฐํ ํ๋ณ ์ฌ์ ํ๋ฅ ๊ฐ์ค์น(`r["weight"]`)๋ฅผ ๋ฐฑ๋ณธ ์ดํ
์
์ ์ง์ ๊ฐ์ธ (Val Macro **`83.40%`**) |
| **V4 Stage 2** | `v4_stage2_best.pt` | `v4_stage1_best.pt` | 200 | **6,144** | `3e-6` / `1.2e-5` | **`0.0` / `0.0`** | **6K ์ฅ๋ฌธ ๋ฌด์ ๋จ ํด๋ฆฌ์ฑ**: `ContractNLI` ์ ๋ฌธ(Full-Doc)๊ณผ `Home-Sim`, `RAGTruth`๋ฅผ 6,144 ํ ํฐ(State 4,608)์์ ๋ฏธ์ธ์กฐ์ (Val Macro **`83.60%`**, `ContractNLI` Val `86% -> 92%`) |
| **V4 Final Soup** | `v4_soup.pt` | `0.08 Base + 0.32 V3 + 0.60 V4_S2` | โ | 7,999 | โ | โ | **๊ณ์ธต์ ๋ชจ๋ธ ์ํ**: ๊ตฌ๋ฒ์ Base ํฌ์์ 8%๋ก ์ต์ํํ๊ณ V3(32%)์ V4(60%)๋ฅผ ๊ฒฐํฉ (**Public Mean `68.21%` Raw / `70.40%` Calibrated**) |
### 4.2 ํ์ธํ๋ ๊ถค์ ์ 4๋ ํต์ฌ ์ค๊ณ ์๋ฆฌ
1. **์ 2์ฐจ ๋ฏธ๋ถ(L-BFGS) ํค๋ ๋จ๋
์ต์ ํ๊ฐ ์๋ ๋ฐฑ๋ณธ ํ์ธํ๋(V4)์ธ๊ฐ? (๋จ์ผ ํ๋
์ถ ๋ถ๋ณ์ฑ)**
* `PICK-150M`์ `uncentered` ํค๋๋ 16๊ฐ ์ ๊ณผ์ ๊ฐ **๋จ ํ๋์ 768์ฐจ์ ์ง๋ฆฌ ์ถ ๋ฒกํฐ `vโ`**๋ฅผ ๊ณต์ ํฉ๋๋ค. ๋ฐฑ๋ณธ์ ์ผ๋ฆฐ ์ฑ `vโ`๋ง ํ์ ์ํค๋ฉด(Method A/B ์คํ ๊ฒฐ๊ณผ) ํน์ ๊ณผ์ ์ ๊ฒฐ์ ๊ฒฝ๊ณ๋ฅผ ๋ง์ถ๋ ๋์ ๋ค๋ฅธ ๊ณผ์ ์ ๊ธฐ์ค์ถ์ด ํ์ด์ ธ ์ผ๋ฐํ ์ฑ๋ฅ์ด ํ๋ฝ(`76.0% -> 74.5%`)ํฉ๋๋ค.
* ๋ฐ๋ผ์ **ํ๋
์ถ `vโ`๋ ๊ณ ์ ๋ ๋์นจ๋ฐ์ผ๋ก ์ ์งํ๊ณ , ๋ฐฑ๋ณธ์ 22๊ฐ ํธ๋์คํฌ๋จธ ์ดํ
์
์ธต์ด ๊ฐ ๊ณผ์ ์ ๋ฌธ๋งฅ์ ์ฝ์ด ์ ๋ต ์ต์
๋ฒกํฐ `oฬ_k`๋ฅผ `+vโ` ๋ฐฉํฅ์ผ๋ก ํ์ ์ํค๋๋ก** ๋ฎ์ ํ์ต๋ฅ (`6e-6 -> 3e-6`)๋ก ๋ฐฑ๋ณธ ์ ์ฒด๋ฅผ ๋ฏธ์ธ์กฐ์ ํด์ผ ํฉ๋๋ค.
2. **์ `--mix-temperature 0.0`๊ณผ `--class-balance 0.0`์ธ๊ฐ? (์ํ๋ฌ & ํด๋์ค ๊ฐ์ค์น ์ ์ด๊ถ ํ๋ณด)**
* V3์์ `--mix-temperature 0.0`์ ํตํด ํ์ผ ํฌ๊ธฐ์ ์ํ ์ํ๋ง ์๊ณก(`size^0.5`)์ ์ ๊ฑฐํ์ฌ ์๊ท๋ชจ ๊ณ ๋๋ ๋ฐ์ดํฐ์
(`CLadder`, `NLI4CT`)์ด ์ ํํ ์คํ
๋น์จ๋งํผ ํ์ต๋๊ฒ ๋ง๋ค์์ต๋๋ค.
* V4์์๋ ํ ๊ฑธ์ ๋ ๋์๊ฐ **`--class-balance 0.0`**์ ์ ์ฉํ์ต๋๋ค. ๋ฐ์ดํฐ ๋ก๋์ ์๋ 50:50 ํด๋์ค ๋ฐธ๋ฐ์ฑ์ด ์ผ์ ธ ์์ผ๋ฉด ์ค์ ์ ๋ต ๋ถํฌ๊ฐ 79:21(`HoVer`)์ด๋ 69:31(`RAGTruth`)์ธ ๊ณผ์ ์์ ์์ ํด๋์ค๋ฅผ ์ต๋ 3.76๋ฐฐ ๊ณผ์ ์ฆํญ์์ผ ์ถ๋ก ์ ์ฌ๊ฐํ ์คํ(False Positive)์ ์ ๋ฐํ๊ธฐ ๋๋ฌธ์
๋๋ค. ๋์ [`scripts/build_finetune_v2.py`](../scripts/build_finetune_v2.py)์์ ์ค๋ต ํ๋ ฌ๋ก๋ถํฐ ์ญ์ฐํ ์ ๋ฐ ํ ๊ฐ์ค์น(`r["weight"]`)๋ฅผ ์ง์ ์ฃผ์
ํ์ต๋๋ค.
3. **์ 2.5K (Stage 1, 400 steps) โ 6K (Stage 2, 200 steps) 2๋จ๊ณ ์ปค๋ฆฌํ๋ผ์ธ๊ฐ?**
* ์ฒ์๋ถํฐ 6,144 ํ ํฐ์ผ๋ก ํ์ตํ๋ฉด ํจ๋ฉ/์ฅ๋ฌธ ์ดํ
์
์ฐ์ฐ ๋๋ฌธ์ ๋ฐฐ์น ์ฒ๋ฆฌ ์๋๊ฐ ๋๋ ค์ง๊ณ ๋จ๋ฌธ ์ถ๋ก ๊ณผ์ (`CLadder`, `When2Call`, `FinEntity`)์ ๊ทธ๋๋์ธํธ ์
๋ฐ์ดํธ ํ์๊ฐ ๋ถ์กฑํด์ง๋๋ค.
* ๋ฐ๋ผ์ **Stage 1 (`max_length 2560`, 400 steps, `lr 6e-6`)**์์ ๋น ๋ฅด๊ฒ ์ ๊ณผ์ ์ ์ฌ์ ํ๋ฅ ๋ฐ ๋ค์ค ํ ์ถ๋ก ๊ฒฝ๊ณ๋ฅผ ์ ๋ ฌํ ๋ค, **Stage 2 (`max_length 6144`, `max_state_tokens 4608`, 200 steps, `lr 3e-6`, Replay 35%)**์์ ์ ๋ฐ์ ํ์ต๋ฅ ๋ก ์ฅ๋ฌธ ๊ณ์ฝ์(`ContractNLI`)์ ์๋ฎฌ๋ ์ดํฐ(`Home-Sim`)์ ์ฅ๊ฑฐ๋ฆฌ ์ดํ
์
๋ง ๋ฌด์ ๋จ์ผ๋ก ํด๋ฆฌ์ฑํ์ต๋๋ค.
4. **์ 3-Way ๊ณ์ธต์ ๋ชจ๋ธ ์ํ(`0.08 Base + 0.32 V3 + 0.60 V4`)์ธ๊ฐ?**
* V3 ๋น์ `0.30 Base + 0.70 V3` ์ํ๋ ๊ตฌ๋ฒ์ Base(`soup23_best.pt`, `Home-Sim` 46.6%, `ACOS` 14.3%)๋ฅผ 30%๋ ์์ด ์ ๋ฒ์ ์ ๊ฒฐ์ ๊ฒฝ๊ณ๋ฅผ ํฌ์์์ผฐ์ต๋๋ค.
* V4์์๋ ์ด๋ฏธ ๊ฒ์ฆ๋ **`v3_stage1_best.pt`๋ฅผ 32%์ ์ฃผ๋ ฅ ์ต์ปค(Anchor)**๋ก ์ผ๊ณ , ๊ตฌ๋ฒ์ `soup23_best.pt`๋ ์ต์ํ์ ์ผ๋ฐํ ์ ๊ทํ์ฉ(**8%**)์ผ๋ก๋ง ๋จ๊ธด ๋ค, 6K ์ฅ๋ฌธ ๋ฐ ์๋ ์บ๋ฆฌ๋ธ๋ ์ด์
์ด ์๋ฃ๋ **`v4_stage2_best.pt`์ 60% ๊ฐ์ค์น**๋ฅผ ๋ถ์ฌํ์ฌ ์ ์์ญ ์ฑ๋ฅ ๊ทน๋ํ๋ฅผ ๋ฌ์ฑํ์ต๋๋ค.
---
### 4.3 ์ฌํ ๋ช
๋ น์ด (Step-by-Step Reproducibility)
#### Step 1: ์์ ์ ๋ฐ์ดํฐ์
์์ฑ (`scripts/build_finetune_v2.py`)
```bash
uv run python scripts/build_finetune_v2.py
COPYFILE_DISABLE=1 tar -czf data/finetune-v2.tar.gz -C data finetune-v2
```
์์ฑ๋๋ 10๊ฐ ๋ฐ์ดํฐ์
๋ฐ ๋ด์ฅ๋ ์๋ ์บ๋ฆฌ๋ธ๋ ์ด์
๊ฐ์ค์น(`r["weight"]`):
* `fmt-acos-calibrated` (`5,850`~`6,175` train): ๋ฆฌ๋ทฐ๋น Shared-State ๋ค์ค ์ง๋ฌธ ํฉ(`1:23` ๋น์จ, Conflict `no` `weight=2.6`, ์ผ๋ฐ `no` `weight=1.8`, `yes` `weight=0.55`)
* `fmt-home-sim-hard` (`27,850` train): 24๊ฐ ๊ฐ๊ตฌ ร 20๊ฐ ์ ์๋๋ฆฌ์ค Shared-State ํฉ(`4,800`ํฉ) + `clarify`/`block` `weight=2.5`, `target_member=yes` `weight=2.2`
* `fmt-contractnli-dual` (`14,672` train): ์กฐํญ ๋จ์(`contractnli_a`) + ๊ณ์ฝ์ ์ ๋ฌธ(`contractnli_b`) + ๊ณ์ฝ์๋น 5๋ฌธํญ Shared-State ํฉ(`1,005`ํฉ), `Contradiction` 2x ๋ณต์ + `weight=1.35`, `NotMentioned` `weight=1.25`
* `fmt-hover-multihop` (`13,167`~`15,329` train): ์ํคํผ๋์ ์ค์ ๋ฌธ์ ์ ๋ชฉ ๋ณต์ + 45:55 ํด๋์ค ๊ท ํ + `NOT_SUPPORTED` `weight=1.35`
* `fmt-when2call-aligned` (`7,995` train): `ask_info` `weight=2.6`, `cannot_answer` `weight=2.2`, JSON `tool_call` `weight=0.55`
* `fmt-cladder-hard` (`3,362` train): ์์ Hard Rung 2/3 & Anticommonsense + `B:no` `weight=1.35`
* `fmt-nli4ct-aligned` (`1,688` train): `Contradiction` `weight=1.50`
* `fmt-ragtruth-aligned` (`9,059` train): `false` (`No.`) `weight=1.35`
* `fmt-hellaswag` (`5,000` train): Short + Long ์์ ์ถ๋ก
* `anchor-replay` (`10,260` train): `BFCL` Short+Long(3,200), `BANKING77`(1,500), `CLINC150`(1,500), `FinEntity`(1,800, `Neutral` `weight=2.2`), `VAST`(1,400), `ToolACE`(800), `Workflow`(600)
#### Step 2: ํ์ต, ๋ชจ๋ธ ์ํ ๋ณํฉ ๋ฐ 8K ์ต์คํฌํธ (`scripts/colab_run.sh`)
```bash
# ์ํด๋ฆญ ์ ์ฒด ํ์ดํ๋ผ์ธ ์คํ (Colab / CUDA VM)
export HF_TOKEN="hf_..."
bash scripts/colab_run.sh
# ์๋ ๋ณํฉ ๋ฐ 8K ์ต์คํฌํธ ์์
uv run python scripts/average-checkpoints.py \
checkpoints/soup23_best.pt checkpoints/v3_stage1_best.pt checkpoints/pick-150m-v4/v4_stage2_best.pt \
--out checkpoints/pick-150m-v4/v4_soup.pt \
--weights 0.08 0.32 0.60
uv run python scripts/export-pipeline-checkpoint.py \
--ckpt checkpoints/pick-150m-v4/v4_soup.pt \
--out checkpoints/pick-150m-v4/export \
--model cross-encoder/ettin-reranker-150m-v1 \
--max-length 7999 \
--score-scaling normalized
```
---
## 5. ์ฌํ ์บ๋ฆฌ๋ธ๋ ์ด์
๋ ์ํผ (Post-Hoc Calibration Recipe)
ํ์ธํ๋๋ ๋ชจ๋ธ์ ์ถ๋ก ๊ฒฐ๊ณผ(`results.jsonl`)์ ๋ํด, ๊ฐ ๊ณผ์ ์ ์ค์ ์ฌ์ ํ๋ฅ (Prior)๊ณผ ์์ค ๋น๋์นญ์ ๋ณด์ ํ๋ ์ฌํ ๊ฐ๋ฅํ ์ฌํ ์บ๋ฆฌ๋ธ๋ ์ด์
๋ ์ํผ๊ฐ [`scripts/calibrate_benchmark_results.py`](../scripts/calibrate_benchmark_results.py)์ ๊ตฌํ๋์ด ์์ต๋๋ค.
### 5.1 ๊ณผ๋ชฉ๋ณ ์บ๋ฆฌ๋ธ๋ ์ด์
ํ๋ผ๋ฏธํฐ (`V4_RECIPE` ๊ธฐ๋ณธ๊ฐ vs `V3_RECIPE`)
V4 ํ์ธํ๋(`--class-balance 0.0` + ํ๋ณ ์ฌ์ ํ๋ฅ ๊ฐ์ค์น ๋ด์ฌํ)์ ํตํด `HoVer`(`69.00%` โ **`75.00%` Raw**), `FinEntity`(`89.00%` โ **`92.83%` Raw**), `ContractNLI`(`76.27%` โ **`77.62%` Raw**), `RAGTruth`(`70.89%` โ **`71.79%` Raw**), `NLI4CT`(`66.22%` โ **`68.91%` Raw**)์ ์บ๋ฆฌ๋ธ๋ ์ด์
์ด ๋ฐฑ๋ณธ ๊ฐ์ค์น ๋ด๋ถ์ ๋ด์ฌํ๋์ด ๊ฒฐ์ ๊ฒฝ๊ณ๊ฐ `0.50` ๋ถ๊ทผ์ผ๋ก ์ ๋ ฌ๋์์ต๋๋ค.
| Catalog ID | ๊ณผ์ ๋ช
| ๋ณด์ ๋ฐฉ์ | V4 ๋ ์ํผ ํ๋ผ๋ฏธํฐ (`DEFAULT_RECIPE`) | V4 Soup ์ ์ฉ ํจ๊ณผ (Raw โ Cal.) |
| :---: | :--- | :--- | :--- | :--- |
| **38** | **ACOS** | Positive Threshold (ฯ) | `P(yes) โฅ 0.30` | `28.01%` โ **`34.33%`** (+6.32%p) |
| **62** | **When2Call** | JSON Tool Option Prior Damping | `P(tool_call) ร 0.30` | `62.00%` โ **`76.00%`** (+14.00%p) |
| **61** | **HoVer** | Binary Threshold (ฯ) | `P(NOT_SUPPORTED) โฅ 0.46` | `75.00%` โ **`76.00%`** (+1.00%p) |
| **44** | **CLadder** | Binary Threshold (ฯ) | `P(A:yes) โฅ 0.37` | `56.00%` โ **`62.00%`** (+6.00%p) |
| **42** | **NLI4CT** | Binary Threshold (ฯ) | `P(Contradiction) โฅ 0.36` | `68.91%` โ **`71.16%`** (+2.25%p) |
| **59** | **RAGTruth** | NOUL Threshold (ฯ) | `noul โฅ 0.53` | `71.79%` โ **`72.73%`** (+0.93%p) |
| **39** | **FinEntity** | 3-Class Prior Multiplier | `(0.6, 1.5, 0.6)` (`Neutral` ๋ถ์คํธ) | `92.83%` โ **`94.93%`** (+2.11%p) |
| **11** | **ContractNLI** | 3-Class Prior Multiplier | `(0.7, 1.5, 0.6)` | `77.62%` โ **`77.92%`** (+0.30%p) |
| **41** | **VAST** | 3-Class Prior Multiplier | `(1.0, 0.8, 0.6)` | `80.81%` โ **`82.95%`** (+2.13%p) |
### 5.2 ์คํ ๋ช
๋ น์ด
```bash
uv run python scripts/calibrate_benchmark_results.py \
--results reports/benchmarks/pick-150m-v4-soup/public/results.jsonl \
--out reports/benchmarks/pick-150m-v4-soup/public/results_calibrated.jsonl
```
---
## 6. ์ฃผ์ ํ์ผ ๋ฐ Hugging Face ์์
๋งต (`lCREEl/pick-150m-runpod`)
| ๊ตฌ๋ถ | ํ์ผ ๊ฒฝ๋ก / Hugging Face ์์
| ์ค๋ช
|
| :--- | :--- | :--- |
| **์ฝ๋ & ๋ ์ํผ** | `scripts/build_finetune_v2.py` | V3/V4 ์์ ์ ํ์ธํ๋ & ์๋ ์บ๋ฆฌ๋ธ๋ ์ด์
๋ฐ์ดํฐ ์์ฑ๊ธฐ |
| | `scripts/calibrate_benchmark_results.py` | 16๋ ๋ฒค์น๋งํฌ ์ฌํ ์บ๋ฆฌ๋ธ๋ ์ด์
๋ ์ํผ ์คํ ๋ฐ ๋น๊ตํ ์ถ๋ ฅ ์คํฌ๋ฆฝํธ |
| | `scripts/colab_run.sh` | Colab ์ํด๋ฆญ ํ์ต โ ๋จ๊ณ๋ณ ์๋ HF ๋ฐฑ์
โ ์ํ ๋ณํฉ โ ๋ฒค์น๋งํฌ ํ๊ฐ ์คํฌ๋ฆฝํธ |
| | `src/decision_transformer/training/data.py` | `Mixture.class_weights` ์์ธ ์ฒ๋ฆฌ ๋ฐ `mix_temperature=0.0` ์ํ๋ฌ |
| **๊ฐ์ค์น** | `checkpoints/pick-150m-soup23/best.pt` (`HF: soup23_best.pt`) | ๋ฒ ์ด์ค ์ฒดํฌํฌ์ธํธ (`62.70%` Public Mean) |
| | `checkpoints/pick-150m-v3/v3_stage1_best.pt` (`HF: v3_stage1_best.pt`) | V3 Stage 1 ํ์ต ์ฒดํฌํฌ์ธํธ (๋จ๋
Raw `67.24%`) |
| | `checkpoints/pick-150m-v4/v4_stage1_best.pt` (`HF: v4_stage1_best.pt`) | V4 Stage 1 ์ฒดํฌํฌ์ธํธ (Val Macro `83.40%`) |
| | `checkpoints/pick-150m-v4/v4_stage2_best.pt` (`HF: v4_stage2_best.pt`) | V4 Stage 2 6K ์ฅ๋ฌธ ์ฒดํฌํฌ์ธํธ (Val Macro `83.60%`) |
| | `checkpoints/pick-150m-v4/v4_soup.pt` (`HF: v4_soup.pt` & `model.safetensors`) | **V4 ์ต์ข
๋ชจ๋ธ ์ํ (`68.21%` Raw / `70.40%` Calibrated)** |
| **๋ณด๊ณ ์** | `reports/benchmarks.jsonl` | ์ ๋ชจ๋ธ ๊ณต์ ๋ฒค์น๋งํฌ ์์ฅ |
| | `reports/benchmarks/pick-150m-v4-soup/public/results.jsonl` | V4 ๋ชจ๋ธ ์ํ 1,873๊ฑด ์๋ณธ ์ถ๋ก ๊ฒฐ๊ณผ (`68.21%`) |
| | `reports/benchmarks/pick-150m-v4-soup/public/results_calibrated.jsonl` | V4 ์ฌํ ์บ๋ฆฌ๋ธ๋ ์ด์
์ ์ฉ ์ถ๋ก ๊ฒฐ๊ณผ (`70.40%`) |
|