ericrcwu commited on
Commit
bff7cd9
Β·
verified Β·
1 Parent(s): 4a86089

Add repo card explaining Stage-1 interpreter/router

Browse files
Files changed (1) hide show
  1. README.md +95 -0
README.md ADDED
@@ -0,0 +1,95 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ ---
2
+ base_model: Qwen/Qwen2.5-0.5B-Instruct
3
+ library_name: transformers
4
+ pipeline_tag: text-generation
5
+ license: other
6
+ language:
7
+ - en
8
+ tags:
9
+ - color-grading
10
+ - lut
11
+ - instruction-following
12
+ - routing
13
+ - refusal
14
+ - intent-classification
15
+ - qwen2
16
+ ---
17
+
18
+ # LUT-SLM β€” Stage-1 Interpreter / Router (Qwen2.5-0.5B, full fine-tune)
19
+
20
+ The **Stage-1 interpreter** for the LUT-SLM project: a small **text-only** model (full fine-tune of
21
+ `Qwen/Qwen2.5-0.5B-Instruct`) that reads a user's free-text photo-editing request and decides **how to
22
+ handle it** before any LUT is generated. It emits an `attribute_spec_text` plus a **route**:
23
+
24
+ - **`grade`** β€” a global color LUT can satisfy this β†’ hand off to the Stage-2 generator.
25
+ - **`clarify`** β€” the request is underspecified / out of gamut β†’ ask a clarifying question.
26
+ - **`refuse`** β€” a single global LUT physically cannot do this (`out_of_scope`) or the ask is out of
27
+ gamut (`out_of_gamut`) β†’ refuse instead of fabricating a wrong grade.
28
+
29
+ It is the safety gatekeeper of the two-stage architecture: *never silently grade a request that should
30
+ be refused or clarified.* The Stage-2 generator adapters live in
31
+ **[`ericrcwu/LUT_SLM_sft_adapters`](https://huggingface.co/ericrcwu/LUT_SLM_sft_adapters)**; the
32
+ training corpus + teacher caches are in
33
+ **[`ericrcwu/LUT_SLM_interpreter_cache`](https://huggingface.co/datasets/ericrcwu/LUT_SLM_interpreter_cache)**;
34
+ the source data is **[`ericrcwu/LUT_SLM`](https://huggingface.co/datasets/ericrcwu/LUT_SLM)**.
35
+
36
+ ## Subfolders
37
+
38
+ | Subfolder | What it is |
39
+ |---|---|
40
+ | `interp_full_smokefull/` | **The router.** Full-run interpreter used by the deploy path (`deploy/modal_app.py`, `INTERPRETER_SUBDIR = "interp_full_smokefull"`). |
41
+ | `interp_intensity/` | Intensity-fix experiment variant (re-captioned to surface magnitude buckets). Kept for comparison; **not** the deployed model. |
42
+
43
+ Each folder is a full model (`model.safetensors` β‰ˆ 0.99 GB, `config.json`, tokenizer, chat template) β€”
44
+ these are **full fine-tunes, not adapters**. Architecture: Qwen2, hidden size 896, 24 layers, 14 heads
45
+ (2 KV heads), vocab 151,936, bf16, tied embeddings.
46
+
47
+ ## Results (from `docs/interpreter_results.md`)
48
+
49
+ **βœ… Routing is production-ready** (full run, 2761 LUTs, n=684 holdout):
50
+
51
+ | metric | value |
52
+ |---|---|
53
+ | route accuracy (3-way) | **0.884** (CI 0.858–0.906) |
54
+ | refuse recall / refuse-kind accuracy | **1.0 / 1.0** |
55
+ | clarify recall | **1.0** |
56
+ | grade recall | 0.868 |
57
+ | over-refusal rate | 0.132 |
58
+ | parse-ok rate | 0.886 |
59
+
60
+ **❌ Grade *magnitude* is not learnable from vague text.** The exact-magnitude score plateaued at
61
+ `attribute_f1 β‰ˆ 0.11` and did not improve with 5Γ— data or an intensity-aware caption fix. Diagnosis:
62
+ **task underdetermination** β€” "make it warmer" doesn't encode *how much*, and the same phrasing maps to
63
+ different measured magnitudes across LUTs, so `(text β†’ magnitude)` supervision is contradictory. The
64
+ model reliably learns **direction** (words carry it, dir-F1 β‰ˆ 0.47) but not **magnitude** (words don't).
65
+
66
+ **Decision: ship as a ROUTER only.** For `grade`, forward the **raw user text** to the one-stage
67
+ generator (which learns magnitude end-to-end) rather than the interpreter's magnitude-free spec.
68
+
69
+ ## How to load
70
+
71
+ ```python
72
+ from huggingface_hub import snapshot_download
73
+ from transformers import AutoModelForCausalLM, AutoTokenizer
74
+ d = snapshot_download("ericrcwu/LUT_SLM_interpreter", allow_patterns=["interp_full_smokefull/*"])
75
+ tok = AutoTokenizer.from_pretrained(f"{d}/interp_full_smokefull")
76
+ model = AutoModelForCausalLM.from_pretrained(f"{d}/interp_full_smokefull")
77
+ # Build the prompt with interpreter.example.build_prompt_ids, then parse the generated text with
78
+ # interpreter.comparator.parse -> {route, attribute_spec}. (Helpers live in the source repo.)
79
+ ```
80
+
81
+ ## Intended use & limitations
82
+
83
+ - **Use it as a router / gatekeeper** for grade / clarify / refuse. Optionally use its predicted
84
+ *direction* as a soft hint to the generator (~0.5 reliable).
85
+ - **Do not** rely on it for grade magnitude β€” that path is deliberately handed to the Stage-2
86
+ generator. Reopen the grade path only if the input distribution changes to carry explicit intensity
87
+ (e.g. a guided UI).
88
+
89
+ ## Licensing & provenance
90
+
91
+ `license: other`. The base model carries the Apache-2.0 Qwen2.5-0.5B license; this fine-tune is derived
92
+ from the mixed-provenance LUT-SLM corpus (teacher-LLM captions of real LUTs, some from
93
+ personal-use/non-redistribution sources β€” see the
94
+ [`LUT_SLM`](https://huggingface.co/datasets/ericrcwu/LUT_SLM) card). Research use; verify source terms
95
+ before redistribution or commercial use.