Text Classification
Transformers
Safetensors
truetype_system_one
feature-extraction
custom_code
gemma4
typed-decisions
Instructions to use stephenlb/system-one-model with libraries, inference providers, notebooks, and local apps. Follow these links to get started.
- Libraries
- Transformers
How to use stephenlb/system-one-model with Transformers:
# Use a pipeline as a high-level helper from transformers import pipeline pipe = pipeline("text-classification", model="stephenlb/system-one-model", trust_remote_code=True)# Load model directly from transformers import AutoModel model = AutoModel.from_pretrained("stephenlb/system-one-model", trust_remote_code=True, device_map="auto") - Notebooks
- Google Colab
- Kaggle
File size: 6,030 Bytes
347abca | 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 | """Render every question in a request to a base-completion prompt.
Prompt layout
-------------
Every block puts the answer-relevant scaffolding *first* and the text being
judged *last*, so a prompt is::
Choices:
Y. Yes, ...
N. No, ...
Question: <question>
Text: <example text>
Answer: Y
... more examples ...
Choices:
...
Question: <target question>
Text: <the caller's state>
Answer:
Putting the state last makes the engine's prefix KV cache effective:
everything above ``Text:`` depends only on the question, so it is byte-identical
across calls and can be cached once. That took a warm Doom decision from 357ms to
178ms (mean prompt tail 68 -> 20 tokens) with no accuracy change: 63/63 on the
50-case suite plus the Doom probe and 8 held-out noul cases.
Two example strategies, chosen by question type:
- Noul (Y/N) uses a fixed bank of demonstrations with their own questions.
The predicate in the options ("Yes, the text requests a refund.") carries the
task; the examples teach the letter slot. Their questions
differ from the target question, so their Y/N labels stay truthful rather than
being relabelled under a question they were not written for. This lifted
accuracy from 3/6 to 6/6 in tests/example_transfer.py.
- Choice and Score use examples generated from the caller's criteria. Each
option gets one synthetic demonstration mapping it to its letter, visited in a
non-alphabetical order so the model cannot exploit A,B,C positional cues. This
reached 10/10 on Choice and 11/12 on Score in tests/choice_score_bakeoff2.py and
needs no hand-authoring.
"""
from __future__ import annotations
from dataclasses import dataclass
from .questions import DEFAULT_EXAMPLE_COUNT, GENERIC_EXAMPLES, Question
@dataclass
class RenderedPrompt:
question_id: str
text: str
def _render_options(question: Question) -> str:
lines = []
for option in question.options:
if question.type == "noul":
lines.append(f"{option.letter}. {option.description or option.label}")
elif option.description:
lines.append(f"{option.letter}. {option.label} - {option.description}")
else:
lines.append(f"{option.letter}. {option.label}")
return "\n".join(lines)
def _header(question: Question, instructions: str | None = None) -> str:
"""Choices + question. Identical for every call on the same question."""
return (
f"Choices:\n{_render_options(question)}\n"
f"Question: {instructions or question.instructions}\n"
)
def _noul_examples(question: Question, count: int) -> list[str]:
blocks = []
for ex_text, ex_question, ex_letter in GENERIC_EXAMPLES[:count]:
blocks.append(f"{_header(question, ex_question)}Text: {ex_text}\nAnswer: {ex_letter}")
return blocks
def _criteria_roundtrip_examples(question: Question) -> list[str]:
"""One demonstration per option, built from the option's own description.
Options use a non-alphabetical order that
interleaves the scale (low, high, middle, ...) so no positional shortcut exists.
"""
header = _header(question)
blocks = []
for index in _interleaved_order(len(question.options)):
option = question.options[index]
if question.type == "choice":
detail = f" This example is about the topic of {option.label}."
else:
detail = " " + (option.description or option.label)
blocks.append(
f"{header}Text: An example of {option.label}:{detail}\nAnswer: {option.letter}"
)
return blocks
def _interleaved_order(n: int) -> list[int]:
"""Low, high, then remaining indices ascending. Breaks A,B,C positional cues."""
if n <= 2:
return list(range(n))
order = [0, n - 1]
order.extend(i for i in range(1, n - 1))
return order
def render_example_prefix(
question: Question,
*,
example_count: int = DEFAULT_EXAMPLE_COUNT,
) -> str:
"""The part of the prompt that depends only on the question, never on the state.
This is what the engine keeps in a KV cache across calls: the few-shot examples
plus the target question's own Choices/Question header. For a fixed question it
is byte-identical every time, and it is ~90% of the prompt.
"""
if question.type == "noul":
blocks = _noul_examples(question, example_count)
else:
blocks = _criteria_roundtrip_examples(question)
body = "\n\n".join(blocks) + "\n\n" if blocks else ""
return body + _header(question)
def render_target_block(question: Question, state: str) -> str:
"""The state-dependent tail, ending at the ``Answer:`` slot.
There is no trailing space after ``Answer:``. The letter tokens
the engine reads are space-prefixed (``"▁Y"``), which is how the examples above
tokenize (``['Answer', ':', '▁Y']``). Adding a trailing space here would emit a
standalone ``'▁'`` token and strand the space, so the model would want a bare
``"Y"`` while the engine read ``"▁Y"``. This measured 0.0000 probability mass on
the letters being scored, versus 0.9871 without the space.
"""
return f"Text: {state}\nAnswer:"
def render_question(
question: Question,
state: str,
*,
example_count: int = DEFAULT_EXAMPLE_COUNT,
) -> RenderedPrompt:
# Composed from the two halves so the cached-prefix path and the plain path
# always produce the exact same prompt string.
text = render_example_prefix(question, example_count=example_count) + render_target_block(
question, state
)
return RenderedPrompt(question_id=question.id, text=text)
def render_batch(
questions: list[Question],
state: str,
*,
example_count: int = DEFAULT_EXAMPLE_COUNT,
) -> list[RenderedPrompt]:
"""One prompt per question. Every question sees the same state, as in TypeSafe."""
return [
render_question(question, state, example_count=example_count) for question in questions
]
|