Text Classification
Transformers
ONNX
Safetensors
English
Portuguese
modernbert
feature-extraction
typestrict
decision-model
typed-decisions
encoder
decision-index
cpu
text-embeddings-inference
Instructions to use typestrict/TS-moBERTo-150M with libraries, inference providers, notebooks, and local apps. Follow these links to get started.
- Libraries
- Transformers
How to use typestrict/TS-moBERTo-150M with Transformers:
# Use a pipeline as a high-level helper from transformers import pipeline pipe = pipeline("text-classification", model="typestrict/TS-moBERTo-150M")# pip install -U transformers accelerate # Load model directly from transformers import AutoTokenizer, AutoModel tokenizer = AutoTokenizer.from_pretrained("typestrict/TS-moBERTo-150M") model = AutoModel.from_pretrained("typestrict/TS-moBERTo-150M", device_map="auto") - Notebooks
- Google Colab
- Kaggle
File size: 6,111 Bytes
9817fc9 | 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 | """Deterministic tools Dinah consults before the encoder. Each one answers only what it can settle exactly.
`code`: "what does this function return" questions are answered by running the function. It fires on content,
the same way for every request (it never looks at a benchmark name, id or task string), when
1. a state field is Python source with a top-level function,
2. another state field is the call's arguments (`[1, 2], 'a'`), screened like the source, and
3. every option of a `choice` question is a Python literal.
The function runs in a child process (`python -I -S`, empty environment, temporary directory, CPU, memory,
file-size and wall-time limits) after an AST screen (imports only from a standard-library allow list; no
open/exec/eval/__import__, no dunder names, no underscore attributes). The tool answers only when exactly one
option equals the result (same type and value); an error, a timeout, or zero or several matching options leave
the question to the encoder. Every option still gets a probability.
"""
from __future__ import annotations
import ast
import json
import re
import subprocess
import sys
import tempfile
MODULES = {"math", "string", "re", "collections", "itertools", "functools", "operator", "copy", "heapq", "bisect",
"datetime", "fractions", "decimal", "statistics", "textwrap", "unicodedata", "numbers", "typing", "dataclasses",
"enum", "array", "calendar"}
FORBIDDEN = {"open", "exec", "eval", "compile", "__import__", "breakpoint", "globals", "locals", "vars", "memoryview",
"setattr", "delattr"}
DUNDER = re.compile(r"__\w+__")
P_MATCH = 0.97 # probability of the matching option; the rest is split evenly
TIMEOUT_S = 3.0
CHILD = r"""
import ast, json, resource, sys
for lim, v in ((resource.RLIMIT_CPU, 2), (resource.RLIMIT_FSIZE, 0), (resource.RLIMIT_AS, 1 << 30)):
try: resource.setrlimit(lim, (v, v))
except (ValueError, OSError): pass
p = json.load(sys.stdin)
g = {"__name__": "__tool__"}
exec(compile(p["source"], "<source>", "exec"), g)
r = eval(compile(p["fn"] + "(" + p["args"] + ")", "<call>", "eval"), g)
def same(a, b):
if type(a) is not type(b): return False
if isinstance(a, (list, tuple)): return len(a) == len(b) and all(same(x, y) for x, y in zip(a, b))
if isinstance(a, dict): return a.keys() == b.keys() and all(same(a[k], b[k]) for k in a)
return a == b
hits = []
for i, o in enumerate(p["options"]):
try:
if same(r, ast.literal_eval(o)): hits.append(i)
except Exception: pass
print(json.dumps({"hits": hits}))
"""
def _safe(tree):
for node in ast.walk(tree):
if isinstance(node, ast.Import) and any(a.name.split(".")[0] not in MODULES for a in node.names):
return None
if isinstance(node, ast.ImportFrom) and (node.module or "").split(".")[0] not in MODULES:
return None
if isinstance(node, ast.Name) and (node.id in FORBIDDEN or node.id.startswith("__")):
return None
if isinstance(node, ast.Attribute) and node.attr.startswith("_"):
return None
if isinstance(node, ast.Constant) and isinstance(node.value, str) and DUNDER.search(node.value):
return None
return tree
def _function(text):
"""Name of the last top-level function if `text` is screened Python source, else None."""
if not isinstance(text, str) or "def " not in text:
return None
try:
tree = _safe(ast.parse(text))
except (SyntaxError, ValueError, RecursionError):
return None
if tree is None:
return None
defs = [n.name for n in tree.body if isinstance(n, ast.FunctionDef)]
return defs[-1] if defs else None
def _call_args(text, fn):
if not isinstance(text, str) or "def " in text:
return False
try:
tree = ast.parse(f"{fn}({text})", mode="eval")
except (SyntaxError, ValueError, MemoryError, RecursionError):
return False
return isinstance(tree.body, ast.Call) and _safe(tree) is not None
def _literals(options):
try:
for o in options:
ast.literal_eval(o)
return True
except (SyntaxError, ValueError, TypeError, MemoryError, RecursionError):
return False
def _candidate(state):
if not isinstance(state, dict):
return None
fields = [v for v in state.values() if isinstance(v, str)]
for src in fields:
fn = _function(src)
if fn:
for args in fields:
if args is not src and _call_args(args, fn):
return src, fn, args
return None
def _run(source, fn, args, options, python=sys.executable):
payload = json.dumps({"source": source, "fn": fn, "args": args, "options": options})
with tempfile.TemporaryDirectory() as d:
try:
r = subprocess.run([python, "-I", "-S", "-c", CHILD], input=payload, capture_output=True, text=True,
timeout=TIMEOUT_S, cwd=d, env={"PYTHONHASHSEED": "0"})
except subprocess.TimeoutExpired:
return None
if r.returncode != 0:
return None
try:
return json.loads(r.stdout.strip().splitlines()[-1])["hits"]
except (ValueError, IndexError, KeyError):
return None
def code(state, questions):
"""Answers {key: answer} for the questions the code tool settles; {} when it does not fire."""
cand = _candidate(state)
if not cand:
return {}
out = {}
for key, q in questions.items():
if q.get("type") != "choice":
continue
keys = list(q["criteria"])
options = [q["criteria"][k] for k in keys]
if len(options) < 2 or not _literals(options):
continue
hits = _run(*cand, options)
if not hits or len(hits) != 1:
continue
rest = (1.0 - P_MATCH) / (len(keys) - 1)
probs = {k: (P_MATCH if i == hits[0] else rest) for i, k in enumerate(keys)}
out[key] = {"type": "choice", "choice": keys[hits[0]], "probabilities": probs, "confidence": P_MATCH}
return out
TOOLS = {"code": code}
|