Text Generation
Transformers
Safetensors
mistral3
image-text-to-text
decision-model
typed-decisions
jev
jevbench
calibration
decode-free
multilingual
vision-language
conversational
Instructions to use StandardThinking/StandardOne-3B with libraries, inference providers, notebooks, and local apps. Follow these links to get started.
- Libraries
- Transformers
How to use StandardThinking/StandardOne-3B with Transformers:
# Use a pipeline as a high-level helper from transformers import pipeline pipe = pipeline("text-generation", model="StandardThinking/StandardOne-3B") messages = [ { "role": "user", "content": [ {"type": "image", "url": "https://huggingface.co/datasets/huggingface/documentation-images/resolve/main/p-blog/candy.JPG"}, {"type": "text", "text": "What animal is on the candy?"} ] }, ] pipe(text=messages)# Load model directly from transformers import AutoProcessor, AutoModelForMultimodalLM processor = AutoProcessor.from_pretrained("StandardThinking/StandardOne-3B") model = AutoModelForMultimodalLM.from_pretrained("StandardThinking/StandardOne-3B", device_map="auto") messages = [ { "role": "user", "content": [ {"type": "image", "url": "https://huggingface.co/datasets/huggingface/documentation-images/resolve/main/p-blog/candy.JPG"}, {"type": "text", "text": "What animal is on the candy?"} ] }, ] inputs = processor.apply_chat_template( messages, add_generation_prompt=True, tokenize=True, return_dict=True, return_tensors="pt", ).to(model.device) outputs = model.generate(**inputs, max_new_tokens=40) print(processor.decode(outputs[0][inputs["input_ids"].shape[-1]:])) - Notebooks
- Google Colab
- Kaggle
- Local Apps Settings
- vLLM
How to use StandardThinking/StandardOne-3B with vLLM:
Install from pip and serve model
# Install vLLM from pip: pip install vllm # Start the vLLM server: vllm serve "StandardThinking/StandardOne-3B" # Call the server using curl (OpenAI-compatible API): curl -X POST "http://localhost:8000/v1/chat/completions" \ -H "Content-Type: application/json" \ --data '{ "model": "StandardThinking/StandardOne-3B", "messages": [ { "role": "user", "content": "What is the capital of France?" } ] }'Use Docker
docker model run hf.co/StandardThinking/StandardOne-3B
- SGLang
How to use StandardThinking/StandardOne-3B with SGLang:
Install from pip and serve model
# Install SGLang from pip: pip install sglang # Start the SGLang server: python3 -m sglang.launch_server \ --model-path "StandardThinking/StandardOne-3B" \ --host 0.0.0.0 \ --port 30000 # Call the server using curl (OpenAI-compatible API): curl -X POST "http://localhost:30000/v1/chat/completions" \ -H "Content-Type: application/json" \ --data '{ "model": "StandardThinking/StandardOne-3B", "messages": [ { "role": "user", "content": "What is the capital of France?" } ] }'Use Docker images
docker run --gpus all \ --shm-size 32g \ -p 30000:30000 \ -v ~/.cache/huggingface:/root/.cache/huggingface \ --env "HF_TOKEN=<secret>" \ --ipc=host \ lmsysorg/sglang:latest \ python3 -m sglang.launch_server \ --model-path "StandardThinking/StandardOne-3B" \ --host 0.0.0.0 \ --port 30000 # Call the server using curl (OpenAI-compatible API): curl -X POST "http://localhost:30000/v1/chat/completions" \ -H "Content-Type: application/json" \ --data '{ "model": "StandardThinking/StandardOne-3B", "messages": [ { "role": "user", "content": "What is the capital of France?" } ] }' - Docker Model Runner
How to use StandardThinking/StandardOne-3B with Docker Model Runner:
docker model run hf.co/StandardThinking/StandardOne-3B
File size: 15,557 Bytes
09d4173 | 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 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 | """Validated requests and pure scoring helpers for the System One compatible API.
This is next-token classification with an existing language model, not the
proprietary Jev model. Confidence follows the llama.cpp fork's formula,
``1 - entropy / log(number of options)``; it is not a calibration guarantee.
"""
import json
import math
import string
from collections.abc import Sequence
from dataclasses import dataclass
from numbers import Real
from typing import Annotated, Literal
from urllib.parse import urlsplit
from pydantic import (
BaseModel,
ConfigDict,
Field,
JsonValue,
StrictBool,
StrictStr,
field_validator,
model_validator,
)
StructuredText = StrictStr | dict[StrictStr, JsonValue] | list[JsonValue]
Description = StructuredText | None
QuestionType = Literal["choice", "noul", "score"]
PromptWording = Literal["served", "native"]
# The jevbench-hard runner's own contract (run_suites_rotation.py: PREFIX,
# format_prompt, CONTRACT), copied verbatim. Rendering ``build_prompt`` with
# wording="native" reproduces this text exactly; the runner measured this
# wording alone as worth about +6 points on jevbench-hard over the served
# wording below (native 61.3 vs served 55.0 Hard accuracy, same tokenizer
# family). See run_suites_ablate.py for the full effect decomposition.
NATIVE_PROMPT_PREFIX = (
"Read the state and question. Choose the single best option using the "
"supplied information. Respond with exactly one option letter and no "
"other text."
)
NATIVE_PROMPT_CONTRACT = "jev-public-hard-native-letter-v1"
_NATIVE_DISPLAY = string.ascii_uppercase
class _SystemOneModel(BaseModel):
model_config = ConfigDict(extra="forbid")
@model_validator(mode="after")
def validate_finite_json(self):
# JsonValue permits floats; JSON descriptions must not contain NaN/Inf.
try:
json.dumps(self.model_dump(), allow_nan=False)
except (ValueError, TypeError) as exc:
raise ValueError("all structured values must be finite JSON") from exc
return self
class ChoiceQuestion(_SystemOneModel):
type: Literal["choice"]
instructions: StructuredText
criteria: dict[StrictStr, Description] = Field(min_length=2, max_length=255)
@field_validator("criteria")
@classmethod
def validate_names(cls, criteria):
if any(not name.strip() for name in criteria):
raise ValueError("option names must not be empty")
return criteria
class NoulQuestion(_SystemOneModel):
type: Literal["noul"]
instructions: StructuredText
criteria: dict[StrictStr, Description] | None = None
@field_validator("criteria")
@classmethod
def validate_boolean_criteria(cls, criteria):
if criteria is not None and set(criteria) != {"true", "false"}:
raise ValueError('noul criteria must contain exactly "true" and "false"')
return criteria
class ScoreQuestion(_SystemOneModel):
type: Literal["score"]
instructions: StructuredText
criteria: list[Description] = Field(min_length=2, max_length=10)
SystemOneQuestion = Annotated[
ChoiceQuestion | NoulQuestion | ScoreQuestion, Field(discriminator="type")
]
class SystemOneOptions(_SystemOneModel):
temperature: float = Field(default=1.0, gt=0, allow_inf_nan=False, strict=True)
temperature_scaling: StrictBool = True
permutations: int = Field(default=1, ge=1, le=16, strict=True)
return_logprobs: StrictBool = False
assistant_prefix: StrictStr | None = None
class SystemOneRequest(_SystemOneModel):
model: StrictStr = Field(min_length=1)
state: StructuredText
questions: dict[StrictStr, SystemOneQuestion] = Field(min_length=1, max_length=256)
options: SystemOneOptions = Field(default_factory=SystemOneOptions)
images: list[StrictStr] = Field(default_factory=list)
@field_validator("model")
@classmethod
def validate_model(cls, model):
if not model.strip():
raise ValueError("model must not be empty")
return model
@field_validator("questions")
@classmethod
def validate_question_names(cls, questions):
if any(not name.strip() for name in questions):
raise ValueError("question names must not be empty")
return questions
@field_validator("images")
@classmethod
def validate_images(cls, images):
for image in images:
if image.startswith("data:image/"):
if "," not in image or not image.split(",", 1)[1]:
raise ValueError("image data URLs must have a nonempty payload")
else:
parsed = urlsplit(image)
if parsed.scheme not in ("http", "https") or not parsed.netloc:
raise ValueError("images must be image data URLs or HTTP(S) URLs")
return images
@dataclass(frozen=True)
class QuestionPlan:
type: QuestionType
instructions: StructuredText
option_names: tuple[str, ...]
descriptions: tuple[Description, ...]
def plan_question(question: SystemOneQuestion) -> QuestionPlan:
"""Keep caller option order; boolean options always map to true, false."""
if isinstance(question, ChoiceQuestion):
names = tuple(question.criteria)
descriptions = tuple(question.criteria.values())
elif isinstance(question, NoulQuestion):
names = ("true", "false")
criteria = question.criteria or {}
descriptions = tuple(criteria.get(name) for name in names)
elif isinstance(question, ScoreQuestion):
names = tuple(str(index) for index in range(len(question.criteria)))
descriptions = tuple(question.criteria)
else:
raise TypeError("question must be a validated System One question")
return QuestionPlan(question.type, question.instructions, names, descriptions)
def render_json_text(value: StructuredText) -> str:
"""Render structured input deterministically without changing plain text."""
if isinstance(value, str):
return value
return json.dumps(value, ensure_ascii=False, sort_keys=True, allow_nan=False)
def render_native_state_text(value: StructuredText) -> str:
"""Render ``state`` exactly as the jevbench-hard runner's ``format_prompt``
does: plain strings verbatim, everything else as a sorted, indented JSON
dump. Only ``state`` gets this treatment in the native contract -- unlike
the served wording, the runner interpolates ``instructions`` and option
descriptions directly (``str()``), which ``_build_native_prompt`` mirrors."""
if isinstance(value, str):
return value
return json.dumps(
value, sort_keys=True, ensure_ascii=False, indent=2, allow_nan=False
)
def rotation_order(option_count: int, rotation: int) -> tuple[int, ...]:
"""Map each displayed label position to its original option index."""
if option_count < 2 or rotation < 0:
raise ValueError("at least two options and a nonnegative rotation are required")
return tuple(
(position + rotation) % option_count for position in range(option_count)
)
def _validate_order(order: Sequence[int], option_count: int) -> None:
if (
len(order) != option_count
or any(isinstance(index, bool) or not isinstance(index, int) for index in order)
or set(order) != set(range(option_count))
):
raise ValueError("option order must be a permutation of all original indices")
def build_prompt(
state: StructuredText,
plan: QuestionPlan,
labels: Sequence[str],
order: Sequence[int] | None = None,
*,
wording: PromptWording = "served",
) -> str:
"""Build user content; the serving layer applies a non-thinking chat template.
Labels must already have been verified as distinct single-token symbols in
the assistant context by the serving layer. The shared state is first to
make prefix reuse possible across questions and option rotations.
``wording="served"`` (default, unchanged) renders this adapter's own
contract (``Context:/.../Options: A: name: description``).
``wording="native"`` renders the jevbench-hard runner's own contract
instead (run_suites_rotation.py: ``PREFIX``/``State:``/``Question:``/
``Options: A. name: description``), which the runner's own ablation
measured as worth about +6 points on jevbench-hard by wording alone. It
requires canonical, single-token ``A``..``Z`` labels (at most 26 options)
in the given order, because that is the letter-token contract the native
runner assumes; a backend whose tokenizer's first labels are not exactly
those letters cannot serve this wording and ``build_prompt`` raises.
"""
option_count = len(plan.option_names)
if len(labels) != option_count or len(set(labels)) != option_count:
raise ValueError("exactly one distinct label per option is required")
if any(
not isinstance(label, str) or not label or "\n" in label for label in labels
):
raise ValueError("labels must be nonempty single-line strings")
order = tuple(range(option_count)) if order is None else order
_validate_order(order, option_count)
if wording == "native":
return _build_native_prompt(state, plan, labels, order)
if wording != "served":
raise ValueError('wording must be "served" or "native"')
lines = []
for label, index in zip(labels, order):
name = plan.option_names[index]
if plan.type == "noul":
name = "yes" if name == "true" else "no"
description = plan.descriptions[index]
text = (
name if description is None else f"{name}: {render_json_text(description)}"
)
lines.append(f"{label}: {text}")
return (
f"Context:\n{render_json_text(state)}\n\n"
"Answer the question with only the label of the best option "
"(the complete label before the colon), nothing else.\n"
f"Question: {render_json_text(plan.instructions)}\nOptions:\n"
+ "\n".join(lines)
)
def _build_native_prompt(
state: StructuredText,
plan: QuestionPlan,
labels: Sequence[str],
order: Sequence[int],
) -> str:
"""``build_prompt(..., wording="native")``'s body: a byte-for-byte port of
run_suites_rotation.py's ``option_texts`` + ``format_prompt`` for the
normalized KEV question schema this adapter already validates into
(``plan.type``/``plan.option_names``/``plan.descriptions``).
Ported quirks, kept intentionally rather than "fixed", because parity with
the runner's actual output is the point: only ``state`` gets a JSON dump
when non-string (``instructions`` and descriptions are interpolated with
plain ``str()``, exactly like the runner's f-strings), and a *falsy*
description (not just ``None``) is omitted, matching ``if description``
in the runner's ``format_prompt``.
"""
option_count = len(plan.option_names)
if tuple(labels) != tuple(_NATIVE_DISPLAY[:option_count]):
raise ValueError(
"native prompt wording requires canonical single-token A-Z labels "
"in order (at most 26 options); this backend's labels are "
f"{tuple(labels)!r}"
)
lines = []
for position, index in enumerate(order):
name = plan.option_names[index]
if plan.type == "noul":
name = "yes" if name == "true" else "no"
description = plan.descriptions[index]
line = f"{_NATIVE_DISPLAY[position]}. {name}"
if description:
line += f": {description}"
lines.append(line)
return (
f"{NATIVE_PROMPT_PREFIX}\n\n"
f"State:\n{render_native_state_text(state)}\n\n"
f"Question:\n{plan.instructions}\n\nOptions:\n" + "\n".join(lines)
)
def probabilities_from_logprobs(
logprobs: Sequence[float], temperature: float = 1.0
) -> list[float]:
"""Normalize selected vocabulary logprobs, equivalent to label-logit softmax.
Subtract the maximum *before* scaling to stay stable even with tiny positive
temperatures or very negative logprobs. Missing/nonfinite engine values are
errors, rather than fabricated probabilities.
"""
if (
isinstance(temperature, bool)
or not isinstance(temperature, Real)
or not math.isfinite(temperature)
or temperature <= 0
):
raise ValueError("temperature must be finite and greater than zero")
if len(logprobs) < 2:
raise ValueError("at least two label logprobs are required")
if any(
isinstance(value, bool)
or not isinstance(value, Real)
or not math.isfinite(value)
for value in logprobs
):
raise ValueError("every label must have a finite numeric logprob")
maximum = max(logprobs)
weights = [math.exp((value - maximum) / temperature) for value in logprobs]
total = math.fsum(weights)
return [weight / total for weight in weights]
def reduce_probabilities(
plan: QuestionPlan,
logprob_vectors: Sequence[Sequence[float]],
orders: Sequence[Sequence[int]],
options: SystemOneOptions,
) -> dict:
"""Scale, undo rotations, then average probabilities across evaluations.
Returned ``logprobs`` (when requested) is a list of canonical option maps,
one per evaluation. These are unmodified vocabulary-normalized logprobs,
not raw logits and not the final label distribution. Keeping each evaluation
separately permits fitting temperature before permutation averaging.
"""
if not logprob_vectors or len(logprob_vectors) != len(orders):
raise ValueError("each logprob vector must have a matching option order")
option_count = len(plan.option_names)
temperature = options.temperature if options.temperature_scaling else 1.0
columns: list[list[float]] = [[] for _ in range(option_count)]
raw_rows = []
for vector, order in zip(logprob_vectors, orders):
if len(vector) != option_count:
raise ValueError("engine must return one logprob for every label")
_validate_order(order, option_count)
probabilities = probabilities_from_logprobs(vector, temperature)
raw = {}
for position, original in enumerate(order):
columns[original].append(probabilities[position])
raw[plan.option_names[original]] = float(vector[position])
raw_rows.append({name: raw[name] for name in plan.option_names})
averaged = [math.fsum(column) / len(logprob_vectors) for column in columns]
# Account for floating-point summation drift before entropy and expectation.
total = math.fsum(averaged)
averaged = [probability / total for probability in averaged]
answer = {"type": plan.type}
if plan.type == "noul":
answer["noul"] = averaged[0]
else:
answer["probabilities"] = dict(zip(plan.option_names, averaged))
entropy = -math.fsum(p * math.log(p) for p in averaged if p > 0)
answer["confidence"] = min(
1.0, max(0.0, 1.0 - entropy / math.log(option_count))
)
if plan.type == "choice":
answer["choice"] = plan.option_names[
max(range(option_count), key=averaged.__getitem__)
]
else:
answer["score"] = math.fsum(index * p for index, p in enumerate(averaged))
answer["legend"] = dict(zip(plan.option_names, plan.descriptions))
if options.return_logprobs:
answer["logprobs"] = raw_rows
return answer
|