--- base_model: neuralmind/bert-base-portuguese-cased library_name: transformers pipeline_tag: token-classification language: - pt license: mit tags: - speech-acts - atos-de-fala - dialogue-acts - portuguese - pt-br - bertimbau - token-classification - bioes widget: - text: "Bom dia! Você pode revisar o relatório? Obrigado." --- # Atos de Fala PT-BR — classificador de atos de fala (span-level) Classificador de **atos de fala (speech acts)** para **português brasileiro**, em nível de **span**: decompõe um texto em trechos contíguos e rotula a intenção de cada um (pedir, perguntar, agradecer, discordar, prometer…). Até onde sabemos, é o **primeiro modelo aberto** de atos de fala span-level para PT-BR. Este é o **modelo completo** (BERTimbau fine-tunado, LoRA já mesclado) — carrega com `transformers` puro, sem PEFT, e roda no `pipeline("token-classification")`. - **Base:** `neuralmind/bert-base-portuguese-cased` (BERTimbau), token classifier **BIOES**. - **Treino:** dados sintéticos destilados de um *teacher* LLM (DeepSeek), balanceados por ato. - **Demo ao vivo:** https://huggingface.co/spaces/lucianfialho/atos-de-fala-ptbr - **Coleta colaborativa + dataset aberto:** https://atos-de-fala.vercel.app - **Código:** https://github.com/lucianfialho/atos-de-fala ## Taxonomia (13 atos → 53 labels BIOES) `informar · perguntar · concordar · discordar · pedir · sugerir · oferecer · prometer · saudar · agradecer · desculpar · despedir · expressar_emocao` (ISO 24617-2 + Searle). ## Como usar ```python from transformers import pipeline clf = pipeline("token-classification", model="lucianfialho/atos-de-fala-ptbr", aggregation_strategy="none") print(clf("Bom dia! Você pode revisar o relatório? Obrigado.")) # -> tags BIOES por token: B-saudar … E-saudar | B-pedir … E-pedir | B-agradecer … ``` Agrupe as tags BIOES (B/I/E/S por ato) em spans `(start, end, ato)`. ## Treino - ~5.000 exemplos sintéticos (frases PT-BR + anotação span-level) gerados por um teacher DeepSeek, com balanceamento por ato. - LoRA nos módulos de atenção (`query`/`value`) + cabeça `classifier`. O adapter foi **mesclado** (`merge_and_unload`) e exportado pra **ONNX int8** (roda no navegador). - **class-weights** (inverse-frequency loss): desbalanço — não domínio — era o gargalo; a loss ponderada tira os atos raros do zero sem precisar de mais dado. - **v3 (atual): + texto real.** Além do sintético, treina com **~500 anotações de texto dialógico real** (entrevistas Roda Viva/FAPESP, anotadas por um teacher e revisadas) — texto real fecha o gap de transferência que o sintético sozinho não fecha. ## Avaliação (honesta) Eval **sentence-level** no Porttinari (notícias; da Silva et al., PROPOR 2024), **zero-shot** (o modelo não treinou no Porttinari): | Métrica | v1 | v2 (class-weights) | **v3 (+ texto real)** | |---|---|---|---| | macro-F1 (13 atos) | 0,201 | 0,233 | **0,269** | | accuracy | 0,827 | 0,834 | **0,862** | Cada passo é melhora Pareto. `perguntar` 0,62 → **0,80** (o texto real de entrevista ajudou), `informar` ~0,93. Referência: o BERTimbau do paper, treinado **in-domain** no Porttinari, faz **0,295** macro-F1 — a v3 chega a ~91% disso **sendo zero-shot**. **Caveat de avaliação:** Porttinari é notícia → mede bem `informar`/`perguntar`, é cego aos atos sociais/comissivos (poucos/zero exemplos). Adicionar texto muito fora-de-domínio (ex: reviews) pode até **piorar** esse número sem ser pior no geral — falta um eval multi-domínio (em construção via coleta humana). ## Limitações - Texto de treino **sintético** (sabor "LLM"), carrega o **viés do teacher**. - Fronteiras de span podem errar por alguns caracteres. - Falta gold humano conversacional — sendo coletado no jogo aberto ([atos-de-fala.vercel.app](https://atos-de-fala.vercel.app)) para treinar versões futuras. ## Licença e contato MIT (respeite a licença do modelo base, BERTimbau). Base teórica: pragmática — atos de fala (Searle) + ISO 24617-2. Contato: lucian@metricasboss.com.br