File size: 7,837 Bytes
3c1eb61
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
# Smart Turn Portuguese Fine-Tuning — Research Log

## Objetivo

Fine-tuning do modelo Pipecat Smart Turn (detecção de fim de turno em conversas) para português brasileiro, visando melhorar a acurácia de ~68% (modelo original inglês aplicado a PT) para 90%+.

## Background

### O que é Smart Turn
- Modelo do framework [Pipecat](https://github.com/pipecat-ai/smart-turn) para detectar se um falante terminou de falar
- Arquitetura: Whisper encoder + attention pooling + classificador binário (complete/incomplete)
- Janela de 8 segundos de áudio, saída binária: "turno completo" vs "turno incompleto"
- Modelo original treinado em inglês (v3.1), 39M parâmetros (Whisper Tiny)

### Por que fine-tuning em português
- O modelo original em inglês tem ~68.6% de acurácia em português
- Prosódia, entonação e padrões de turn-taking são diferentes entre idiomas
- Aplicação: tradução em tempo real de reuniões (BabelCast)

---

## Fase 1: Benchmark do modelo original (pré fine-tuning)

### Datasets de avaliação
- **NURC-SP Corpus Minimo** (nilc-nlp): diálogos reais em PT-BR espontâneo dos anos 1970-1990
- Scripts: `setup_nurc_dataset.py`, `benchmark_pipecat.py`

### Resultado baseline
- Acurácia do Smart Turn v3.1 em português: **~68.6%**
- Problema principal: modelo não entende padrões prosódicos do português

---

## Fase 2: Fine-tuning v2 — Heurística de corte (2026-03-14)

### Abordagem
- Baixar datasets de ASR em português do HuggingFace
- Criar labels heurísticas: "complete" = final da frase, "incomplete" = corte aleatório a 30-75%
- Treinar com speaker-based split para evitar data leakage

### Datasets utilizados
| Dataset | Tipo | Horas | Samples |
|---------|------|-------|---------|
| CORAA v1.1 | Conversacional BR-PT | 291h | 7,000 |
| MLS Portuguese | Audiobook (leitura) | 168h | 7,000 |
| CORAA-MUPE-ASR | Entrevistas | 365h | 7,000 |
| **Total** | | | **21,000** |

### Configuração de treino
- **Modelo**: Whisper Tiny encoder (39M params)
- **GPU**: RTX 3090 24GB (Vast.ai, $0.069/hr)
- **Batch size**: 32
- **Learning rate**: 2e-5 (encoder: 2e-6, head: 2e-5)
- **Augmentation**: volume scaling, Gaussian noise
- **Split**: 13,032 train (4,100 speakers) / 698 val (512 speakers) / 7,270 test (512 speakers)
- **Early stopping**: patience=5 no val_f1

### Infraestrutura (problemas e soluções)
- **6+ instâncias Vast.ai morreram** durante o treino (spot instances instáveis)
- **3 pods RunPod falharam** (PyTorch images too large for container disk)
- **Solução**: on-demand Vast.ai instance, RTX 3090, reliability=1.00
- **Mac local**: treinamento funciona mas deixa a máquina muito lenta (MPS)
- **Dependências críticas**: PyTorch >= 2.4, `datasets<4` (para evitar torchcodec), librosa, typing_extensions >= 4.12

### Resultados v2

#### Progresso por época
| Epoch | Train Loss | Train Acc | Val Acc | Val F1 | Val Prec | Val Rec |
|-------|-----------|-----------|---------|--------|----------|---------|
| 1 | 0.6032 | 0.668 | 0.669 | 0.721 | 0.600 | 0.903 |
| 2 | 0.5019 | 0.748 | 0.716 | 0.751 | 0.643 | 0.903 |
| 3 | 0.4521 | 0.782 | 0.716 | 0.751 | 0.643 | 0.903 |
| 4 | 0.4161 | 0.806 | 0.749 | 0.748 | 0.714 | 0.785 |
| 5 | 0.3962 | 0.817 | 0.742 | 0.717 | 0.748 | 0.689 |
| **6** | **0.3806** | **0.831** | **0.754** | **0.760** | **0.707** | **0.822** |
| 7 | 0.3703 | 0.832 | 0.742 | 0.748 | 0.697 | 0.807 |
| 8 | 0.3566 | 0.845 | 0.739 | 0.709 | 0.752 | 0.671 |
| 9 | 0.3449 | 0.846 | 0.748 | 0.745 | 0.716 | 0.776 |
| 10 | 0.3390 | 0.853 | 0.748 | 0.758 | 0.695 | 0.834 |
| 11 | 0.3237 | 0.865 | 0.754 | 0.756 | 0.713 | 0.804 |

Early stopping na época 11 (sem melhora por 5 épocas).

#### Melhor modelo (época 6)
- **Val Accuracy**: 75.4%
- **Val F1**: 0.760
- **Val Precision**: 70.7%
- **Val Recall**: 82.2%

#### Teste (speakers totalmente novos)
- **Test Accuracy**: 64.4%
- **Test F1**: 0.600
- **Test Precision**: 68.0%
- **Test Recall**: 53.7%
- TP=1945, FP=916, FN=1674, TN=2735

### Análise dos problemas da v2

1. **Labels heurísticas (problema principal)**: Cortar frases aleatoriamente em 30-75% não simula turn-taking real. O modelo aprendeu "tem silêncio no final?" em vez de "a pessoa terminou de falar?"

2. **MLS é audiobook**: 1/3 dos dados são leitura de audiobook — prosódia completamente diferente de conversação real

3. **MUPE speaker_id quebrado**: Usava `speaker_type` ("interviewer"/"interviewee") como speaker_id, comprometendo o speaker split

4. **Modelo pequeno**: Whisper Tiny (39M params) tem capacidade limitada para capturar padrões prosódicos complexos

5. **Gap val/test grande (75.4% vs 64.4%)**: Indica que o modelo não generaliza bem para speakers novos

### Arquivos gerados
- `checkpoints/smart_turn_pt_v2/best_model.pt` — 31MB PyTorch checkpoint
- `checkpoints/smart_turn_pt_v2/smart_turn_pt.onnx` + `.onnx.data` — 31MB ONNX
- `checkpoints/smart_turn_pt_v2/finetune.log` — log completo

### Commits
- `4517458` — feat: Pipecat Smart Turn Portuguese evaluation, fine-tuning pipeline
- `307b0fd` — feat: GPU fine-tuning script with HuggingFace Portuguese datasets
- `62e1816` — fix: total_mem → total_memory for PyTorch 2.10 compat
- `0039c15` — fix: reduce samples to 5k/dataset and workers to prevent OOM
- `51025dd` — fix: MPS support, skip Common Voice, increase samples to 7k/dataset

---

## Fase 3: Fine-tuning v3 — Labels por pontuação + Whisper Base (em andamento)

### Melhorias implementadas

1. **Labels baseadas em pontuação do texto**
   - Frase termina com `.` `!` `?` `…` → complete (1.0)
   - Frase termina com `,` `;` `:` `-` → incomplete (0.0)
   - Texto sem pontuação com ≤2 palavras → descartado (ambíguo)
   - Texto sem pontuação com 3+ palavras → incomplete (transcritor teria colocado ponto se fosse completa)

2. **Removido MLS audiobook** — só dados conversacionais (CORAA + MUPE)

3. **Whisper Base** (74M params) em vez de Whisper Tiny (39M)
   - 2x mais parâmetros no encoder
   - hidden_size: 512 (vs 384 no Tiny)
   - Melhor capacidade para capturar prosódia

4. **Speaker ID do MUPE corrigido** — usa hash do audio_path ou agrupamento por index

5. **Mais dados**: 25k samples por dataset (vs 7k na v2) = ~50k total

6. **Augmentation melhorada**:
   - Speed perturbation (0.9x–1.1x)
   - Volume scaling (0.6x–1.4x)
   - Gaussian noise mais agressivo
   - Time shift aleatório (±0.3s)

7. **LR schedule com warmup**: 2 épocas de warmup + cosine decay

8. **Classifier head maior**: 512→128→1 (vs 256→64→1)

9. **Patience aumentado**: 7 épocas (vs 5)

### Configuração
- **Modelo**: Whisper Base (74M params)
- **Datasets**: CORAA + MUPE (~50k samples)
- **LR**: 3e-5 (encoder: 3e-6)
- **Epochs**: até 30 (com early stopping patience=7)
- **Batch size**: 32

### Resultados v3
*(a ser preenchido após o treino)*

---

## Roadmap futuro (se necessário)

### Nível 4 — Dados reais de turn-taking
- Usar NURC-SP com anotações reais de fronteiras de turno
- Gravar dados de reuniões reais em português
- Combinar features de áudio + texto (multimodal)

### Nível 5 — Arquitetura avançada
- Whisper Small (244M params)
- Adicionar features linguísticas (completude sintática via LLM)
- Ensemble de modelos

### Limites teóricos
- Humanos discordam em ~10-15% dos casos de turn-taking
- Teto realista: 90-95%
- Algumas frases são genuinamente ambíguas ("Sim...", "É...")

---

## Referências

- Pipecat Smart Turn: https://github.com/pipecat-ai/smart-turn
- CORAA v1.1: https://huggingface.co/datasets/Racoci/CORAA-v1.1
- CORAA-MUPE-ASR: https://huggingface.co/datasets/nilc-nlp/CORAA-MUPE-ASR
- NURC-SP Corpus Minimo: https://huggingface.co/datasets/nilc-nlp/NURC-SP_Corpus_Minimo
- MLS Portuguese: https://huggingface.co/datasets/facebook/multilingual_librispeech