Open History to see the last commit
1import type { EnvironmentSpeechModel, SpeechBenchmarkTier } from "@t3tools/contracts";
2
3import { languageLabel } from "./SpeechLanguageSelect";
4
5const commonLanguages = [
6 "en",
7 "zh",
8 "hi",
9 "es",
10 "fr",
11 "bn",
12 "pt",
13 "id",
14 "ur",
15 "ru",
16 "de",
17 "ja",
18 "mr",
19 "vi",
20 "te",
21 "sw",
22 "ha",
23 "tr",
24 "tl",
25 "ta",
26 "jw",
27 "ko",
28 "am",
29 "th",
30 "it",
31 "gu",
32 "kn",
33 "yo",
34];
35
36export function orderSpeechLanguages(languages: readonly string[], preferred: readonly string[]) {
37 const order = [...new Set([...preferred, ...commonLanguages])];
38 const rank = new Map(order.map((code, index) => [code, index]));
39 return languages.toSorted(
40 (left, right) =>
41 (rank.get(left) ?? order.length) - (rank.get(right) ?? order.length) ||
42 languageLabel(left).localeCompare(languageLabel(right)),
43 );
44}
45
46export function ModelBenchmarks({
47 model,
48 languages,
49 tier,
50 facts,
51}: {
52 model: EnvironmentSpeechModel;
53 languages: readonly string[];
54 tier: SpeechBenchmarkTier;
55 /** Plain facts, such as language count and size, shown after the scores. */
56 facts: readonly string[];
57}) {
58 const data = model.benchmark;
59 const seconds = data?.secondsPer30s[tier];
60 const visible = !data
61 ? []
62 : languages.length
63 ? languages
64 : [model.languages.find((code) => data.accuracy[code]) ?? model.languages[0]].filter(
65 (code): code is string => code !== undefined,
66 );
67 return (
68 <div className="mt-1 flex flex-wrap gap-x-3 gap-y-1 text-xs text-muted-foreground tabular-nums">
69 {visible.map((code) => {
70 const score = data?.accuracy[code];
71 return (
72 <span key={code}>
73 {languageLabel(code)}:{" "}
74 {score ? (
75 <>
76 <strong className="font-medium text-foreground">{score.grade}</strong> (
77 {score.errorPercent}% error)
78 </>
79 ) : (
80 "not benchmarked"
81 )}
82 </span>
83 );
84 })}
85 <span>
86 Speed:{" "}
87 {tier === "cpu" && data && data.secondsPer30s.cpu === undefined ? (
88 "update server"
89 ) : seconds == null ? (
90 "not benchmarked"
91 ) : (
92 <>
93 <strong className="font-medium text-foreground">{seconds} s</strong> / 30 s
94 </>
95 )}
96 </span>
97 {facts.map((fact) => (
98 <span key={fact}>{fact}</span>
99 ))}
100 </div>
101 );
102}