模型简介
模型特点
模型能力
使用案例
🚀 用于GigaSpeech的Conformer模型
本仓库提供了在SpeechBrain中基于预训练于GigaSpeech(英文,XL分割)的端到端系统进行自动语音识别所需的所有工具。为获得更好的体验,建议你进一步了解 SpeechBrain。 该模型在全上下文模式(非流式)下的性能如下:
发布日期 | 测试字错率 (WER) | GPU 配置 |
---|---|---|
2024-11-08 | 11.00% | 4xA100 40GB |
在流式模式下,不同块大小在测试集上的结果如下:
全上下文 | cs=32 (1280ms) | 24 (960ms) | 16 (640ms) | 12 (480ms) | 8 (320ms) | |
---|---|---|---|---|---|---|
全上下文 | 11.00% | - | - | - | - | - |
16 | - | - | - | 11.70% | 11.84% | 12.14% |
8 | - | - | 11.50% | 11.72% | 11.88% | 12.28% |
4 | - | 11.40% | 11.53% | 11.81% | 12.03% | 12.64% |
2 | - | 11.46% | 11.67% | 12.03% | 12.43% | 13.25% |
1* | - | 11.59% | 11.85% | 12.39% | 12.93% | 14.13% |
(*: 模型从未在该设置下显式训练过)
在比较不同配置时,请记住测试集的语音片段长度是有限的。所有字错率(WER)值均使用 此脚本 进行评估(直到我们集成更便捷的方式来评估不同条件下的流式WER)。
🚀 快速开始
本项目提供了在SpeechBrain中基于预训练于GigaSpeech的端到端系统进行自动语音识别的工具。你可以按照以下步骤进行操作:
- 安装SpeechBrain。
- 使用示例代码转录自己的英文音频文件。
- 可根据需求在GPU上进行推理或进行批量并行推理。
✨ 主要特性
- 多模式支持:支持全上下文模式和流式模式,适用于不同场景。
- 多块大小适配:模型支持不同块大小的训练和推理,适用于各种流式和离线转录需求。
- 自动音频处理:代码会自动对音频进行归一化处理(重采样 + 单声道选择)。
📦 安装指南
安装SpeechBrain
首先,请使用以下命令安装SpeechBrain:
pip install speechbrain
建议你阅读我们的教程,进一步了解 SpeechBrain。
💻 使用示例
基础用法
转录自己的英文音频文件:
from speechbrain.inference.ASR import StreamingASR
from speechbrain.utils.dynamic_chunk_training import DynChunkTrainConfig
asr_model = StreamingASR.from_hparams("speechbrain/asr-streaming-conformer-gigaspeech")
asr_model.transcribe_file(
"speechbrain/asr-streaming-conformer-librispeech/test-en.wav",
# 选择约960ms的块大小,左上下文为4个块
DynChunkTrainConfig(24, 4),
# 禁用torchaudio流式处理,以便从HuggingFace获取数据
# 对于你自己的文件或流,将此设置为True以启用流式文件解码
use_torchaudio_streaming=False,
)
DynChunkTrainConfig
的值可以根据延迟、计算能力和转录准确性进行调整。请参考流式WER表选择适合你用例的值。
高级用法
命令行工具转录文件或实时流
# 从实时流(BBC Radio 4)解码
python3 asr.py http://as-hls-ww-live.akamaized.net/pool_904/live/ww/bbc_radio_fourfm/bbc_radio_fourfm.isml/bbc_radio_fourfm-audio%3d96000.norewind.m3u8 --model-source=speechbrain/asr-streaming-conformer-gigaspeech --device=cpu -v
# 从文件解码
python3 asr.py some-english-speech.wav --model-source=speechbrain/asr-streaming-conformer-gigaspeech --device=cpu -v
from argparse import ArgumentParser
import logging
parser = ArgumentParser()
parser.add_argument("audio_path")
parser.add_argument("--model-source", required=True)
parser.add_argument("--device", default="cpu")
parser.add_argument("--ip", default="127.0.0.1")
parser.add_argument("--port", default=9431)
parser.add_argument("--chunk-size", default=24, type=int)
parser.add_argument("--left-context-chunks", default=4, type=int)
parser.add_argument("--num-threads", default=None, type=int)
parser.add_argument("--verbose", "-v", default=False, action="store_true")
args = parser.parse_args()
if args.verbose:
logging.getLogger().setLevel(logging.INFO)
logging.info("Loading libraries")
from speechbrain.inference.ASR import StreamingASR
from speechbrain.utils.dynamic_chunk_training import DynChunkTrainConfig
import torch
device = args.device
if args.num_threads is not None:
torch.set_num_threads(args.num_threads)
logging.info(f"Loading model from \"{args.model_source}\" onto device {device}")
asr = StreamingASR.from_hparams(args.model_source, run_opts={"device": device})
config = DynChunkTrainConfig(args.chunk_size, args.left_context_chunks)
logging.info(f"Starting stream from URI \"{args.audio_path}\"")
for text_chunk in asr.transcribe_file_streaming(args.audio_path, config):
print(text_chunk, flush=True, end="")
使用Gradio在浏览器中进行实时ASR解码
python3 gradio-asr.py --model-source speechbrain/asr-streaming-conformer-gigaspeech --ip=localhost --device=cpu
from argparse import ArgumentParser
from dataclasses import dataclass
import logging
parser = ArgumentParser()
parser.add_argument("--model-source", required=True)
parser.add_argument("--device", default="cpu")
parser.add_argument("--ip", default="127.0.0.1")
parser.add_argument("--port", default=9431)
parser.add_argument("--chunk-size", default=24, type=int)
parser.add_argument("--left-context-chunks", default=4, type=int)
parser.add_argument("--num-threads", default=None, type=int)
parser.add_argument("--verbose", "-v", default=False, action="store_true")
args = parser.parse_args()
if args.verbose:
logging.getLogger().setLevel(logging.INFO)
logging.info("Loading libraries")
from speechbrain.inference.ASR import StreamingASR, ASRStreamingContext
from speechbrain.utils.dynamic_chunk_training import DynChunkTrainConfig
import torch
import gradio as gr
import torchaudio
import numpy as np
device = args.device
if args.num_threads is not None:
torch.set_num_threads(args.num_threads)
logging.info(f"Loading model from \"{args.model_source}\" onto device {device}")
asr = StreamingASR.from_hparams(args.model_source, run_opts={"device": device})
config = DynChunkTrainConfig(args.chunk_size, args.left_context_chunks)
@dataclass
class GradioStreamingContext:
context: ASRStreamingContext
chunk_size: int
waveform_buffer: torch.Tensor
decoded_text: str
def transcribe(stream, new_chunk):
sr, y = new_chunk
y = y.astype(np.float32)
y = torch.tensor(y, dtype=torch.float32, device=device)
y /= max(1, torch.max(torch.abs(y)).item()) # norm by max abs() within chunk & avoid NaN
if len(y.shape) > 1:
y = torch.mean(y, dim=1) # downmix to mono
# HACK: we are making poor use of the resampler across chunk boundaries
# which may degrade accuracy.
# NOTE: we should also absolutely avoid recreating a resampler every time
resampler = torchaudio.transforms.Resample(orig_freq=sr, new_freq=asr.audio_normalizer.sample_rate).to(device)
y = resampler(y) # janky resample (probably to 16kHz)
if stream is None:
stream = GradioStreamingContext(
context=asr.make_streaming_context(config),
chunk_size=asr.get_chunk_size_frames(config),
waveform_buffer=y,
decoded_text="",
)
else:
stream.waveform_buffer = torch.concat((stream.waveform_buffer, y))
while stream.waveform_buffer.size(0) > stream.chunk_size:
chunk = stream.waveform_buffer[:stream.chunk_size]
stream.waveform_buffer = stream.waveform_buffer[stream.chunk_size:]
# fake batch dim
chunk = chunk.unsqueeze(0)
# list of transcribed strings, of size 1 because the batch size is 1
with torch.no_grad():
transcribed = asr.transcribe_chunk(stream.context, chunk)
stream.decoded_text += transcribed[0]
return stream, stream.decoded_text
# NOTE: latency seems relatively high, which may be due to this:
# https://github.com/gradio-app/gradio/issues/6526
demo = gr.Interface(
transcribe,
["state", gr.Audio(sources=["microphone"], streaming=True)],
["state", "text"],
live=True,
)
demo.launch(server_name=args.ip, server_port=args.port)
在GPU上进行推理
在调用 from_hparams
方法时,添加 run_opts={"device":"cuda"}
以在GPU上进行推理。
批量并行推理
目前,高级转录接口不支持批量推理,但低级接口(如 encode_chunk
)支持。我们希望未来能提供更高效的批量推理功能。
📚 详细文档
管道描述
此自动语音识别(ASR)系统是一个基于Conformer模型的系统,使用RNN-T损失函数进行训练(并使用辅助的CTC损失来稳定训练过程)。该模型使用单字分词器进行操作。架构细节在 训练超参数文件 中有详细描述。
流式支持采用了动态块训练(Dynamic Chunk Training)技术。多头注意力模块使用了分块注意力机制,并采用了 动态块卷积 的实现。该模型在训练时支持不同的块大小(甚至全上下文),因此适用于各种块大小的流式处理和离线转录。
该系统使用采样率为16kHz(单声道)的录音进行训练。在调用 transcribe_file
时,如果需要,代码会自动对音频进行归一化处理(即重采样 + 单声道选择)。
训练
该模型使用SpeechBrain v1.0.2
进行训练。要从头开始训练该模型,请按照以下步骤操作:
- 克隆SpeechBrain仓库:
git clone https://github.com/speechbrain/speechbrain/
- 安装依赖:
cd speechbrain
pip install -r requirements.txt
pip install -e .
- 按照 README 中的步骤进行操作。
局限性
SpeechBrain团队不保证该模型在其他数据集上的性能。
🔧 技术细节
模型信息
属性 | 详情 |
---|---|
模型类型 | Conformer模型,使用RNN-T损失函数训练,有辅助CTC损失 |
训练数据 | speechcolab/gigaspeech |
评估指标
模型在GigaSpeech测试集上的评估指标为字错率(WER),全上下文模式下测试WER为11.00%,流式模式下不同块大小有不同的WER值。
技术实现
采用动态块训练技术实现流式支持,多头注意力模块使用分块注意力,采用动态块卷积实现。
📄 许可证
本项目采用Apache-2.0许可证。
关于SpeechBrain
- 网站:https://speechbrain.github.io/
- 代码仓库:https://github.com/speechbrain/speechbrain/
- HuggingFace页面:https://huggingface.co/speechbrain/
引用SpeechBrain
如果你在研究或业务中使用了SpeechBrain,请引用以下文献:
@misc{speechbrainV1,
title={Open-Source Conversational AI with SpeechBrain 1.0},
author={Mirco Ravanelli and Titouan Parcollet and Adel Moumen and Sylvain de Langen and Cem Subakan and Peter Plantinga and Yingzhi Wang and Pooneh Mousavi and Luca Della Libera and Artem Ploujnikov and Francesco Paissan and Davide Borra and Salah Zaiem and Zeyu Zhao and Shucong Zhang and Georgios Karakasidis and Sung-Lin Yeh and Pierre Champion and Aku Rouhe and Rudolf Braun and Florian Mai and Juan Zuluaga-Gomez and Seyed Mahed Mousavi and Andreas Nautsch and Xuechen Liu and Sangeet Sagar and Jarod Duret and Salima Mdhaffar and Gaelle Laperriere and Mickael Rouvier and Renato De Mori and Yannick Esteve},
year={2024},
eprint={2407.00463},
archivePrefix={arXiv},
primaryClass={cs.LG},
url={https://arxiv.org/abs/2407.00463},
}
@misc{speechbrain,
title={{SpeechBrain}: A General-Purpose Speech Toolkit},
author={Mirco Ravanelli and Titouan Parcollet and Peter Plantinga and Aku Rouhe and Samuele Cornell and Loren Lugosch and Cem Subakan and Nauman Dawalatabad and Abdelwahab Heba and Jianyuan Zhong and Ju-Chieh Chou and Sung-Lin Yeh and Szu-Wei Fu and Chien-Feng Liao and Elena Rastorgueva and François Grondin and William Aris and Hwidong Na and Yan Gao and Renato De Mori and Yoshua Bengio},
year={2021},
eprint={2106.04624},
archivePrefix={arXiv},
primaryClass={eess.AS},
note={arXiv:2106.04624}
}



