Instructions to use mrm8488/embeddinggemma-2-ft-typed-decision with libraries, inference providers, notebooks, and local apps. Follow these links to get started.
- Libraries
- Transformers
How to use mrm8488/embeddinggemma-2-ft-typed-decision with Transformers:
# Use a pipeline as a high-level helper from transformers import pipeline pipe = pipeline("text-classification", model="mrm8488/embeddinggemma-2-ft-typed-decision", trust_remote_code=True)# pip install -U transformers accelerate # Load model directly from transformers import AutoModel model = AutoModel.from_pretrained("mrm8488/embeddinggemma-2-ft-typed-decision", trust_remote_code=True, device_map="auto") - Notebooks
- Google Colab
- Kaggle
EmbeddingGemma 2 Β· typed decisions
EmbeddingGemma 2 fine-tuned for typed decisions
A typed decision model: given the state of a workflow (an agent trace, a support ticket, an invoice, a security alertβ¦) and a schema of questions, it returns a typed, calibrated answer to each question.
| Question type | Example | Python type of value |
|---|---|---|
choice |
What should we do with this trace? β continue / observe / human_review / stop |
str |
score |
How risky is it? β level 0..3 |
int |
noul |
Does it need human review? β probabilistic yes/no | bool |
The head scores the text of each option against the state and the question, so the schema is plain data: you can rename options, change descriptions or add new questions without retraining (answers to questions far from the training data are less reliable).
Usage
from transformers import AutoModel
model = AutoModel.from_pretrained("mrm8488/embeddinggemma-2-ft-typed-decision", trust_remote_code=True)
state = {
"agent": {"autonomy": "unsupervised", "model": "internal-agent-v2"},
"task": "Clean up stale feature branches merged more than 90 days ago.",
"constraints": ["Never delete anything matching release/*", "Do not force-push to any branch"],
"trace_summary": {"steps": 9, "tool_errors": 1, "constraint_violations": 1,
"irreversible_actions": 1, "duration_s": 312.4},
}
questions = {
"action": {
"type": "choice",
"instructions": "What should the observability system do with this trace?",
"criteria": {
"continue": "Let the agent proceed without interruption.",
"observe": "Keep running, but flag the trace for later sampling.",
"human_review": "Queue this trace for a human to review.",
"stop": "Halt the agent now.",
},
},
"needs_review": {"type": "noul", "instructions": "Does a human need to review this trace?"},
"risk": {
"type": "score",
"instructions": "How risky is what the agent did?",
"criteria": ["no risk", "low risk", "significant risk", "severe risk"],
},
}
answers = model.decide(state, questions, workflow="agent_trace_observability")
for qid, answer in answers.items():
print(f"{qid:13s} β {answer.value!r:15} ({answer.confidence:.0%}) {answer.probabilities}")
Every answer is a TypedAnswer:
TypedAnswer(
kind="choice", # "choice" | "score" | "noul"
label="human_review", # the winning option key
value="human_review", # typed: str for choice, int for score, bool for noul
confidence=0.61, # calibrated probability of the winning option
probabilities={"continue": 0.02, "observe": 0.11, "human_review": 0.61, "stop": 0.26},
expected_level=None, # score questions only: E[level]
)
Use answer.to_dict() for JSON. The tokenizer is loaded from the same repo on first use.
Schema format
choice:"criteria": {option_key: description, ...}score:"criteria": [level_0_description, level_1_description, ...](lowest to highest)noul: only"instructions"; the answer isTrue/Falsewith a probability
It works in other languages
EmbeddingGemma 2 is multilingual, so states and schemas don't have to be in English:
preguntas = {
"accion": {
"type": "choice",
"instructions": "ΒΏQuΓ© debe hacer el sistema de observabilidad con esta traza?",
"criteria": {
"continuar": "Dejar que el agente siga sin interrupciΓ³n.",
"observar": "Seguir ejecutando, pero marcar la traza para revisarla mΓ‘s tarde.",
"revision_humana": "Poner la traza en cola para que la revise una persona.",
"detener": "Detener el agente inmediatamente.",
},
},
"necesita_revision": {"type": "noul", "instructions": "ΒΏNecesita una persona revisar lo que ha hecho el agente?"},
}
paquita = {
"agente": {"autonomΓa": "sin_supervisiΓ³n"},
"tarea": "Actualizar los precios del RoscΓ³n de Reyes en la tienda online.",
"resumen_traza": {"violaciones_de_restricciones": 2, "acciones_irreversibles": 1,
"notas": "AplicΓ³ un 90 % de descuento a todo el catΓ‘logo y enviΓ³ un correo a 12.000 clientes."},
}
model.decide(paquita, preguntas, workflow="agent_trace_observability")
The head was trained on English schemas only, so expect softer probabilities in other languages.
GPU and precision
import torch
model = AutoModel.from_pretrained("mrm8488/embeddinggemma-2-ft-typed-decision", trust_remote_code=True,
dtype=torch.bfloat16).to("cuda")
Use bfloat16 (Ampere or newer) or float32. Never float16: EmbeddingGemma 2 overflows and returns NaNs
without raising an error.
Lower-level API
| Method | What it does |
|---|---|
model.decide(state, questions, workflow="") |
typed answers for one state |
model.encode(texts) |
normalized sentence embeddings, exactly as in training |
model.collate(rows) |
turns dataset rows {workflow, state, questions, gold} into a training batch |
model(**batch) |
GemmaDecisionOutput(loss, logits, probabilities, text_embeds) |
Fine-tuning further with the π€ Trainer:
from datasets import load_dataset
from transformers import Trainer, TrainingArguments
ds = load_dataset("LocalLLaMA/typed-decisions", "all")
trainer = Trainer(
model=model,
args=TrainingArguments("out", per_device_train_batch_size=16, learning_rate=2e-5,
num_train_epochs=2, remove_unused_columns=False),
train_dataset=ds["train"],
data_collator=model.collate,
)
trainer.train()
A single learning rate fine-tunes the encoder and the head together; for the two-learning-rate recipe used to train this model, build the optimizer yourself.
How it was built
state βββΊ EmbeddingGemma 2 ββ
question βββΊ EmbeddingGemma 2 ββΌββΊ field(state, question, type) ββ
option_i βββΊ EmbeddingGemma 2 ββ΄βββββββββββββββββββββββββββββββββ β΄ββΊ logit_i
logit_i = prior_i + Ο(gate) Β· (s Β· cos(field, option_i) + residual_i)
- Encoder:
google/embeddinggemma-2, text only,Classificationtask prompt, mean pooling, 768-d, L2-normalized. - Input rendering: the state is flattened into readable
key: valuelines (trace summary Β· constraint violations: 1) instead of raw JSON, which embedding models read much better. - Head: schema-conditioned scorer (~0.5M parameters). The
priorterm is zero-shot embedding similarity; the trained part is a gated correction on top. - Phase 1: head only, on cached embeddings (encoder frozen).
- Phase 2: end-to-end fine-tuning of encoder + head, with two learning rates (encoder 2e-5, head 1e-4), frozen token embeddings, 5 epochs, 32 rows per batch.
- Loss: cross-entropy against the annotators' soft labels + Brier term + ordinal distance for
scorequestions. - Calibration: one temperature per question type, fitted on held-out training rows and stored in the weights.
Results
LocalLLaMA/typed-decisions, subset all, test split (argmax vs gold label, all question types):
| Model | Test accuracy | Soft CE | Brier |
|---|---|---|---|
| Phase 1 (frozen encoder) | 67.7% | 0.968 | 0.113 |
| Phase 2 (this model) | 76.4% | 0.887 | 0.065 |
Per question type (phase 1 β phase 2): choice 66.2% β 71.2% Β· score 61.8% β 74.0% Β· noul 77.0% β 84.8%.
Fine-tuning did not hurt the encoder's multilingual alignment: on an English/Spanish probe, the mean cosine of translation pairs went from 0.869 to 0.901, with 100% retrieval@1 before and after.
Hyperparameters were chosen while looking at the test split, so treat these numbers as slightly optimistic.
Limitations
- Soft labels set a ceiling. Many rows are near-ties between annotators; on those, the gold label is close to a coin flip.
- Calibration means "matches annotator disagreement". A 43% answer on a row where annotators split 43/28/25 is correct behaviour, but looks underconfident if you only compare confidence against the majority label.
- Numbers inside the state are harder for an embedding model than words;
scorequestions are the weakest type. - Unseen schemas and languages work, with softer probabilities. Validate on your own data before relying on them.
- The rendering of state, questions and options is part of the model. It lives in
modeling_gemmadecision.py; changing it changes the predictions.
- Downloads last month
- 60
Model tree for mrm8488/embeddinggemma-2-ft-typed-decision
Base model
google/embeddinggemma-2