Meanblock commited on
Commit
af4853f
·
verified ·
1 Parent(s): b6c8d55

Add JEV-CPU: CPU port of SemIf + web UI

Browse files
.gitattributes CHANGED
@@ -39,3 +39,11 @@ assets/semif-no-waitlist.png filter=lfs diff=lfs merge=lfs -text
39
  demo/assets/semif-phase1-replay.gif filter=lfs diff=lfs merge=lfs -text
40
  demo/assets/semif-phase1-replay.webm filter=lfs diff=lfs merge=lfs -text
41
  assets/jev-cpu-demo.gif filter=lfs diff=lfs merge=lfs -text
 
 
 
 
 
 
 
 
 
39
  demo/assets/semif-phase1-replay.gif filter=lfs diff=lfs merge=lfs -text
40
  demo/assets/semif-phase1-replay.webm filter=lfs diff=lfs merge=lfs -text
41
  assets/jev-cpu-demo.gif filter=lfs diff=lfs merge=lfs -text
42
+ assets/domains/code-review.gif filter=lfs diff=lfs merge=lfs -text
43
+ assets/domains/compliance.gif filter=lfs diff=lfs merge=lfs -text
44
+ assets/domains/email-intent.gif filter=lfs diff=lfs merge=lfs -text
45
+ assets/domains/incident.gif filter=lfs diff=lfs merge=lfs -text
46
+ assets/domains/loan-risk.gif filter=lfs diff=lfs merge=lfs -text
47
+ assets/domains/moderation.gif filter=lfs diff=lfs merge=lfs -text
48
+ assets/domains/prioritization.gif filter=lfs diff=lfs merge=lfs -text
49
+ assets/domains/support.gif filter=lfs diff=lfs merge=lfs -text
README.md CHANGED
@@ -1,17 +1,3 @@
1
- ---
2
- license: mit
3
- base_model:
4
- - Qwen/Qwen3-0.6B
5
- tags:
6
- - semantic-if
7
- - decision
8
- - semif
9
- - cpu
10
- - zero-shot-classification
11
- pipeline_tag: zero-shot-classification
12
- library_name: transformers
13
- ---
14
-
15
  # JEV-CPU
16
 
17
  <div align="center">
@@ -22,9 +8,9 @@ library_name: transformers
22
 
23
  [Run it locally](#quick-start) · [How it works](#how-it-works) · [Web UI](#web-ui)
24
 
25
- ![JEV-CPU running live across domains: customer support, content moderation, code review, incident response, email intent, and compliance](assets/jev-cpu-demo.gif)
26
 
27
- *Live PoC — the same CPU engine deciding across six domains: **support** (sentiment + routing), **content moderation**, **code-review triage**, **incident severity**, **email intent**, and a **compliance gate**. Each answer is read from `Qwen3-0.6B`'s option logits in ~1 s, no text generated.*
28
 
29
  </div>
30
 
@@ -171,27 +157,128 @@ POST /api/decide
171
 
172
  ## Verified results (CPU · Qwen3-0.6B · float32)
173
 
174
- These are the exact decisions shown in the demo GIF above — one CPU engine, six domains:
175
 
176
  | Domain | Criterion | Decision | Forward |
177
  |---|---|---|---:|
178
- | Customer support | Sentiment | **negative — 100%** | ~1.1 s |
179
- | Customer support | Route to team | **billing — 100%** | ~1.1 s |
180
- | Content moderation | Policy violation? | **violation — 99.3%** | ~1.1 s |
181
- | Content moderation | Recommended action | **warn — 69.2%** | ~1.0 s |
182
- | Code-review triage | Merge risk | **high — 99.8%** | ~1.2 s |
183
- | Code-review triage | PR disposition | **block — 94.9%** | ~1.1 s |
184
- | Incident / DevOps | Severity | **sev1 — 100%** | ~1.2 s |
185
- | Incident / DevOps | Page on-call now? | **page_now — 100%** | ~1.1 s |
186
- | Email intent | Primary intent | **sales — 100%** | ~1.2 s |
187
- | Compliance gate | Change ticket required? | **required — 100%** | ~1.1 s |
 
 
 
188
 
189
  - Model load ≈ 5–17 s; each decision ≈ **1 s** on CPU (no text is generated).
190
  - Because SemIf reads option logits instead of decoding tokens, CPU latency stays low.
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
191
 
192
- ### ⚠️ Small-model accuracy
193
 
194
- `Qwen/Qwen3-0.6B` is the smallest browser-ladder model; SemIf's own results note it is the least accurate (authored balanced accuracy ≈ 0.44 vs ≈ 0.81 for the 4B). In practice, **terse non-English sentiment labels can be misclassified**, while clear tasks (routing, retrieval) stay correct. For higher accuracy, point `MODEL` in `semif_cpu.py` at a larger checkpoint (e.g. `openbmb/MiniCPM5-2B` or `Qwen/Qwen3.5-4B`). Note the 4B needs `transformers`' native Qwen3.5 support and more RAM, as in upstream SemIf.
195
 
196
  ---
197
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
  # JEV-CPU
2
 
3
  <div align="center">
 
8
 
9
  [Run it locally](#quick-start) · [How it works](#how-it-works) · [Web UI](#web-ui)
10
 
11
+ ![JEV-CPU running live across eight domains, typing each input and reading the decision from logits](assets/jev-cpu-demo.gif)
12
 
13
+ *Live PoC — the state is **typed in**, criteria are added, and the decision is read from `Qwen3-0.6B`'s option logits in ~1 s (no text generated). One CPU engine across **eight domains**: support, content moderation, code-review triage, incident severity, email intent, compliance, loan/credit risk, and support prioritization.*
14
 
15
  </div>
16
 
 
157
 
158
  ## Verified results (CPU · Qwen3-0.6B · float32)
159
 
160
+ These are decisions from the demo GIF above — one CPU engine, eight domains:
161
 
162
  | Domain | Criterion | Decision | Forward |
163
  |---|---|---|---:|
164
+ | Customer support | Sentiment | **negative — 97.4%** ✅ | ~1.1 s |
165
+ | Customer support | Route to team | **billing — 100%** ✅ | ~1.0 s |
166
+ | Content moderation | Policy violation? | **violation — 99.3%** ✅ | ~1.1 s |
167
+ | Content moderation | Recommended action | **warn — 69.2%** ✅ | ~1.0 s |
168
+ | Code-review triage | Merge risk | **high — 99.8%** ✅ | ~1.2 s |
169
+ | Code-review triage | PR disposition | **block — 94.9%** ✅ | ~1.1 s |
170
+ | Incident / DevOps | Severity | **sev1 — 100%** ✅ | ~1.2 s |
171
+ | Incident / DevOps | Page on-call now? | **page_now — 100%** ✅ | ~1.1 s |
172
+ | Email intent | Primary intent | **sales — 100%** ✅ | ~1.2 s |
173
+ | Compliance gate | Change ticket required? | **required — 100%** ✅ | ~1.1 s |
174
+ | Loan / credit risk | Credit risk | **high — 100%** ✅ | ~1.2 s |
175
+ | Loan / credit risk | Recommended decision | **approve — 82.8%** ⚠️ | ~1.1 s |
176
+ | Support prioritization | Priority | **p1 — 100%** ✅ | ~1.2 s |
177
 
178
  - Model load ≈ 5–17 s; each decision ≈ **1 s** on CPU (no text is generated).
179
  - Because SemIf reads option logits instead of decoding tokens, CPU latency stays low.
180
+ - ⚠️ The loan **decision** row is a small-model slip: `Qwen3-0.6B` correctly flags *high risk* but still leans *approve* — an inconsistency that larger models resolve (see **[Scaling up](#scaling-up-the-brain-model)**).
181
+
182
+ ### Per-domain demos (click to expand)
183
+
184
+ Each clip types the state in live, adds the criteria, and reads the decision from logits — on CPU.
185
+
186
+ <details>
187
+ <summary><b>🎧 Customer support</b> — sentiment + team routing</summary>
188
+
189
+ ![Customer support demo](assets/domains/support.gif)
190
+ </details>
191
+
192
+ <details>
193
+ <summary><b>🛡️ Content moderation</b> — policy violation + action</summary>
194
+
195
+ ![Content moderation demo](assets/domains/moderation.gif)
196
+ </details>
197
+
198
+ <details>
199
+ <summary><b>🔀 Code-review triage</b> — merge risk + PR disposition</summary>
200
+
201
+ ![Code-review triage demo](assets/domains/code-review.gif)
202
+ </details>
203
+
204
+ <details>
205
+ <summary><b>🚨 Incident / DevOps</b> — severity + page on-call</summary>
206
+
207
+ ![Incident demo](assets/domains/incident.gif)
208
+ </details>
209
+
210
+ <details>
211
+ <summary><b>📧 Email intent</b> — intent classification</summary>
212
+
213
+ ![Email intent demo](assets/domains/email-intent.gif)
214
+ </details>
215
+
216
+ <details>
217
+ <summary><b>📋 Compliance gate</b> — change-ticket requirement</summary>
218
+
219
+ ![Compliance demo](assets/domains/compliance.gif)
220
+ </details>
221
+
222
+ <details>
223
+ <summary><b>💳 Loan / credit risk</b> — risk + recommended decision</summary>
224
+
225
+ ![Loan risk demo](assets/domains/loan-risk.gif)
226
+ </details>
227
+
228
+ <details>
229
+ <summary><b>⏱️ Support prioritization</b> — ticket priority</summary>
230
+
231
+ ![Support prioritization demo](assets/domains/prioritization.gif)
232
+ </details>
233
+
234
+ ---
235
+
236
+ ## Scaling up the brain model
237
+
238
+ The decisions above run on `Qwen/Qwen3-0.6B` — the **smallest** model on SemIf's ladder, chosen so it fits in CPU RAM. It is the accuracy floor, not the ceiling. From SemIf's own evaluation:
239
+
240
+ | Brain model | Size | Authored balanced accuracy | TypeSafe subset agreement |
241
+ |---|---:|---:|---:|
242
+ | **Qwen3-0.6B** (JEV-CPU default) | 0.6 B | 0.440 | 0.407 |
243
+ | MiniCPM5-2B | 2 B | 0.686 | 0.637 |
244
+ | **Qwen3.5-4B** | 4 B | **0.813** | **0.845** |
245
+
246
+ **Swapping the brain is a one-line change** — set `MODEL` in `semif_cpu.py`; the JEV-CPU engine and web UI are model-agnostic:
247
+
248
+ ```python
249
+ MODEL = "openbmb/MiniCPM5-2B" # or "Qwen/Qwen3.5-4B"
250
+ ```
251
+
252
+ That is exactly what fixes the slip in the loan demo: `Qwen3-0.6B` flags *high risk* correctly but still leans *approve*; a 2B/4B brain keeps the secondary decision consistent. The trade-off is resources — a 4B model needs `transformers`' native Qwen3.5 support and more RAM/compute than this 8 GB CPU box; a GPU (SemIf's target) makes it comfortable.
253
+
254
+ **Takeaway:** JEV-CPU shows the method runs anywhere; **accuracy scales with the model you point it at.**
255
+
256
+ ---
257
+
258
+ ## Input token limits
259
+
260
+ Two different numbers matter — and the smaller one is **not** a limit of the small model:
261
+
262
+ | Limit | Value | What it is |
263
+ |---|---:|---|
264
+ | Model context (`Qwen3-0.6B`) | **40,960 tokens** | The model's architectural window — large even at 0.6 B; context length comes from RoPE, independent of parameter count. |
265
+ | JEV-CPU / SemIf default cap | **4,096 tokens / decision** | A safety guard (`max_tokens`); over-long prompts raise instead of being silently truncated. Configurable. |
266
+ | Stable on this 8 GB CPU box | *(measured below)* | Where CPU **prefill latency**, not the model, becomes the practical ceiling. |
267
+
268
+ **Measured on this 8 GB CPU box** (no GPU), one decision, growing input:
269
+
270
+ | Input tokens | Forward (CPU) | Peak RAM |
271
+ |---:|---:|---:|
272
+ | 254 | 2.5 s | ~3.5 GB |
273
+ | 731 | 5.6 s | ~3.5 GB |
274
+ | 1,363 | 11.9 s | ~3.5 GB |
275
+ | 2,629 | 26.0 s | ~3.5 GB |
276
+ | 5,165 | 66.1 s | ~3.5 GB |
277
+ | 7,697 | 117.4 s | ~3.5 GB |
278
 
279
+ RAM stayed **flat at ~3.5 GB** even at 7,697 tokens — well past the 4,096 default and with no OOM — so on this box the ceiling is **prefill latency (≈ quadratic)**, not memory or the model. Interactive ~1 s decisions want short states (≲ ~300 tokens); long documents still work, just slower. A GPU removes this latency wall entirely.
280
 
281
+ Raising the cap is a parameter, not a rebuild: pass a larger `max_tokens` to `direct_score(...)` (or `--max-tokens` in upstream SemIf's CLI). The model accepts input up to 40,960 tokens; on **CPU** the real constraint is prefill time — latency grows with length, so short states keep decisions near ~1 s.
282
 
283
  ---
284
 
assets/domains/code-review.gif ADDED

Git LFS Details

  • SHA256: 86ab6254ccffb4e1820b5fe160dd5d8af52b6d7888c8dafefac7f3feb8f3508e
  • Pointer size: 131 Bytes
  • Size of remote file: 194 kB
assets/domains/compliance.gif ADDED

Git LFS Details

  • SHA256: 2cf14da78805f3aa591ffe4154f746fba33833007443321ca62fd73b54cb7e65
  • Pointer size: 131 Bytes
  • Size of remote file: 191 kB
assets/domains/email-intent.gif ADDED

Git LFS Details

  • SHA256: 451210ec2d8ab93d026d7320a677aa827cd1d390f2ccf1df408ed109b3c7e110
  • Pointer size: 131 Bytes
  • Size of remote file: 170 kB
assets/domains/incident.gif ADDED

Git LFS Details

  • SHA256: 94f7fa44183d2a4e403a0813a2caa2225cee35b48a8b27c7e3ddd70273cd454a
  • Pointer size: 131 Bytes
  • Size of remote file: 202 kB
assets/domains/loan-risk.gif ADDED

Git LFS Details

  • SHA256: fab49b67d8b3ca841854a77d47c8a694078624a3c66ecd96ac7ebe806a52dde9
  • Pointer size: 131 Bytes
  • Size of remote file: 188 kB
assets/domains/moderation.gif ADDED

Git LFS Details

  • SHA256: 50004f93fca8bde9c9ba9fd86544de5a77386c87c7d34f3695b5e627e8bfeac0
  • Pointer size: 131 Bytes
  • Size of remote file: 183 kB
assets/domains/prioritization.gif ADDED

Git LFS Details

  • SHA256: 59e3c2dbe5f1141b826975c11b98d2e2fffcf2d198062f2437e02147f1ed7b48
  • Pointer size: 131 Bytes
  • Size of remote file: 187 kB
assets/domains/support.gif ADDED

Git LFS Details

  • SHA256: 5894578358656632b0848179b3b3c3e299383f02926593ff52b1d5978229e41e
  • Pointer size: 131 Bytes
  • Size of remote file: 202 kB
assets/jev-cpu-demo.gif CHANGED

Git LFS Details

  • SHA256: 721abfe77b73cfe845e16231edc05ec4c9045ff49ff2b2f061292ad6eca838c9
  • Pointer size: 131 Bytes
  • Size of remote file: 265 kB

Git LFS Details

  • SHA256: 40a34ad3028a4693dc048d8fc80dcb21375678715010b1a4f2e78940f8321757
  • Pointer size: 132 Bytes
  • Size of remote file: 1.04 MB
server.py CHANGED
@@ -184,7 +184,7 @@ button.mini{padding:3px 8px;font-size:12px;font-weight:500}
184
  <div class="grid">
185
 
186
  <section class="panel" id="pData">
187
- <div class="head"><span class="num">1</span> State / Evidence &nbsp;<span style="color:var(--muted);font-weight:400">— data to judge</span></div>
188
  <div class="body">
189
  <textarea id="state" placeholder="Paste the data to judge here.&#10;e.g. a customer review, support ticket, log line, or JSON."></textarea>
190
  </div>
 
184
  <div class="grid">
185
 
186
  <section class="panel" id="pData">
187
+ <div class="head"><span class="num">1</span> State / Evidence &nbsp;<span style="color:var(--muted);font-weight:400">— data to judge · ≤ ~4,096 tok/decision (model ctx 40,960)</span></div>
188
  <div class="body">
189
  <textarea id="state" placeholder="Paste the data to judge here.&#10;e.g. a customer review, support ticket, log line, or JSON."></textarea>
190
  </div>