base on <div align="center">
<h1>
星辰语音大模型-超多方言ASR
</h1>
</div>
<p align="center">
🤗 <a href="https://huggingface.co/Tele-AI/TeleSpeech-ASR1.0" target="_blank">Hugging Face</a>️ • 🤖 <a href="https://www.modelscope.cn/models/TeleAI/TeleSpeech-ASR1.0/summary" target="_blank">ModelScope</a> • 🐾 <a href="https://gitee.com/Tele-AI/TeleSpeech-ASR" target="_blank">gitee</a>
</p>
# 目录
- [目录](#目录)
- [模型开源](#模型开源)
- [环境配置](#环境配置)
- [数据准备](#数据准备)
- [特征提取](#特征提取)
- [字典准备](#字典准备)
- [微调模型推理流程示例\*](#微调模型推理流程示例)
- [预训练模型微调](#预训练模型微调)
- [微调阶段](#微调阶段)
- [推理与解码阶段](#推理与解码阶段)
- [表征训练下游任务](#表征训练下游任务)
- [开源数据集结果](#开源数据集结果)
- [声明与协议](#声明与协议)
- [声明](#声明)
- [协议](#协议)
# 模型开源
星辰超多方言语音识别大模型v1.0,由30万小时无标注多方言语音数据进行预训练,并利用内部30种有标注数据进行微调,打破单一模型只能识别特定单一方言的困境,可支持理解粤语、上海话、四川话、温州话等30种方言
本次开源三个模型:两个30万小时无标注语音预训练模型和一个KeSpeech数据集8种方言微调模型。发布版本和下载链接见下表
| 模型版本 | 参数量 | 下载链接 | 字典 | 备注 |
|---------------------|-------|---------------------|-------|-------|
| pretrain_base | 0.09 B | [TeleSpeech-ASR1.0-base](https://huggingface.co/Tele-AI/TeleSpeech-ASR1.0/blob/main/base.pt) | ✗ | 30万小时无标注语音预训练模型 |
| pretrain_large | 0.3 B | [TeleSpeech-ASR1.0-large](https://huggingface.co/Tele-AI/TeleSpeech-ASR1.0/blob/main/large.pt) | ✗ | 30万小时无标注语音预训练模型 |
| finetune_large_kespeech | 0.3 B | [TeleSpeech-ASR1.0-large-kespeech](https://huggingface.co/Tele-AI/TeleSpeech-ASR1.0/blob/main/finetune_large_kespeech.pt) | [dict.char7531.txt](https://huggingface.co/Tele-AI/TeleSpeech-ASR1.0/blob/main/dict.chr7531.txt) | 基于pretrain_large,采用KeSpeech数据集[8种方言](#KeSpeech各方言上结果)微调训练|
* finetune模型为已经在特定数据集微调过的模型,可直接使用
* pretrain模型为无监督预训练模型,**无法直接进行ASR任务**,需要用少量标注数据进行有监督训练后使用。相比于直接训练的方言识别模型,基于预训练模型可以利用更少的有标注数据获得更好的方言识别性能。我们提供了两种有监督训练框架,用于下游ASR任务:1) 基于fairseq的预训练模型微调; 2) 基于wenet的表征提取(特征提取器)训练下游ASR模型
# 环境配置
* PyTorch version >= 1.13.0
* Python version >= 3.8
* 数据准备、程序训练需要使用kaldi,请确保已正确安装:https://github.com/kaldi-asr/kaldi
* 若已有提好的特征,程序运行时可以使用wenet开源框架中kaldi_io.py实现的方法替换kaldiio.load_mat,从而无需安装kaldi
<a id="fairseq安装"></a>
* 安装fairseq及其依赖
```shell script
$ git clone https://github.com/pytorch/fairseq
$ cd fairseq
$ pip install --editable ./
```
* 安装fairseq额外依赖以及wenet表征训练任务运行所需依赖
```shell script
$ pip install -r requirements.txt
```
* 若只需要fairseq进行微调、解码,可以不安装完整的requirements.txt,只需保证kaldiio, timm, editdistance, soundfile已正确安装
```shell script
$ pip install kaldiio timm editdistance soundfile
```
# 数据准备
## 特征提取
<a id="特征提取"></a>
* 模型输入为从16K采样率音频中提取的40维mfcc特征,**非原始音频**
* 利用kaldi提取40维mfcc特征,运行脚本参考`prepare_kaldi_feats.sh`
* 可将运行脚本`prepare_kaldi_feats.sh`与参数设置`mfcc_hires.conf`置于kaldi任一egs目录下(与cmd.sh等脚本平级,例如/path/to/kaldi/egs/aishell/s5/prepare_kaldi_feats.sh),运行`prepare_kaldi_feats.sh`即可
* 为各数据集准备训练用文件`data.list`,可参考`make_datalist.py`,以`\t`分隔:
```
$ cat train/data.list
utt:X0000000000_100638174_S00037 feat:/data/raw_nnaudio.test.1.ark:2983479385 feat_shape:363,40 text:不惜在这种试验中毁灭包括自己在内的一切 token:不 惜 在 这 种 试 验 中 毁 灭 包 括 自 己 在 内 的 一 切 tokenid:[TOKENID] token_shape:19,5537
utt:X0000000001_100849618_S00006 feat:/data/raw_nnaudio.test.1.ark:2984296665 feat_shape:345,40 text:在他们收到足够建立大统一模型的数据后 token:在 他 们 收 到 足 够 建 立 大 统 一 模 型 的 数 据 后 tokenid:[TOKENID] token_shape:18,5537
...
```
## 字典准备
* 微调阶段,需要准备fairseq格式的 `dict.${label}.txt`,`${label}`为建模单元类型,如ltr, bpe等。以`dict.ltr.txt`为例:
```
是 2
好 3
...
```
* 预训练模型表征训练ASR任务阶段,需要准备wenet格式的`lang_char.txt`,相比于`dict.${label}.txt`额外添加`<blank>`, `<unk>`, `<sos/eos>`3个token,例如
```
<blank> 0
<unk> 1
是 2
好 3
...
<sos/eos> 5536
```
# 微调模型推理流程示例*
1. [fairseq环境准备](#fairseq安装),修改`data2vec_dialect/path.sh`文件中`/path/to/fairseq`为fairseq安装路径
2. 利用kaldi提取音频特征,准备data.list格式文件,参考[特征提取](#特征提取),并命名为以 .tsv 结尾的文件
* data.list中`text`、`token`是为了微调和统计CER使用,若只想拿到解码结果,data.list中的`text`、`token`只需保证有内容即可
3. 进入data2vec_dialect目录,并修改`run_scripts/decode.sh`文件,参考[推理与解码阶段](#推理与解码阶段)
4. 在data2vec_dialect路径下,执行`run_scripts/decode.sh`
*仅经过微调后的finetune模型支持直接推理,无监督预训练模型`pretrain_base`和`pretrain_large`需要先在标注数据上训练后,再进行推理,详见[预训练模型微调](#预训练模型微调)或[表征训练下游任务](#表征训练下游任务)
# 预训练模型微调
<a id="预训练模型微调"></a>
## 微调阶段
* 准备`train.tsv`和`dev.tsv`,保存于同一训练目录下
```
$ ln -s /path/to/train/data.list /path/to/train/train.tsv
$ ln -s /path/to/dev/data.list /path/to/train/dev.tsv
```
* 进入data2vec_dialect目录,修改`path.sh`文件中`/path/to/fairseq`为fairseq安装路径
* 将`run_scripts/run_d2v_finetune.sh`中`/path/to`相关路径替换
* 修改`task.data`为 .tsv 文件保存路径,如`task.data=/data/wenetspeech/train`
* 在data2vec_dialect路径下,执行
```shell script
$ bash run_scripts/run_d2v_finetune.sh
```
<a id="推理与解码阶段"></a>
## 推理与解码阶段
* 同样修改`run_scripts/decode.sh`中的模型路径、测试数据路径等
* `dataset.gen_subset`为测试数据路径下 .tsv 文件的名称,可配置多个
* 执行
```shell script
$ bash run_scripts/decode.sh
```
# 表征训练下游任务
<a id="表征训练下游任务"></a>
* 进入wenet_representation路径,修改`path.sh`文件中`fairseq`, `data2vec_dialect`, `wenet_representation`相关路径
* 连续表征训练与解码:
* 配置`run_d2v.sh`中dataset相关内容,执行
```shell script
$ bash run_d2v.sh
```
* 离散表征训练与解码:
* 首先根据`data.list`,准备离散表征对应训练文件`data.list.discrete`,修改`wenet/discrete_token/kmeans_d2v.yaml`中`model_dir`和`user_dir`,执行
```
$ bash wenet/discrete_token/dump_feat.sh
```
* 再配置`run_discrete.sh`中dataset相关内容,执行
```
$ bash run_discrete.sh
```
# 开源数据集结果
* 我们选择了多个开源中文数据集进行验证,以测试集上的字错误率 (Character Error Rate, CER) 结果作为衡量标准
* 在Aishell-1上我们选择其Train集作为有监督数据进行训练,在Test集上统计CER
* 在WenetSpeech上,我们分别使用100小时训练集Train_s和1000小时训练集Train_m分别作为有监督数据进行训练,在Test_Meeting测试集上统计CER
* Babel为NIST(美国国家标准与技术研究院)举办的低资源粤语电话识别任务数据集,我们使用其提供的训练集与测试集统计CER
* KeSpeech为中文多方言测试集,我们使用1396小时训练集作为有监督数据进行训练,选择提供的Test测试集统计CER
| 模型版本 | Aishell-1 (%)| WenetSpeech* (%)| Babel (%) | KeSpeech (%) |
| ----------| -------- | ------- | ---- | ---- |
| pretrain_base | 4.7 | 18.3 / 16.4 | 22.1 | 10.9 |
| pretrain_large | 4.0 | 14.3 / 13.0 | 19.1 | 8.1 |
*WenetSpeech中的结果为分别使用 `train_s/train_m`训练后,在Test_Meeting上的CER
<a id="KeSpeech各方言上结果"></a>
KeSpeech各方言上结果(CER%)
| 模型版本 | 普通话 | 北京 | 西南 | 中原 | 东北 | 兰银 | 江淮 | 冀鲁 | 胶辽 |
| ---------| ------ | ---- | ---- | ---- |---- | ---- | ---- | ---- | ---- |
| pretrain_large | 4.61 | 8.23 | 8.74 | 7.62 | 7.89 | 9.72 | 12.89 | 8.91 | 9.30 |
# 声明与协议
## 声明
我们在此声明,不要使用TeleSpeech模型及其衍生模型进行任何危害国家社会安全或违法的活动。同时,我们也要求使用者不要将TeleSpeech模型用于没有安全审查和备案的互联网服务。我们希望所有使用者遵守上述原则,确保科技发展在合法合规的环境下进行。
我们已经尽我们所能,来确保模型训练过程中使用的数据的合规性。然而,尽管我们已经做出了巨大的努力,但由于模型和数据的复杂性,仍有可能存在一些无法预见的问题。因此,如果由于使用TeleSpeech开源模型而导致的任何问题,包括但不限于数据安全问题、公共舆论风险,或模型被误导、滥用、传播或不当利用所带来的任何风险和问题,我们将不承担任何责任。
## 协议
社区使用TeleSpeech模型需要遵循《[TeleSpeech模型社区许可协议](./TeleSpeech模型社区许可协议.pdf)》。TeleSpeech模型支持商业用途,如果您计划将TeleSpeech模型或其衍生品用于商业目的,您需要通过以下联系邮箱
[email protected],提交《TeleSpeech模型社区许可协议》要求的申请材料。审核通过后,将特此授予您一个非排他性、全球性、不可转让、不可再许可、可撤销的商用版权许可。
---", Assign "at most 3 tags" to the expected json: {"id":"10478","tags":[]} "only from the tags list I provide: [{"id":77,"name":"3d"},{"id":89,"name":"agent"},{"id":17,"name":"ai"},{"id":54,"name":"algorithm"},{"id":24,"name":"api"},{"id":44,"name":"authentication"},{"id":3,"name":"aws"},{"id":27,"name":"backend"},{"id":60,"name":"benchmark"},{"id":72,"name":"best-practices"},{"id":39,"name":"bitcoin"},{"id":37,"name":"blockchain"},{"id":1,"name":"blog"},{"id":45,"name":"bundler"},{"id":58,"name":"cache"},{"id":21,"name":"chat"},{"id":49,"name":"cicd"},{"id":4,"name":"cli"},{"id":64,"name":"cloud-native"},{"id":48,"name":"cms"},{"id":61,"name":"compiler"},{"id":68,"name":"containerization"},{"id":92,"name":"crm"},{"id":34,"name":"data"},{"id":47,"name":"database"},{"id":8,"name":"declarative-gui "},{"id":9,"name":"deploy-tool"},{"id":53,"name":"desktop-app"},{"id":6,"name":"dev-exp-lib"},{"id":59,"name":"dev-tool"},{"id":13,"name":"ecommerce"},{"id":26,"name":"editor"},{"id":66,"name":"emulator"},{"id":62,"name":"filesystem"},{"id":80,"name":"finance"},{"id":15,"name":"firmware"},{"id":73,"name":"for-fun"},{"id":2,"name":"framework"},{"id":11,"name":"frontend"},{"id":22,"name":"game"},{"id":81,"name":"game-engine "},{"id":23,"name":"graphql"},{"id":84,"name":"gui"},{"id":91,"name":"http"},{"id":5,"name":"http-client"},{"id":51,"name":"iac"},{"id":30,"name":"ide"},{"id":78,"name":"iot"},{"id":40,"name":"json"},{"id":83,"name":"julian"},{"id":38,"name":"k8s"},{"id":31,"name":"language"},{"id":10,"name":"learning-resource"},{"id":33,"name":"lib"},{"id":41,"name":"linter"},{"id":28,"name":"lms"},{"id":16,"name":"logging"},{"id":76,"name":"low-code"},{"id":90,"name":"message-queue"},{"id":42,"name":"mobile-app"},{"id":18,"name":"monitoring"},{"id":36,"name":"networking"},{"id":7,"name":"node-version"},{"id":55,"name":"nosql"},{"id":57,"name":"observability"},{"id":46,"name":"orm"},{"id":52,"name":"os"},{"id":14,"name":"parser"},{"id":74,"name":"react"},{"id":82,"name":"real-time"},{"id":56,"name":"robot"},{"id":65,"name":"runtime"},{"id":32,"name":"sdk"},{"id":71,"name":"search"},{"id":63,"name":"secrets"},{"id":25,"name":"security"},{"id":85,"name":"server"},{"id":86,"name":"serverless"},{"id":70,"name":"storage"},{"id":75,"name":"system-design"},{"id":79,"name":"terminal"},{"id":29,"name":"testing"},{"id":12,"name":"ui"},{"id":50,"name":"ux"},{"id":88,"name":"video"},{"id":20,"name":"web-app"},{"id":35,"name":"web-server"},{"id":43,"name":"webassembly"},{"id":69,"name":"workflow"},{"id":87,"name":"yaml"}]" returns me the "expected json"