Add jev.probabilities and an eight-way aspect ratio default Jev script
This commit is contained in:
@@ -92,6 +92,7 @@ Functions (`state` is a string, dict, or list; text only):
|
||||
- `jev.yes(state, question[, threshold])` → `bool` (yes-probability ≥ `threshold`, default `0.5`)
|
||||
- `jev.noul(state, question)` → yes-probability (`0.0`–`1.0`). Compare it with a threshold; using it directly as a condition raises an error.
|
||||
- `jev.choice(state, question, options)` → the most likely option (`str`). `options` is a list of 2–16 labels, or a dict of labels to descriptions.
|
||||
- `jev.probabilities(state, question, options)` → `dict` of each option to its probability (sums to `1.0`). Same `options` as `jev.choice`; asking both with the same arguments runs the model once.
|
||||
- `jev.score(state, question, levels)` → expected level (`float`, `0` to `len(levels) - 1`) for 2–16 ordered level descriptions
|
||||
|
||||
```python
|
||||
@@ -103,8 +104,13 @@ else:
|
||||
|
||||
kind = jev.choice(it1, "Which orientation suits this prompt?", ["portrait", "landscape"])
|
||||
ov2, ov3 = (384, 512) if kind == "portrait" else (512, 384)
|
||||
|
||||
probs = jev.probabilities(it1, "Which orientation suits this prompt?", ["portrait", "landscape"])
|
||||
ot1 = f"{kind} (portrait: {probs['portrait']:.3f}, landscape: {probs['landscape']:.3f})"
|
||||
```
|
||||
|
||||
The node's default script picks one of eight aspect ratios for the prompt in `it1`, outputs its width and height to `out_value_1` / `out_value_2`, and lists every ratio's probability in `out_text_1`.
|
||||
|
||||
Notes:
|
||||
- Each question takes one forward pass (about 1–1.5 s with a 4B–9B model on GPU); the first question also loads the model.
|
||||
- Probabilities are uncalibrated and depend on the model; test thresholds on your own inputs.
|
||||
|
||||
+25
-4
@@ -517,6 +517,10 @@ class _SafeScriptInterpreter:
|
||||
if len(args) != 3:
|
||||
raise ValueError("jev.choice() expects 3 arguments")
|
||||
return self.jev.choice(*args)
|
||||
if name == "probabilities":
|
||||
if len(args) != 3:
|
||||
raise ValueError("jev.probabilities() expects 3 arguments")
|
||||
return self.jev.probabilities(*args)
|
||||
if name == "score":
|
||||
if len(args) != 3:
|
||||
raise ValueError("jev.score() expects 3 arguments")
|
||||
@@ -868,11 +872,28 @@ class MultiOutputScriptJev(MultiOutputScript):
|
||||
"# Jev: jev.yes(state, question[, threshold]) -> bool\n"
|
||||
"# jev.noul(state, question) -> probability\n"
|
||||
"# jev.choice(state, question, options) -> str\n"
|
||||
"# jev.probabilities(state, question, options) -> {option: probability}\n"
|
||||
"# jev.score(state, question, levels) -> float\n"
|
||||
"# Example:\n"
|
||||
"kind = jev.choice(it1, \"What orientation suits this prompt?\", [\"portrait\", \"landscape\"])\n"
|
||||
"ov1, ov2 = (384, 512) if kind == \"portrait\" else (512, 384)\n"
|
||||
"ot1 = kind\n"
|
||||
"# Example: pick an aspect ratio for the prompt in it1\n"
|
||||
"sizes = {\n"
|
||||
" \"1:1 (Square)\": (1024, 1024),\n"
|
||||
" \"2:3 (Portrait Photo)\": (832, 1216),\n"
|
||||
" \"3:2 (Photo)\": (1216, 832),\n"
|
||||
" \"3:4 (Portrait Standard)\": (896, 1152),\n"
|
||||
" \"4:3 (Standard)\": (1152, 896),\n"
|
||||
" \"9:16 (Portrait Widescreen)\": (768, 1344),\n"
|
||||
" \"16:9 (Widescreen)\": (1344, 768),\n"
|
||||
" \"21:9 (Ultrawide)\": (1536, 640),\n"
|
||||
"}\n"
|
||||
"question = \"Which image aspect ratio best suits this prompt?\"\n"
|
||||
"ratios = list(sizes)\n"
|
||||
"best = jev.choice(it1, question, ratios)\n"
|
||||
"probs = jev.probabilities(it1, question, ratios)\n"
|
||||
"ov1, ov2 = sizes[best]\n"
|
||||
"lines = [best]\n"
|
||||
"for ratio in ratios:\n"
|
||||
" lines.append(f\"{ratio}: {probs[ratio]:.3f}\")\n"
|
||||
"ot1 = \"\\n\".join(lines)\n"
|
||||
)
|
||||
types["required"]["model"] = (list(list_local_models()),)
|
||||
types["required"]["max_jev_calls"] = ("INT", {"default": 8, "min": 1, "max": 64})
|
||||
|
||||
+5
-3
@@ -49,12 +49,14 @@ class JevBackend:
|
||||
return self._ask(state, question, ["Yes", "No"])[0]
|
||||
|
||||
def choice(self, state: Any, question: Any, options: list | dict) -> str:
|
||||
probabilities = self.probabilities(state, question, options)
|
||||
return max(probabilities, key=probabilities.get)
|
||||
|
||||
def probabilities(self, state: Any, question: Any, options: list | dict) -> dict[str, float]:
|
||||
if isinstance(options, list):
|
||||
options = {str(option): None for option in options}
|
||||
labels = list(options)
|
||||
descriptions = [label if description is None else f"{label}: {description}" for label, description in options.items()]
|
||||
probabilities = self._ask(state, question, descriptions)
|
||||
return labels[probabilities.index(max(probabilities))]
|
||||
return dict(zip(options, self._ask(state, question, descriptions)))
|
||||
|
||||
def score(self, state: Any, question: Any, levels: list) -> float:
|
||||
probabilities = self._ask(state, question, list(levels))
|
||||
|
||||
Reference in New Issue
Block a user