techfreakworm commited on
Commit
200e3fe
·
unverified ·
1 Parent(s): 14c6f28

feat(web): info icon on every param with hover/click tooltip; add help text to all params

Browse files
server/models/chatterbox_en.py CHANGED
@@ -23,38 +23,43 @@ class Adapter:
23
  ParamSpec(
24
  name="exaggeration", label="Exaggeration", type="float",
25
  default=0.5, min=0.0, max=2.0, step=0.05,
26
- help="Higher = more expressive prosody.",
27
  group="basic",
28
  ),
29
  ParamSpec(
30
  name="cfg_weight", label="CFG weight", type="float",
31
  default=0.5, min=0.0, max=1.0, step=0.05,
 
32
  group="basic",
33
  ),
34
  ParamSpec(
35
  name="temperature", label="Temperature", type="float",
36
  default=0.8, min=0.1, max=1.5, step=0.05,
 
37
  group="basic",
38
  ),
39
  ParamSpec(
40
  name="seed", label="Seed", type="int",
41
  default=-1, min=-1, step=1,
42
- help="-1 draws a random seed each time.",
43
  group="advanced",
44
  ),
45
  ParamSpec(
46
  name="repetition_penalty", label="Repetition penalty", type="float",
47
  default=1.2, min=1.0, max=3.0, step=0.05,
 
48
  group="advanced",
49
  ),
50
  ParamSpec(
51
  name="min_p", label="Min p", type="float",
52
  default=0.05, min=0.0, max=1.0, step=0.01,
 
53
  group="advanced",
54
  ),
55
  ParamSpec(
56
  name="top_p", label="Top p", type="float",
57
  default=1.0, min=0.0, max=1.0, step=0.01,
 
58
  group="advanced",
59
  ),
60
  ]
 
23
  ParamSpec(
24
  name="exaggeration", label="Exaggeration", type="float",
25
  default=0.5, min=0.0, max=2.0, step=0.05,
26
+ help="How emotive the speech is. Higher pushes prosody, pacing, and emphasis; lower stays flat and neutral.",
27
  group="basic",
28
  ),
29
  ParamSpec(
30
  name="cfg_weight", label="CFG weight", type="float",
31
  default=0.5, min=0.0, max=1.0, step=0.05,
32
+ help="Classifier-free guidance. Higher sticks closer to the reference voice; lower allows more variation but may drift in identity.",
33
  group="basic",
34
  ),
35
  ParamSpec(
36
  name="temperature", label="Temperature", type="float",
37
  default=0.8, min=0.1, max=1.5, step=0.05,
38
+ help="Sampling randomness. Lower = deterministic and safer; higher = more creative but riskier and prone to artifacts.",
39
  group="basic",
40
  ),
41
  ParamSpec(
42
  name="seed", label="Seed", type="int",
43
  default=-1, min=-1, step=1,
44
+ help="Reproducibility. -1 draws a fresh random seed every run; any non-negative value pins the result so you can reproduce it.",
45
  group="advanced",
46
  ),
47
  ParamSpec(
48
  name="repetition_penalty", label="Repetition penalty", type="float",
49
  default=1.2, min=1.0, max=3.0, step=0.05,
50
+ help="Discourages repeating the same tokens. >1 reduces stuttering and loops; too high hurts natural fluency.",
51
  group="advanced",
52
  ),
53
  ParamSpec(
54
  name="min_p", label="Min p", type="float",
55
  default=0.05, min=0.0, max=1.0, step=0.01,
56
+ help="Cuts off tokens whose probability is below this fraction of the top token's. Higher trims more aggressively.",
57
  group="advanced",
58
  ),
59
  ParamSpec(
60
  name="top_p", label="Top p", type="float",
61
  default=1.0, min=0.0, max=1.0, step=0.01,
62
+ help="Nucleus sampling. Keep tokens until cumulative probability reaches this. Lower = safer/conservative.",
63
  group="advanced",
64
  ),
65
  ]
server/models/chatterbox_mtl.py CHANGED
@@ -50,37 +50,43 @@ class Adapter:
50
  ParamSpec(
51
  name="exaggeration", label="Exaggeration", type="float",
52
  default=0.5, min=0.0, max=2.0, step=0.05,
 
53
  group="basic",
54
  ),
55
  ParamSpec(
56
  name="cfg_weight", label="CFG weight", type="float",
57
  default=0.5, min=0.0, max=1.0, step=0.05,
 
58
  group="basic",
59
  ),
60
  ParamSpec(
61
  name="temperature", label="Temperature", type="float",
62
  default=0.8, min=0.1, max=1.5, step=0.05,
 
63
  group="basic",
64
  ),
65
  ParamSpec(
66
  name="repetition_penalty", label="Repetition penalty", type="float",
67
  default=2.0, min=1.0, max=3.0, step=0.05,
 
68
  group="basic",
69
  ),
70
  ParamSpec(
71
  name="seed", label="Seed", type="int",
72
  default=-1, min=-1, step=1,
73
- help="-1 draws a random seed each time.",
74
  group="advanced",
75
  ),
76
  ParamSpec(
77
  name="min_p", label="Min p", type="float",
78
  default=0.05, min=0.0, max=1.0, step=0.01,
 
79
  group="advanced",
80
  ),
81
  ParamSpec(
82
  name="top_p", label="Top p", type="float",
83
  default=1.0, min=0.0, max=1.0, step=0.01,
 
84
  group="advanced",
85
  ),
86
  ]
 
50
  ParamSpec(
51
  name="exaggeration", label="Exaggeration", type="float",
52
  default=0.5, min=0.0, max=2.0, step=0.05,
53
+ help="How emotive the speech is. Higher pushes prosody and emphasis; lower stays flat and neutral.",
54
  group="basic",
55
  ),
56
  ParamSpec(
57
  name="cfg_weight", label="CFG weight", type="float",
58
  default=0.5, min=0.0, max=1.0, step=0.05,
59
+ help="Classifier-free guidance. Higher sticks closer to the reference voice; lower allows more variation but may drift in identity.",
60
  group="basic",
61
  ),
62
  ParamSpec(
63
  name="temperature", label="Temperature", type="float",
64
  default=0.8, min=0.1, max=1.5, step=0.05,
65
+ help="Sampling randomness. Lower = deterministic and safer; higher = more creative but riskier and prone to artifacts.",
66
  group="basic",
67
  ),
68
  ParamSpec(
69
  name="repetition_penalty", label="Repetition penalty", type="float",
70
  default=2.0, min=1.0, max=3.0, step=0.05,
71
+ help="Discourages repeating the same tokens. Higher than for English because non-Latin scripts loop more easily.",
72
  group="basic",
73
  ),
74
  ParamSpec(
75
  name="seed", label="Seed", type="int",
76
  default=-1, min=-1, step=1,
77
+ help="Reproducibility. -1 draws a fresh random seed every run; any non-negative value pins the result so you can reproduce it.",
78
  group="advanced",
79
  ),
80
  ParamSpec(
81
  name="min_p", label="Min p", type="float",
82
  default=0.05, min=0.0, max=1.0, step=0.01,
83
+ help="Cuts off tokens whose probability is below this fraction of the top token's. Higher trims more aggressively.",
84
  group="advanced",
85
  ),
86
  ParamSpec(
87
  name="top_p", label="Top p", type="float",
88
  default=1.0, min=0.0, max=1.0, step=0.01,
89
+ help="Nucleus sampling. Keep tokens until cumulative probability reaches this. Lower = safer/conservative.",
90
  group="advanced",
91
  ),
92
  ]
server/models/chatterbox_turbo.py CHANGED
@@ -34,37 +34,43 @@ class Adapter:
34
  ParamSpec(
35
  name="temperature", label="Temperature", type="float",
36
  default=0.8, min=0.1, max=1.5, step=0.05,
 
37
  group="basic",
38
  ),
39
  ParamSpec(
40
  name="top_p", label="Top p", type="float",
41
  default=0.95, min=0.0, max=1.0, step=0.01,
 
42
  group="basic",
43
  ),
44
  ParamSpec(
45
  name="repetition_penalty", label="Repetition penalty", type="float",
46
  default=1.2, min=1.0, max=3.0, step=0.05,
 
47
  group="basic",
48
  ),
49
  ParamSpec(
50
  name="seed", label="Seed", type="int",
51
  default=-1, min=-1, step=1,
52
- help="-1 draws a random seed each time.",
53
  group="advanced",
54
  ),
55
  ParamSpec(
56
  name="top_k", label="Top k", type="int",
57
  default=1000, min=1, max=4000, step=1,
 
58
  group="advanced",
59
  ),
60
  ParamSpec(
61
  name="exaggeration", label="Exaggeration", type="float",
62
  default=0.0, min=0.0, max=2.0, step=0.05,
 
63
  group="advanced",
64
  ),
65
  ParamSpec(
66
  name="cfg_weight", label="CFG weight", type="float",
67
  default=0.0, min=0.0, max=1.0, step=0.05,
 
68
  group="advanced",
69
  ),
70
  ]
 
34
  ParamSpec(
35
  name="temperature", label="Temperature", type="float",
36
  default=0.8, min=0.1, max=1.5, step=0.05,
37
+ help="Sampling randomness. Lower = deterministic and safer; higher = more creative but riskier and prone to artifacts.",
38
  group="basic",
39
  ),
40
  ParamSpec(
41
  name="top_p", label="Top p", type="float",
42
  default=0.95, min=0.0, max=1.0, step=0.01,
43
+ help="Nucleus sampling. Keep tokens until cumulative probability reaches this. Lower = safer/conservative.",
44
  group="basic",
45
  ),
46
  ParamSpec(
47
  name="repetition_penalty", label="Repetition penalty", type="float",
48
  default=1.2, min=1.0, max=3.0, step=0.05,
49
+ help="Discourages repeating the same tokens. >1 reduces stuttering and loops; too high hurts natural fluency.",
50
  group="basic",
51
  ),
52
  ParamSpec(
53
  name="seed", label="Seed", type="int",
54
  default=-1, min=-1, step=1,
55
+ help="Reproducibility. -1 draws a fresh random seed every run; any non-negative value pins the result so you can reproduce it.",
56
  group="advanced",
57
  ),
58
  ParamSpec(
59
  name="top_k", label="Top k", type="int",
60
  default=1000, min=1, max=4000, step=1,
61
+ help="Sample only from the top-k most likely tokens. Higher = more diversity. Turbo defaults to a wide pool.",
62
  group="advanced",
63
  ),
64
  ParamSpec(
65
  name="exaggeration", label="Exaggeration", type="float",
66
  default=0.0, min=0.0, max=2.0, step=0.05,
67
+ help="How emotive the speech is. Turbo defaults to 0 (flat); raise it for more expressive prosody.",
68
  group="advanced",
69
  ),
70
  ParamSpec(
71
  name="cfg_weight", label="CFG weight", type="float",
72
  default=0.0, min=0.0, max=1.0, step=0.05,
73
+ help="Classifier-free guidance. Higher sticks closer to the reference voice; lower allows more variation.",
74
  group="advanced",
75
  ),
76
  ]
web/src/components/InfoTip.tsx ADDED
@@ -0,0 +1,47 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import { useEffect, useRef, useState } from "react";
2
+
3
+ type Props = { text: string };
4
+
5
+ export default function InfoTip({ text }: Props) {
6
+ const [hover, setHover] = useState(false);
7
+ const [sticky, setSticky] = useState(false);
8
+ const ref = useRef<HTMLSpanElement>(null);
9
+ const open = hover || sticky;
10
+
11
+ useEffect(() => {
12
+ if (!sticky) return;
13
+ function onDocClick(e: MouseEvent) {
14
+ if (ref.current && !ref.current.contains(e.target as Node)) {
15
+ setSticky(false);
16
+ }
17
+ }
18
+ document.addEventListener("mousedown", onDocClick);
19
+ return () => document.removeEventListener("mousedown", onDocClick);
20
+ }, [sticky]);
21
+
22
+ return (
23
+ <span ref={ref} className="relative inline-flex align-middle">
24
+ <button
25
+ type="button"
26
+ aria-label="What does this parameter do?"
27
+ onClick={(e) => {
28
+ e.stopPropagation();
29
+ setSticky((s) => !s);
30
+ }}
31
+ onMouseEnter={() => setHover(true)}
32
+ onMouseLeave={() => setHover(false)}
33
+ className="inline-flex size-4 items-center justify-center rounded-full border border-border text-[10px] font-mono italic text-muted-foreground hover:text-[hsl(var(--ember))] hover:border-[hsl(var(--ember))]/60 transition-colors leading-none"
34
+ >
35
+ i
36
+ </button>
37
+ {open && (
38
+ <span
39
+ role="tooltip"
40
+ className="absolute left-1/2 -translate-x-1/2 bottom-full mb-2 w-56 px-3 py-2 rounded-sm border border-border bg-paper text-[11px] leading-snug text-foreground shadow-lg z-50 normal-case tracking-normal pointer-events-none"
41
+ >
42
+ {text}
43
+ </span>
44
+ )}
45
+ </span>
46
+ );
47
+ }
web/src/components/ParamsPanel.tsx CHANGED
@@ -1,4 +1,5 @@
1
  import type { ParamSpec } from "@/lib/api";
 
2
 
3
  type Props = {
4
  specs: ParamSpec[];
@@ -6,6 +7,15 @@ type Props = {
6
  onChange: (next: Record<string, unknown>) => void;
7
  };
8
 
 
 
 
 
 
 
 
 
 
9
  function renderControl(
10
  s: ParamSpec,
11
  values: Record<string, unknown>,
@@ -17,7 +27,7 @@ function renderControl(
17
  const v = (values[s.name] ?? s.default) as number;
18
  return (
19
  <div key={s.name} className="space-y-1.5">
20
- <label htmlFor={id} className="label-mono">{s.label}</label>
21
  <div className="flex flex-wrap items-center gap-x-3 gap-y-2">
22
  <input
23
  id={id}
@@ -40,9 +50,6 @@ function renderControl(
40
  <span className="label-mono text-muted-foreground">(random per generate)</span>
41
  )}
42
  </div>
43
- {s.help && (
44
- <p className="text-[11px] text-muted-foreground/80 italic">{s.help}</p>
45
- )}
46
  </div>
47
  );
48
  }
@@ -51,7 +58,7 @@ function renderControl(
51
  return (
52
  <div key={s.name} className="space-y-1.5">
53
  <div className="flex items-baseline justify-between">
54
- <label htmlFor={id} className="label-mono">{s.label}</label>
55
  <span className="font-mono text-[12px] text-foreground tracking-wider">
56
  {Number.isFinite(n) ? n.toFixed(2) : String(current)}
57
  </span>
@@ -67,20 +74,13 @@ function renderControl(
67
  onChange={(e) => set(s.name, Number(e.target.value))}
68
  className="w-full accent-[hsl(var(--ember))]"
69
  />
70
- {s.help && (
71
- <p className="text-[11px] text-muted-foreground/80 italic">{s.help}</p>
72
- )}
73
  </div>
74
  );
75
  }
76
  if (s.type === "bool") {
77
  return (
78
- <label
79
- key={s.name}
80
- htmlFor={id}
81
- className="flex items-center justify-between cursor-pointer"
82
- >
83
- <span className="label-mono">{s.label}</span>
84
  <input
85
  id={id}
86
  aria-label={s.label}
@@ -89,12 +89,12 @@ function renderControl(
89
  onChange={(e) => set(s.name, e.target.checked)}
90
  className="accent-[hsl(var(--ember))]"
91
  />
92
- </label>
93
  );
94
  }
95
  return (
96
  <div key={s.name} className="space-y-1.5">
97
- <label htmlFor={id} className="label-mono block">{s.label}</label>
98
  <select
99
  id={id}
100
  aria-label={s.label}
 
1
  import type { ParamSpec } from "@/lib/api";
2
+ import InfoTip from "@/components/InfoTip";
3
 
4
  type Props = {
5
  specs: ParamSpec[];
 
7
  onChange: (next: Record<string, unknown>) => void;
8
  };
9
 
10
+ function ParamLabel({ id, label, help }: { id: string; label: string; help?: string }) {
11
+ return (
12
+ <span className="inline-flex items-center gap-1.5">
13
+ <label htmlFor={id} className="label-mono">{label}</label>
14
+ {help && <InfoTip text={help} />}
15
+ </span>
16
+ );
17
+ }
18
+
19
  function renderControl(
20
  s: ParamSpec,
21
  values: Record<string, unknown>,
 
27
  const v = (values[s.name] ?? s.default) as number;
28
  return (
29
  <div key={s.name} className="space-y-1.5">
30
+ <ParamLabel id={id} label={s.label} help={s.help} />
31
  <div className="flex flex-wrap items-center gap-x-3 gap-y-2">
32
  <input
33
  id={id}
 
50
  <span className="label-mono text-muted-foreground">(random per generate)</span>
51
  )}
52
  </div>
 
 
 
53
  </div>
54
  );
55
  }
 
58
  return (
59
  <div key={s.name} className="space-y-1.5">
60
  <div className="flex items-baseline justify-between">
61
+ <ParamLabel id={id} label={s.label} help={s.help} />
62
  <span className="font-mono text-[12px] text-foreground tracking-wider">
63
  {Number.isFinite(n) ? n.toFixed(2) : String(current)}
64
  </span>
 
74
  onChange={(e) => set(s.name, Number(e.target.value))}
75
  className="w-full accent-[hsl(var(--ember))]"
76
  />
 
 
 
77
  </div>
78
  );
79
  }
80
  if (s.type === "bool") {
81
  return (
82
+ <div key={s.name} className="flex items-center justify-between">
83
+ <ParamLabel id={id} label={s.label} help={s.help} />
 
 
 
 
84
  <input
85
  id={id}
86
  aria-label={s.label}
 
89
  onChange={(e) => set(s.name, e.target.checked)}
90
  className="accent-[hsl(var(--ember))]"
91
  />
92
+ </div>
93
  );
94
  }
95
  return (
96
  <div key={s.name} className="space-y-1.5">
97
+ <ParamLabel id={id} label={s.label} help={s.help} />
98
  <select
99
  id={id}
100
  aria-label={s.label}