Transformers documentation
MMS
Este modelo foi publicado em papers do HF em 2023-05-22 e contribuído para o Hugging Face Transformers em 2023-06-20.
MMS
Visão geral
O modelo MMS foi proposto em Scaling Speech Technology to 1,000+ Languages por Vineel Pratap, Andros Tjandra, Bowen Shi, Paden Tomasello, Arun Babu, Sayani Kundu, Ali Elkahky, Zhaoheng Ni, Apoorv Vyas, Maryam Fazel-Zarandi, Alexei Baevski, Yossi Adi, Xiaohui Zhang, Wei-Ning Hsu, Alexis Conneau, Michael Auli
O resumo do artigo é o seguinte:
Ampliar a cobertura de idiomas da tecnologia de fala tem o potencial de melhorar o acesso à informação para muitas mais pessoas. No entanto, a tecnologia de fala atual é restrita a cerca de cem idiomas, uma pequena fração dos mais de 7.000 idiomas falados ao redor do mundo. O projeto Massively Multilingual Speech (MMS) aumenta o número de idiomas suportados em 10 a 40 vezes, dependendo da tarefa. Os principais ingredientes são um novo dataset baseado em leituras de textos religiosos de domínio público e o aproveitamento eficaz do aprendizado auto-supervisionado. Construímos modelos pré-treinados wav2vec 2.0 cobrindo 1.406 idiomas, um único modelo multilíngue de reconhecimento automático de fala para 1.107 idiomas, modelos de síntese de fala para o mesmo número de idiomas, bem como um modelo de identificação de idioma para 4.017 idiomas. Experimentos mostram que nosso modelo multilíngue de reconhecimento de fala reduz mais pela metade a taxa de erro de palavra do Whisper em 54 idiomas do benchmark FLEURS, sendo treinado em uma pequena fração dos dados rotulados.
Aqui estão os diferentes modelos de código aberto no projeto MMS. Os modelos e o código foram originalmente lançados aqui. Adicionamos-os ao framework transformers, tornando-os mais fáceis de usar.
Reconhecimento Automático de Fala (ASR)
Os checkpoints dos modelos de ASR podem ser encontrados aqui: mms-1b-fl102, mms-1b-l1107, mms-1b-all. Para a melhor precisão, use o modelo mms-1b-all.
Dicas:
- Todos os modelos de ASR aceitam um array de float correspondente à forma de onda bruta do sinal de fala. A forma de onda bruta deve ser pré-processada com Wav2Vec2FeatureExtractor.
- Os modelos foram treinados usando classificação temporal conexionista (CTC), portanto a saída do modelo precisa ser decodificada usando Wav2Vec2CTCTokenizer.
- Você pode carregar pesos de adaptadores de linguagem diferentes para idiomas distintos por meio de load_adapter(). Os adaptadores de linguagem consistem em aproximadamente 2 milhões de parâmetros e, portanto, podem ser carregados de forma eficiente sob demanda.
Carregando
Por padrão, o MMS carrega os pesos do adaptador para o inglês. Se você deseja carregar os pesos do adaptador de outro idioma, certifique-se de especificar target_lang=<your-chosen-target-lang> bem como "ignore_mismatched_sizes=True.
A palavra-chave ignore_mismatched_sizes=True deve ser passada para permitir que a cabeça do modelo de linguagem seja redimensionada de acordo
com o vocabulário do idioma especificado.
Da mesma forma, o processador deve ser carregado com o mesmo idioma de destino
from transformers import AutoProcessor, Wav2Vec2ForCTC
model_id = "facebook/mms-1b-all"
target_lang = "fra"
processor = AutoProcessor.from_pretrained(model_id, target_lang=target_lang)
model = Wav2Vec2ForCTC.from_pretrained(model_id, target_lang=target_lang, ignore_mismatched_sizes=True, device_map="auto")Você pode ignorar com segurança um aviso como:
Some weights of Wav2Vec2ForCTC were not initialized from the model checkpoint at facebook/mms-1b-all and are newly initialized because the shapes did not match: - lm_head.bias: found shape torch.Size([154]) in the checkpoint and torch.Size([314]) in the model instantiated - lm_head.weight: found shape torch.Size([154, 1280]) in the checkpoint and torch.Size([314, 1280]) in the model instantiated You should probably TRAIN this model on a down-stream task to be able to use it for predictions and inference.
Se você deseja usar o pipeline de ASR, pode carregar o idioma de destino escolhido da seguinte forma:
from transformers import pipeline
model_id = "facebook/mms-1b-all"
target_lang = "fra"
pipe = pipeline(model=model_id, model_kwargs={"target_lang": "fra", "ignore_mismatched_sizes": True})Inferência
A seguir, vamos ver como podemos executar o MMS em inferência e alterar as camadas de adaptador após ter chamado ~PretrainedModel.from_pretrained. Primeiro, carregamos dados de áudio em diferentes idiomas usando o Datasets.
from datasets import Audio, load_dataset
# English
stream_data = load_dataset("mozilla-foundation/common_voice_13_0", "en", split="test", streaming=True)
stream_data = stream_data.cast_column("audio", Audio(sampling_rate=16000))
en_sample = next(iter(stream_data))["audio"]["array"]
# French
stream_data = load_dataset("mozilla-foundation/common_voice_13_0", "fr", split="test", streaming=True)
stream_data = stream_data.cast_column("audio", Audio(sampling_rate=16000))
fr_sample = next(iter(stream_data))["audio"]["array"]Em seguida, carregamos o modelo e o processador
from transformers import AutoProcessor, Wav2Vec2ForCTC
model_id = "facebook/mms-1b-all"
processor = AutoProcessor.from_pretrained(model_id)
model = Wav2Vec2ForCTC.from_pretrained(model_id, device_map="auto")Agora processamos os dados de áudio, passamos os dados de áudio processados para o modelo e transcrevemos a saída do modelo, da mesma forma que normalmente fazemos para Wav2Vec2ForCTC.
inputs = processor(en_sample, sampling_rate=16_000, return_tensors="pt").to(model.device)
with torch.no_grad():
outputs = model(**inputs).logits
ids = torch.argmax(outputs, dim=-1)[0]
transcription = processor.decode(ids)
# 'joe keton disapproved of films and buster also had reservations about the media'Agora podemos manter o mesmo modelo em memória e simplesmente alternar os adaptadores de idioma chamando a função conveniente load_adapter() para o modelo e set_target_lang() para o tokenizer. Passamos o idioma de destino como entrada - "fra" para francês.
processor.tokenizer.set_target_lang("fra")
model.load_adapter("fra")
inputs = processor(fr_sample, sampling_rate=16_000, return_tensors="pt").to(model.device)
with torch.no_grad():
outputs = model(**inputs).logits
ids = torch.argmax(outputs, dim=-1)[0]
transcription = processor.decode(ids)
# "ce dernier est volé tout au long de l'histoire romaine"Da mesma forma, o idioma pode ser alterado para todos os outros idiomas suportados. Por favor, consulte:
processor.tokenizer.vocab.keys()
para ver todos os idiomas suportados.
Para melhorar ainda mais o desempenho dos modelos de ASR, é possível utilizar a decodificação com modelo de linguagem. Consulte a documentação aqui para mais detalhes.
Síntese de Fala (TTS)
O MMS-TTS utiliza a mesma arquitetura de modelo que o VITS, que foi adicionado ao 🤗 Transformers na v4.33. O MMS treina um checkpoint de modelo separado para cada um dos mais de 1100 idiomas do projeto. Todos os checkpoints disponíveis podem ser encontrados no Hugging Face Hub: facebook/mms-tts, e a documentação de inferência sob VITS.
Inferência
Para usar o modelo MMS, primeiro atualize para a versão mais recente da biblioteca Transformers:
pip install --upgrade transformers accelerate
Como o modelo baseado em fluxo no VITS é não determinístico, é uma boa prática definir uma semente para garantir a reprodutibilidade das saídas.
- Para idiomas com alfabeto romano, como inglês ou francês, o tokenizer pode ser usado diretamente para pré-processar as entradas de texto. O exemplo de código a seguir executa uma passagem direta usando o checkpoint em inglês do MMS-TTS:
import torch
from transformers import VitsModel, VitsTokenizer, set_seed
tokenizer = VitsTokenizer.from_pretrained("facebook/mms-tts-eng")
model = VitsModel.from_pretrained("facebook/mms-tts-eng", device_map="auto")
inputs = tokenizer(text="Hello - my dog is cute", return_tensors="pt").to(model.device)
set_seed(555) # make deterministic
with torch.no_grad():
outputs = model(**inputs)
waveform = outputs.waveform[0]A forma de onda resultante pode ser salva como um arquivo .wav:
import scipy
scipy.io.wavfile.write("synthesized_speech.wav", rate=model.config.sampling_rate, data=waveform)Ou exibido em um Jupyter Notebook / Google Colab:
from IPython.display import Audio
Audio(waveform, rate=model.config.sampling_rate)Para determinados idiomas com alfabetos não romanos, como árabe, mandarim ou hindi, o pacote perl uroman é necessário para pré-processar os textos de entrada para o alfabeto romano.
Você pode verificar se precisa do pacote uroman para o seu idioma inspecionando o atributo is_uroman do
tokenizer pré-treinado:
from transformers import VitsTokenizer
tokenizer = VitsTokenizer.from_pretrained("facebook/mms-tts-eng")
print(tokenizer.is_uroman)Se necessário, você deve aplicar o pacote uroman aos seus textos de entrada antes de passá-los para o VitsTokenizer,
pois, atualmente, o tokenizer não suporta a execução do pré-processamento por conta própria.
Para fazer isso, primeiro clone o repositório uroman para sua máquina local e defina a variável bash UROMAN para o caminho local:
git clone https://github.com/isi-nlp/uroman.git
cd uroman
export UROMAN=$(pwd)Em seguida, você pode pré-processar a entrada de texto usando o seguinte trecho de código. Você pode usar a variável bash UROMAN para apontar para o repositório uroman, ou passar o diretório uroman como argumento para a função uromanize:
import os
import subprocess
import torch
from transformers import VitsModel, VitsTokenizer, set_seed
tokenizer = VitsTokenizer.from_pretrained("facebook/mms-tts-kor")
model = VitsModel.from_pretrained("facebook/mms-tts-kor", device_map="auto")
def uromanize(input_string, uroman_path):
"""Convert non-Roman strings to Roman using the `uroman` perl package."""
script_path = os.path.join(uroman_path, "bin", "uroman.pl")
command = ["perl", script_path]
process = subprocess.Popen(command, stdin=subprocess.PIPE, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
# Execute the perl command
stdout, stderr = process.communicate(input=input_string.encode())
if process.returncode != 0:
raise ValueError(f"Error {process.returncode}: {stderr.decode()}")
# Return the output as a string and skip the new-line character at the end
return stdout.decode()[:-1]
text = "이봐 무슨 일이야"
uromanized_text = uromanize(text, uroman_path=os.environ["UROMAN"])
inputs = tokenizer(text=uromanized_text, return_tensors="pt").to(model.device)
set_seed(555) # make deterministic
with torch.no_grad():
outputs = model(inputs["input_ids"])
waveform = outputs.waveform[0]Dicas:
- Os checkpoints do MMS-TTS são treinados em texto em minúsculas e sem pontuação. Por padrão, o
VitsTokenizernormaliza as entradas removendo qualquer capitalização e pontuação, para evitar passar caracteres fora do vocabulário para o modelo. Portanto, o modelo é agnóstico em relação à capitalização e à pontuação, então esses elementos devem ser evitados no prompt de texto. Você pode desabilitar a normalização definindonormalize=Falsena chamada ao tokenizer, mas isso levará a um comportamento inesperado e é desencorajado. - A taxa de fala pode ser variada definindo o atributo
model.speaking_ratepara um valor escolhido. Da mesma forma, a aleatoriedade do ruído é controlada pormodel.noise_scale:
import torch
from transformers import VitsModel, VitsTokenizer, set_seed
tokenizer = VitsTokenizer.from_pretrained("facebook/mms-tts-eng")
model = VitsModel.from_pretrained("facebook/mms-tts-eng", device_map="auto")
inputs = tokenizer(text="Hello - my dog is cute", return_tensors="pt").to(model.device)
# make deterministic
set_seed(555)
# make speech faster and more noisy
model.speaking_rate = 1.5
model.noise_scale = 0.8
with torch.no_grad():
outputs = model(**inputs)Identificação de Idioma (LID)
Estão disponíveis diferentes modelos de LID com base no número de idiomas que podem reconhecer - 126, 256, 512, 1024, 2048, 4017.
Inferência
Primeiro, instalamos o transformers e algumas outras bibliotecas
pip install torch accelerate datasets[audio] pip install --upgrade transformers
Em seguida, carregamos alguns exemplos de áudio por meio de datasets. Certifique-se de que os dados de áudio sejam amostrados a 16000 kHz.
from datasets import Audio, load_dataset
# English
stream_data = load_dataset("mozilla-foundation/common_voice_13_0", "en", split="test", streaming=True)
stream_data = stream_data.cast_column("audio", Audio(sampling_rate=16000))
en_sample = next(iter(stream_data))["audio"]["array"]
# Arabic
stream_data = load_dataset("mozilla-foundation/common_voice_13_0", "ar", split="test", streaming=True)
stream_data = stream_data.cast_column("audio", Audio(sampling_rate=16000))
ar_sample = next(iter(stream_data))["audio"]["array"]Em seguida, carregamos o modelo e o processador
from transformers import AutoFeatureExtractor, Wav2Vec2ForSequenceClassification
model_id = "facebook/mms-lid-126"
processor = AutoFeatureExtractor.from_pretrained(model_id)
model = Wav2Vec2ForSequenceClassification.from_pretrained(model_id, device_map="auto")Agora processamos os dados de áudio e passamos os dados de áudio processados para o modelo classificá-los em um idioma, da mesma forma que normalmente fazemos para modelos de classificação de áudio Wav2Vec2, como ehcalabres/wav2vec2-lg-xlsr-en-speech-emotion-recognition
# English
inputs = processor(en_sample, sampling_rate=16_000, return_tensors="pt").to(model.device)
with torch.no_grad():
outputs = model(**inputs).logits
lang_id = torch.argmax(outputs, dim=-1)[0].item()
detected_lang = model.config.id2label[lang_id]
# 'eng'
# Arabic
inputs = processor(ar_sample, sampling_rate=16_000, return_tensors="pt").to(model.device)
with torch.no_grad():
outputs = model(**inputs).logits
lang_id = torch.argmax(outputs, dim=-1)[0].item()
detected_lang = model.config.id2label[lang_id]
# 'ara'Para ver todos os idiomas suportados de um checkpoint, você pode imprimir os ids de idioma da seguinte forma:
processor.id2label.values()
Modelos pré-treinados de áudio
Modelos pré-treinados estão disponíveis em dois tamanhos diferentes - 300M , 1Bil.
Update on GitHubA arquitetura do MMS para ASR é baseada no modelo Wav2Vec2. Consulte a página de documentação do Wav2Vec2 para mais detalhes sobre como fazer o ajuste fino com modelos para diversas tarefas de nível inferior.
O MMS-TTS utiliza a mesma arquitetura de modelo que o VITS; consulte a página de documentação do VITS para referência da API.