How to build a systematically varied, EN/DE-paired speech corpus for every reference voice, and why every constant in it is the value it is.
The one-sentence version. For each of ~6,000 reference speaking voices, generate a large, systematically varied set of speech clips — every emotion at four intensity and containment settings, every voice-quality dimension at four levels, a set of hard edge cases, plus sports-commentary and explicit-register variants — in English and in German using the same sentence, and store every candidate with its full measurement record.
Why the same sentence in both languages matters. Suppose you want to train a model that hears German speech and produces the same person saying the same thing in English, still angry, still holding it in, still at the same speaking rate. To learn that, the model needs paired examples where only the language changes. Everything else — who is speaking, what they feel, how strongly, how contained, how fast — must be held fixed. That is exactly what this corpus is: for one voice, one emotion, one intensity setting, you get an English take and a German take of the same meaning. The model can then learn “translate the words, keep the person and the performance”, because the data shows it that pairing thousands of times.
Why so many conditions. A speech-to-speech model that only ever saw neutral speech will translate an argument into a weather report. Sweeping 40 emotions x 4 settings and 57 voice dimensions x 4 levels gives dense coverage of the space of deliveries, not just its centre. Each cell also carries a measured label for what actually came out, so the corpus can be filtered or re-weighted later without regenerating anything.
How a clip is made, mechanically. A 4.55 B speech model
(laion/moss-tts-local-transformer-4.55b-voice-acting-v2) is given three things: a reference wav of the target
voice, a caption describing the delivery, and the words to say. Small trained
adapters (LoRAs) are merged into the model at a chosen strength to push it toward a specific
emotion or voice quality. It generates 200 candidates; every candidate is measured by
a stack of sensors; the candidates are ranked; all of them are kept.
audio_codes_list — reference-conditioned and unconditioned, at every token
budget. The worker detects and counts empty decodes rather than assuming a token fix
worked.| block | conditions | groups | source of the settings |
|---|---|---|---|
| emotion | 40 emotions × {intense, moderate} × {free, contained} × {EN, DE} | 320 | emotion-voice-conditions/voice0.html + contained.html |
| VoiceNet | 57 dimensions × 4 levels × {EN, DE} | 456 | moss-voicenet-manual/site/dims (5-dose sweep per dim and direction) |
| edge cases | (8 from voice0.html + 6 from the edge-case GA) × {EN, DE} | 28 | voice0.html carriers; moss-emotion-edgecase-evolution hall-of-fame genomes |
| sports | 1 × {EN, DE} | 2 | laion/moss-sports-commentator-lora real_r64_e8 |
| explicitness | 1 × {EN, DE}, safety-gated | 2 | TTS-AGI/moss-explicitness-loras aesthetic_mix_r32 |
| total | 808 |
A group is one cell of the matrix. Each group produces 200 candidates in the demo and 32 in production — 32 because a measured sweep found batch 16→32 flat in wall time on a GH200 (20.34 s → 20.54 s, +4.5 % reward) while 32→64 costs 3.4×.
The four emotion conditions follow the published A/B/C/D definitions:
| intensity | containment | published sublabel | emotion LoRA lambda | |
|---|---|---|---|---|
| A | intense | free-flowing | maximum emotion, freely let out | per-emotion (table in §6) |
| B | moderate | free-flowing | mild emotion, freely expressed | 0.5 |
| C | intense | contained | very strong but held back — it leaks through | per-emotion (table in §6) |
| D | moderate | contained | mild, quietly controlled | 0.5 |
Published pooled statistics for the four conditions (240 cells each, 6 voices): A emo 0.437 / genu 0.362 / spk 0.569, 41 of 240 below the identity floor · B 0.273 / 0.400 / 0.617, 6 · C 0.294 / 0.265 / 0.559, 48 · D 0.185 / 0.326 / 0.617, 6. Intensity, not containment, is what breaks the voice clone: A and C carry 89 of the 113 flags. C also costs the most genuineness.
Source: TTS-AGI/moss-reference-voices-consolidated — 12 WebDataset shards
(data/voices-NNNN.tar, ~505 voices each) plus annotations/ and
metadata.parquet. 6,064 voices, each present in three variants:
orig, sidon (SIDON speech enhancement) and cbx
(Chatterbox voice-conversion to itself).
Variant choice: highest DNSMOS ovrl_mos. Recomputed here from the shipped
annotations/dnsmos.json rather than taken from the best_version column,
so the rule is auditable; the two agree on 100 % of voices. Distribution of winners:
orig 2,317 (38.2 %),
sidon 1,940 (32.0 %),
cbx 1,807 (29.8 %).
Mean DNSMOS is essentially identical across the three (3.343 / 3.346 / 3.344) — the
enhancement does not raise the mean, it changes which clips are best, which is exactly
why the choice is made per voice.
All metadata is carried forward: cid, name, gender, age, language, accent,
tagline, tags, source, all three DNSMOS values, the chosen variant, the shard, and the 99
precomputed annotation dimensions (40 EmoNet + 57 VoiceNet + genuineness + blend) for both the
original and the enhanced version.
Chatterbox voice conversion (LAION-AI/chatterbox-voice-conversion,
from chatterbox_vc.convert import VoiceConverter) is available as an identity
repair. Measured over 68 converted parts it moved similarity 0.755 → 0.820 (improved
on 88 %) with DNSMOS 3.30 → 3.35 — no net quality cost. It is applied only
when identity has actually drifted below 0.45, and kept only if
sim_after > sim_before and
dnsmos_after ≥ dnsmos_before − 0.15.
| test | threshold | source | what it catches |
|---|---|---|---|
| Empathic-Insight / EmoNet Age head | ≥ 2.0 | laion/Empathic-Insight-Voice-Plus :: model_Age_best.pth, scale 0 = infant, 2 = teenager, 4 = adult, 6 = very old | measured on the reference audio itself |
| VoiceNet AGEV | ≥ 2.4 | laion/voicenet-dimension-predictors-commercial :: dimensions.py | voices that read young despite an adult card |
character card age string | no child/teen term | metadata.parquet, human-written | removes all 405 card-labelled minors outright |
The taxonomy anchors put AGEV level 2 at adolescent and level 3 at peak adult vigour, which reads like a 3.00 cutoff. But the regressor is measurably biased low against this dataset's own human-written age cards: voices whose card says “late 20s to mid-30s” have a median AGEV of 2.63, and “early to mid-20s” a median of 2.30. A 3.00 cutoff is therefore not conservative, it is miscalibrated.
Calibrated against all 6,064 reference voices (405 cards naming a child or teenager, 5,642 naming an adult age), AGEV separates the two at AUC 0.843 — useful, but not clean enough to gate on alone, which is precisely why the gate is conjunctive:
| AGEV cutoff | card-labelled minors excluded | card-labelled adults lost | whole pool excluded |
|---|---|---|---|
| 1.90 | 55.1 % | 11.4 % | 14.4 % |
| 2.40 ← chosen | 82.2 % | 25.9 % | 23.2 % |
| 3.00 | 92.8 % | 49.3 % | 52.3 % |
Under the combined pre-gate (card string + AGEV ≥ 2.4), 4,187 of 6,064 (69.0 %) voices are eligible for the explicitness group. The Empathic-Insight Age head then runs on the actual reference audio in the worker and can still veto.
On the demo voice: EI-Age 3.10, VoiceNet AGEV 4.72, card 'Late 40s to 60s' → explicitness ALLOWED.
Source: HuggingFaceFW/finetranslations, subset data/deu_Latn/ (230
parquets). Each row is a document: og_full_text is the German original,
translated_text the English translation, with og_chunks /
translated_chunks giving chunk-level alignment.
subsets.csv is a
language table (534 rows: subset_name, num_documents, num_english_tokens,
filesize_bytes) — it contains no topical taxonomy, and neither do the parquet
columns. A domain label therefore has to be derived. Here it is derived from the source
URL host plus a keyword lexicon over the English side; both the label and which of the two rules
produced it are stored, so the labelling can be audited or replaced without re-sampling any
text.Filters: og_language_score ≥ 0.95; equal chunk counts EN/DE; equal
sentence counts within a chunk; 12–80 words on both sides; length ratio within
2×; no markup, URLs or long digit runs; must start with a capital; de-duplicated on a hash
of the English side.
Balance achieved over 4,000 pairs — sampled with an equal per-domain quota rather than proportionally, which is what stops news and academic text dominating:
| domain | pairs | share |
|---|---|---|
| medicine_health | 290 | 7.2 % |
| arts_culture | 287 | 7.2 % |
| general | 287 | 7.2 % |
| business_finance | 286 | 7.2 % |
| academic | 285 | 7.1 % |
| education_howto | 285 | 7.1 % |
| fiction_personal | 285 | 7.1 % |
| food_cooking | 285 | 7.1 % |
| government_law | 285 | 7.1 % |
| news | 285 | 7.1 % |
| religion_philosophy | 285 | 7.1 % |
| sports | 285 | 7.1 % |
| technology | 285 | 7.1 % |
| travel_geography | 285 | 7.1 % |
English side: mean 23.3 words, median 21, max 80. Each voice draws its 99 slots round-robin across domains, so one voice's corpus spans the taxonomy instead of clustering.
Adapter: TTS-AGI/moss-emotion-loras-v3, subfolder=<EmotionSlug>, one
rank-64 adapter per emotion. Scaffold: TTS-AGI/moss-character-loras-refined-public :: human at
1.0 under both the free and the contained take — the
published contained-emotion recipe puts it under both so the pair differs only in the
containment layer.
Containment is masking, not turning the emotion down. The emotion adapter stays
present; VoiceNet VULN (Vulnerability) is pushed below a matched free take with
vn_VULN__low. Containment is a contrast, never an absolute. The primary
knob wants a trace, 0.06–0.18, not a dose; Emotional_Numbness above
~0.05 and vn_TENS__high above ~0.06 are traps that armour the voice instead of
containing it.
| family | contained auxiliary adapters | containment cue (verbatim) |
|---|---|---|
| anger | vn_VULN__low@0.12 | (restrained and civil, the irritation tucked under the words, keeping control by effort, a small bite only on the final words) |
| cognitive | vn_VULN__low@0.08 + vn_COGL__high@0.05 | (quietly occupied and keeping most of it to yourself, tiny natural pauses, calm on the surface, still real and conversational) |
| joy | vn_VULN__low@0.16 + vn_WARM__high@0.12 | (trying not to show how much this moves you, smile barely audible, warm, composed, private, natural, not cinematic) |
| fear | vn_VULN__low@0.1 + vn_COGL__high@0.07 | (speaking coolly on purpose, jaw tight, trying very hard not to sound terrified, the fear still audible underneath) |
| sadness | vn_VULN__low@0.08 | (the sadness held back behind practical focus, holding it together by concentrating on the facts, a small swallowed catch, natural not flat) |
Free takes instead get vn_VULN__high@0.22
with the cue (letting it out / not hiding it, warm and open, emotionally reachable, unguarded).
vn_COGL__high and must never get Emotional_Numbness.
Joy wants a little vn_WARM__high. Sadness resists masking: measured
ΔVULN reaches −3.44 but the sadness itself drops −1.07, so the honest
deliverable for sadness is the open take — contained sadness is generated anyway, and
labelled, so the effect is visible in the data rather than hidden by a design decision.
Moderate contains, intense flattens: under masking, emotion rose at moderate
(anger +0.31, cognitive +0.26) and eroded at intense (cognitive −0.35, sadness
−0.27, anger −0.22).λ intense from emotion-voice-conditions/voice0.html
(identical for A and C). λ moderate is 0.5 flat for B and D. Sampling is the evolved
setting from the per-emotion manual page. “λ best reward” is that page's own
best-merge figure, which optimises reward rather than emotion strength — it is recorded so
an ablation is possible, but the corpus uses the intense/moderate column.
| emotion | λ intense (A,C) | λ moderate (B,D) | family | temp | top_p | top_k | λ best reward |
|---|---|---|---|---|---|---|---|
Affection | 0.75 | 0.5 | joy | 0.9 | 0.95 | 25 | 0.5 |
Amusement | 1.5 | 0.5 | joy | 1.1 | 0.95 | 30 | 1.5 |
Anger | 1.9 | 0.5 | anger | 1.0 | 0.9 | 40 | 0.5 |
Astonishment_Surprise | 1.5 | 0.5 | cognitive | 1.0 | 0.95 | 25 | 1.5 |
Awe | 0.5 | 0.5 | joy | 1.1 | 0.95 | 25 | 0.5 |
Bitterness | 1.0 | 0.5 | anger | 0.9 | 0.95 | 25 | 0.5 |
Concentration | 1.9 | 0.5 | cognitive | 0.9 | 0.95 | 25 | 0.5 |
Confusion | 1.9 | 0.5 | cognitive | 1.0 | 0.9 | 30 | 0.5 |
Contemplation | 1.25 | 0.5 | cognitive | 1.1 | 0.95 | 25 | 0.5 |
Contempt | 1.5 | 0.5 | anger | 1.1 | 0.9 | 30 | 0.5 |
Contentment | 1.0 | 0.5 | joy | 1.0 | 0.9 | 40 | 0.5 |
Disappointment | 0.5 | 0.5 | sadness | 1.1 | 0.9 | 40 | 1.5 |
Disgust | 1.5 | 0.5 | anger | 1.05 | 0.95 | 30 | 0.5 |
Distress | 1.5 | 0.5 | fear | 0.9 | 0.95 | 25 | 1.0 |
Doubt | 1.0 | 0.5 | cognitive | 1.15 | 0.9 | 25 | 0.5 |
Elation | 1.25 | 0.5 | joy | 1.05 | 0.9 | 25 | 0.5 |
Embarrassment | 1.75 | 0.5 | fear | 1.05 | 0.9 | 30 | 0.5 |
Emotional_Numbness | 1.5 | 0.5 | sadness | 0.8 | 0.9 | 40 | 0.5 |
Fatigue_Exhaustion | 1.9 | 0.5 | sadness | 1.1 | 0.95 | 25 | 0.5 |
Fear | 1.75 | 0.5 | fear | 0.85 | 0.9 | 40 | 0.5 |
Helplessness | 1.9 | 0.5 | fear | 0.9 | 0.9 | 25 | 0.5 |
Hope_Enthusiasm_Optimism | 1.75 | 0.5 | joy | 1.0 | 0.9 | 25 | 1.5 |
Impatience_and_Irritability | 1.9 | 0.5 | anger | 1.0 | 0.9 | 25 | 0.5 |
Infatuation | 1.0 | 0.5 | joy | 1.1 | 0.95 | 40 | 0.5 |
Interest | 0.5 | 0.5 | cognitive | 1.15 | 0.95 | 40 | 0.5 |
Intoxication_Altered_States_of_Consciousness | 1.75 | 0.5 | fear | 1.0 | 0.9 | 30 | 0.5 |
Jealousy_and_Envy | 0.75 | 0.5 | anger | 1.15 | 0.95 | 25 | 0.5 |
Longing | 1.5 | 0.5 | sadness | 1.05 | 0.9 | 25 | 0.5 |
Malevolence_Malice | 1.5 | 0.5 | anger | 1.05 | 0.9 | 40 | 0.5 |
Pain | 1.9 | 0.5 | fear | 1.0 | 0.9 | 25 | 0.5 |
Pleasure_Ecstasy | 0.5 | 0.5 | joy | 1.15 | 0.9 | 25 | 1.5 |
Pride | 1.0 | 0.5 | joy | 1.05 | 0.95 | 25 | 0.5 |
Relief | 1.25 | 0.5 | joy | 1.2 | 0.95 | 30 | 1.0 |
Sadness | 1.25 | 0.5 | sadness | 1.0 | 0.95 | 40 | 1.0 |
Sexual_Lust | 1.5 | 0.5 | joy | 1.0 | 0.95 | 25 | 0.5 |
Shame | 1.25 | 0.5 | fear | 0.9 | 0.95 | 25 | 0.5 |
Sourness | 1.25 | 0.5 | anger | 1.2 | 0.9 | 30 | 0.5 |
Teasing | 1.75 | 0.5 | joy | 1.2 | 0.95 | 30 | 0.5 |
Thankfulness_Gratitude | 0.5 | 0.5 | joy | 1.05 | 0.9 | 40 | 0.5 |
Triumph | 1.75 | 0.5 | joy | 0.9 | 0.95 | 30 | 0.5 |
(1−WER) factor (correlation +0.91 to +0.98) rather than
by emotion. The evolved prompt is used as well — so every take is
“BASE_P + LoRA”, the union of both best practices — and every
component is stored separately so the ablation can be run later without regenerating
anything.Adapter: laion/moss-voicenet-dimension-loras, 114 adapters named
vn_<CODE>__high / vn_<CODE>__low.
BKGN which has 5 and EXPL which has 3 — and (b) a caption
generator using the adverb ladder extremely > very > notably > somewhat. The four
requested levels are therefore realised as a dose ladder on the measured best dose, with
the caption built from the taxonomy's own anchor for the corresponding level:
| level | adapter direction | dose | target anchor level (7-level dims) | adverb |
|---|---|---|---|---|
| extremely low | __low | 100 % of the measured best low dose | 0 | extremely |
| moderately low | __low | 40 % | 2 | somewhat |
| moderately high | __high | 40 % | 4 | notably |
| very high | __high | 100 % of the measured best high dose | 6 | very |
The 40 % step is used because the published per-dimension sweeps (25/50/75/100/125 %) are monotone in the target score, so a fraction of the best dose is the documented way to ask for some rather than all of a dimension. For the 5-level and 3-level dimensions the ladder is mapped proportionally (0/1/3/4 and 0/1/1/2), which is why a hard-coded 0/2/4/6 was replaced by a fractional map.
| code | name | levels | best low dose | best high dose | doses used: xlow / modlow / modhigh / vhigh |
|---|---|---|---|---|---|
TEMP | Tempo | 7 | 0.75 | 1.25 | 0.75 / 0.3 / 0.5 / 1.25 |
CHNK | Chunking | 7 | 0.5 | 1.25 | 0.5 / 0.2 / 0.5 / 1.25 |
SMTH | Smoothness | 7 | 1.25 | 1.25 | 1.25 / 0.5 / 0.5 / 1.25 |
CLRT | Articulation Clarity | 7 | 0.75 | 1.25 | 0.75 / 0.3 / 0.5 / 1.25 |
RANG | Pitch Range | 7 | 1.25 | 1.25 | 1.25 / 0.5 / 0.5 / 1.25 |
EMPH | Emphasis | 7 | 1.0 | 1.0 | 1.0 / 0.4 / 0.4 / 1.0 |
DFLU | Disfluency | 7 | 1.25 | 1.25 | 1.25 / 0.5 / 0.5 / 1.25 |
STRU | Structure | 7 | 1.0 | 1.25 | 1.0 / 0.4 / 0.5 / 1.25 |
STNC | Stance | 7 | 1.25 | 1.25 | 1.25 / 0.5 / 0.5 / 1.25 |
FOCS | Focus | 7 | 1.25 | 1.25 | 1.25 / 0.5 / 0.5 / 1.25 |
VULN | Vulnerability | 7 | 1.25 | 1.25 | 1.25 / 0.5 / 0.5 / 1.25 |
GEND | Perceived Gender | 7 | 1.25 | 1.25 | 1.25 / 0.5 / 0.5 / 1.25 |
AGEV | Voice Age | 7 | 1.25 | 1.0 | 1.25 / 0.5 / 0.4 / 1.0 |
REGS | Register | 7 | 1.0 | 1.25 | 1.0 / 0.4 / 0.5 / 1.25 |
VALN | Valence | 7 | 0.25 | 1.25 | 0.25 / 0.1 / 0.5 / 1.25 |
AROU | Arousal | 7 | 0.5 | 1.0 | 0.5 / 0.2 / 0.4 / 1.0 |
VOLT | Volatility | 7 | 0.75 | 1.25 | 0.75 / 0.3 / 0.5 / 1.25 |
RESP | Respiration | 7 | 1.25 | 1.0 | 1.25 / 0.5 / 0.4 / 1.0 |
TENS | Tension | 7 | 0.25 | 1.25 | 0.25 / 0.1 / 0.5 / 1.25 |
COGL | Cognitive Load | 7 | 1.0 | 1.0 | 1.0 / 0.4 / 0.4 / 1.0 |
ATCK | Attack | 7 | 0.5 | 1.25 | 0.5 / 0.2 / 0.5 / 1.25 |
BRGT | Brightness | 7 | 0.5 | 1.0 | 0.5 / 0.2 / 0.4 / 1.0 |
ROUG | Roughness | 7 | 0.5 | 1.25 | 0.5 / 0.2 / 0.5 / 1.25 |
HARM | Harmonicity | 7 | 1.25 | 1.25 | 1.25 / 0.5 / 0.5 / 1.25 |
FULL | Fullness | 7 | 0.75 | 1.25 | 0.75 / 0.3 / 0.5 / 1.25 |
WARM | Warmth | 7 | 1.25 | 1.25 | 1.25 / 0.5 / 0.5 / 1.25 |
METL | Metallic Character | 7 | 0.75 | 1.0 | 0.75 / 0.3 / 0.4 / 1.0 |
ESTH | Esthetics | 7 | 1.0 | 1.25 | 1.0 / 0.4 / 0.5 / 1.25 |
VFLX | Velocity Flux | 7 | 1.0 | 1.25 | 1.0 / 0.4 / 0.5 / 1.25 |
DARC | Dynamic Arc | 7 | 0.25 | 1.25 | 0.25 / 0.1 / 0.5 / 1.25 |
ARSH | Arousal Shift | 7 | 1.25 | 1.0 | 1.25 / 0.5 / 0.4 / 1.0 |
VALS | Valence Shift | 7 | 1.25 | 1.0 | 1.25 / 0.5 / 0.4 / 1.0 |
RCQL | Recording Quality | 7 | 1.25 | 1.25 | 1.25 / 0.5 / 0.5 / 1.25 |
BKGN | Background Noise | 5 | 0.5 | 1.0 | 0.5 / 0.2 / 0.4 / 1.0 |
EXPL | Content Appropriateness (3-point Scale) | 3 | 0.5 | 1.25 | 0.5 / 0.2 / 0.5 / 1.25 |
R_CHST | Chest Resonance | 7 | 0.5 | 1.25 | 0.5 / 0.2 / 0.5 / 1.25 |
R_THRT | Throat Resonance | 7 | 0.75 | 1.25 | 0.75 / 0.3 / 0.5 / 1.25 |
R_ORAL | Oral Resonance | 7 | 1.0 | 1.0 | 1.0 / 0.4 / 0.4 / 1.0 |
R_MASK | Mask Resonance | 7 | 0.5 | 1.25 | 0.5 / 0.2 / 0.5 / 1.25 |
R_NASL | Nasal Resonance | 7 | 0.25 | 1.0 | 0.25 / 0.1 / 0.4 / 1.0 |
R_HEAD | Head Resonance | 7 | 0.25 | 1.25 | 0.25 / 0.1 / 0.5 / 1.25 |
R_MIXD | Mixed Resonance | 7 | 0.25 | 1.25 | 0.25 / 0.1 / 0.5 / 1.25 |
S_CASU | Casual Style | 7 | 1.25 | 1.25 | 1.25 / 0.5 / 0.5 / 1.25 |
S_CONV | Conversational Style | 7 | 1.25 | 1.25 | 1.25 / 0.5 / 0.5 / 1.25 |
S_FORM | Formal Style | 7 | 1.0 | 1.25 | 1.0 / 0.4 / 0.5 / 1.25 |
S_DRAM | Dramatic Style | 7 | 1.25 | 1.0 | 1.25 / 0.5 / 0.4 / 1.0 |
S_NARR | Narrator Style | 7 | 1.25 | 1.25 | 1.25 / 0.5 / 0.5 / 1.25 |
S_NEWS | Newsreader Style | 7 | 0.5 | 1.25 | 0.5 / 0.2 / 0.5 / 1.25 |
S_TECH | Teacher/Didactic Style | 7 | 0.25 | 1.25 | 0.25 / 0.1 / 0.5 / 1.25 |
S_AUTH | Authoritative Style | 7 | 0.25 | 1.25 | 0.25 / 0.1 / 0.5 / 1.25 |
S_PLAY | Playful Style | 7 | 0.75 | 1.25 | 0.75 / 0.3 / 0.5 / 1.25 |
S_CART | Cartoonish Style | 7 | 0.5 | 1.25 | 0.5 / 0.2 / 0.5 / 1.25 |
S_ASMR | ASMR Style | 7 | 1.25 | 1.25 | 1.25 / 0.5 / 0.5 / 1.25 |
S_WHIS | Whisper-Talk Style | 7 | 1.0 | 1.0 | 1.0 / 0.4 / 0.4 / 1.0 |
S_RANT | Ranting/Angry Style | 7 | 0.25 | 1.25 | 0.25 / 0.1 / 0.5 / 1.25 |
S_STRY | Storytelling Style | 7 | 1.25 | 1.0 | 1.25 / 0.5 / 0.4 / 1.0 |
S_MONO | Monologue Style | 7 | 1.25 | 0.75 | 1.25 / 0.5 / 0.3 / 0.75 |
Fourteen per language: 8 from emotion-voice-conditions/voice0.html (carrier
line and λ as published) and 6 hall-of-fame genomes from
moss-emotion-edgecase-evolution (a genetic search, population 24, 6 generations,
elitism 8, best-of-4 per genome; mean LoRA lift +0.147). The GA genomes are used
verbatim: their GENERAL text, delivery cue, inline burst tags, carrier line, λ and
sampling are the winning genome, not a paraphrase.
| source | id | emotion adapter | λ* | burst tags | carrier (EN) |
|---|---|---|---|---|---|
| voice0.html | fear_scream | emo_Fear | 0.75 | — | No, no, please stay back, do not come any closer to me, oh god, somebody, anybody, please … |
| voice0.html | pain_scream | emo_Pain | 0.75 | — | My leg, my leg, something is horribly wrong with it, I cannot move at all, oh it hurts, it… |
| voice0.html | pain_groan | emo_Pain | 0.75 | — | Just give me a moment here, do not touch it, every little movement sends this deep, grindi… |
| voice0.html | cold_shiver | emo_Fear | 0.5 | — | I have been out here in the freezing snow for hours now, I cannot feel my hands anymore, p… |
| voice0.html | amused_laughter | emo_Amusement | 1.0 | — | Wait, wait, you actually said that to his face, in front of everyone, oh that is honestly … |
| voice0.html | sad_crying | emo_Sadness | 0.75 | — | I really thought this time would finally be different for us, but it is over now, and I ju… |
| voice0.html | whimpering | emo_Fear | 0.6 | — | Please do not leave me here all alone in the dark like this, I am so scared and I do not k… |
| voice0.html | tears | emo_Pain | 0.75 | — | It hurts so much and I cannot make it stop, I have tried everything I can think of, please… |
| edge-case GA | ga_fear_scream | emo_Fear | 0.75 | <terrified scream><screaming> | Help me. Somebody, please. |
| edge-case GA | ga_pain_scream | emo_Pain | 0.75 | <cry of pain><screams in pain> | I can't - I can't do this anymore. |
| edge-case GA | ga_sad_cry | emo_Sadness | 0.75 | <whimpers><voice breaks> | I can't - I can't do this anymore. |
| edge-case GA | ga_cold_shiver | emo_Fear | 0.5 | [shivers]<trembling breath> | P-please, I need to get warm. |
| edge-case GA | ga_pain_groan | emo_Pain | 0.75 | <pained grunt> | Help me. Somebody, please. |
| edge-case GA | ga_amuse_laugh | emo_Amusement | 1.5 | <giggles><warm laughter> | I can't believe you just said that. |
tokens defaults to the word
count, and a scream carrier has almost no words — which is how a scream group ends up
asking for ~5 tokens and producing 0.3 s of audio. Edge groups are sized by intended
duration at 12.5 tokens per second, with
max_new_frames raised to 1.6× the token budget. The German carriers for the
edge cases are fixed translations held in the spec, because for these groups the carrier line
is the content and must not vary.Published cross-voice identity for these cells, worst first: fear scream 0.504 · laughter 0.525 · pain groan 0.564 · pain scream 0.592 · cold shiver 0.594 · whimpering 0.598 · crying 0.599 · tears 0.639. Loud extremes clone worst; quiet extremes clone best.
Sports: laion/moss-sports-commentator-lora, checkpoint real_r64_e8
at λ 1.0. The real-data-only checkpoint beat the mixed one on
11 of 12 prompts (Wilcoxon p = 0.0010; judge 1.979 vs 1.891, arousal 4.633 vs
3.914, WER 0.066 vs 0.061, n.s.), which is why real_r64_e8 is used rather than the
otherwise-tempting r64_e8.
Explicitness: TTS-AGI/moss-explicitness-loras, checkpoint
aesthetic_mix_r32 at λ 0.8, sampling
temp 0.9 / top_p 0.95 /
top_k 35 — the rank-32 aesthetic mix, which won the published raw
sweep, in the 0.2–1.0 blend band. Gated by §4.
The processor is driven exactly like this. instruction holds the WHOLE
GENERAL: … SCRIPT: … caption; text holds ONLY the spoken
words. An empty field renders as the literal string "None".
from transformers import AutoModel, AutoProcessor # AutoModel, NOT AutoModelForCausalLM
proc = AutoProcessor.from_pretrained("laion/moss-tts-local-transformer-4.55b-voice-acting-v2",
trust_remote_code=True,
codec_path="OpenMOSS-Team/MOSS-Audio-Tokenizer-v2")
proc.audio_tokenizer = proc.audio_tokenizer.to("cuda").eval()
base = AutoModel.from_pretrained("laion/moss-tts-local-transformer-4.55b-voice-acting-v2", trust_remote_code=True,
dtype=torch.bfloat16, attn_implementation="sdpa").cuda().eval()
# the missing audio_lm_heads.* / text_lm_head.weight warnings on load are BENIGN
msg = proc.build_user_message(text=spoken_words_only,
instruction=whole_GENERAL_SCRIPT_caption,
language="English", # or "German"
reference=[ref_wav_path],
tokens=n_tokens) # defaults to the WORD COUNT
batch = proc([[msg]], mode="generation")
out = net.generate(input_ids=batch["input_ids"].cuda(),
attention_mask=batch["attention_mask"].cuda(),
max_new_frames=400, do_sample=True,
text_temperature=0.7, text_top_k=50, text_top_p=1.0,
audio_temperature=T, audio_top_p=P, audio_top_k=K,
audio_repetition_penalty=1.1)
for m in proc.decode(out):
if not m.audio_codes_list: # DETECT this. Never assume a token fix worked.
empty += 1; continue
base_scaling = {nm: dict(m.scaling) for nm, m in pm.named_modules()
if isinstance(m, LoraLayer)} # captured ONCE, after loading
pm.base_model.enable_adapter_layers()
pm.base_model.set_adapter(list(keys)) # base_model, not PeftModel
for nm, m in pm.named_modules():
if isinstance(m, LoraLayer):
for adapter, lam in keys.items():
if adapter in m.scaling:
m.scaling[adapter] = base_scaling[nm][adapter] * lam
PeftModel.set_adapter and base_model.set_adapter do not
take the same argument. This pair is copied verbatim from
$NB/act/code/actworker_v9.py; a hand-rewrite cost a whole nine-job run.
Emotion, condition C (intense + contained), Fear:
GENERAL: A voice powerfully expressing fear, a terrified voice, trembling and breathless, shaking with fear, near screaming, in every breath. The feeling is fought down rather than shown: it is held in and only leaks through at the edges of phrases. SCRIPT: (speaking coolly on purpose, jaw tight, trying very hard not to sound terrified, the fear still audible underneath) "We were supposed to meet at the corner near the old station around six, but the bus was running late again."
VoiceNet, TEMP at “very high”
(vn_TEMP__high@1.25):
GENERAL: A voice very high in tempo. The tempo reaches the absolute human limit of linguistic speed, resulting in a blistering, hyper-accelerated wall of sound. Phonation is extremely dense, causing individual word boundaries to completely blur into a continuous, high-velocity acoustic vibration. SCRIPT: (neutral, natural delivery, exactly as this voice normally speaks) "We were supposed to meet at the corner near the old station around six, but the bus was running late again."
Edge case, GA hall-of-fame genome, fear → screaming:
GENERAL: A horrified voice, blood-curdling, pushed to the extreme edge of scream. SCRIPT: (terrified, screaming, voice cracking with panic) "Help me. Somebody, please." <terrified scream><screaming>
GENERAL lines and delivery cuesThese are the manual's own evolved (BASE_P) prompts, used verbatim for the
intense conditions. For the moderate conditions the intensifier is softened by a fixed
substitution table (overwhelmingly→mildly, intensely→mildly,
deeply→slightly, powerfully→mildly,
utterly→slightly, unmistakably→faintly,
viscerally→slightly, to the extreme→a little) plus one added
sentence, so that A/B and C/D stay comparable in vocabulary. For the contained conditions the
cue below is replaced by the family containment cue from §6 and a containment sentence is
appended to GENERAL.
| emotion | GENERAL (evolved, verbatim) | delivery cue (free conditions) |
|---|---|---|
Affection | A voice intensely expressing affection, a warm, tender voice overflowing with affection, soft and caring, a gentle smile in every word, impossible to hide. | (warmly, tenderly, full of affection) |
Amusement | A voice overwhelmingly expressing amusement, a voice bubbling with amusement, on the edge of laughter, playful and delighted, impossible to hide. | (chuckling, highly amused, barely holding back laughter) |
Anger | A voice overwhelmingly expressing anger, a furious voice, seething and exploding into a rant, sharp, loud and cutting, building and building. | (furious, ranting, exploding with rage) |
Astonishment_Surprise | A voice unmistakably expressing astonishment surprise, a voice struck with astonishment, gasping, utterly surprised, eyes wide, pouring out. | (gasping, astonished, taken completely by surprise) |
Awe | A voice utterly expressing awe, a hushed voice filled with awe and wonder, breath taken away, reverent, impossible to hide. | (in hushed awe and wonder) |
Bitterness | A voice deeply expressing bitterness, a bitter, resentful voice, jaded and sardonic, dripping with disillusion, in every breath. | (bitterly, with jaded resentment) |
Concentration | A voice intensely expressing concentration, a focused, deliberate voice, fully concentrated, measured and precise, raw and unfiltered. | (intensely focused and concentrated) |
Confusion | A voice powerfully expressing confusion, a baffled, disoriented voice, struggling to make sense of things, hesitant and lost, pouring out. | (confused, bewildered, thrown off) |
Contemplation | A voice to the extreme expressing contemplation, a slow, thoughtful voice, deep in contemplation, musing and reflective, in every breath. | (slowly, deep in contemplative thought) |
Contempt | A voice to the extreme expressing contempt, a cold, sneering voice, full of contempt and disdain, looking down with scorn, pouring out. | (with cold, sneering contempt) |
Contentment | A voice utterly expressing contentment, a relaxed, satisfied voice, at peace and content, easy and unhurried, in every breath. | (calmly content and at ease) |
Disappointment | A voice viscerally expressing disappointment, a deflated, let-down voice, heavy with disappointment, quietly crushed, in every breath. | (deeply disappointed, deflated) |
Disgust | A voice intensely expressing disgust, a revolted voice, curling with disgust, repulsed and sickened, in every breath. | (with revulsion and disgust, sickened) |
Distress | A voice powerfully expressing distress, a distressed, anguished voice, tight with panic and pain, on the verge of breaking, in every breath. | (in acute distress and anguish) |
Doubt | A voice powerfully expressing doubt, a skeptical, uncertain voice, hedging and unconvinced, full of doubt, pouring out. | (doubtfully, deeply unconvinced) |
Elation | A voice utterly expressing elation, a soaring, jubilant voice, elated and euphoric, bursting with joy, in every breath. | (elated, euphoric, bursting with joy) |
Embarrassment | A voice unmistakably expressing embarrassment, a flustered, sheepish voice, cheeks burning with embarrassment, awkward and shrinking, impossible to hide. | (flustered and mortified with embarrassment) |
Emotional_Numbness | A voice utterly expressing emotional numbness, a flat, hollow, emotionally numb voice, detached and empty, drained of all feeling, in every breath. | (flatly, hollow and emotionally numb) |
Fatigue_Exhaustion | A voice intensely expressing fatigue exhaustion, a weary, exhausted voice, heavy and dragging, barely able to stay awake, raw and unfiltered. | (utterly exhausted, weary and dragging) |
Fear | A voice powerfully expressing fear, a terrified voice, trembling and breathless, shaking with fear, near screaming, in every breath. | (trembling, terrified, voice shaking with fear) |
Helplessness | A voice unmistakably expressing helplessness, a powerless, defeated voice, pleading and helpless, out of options, impossible to hide. | (helplessly, defeated and powerless) |
Hope_Enthusiasm_Optimism | A voice deeply expressing hope enthusiasm optimism, a bright, hopeful voice, brimming with enthusiasm and optimism, uplifting, impossible to hide. | (brightly, full of hope and enthusiasm) |
Impatience_and_Irritability | A voice utterly expressing impatience and irritability, a tense, irritable voice, snapping with impatience, on a short fuse, pouring out. | (impatiently, irritable and snappy) |
Infatuation | A voice to the extreme expressing infatuation, a dreamy, smitten voice, lovestruck and breathless with infatuation, impossible to hide. | (dreamily infatuated, lovestruck) |
Interest | A voice viscerally expressing interest, a keenly interested voice, leaning in, curious and engaged, with every word. | (keenly interested and curious) |
Intoxication_Altered_States_of_Consciousness | A voice overwhelmingly expressing intoxication altered states of consciousness, a woozy, slurring voice, intoxicated and untethered, in an altered haze, impossible to hide. | (woozy, slurring, intoxicated) |
Jealousy_and_Envy | A voice intensely expressing jealousy and envy, a jealous, envious voice, seething with covetous resentment, bitter and possessive, in every breath. | (with jealous, envious resentment) |
Longing | A voice unmistakably expressing longing, an aching, yearning voice, full of wistful longing, reaching for what is out of reach, with every word. | (with aching, wistful longing) |
Malevolence_Malice | A voice deeply expressing malevolence malice, a menacing, malicious voice, cruel and threatening, savoring the harm, in every breath. | (with cruel, menacing malice) |
Pain | A voice to the extreme expressing pain, a voice wracked with pain, gasping and groaning, near screaming in agony, raw and unfiltered. | (groaning, gasping in pain and agony) |
Pleasure_Ecstasy | A voice intensely expressing pleasure ecstasy, a voice breathless with pleasure and ecstasy, rapturous and overwhelmed, with every word. | (breathless with pleasure and ecstasy) |
Pride | A voice overwhelmingly expressing pride, a proud, self-assured voice, chest swelling with pride, triumphantly boastful, impossible to hide. | (with swelling, self-assured pride) |
Relief | A voice deeply expressing relief, a voice flooding with relief, exhaling the tension, grateful it is finally over, in every breath. | (exhaling in profound relief) |
Sadness | A voice powerfully expressing sadness, a soft, grief-worn voice, heavy and slow, on the edge of tears, impossible to hide. | (quietly, grief-stricken, near tears) |
Sexual_Lust | A voice unmistakably expressing sexual lust, a husky, sultry voice, low and breathy, thick with desire and longing, pouring out. | (huskily, low and breathy with desire) |
Shame | A voice deeply expressing shame, a small, shame-filled voice, cringing and self-reproaching, unable to look up, building and building. | (with cringing shame and self-reproach) |
Sourness | A voice intensely expressing sourness, a sour, grumbling voice, peevish and put-out, curdled with displeasure, with every word. | (sourly, grumbling and peevish) |
Teasing | A voice to the extreme expressing teasing, a playful, teasing voice, sing-song and mischievous, poking fun, pouring out. | (playfully teasing, mischievous) |
Thankfulness_Gratitude | A voice intensely expressing thankfulness gratitude, a warm, heartfelt voice, full of gratitude and thanks, deeply touched, raw and unfiltered. | (warmly, full of heartfelt gratitude) |
Triumph | A voice unmistakably expressing triumph, a triumphant, victorious voice, roaring with the thrill of winning, exultant, in every breath. | (triumphantly, roaring with victory) |
The burst adapters in laion/vocal-burst-lora-adapters (64 classes) are not merged in
this corpus. The edge cases instead carry the GA's inline burst tags in the SCRIPT, which
is what the edge-case search actually optimised. If burst adapters are added later, the measured
operating points are: λ = 0.50 (presence 50.3 %, tail coverage 0.90, joint
0.448 — the peak; at 1.0 presence rises to 72 % but tail coverage collapses to 0.45
and WER to 0.57), the emotion adapter must sit at or below half the burst dose, and the
tag goes inline mid-line with real words after it, never in the first or last
0.45 s. Five classes never fire at any dose: Hiss, Kissing Noises, Lip Smack, Person
Whistling Playfully, Slurping Noises.
Groups are sorted by (block, emotion|dim|edge, condition|level, lang) and each
worker takes a contiguous slice. That matters: with 114 dimension adapters and 40 emotion
adapters, a stride slice (groups[shard::nshards]) would give a worker groups 32
apart in the sorted order, so no two consecutive groups would share an adapter and the LoRA
loader would thrash on every single group. Adapters are loaded lazily with an LRU cap of
24 resident at once.
The base formula is the published one:
core = z(genuineness) + w_blend · z(vocal-burst blend) + 1.25 · z(strength)
[ + 1.0 · z(−VULN) for contained conditions only ]
score = sigmoid(core / 2) · (1 − min(WER,1)) · (0.5 + 0.5 · naturalness)
· (0.81 + 0.19 · clip(spk_sim,0,1)/0.7) · id_mult
All z-scores are taken within the group, over its 200 candidates — which is what makes the components comparable across conditions with wildly different absolute scales.
| term | free conditions (A, B) | contained conditions (C, D) | why |
|---|---|---|---|
w_blend | 1.0 | 0.6 | an audible vocal burst is the emotion escaping, which is the opposite of containment |
| containment term | not applied | +1.0 · z(−VULN) | containment is measured as VULN below the group's own mean, i.e. as a contrast, never as an absolute |
strength (A, C: intense) | target EmoNet score, maximised | target EmoNet score, maximised | intense rows want as much as they can get |
strength (B, D: moderate) | band fitness | band fitness | moderate rows are scored for LANDING inside a band, not for maximising |
strength (VoiceNet block) | signed target-dimension value | — | +1 for a __high group, −1 for a __low group |
Target bands for the moderate rows, and floors for the intense rows, by family:
| family | moderate band | intense floor |
|---|---|---|
| anger | [1.0, 1.9] | 2.4 |
| fear | [0.9, 1.6] | 2.0 |
| sadness | [1.0, 1.8] | 2.3 |
| joy | [0.6, 1.1] | 1.5 |
| cognitive | [0.5, 1.0] | 1.2 |
Naturalness = 0.6 · disfluency-band term + 0.4 · speed-band term. Disfluency: full credit 2.5–4.0, capped at 0.55 below 1.8 (robotic), decaying above 4.0 (a mess). Speed: full credit 2.4–3.3 words/s, penalised on both sides.
Identity enters as a ranking weight of 0.19 and a single hard floor at
0.4 (id_mult = 0.25 below it). Nothing is rejected for
being below 0.58 or 0.68 — the 0.58 threshold only sets a resample_flag in the
group statistics, because with 200 candidates the size of the pool already does the
job the resample loop used to do.
z_genuineness,
z_blend, z_strength, z_containment, strength_raw, core, naturalness, id_mult, w_blend, wer,
spk_sim — so any later re-ranking needs no regeneration. That is not a
nicety: the published post-mortems found (1−WER) correlating +0.91 to +0.98
with the composite while genuineness correlated +0.00, and three of eight terms effectively
dead. A stored-component design is what lets that be fixed after the fact.Every candidate gets a row, including the worst-ranked one. Nothing is discarded.
| columns | what it is |
|---|---|
gid, voice, profile, block, lang, emotion, condition, dim, level, edge | identity of the cell |
text, text_slot, caption, adapters, sampling, mediathek, domain | exactly what was asked for, including the JSON adapter/λ dict |
asr, wer, wps, dur, empty | whisper-large-v3-turbo transcript used for in-loop WER (language forced per group) |
parakeet_text, parakeet_words, parakeet_nwords | Parakeet v3 word-level timestamps, added by the stage-2 pass |
voicenet (57), voicenet_bucket (57) | continuous regression value and ordinal bucket for every dimension |
emonet (40), emo_strength, emo_argmax | Empathic-Insight / EmoNet per-emotion intensities |
genuineness, blend, quality, quality_full | genuineness 0–6, vocal-burst blend 0–10, four quality heads |
voiceclap (768, fp16) | VoiceCLAP-commercial embedding — stored now because regenerating it later is waste |
spk_emb (192, fp16), spk_sim, ref_spk_emb.npy | ECAPA embedding of the candidate, cosine to the reference; the reference embedding is identical for every row so it is stored once per shard |
caption_gen | procedurally generated caption written from what was MEASURED, not from what was asked |
rank, score, z_genuineness, z_blend, z_strength, z_containment, strength_raw, core, naturalness, id_mult, w_blend, contained, moderate | within-group rank and every score component |
vuln, tempo, chunk, dflu, arou, expl, tens, narration, dim_target | the dimensions the ranking actually reads, promoted to top-level columns |
audio_key | the tar member name — the join key to the audio |
out/<voice_cid>/P<profile>/
cands-<shard>.tar # WebDataset: <gid>.c<NNN>.mp3, one member per candidate
cands-<shard>.parakeet.parquet # stage-2 word timestamps, joined on audio_key
meta-<shard>-<ts>.parquet # one row per candidate, schema above
groupstats-<shard>.jsonl # one line per group: timings, empties, best-take summary
throughput-<shard>.json # measured gen/GPU-hour for this shard
ref_spk_emb.npy # the reference ECAPA embedding, stored once
safety_gate.json # the gate decision and its three inputs
shard<NNN>.DONE # idempotent-resume marker
Audio is mono MP3 at 16 kHz. The tar member name is the audio_key column, so
audio and metadata join without a manifest. Shards are written append-only and the worker
re-reads groupstats on restart, so an interrupted job resumes at group
granularity.
| block | groups | candidates | mean gen s/group | mean score s/group | gen / GPU-hour | empty decodes |
|---|---|---|---|---|---|---|
| edge | 56 | 11200 | 329 | 13 | 2,106 | 0.00% |
| emotion | 640 | 128000 | 331 | 13 | 2,092 | 0.01% |
| explicit | 4 | 800 | 312 | 12 | 2,220 | 0.00% |
| sports | 4 | 800 | 157 | 12 | 4,263 | 0.00% |
| voicenet | 912 | 182400 | 322 | 13 | 2,146 | 0.17% |
| all | 1616 | 323200 | 2,126 | 0.10% |
Extrapolating at production settings (32 candidates/group), using the per-block measured rates above rather than a single average — the blocks differ by more than 3× and a single average would flatter the estimate:
| voices | generations | GPU-hours | node-hours (4 GPU/node) | wall-clock h on 64 GPUs | wall-clock h on 256 GPUs | storage TB |
|---|---|---|---|---|---|---|
| 1 | 808 × 32 × 1 = 25,856 | 12 | 3 | 0.2 | 0.0 | 0.0 |
| 100 | 808 × 32 × 100 = 2,585,600 | 1,216 | 304 | 19.0 | 4.8 | 0.3 |
| 1,000 | 808 × 32 × 1,000 = 25,856,000 | 12,164 | 3,041 | 190.1 | 47.5 | 2.9 |
| 6,000 | 808 × 32 × 6,000 = 155,136,000 | 72,982 | 18,246 | 1,140.3 | 285.1 | 17.2 |
One voice costs 12.16 GPU-hours at 32 candidates per group. Storage is measured at 111 kB per candidate (MP3 + parquet row including both embeddings) from the demo artefacts.
It is the voicenet block, and the reason is count, not speed. Measured per-candidate throughput is nearly flat across the blocks — sports 4,263 gen/GPU-h against emotion 2,092, a spread of only 2.04× — so cost tracks the number of groups almost exactly. The voicenet block is 56 % of the matrix and therefore 56 % of the GPU-hours.
That has a useful consequence: there is no clever optimisation hiding here. Nothing is pathologically slow, so the only real lever is generating fewer cells. Halving the voicenet block — two levels instead of four, or the 30 highest-|Δ| dimensions instead of all 57 — takes 28 % straight off the total, and no amount of batching or kernel work will do the same.
Secondary constraint: the scoring stack is 4–5 % of wall time only because the VoiceCLAP embedder is shared across the VoiceNet, genuineness and blend heads — one encode per clip instead of three. Un-sharing it would roughly triple that term.
At the full 808-group matrix, no — not as a single campaign. It is 72,982 GPU-hours, which at 256 GPUs is 285 hours of wall clock of uninterrupted whole-partition time, and it produces 17 TB. That is a program, not a run.
Defensible subset. Three cuts, in the order they should be taken:
NB=/e/data1/datasets/playground/mmlaion/schuhmann1/dramabox
export HF_HOME=$NB HF_HUB_CACHE=$NB/hfcache/.cache/dramabox
# 1. LOGIN NODE ONLY - compute nodes have no internet
$NB/env_transcribe/bin/python $NB/vprof/code/prefetch.py # datasets + LoRA repos
$NB/env_transcribe/bin/python $NB/vprof/code/vpprep.py # voices, text pool, matrix
# 2. GPU - 16 nodes x 4 GPUs, 32 shards x 2 profiles
sbatch --array=0-15 --export=ALL,VOICE=<cid>,CANDS=32,BATCH=32,NSH=32 \
$NB/vprof/code/vprof.sbatch
# 3. stage-2 ASR, in the NeMo venv (never pip-install nemo into env_transcribe)
$NB/env_asr/bin/python $NB/vprof/code/vpasr.py --indir $NB/vprof/out/<cid>/PA
# 4. grid + docs
$NB/env_transcribe/bin/python $NB/vprof/code/vpgrid.py --voice <cid>
$NB/env_transcribe/bin/python $NB/vprof/code/vpdocs.py --voice <cid>
Cluster constraints that are not optional. There is no system python — use
$NB/env_transcribe/bin/python. Compute nodes are offline; run with
HF_HUB_OFFLINE=1 after pre-fetching everything on the login node. Stagger worker
startup by ~150 s on a multi-GPU node: concurrent import transformers from
/e puts every worker into uninterruptible sleep. Never write to
$HOME (~20 GB quota). Launch long jobs from setsid-detached scripts. Never
pip install without --no-deps into this venv — it has been
destroyed that way by a torch downgrade.
| role | repo / package | notes |
|---|---|---|
| base model | laion/moss-tts-local-transformer-4.55b-voice-acting-v2 | load with AutoModel, not AutoModelForCausalLM; bf16; attn_implementation="sdpa" |
| audio codec | OpenMOSS-Team/MOSS-Audio-Tokenizer-v2 | passed to the processor as codec_path= |
| emotion LoRAs | TTS-AGI/moss-emotion-loras-v3 | 40, subfolder = emotion slug |
| VoiceNet dim LoRAs | laion/moss-voicenet-dimension-loras | 114 = 57 × __high/__low |
| character scaffold | TTS-AGI/moss-character-loras-refined-public | subfolder human/ep3 — note the extra epoch level |
| sports | laion/moss-sports-commentator-lora | real_r64_e8 |
| explicitness | TTS-AGI/moss-explicitness-loras | aesthetic_mix_r32 |
| Mediathek (Profile B) | laion/moss-mediathek-emotion-lora | r64_e2 at 0.25 |
| burst LoRAs (not merged) | laion/vocal-burst-lora-adapters | 64 classes |
| reference voices | TTS-AGI/moss-reference-voices-consolidated | dataset, 12 tar shards + annotations |
| text | HuggingFaceFW/finetranslations | dataset, data/deu_Latn/ |
| VoiceNet + captions | laion/voicenet-dimension-predictors-commercial | 57 dims, regression + classification heads, dimensions.py |
| EmoNet / quality / age | laion/Empathic-Insight-Voice-Plus | 40 emotion heads, 4 quality heads, model_Age_best.pth |
| encoder for the heads | laion/BUD-E-Whisper | shared Whisper encoder |
| genuineness | laion/voiceclap-commercial-genuineness | 0–6 |
| burst blend | laion/voiceclap-commercial-vocalburst-blend | 0–10 |
| VoiceCLAP embedding | laion/voiceclap-commercial | 768-d, shared across VoiceNet/genuineness/blend — one encode per clip |
| speaker embedding | speechbrain/spkrec-ecapa-voxceleb | 192-d |
| timbre embedding (evaluated) | Orange/Speaker-wavLM-tbr | AUC 0.794 |
| in-loop ASR / WER | openai/whisper-large-v3-turbo | language forced per group |
| word timestamps | nvidia/parakeet-tdt-0.6b-v3 | stage 2, in env_asr (NeMo 2.7.3); disable the CUDA-graph TDT decoder on GH200 |
| voice conversion | LAION-AI/chatterbox-voice-conversion | from chatterbox_vc.convert import VoiceConverter, 24 kHz out |
| DNSMOS | speechmos | dnsmos.run(x16k, 16000)['ovrl_mos'] |
subsets.csv
is a language table. The URL-host + keyword labeller is ours and is stored per row so it can be
replaced.Helplessness in particular sits between the fear and sadness
families.env_asr, NeMo 2.7.3) and installing NeMo into the generation venv
risks a torch downgrade that has destroyed it before. Parakeet runs as stage 2 and supplies the
word timestamps; because every ranking component is stored, re-ranking on Parakeet WER needs no
regeneration.laion/moss-mediathek-emotion-lora ::
r64_e2 at 0.25, as specified. Note a second, differently
named repo laion/moss-mediathek-hq-lora (r64_epoch3) also exists and is
the one the voice-acting manual names; they were not compared.