Decoder evaluation targets
Decoder evaluation scores target-token probabilities across a grid of decoder updates.
This guide covers decoder_eval_targets: which tokens are scored per class, or per
training example when a token means different things in different rows.
Where to set it
Set decoder_eval_targets when you create the trainer — it is a field on
TextPredictionConfig,
passed either as config=TextPredictionConfig(...) or as a
TextPredictionTrainer
keyword argument:
trainer = TextPredictionTrainer(
model="distilbert-base-uncased",
data=df,
target_classes=["3SG", "3PL"],
decoder_eval_targets=None, # default
args=TrainingArguments(experiment_dir="runs/pronouns"),
)
evaluate_decoder() does not take
decoder_eval_targets; it reads the value stored on the trainer config. Grid size and
sample caps for decoder eval (decoder_eval_lrs, decoder_eval_feature_factors,
decoder_eval_max_size_training_like, …) live on
TrainingArguments instead.
You can override the evaluation subset per call with split and max_size:
evaluate_decoder(split="test", max_size=50) uses the test split for training-like
probability scoring and caps both training-like rows and neutral LMS rows at 50.
Use max_size_training_like or max_size_neutral when those caps should differ.
Default: decoder_eval_targets=None. Leave it unset (or pass None) and GRADIEND
infers targets from your training data when decoder evaluation runs depending on the data:
- Disjoint tokens (usual case; e.g.
heandHefor 3SG vstheyandTheyin 3PL): one shared token list per class - Shared surface forms (e.g.
+in both commutative and non-commutative rows): score that row's factual token (label) against that row's alternative token (alternative) — not one global list per class.
Note that decoder_eval_targets is independent of prediction_objective (training gradient source).
Decision guide
| Situation | Setting |
|---|---|
| Disjoint token sets per class (e.g. 3SG vs 3PL pronouns) | default (None) — auto-infer one list per class |
Same token, different class meaning (e.g. * vs + in math) |
default (None, auto per-row) or "label" |
Always use each row's label / alternative tokens (targets depend on row) |
"label" |
| Fixed token list per class, no per-row semantics | {class_name: [tokens]} dict |
1. Default (None): infer from data
When you do not pass decoder_eval_targets to the trainer (default None), GRADIEND
collects factual and alternative tokens per class from training data at evaluation time.
- No token overlap across classes → build one token list per class (e.g.
3SG → [he, He],3PL → [they, They]). Every row in a class is scored against that class's list. - Overlap (same token in more than one class) → score per training row: compare
P(
label) vs P(alternative) for that row only. GRADIEND logs an info message when it switches to this mode.
Use the default for disjoint pronoun sets. Overlap is detected automatically when classes
share operators like + or *.
The automatically inferred decoder eval targets are logged.
2. Per-row scoring: decoder_eval_targets="label"
Force per-row scoring even when classes do not overlap. For each training row:
- P(dataset class) = probability of the row's factual token (
label) - P(other class) = probability of the row's alternative token (
alternative)
Use this when the same surface form has different meanings per row (commutative math is the usual example).
trainer = TextPredictionTrainer(
model="distilbert-base-uncased",
data=commutative_df,
label_col="label",
label_class_col="label_class",
alternative_col="alternative",
alternative_class_col="alternative_class",
masked_col="masked",
decoder_eval_targets="label",
args=TrainingArguments(experiment_dir="runs/math", max_steps=60),
)
trainer.train()
dec = trainer.evaluate_decoder(plot=True, target_class="commutative")
There is no dedicated example script for commutative overlap — inline snippet only. Overlap detection is covered in
tests/test_trainer_data_inputs.py (test_infer_decoder_eval_targets_marks_overlapping_tokens_for_row_wise_fallback).
3. Class-based static lists
:material-file-code-outline: start_workflow.py
Keys must match class names. The same token in multiple classes emits a warning — use
decoder_eval_targets="label" (per-row scoring) when token meaning depends on the row.
Exporting per-row scores
When per-row scoring is active (decoder_eval_targets="label", or default with overlapping
tokens), decoder_eval_export_row_wise_csv=True writes
experiment_dir/decoder_row_wise_scores.csv with per-row P_factual, P_alternative,
class ids, and masked text.