Inflect Micro PT-BR · 20k
Inflect Micro PT-BR is a single-speaker Brazilian Portuguese TTS model adapted from the open-weight owensong/Inflect-Micro-v2. It was trained on 20,000 clips (37.45 hours) from one speaker at 24 kHz, for 20,000 steps, and is released as a self-contained PyTorch inference package.
Listen to the samples ↓ · Get started ↓ · See the training evidence ↓ · Read the training recipe ↓
Table of contents
Model Overview
Description
Inflect Micro PT-BR adapts a multilingual VITS-based speech model to one Brazilian Portuguese speaker. The adaptation uses a staged schedule: the posterior encoder warms up first, the linguistic layers follow, and the decoder stays frozen until step 6,000 so the acoustic quality learned from the base model survives the language shift.
The package in this repository runs on CPU or GPU without installing the training toolchain. Text goes in, a 24 kHz waveform comes out, with adjustable speed and prosody variation.
This model is a research artifact. Read Limitations before deploying it.
Model Summary
| Base model | owensong/Inflect-Micro-v2 |
| Architecture | VITS (posterior encoder, flow, HiFi-GAN decoder), inference-only export |
| Parameters on disk | 37.5 MB (model.pth) |
| Sample rate | 24 kHz, mono, PCM |
| Language | Brazilian Portuguese (pt-BR) |
| Speakers | 1 (source speaker ID 2961) |
| Text frontend | espeak-ng, pt-br, with stress marks and punctuation preserved |
| Symbol inventory | 181 entries (178 from the base model + 3 added for Portuguese) |
| Inputs / Outputs | Text / 24 kHz waveform |
| Control knobs | --speed (duration scaling), --variation (prosody diversity), --seed |
| Training hardware | 1× A100 40 GB, ~3.2 GB peak VRAM |
| Training budget | 20,000 steps, effective batch 8 |
| License | Inherited from the base model; see License |
Results at a Glance
Training losses are means over step ranges, computed from 22,404 rows of metrics.jsonl. ↓ Lower is better.
| Step range | loss_g |
loss_d |
What was happening |
|---|---|---|---|
| 1–999 | 75.22 | 2.192 | Posterior warm-up, decoder frozen |
| 1,000–4,999 | 45.84 | 1.857 | Discriminator learns the base/target gap |
| 5,000–9,999 | 29.97 | 2.562 | Decoder unfreezes at 6,000 |
| 10,000–14,999 | 26.13 | 2.695 | Timbre consolidation |
| 15,000–19,499 | 25.64 | 2.687 | Plateau |
| 19,500–20,000 | 25.53 | 2.679 | Final checkpoint |
loss_g drops 66% across the run. loss_d falls early, then rises and settles near 2.68 — the expected rebalancing once the generator starts producing the target speaker's distribution and the discriminator loses its shortcut.
Listen
Every clip below is served from this repository. Press play; nothing is downloaded separately.
Prosody control
Same eight sentences, same seed (42), CPU inference. Only speed and variation change, so the prosody is the single variable.
| ID | Sentence | defaultspeed 1.0 · var 0.667 |
slowerspeed 0.90 · var 0.667 |
variedspeed 0.95 · var 0.80 |
|---|---|---|---|---|
| frase-00 | Olá, tudo bem com você? | 1.65 s |
1.78 s |
1.72 s |
| frase-01 | Hoje está fazendo um dia muito bonito. | 2.55 s |
2.73 s |
2.61 s |
| frase-02 | O Brasil é um país de dimensões continentais. | 3.43 s |
3.63 s |
3.53 s |
| frase-03 | Você gostaria de ouvir uma história interessante? | 3.11 s |
3.33 s |
3.23 s |
| frase-04 | Não acredito que isso aconteceu! | 2.20 s |
2.25 s |
2.23 s |
| frase-05 | Que notícia maravilhosa! | 1.76 s |
1.90 s |
1.83 s |
| frase-06 | Por favor, me diga que horas são. | 2.10 s |
2.29 s |
2.19 s |
| frase-07 | Amanhã teremos uma reunião importante. | 2.60 s |
2.76 s |
2.65 s |
Total duration: 19.41 s (default), 20.67 s (slower), 19.99 s (varied). Reducing speed to 0.90 stretches the mean utterance by 6.6%, not the 11.1% a purely linear scaling would give — the model targets per-phoneme duration, and pauses do not scale with it. Short sentences deviate most: frase-04 stretched 2.4%, while frase-02 stretched 9.1%.
Version comparison: 4k steps vs 20k steps
Same six sentences, synthesized by the earlier 4,000-step checkpoint and by this 20,000-step one. Meant for listening, not for crowning a winner.
| Sentence | V1 · 4k steps | V2 · 20k steps |
|---|---|---|
| Bom dia! Tudo bem com você? | V1 · 2.34 s |
V2 · 2.23 s |
| O Brasil é um país de dimensões continentais. | V1 · 3.13 s |
V2 · 3.51 s |
| Preciso marcar uma consulta para a próxima terça-feira. | V1 · 3.66 s |
V2 · 3.67 s |
| A reunião começou às nove da manhã e terminou ao meio-dia. | V1 · 3.59 s |
V2 · 3.63 s |
| Eu gostaria de um café com leite e dois pães de queijo, por favor. | V1 · 4.27 s |
V2 · 4.31 s |
| O relatório será entregue até o final da semana que vem. | V1 · 3.62 s |
V2 · 3.62 s |
Training progression
The model's own validation samples, taken every 500 steps. Useful for hearing where the voice becomes intelligible and what changes after the decoder unfreezes.
| Step | Stage | Validation audio |
|---|---|---|
| 500 | Primeiros passos: posterior aquecendo, decoder congelado. | |
| 5.000 | Posterior estabilizado, ainda sem descongelar o decoder. | |
| 10.000 | Decoder descongelado em 6.000; ajuste de timbre. | |
| 15.000 | Fase final de refinamento. | |
| 20.000 | Checkpoint final exportado. |
Quick Start
The package is self-contained. You do not need inflect-adapt to run inference.
pip install -r requirements.txt
python inference.py --text "Bom dia, tudo bem com você?" --output saida.wav
With prosody control:
python inference.py \
--text "A reunião começou às nove da manhã." \
--speed 0.9 \
--variation 0.8 \
--device cuda \
--output saida.wav
Batching over a jsonl manifest:
while IFS= read -r line; do
id=$(echo "$line" | python3 -c "import sys,json;print(json.load(sys.stdin)['id'])")
txt=$(echo "$line" | python3 -c "import sys,json;print(json.load(sys.stdin)['text'])")
python inference.py --text "$txt" --output "audios/$id.wav"
done < frases.jsonl
| Flag | Default | Effect |
|---|---|---|
--text |
— | Plain text input, normalized by the espeak frontend |
--phonemes |
— | Skip the frontend and pass phonemes directly |
--output |
required | Destination .wav |
--device |
cpu |
cpu or cuda |
--speed |
1.0 | Duration multiplier across the utterance |
--variation |
0.667 | Prosody diversity; higher is looser |
--seed |
0 | Reproducibility seed |
Model Architecture
The export is a VITS-style end-to-end TTS model: a text encoder, a normalizing flow, a posterior encoder used at training time, and a HiFi-GAN decoder that upsamples to 24 kHz.
| Component | Configuration |
|---|---|
| Inter channels / hidden channels | 192 / 96 |
| Encoder layers, heads | 3, 2 |
| Upsample rates | 8, 8, 2, 2 |
| Upsample kernel sizes | 16, 16, 4, 4 |
| Resblock kernel sizes | 3, 7, 11 |
| Mel channels, FFT | 80, 1024 |
| Hop length | 256 |
The Portuguese adaptation added three symbols — õ, ũ and the combining tilde ̃ — to the base inventory. Before adaptation, 97.6% of corpus symbols already existed in the base vocabulary, so the embedding table grew by three rows while staying compatible with the pretrained weights.
Inputs and Outputs
| Property | Specification |
|---|---|
| Input types | Plain text, or phoneme sequences with --phonemes |
| Output type | Mono waveform, float32 |
| Output format | 24 kHz .wav |
| Frontend | espeak-ng pt-br, stress marks on, punctuation preserved |
| Text limit | The package splits long input into chunks at punctuation boundaries |
| Determinism | Fixed --seed and --variation 0 reproduce the same audio |
Chunking is worth knowing about: sentences longer than the internal limit are synthesized in pieces and concatenated, which can produce a prosody discontinuity at the junction.
Training
Dataset
| Metric | Value |
|---|---|
| Total clips | 20,000 |
| Train / validation | 19,123 / 877 |
| Total duration | 134,807 s (37.45 h) |
| Clip duration min / max | 1.50 s / 12.00 s |
| Sample rate | 24 kHz |
| Speakers | 1 |
| Language / frontend | pt-BR / espeak with stress |
The split is group-aware and normalizes text before separating, so the same sentence never appears in both sides. The target was 1,000 validation rows; the result was 877 because whole groups were kept together rather than sliced. Smaller validation set, no text leakage between train and evaluation.
Recipe
| Parameter | Value |
|---|---|
| Base checkpoint | owensong/Inflect-Micro-v2 |
| Preset | micro-12gb |
| Steps | 20,000 |
| Batch × accumulation | 4 × 2 (effective 8) |
| Learning rate (G / D) | 8e-5 / 8e-5 |
| Posterior warm-up | 1,500 steps |
| Decoder unfreeze | step 6,000 |
| Precision | AMP |
| Checkpoint / validation interval | 500 steps |
| Seeds (training / split) | 1234 / 42 |
Final learning rates were 6.95e-5 for the posterior, 3.48e-5 for the linguistic layers and 6.95e-6 for the decoder. The asymmetry is deliberate: the decoder moves slowly so the acoustic detail from the base model is not overwritten.
Evaluation
The prosody runs used inflect-adapt evaluate on CPU with a fixed seed. All three configurations passed the automatic checks.
| Configuration | Evaluated | Failures | Clipped clips | Silent clips | Result |
|---|---|---|---|---|---|
default |
8/8 | 0 | 0 | 0 | PASS |
slower |
8/8 | 0 | 0 | 0 | PASS |
varied |
8/8 | 0 | 0 | 0 | PASS |
These checks verify that the audio is well-formed and audible. They do not measure intelligibility. See Limitations.
Engineering Notes
Three problems cost real time during this run. All three share a cause: state that survives a restart and nobody reconciles.
Concurrent training processes. Restarting the run after a session drop spawned a new process without killing the old one. Within a few cycles, five inflect-adapt processes were sharing one A100 and writing to the same latest.pth. The symptom was not a clean error — the loss moved backwards, because different copies saved checkpoints with different optimizer states. Restart routines now terminate the process tree by PID and abort if anything survives.
Non-monotonic W&B steps. A resumed run emits step numbers below the ones already logged. W&B rejects non-increasing steps, so every new row was discarded while training continued normally. The fix separates the two axes: the W&B step counter stays monotonic, and the real training step is logged as a metric.
Validation audio that seemed to stop. The uploader checked for new metric lines first and returned early when there were none — before looking at audio. Since metrics are written every 25 steps and validation every 500, audio only uploaded when the two coincided. Metrics and audio are now independent in the same cycle, and the list of already-sent clips is persisted to disk so restarts do not resend old samples.
Limitations
- No intelligibility metric. The transcript evaluator was disabled in every run. "The voice is intelligible" remains an auditory judgment, not a measured result.
- No MOS study. No listening test was conducted.
- Single speaker. One voice. The model does not accept
speaker_idand does not generalize timbre. - Narrow domain. Read speech, 1.5–12 s per clip. Long utterances are chunked, which can cause prosody seams.
- Text normalization gaps. Acronyms, spelled-out numbers and foreign terms depend on the espeak frontend and were not systematically evaluated.
- License. See below. Confirm the base model and corpus terms before commercial use.
Reproduction
| Path | Contents |
|---|---|
training/launch-config.yaml |
Effective configuration recorded by the run |
training/train.py |
Launcher with resume and W&B synchronization |
training/supervisor.py |
Automatic restart from the newest intact checkpoint |
training/hyperparameters.yaml |
Hyperparameters |
validation/ |
40 audio and metadata pairs captured every 500 steps |
audio/prosody_tests/ |
Prosody test across three configurations |
checksums.sha256 |
Checksums for the exported package |
export_report.json |
Export verification report |
Training ran at 1.25–2.0 s per step on one A100 40 GB. The source corpus is not redistributed here for licensing reasons; launch-config.yaml records the paths that were used.
License
The package carries the license of the base model. Review the terms of owensong/Inflect-Micro-v2 and of the source corpus before redistribution or commercial use.
Citation
@misc{rios2026inflectptbr,
author = {Hugo Rios},
title = {Inflect Micro PT-BR: 20k steps of single-speaker adaptation},
year = {2026},
url = {https://huggingface.co/HRB25/inflect-micro-ptbr-20k}
}
Built on Inflect by owenawsong.
- Downloads last month
- 48
Model tree for HRB25/inflect-micro-ptbr-20k
Base model
owensong/Inflect-Micro-v2