SPB Git

spb/wpai0001_uqo

Public
2.2 KB · 55 lines python
1"""Exact-match evaluation of a toy model on a Split under greedy decoding, with per-item outputs."""2from __future__ import annotations34from dataclasses import dataclass56import numpy as np7import torch89from wp_ai_0001.datasets.common import Split, Vocab, encode_split10from wp_ai_0001.models.decoding import greedy_decode11from wp_ai_0001.models.toy_transformer import ToyTransformer121314@dataclass15class EvalResult:16    split: str17    split_hash: str18    n: int19    accuracy: float  # final-answer exact match20    trace_accuracy: float  # all scratchpad tokens exact match21    correct: np.ndarray  # [N] bool (final answer)22    trace_correct: np.ndarray  # [N] bool23    clusters: list[str]24    predictions: list[list[str]]25    answers: list[list[str]]2627    def to_summary(self) -> dict:28        return {"split": self.split, "split_hash": self.split_hash, "n": self.n, "accuracy": self.accuracy, "trace_accuracy": self.trace_accuracy}293031@torch.no_grad()32def evaluate(model: ToyTransformer, split: Split, vocab: Vocab, device: torch.device, bs: int = 1024) -> EvalResult:33    enc = encode_split(split, vocab, model.cfg.max_seq_len)34    K = enc["answers"].shape[1]35    preds = []36    for i in range(0, len(enc["ids"]), bs):37        ids = torch.from_numpy(enc["ids"][i : i + bs]).to(device)38        pl = torch.from_numpy(enc["prompt_len"][i : i + bs]).to(device)39        na = torch.from_numpy(enc["n_answer"][i : i + bs]).to(device)40        preds.append(greedy_decode(model, ids, pl, na, K).cpu().numpy())41    pred = np.concatenate(preds)42    na = enc["n_answer"]43    ar = np.arange(len(na))44    final_ok = pred[ar, na - 1] == enc["answers"][ar, na - 1]45    valid = np.arange(K)[None] < na[:, None]46    trace_ok = ((pred == enc["answers"]) | ~valid).all(-1)47    return EvalResult(split.name, split.hash, len(na), float(final_ok.mean()), float(trace_ok.mean()), final_ok, trace_ok,48                      [e.cluster for e in split.examples], [vocab.decode(pred[i, : na[i]]) for i in ar],49                      [list(e.answers) for e in split.examples])505152def chance_level(split: Split) -> float:53    """Majority-class rate of the answer distribution (the relevant chance baseline)."""54    return max(split.answer_distribution().values())55
Files · main
Menu

Theme