Qualidade

Como corrigir nome próprio errado na transcrição

Nome, marca e jargão são o erro mais comum de qualquer transcrição automática. O campo glossary conserta isso por requisição, e tem limites que vale conhecer antes de montar a lista.

Todo sistema de transcrição erra nas mesmas palavras: nome de pessoa, nome de empresa, anglicismo, sigla interna. Não é coincidência nem defeito de um motor específico. São exatamente as palavras que menos aparecem em qualquer conjunto de treino, e o modelo escreve o que soa parecido e é comum.

"Bertuol" vira "bertual". "Gatto" vira "gatu". "Kubernetes" vira "cubernetes".

A parte boa é que você sabe quais palavras vão aparecer no seu áudio antes de mandar. Uma reunião interna tem o nome dos seus projetos. Uma ligação de suporte tem o nome dos seus produtos. Um podcast tem o convidado da semana. Essa lista já está no seu banco de dados.

O campo glossary

É um objeto { "o que ele ouve": "o que escrever" }, aplicado depois da transcrição e válido só para aquele áudio:

curl https://api.transcrevo.com/v1/transcripts \
  -H "Authorization: Bearer $TRANSCREVO_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "url": "https://example.com/reuniao.mp3",
    "glossary": { "gatu": "Gatto", "bertual": "Bertuol", "cubernetes": "Kubernetes" }
  }'

As regras:

  • Até 100 entradas, cada lado com até 80 caracteres.
  • A correção vale por sequência de palavras, então "mote gruto": "Mateus Gruto" funciona: duas palavras viram duas.
  • O intervalo de tempo é repartido entre as palavras trocadas, então os timestamps continuam válidos para legenda.
  • O que você manda tem preferência sobre as correções que já vêm de casa.
  • Nada disso muda a tarifa. Glossário é de graça.

A referência completa está em transcrições.

Como descobrir o que ele ouve

O lado esquerdo do glossário não é o nome certo escrito errado de qualquer jeito: é o que o sistema de fato escreve. Descobrir isso é empírico, e leva cinco minutos.

  1. Transcreva um áudio representativo sem glossário.
  2. Procure no text os termos que você esperava e não achou.
  3. Veja o que apareceu no lugar.
  4. Monte a entrada com exatamente aquilo.

Um detalhe que vale saber antes de investir tempo nisso: a saída não é determinística. O mesmo arquivo pode voltar com diferenças pequenas entre execuções, e não existe seed. Então o mesmo nome pode ser ouvido de duas ou três formas diferentes ao longo do acervo. Na prática isso significa que a entrada única raramente basta para um termo importante: mapeie as duas ou três grafias que você viu, todas para o mesmo destino.

{
	"glossary": {
		"bertual": "Bertuol",
		"bertuau": "Bertuol",
		"bertuol": "Bertuol"
	}
}

A terceira entrada parece inútil e não é: ela padroniza a capitalização.

O que o glossário não faz

Vale ser explícito, porque a expectativa errada aqui gera frustração.

Ele não muda como o modelo escuta. A correção acontece depois da transcrição, sobre o texto que saiu. Isso quer dizer que uma palavra que o sistema não escreveu de forma nenhuma, porque o áudio estava baixo demais ou alguém falou por cima, não volta pelo glossário. Não há o que reescrever.

Ele não resolve microfone ruim. Se o problema é distância, ruído ou codec degradado, o glossário conserta um sintoma de cada vez enquanto o resto do texto continua ruim.

Ele é literal, e isso corta dos dois lados. Uma entrada curta demais casa onde você não quer. Mapear "pai" para o nome de um cliente vai reescrever todo "pai" do áudio. Prefira sequências de duas palavras quando o termo for curto, e teste antes de rodar um lote inteiro.

Onde isso muda mais o resultado

Nossa medição de precisão em português dá 6,34% de WER em 2.000 trechos de fala espontânea brasileira, contra transcrição humana. Esse número é a média do material inteiro. A distribuição do erro não é uniforme: os nomes próprios concentram uma fatia grande dele, e são justamente as palavras que o leitor percebe.

É uma assimetria útil. Um transcrito com 6% de erro em palavras comuns lê bem; um transcrito que erra o nome do cliente em toda menção parece inútil, mesmo que o WER seja idêntico. Corrigir a fatia que o leitor nota custa uma lista.

Os números por fatia, com os limites conhecidos, estão em precisão e qualidade.

Uma lista por requisição, gerada do seu banco

Como o glossário vale só para aquele áudio, a montagem certa é dinâmica. Numa ligação de suporte, os nomes que importam são os do cliente daquele ticket. Numa reunião, os dos participantes do convite. Num episódio, o do convidado.

async function glossaryFor(ticketId: string) {
	const { customer, products } = await context(ticketId);
	return {
		...misheard(customer.name),
		...Object.fromEntries(products.flatMap((p) => Object.entries(misheard(p.name)))),
		...COMPANY_TERMS, // fixo: nome da empresa, produtos, siglas internas
	};
}

O teto de 100 entradas cabe folgado num caso desses, e ele existe por um motivo prático: uma lista de mil termos aumenta muito a chance de casamento indevido, e o texto piora em vez de melhorar.

O resto da qualidade

Duas outras coisas mudam o resultado antes de qualquer glossário. Informar language quando você já sabe o idioma evita que a detecção automática decida em áudio curto ou com ruído. E pedir speakers só quando você vai usar a separação, porque ela muda a tarifa (US$ 0,05 contra US$ 0,03 por hora) e não melhora o texto em nada.

Se o seu problema é saber quem falou, e não o que foi dito, o assunto é outro: o que é diarização e quando você precisa dela.

Todos os posts