Replies: 2 comments
|
Update: found a real bug in RUAccent 1.5.8.3 while testing against a Russian text sample, want to flag it here before it comes up in review. Any word missing from RUAccent's built-in dictionary crashes Practical effect for this integration: without a guard, one uncatalogued name or technical term anywhere in a paragraph kills the entire generation, not just that word. I've written a wrapper that catches it per-word and leaves that one word unmarked instead of crashing the sentence — costs one skipped stress mark, not the whole output. That guard is now a hard requirement for the integration, not an edge case worth skipping. Wanted to be upfront about this since it's a real limitation, not just theoretical — happy to answer anything on it before this goes further. |
|
Second update, unrelated to Russian text specifically but relevant to anyone using F5-TTS voice cloning through this suite: found and fixed a reference-audio bleed-through bug while testing, worth documenting here since it's the kind of thing other users will hit. SymptomWith some reference audio/text pairs, generated output would contain fragments of the reference audio's own content — words from the reference clip appearing verbatim in the generated speech, inserted at arbitrary points (start, middle, anywhere), sometimes alongside garbled/hallucinated non-words nearby. Got worse on longer generation text. Confirmed via ASR transcription of generated output — e.g. one reference clip produced output starting with a phrase that was literally the last two lines of that reference's own transcript, before the actual requested text even began. Root causeReference clips that are longer than they need to be — whether the excess is trailing dead air after the spoken content, or genuinely more spoken material than intended (e.g. a clip that continues past a single sentence into unrelated following content) — destabilize generation on longer target text. The model appears to draw stray content from the reference's own tail. Verified this is duration-driven, not content-specific: the exact clause that leaked stopped leaking once the reference was trimmed down, even though that clause was still present in the trimmed reference. FixTrim reference clips to a short, complete, grammatically well-formed sentence — no partial sentences, no trailing silence, no bonus content beyond the intended reference. In testing, ~10-12s clips were reliably clean; a ~32s clip (continuous speech, no dead air) still leaked and produced additional corruption. Cutting a fragment (stopping mid-sentence) also fixes the leak but visibly hurts prosody/stress quality compared to a short-but-complete sentence — so "short" and "complete" both matter, not just "short." Why I'm flagging this here rather than just fixing my own filesThis took real, iterative effort to diagnose — waveform silence analysis, precise timestamp identification via ASR word timing, building controlled test references, and transcribing generated output to objectively confirm leaked content vs. clean output. That's not something a non-programmer user can reasonably do. And it's the kind of failure that gives no error message — it just quietly sounds wrong, or subtly wrong in a way that's easy to blame on the model rather than the reference clip. Related: the intended UI path for this (🎭 Character Voices' waveform trim editor) doesn't currently render on newer ComfyUI frontends — filed separately as #348. So right now there's no low-effort way for a user to even attempt the fix that's already built. Possible future enhancementOnce #348 is fixed, the trim UI could proactively help here rather than just enabling manual trimming:
The pieces (waveform trim, ASR transcription) already exist as separate features in the suite — this would just be connecting them into a guided workflow for a failure mode that's currently invisible until a user notices their audio sounds off and has no easy way to know why. Happy to write this up as its own issue if that's a better place for it than buried in this discussion. |
Uh oh!
There was an error while loading. Please reload this page.
I'm using F5-TTS with the
Misha24-10/F5-TTS_RUSSIANF5TTS_v1_Base_accent_tunecheckpoint. Its model card states it was fine-tuned with full stress markup on 100% of training sentences (молок+о). There are two gaps I'd like to close, and I have a working, verified implementation — but I'd rather ask where it belongs before writing the integration, since a Russian-only node would overlap existing functionality.The gaps
1. Stress marking. The suite already has
utils/text/russian_stress_support.py, but its only call site isadd_russian_stress()inMTLTokenizer.preprocess_text— ChatterBox Official 23-Lang only. There's no path from F5-TTS to it. It also emits acute accents (молоко́, U+0301), whereasaccent_tuneexpects a+before the stressed vowel.2. Numbers. F5-TTS has no text normalizer and is character-level, so
2026fails. Russian additionally needs case agreement:в 2026 году→в две тысячи двадцать шестом году(prepositional ordinal), not the cardinalдве тысячи двадцать шесть.PhonemeTextNormalizerdoesn't cover either — and its IPA Phonemization method would actively break this checkpoint, which expects Cyrillic plus+, not IPA.What I have working
Pipeline is expand numbers → mark stress (RUAccent) → drop redundant markers:
Ordering matters: RUAccent leaves digits untouched but correctly accents the words
num2wordsproduces, so expansion has to run first.Two details that keep it small. Russian compound ordinals decline only on the final component (
две тысячи двадцать шестой→…шестом), so a last-word ending rewrite is the whole job. And the noun's own case tells you the ordinal's case since they agree — matching onгод/года/году/годомrather than enumerating prepositions meansв конце 2023 годаworks without a rule forв конце.RUAccent's real advantage over the existing dictionary backend is homograph disambiguation, which I've verified works:
Это ст+оит дорого, но он сто+ит у двери,Дор+ога домой была дорог+а ему.The question
Where would you like this?
russian-text-stresserPhonemeTextNormalizerI lean toward (a), but it's your architecture and I don't want to polish the wrong shape.
Two things you'd want to know up front
RUAccent would stay optional. I'd follow the exact pattern of
install_russian_text_stresser_support()— kept out ofrequirements.txt, installed best-effort ininstall.pywithignore_errors=True, lazy-imported and cached at module level, degrading to pass-through when absent. Worth being precise about the cost: its assets are ~693MB (482M neural models, 189M koziev data, 22M dictionaries), not the ~100MB the README implies. It also downloads intosite-packages/ruaccent/by default;workdir=redirects most of it to a proper model cache, but a hardcodedmodule_pathin thekozievbranch leaks ~189MB back regardless. That's an upstream bug I'll report separately.Number expansion needs
num2words, which is LGPL-2.1. It's already present transitively via the RVC engine (engines/rvc/impl/lib/infer_pack/text/cleaners.py), but it would become a direct dependency, so flagging it rather than letting you discover it in a diff.Unrelated possible bug
While testing I found
pymorphy2fails on Python 3.12 — it callsinspect.getargspec, removed in 3.11. Sincerussian-text-stresserdepends on it, the existing ChatterBox Official 23-Lang Russian stress path may be broken on 3.12 installs. I haven't confirmed end-to-end and it doesn't affect this proposal, but it seemed worth mentioning. Happy to open a separate issue if useful.All reactions