Document scoped quality-reranked inference
Browse files- README.md +48 -0
- USAGE.md +25 -0
- release_metadata.json +40 -0
README.md
CHANGED
|
@@ -127,6 +127,35 @@ python scripts/generate_tts.py \
|
|
| 127 |
--out long.wav
|
| 128 |
```
|
| 129 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 130 |
## Evaluation
|
| 131 |
|
| 132 |
Numbers below are from an internal held-out evaluation set. The eval set and
|
|
@@ -144,6 +173,17 @@ reaches 6.25 chars/sec and early-stop classification exceeds 50%. Controlled
|
|
| 144 |
pace is therefore part of the current production contract, not an optional
|
| 145 |
benchmark optimization.
|
| 146 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 147 |
The selected long-form contract was repeated in four independent processes,
|
| 148 |
each with three multi-sentence texts and five request seeds. It uses
|
| 149 |
80-character chunks, 4.0 target chars/sec, no retry selection, one reference
|
|
@@ -168,6 +208,12 @@ chunk consistently worsened CER, pace variance, and speaker drift, so
|
|
| 168 |
`--continuation-context-sec 0` remains the production default. Raw reference
|
| 169 |
tokens are not represented by these production metrics.
|
| 170 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 171 |
## Limitations
|
| 172 |
|
| 173 |
- Metrics are not a public benchmark and should be used only for internal model
|
|
@@ -179,6 +225,8 @@ tokens are not represented by these production metrics.
|
|
| 179 |
target pace, stop hysteresis, and chunking contract; inspect important output.
|
| 180 |
- Raw reference tokens remain a separately gated research backend.
|
| 181 |
- Very long passages should be chunked to avoid stop-token and prosody drift.
|
|
|
|
|
|
|
| 182 |
- Generated-audio continuation context is experimental and disabled by default.
|
| 183 |
- Generated speech may be incorrect; do not use it as a real-world notification
|
| 184 |
without human review.
|
|
|
|
| 127 |
--out long.wav
|
| 128 |
```
|
| 129 |
|
| 130 |
+
## Quality-First Short and Medium Text
|
| 131 |
+
|
| 132 |
+
The optional offline quality path generates multiple candidates and uses ASR
|
| 133 |
+
plus speaker verification to select one. It is slower than ordinary generation
|
| 134 |
+
and does not change the checkpoint weights:
|
| 135 |
+
|
| 136 |
+
```bash
|
| 137 |
+
python scripts/generate_tts_quality.py \
|
| 138 |
+
--checkpoint /path/to/model-snapshot \
|
| 139 |
+
--mode speaker-reference-audio-only \
|
| 140 |
+
--speaker-reference-wav /path/to/rights-cleared-reference.wav \
|
| 141 |
+
--text "這是離線品質優先的語音合成測試。" \
|
| 142 |
+
--candidates 10 \
|
| 143 |
+
--asr-backend whisper \
|
| 144 |
+
--asr-model /path/to/compatible-asr-checkpoint \
|
| 145 |
+
--candidate-speaker-weight 0.05 \
|
| 146 |
+
--candidate-boundary-speaker-weight 0.1 \
|
| 147 |
+
--candidate-max-boundary-speaker-drop 0.03 \
|
| 148 |
+
--target-chars-per-sec 4.2 \
|
| 149 |
+
--out quality.wav
|
| 150 |
+
```
|
| 151 |
+
|
| 152 |
+
The candidate count and score weights are measured project heuristics, not
|
| 153 |
+
universal TTS defaults. The command fails closed when no candidate passes the
|
| 154 |
+
speaker-boundary gate. `--allow-boundary-fallback` is available for research,
|
| 155 |
+
but is outside the measured contract. This quality policy is promoted only for
|
| 156 |
+
speaker-reference short/medium synthesis; centroid and strict long-form gates
|
| 157 |
+
did not pass.
|
| 158 |
+
|
| 159 |
## Evaluation
|
| 160 |
|
| 161 |
Numbers below are from an internal held-out evaluation set. The eval set and
|
|
|
|
| 173 |
pace is therefore part of the current production contract, not an optional
|
| 174 |
benchmark optimization.
|
| 175 |
|
| 176 |
+
The opt-in short/medium quality policy was measured on 30 texts with ten
|
| 177 |
+
candidates per text. The full candidate pool reached 9.35% CER / 9.51% WER;
|
| 178 |
+
the selected outputs reached 1.14% / 1.86%, with zero early stops, overruns,
|
| 179 |
+
final truncations, or speaker-boundary fallbacks. Across-text speaker
|
| 180 |
+
similarity was 0.511, reference-similarity P10 was 0.444, and median/P95 pace
|
| 181 |
+
was 4.04/4.17 chars/sec. A second ASR that did not participate in selection
|
| 182 |
+
measured 6.83% CER / 6.78% WER; on matched target recordings it measured
|
| 183 |
+
9.20% / 8.76%. The same single code-switch item was the only outlier in both.
|
| 184 |
+
These are test-time selection results and must not be described as a trained
|
| 185 |
+
checkpoint improvement.
|
| 186 |
+
|
| 187 |
The selected long-form contract was repeated in four independent processes,
|
| 188 |
each with three multi-sentence texts and five request seeds. It uses
|
| 189 |
80-character chunks, 4.0 target chars/sec, no retry selection, one reference
|
|
|
|
| 208 |
`--continuation-context-sec 0` remains the production default. Raw reference
|
| 209 |
tokens are not represented by these production metrics.
|
| 210 |
|
| 211 |
+
A separately frozen 12-text long-form holdout reached 4.00% selected CER and
|
| 212 |
+
4.91% WER under the selection ASR, but one numeric/ASCII-heavy request had no
|
| 213 |
+
candidate below the 0.03 speaker-boundary gate. Independent-ASR CER was 15.25%
|
| 214 |
+
with one cross-chunk outlier. The quality-reranked long-form path is therefore
|
| 215 |
+
not promoted; use the standard measured 80-character/no-context command above.
|
| 216 |
+
|
| 217 |
## Limitations
|
| 218 |
|
| 219 |
- Metrics are not a public benchmark and should be used only for internal model
|
|
|
|
| 225 |
target pace, stop hysteresis, and chunking contract; inspect important output.
|
| 226 |
- Raw reference tokens remain a separately gated research backend.
|
| 227 |
- Very long passages should be chunked to avoid stop-token and prosody drift.
|
| 228 |
+
- Quality reranking is currently promoted only for speaker-reference
|
| 229 |
+
short/medium synthesis; it is not the default centroid or long-form path.
|
| 230 |
- Generated-audio continuation context is experimental and disabled by default.
|
| 231 |
- Generated speech may be incorrect; do not use it as a real-world notification
|
| 232 |
without human review.
|
USAGE.md
CHANGED
|
@@ -123,6 +123,31 @@ python scripts/generate_tts.py \
|
|
| 123 |
--out long.wav
|
| 124 |
```
|
| 125 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 126 |
This path extracts the windowed speaker embedding once and reuses it for every
|
| 127 |
chunk. Each request gets a new random seed that is reused inside that request;
|
| 128 |
the release gate varies request seeds, so stability does not depend on one
|
|
|
|
| 123 |
--out long.wav
|
| 124 |
```
|
| 125 |
|
| 126 |
+
Quality-first short or medium text:
|
| 127 |
+
|
| 128 |
+
```bash
|
| 129 |
+
python scripts/generate_tts_quality.py \
|
| 130 |
+
--checkpoint /path/to/model-snapshot \
|
| 131 |
+
--mode speaker-reference-audio-only \
|
| 132 |
+
--speaker-reference-wav /path/to/rights-cleared-reference.wav \
|
| 133 |
+
--text "這是離線品質優先的語音合成測試。" \
|
| 134 |
+
--candidates 10 \
|
| 135 |
+
--asr-backend whisper \
|
| 136 |
+
--asr-model /path/to/compatible-asr-checkpoint \
|
| 137 |
+
--candidate-speaker-weight 0.05 \
|
| 138 |
+
--candidate-boundary-speaker-weight 0.1 \
|
| 139 |
+
--candidate-max-boundary-speaker-drop 0.03 \
|
| 140 |
+
--target-chars-per-sec 4.2 \
|
| 141 |
+
--out quality.wav
|
| 142 |
+
```
|
| 143 |
+
|
| 144 |
+
This opt-in path is approximately proportional to the candidate count in
|
| 145 |
+
latency. It fails closed if no candidate passes the speaker-boundary gate.
|
| 146 |
+
`--allow-boundary-fallback` is a research override, not part of the measured
|
| 147 |
+
contract. The quality policy is promoted only for speaker-reference
|
| 148 |
+
short/medium text; keep using `generate_tts.py` for centroid and long-form
|
| 149 |
+
production requests.
|
| 150 |
+
|
| 151 |
This path extracts the windowed speaker embedding once and reuses it for every
|
| 152 |
chunk. Each request gets a new random seed that is reused inside that request;
|
| 153 |
the release gate varies request seeds, so stability does not depend on one
|
release_metadata.json
CHANGED
|
@@ -26,6 +26,23 @@
|
|
| 26 |
"raw-reference-tokens"
|
| 27 |
]
|
| 28 |
},
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 29 |
"evaluation": {
|
| 30 |
"scope": "internal held-out evaluation",
|
| 31 |
"centroid_only": {
|
|
@@ -48,6 +65,29 @@
|
|
| 48 |
"speaker_across_texts_median": 0.4557993102947186,
|
| 49 |
"speaker_reference_p10": 0.3619180113077164
|
| 50 |
},
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 51 |
"natural_stop": {
|
| 52 |
"status": "pace_gate_failed",
|
| 53 |
"speaker_reference_cer": 0.1285453712953713,
|
|
|
|
| 26 |
"raw-reference-tokens"
|
| 27 |
]
|
| 28 |
},
|
| 29 |
+
"inference_policies": {
|
| 30 |
+
"standard": {
|
| 31 |
+
"scope": [
|
| 32 |
+
"centroid-only",
|
| 33 |
+
"speaker-reference-embedding"
|
| 34 |
+
]
|
| 35 |
+
},
|
| 36 |
+
"quality_rerank": {
|
| 37 |
+
"scope": [
|
| 38 |
+
"speaker-reference-embedding-short-medium"
|
| 39 |
+
],
|
| 40 |
+
"candidate_count": 10,
|
| 41 |
+
"fail_closed_on_boundary_fallback": true,
|
| 42 |
+
"centroid_status": "not_promoted",
|
| 43 |
+
"longform_status": "not_promoted"
|
| 44 |
+
}
|
| 45 |
+
},
|
| 46 |
"evaluation": {
|
| 47 |
"scope": "internal held-out evaluation",
|
| 48 |
"centroid_only": {
|
|
|
|
| 65 |
"speaker_across_texts_median": 0.4557993102947186,
|
| 66 |
"speaker_reference_p10": 0.3619180113077164
|
| 67 |
},
|
| 68 |
+
"speaker_reference_quality_rerank": {
|
| 69 |
+
"release_role": "opt_in_short_medium",
|
| 70 |
+
"profile": "controlled_30_texts_10_candidates",
|
| 71 |
+
"candidate_pool_cer": 0.09351897921002666,
|
| 72 |
+
"candidate_pool_wer": 0.0950508473008473,
|
| 73 |
+
"selected_cer": 0.011402486402486402,
|
| 74 |
+
"selected_wer": 0.018602693602693603,
|
| 75 |
+
"independent_asr_selected_cer": 0.06834166650343122,
|
| 76 |
+
"independent_asr_selected_wer": 0.06783609908609908,
|
| 77 |
+
"chars_per_second_median": 4.044117647058823,
|
| 78 |
+
"chars_per_second_p95": 4.166666666666667,
|
| 79 |
+
"early_stop_rate": 0.0,
|
| 80 |
+
"overrun_rate": 0.0,
|
| 81 |
+
"sentence_final_truncation_rate": 0.0,
|
| 82 |
+
"boundary_fallback_count": 0,
|
| 83 |
+
"speaker_across_texts_median": 0.5111590030378309,
|
| 84 |
+
"speaker_reference_p10": 0.4438544690608978,
|
| 85 |
+
"begin_end_speaker_drop_max": 0.029450446367263794
|
| 86 |
+
},
|
| 87 |
+
"quality_rerank_non_promoted": {
|
| 88 |
+
"centroid": "speaker boundary and duration-variance gates failed",
|
| 89 |
+
"longform": "one of twelve holdout requests failed the speaker boundary gate"
|
| 90 |
+
},
|
| 91 |
"natural_stop": {
|
| 92 |
"status": "pace_gate_failed",
|
| 93 |
"speaker_reference_cer": 0.1285453712953713,
|