英文

Whisper

Whisper是一个用于自动语音识别(ASR)和语音翻译的预训练模型。Whisper模型在680,000小时的标记数据上进行了训练,展示了在许多数据集和领域中的强大泛化能力,而无需进行微调。

Whisper模型是由OpenAI的Alec Radford等人在论文 Robust Speech Recognition via Large-Scale Weak Supervision 中提出的。原始代码存储库可以在 here 中找到。

更新:在论文发布后,Whisper的作者宣布了一个经过2.5倍的正则化训练的 large-v2 模型。这个 large-v2 模型在没有改变架构的情况下超越了大模型的性能。因此,建议使用 large-v2 模型替代原始的大模型。

声明:本模型卡片的内容部分由Hugging Face团队撰写,部分内容是从原始模型卡片中复制粘贴的。

模型详情

Whisper是基于Transformer的编码器-解码器模型,也称为序列到序列模型。它是使用大规模弱监督标注的680k小时带标签的语音数据进行训练的。

这些模型可以根据仅英文数据或多语言数据进行训练。仅英文的模型是在语音识别任务上进行训练的。多语言模型则是在语音识别和语音翻译两个任务上进行训练的。对于语音识别,模型预测的是与音频相同语言的转录文本。对于语音翻译,模型预测的是与音频不同语言的转录文本。

Whisper检查点有五种不同模型大小的配置。最小的四个模型是在仅英文或多语言数据上训练的。最大的检查点仅支持多语言。所有十个预训练检查点都可以在 Hugging Face Hub 中找到。以下是这些检查点的摘要和链接到Hub上的模型的表格:

Size Parameters English-only Multilingual
tiny 39 M 12314321 12315321
base 74 M 12316321 12317321
small 244 M 12318321 12319321
medium 769 M 12320321 12321321
large 1550 M x 12322321
large-v2 1550 M x 12323321

使用

若要转录音频样本,需要将模型与 WhisperProcessor 一起使用。

WhisperProcessor用于:

  • 预处理音频输入(将其转换为模型的对数梅尔频谱图)
  • 后处理模型输出(将其从标记转换为文本)
  • 通过传递适当的“上下文标记”信息,可以告诉模型需要执行的任务(转录或翻译)。这些上下文标记是一系列在解码过程开始时传递给解码器的标记,按照以下顺序传递:

  • 转录始终以“< |startoftranscript|>”标记开头
  • 第二个标记是语言标记(例如“< |en|>”表示英语)
  • 第三个标记是“任务标记”。它可以是两个值之一:“< |transcribe|>”表示语音识别或“< |translate|>”表示语音翻译
  • 此外,如果模型不应包括时间戳预测,则添加“< |notimestamps|>”标记
  • 因此,典型的上下文标记序列可能如下所示:

    <|startoftranscript|> <|en|> <|transcribe|> <|notimestamps|>
    

    这告诉模型要进行英语解码,任务是语音识别,并且不需要预测时间戳。

    这些标记可以被强制或非强制。如果强制,模型将被要求在每个位置预测每个标记。这样可以控制Whisper模型的输出语言和任务。如果不强制,Whisper模型将自动预测输出的语言和任务。

    可以相应地设置上下文标记:

    model.config.forced_decoder_ids = WhisperProcessor.get_decoder_prompt_ids(language="english", task="transcribe")
    

    这将强制模型预测英语的语音识别。

    转录

    英语到英语

    在这个例子中,上下文标记是“非强制”的,意味着模型会自动预测输出语言(英语)和任务(转录)。

    >>> from transformers import WhisperProcessor, WhisperForConditionalGeneration
    >>> from datasets import load_dataset
    
    >>> # load model and processor
    >>> processor = WhisperProcessor.from_pretrained("openai/whisper-large")
    >>> model = WhisperForConditionalGeneration.from_pretrained("openai/whisper-large")
    >>> model.config.forced_decoder_ids = None
    
    >>> # load dummy dataset and read audio files
    >>> ds = load_dataset("hf-internal-testing/librispeech_asr_dummy", "clean", split="validation")
    >>> sample = ds[0]["audio"]
    >>> input_features = processor(sample["array"], sampling_rate=sample["sampling_rate"], return_tensors="pt").input_features 
    
    >>> # generate token ids
    >>> predicted_ids = model.generate(input_features)
    >>> # decode token ids to text
    >>> transcription = processor.batch_decode(predicted_ids, skip_special_tokens=False)
    ['<|startoftranscript|><|en|><|transcribe|><|notimestamps|> Mr. Quilter is the apostle of the middle classes and we are glad to welcome his gospel.<|endoftext|>']
    
    >>> transcription = processor.batch_decode(predicted_ids, skip_special_tokens=True)
    [' Mr. Quilter is the apostle of the middle classes and we are glad to welcome his gospel.']
    

    可以通过设置skip_special_tokens=True来删除转录开始的上下文标记。

    法语到法语

    以下示例演示了如何通过适当设置解码器标识符来进行法语到法语的转录。

    >>> from transformers import WhisperProcessor, WhisperForConditionalGeneration
    >>> from datasets import Audio, load_dataset
    
    >>> # load model and processor
    >>> processor = WhisperProcessor.from_pretrained("openai/whisper-large")
    >>> model = WhisperForConditionalGeneration.from_pretrained("openai/whisper-large")
    >>> forced_decoder_ids = processor.get_decoder_prompt_ids(language="french", task="transcribe")
    
    >>> # load streaming dataset and read first audio sample
    >>> ds = load_dataset("common_voice", "fr", split="test", streaming=True)
    >>> ds = ds.cast_column("audio", Audio(sampling_rate=16_000))
    >>> input_speech = next(iter(ds))["audio"]
    >>> input_features = processor(input_speech["array"], sampling_rate=input_speech["sampling_rate"], return_tensors="pt").input_features
    
    >>> # generate token ids
    >>> predicted_ids = model.generate(input_features, forced_decoder_ids=forced_decoder_ids)
    >>> # decode token ids to text
    >>> transcription = processor.batch_decode(predicted_ids)
    ['<|startoftranscript|><|fr|><|transcribe|><|notimestamps|> Un vrai travail intéressant va enfin être mené sur ce sujet.<|endoftext|>']
    
    >>> transcription = processor.batch_decode(predicted_ids, skip_special_tokens=True)
    [' Un vrai travail intéressant va enfin être mené sur ce sujet.']
    

    翻译

    将任务设置为“翻译”会强制Whisper模型执行语音翻译。

    法语到英语

    >>> from transformers import WhisperProcessor, WhisperForConditionalGeneration
    >>> from datasets import Audio, load_dataset
    
    >>> # load model and processor
    >>> processor = WhisperProcessor.from_pretrained("openai/whisper-large")
    >>> model = WhisperForConditionalGeneration.from_pretrained("openai/whisper-large")
    >>> forced_decoder_ids = processor.get_decoder_prompt_ids(language="french", task="translate")
    
    >>> # load streaming dataset and read first audio sample
    >>> ds = load_dataset("common_voice", "fr", split="test", streaming=True)
    >>> ds = ds.cast_column("audio", Audio(sampling_rate=16_000))
    >>> input_speech = next(iter(ds))["audio"]
    >>> input_features = processor(input_speech["array"], sampling_rate=input_speech["sampling_rate"], return_tensors="pt").input_features
    
    >>> # generate token ids
    >>> predicted_ids = model.generate(input_features, forced_decoder_ids=forced_decoder_ids)
    >>> # decode token ids to text
    >>> transcription = processor.batch_decode(predicted_ids, skip_special_tokens=True)
    [' A very interesting work, we will finally be given on this subject.']
    

    评估

    以下代码片段展示了如何在 LibriSpeech test-clean 上评估Whisper Large:

    >>> from datasets import load_dataset
    >>> from transformers import WhisperForConditionalGeneration, WhisperProcessor
    >>> import torch
    >>> from evaluate import load
    
    >>> librispeech_test_clean = load_dataset("librispeech_asr", "clean", split="test")
    
    >>> processor = WhisperProcessor.from_pretrained("openai/whisper-large")
    >>> model = WhisperForConditionalGeneration.from_pretrained("openai/whisper-large").to("cuda")
    
    >>> def map_to_pred(batch):
    >>>     audio = batch["audio"]
    >>>     input_features = processor(audio["array"], sampling_rate=audio["sampling_rate"], return_tensors="pt").input_features
    >>>     batch["reference"] = processor.tokenizer._normalize(batch['text'])
    >>> 
    >>>     with torch.no_grad():
    >>>         predicted_ids = model.generate(input_features.to("cuda"))[0]
    >>>     transcription = processor.decode(predicted_ids)
    >>>     batch["prediction"] = processor.tokenizer._normalize(transcription)
    >>>     return batch
    
    >>> result = librispeech_test_clean.map(map_to_pred)
    
    >>> wer = load("wer")
    >>> print(100 * wer.compute(references=result["reference"], predictions=result["prediction"]))
    3.0003583080317572
    

    长篇转录

    Whisper模型本质上设计用于处理长达30秒的音频样本。然而,通过使用分块算法,它可以用于转录任意长度的音频样本。在实例化管道时,可以通过设置chunk_length_s=30启用分块。启用分块后,可以以批量推理的方式运行管道。还可以通过传递return_timestamps=True来预测序列级别的时间戳:

    >>> import torch
    >>> from transformers import pipeline
    >>> from datasets import load_dataset
    
    >>> device = "cuda:0" if torch.cuda.is_available() else "cpu"
    
    >>> pipe = pipeline(
    >>>   "automatic-speech-recognition",
    >>>   model="openai/whisper-large",
    >>>   chunk_length_s=30,
    >>>   device=device,
    >>> )
    
    >>> ds = load_dataset("hf-internal-testing/librispeech_asr_dummy", "clean", split="validation")
    >>> sample = ds[0]["audio"]
    
    >>> prediction = pipe(sample.copy(), batch_size=8)["text"]
    " Mr. Quilter is the apostle of the middle classes, and we are glad to welcome his gospel."
    
    >>> # we can also return timestamps for the predictions
    >>> prediction = pipe(sample.copy(), batch_size=8, return_timestamps=True)["chunks"]
    [{'text': ' Mr. Quilter is the apostle of the middle classes and we are glad to welcome his gospel.',
      'timestamp': (0.0, 5.44)}]
    

    有关分块算法的更多详细信息,请参阅博客文章 ASR Chunking

    微调

    预训练的Whisper模型在泛化到不同数据集和领域方面表现出良好的能力。然而,通过对少量带标签数据进行微调,可以进一步提高模型在某些语言和任务上的预测能力。博客文章 Fine-Tune Whisper with ? Transformers 提供了有关使用仅有5小时标记数据进行Whisper模型微调的逐步指南。

    评估使用

    这些模型的主要目标用户是研究当前模型的稳健性、泛化性、能力、偏差和约束的AI研究人员。然而,Whisper作为一个ASR解决方案对于开发人员也可能非常有用,尤其是英语语音识别。我们意识到,一旦模型发布,就不可能将访问限制在仅限于“预期”使用上,也无法在其周围建立合理的指导方针。

    这些模型主要在ASR和将语音翻译成英语的任务上进行了训练和评估。它们在大约10种语言的ASR结果上表现出强大的功能。它们可能具有额外的能力,特别是在某些任务(如声音活动检测、说话人分类或说话人分割)上进行微调,但在这些领域尚未进行过全面的评估。我们强烈建议用户在部署这些模型之前在特定的上下文和领域中进行全面的评估。

    特别是,我们警告不要使用Whisper模型转录未经个人同意的录音,或者声称使用这些模型进行任何类型的主观分类。我们建议不要在决策环境等高风险领域使用它们,因为准确度的缺陷可能导致显著的结果缺陷。这些模型旨在进行语音转录和翻译,不仅未经评估,而且不适用于用于推断人类属性。

    训练数据

    这些模型是在从互联网收集的680,000小时音频及其对应的转录文本上进行训练的。其中65%的数据(即438,000小时)是英语语音和匹配的英语转录文本,大约18%的数据(即126,000小时)是非英语语音和英语转录文本,最后17%的数据(即117,000小时)是非英语语音和对应的转录文本。这些非英语数据代表了98种不同的语言。

    the accompanying paper 中所讨论的那样,我们发现在给定语言上的转录性能与我们在该语言中使用的训练数据量直接相关。

    性能和限制

    我们的研究表明,与许多现有的ASR系统相比,这些模型在口音、背景噪音、技术语言以及从多种语言零翻译为英语方面具有更好的鲁棒性;在语音识别和翻译方面的准确性接近最先进水平。

    然而,由于模型使用大规模噪声数据以弱监督方式进行训练,其预测可能包含实际上不在音频输入中的文本(即幻觉)。我们假设这是因为模型结合了对语音下一个词进行预测和对音频进行转录的努力,基于其对语言的一般知识。

    我们的模型在不同语言上的表现不平衡,并且我们观察到在低资源和/或低可发现性的语言或具有较少训练数据的语言上的准确性较低。这些模型在特定语言的不同口音和方言上的表现也有差异,这可能包括对不同性别、种族、年龄或其他人口统计标准的说话者的更高词错误率。我们的完整评估结果在 the paper accompanying this release 中提供。

    此外,模型的序列到序列架构容易生成重复文本,尽管可以通过束搜索和温度调度在一定程度上缓解这一问题,但并非完美。有关这些限制的进一步分析在 the paper 中提供。在低资源和/或低可发现性的语言上,这种行为和幻觉可能会更严重。

    更广泛的影响

    我们预计Whisper模型的转录功能可能被用于改进辅助工具。虽然Whisper模型不能直接用于实时转录,但其速度和大小表明其他人可以在其基础上构建应用程序,实现近实时的语音识别和翻译。建立在Whisper模型上的有益应用程序的真正价值表明,这些模型的表现差异可能具有实际的经济影响。

    发布Whisper还涉及潜在的双重使用问题。虽然我们希望该技术主要用于有益目的,但使得ASR技术更易获得可能会使更多的参与者能够建立功能强大的监视技术或扩大现有的监视工作,因为其速度和准确性可实现大规模音频通信的经济实惠的自动转录和翻译。此外,这些模型可能具有一些识别特定个体的能力,这引发了与双重使用和不同表现相关的安全问题。实际上,我们预计转录成本不是扩大监视项目的限制因素。

    BibTeX条目和引用信息

    @misc{radford2022whisper,
      doi = {10.48550/ARXIV.2212.04356},
      url = {https://arxiv.org/abs/2212.04356},
      author = {Radford, Alec and Kim, Jong Wook and Xu, Tao and Brockman, Greg and McLeavey, Christine and Sutskever, Ilya},
      title = {Robust Speech Recognition via Large-Scale Weak Supervision},
      publisher = {arXiv},
      year = {2022},
      copyright = {arXiv.org perpetual, non-exclusive license}
    }