Whisper OpenAI开源语音识别模型

介绍

Whisper 是一个自动语音识别(ASR,Automatic Speech Recognition)系统,OpenAI 通过从网络上收集了 68 万小时的多语言(98 种语言)和多任务(multitask)监督数据对 Whisper 进行了训练。OpenAI 认为使用这样一个庞大而多样的数据集,可以提高对口音、背景噪音和技术术语的识别能力。除了可以用于语音识别,Whisper 还能实现多种语言的转录,以及将这些语言翻译成英语。

语音转文字在许多不同领域都有着广泛的应用。以下是一些例子:

1.字幕制作:语音转文字可以帮助视频制作者快速制作字幕,这在影视行业和网络视频领域非常重要。通过使用语音转文字工具,字幕制作者可以更快地生成字幕,从而缩短制作时间,节省人工成本,并提高制作效率。

2.法律文书:在法律领域,语音转文字可以帮助律师和律所将听证会、辩论和其他法律活动的录音转化为文字文档。这些文档可以用于研究、起草文件和法律分析等目的,从而提高工作效率。

3.医疗文档:医疗专业人员可以使用语音转文字技术来记录病人的医疗记录、手术记录和其他相关信息。这可以减少错误和遗漏,提高记录的准确性和完整性,为患者提供更好的医疗服务。

4.市场调查和分析:语音转文字可以帮助企业快速收集和分析消费者反馈、电话调查和市场研究结果等数据。这可以帮助企业更好地了解其目标受众和市场趋势,从而制定更有效的营销策略和商业计划。

一、Whisper 模型及配置

目前 Whisper 模型的大小,及其内存要求和相对速度:

大小 参数 纯英文模型 多语言模型 所需显存 相对速度
tiny 39 M tiny.en tiny ~1 GB ~32x
base 74 M base.en base ~1 GB ~16x
small 244 M small.en small ~2 GB ~6x
medium 769 M medium.en medium ~5 GB ~2x
large 1550 M N/A large ~10 GB 1x

Whisper 参数

参数名 描述 默认值
[–model {tiny.en,tiny,base.en,base,small.en,small,medium.en,medium,large}] –model 模型类型 从小到大的不同模型,分别为tiny.en,tiny,base.en,base,small.en,small,medium.en,medium,large
[–model_dir MODEL_DIR] 存储模型文件的路径 ~/.cache/whisper
[–device DEVICE] 使用Pytorch的设备(CPU or GPU) CUDA
[–output_dir OUTPUT_DIR] – output_dir 保存输出的路径 None
[–verbose VERBOSE] 是否打印过程和debug信息 True
[–task {transcribe,translate}] –task 任务:是否执行 X->X 语音识别 (‘transcribe’) 或 X->英文翻译 (‘translate’) transcribe
[–language {af,am,ar,as,az,ba,be,bg,bn,bo,br,bs,ca,cs,cy,da,de,el,en,es,et,eu,fa,fi,fo,fr,gl,gu,ha,https://www.zhihu.com/search?q=haw&search_source=Entity&hybrid_search_source=Entity&hybrid_search_extra=%7B%22sourceType%22%3A%22answer%22%2C%22sourceId%22%3A2778034018%7D,hi,hr,ht,hu,hy,id,is,it,iw,ja,jw,ka,kk,km,kn,ko,la,lb,ln,lo,lt,lv,mg,mi,mk,ml,mn,mr,ms,mt,my,ne,nl,nn,no,oc,pa,pl,ps,pt,ro,ru,sa,sd,si,sk,sl,sn,so,sq,sr,su,sv,sw,ta,te,tg,th,tk,tl,tr,tt,uk,ur,uz,vi,yi,yo,zh,Afrikaans,Albanian,Amharic,Arabic,Armenian,Assamese,Azerbaijani,Bashkir,Basque,Belarusian,Bengali,Bosnian,Breton,Bulgarian,Burmese,Castilian,Catalan,Chinese,Croatian,Czech,Danish,Dutch,English,Estonian,Faroese,Finnish,Flemish,French,Galician,Georgian,German,Greek,Gujarati,Haitian,Haitian Creole,Hausa,Hawaiian,Hebrew,Hindi,Hungarian,Icelandic,Indonesian,Italian,Japanese,Javanese,Kannada,Kazakh,Khmer,Korean,Lao,Latin,Latvian,Letzeburgesch,Lingala,Lithuanian,Luxembourgish,Macedonian,Malagasy,Malay,Malayalam,Maltese,Maori,Marathi,Moldavian,Moldovan,Mongolian,Myanmar,Nepali,Norwegian,Nynorsk,Occitan,Panjabi,Pashto,Persian,Polish,Portuguese,Punjabi,Pushto,Romanian,Russian,Sanskrit,Serbian,Shona,Sindhi,Sinhala,Sinhalese,Slovak,Slovenian,Somali,Spanish,Sundanese,Swahili,Swedish,Tagalog,Tajik,Tamil,Tatar,Telugu,Thai,Tibetan,Turkish,Turkmen,Ukrainian,Urdu,Uzbek,Valencian,Vietnamese,Welsh,Yiddish,Yoruba}] –language 语言:原音频中使用的语言
[–temperature TEMPERATURE] –temperature 温度参数:文章使用的是基于温度系数的采样,这个参数就是采样的温度系数
[–best_of BEST_OF] 在温度非0时的抽样使用的候选词数 5
[–beam_size BEAM_SIZE] beam搜索中的beam数据的数目,仅在温度为0时可用 5
[–patience PATIENCE] https://www.zhihu.com/search?q=beam%E8%A7%A3%E7%A0%81&search_source=Entity&hybrid_search_source=Entity&hybrid_search_extra=%7B%22sourceType%22%3A%22answer%22%2C%22sourceId%22%3A2778034018%7D是使用的可选耐性系数optional patience value to use in beam decoding, as in https://link.zhihu.com/?target=https%3A//arxiv.org/abs/2204.05424, the default(1.0) is equivalent to conventional beam search (default: None) None
[–length_penalty LENGTH_PENALTY] – length_penalty 惩罚系数:用于正则化的optional token length penalty coefficient (alpha) as in https://link.zhihu.com/?target=https%3A//arxiv.org/abs/1609.08144, usessimple length normalization by default (default: None)可选的惩罚系数 α \alpha α None
[–suppress_tokens SUPPRESS_TOKENS] 采样期间要抑制的token ID的逗号分隔列表;“-1”时将抑制大多数特殊字符(https://www.zhihu.com/search?q=%E5%B8%B8%E7%94%A8%E6%A0%87%E7%82%B9%E7%AC%A6%E5%8F%B7&search_source=Entity&hybrid_search_source=Entity&hybrid_search_extra=%7B%22sourceType%22%3A%22answer%22%2C%22sourceId%22%3A2778034018%7D除外) -1
[–initial_prompt INITIAL_PROMPT] 可选文本,作为第一个窗口的提示。 None
[–https://www.zhihu.com/search?q=condition_on_previous_text%20CONDITION_ON_PREVIOUS_TEXT&search_source=Entity&hybrid_search_source=Entity&hybrid_search_extra=%7B%22sourceType%22%3A%22answer%22%2C%22sourceId%22%3A2778034018%7D] –condition_on_previous_text 先前文本使用状况:如果为 True,则提供模型的先前输出作为下一个窗口的提示; 禁用可能会使文本跨窗口不一致,但模型变得不太容易陷入故障
[–fp16 FP16] 在fp16中进行推理 True
[–temperature_increment_on_fallback TEMPERATURE_INCREMENT_ON_FALLBACK] –temperature_increment_on_fallback 回退温度系数:当解码未能满足以下任一阈值时的回退增加的温度 0.2
[–compression_ratio_https://www.zhihu.com/search?q=threshold%20COMPRESSION_RATIO_THRESHOLD&search_source=Entity&hybrid_search_source=Entity&hybrid_search_extra=%7B%22sourceType%22%3A%22answer%22%2C%22sourceId%22%3A2778034018%7D] compression_ratio_threshold 压缩率阈值:如果gzip压缩比高于这个值,则认为解码失败 2.4
[–logprob_threshold LOGPROB_THRESHOLD] 如果平均对数概率低于此值,则将解码视为失败 -1.0
[–https://www.zhihu.com/search?q=no_speech_threshold%20NO_SPEECH_THRESHOLD&search_source=Entity&hybrid_search_source=Entity&hybrid_search_extra=%7B%22sourceType%22%3A%22answer%22%2C%22sourceId%22%3A2778034018%7D] –no_speech_threshold 静音阈值:如果 < nospeech
[–threads THREADS] 使用Pytorch CPU做推理时,使用的CPU线程数 0

评测数据

模型测试表

  1. 原始模型字错率测试表。
使用模型 指定语言 aishell_test test_net test_meeting 下载地址 CTranslate2模型下载地址
whisper-tiny Chinese 0.31898 0.40482 0.75332 https://pan.baidu.com/s/1q8xHr71XPe1dnRHv2IzldQ?pwd=wjrf https://pan.baidu.com/s/1Rg8KM1gDKLw8kObZEJQG1A?pwd=hnhe
whisper-base Chinese 0.22196 0.30404 0.50378 https://pan.baidu.com/s/1q8xHr71XPe1dnRHv2IzldQ?pwd=wjrf https://pan.baidu.com/s/1Rg8KM1gDKLw8kObZEJQG1A?pwd=hnhe
whisper-small Chinese 0.13897 0.18417 0.31154 https://pan.baidu.com/s/1q8xHr71XPe1dnRHv2IzldQ?pwd=wjrf https://pan.baidu.com/s/1Rg8KM1gDKLw8kObZEJQG1A?pwd=hnhe
whisper-medium Chinese 0.09538 0.13591 0.26669 https://pan.baidu.com/s/1q8xHr71XPe1dnRHv2IzldQ?pwd=wjrf https://pan.baidu.com/s/1Rg8KM1gDKLw8kObZEJQG1A?pwd=hnhe
whisper-large Chinese 0.08969 0.12933 0.23439 https://pan.baidu.com/s/1q8xHr71XPe1dnRHv2IzldQ?pwd=wjrf https://pan.baidu.com/s/1Rg8KM1gDKLw8kObZEJQG1A?pwd=hnhe
whisper-large-v2 Chinese 0.08817 0.12332 0.26547 https://pan.baidu.com/s/1q8xHr71XPe1dnRHv2IzldQ?pwd=wjrf https://pan.baidu.com/s/1Rg8KM1gDKLw8kObZEJQG1A?pwd=hnhe
  1. 微调AIShell数据集后字错率测试表。
使用模型 指定语言 数据集 aishell_test test_net test_meeting 下载地址 CTranslate2模型下载地址
whisper-tiny Chinese https://openslr.magicdatatech.com/resources/33/ 0.13043 0.4463 0.57728 https://pan.baidu.com/s/1hIximy9ddN3cMHN4_VdhnQ?pwd=nfc2 https://pan.baidu.com/s/1H-OBD9L0hYV-M_WoPEbiJA?pwd=8hbb
whisper-base Chinese https://openslr.magicdatatech.com/resources/33/ 0.08999 0.33089 0.40713 https://pan.baidu.com/s/1hIximy9ddN3cMHN4_VdhnQ?pwd=nfc2 https://pan.baidu.com/s/1H-OBD9L0hYV-M_WoPEbiJA?pwd=8hbb
whisper-small Chinese https://openslr.magicdatatech.com/resources/33/ 0.05452 0.19831 0.24229 https://pan.baidu.com/s/1hIximy9ddN3cMHN4_VdhnQ?pwd=nfc2 https://pan.baidu.com/s/1H-OBD9L0hYV-M_WoPEbiJA?pwd=8hbb
whisper-medium Chinese https://openslr.magicdatatech.com/resources/33/ 0.03681 0.13073 0.16939 https://pan.baidu.com/s/1hIximy9ddN3cMHN4_VdhnQ?pwd=nfc2 https://pan.baidu.com/s/1H-OBD9L0hYV-M_WoPEbiJA?pwd=8hbb
whisper-large-v2 Chinese https://openslr.magicdatatech.com/resources/33/ 0.03078 0.11359 0.14079 https://pan.baidu.com/s/1hIximy9ddN3cMHN4_VdhnQ?pwd=nfc2 https://pan.baidu.com/s/1H-OBD9L0hYV-M_WoPEbiJA?pwd=8hbb
whisper-tiny Chinese WenetSpeech 0.21009 0.29352 0.41506 https://pan.baidu.com/s/18l6K59nP0j3XXmEQZ_Up_g?pwd=x7ay https://pan.baidu.com/s/1X37l5pvbpGmRhDkRkgYCQw?pwd=vm4k
whisper-large-v2 Chinese WenetSpeech 0.05545 0.10280 0.20719
  1. 未加速和加速后的推理速度测试表,使用GPU为GTX3090(24G)。
使用模型 原生模型实时率(float16) 转换CTranslate2加速后实时率(float16) 转换CTranslate2加速后实时率(int8_float16)
whisper-tiny 0.03 0.06 0.06
whisper-base 0.04 0.06 0.06
whisper-small 0.08 0.08 0.08
whisper-medium 0.13 0.10 0.10
whisper-large-v2 0.19 0.12 0.12
  1. 经过处理的数据列表,添加标点符号的模型为PunctuationModel。
数据列表处理方式 AiShell WenetSpeech
添加标点符号 https://pan.baidu.com/s/1Qzalcy0R2SyrOBSxtezN0A?pwd=v45t https://pan.baidu.com/s/1XrnD_YLYWYUs65lq4StzTg?pwd=hv3i
添加标点符号和时间戳 https://pan.baidu.com/s/1zC3CTqPrNkhDIwAwqlZ6kw?pwd=xun4 https://pan.baidu.com/s/1JrlQ97fZfCD-JEbW7Td_2g?pwd=97ki

重要说明:

  1. 在评估的时候移除模型输出的标点符号,并把繁体中文转成简体中文。
  2. aishell_test为AIShell的测试集,test_nettest_meeting为WenetSpeech的测试集。
  3. RTF= 所有音频总时间(单位秒) / ASR识别所有音频处理时间(单位秒)。
  4. 测试速度的音频为dataset/test.wav,时长为8秒。
  5. 训练数据使用的是带标点符号的数据,字错率高一点。

二、安装 ffmpeg

  • ffmpeg

    Win

    Scoop 包管理工具去下载,具体安装方法借鉴 https://zhuanlan.zhihu.com/p/561204256
    scoop install ffmpeg
    

    Mac (打开终端(Terminal), 用 homebrew 安装):

    brew install ffmpeg --with-libvorbis --with-sdl2 --with-theora
    

    Linux:

    apt-get install ffmpeg libavcodec-extra
    
    # contos7
    sudo rpm --import http://li.nux.ro/download/nux/RPM-GPG-KEY-nux.ro
    sudo rpm -Uvh http://li.nux.ro/download/nux/dextop/el7/x86_64/nux-dextop-release-0-5.el7.nux.noarch.rpm
    sudo yum install ffmpeg ffmpeg-devel -y
    

三、python的实现

准备环境

conda create -n whisper python=3.9
conda activate whisper

# 一
git clone https://gitee.com/mirrors/openai-whisper.git
python setup.py install

# 二
pip install git+https://github.com/openai/whisper.git 
pip install --upgrade --no-deps --force-reinstall git+https://github.com/openai/whisper.git

pip install -U openai-whisper
pip install setuptools-rust

# 验证调用
whisper audio.mp3 --model medium --language Chinese
pip install setuptools-rust

git clone https://gitee.com/mirrors/openai-whisper.git
python setup.py install

代码

# 音频的前5分钟输出成单独的mp3文件
from pydub import AudioSegment

song = AudioSegment.from_mp3("test.mp3")
# PyDub handles time in milliseconds
five_minutes = 5 * 60 * 1000
first_5_minutes = song[:five_minutes]
first_5_minutes.export("test.mp3", format="mp3")
import whisper
import arrow

# 定义模型、音频地址、录音开始时间
def excute(model_name, file_path, start_time):
    model = whisper.load_model(model_name)
    result = model.transcribe(file_path)
    for segment in result["segments"]:
        now = arrow.get(start_time)
        start = now.shift(seconds=segment["start"]).format("YYYY-MM-DD HH:mm:ss")
        end = now.shift(seconds=segment["end"]).format("YYYY-MM-DD HH:mm:ss")
        print("【"+start+"->" +end+"】:" + segment["text"])

if __name__ == '__main__':
    excute("base", "55555.mp3", "2023-06-03 16:23:00")
import whisper

# device是计算引擎,可以选择cpu,或者cuda(也就是gpu),不填默认为cpu,有显卡并且显存满足你所选的模型大小可以正常跑起来,不然会报内存错误。
# download_root是模型保存以及读取路径,不填默认为系统用户下的路径,我的为例C:\Users\heyj01\.cache\whisper,第一次加载模型,模型没有在路径下会下载模型到download_root路径下。
Model = 'large-v2' #@param ['tiny.en', 'tiny', 'base.en', 'base', 'small.en', 'small', 'medium.en', 'medium', 'large', 'large-v2']
whisper_model = whisper.load_model("large", device='gpu')
result = whisper_model.transcribe(r"C:\Users\win10\Downloads\test.wav", fp16="False")
print(", ".join([i["text"] for i in result["segments"] if i is not None]))
  • huggingface

    !pip install zhconv
    !pip install whisper
    !pip install tqdm
    !pip install ffmpeg-python
    !pip install transformers
    !pip install librosa
    
    from transformers import WhisperProcessor, WhisperForConditionalGeneration
    
    import librosa
    import torch
    from zhconv import convert
    import warnings
    
    warnings.filterwarnings("ignore")
    
    audio_file = f"test.wav"
    #load audio file
    audio, sampling_rate = librosa.load(audio_file, sr=16_000)
    
    # # audio
    # display.Audio(audio_file, autoplay=True)
    
    # load model and processor
    processor = WhisperProcessor.from_pretrained("openai/whisper-large-v2")
    model = WhisperForConditionalGeneration.from_pretrained("openai/whisper-large-v2")
    tokenizer = WhisperProcessor.from_pretrained("openai/whisper-large-v2")
    
    processor.save_pretrained("openai/model/whisper-large-v2")
    model.save_pretrained("openai/model/whisper-large-v2")
    tokenizer.save_pretrained("openai/model/whisper-large-v2")
    
    processor = WhisperProcessor.from_pretrained("openai/model/whisper-large-v2")
    model = WhisperForConditionalGeneration.from_pretrained("openai/model/whisper-large-v2")
    tokenizer = WhisperProcessor.from_pretrained("openai/model/whisper-large-v2")
    
    # load dummy dataset and read soundfiles
    # ds = load_dataset("common_voice", "fr", split="test", streaming=True)
    # ds = ds.cast_column("audio", datasets.Audio(sampling_rate=16_000))
    # input_speech = next(iter(ds))["audio"]["array"]
    model.config.forced_decoder_ids = processor.get_decoder_prompt_ids(language="zh", task="transcribe")
    input_features = processor(audio, return_tensors="pt").input_features
    predicted_ids = model.generate(input_features)
    # transcription = processor.batch_decode(predicted_ids)
    
    transcription = processor.batch_decode(predicted_ids, skip_special_tokens=True)
    print(transcription)
    print('转化为简体结果:', convert(transcription, 'zh-cn'))
    
  • transformers

    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-v2",
      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"]
    
    # we can also return timestamps for the predictions
    prediction = pipe(sample.copy(), batch_size=8, return_timestamps=True)["chunks"]
    

出参

{ 
'id': 1, 
'seek': 0,  
'start': 4.8,  //起始时间
'end': 6.7,    //结束时间
'text': '你不要去博这个东西',  
'tokens': [50604, 2166, 11962, 6734, 5322, 248, 15368, 38409, 16220, 50699],  
'temperature': 0.0,    //在语音转文本模型生成结果时,控制输出随机性和多样性的参数
'avg_logprob': -0.2088493855794271,  //语音转文字模型预测的置信度评分的平均值
'compression_ratio': 1.649402390438247,  
'no_speech_prob': 0.5881261825561523 //指模型在某段时间内检测到没有语音信号的概率
}

//置信度参数你可以用来提高识别准确率

四、加速

HuggingFace

Whisper JAX - a Hugging Face Space by sanchit-gandhi

HuggingFace 新版本Whisper速度提升70倍

Google’s JAX是一个用于高性能数值计算和机器学习的Python库,它可以让用户使用类似NumPy的API进行计算,并且能够在GPU和TPU等加速设备上进行自动的优化和并行化处理。JAX提供了一些强大的功能,包括自动微分,高阶梯度计算和动态编译等,这使得它成为许多机器学习算法的理想实现平台。

与其他深度学习框架类似,JAX提供了一个自动微分系统,可以轻松地计算复杂函数的梯度,并且可以支持高阶导数的计算。此外,JAX还提供了一种称为jax.jit()的动态编译器,可以将Python函数转换为高效的机器码,以实现更快的执行速度和更低的内存占用。

JAX的一个独特之处在于它可以使用XLA(Accelerated Linear Algebra)库来自动并行化和优化计算,从而在GPU和TPU等加速设备上获得更好的性能。此外,JAX还提供了一些用于构建神经网络的高级API,例如jax.nn模块和jax.experimental.stax模块,以帮助用户更轻松地构建复杂的神经网络。

总的来说,JAX是一个非常强大的数值计算和机器学习库,可以帮助用户更轻松地构建高效的模型,并在加速设备上获得更好的性能。

  • Whisper现已在Jax上运行,能够在短短几秒钟内转录1小时的音频。
  • 该模型本身已经是最强大的语音转文本系统之一,现在加上了惊人的速度,使用起来几乎是不费吹灰之力。
  • 尽管仍有缺点,但这是社区取得的卓越成果。

faster-whisper模型

!pip install faster-whisper
!pip install "faster-whisper @ https://github.com/guillaumekln/faster-whisper/archive/refs/heads/master.tar.gz"
!pip install zhconv -i https://pypi.tuna.tsinghua.edu.cn/simple

from faster_whisper import WhisperModel
from zhconv import convert
import time

model_size = "large-v2"
# Run on GPU with FP16
# model = WhisperModel(model_size, device="cuda", compute_type="float16")
# or run on GPU with INT8
# model = WhisperModel(model_size, device="cuda", compute_type="int8_float16")
# or run on CPU with INT8
model = WhisperModel(model_size, device="cpu", compute_type="int8")

print(time.time())
segments, info = model.transcribe("11685669437.wav", beam_size=5)
print(time.time())

print("Detected language '%s' with probability %f" % (info.language, info.language_probability))
for segment in segments:
    print("[%.2fs -> %.2fs] %s" % (segment.start, segment.end, segment.text))
    print("[%.2fs -> %.2fs] %s" % (segment.start, segment.end, convert(segment.text, 'zh-cn')))

# whisper转化成faster-whisper
ct2-transformers-converter\
	--model openai/whisper-large-v2\
	--output_dir whisper-large-v2-ct2 \
	--copy_files tokenizer.json\
	--quantization float16

faster-whisper是stream-translator的作者最近支持的,相比whisper,faster-whisper速度要快4倍,而显存只用不到50%(在large v2模型下)whisper和faster-whisper的对比测试:

Large-v2 model on GPU

Implementation Precision Beam size Time Max. GPU memory Max. CPU memory
openai/whisper fp16 5 4m30s 11325MB 9439MB
faster-whisper fp16 5 54s 4755MB 3244MB
faster-whisper int8 5 59s 3091MB 3117MB

Executed with CUDA 11.7.1 on a NVIDIA Tesla V100S.

Small model on CPU

Implementation Precision Beam size Time Max. memory
openai/whisper fp32 5 10m31s 3101MB
whisper.cpp fp32 5 17m42s 1581MB
whisper.cpp fp16 5 12m39s 873MB
faster-whisper fp32 5 2m44s 1675MB
faster-whisper int8 5 2m04s 995MB

Executed with 8 threads on a Intel® Xeon® Gold 6226R.

CTranslate2

众所周知,直接使用Whisper模型推理是比较慢的,所以这里提供了一个加速的方式,主要是使用了CTranslate2进行加速,首先要转换模型,把合并后的模型转换为CTranslate2模型。如下命令,--model参数指定的是合并后的模型路径,同时也支持直接使用Whisper原模型,例如直接指定openai/whisper-large-v2--output_dir参数指定的是转换后的CTranslate2模型路径,--quantization参数指定的是量化模型大小,不希望量化模型的可以直接去掉这个参数。

ct2-transformers-converter --model models/whisper-tiny-finetune --output_dir models/whisper-tiny-ct2 --copy_files tokenizer.json --quantization float16

执行以下程序进行加速语音识别,--audio_path参数指定的是要预测的音频路径。--model_path指定的是转换后的CTranslate2模型。其他更多的参数请查看这个程序。

python infer_ct2.py --audio_path=dataset/test.wav --model_path=models/whisper-tiny-ct2

输出结果如下:

{
    "language": "zh",
    "duration": 8.39,
    "results": [
        {
            "start": 0.0,
            "end": 8.39,
            "text": "近几年不但我用书给女儿压岁也劝说亲朋友不要给女儿压岁钱而改送压岁书"
        }
    ],
    "text": "近几年不但我用书给女儿压岁也劝说亲朋友不要给女儿压岁钱而改送压岁书"
}

whisper.cpp

https://github.com/ggerganov/whisper.cpp

五、微调训练

安装环境

# Pytorch的GPU版本
conda install pytorch==1.13.1 torchvision==0.14.1 torchaudio==0.13.1 pytorch-cuda=11.6 -c pytorch -c nvidia
# 依赖库
python -m pip install -r requirements.txt -i https://pypi.tuna.tsinghua.edu.cn/simple

准备数据

训练的数据集如下,是一个jsonlines的数据列表,也就是每一行都是一个JSON数据,数据格式如下。Whisper是支持有标点符号的,所以训练的数据集中可以带有标点符号。本项目提供了一个制作AIShell数据集的程序aishell.py,执行这个程序可以自动下载并生成如下列格式的训练集和测试集,注意: 这个程序可以通过指定AIShell的压缩文件来跳过下载过程的,如果直接下载会非常慢,可以使用一些如迅雷等下载器下载该数据集,然后通过参数--filepath指定下载的压缩文件路径,如/home/test/data_aishell.tgz如果不使用时间戳训练,可以不包含sentences部分的数据

{
   "audio": {
      "path": "dataset/0.wav"
   },
   "sentence": "近几年,不但我用书给女儿压岁,也劝说亲朋不要给女儿压岁钱,而改送压岁书。",
   "sentences": [
      {
         "start": 0,
         "end": 1.4,
         "text": "近几年,"
      },
      {
         "start": 1.42,
         "end": 8.4,
         "text": "不但我用书给女儿压岁,也劝说亲朋不要给女儿压岁钱,而改送压岁书。"
      }
   ],
   "duration": 7.37
}

微调模型

准备好数据之后,就可以开始微调模型了。训练最重要的两个参数分别是,--base_model指定微调的Whisper模型,这个参数值需要在HuggingFace存在的,这个不需要提前下载,启动训练时可以自动下载,当然也可以提前下载,那么--base_model指定就是路径,同时--local_files_only设置为True。第二个--output_path是是训练时保存的Lora检查点路径,因为我们使用Lora来微调模型。如果想存足够的话,最好将--use_8bit设置为False,这样训练速度快很多。其他更多的参数请查看这个程序。

单卡训练

单卡训练命令如下,Windows系统可以不添加CUDA_VISIBLE_DEVICES参数。

CUDA_VISIBLE_DEVICES=0 python finetune.py --base_model=openai/whisper-tiny --output_dir=output/

多卡训练

多卡训练有两种方法,分别是torchrun和accelerate,开发者可以根据自己的习惯使用对应的方式。

  1. 使用torchrun启动多卡训练,命令如下,通过-nproc_per_node指定使用的显卡数量。torchrun --nproc_per_node=2 finetune.py --base_model=openai/whisper-tiny --output_dir=output/
  2. 使用accelerate启动多卡训练,如果是第一次使用accelerate,要配置训练参数,方式如下。

首先配置训练参数,过程是让开发者回答几个问题,基本都是默认就可以,但有几个参数需要看实际情况设置。

accelerate config

大概过程就是这样:

----------------------------------In which compute environment are you running?
This machine
----------------------------------Which type of machine are you using?
multi-GPU
How many different machines will you use (use more than 1 for multi-node training)? [1]:
Do you wish to optimize your script with torch dynamo?[yes/NO]:
Do you want to use DeepSpeed? [yes/NO]:
Do you want to use FullyShardedDataParallel? [yes/NO]:
Do you want to use Megatron-LM ? [yes/NO]:
How many GPU(s) should be used for distributed training? [1]:2
What GPU(s) (by id) should be used for training on this machine as a comma-seperated list? [all]:
----------------------------------Do you wish to use FP16 or BF16 (mixed precision)?
fp16

配置完成之后,可以使用以下命令查看配置。

accelerate env

开始训练命令如下。

accelerate launch finetune.py --base_model=openai/whisper-tiny --output_dir=output/

输出日志如下:

{'loss': 0.9098, 'learning_rate': 0.000999046843662503, 'epoch': 0.01}
{'loss': 0.5898, 'learning_rate': 0.0009970611012927184, 'epoch': 0.01}
{'loss': 0.5583, 'learning_rate': 0.0009950753589229333, 'epoch': 0.02}
{'loss': 0.5469, 'learning_rate': 0.0009930896165531485, 'epoch': 0.02}
{'loss': 0.5959, 'learning_rate': 0.0009911038741833634, 'epoch': 0.03}

合并模型

微调完成之后会有两个模型,第一个是Whisper基础模型,第二个是Lora模型,需要把这两个模型合并之后才能之后的操作。这个程序只需要传递两个参数,--lora_model指定的是训练结束后保存的Lora模型路径,注意如何不是最后的checkpoint-final后面还有adapter_model文件夹,第二个--output_dir是合并后模型的保存目录。

python merge_lora.py --lora_model=output/checkpoint-final --output_dir=models/

评估模型

执行以下程序进行评估模型,最重要的两个参数分别是。第一个--model_path指定的是合并后的模型路径,同时也支持直接使用Whisper原模型,例如直接指定openai/whisper-large-v2,第二个是--metric指定的是评估方法,例如有字错率cer和词错率wer提示: 没有微调的模型,可能输出带有标点符号,影响准确率。其他更多的参数请查看这个程序。

python evaluation.py --model_path=models/whisper-tiny-finetune --metric=cer

预测

执行以下程序进行语音识别,这个使用transformers直接调用微调后的模型或者Whisper原模型预测,只适合推理短音频,长语音还是参考infer_ct2.py的使用方式。第一个--audio_path参数指定的是要预测的音频路径。第二个--model_path指定的是合并后的模型路径,同时也支持直接使用Whisper原模型,例如直接指定openai/whisper-large-v2。其他更多的参数请查看这个程序。

python infer_tfs.py --audio_path=dataset/test.wav --model_path=models/whisper-tiny-finetune

六、部署

CTranslate2 Web部署

Web部署同样是使用了CTranslate2进行加速,转换模型方式看上面文档。--host指定服务启动的地址,这里设置为0.0.0.0,即任何地址都可以访问。--port指定使用的端口号。--model_path指定的是转换后的CTranslate2模型。--num_workers指定是使用多少个线程并发推理,这在Web部署上很重要,当有多个并发访问是可以同时推理。其他更多的参数请查看这个程序。

python infer_server.py --host=0.0.0.0 --port=5000 --model_path=models/whisper-tiny-ct2 --num_workers=2

接口文档

目前提供两个接口,普通的识别接口/recognition和流式返回结果/recognition_stream,注意这个流式是指流式返回识别结果,同样是上传完整的音频,然后流式返回识别结果,这种方式针对长语音识别体验非常好。他们的文档接口是完全一致的,接口参数如下。

字段 是否必须 类型 默认值 说明
audio File 要识别的音频文件
to_simple int 1 是否繁体转简体
remove_pun int 0 是否移除标点符号
task String transcribe 识别任务类型,支持transcribe和translate

为了方便理解,这里提供了调用Web接口的Python代码,下面的是/recognition的调用方式。

import requests

response = requests.post(url="http://127.0.0.1:5000/recognition",
                         files=[("audio", ("test.wav", open("dataset/test.wav", 'rb'), 'audio/wav'))],
                         json={"to_simple": 1, "remove_pun": 0, "task": "transcribe"}, timeout=20)
print(response.text)

下面的是/recognition_stream的调用方式。

import json
import requests

response = requests.post(url="http://127.0.0.1:5000/recognition_stream",
                         files=[("audio", ("test.wav", open("dataset/test_long.wav", 'rb'), 'audio/wav'))],
                         json={"to_simple": 1, "remove_pun": 0, "task": "transcribe"}, stream=True, timeout=20)
for chunk in response.iter_lines(decode_unicode=False, delimiter=b"\0"):
    if chunk:
        result = json.loads(chunk.decode())
        text = result["result"]
        start = result["start"]
        end = result["end"]
        print(f"[{start} - {end}]:{text}")

whisper-asr-ebservice

https://github.com/ahmetoner/whisper-asr-webservice

七、文档

https:*//huggingface.co/openai/whisper-large-v2*

模型下载:

large-v1: https://openaipublic.azureedge.net/main/whisper/models/e4b87e7e0bf463eb8e6956e646f1e277e901512310def2c24bf0e11bd3c28e9a/large-v1.pt
large-v2:

https://openaipublic.azureedge.net/main/whisper/models/81f7c96c852ee8fc832187b0132e569d6c3065a3252ed18e56effd0b6a73e524/large-v2.pt

你可能感兴趣的:(AI,语音识别,whisper,开源)