Spaces:
Sleeping
Sleeping
| import clsx from "clsx"; | |
| import { FlaskConical } from "lucide-react"; | |
| import { fmt } from "@/lib/data"; | |
| import type { ModelRow, Provenance, SplitInfo, SplitMetrics } from "@/lib/types"; | |
| import SectionLabel from "./SectionLabel"; | |
| export interface GeneralizationStripProps { | |
| model: ModelRow; | |
| hardInfo: SplitInfo; | |
| } | |
| function hasNumbers(m?: SplitMetrics): boolean { | |
| return !!m && Object.values(m).some((v) => typeof v === "number"); | |
| } | |
| function DeltaTile({ | |
| label, | |
| test, | |
| hard, | |
| }: { | |
| label: string; | |
| test?: number; | |
| hard?: number; | |
| }) { | |
| const d = | |
| typeof test === "number" && typeof hard === "number" ? hard - test : null; | |
| const degrading = d !== null && d > 0; | |
| return ( | |
| <div className="hairline depth-1 hover-lift flex min-w-[160px] flex-col gap-1 rounded-sm bg-surface px-4 py-3"> | |
| <span className="text-[11px] uppercase tracking-[0.14em] text-muted"> | |
| Δ {label} | |
| </span> | |
| <span | |
| className={clsx( | |
| "num text-2xl leading-none", | |
| d === null ? "text-muted/50" : degrading ? "text-warn" : "text-text", | |
| )} | |
| > | |
| {d === null ? "—" : `${d >= 0 ? "+" : "−"}${Math.abs(d).toFixed(2)}`} | |
| </span> | |
| <span className="num text-[11px] text-muted"> | |
| {fmt(test)} → {fmt(hard)} | |
| </span> | |
| </div> | |
| ); | |
| } | |
| function GhostTile({ label }: { label: string }) { | |
| return ( | |
| <div | |
| aria-hidden | |
| className="flex min-w-[160px] flex-col gap-1 rounded-sm border border-dashed border-line px-4 py-3" | |
| > | |
| <span className="text-[11px] uppercase tracking-[0.14em] text-muted/70"> | |
| Δ {label} | |
| </span> | |
| <span className="num text-2xl leading-none text-muted/50">—</span> | |
| <span className="num text-[11px] text-muted/50">test → hard</span> | |
| </div> | |
| ); | |
| } | |
| function gapCopy(provenance: Provenance): string { | |
| if (provenance === "running") | |
| return "This model’s pilot run is executing on Test + Hard right now — the delta lands here the moment it commits."; | |
| if (provenance === "planned") | |
| return "A platform run covering Test + Hard is on the roadmap for this model."; | |
| return "Published results cover Test only; the platform pilot re-runs every model on Test + Hard, and this gap closes when its run lands."; | |
| } | |
| /** | |
| * Test → Hard generalization: signed delta tiles when both splits are | |
| * measured (amber when degrading), otherwise a dashed evidence-gap callout | |
| * with ghost tiles showing the shape of what will appear. | |
| */ | |
| export default function GeneralizationStrip({ | |
| model, | |
| hardInfo, | |
| }: GeneralizationStripProps) { | |
| const test = model.metrics?.test; | |
| const hard = model.metrics?.hard; | |
| const measured = hasNumbers(test) && hasNumbers(hard); | |
| return ( | |
| <section className="flex flex-col gap-4"> | |
| <SectionLabel | |
| index="03" | |
| title="Generalization" | |
| hint="Test → Hard delta" | |
| /> | |
| {measured ? ( | |
| <div className="flex flex-col gap-5 md:flex-row md:items-center md:justify-between"> | |
| <div className="flex flex-wrap gap-3"> | |
| <DeltaTile label="WER" test={test?.wer} hard={hard?.wer} /> | |
| <DeltaTile label="CS-WER" test={test?.csWer} hard={hard?.csWer} /> | |
| </div> | |
| <p className="max-w-sm text-[13px] leading-relaxed text-muted"> | |
| The Hard split holds{" "} | |
| <span className="num">{fmt(hardInfo.hours)}</span> | |
| <span className="num text-[11px]">{" "}h</span> of rare and | |
| unseen code-switched terms. A positive Δ (amber) means the model | |
| degrades off the common-term distribution. | |
| </p> | |
| </div> | |
| ) : ( | |
| <div className="flex flex-col gap-5 rounded-sm border border-dashed border-line p-5 md:flex-row md:items-center md:justify-between md:p-6"> | |
| <div className="flex max-w-xl items-start gap-4"> | |
| <span aria-hidden className="mt-1 shrink-0 text-muted"> | |
| <FlaskConical size={18} /> | |
| </span> | |
| <div> | |
| <h3 className="font-display text-lg italic text-text"> | |
| Evidence gap — no Hard-split measurement yet | |
| </h3> | |
| <p className="mt-1.5 text-[13px] leading-relaxed text-muted"> | |
| The Hard split holds{" "} | |
| <span className="num">{fmt(hardInfo.hours)}</span> | |
| <span className="num text-[11px]">{" "}h</span> /{" "} | |
| <span className="num"> | |
| {hardInfo.utts.toLocaleString("en-US")} | |
| </span>{" "} | |
| utterances of rare and unseen code-switched terms — the | |
| generalization leaderboard. {gapCopy(model.provenance)} | |
| </p> | |
| </div> | |
| </div> | |
| <div className="flex shrink-0 flex-wrap gap-3"> | |
| <GhostTile label="WER" /> | |
| <GhostTile label="CS-WER" /> | |
| </div> | |
| </div> | |
| )} | |
| </section> | |
| ); | |
| } | |