OpenJevX v0.5.0: model folder (config.json temperatures, tokenizer.json), clean-gate card, Python helper reads config.json
Browse files- README.md +27 -50
- TRAINING_COMPLETE +0 -0
- config.json +20 -0
- openjevx.int8.onnx +0 -3
- openjevx.py +6 -4
- tokenizer.json +0 -0
README.md
CHANGED
|
@@ -13,9 +13,10 @@ one container, the model inside, your requests never leave your machine.
|
|
| 13 |
- Server, releases, Docker image, recipes: [github.com/muthuishere/openjevx](https://github.com/muthuishere/openjevx)
|
| 14 |
- CLI: [jevx](https://github.com/muthuishere/jevx)
|
| 15 |
|
| 16 |
-
**
|
| 17 |
-
what else is in the request)
|
| 18 |
-
`tokenizer
|
|
|
|
| 19 |
|
| 20 |
## Run it in a container (recommended)
|
| 21 |
|
|
@@ -58,7 +59,7 @@ path = hf_hub_download("muthuishere/openjevx", "openjevx.py")
|
|
| 58 |
spec = importlib.util.spec_from_file_location("openjevx", path); openjevx = importlib.util.module_from_spec(spec)
|
| 59 |
spec.loader.exec_module(openjevx)
|
| 60 |
|
| 61 |
-
jev = openjevx.OpenJevX() # downloads openjevx.w8.onnx + tokenizer once
|
| 62 |
print(jev.decide({"age": 17}, {
|
| 63 |
"adult": {"type": "noul", "instructions": "Is this person an adult (18 or older)?"},
|
| 64 |
}))
|
|
@@ -68,61 +69,37 @@ print(jev.decide({"age": 17}, {
|
|
| 68 |
`openjevx.py` is a single file (also in the GitHub repo under `python/`); copy it into your project if you
|
| 69 |
prefer. Request and answer shapes match `POST /v1/systemone`.
|
| 70 |
|
| 71 |
-
## Release gate (v0.5.0
|
| 72 |
|
| 73 |
-
|
| 74 |
-
|
| 75 |
|
| 76 |
-
| Gate set | Right and confident | Confidently wrong |
|
| 77 |
|---|---|---|---|
|
| 78 |
-
| Everyday basics (
|
| 79 |
-
|
|
| 80 |
|
| 81 |
-
|
| 82 |
-
|
|
|
|
| 83 |
|
| 84 |
-
|
| 85 |
|
| 86 |
-
|
| 87 |
-
(so each number is within about ±9 points). "Confident" means the model gave its answer at least 80%.
|
| 88 |
-
Jeff-0.8B ([mstrasser/Jeff-Qwen3.5-0.8B](https://huggingface.co/mstrasser/Jeff-Qwen3.5-0.8B)) is the closest
|
| 89 |
-
open model in size and API; it ran on Apple silicon (MLX), OpenJevX on CPU.
|
| 90 |
|
| 91 |
-
|
| 92 |
|
| 93 |
-
|
|
| 94 |
-
|---|---|---|---|---|
|
| 95 |
-
| Everyday rules | 100% | 0% | 86% | 0% |
|
| 96 |
-
| Rules with conditions | 91% | 5% | 82% | 0% |
|
| 97 |
-
| Log triage | **93%** | 7% | 38% | 8% |
|
| 98 |
-
| Real public postmortems | 50% | **18%** | 71% | 8% |
|
| 99 |
-
| All four | **83.5%** | 7.5% | 69.2% | 4.0% |
|
| 100 |
-
|
| 101 |
-
**General benchmarks** (Jeff's public panel: BBH, Financial PhraseBank, JudgeBench, RAGTruth, WinoGrande)
|
| 102 |
-
|
| 103 |
-
| | OpenJevX | Jeff-0.8B |
|
| 104 |
-
|---|---|---|
|
| 105 |
-
| Accuracy | 60.4% | **75.4%** |
|
| 106 |
-
| Confident on | 11% | 65% |
|
| 107 |
-
| Confident and wrong | 1.0% | 9.6% |
|
| 108 |
-
|
| 109 |
-
**Size and speed**
|
| 110 |
-
|
| 111 |
-
| | OpenJevX | Jeff-0.8B |
|
| 112 |
|---|---|---|
|
| 113 |
-
|
|
| 114 |
-
|
|
| 115 |
-
|
|
| 116 |
-
|
| 117 |
-
|
| 118 |
-
|
| 119 |
-
|
| 120 |
-
|
| 121 |
-
|
| 122 |
-
misleads there but rarely helps either. Larger models, and hosted Jev, do much better on reasoning.
|
| 123 |
-
- Known miss: on real incident postmortems it is confidently wrong 18% of the time. Check those answers.
|
| 124 |
-
- The rules set shares facts with the training data (the questions are reworded), so its 100% overstates
|
| 125 |
-
performance on new rules.
|
| 126 |
|
| 127 |
## Using it with jevx
|
| 128 |
|
|
|
|
| 13 |
- Server, releases, Docker image, recipes: [github.com/muthuishere/openjevx](https://github.com/muthuishere/openjevx)
|
| 14 |
- CLI: [jevx](https://github.com/muthuishere/jevx)
|
| 15 |
|
| 16 |
+
**The model is a folder:** `openjevx.w8.onnx` (8-bit weight-only, 598 MB; activations stay float, so answers
|
| 17 |
+
don't depend on what else is in the request) + `config.json` (this model's own calibration temperatures) +
|
| 18 |
+
`tokenizer.json`. The other files are the trainable checkpoint for fine-tuning further: `model.safetensors`,
|
| 19 |
+
`encoder/`, `tokenizer/`, `rl_agent_config.json`. Older versions: git revision `v0.4.0`.
|
| 20 |
|
| 21 |
## Run it in a container (recommended)
|
| 22 |
|
|
|
|
| 59 |
spec = importlib.util.spec_from_file_location("openjevx", path); openjevx = importlib.util.module_from_spec(spec)
|
| 60 |
spec.loader.exec_module(openjevx)
|
| 61 |
|
| 62 |
+
jev = openjevx.OpenJevX() # downloads openjevx.w8.onnx + tokenizer.json + config.json once
|
| 63 |
print(jev.decide({"age": 17}, {
|
| 64 |
"adult": {"type": "noul", "instructions": "Is this person an adult (18 or older)?"},
|
| 65 |
}))
|
|
|
|
| 69 |
`openjevx.py` is a single file (also in the GitHub repo under `python/`); copy it into your project if you
|
| 70 |
prefer. Request and answer shapes match `POST /v1/systemone`.
|
| 71 |
|
| 72 |
+
## Release gate (v0.5.0)
|
| 73 |
|
| 74 |
+
The model folder on the Go server, on CPU. The gate sets share **no state** with training.
|
| 75 |
+
"Right and confident" = right AND past jevx's default thresholds (yes >= 0.8, no <= 0.2, choice/score >= 0.6).
|
| 76 |
|
| 77 |
+
| Gate set | Accuracy | Right and confident | Confidently wrong |
|
| 78 |
|---|---|---|---|
|
| 79 |
+
| Everyday basics (463) | 96.3% | 96.3% | 3.0% |
|
| 80 |
+
| Rule-checking basics (300) | 94.7% | 94.3% | 3.7% |
|
| 81 |
|
| 82 |
+
**Known miss:** confidently wrong is 3.0–3.7% on the basics gates, against our 2% target. It was accepted for this
|
| 83 |
+
release; the fix is planned for v0.5.1. The rest of the gate (held-out test sets, logs gate, 13 fundamentals) is
|
| 84 |
+
still being scored and will be added here.
|
| 85 |
|
| 86 |
+
**Benchmarks:** coming in a follow-up.
|
| 87 |
|
| 88 |
+
## What v0.5.0 was trained on
|
|
|
|
|
|
|
|
|
|
| 89 |
|
| 90 |
+
734,795 decisions (408,505 rows). Labels come from evaluating rules or from real outcomes, never from another model's guesses.
|
| 91 |
|
| 92 |
+
| Area | Decisions | Share |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 93 |
|---|---|---|
|
| 94 |
+
| Rule-checking across 38 business domains (retail pricing, recruiting, real estate, CI/CD, insurance claims, pharmacy stock, HR payroll, gaming, ...) | 200,139 | 27.2% |
|
| 95 |
+
| Software-work roles (developers, testers, tech leads, managers, operations, everyone, agent checks) | 183,543 | 25.0% |
|
| 96 |
+
| tasksource decision corpus | 146,567 | 19.9% |
|
| 97 |
+
| Public sets with real labels (CVE fixes from bigvul, defect detection, code search, ms_marco relevance, HDFS and BGL operator log alerts) | 104,990 | 14.3% |
|
| 98 |
+
| Log triage: application (Java/Python/Node/Go/nginx), database (Postgres/MySQL, real SQLSTATE codes), frontend (browser/Sentry) | 60,001 | 8.2% |
|
| 99 |
+
| Everyday basics (driving licence age, store hours, parcel late, discount thresholds, fever, bag weight, ...) | 30,405 | 4.1% |
|
| 100 |
+
| Public typed-decisions | 9,150 | 1.2% |
|
| 101 |
+
|
| 102 |
+
Run: one RTX 4090 on Vast.ai, 734,145 decisions after packaging, one full pass in 2.4 h at ~88 items/s, about $1.10 in total. Leakage-checked (22,592 test questions removed); every row checked against the trainer before renting.
|
|
|
|
|
|
|
|
|
|
|
|
|
| 103 |
|
| 104 |
## Using it with jevx
|
| 105 |
|
TRAINING_COMPLETE
DELETED
|
File without changes
|
config.json
ADDED
|
@@ -0,0 +1,20 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
{
|
| 2 |
+
"name": "openjevx",
|
| 3 |
+
"version": "0.5.0",
|
| 4 |
+
"temperature": {
|
| 5 |
+
"choice": 1.220432996749878,
|
| 6 |
+
"score": 1.161743402481079,
|
| 7 |
+
"noul": 1.2535336017608643
|
| 8 |
+
},
|
| 9 |
+
"max_len": 1024,
|
| 10 |
+
"head_max": 256,
|
| 11 |
+
"special_ids": {
|
| 12 |
+
"cls": 50281,
|
| 13 |
+
"sep": 50282,
|
| 14 |
+
"pad": 50283,
|
| 15 |
+
"mask": 50284
|
| 16 |
+
},
|
| 17 |
+
"quantization": "8-bit weight-only",
|
| 18 |
+
"base_model": "convaiinnovations/laya",
|
| 19 |
+
"sha256": "109b2b1d3717ff9038da811d84f538262fc9d9bc1f958967d437e837f507e294"
|
| 20 |
+
}
|
openjevx.int8.onnx
DELETED
|
@@ -1,3 +0,0 @@
|
|
| 1 |
-
version https://git-lfs.github.com/spec/v1
|
| 2 |
-
oid sha256:02ec28639b86bc9891f396c2a86909234df080336b59ef13addb0cec8eec4b93
|
| 3 |
-
size 598012474
|
|
|
|
|
|
|
|
|
|
|
|
openjevx.py
CHANGED
|
@@ -23,7 +23,6 @@ from tokenizers import Tokenizer
|
|
| 23 |
REPO = "muthuishere/openjevx"
|
| 24 |
CLS, SEP, MASK = 50281, 50282, 50284
|
| 25 |
MAX_LEN, HEAD_MAX = 1024, 256
|
| 26 |
-
TEMPERATURE = {0: 1.02553391456604, 1: 1.034013271331787, 2: 1.147902488708496} # choice, score, noul
|
| 27 |
|
| 28 |
|
| 29 |
def _criterion(v):
|
|
@@ -48,9 +47,12 @@ def _parse(q):
|
|
| 48 |
|
| 49 |
|
| 50 |
class OpenJevX:
|
| 51 |
-
def __init__(self, model=None, tokenizer=None, providers=None):
|
| 52 |
model = model or hf_hub_download(REPO, "openjevx.w8.onnx")
|
| 53 |
-
tokenizer = tokenizer or hf_hub_download(REPO, "tokenizer
|
|
|
|
|
|
|
|
|
|
| 54 |
self.tok = Tokenizer.from_file(tokenizer)
|
| 55 |
self.session = ort.InferenceSession(model, providers=providers or ["CPUExecutionProvider"])
|
| 56 |
|
|
@@ -93,7 +95,7 @@ class OpenJevX:
|
|
| 93 |
out = {}
|
| 94 |
for r, qid in enumerate(qids):
|
| 95 |
_, markers, qtype, keys = items[r]
|
| 96 |
-
z = [float(x) /
|
| 97 |
m = max(z); p = [math.exp(x - m) for x in z]; s = sum(p); p = [x / s for x in p]
|
| 98 |
best = max(range(len(p)), key=p.__getitem__)
|
| 99 |
ans = {"type": questions[qid]["type"], "probabilities": {k: round(p[j], 4) for j, k in enumerate(keys)},
|
|
|
|
| 23 |
REPO = "muthuishere/openjevx"
|
| 24 |
CLS, SEP, MASK = 50281, 50282, 50284
|
| 25 |
MAX_LEN, HEAD_MAX = 1024, 256
|
|
|
|
| 26 |
|
| 27 |
|
| 28 |
def _criterion(v):
|
|
|
|
| 47 |
|
| 48 |
|
| 49 |
class OpenJevX:
|
| 50 |
+
def __init__(self, model=None, tokenizer=None, config=None, providers=None):
|
| 51 |
model = model or hf_hub_download(REPO, "openjevx.w8.onnx")
|
| 52 |
+
tokenizer = tokenizer or hf_hub_download(REPO, "tokenizer.json")
|
| 53 |
+
config = config or hf_hub_download(REPO, "config.json") # this model's own calibration temperatures
|
| 54 |
+
t = json.load(open(config))["temperature"]
|
| 55 |
+
self.temperature = {0: t["choice"], 1: t["score"], 2: t["noul"]}
|
| 56 |
self.tok = Tokenizer.from_file(tokenizer)
|
| 57 |
self.session = ort.InferenceSession(model, providers=providers or ["CPUExecutionProvider"])
|
| 58 |
|
|
|
|
| 95 |
out = {}
|
| 96 |
for r, qid in enumerate(qids):
|
| 97 |
_, markers, qtype, keys = items[r]
|
| 98 |
+
z = [float(x) / self.temperature[qtype] for x in logits[r, :len(markers)]]
|
| 99 |
m = max(z); p = [math.exp(x - m) for x in z]; s = sum(p); p = [x / s for x in p]
|
| 100 |
best = max(range(len(p)), key=p.__getitem__)
|
| 101 |
ans = {"type": questions[qid]["type"], "probabilities": {k: round(p[j], 4) for j, k in enumerate(keys)},
|
tokenizer.json
ADDED
|
The diff for this file is too large to render.
See raw diff
|
|
|