"""GLiDE-0.4B — a decision model: state in, typed questions out, calibrated probabilities. Model: https://huggingface.co/fastino/GLiDE-0.4B Author: Fastino — https://fastino.ai Given a state (text or JSON) and one or more typed questions, GLiDE returns a probability for every option of every question. The probabilities are read from a 255-way decision readout — nothing is generated. The `glide/` package is vendored verbatim from the model repository and the checkpoint is streamed from the Hub at startup (~0.8 GB, bf16). """ import html as _html import json import time import spaces # must come before torch import torch import gradio as gr from glide import Glide, RequestError MODEL_ID = "fastino/GLiDE-0.4B" model = Glide.from_pretrained(MODEL_ID) # device="cuda", bf16, vision=True defaults # -------------------------------------------------------------------------------------- # request building # -------------------------------------------------------------------------------------- def _parse_state(text: str): """A JSON object/array is passed through structurally; anything else is plain text.""" s = (text or "").strip() if s[:1] in "{[": try: v = json.loads(s) if isinstance(v, (dict, list)): return v except json.JSONDecodeError: pass return text or "" def _build_questions(questions_json: str) -> dict: try: questions = json.loads(questions_json) except json.JSONDecodeError as e: raise gr.Error(f"Questions are not valid JSON: {e}") from None if not isinstance(questions, dict) or not questions: raise gr.Error( 'Questions must be a non-empty JSON object, e.g. ' '{"intent": {"type": "choice", "instructions": "...", "criteria": {"a": "A", "b": "B"}}}' ) return questions def _score_legend(q: dict) -> dict: """Map the numeric level index strings GLiDE returns to the user's level descriptions.""" crit = q.get("criteria") if isinstance(q, dict) else None if isinstance(crit, list): return {str(i): str(d) for i, d in enumerate(crit)} if isinstance(crit, dict): try: keys = sorted(crit, key=lambda x: float(x)) return {str(i): str(crit[k]) for i, k in enumerate(keys)} except (TypeError, ValueError): pass return {} # -------------------------------------------------------------------------------------- # rendering # -------------------------------------------------------------------------------------- BADGE = {"noul": "#2563eb", "choice": "#7c3aed", "score": "#ea580c"} def _bar(label: str, p: float, highlight: bool) -> str: pct = max(0.0, min(1.0, float(p))) * 100 colour = "var(--color-accent)" if highlight else "var(--border-color-accent)" weight = "600" if highlight else "400" return ( '
' f'
{_html.escape(label)}
' '
' f'
' f'
{p:.2f}
' "
" ) def _card(qid: str, ans: dict, question: dict) -> str: t = ans["type"] head = ( '
' f'{_html.escape(qid)}' f'{t}' ) if t == "noul": p = ans["noul"] head += ( f'{p:.2f}' f'conf {ans["confidence"]:.2f}
' ) body = _bar("yes", p, p >= 0.5) + _bar("no", 1 - p, p < 0.5) elif t == "choice": head += ( f'{_html.escape(str(ans["choice"]))}' f'conf {ans["confidence"]:.2f}' ) best = ans["choice"] body = "".join(_bar(k, v, k == best) for k, v in ans["probabilities"].items()) else: # score legend = _score_legend(question) head += ( f'level {ans["score"]}' f'conf {ans["confidence"]:.2f}' ) best = ans["score"] body = "".join( _bar(f"{k} · {legend[k]}" if k in legend else str(k), v, k == str(best)) for k, v in ans["probabilities"].items() ) head += ( f'
' f'expected level {ans["expected_level"]:.2f}
' ) return ( '
' + head + body + "
" ) def _render(result: dict, questions: dict, latency_ms: float) -> str: answers = result["answers"] cards = "".join(_card(qid, a, questions.get(qid, {})) for qid, a in answers.items()) tokens = result.get("usage", {}).get("input_tokens", 0) meta = ( '
' f'{len(answers)} question(s) · {tokens} input tokens · {latency_ms:.0f} ms on GPU · ' 'bf16 · nothing generated
' ) return f'
{meta}{cards}
' # -------------------------------------------------------------------------------------- # inference # -------------------------------------------------------------------------------------- @spaces.GPU(duration=15) def decide(state: str, questions: str): """Answer typed questions about one state and return calibrated probabilities. Args: state: the situation to evaluate. Plain text, or a JSON object / array (passed through structurally, e.g. {"ticket": "...", "customer_tier": "gold"}). questions: a JSON object mapping your own question id to a question of type "choice" (criteria = {option: description}, up to 255 options), "noul" (yes/no, criteria = optional {"true": ..., "false": ...}) or "score" (criteria = [ordered level descriptions, ...]). Returns: An HTML summary with a probability bar per option of every question, and the raw System One response ({"model", "answers", "usage"}). """ q = _build_questions(questions) t0 = time.perf_counter() try: result = model.decide(state=_parse_state(state), questions=q) except RequestError as e: raise gr.Error(f"GLiDE cannot serve this request: {e}") from None if torch.cuda.is_available(): torch.cuda.synchronize() latency_ms = (time.perf_counter() - t0) * 1000 return _render(result, q, latency_ms), result # -------------------------------------------------------------------------------------- # examples — the two quickstart requests from the model card, verbatim # -------------------------------------------------------------------------------------- EX1_STATE = json.dumps( {"ticket": "I was charged twice for order #4821 and the second charge is still pending.", "customer_tier": "gold"}, indent=2, ) EX1_QUESTIONS = json.dumps( { "intent": {"type": "choice", "instructions": "What does the customer want?", "criteria": {"refund": "Get money back", "cancel": "Cancel the order", "track": "Track a delivery", "other": "Something else"}}, "urgent": {"type": "noul", "instructions": "Should this ticket be escalated today?"}, "priority": {"type": "score", "instructions": "What support priority should this ticket get?", "criteria": ["low: no impact on the customer", "medium: the customer is inconvenienced", "high: the customer has lost money or cannot use the service"]}, }, indent=2, ) EX2_STATE = "Order #4821 was delivered to the wrong address and the customer wants it re-sent today." EX2_QUESTIONS = json.dumps( { "action": {"type": "choice", "instructions": "What should support do next?", "criteria": {"resend": "Re-ship the order", "refund": "Refund the order", "investigate": "Open a carrier investigation"}}, "urgent": {"type": "noul", "instructions": "Is the request time-sensitive?"}, }, indent=2, ) EXAMPLES = [ [EX1_STATE, EX1_QUESTIONS], [EX2_STATE, EX2_QUESTIONS], ] EXAMPLE_LABELS = ["Support ticket — intent, urgency, priority (model-card quickstart)", "Wrong address — next action + urgency (model-card HTTP example)"] # -------------------------------------------------------------------------------------- # UI # -------------------------------------------------------------------------------------- CSS = """ #col-container { max-width: 1180px; margin: 0 auto; } .dark .gradio-container { color: var(--body-text-color); } """ INTRO = f"""# GLiDE-0.4B — state in, typed questions, calibrated probabilities out [`{MODEL_ID}`](https://huggingface.co/{MODEL_ID}) is a **decision model** from [Fastino](https://fastino.ai). Given a state (text or JSON) and one or more typed questions, it returns a **probability for every option of every question** — read from a 255-way decision readout in a single forward pass. Nothing is generated. Three question types: **choice** (one of up to 255 named options), **noul** (yes / no → P(yes)) and **score** (ordered levels). 0.40B params, bf16, 51.10 on the Decision Index 0.3.1 public suite. This model has no vision encoder — images are rejected. [Fastino](https://fastino.ai) · [model card](https://huggingface.co/{MODEL_ID}) · [Fastino API](https://docs.fastino.ai/inference/systemone) """ with gr.Blocks(title="GLiDE-0.4B decision model") as demo: with gr.Column(elem_id="col-container"): gr.Markdown(INTRO) with gr.Row(): with gr.Column(scale=1): state = gr.Textbox( label="State — the situation to evaluate", placeholder='e.g. {"ticket": "I was charged twice for order #4821…", "customer_tier": "gold"} (plain text or JSON)', lines=10, value=EX1_STATE, ) with gr.Column(scale=1): questions = gr.Code( label="Questions (JSON)", language="json", lines=10, value=EX1_QUESTIONS, ) run = gr.Button("Decide", variant="primary") answers_html = gr.HTML(label="Answers") raw = gr.JSON(label="Raw System One response") with gr.Accordion("Advanced — question schema & limits", open=False): gr.Markdown( '**Question schema** — `{"": {"type": …, "instructions": …, "criteria": …}}`\n\n' "| type | `criteria` | answer |\n|---|---|---|\n" "| `choice` | `{option: description or null}`, 1–255 options | `choice`, `probabilities`, `confidence` = top − second |\n" "| `noul` | optional `{\"true\": …, \"false\": …}` | `noul` = P(yes), `confidence` = \\|2·P − 1\\| |\n" "| `score` | `[level, level, …]` ordered, or `{numeric level: description}` | `score` = top level, `expected_level`, `probabilities` |\n\n" "`state` and `instructions` may be any JSON value — objects are rendered as `key: value` lines. " "Each question prompt holds up to **7,999 tokens** (state + question + options); longer prompts keep " "their first 1,024 tokens and their end, so they are still answered. Answers are read from a " "255-way decision readout — nothing is generated, so outputs are deterministic at a fixed temperature." ) gr.Examples( examples=EXAMPLES, example_labels=EXAMPLE_LABELS, inputs=[state, questions], outputs=[answers_html, raw], fn=decide, cache_examples=True, cache_mode="lazy", label="Examples from the GLiDE-0.4B model card", ) gr.on( triggers=[run.click], fn=decide, inputs=[state, questions], outputs=[answers_html, raw], api_name="decide", ) if __name__ == "__main__": demo.launch(theme=gr.themes.Citrus(), css=CSS, mcp_server=True)