mrfakename commited on
Commit
167f5d0
·
verified ·
1 Parent(s): cdc1403

Mirror wlc952/FunASR-bmodel from ModelScope

Browse files
This view is limited to 50 files because it contains too many changes.   See raw diff
Files changed (50) hide show
  1. .gitattributes +22 -9
  2. .gitignore +32 -0
  3. .python-version +1 -0
  4. bmodel/README.md +73 -0
  5. bmodel/check_time.py +34 -0
  6. bmodel/monitor.py +749 -0
  7. bmodel/offline.py +35 -0
  8. bmodel/punc_ct-transformer_zh-cn-common-vocab272727/README.md +25 -0
  9. bmodel/punc_ct-transformer_zh-cn-common-vocab272727/models/BM1684X/config.yaml +46 -0
  10. bmodel/punc_ct-transformer_zh-cn-common-vocab272727/models/BM1684X/punc_fp16.bmodel +3 -0
  11. bmodel/punc_ct-transformer_zh-cn-common-vocab272727/models/BM1684X/tokens.json +0 -0
  12. bmodel/punc_ct-transformer_zh-cn-common-vocab272727/scripts/download.sh +35 -0
  13. bmodel/punc_ct-transformer_zh-cn-common-vocab272727/scripts/gen_fp16bmodel_mlir.sh +51 -0
  14. bmodel/punc_ct-transformer_zh-cn-common-vocab272727/scripts/gen_fp32bmodel_mlir.sh +51 -0
  15. bmodel/punc_ct-transformer_zh-cn-common-vocab272727/scripts/gen_input.py +10 -0
  16. bmodel/speech_campplus_sv_zh-cn_16k-common/models/BM1684X/campplus_fp16_1b.bmodel +3 -0
  17. bmodel/speech_campplus_sv_zh-cn_16k-common/models/BM1684X/campplus_fp32_1b.bmodel +3 -0
  18. bmodel/speech_campplus_sv_zh-cn_16k-common/models/BM1684X/config.yaml +23 -0
  19. bmodel/speech_campplus_sv_zh-cn_16k-common/scripts/download.sh +35 -0
  20. bmodel/speech_campplus_sv_zh-cn_16k-common/scripts/gen_fp16bmodel_mlir.sh +49 -0
  21. bmodel/speech_campplus_sv_zh-cn_16k-common/scripts/gen_fp32bmodel_mlir.sh +49 -0
  22. bmodel/speech_fsmn_vad_zh-cn-16k-common/README.md +25 -0
  23. bmodel/speech_fsmn_vad_zh-cn-16k-common/models/BM1684X/am.mvn +8 -0
  24. bmodel/speech_fsmn_vad_zh-cn-16k-common/models/BM1684X/config.yaml +56 -0
  25. bmodel/speech_fsmn_vad_zh-cn-16k-common/models/BM1684X/fsmn_fp16.bmodel +3 -0
  26. bmodel/speech_fsmn_vad_zh-cn-16k-common/models/BM1684X/fsmn_fp32.bmodel +3 -0
  27. bmodel/speech_fsmn_vad_zh-cn-16k-common/scripts/download.sh +35 -0
  28. bmodel/speech_fsmn_vad_zh-cn-16k-common/scripts/gen_fp16bmodel_mlir.sh +51 -0
  29. bmodel/speech_fsmn_vad_zh-cn-16k-common/scripts/gen_fp32bmodel_mlir.sh +51 -0
  30. bmodel/speech_fsmn_vad_zh-cn-16k-common/scripts/gen_input.py +8 -0
  31. bmodel/speech_seaco_paraformer_large_asr_nat-zh-cn-16k-common-vocab8404/README.md +4 -0
  32. bmodel/speech_seaco_paraformer_large_asr_nat-zh-cn-16k-common-vocab8404/models/BM1684X/am.mvn +8 -0
  33. bmodel/speech_seaco_paraformer_large_asr_nat-zh-cn-16k-common-vocab8404/models/BM1684X/config.yaml +160 -0
  34. bmodel/speech_seaco_paraformer_large_asr_nat-zh-cn-16k-common-vocab8404/models/BM1684X/decoder_fp32_10b.bmodel +3 -0
  35. bmodel/speech_seaco_paraformer_large_asr_nat-zh-cn-16k-common-vocab8404/models/BM1684X/encoder_fp16_10b.bmodel +3 -0
  36. bmodel/speech_seaco_paraformer_large_asr_nat-zh-cn-16k-common-vocab8404/models/BM1684X/predictor_fp16_10b.bmodel +3 -0
  37. bmodel/speech_seaco_paraformer_large_asr_nat-zh-cn-16k-common-vocab8404/models/BM1684X/predictor_fp32_10b.bmodel +3 -0
  38. bmodel/speech_seaco_paraformer_large_asr_nat-zh-cn-16k-common-vocab8404/models/BM1684X/seg_dict +0 -0
  39. bmodel/speech_seaco_paraformer_large_asr_nat-zh-cn-16k-common-vocab8404/models/BM1684X/tokens.json +0 -0
  40. bmodel/speech_seaco_paraformer_large_asr_nat-zh-cn-16k-common-vocab8404/scripts/download.sh +27 -0
  41. bmodel/tpu_perf-1.2.35-py3-none-manylinux2014_aarch64.whl +3 -0
  42. funasr/__init__.py +42 -0
  43. funasr/auto/__init__.py +0 -0
  44. funasr/auto/auto_frontend.py +109 -0
  45. funasr/auto/auto_model.py +684 -0
  46. funasr/auto/auto_tokenizer.py +7 -0
  47. funasr/bin/__init__.py +0 -0
  48. funasr/bin/compute_audio_cmvn.py +136 -0
  49. funasr/bin/export.py +42 -0
  50. funasr/bin/inference.py +30 -0
.gitattributes CHANGED
@@ -1,35 +1,48 @@
1
  *.7z filter=lfs diff=lfs merge=lfs -text
2
  *.arrow filter=lfs diff=lfs merge=lfs -text
3
  *.bin filter=lfs diff=lfs merge=lfs -text
 
4
  *.bz2 filter=lfs diff=lfs merge=lfs -text
5
- *.ckpt filter=lfs diff=lfs merge=lfs -text
6
  *.ftz filter=lfs diff=lfs merge=lfs -text
7
  *.gz filter=lfs diff=lfs merge=lfs -text
8
  *.h5 filter=lfs diff=lfs merge=lfs -text
9
  *.joblib filter=lfs diff=lfs merge=lfs -text
10
  *.lfs.* filter=lfs diff=lfs merge=lfs -text
11
- *.mlmodel filter=lfs diff=lfs merge=lfs -text
12
  *.model filter=lfs diff=lfs merge=lfs -text
13
  *.msgpack filter=lfs diff=lfs merge=lfs -text
14
- *.npy filter=lfs diff=lfs merge=lfs -text
15
- *.npz filter=lfs diff=lfs merge=lfs -text
16
  *.onnx filter=lfs diff=lfs merge=lfs -text
17
  *.ot filter=lfs diff=lfs merge=lfs -text
18
  *.parquet filter=lfs diff=lfs merge=lfs -text
19
  *.pb filter=lfs diff=lfs merge=lfs -text
20
- *.pickle filter=lfs diff=lfs merge=lfs -text
21
- *.pkl filter=lfs diff=lfs merge=lfs -text
22
  *.pt filter=lfs diff=lfs merge=lfs -text
23
  *.pth filter=lfs diff=lfs merge=lfs -text
24
  *.rar filter=lfs diff=lfs merge=lfs -text
25
- *.safetensors filter=lfs diff=lfs merge=lfs -text
26
  saved_model/**/* filter=lfs diff=lfs merge=lfs -text
27
  *.tar.* filter=lfs diff=lfs merge=lfs -text
28
- *.tar filter=lfs diff=lfs merge=lfs -text
29
  *.tflite filter=lfs diff=lfs merge=lfs -text
30
  *.tgz filter=lfs diff=lfs merge=lfs -text
31
- *.wasm filter=lfs diff=lfs merge=lfs -text
32
  *.xz filter=lfs diff=lfs merge=lfs -text
33
  *.zip filter=lfs diff=lfs merge=lfs -text
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
34
  *.zst filter=lfs diff=lfs merge=lfs -text
35
  *tfevents* filter=lfs diff=lfs merge=lfs -text
 
 
1
  *.7z filter=lfs diff=lfs merge=lfs -text
2
  *.arrow filter=lfs diff=lfs merge=lfs -text
3
  *.bin filter=lfs diff=lfs merge=lfs -text
4
+ *.bin.* filter=lfs diff=lfs merge=lfs -text
5
  *.bz2 filter=lfs diff=lfs merge=lfs -text
 
6
  *.ftz filter=lfs diff=lfs merge=lfs -text
7
  *.gz filter=lfs diff=lfs merge=lfs -text
8
  *.h5 filter=lfs diff=lfs merge=lfs -text
9
  *.joblib filter=lfs diff=lfs merge=lfs -text
10
  *.lfs.* filter=lfs diff=lfs merge=lfs -text
 
11
  *.model filter=lfs diff=lfs merge=lfs -text
12
  *.msgpack filter=lfs diff=lfs merge=lfs -text
 
 
13
  *.onnx filter=lfs diff=lfs merge=lfs -text
14
  *.ot filter=lfs diff=lfs merge=lfs -text
15
  *.parquet filter=lfs diff=lfs merge=lfs -text
16
  *.pb filter=lfs diff=lfs merge=lfs -text
 
 
17
  *.pt filter=lfs diff=lfs merge=lfs -text
18
  *.pth filter=lfs diff=lfs merge=lfs -text
19
  *.rar filter=lfs diff=lfs merge=lfs -text
 
20
  saved_model/**/* filter=lfs diff=lfs merge=lfs -text
21
  *.tar.* filter=lfs diff=lfs merge=lfs -text
 
22
  *.tflite filter=lfs diff=lfs merge=lfs -text
23
  *.tgz filter=lfs diff=lfs merge=lfs -text
 
24
  *.xz filter=lfs diff=lfs merge=lfs -text
25
  *.zip filter=lfs diff=lfs merge=lfs -text
26
+ *.zstandard filter=lfs diff=lfs merge=lfs -text
27
+ *.tfevents* filter=lfs diff=lfs merge=lfs -text
28
+ *.db* filter=lfs diff=lfs merge=lfs -text
29
+ *.ark* filter=lfs diff=lfs merge=lfs -text
30
+ **/*ckpt*data* filter=lfs diff=lfs merge=lfs -text
31
+ **/*ckpt*.meta filter=lfs diff=lfs merge=lfs -text
32
+ **/*ckpt*.index filter=lfs diff=lfs merge=lfs -text
33
+ *.safetensors filter=lfs diff=lfs merge=lfs -text
34
+ *.ckpt filter=lfs diff=lfs merge=lfs -text
35
+ *.gguf* filter=lfs diff=lfs merge=lfs -text
36
+ *.ggml filter=lfs diff=lfs merge=lfs -text
37
+ *.llamafile* filter=lfs diff=lfs merge=lfs -text
38
+ *.pt2 filter=lfs diff=lfs merge=lfs -text
39
+ *.mlmodel filter=lfs diff=lfs merge=lfs -text
40
+ *.npy filter=lfs diff=lfs merge=lfs -text
41
+ *.npz filter=lfs diff=lfs merge=lfs -text
42
+ *.pickle filter=lfs diff=lfs merge=lfs -text
43
+ *.pkl filter=lfs diff=lfs merge=lfs -text
44
+ *.tar filter=lfs diff=lfs merge=lfs -text
45
+ *.wasm filter=lfs diff=lfs merge=lfs -text
46
  *.zst filter=lfs diff=lfs merge=lfs -text
47
  *tfevents* filter=lfs diff=lfs merge=lfs -text
48
+ *.bmodel filter=lfs diff=lfs merge=lfs -textbmodel/tpu_perf-1.2.35-py3-none-manylinux2014_aarch64.whl filter=lfs diff=lfs merge=lfs -text
.gitignore ADDED
@@ -0,0 +1,32 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ .idea
2
+ ./__pycache__/
3
+ */__pycache__/
4
+ */*/__pycache__/
5
+ */*/*/__pycache__/
6
+ .DS_Store
7
+ init_model/
8
+ *.tar.gz
9
+ test_local/
10
+ RapidASR
11
+ export/*
12
+ *.pyc
13
+ .eggs
14
+ MaaS-lib
15
+ .egg*
16
+ dist
17
+ build
18
+ funasr.egg-info
19
+ docs/_build
20
+ modelscope
21
+ samples
22
+ .ipynb_checkpoints
23
+ outputs*
24
+ emotion2vec*
25
+ GPT-SoVITS*
26
+ modelscope_models
27
+ examples/aishell/llm_asr_nar/*
28
+ *egg-info
29
+ .venv
30
+ bmodel/alerts
31
+ bmodel/segments
32
+ ref*.wav
.python-version ADDED
@@ -0,0 +1 @@
 
 
1
+ 3.10
bmodel/README.md ADDED
@@ -0,0 +1,73 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # FunASR-bmodel
2
+
3
+ ## 目录
4
+
5
+ - [FunASR-bmodel](#funasr)
6
+ - [目录](#目录)
7
+ - [1. 简介](#1-简介)
8
+ - [2. 特性](#2-特性)
9
+ - [3. 准备模型和链接库](#3-准备模型和链接库)
10
+ - [3.1 使用提供的模型](#31-使用提供的模型)
11
+ - [3.2 编译模型](#32-编译模型)
12
+ - [4.运行测试](#4-运行测试)
13
+ - [4.1 环境准备](#41-环境准备)
14
+ - [4.2 离线识别](#42-离线识别)
15
+
16
+ ## 1. 简介
17
+
18
+ FunASR是一个流行的语音识别框架,本目录将常用的几个模型移植到算丰平台。
19
+
20
+ 该例程支持在V23.09LTS SP3及以上的BM1684X SOPHONSDK, 或在v1.7.0及以上的BM1688 SOPHONSDK上运行,支持在插有1684X加速卡(SC7系列)的x86主机上运行,也可以在1684X SoC设备(如SE7、SM7、Airbox等)上运行,也支持在BM1688 Soc设备(如SE9-16)上运行。
21
+
22
+ ## 2.特性
23
+
24
+ * 支持BM1684X(x86 PCIe、SoC),BM1688(SoC)
25
+ * 支持FP32(BM1684X/BM1688)模型编译和推理
26
+
27
+ ## 3. 准备模型
28
+
29
+ 该模型目前支持在BM1684X和BM1688上运行,已提供编译好的bmodel。
30
+
31
+ ### 3.1 使用提供的模型
32
+
33
+ ​本例程在各个模型的目录内`scripts`目录下提供了下载脚本`download.sh`
34
+
35
+ ```bash
36
+ # 安装unzip,若已安装请跳过,非ubuntu系统视情况使用yum或其他方式安装
37
+ sudo apt-get update
38
+ sudo apt install unzip
39
+ chmod -R +x scripts/
40
+ ./scripts/download.sh
41
+ ```
42
+
43
+ 支持的模型
44
+ | 模型名称 | Python | C++ |
45
+ |------------|----------|-----|
46
+ |[speech_paraformer-large-contextual_asr_nat-zh-cn-16k-common-vocab8404](speech_paraformer-large-contextual_asr_nat-zh-cn-16k-common-vocab8404)|支持|支持|
47
+ |[speech_paraformer-large_asr_nat-zh-cn-16k-common-vocab8404-online](speech_paraformer-large_asr_nat-zh-cn-16k-common-vocab8404-online)|支持|支持|
48
+ |[speech_seaco_paraformer_large_asr_nat-zh-cn-16k-common-vocab8404](speech_seaco_paraformer_large_asr_nat-zh-cn-16k-common-vocab8404)|支持|不支持|
49
+ |[speech_fsmn_vad_zh-cn-16k-common](speech_fsmn_vad_zh-cn-16k-common)|支持|支持|
50
+ |[punc_ct-transformer_zh-cn-common-vocab272727](punc_ct-transformer_zh-cn-common-vocab272727)|支持|支持|
51
+ |[speech_campplus_sv_zh-cn_16k-common](speech_campplus_sv_zh-cn_16k-common)|支持|不支持|
52
+
53
+ ## 3.2 编译模型
54
+ 请参考模型目录内的readme.md编译
55
+
56
+ ## 4. 运行测试
57
+
58
+ ### 4.1 环境准备
59
+ Python需要先安装tpu_perf, 在x86平台使用算能计算卡(PCIE模式)时执行
60
+ ```bash
61
+ pip3 install tpu_perf-1.2.35-py3-none-manylinux2014_x86_64.whl
62
+ ```
63
+ 在算能边缘计算盒子(SOC模式)上执行
64
+ ```bash
65
+ pip3 install tpu_perf-1.2.35-py3-none-manylinux2014_aarch64.whl
66
+ ```
67
+ 另外还需要安装外部依赖库
68
+ ```bash
69
+ pip3 install -r requirements.txt
70
+ ```
71
+
72
+ ### 4.2 离线识别
73
+ Python离线识别可参考offline.py,配置好音频文件路径,以及平台和设备ID后,即可执行推理。
bmodel/check_time.py ADDED
@@ -0,0 +1,34 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import numpy as np
2
+
3
+ with open("record_sent.txt","r") as f:
4
+ sent = f.readlines()
5
+ with open("record_recv.txt","r") as f:
6
+ recv = f.readlines()
7
+
8
+ # sent[id] = time from first sent
9
+ sent = np.array([ float(item[5:14]) for item in sent ])
10
+
11
+ # recv[i][j] for each j
12
+ # j=0 -> 0 for online and 1 for offline
13
+ # j=1 -> start id
14
+ # j=2 -> end id
15
+ # j=3 -> time from first sent
16
+ recv = [[int(item[0]), int(item[2:6]), int(item[7:11]), float(item[12:21])] for item in recv]
17
+
18
+ online_time = []
19
+ offline_time = []
20
+ alltime = []
21
+
22
+ for item in recv:
23
+ proc_time = item[3] - sent[item[2]]
24
+ if item[0] == 1:
25
+ # offline
26
+ offline_time.append(proc_time)
27
+ else:
28
+ # online
29
+ online_time.append(proc_time)
30
+ alltime.append(proc_time)
31
+
32
+ print("online time avg: "+format(np.mean(online_time),'6.3f')+", std = "+format(np.std(online_time),'6.3f'))
33
+ print("offline time avg: "+format(np.mean(offline_time),'6.3f')+", std = "+format(np.std(offline_time),'6.3f'))
34
+ print("allline time avg: "+format(np.mean(alltime),'6.3f')+", std = "+format(np.std(alltime),'6.3f'))
bmodel/monitor.py ADDED
@@ -0,0 +1,749 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ #!/usr/bin/env python3
2
+ # -*- coding: utf-8 -*-
3
+
4
+ """
5
+ 监控场景语音检测:
6
+ - 使用 ffmpeg 将 RTSP 流按 10s 切片为 mp4(含音频)。
7
+ - 对每个切片提取 16k 单声道 wav,并在前面拼接系统参考音频(系统说话人 spk=0)。
8
+ - 调用 FunASR AutoModel 进行识别与说话人区分,若存在非0说话人,且文本不在系统提示词库内,则判定为告警。
9
+ - 命中后将对应 10s mp4 保存到本地 /data/alarms 下,并按协议 POST 上报。
10
+
11
+ 运行示例:
12
+ python bmodel/monitor.py \
13
+ --rtsp rtsp://user:pass@ip:554/Streaming/Channels/101 \
14
+ --system-audio /data/FunASR-bmodel/system_ref.wav \
15
+ --chunk-seconds 10 \
16
+ --out-dir /data/alarm
17
+
18
+ 注意:
19
+ - 本机需已安装 ffmpeg 且可访问 RTSP。
20
+ - nginx 已将 /data/alarm 映射至 http://<ip>/static/。
21
+ """
22
+
23
+ import argparse
24
+ import datetime as dt
25
+ import requests
26
+ import json
27
+ import os
28
+ import re
29
+ import shutil
30
+ import signal
31
+ import subprocess
32
+ import sys
33
+ import queue
34
+ import threading
35
+ import time
36
+ from typing import List, Optional, Tuple
37
+
38
+ # 使得可以从项目根目录导入 funasr
39
+ sys.path.append(os.path.abspath(os.path.join(os.path.dirname(__file__), "..")))
40
+
41
+ from funasr import AutoModel # type: ignore
42
+
43
+
44
+ # ----------------------------- 工具函数 -----------------------------
45
+
46
+ def ensure_dir(path: str) -> None:
47
+ os.makedirs(path, exist_ok=True)
48
+
49
+
50
+ def get_local_ip_fallback() -> str:
51
+ ip = "127.0.0.1"
52
+ return ip
53
+
54
+
55
+ def normalize_text(text: str) -> str:
56
+ """简单文本归一化:去空白、常见标点,转小写。"""
57
+ text = text.strip().lower()
58
+ # 去除中英文标点与空白
59
+ text = re.sub(r"[\s\u3000\t\r\n]+", "", text)
60
+ text = re.sub(r"[,。!?、;:‘’“”'\".,!?;:()\[\]{}<>-]", "", text)
61
+ return text
62
+
63
+
64
+ def longest_common_substring_len(a: str, b: str) -> int:
65
+ """计算最长公共子串长度(按字符计数,中文自然计为1个字符)。"""
66
+ s1 = normalize_text(a)
67
+ s2 = normalize_text(b)
68
+ if not s1 or not s2:
69
+ return 0
70
+ n, m = len(s1), len(s2)
71
+ # DP 优化为一维,记录上一行
72
+ prev = [0] * (m + 1)
73
+ best = 0
74
+ for i in range(1, n + 1):
75
+ cur = [0] * (m + 1)
76
+ for j in range(1, m + 1):
77
+ if s1[i - 1] == s2[j - 1]:
78
+ cur[j] = prev[j - 1] + 1
79
+ if cur[j] > best:
80
+ best = cur[j]
81
+ prev = cur
82
+ return best
83
+
84
+
85
+ def load_system_phrases(path: Optional[str]) -> List[str]:
86
+ if not path:
87
+ return []
88
+ if not os.path.exists(path):
89
+ return []
90
+ phrases: List[str] = []
91
+ with open(path, "r", encoding="utf-8") as f:
92
+ for line in f:
93
+ s = line.strip()
94
+ if s:
95
+ phrases.append(s)
96
+ return phrases
97
+
98
+
99
+ # ----------------------------- FFmpeg 处理 -----------------------------
100
+
101
+ class RtspSegmenter:
102
+ def __init__(
103
+ self,
104
+ rtsp_url: str,
105
+ out_dir_video: str,
106
+ segment_time: int = 10,
107
+ ) -> None:
108
+ self.rtsp_url = rtsp_url
109
+ self.out_dir_video = out_dir_video
110
+ self.segment_time = int(segment_time)
111
+ self.proc: Optional[subprocess.Popen] = None
112
+ ensure_dir(out_dir_video)
113
+
114
+ def build_cmd(self) -> List[str]:
115
+ # 输出文件名:seg_YYYYmmdd_HHMMSS.mp4
116
+ pattern = os.path.join(self.out_dir_video, "seg_%Y%m%d_%H%M%S.mp4")
117
+ cmd = [
118
+ "ffmpeg",
119
+ "-rtsp_transport",
120
+ "tcp",
121
+ "-stimeout",
122
+ "5000000", # 5s
123
+ "-i",
124
+ self.rtsp_url,
125
+ # 保留视频原编码,音频转为 aac 以保证 mp4 兼容,避免部分摄像头的 G.711 无法封装
126
+ "-c:v",
127
+ "copy",
128
+ "-c:a",
129
+ "aac",
130
+ "-b:a",
131
+ "128k",
132
+ # 分段参数
133
+ "-f",
134
+ "segment",
135
+ "-reset_timestamps",
136
+ "1",
137
+ "-segment_time",
138
+ str(self.segment_time),
139
+ "-strftime",
140
+ "1",
141
+ pattern,
142
+ ]
143
+ return cmd
144
+
145
+ def start(self) -> None:
146
+ self.stop()
147
+ cmd = self.build_cmd()
148
+ self.proc = subprocess.Popen(
149
+ cmd, stdout=subprocess.DEVNULL, stderr=subprocess.DEVNULL
150
+ )
151
+
152
+ def is_running(self) -> bool:
153
+ return self.proc is not None and self.proc.poll() is None
154
+
155
+ def stop(self) -> None:
156
+ if self.proc is not None and self.proc.poll() is None:
157
+ try:
158
+ self.proc.terminate()
159
+ try:
160
+ self.proc.wait(timeout=3)
161
+ except subprocess.TimeoutExpired:
162
+ self.proc.kill()
163
+ finally:
164
+ self.proc = None
165
+
166
+
167
+ def extract_wav_from_mp4(mp4_path: str, wav_path: str, timeout: int = 15) -> bool:
168
+ """从 mp4 提取 16k 单声道 wav。"""
169
+ cmd = [
170
+ "ffmpeg",
171
+ "-hide_banner",
172
+ "-loglevel",
173
+ "error",
174
+ "-nostdin",
175
+ "-y",
176
+ "-i",
177
+ mp4_path,
178
+ "-vn",
179
+ "-sn",
180
+ "-dn",
181
+ "-map",
182
+ "0:a:0?", # 显式映射首个音频流(可选)
183
+ "-ac",
184
+ "1",
185
+ "-ar",
186
+ "16000",
187
+ "-af",
188
+ "aresample=async=1:min_hard_comp=0.100:first_pts=0",
189
+ "-acodec",
190
+ "pcm_s16le",
191
+ wav_path,
192
+ ]
193
+ try:
194
+ ret = subprocess.run(
195
+ cmd, stdout=subprocess.PIPE, stderr=subprocess.PIPE, check=False, timeout=timeout
196
+ )
197
+ ok = ret.returncode == 0 and os.path.exists(wav_path)
198
+ if not ok:
199
+ # 打印简要诊断信息
200
+ msg = ret.stderr.decode("utf-8", errors="ignore").strip()
201
+ if msg:
202
+ print(f"[monitor] ffmpeg 提取失败: {os.path.basename(mp4_path)} => {msg.splitlines()[-1]}")
203
+ return ok
204
+ except subprocess.TimeoutExpired:
205
+ print(f"[monitor] ffmpeg 提取超时: {os.path.basename(mp4_path)}")
206
+ return False
207
+ except Exception as e:
208
+ print(f"[monitor] 提取异常: {e}")
209
+ return False
210
+
211
+
212
+ def ensure_wav_16k_mono(src_audio: str, dst_wav: str, timeout: int = 15) -> bool:
213
+ cmd = [
214
+ "ffmpeg",
215
+ "-y",
216
+ "-i",
217
+ src_audio,
218
+ "-ac",
219
+ "1",
220
+ "-ar",
221
+ "16000",
222
+ "-acodec",
223
+ "pcm_s16le",
224
+ dst_wav,
225
+ ]
226
+ try:
227
+ ret = subprocess.run(
228
+ cmd, stdout=subprocess.DEVNULL, stderr=subprocess.DEVNULL, check=False, timeout=timeout
229
+ )
230
+ return ret.returncode == 0 and os.path.exists(dst_wav)
231
+ except subprocess.TimeoutExpired:
232
+ print(f"[monitor] 参考音频转换超时: {os.path.basename(src_audio)}")
233
+ return False
234
+ except Exception:
235
+ return False
236
+
237
+
238
+ def concat_wav(sys_wav: str, seg_wav: str, out_wav: str, timeout: int = 15) -> bool:
239
+ """将系统参考音频与片段音频首尾拼接为 out_wav。"""
240
+ # 使用 concat filter,保证音频参数一致
241
+ cmd = [
242
+ "ffmpeg",
243
+ "-y",
244
+ "-i",
245
+ sys_wav,
246
+ "-i",
247
+ sys_wav,
248
+ "-i",
249
+ seg_wav,
250
+ "-filter_complex",
251
+ "[0:a][1:a][2:a]concat=n=3:v=0:a=1[a]",
252
+ "-map",
253
+ "[a]",
254
+ out_wav,
255
+ ]
256
+ try:
257
+ ret = subprocess.run(
258
+ cmd, stdout=subprocess.DEVNULL, stderr=subprocess.DEVNULL, check=False, timeout=timeout
259
+ )
260
+ return ret.returncode == 0 and os.path.exists(out_wav)
261
+ except subprocess.TimeoutExpired:
262
+ print(f"[monitor] 音频拼接超时: {os.path.basename(seg_wav)}")
263
+ return False
264
+ except Exception:
265
+ return False
266
+
267
+
268
+ # ----------------------------- 告警上报 -----------------------------
269
+
270
+ def post_alert(safety_url: str, when: str, timeout: int = 2):
271
+ """按协议 POST 上报,
272
+ 返回 (http_status, body_code, body_msg)
273
+ """
274
+ payload = {
275
+ "deviceId":"1287",
276
+ "deviceIp":"127.0.0.1",
277
+ "safetyId":"1",
278
+ "safetyName":"安全员1",
279
+ "warning":"way",
280
+ "type":1,
281
+ "safetyUrl":safety_url,
282
+ "brakeUrl":"",
283
+ "datatime":when,
284
+ "imgUrl":""
285
+ }
286
+ url = "http://182.92.230.1:9181/warning-agreement/upload"
287
+
288
+ headers = {"Content-Type": "application/json"}
289
+ r = requests.post(url, headers=headers, json=payload, timeout=timeout)
290
+ body_code = None
291
+ body_msg = None
292
+ try:
293
+ j = r.json()
294
+ body_code = int(j.get("code")) if "code" in j else None
295
+ body_msg = str(j.get("msg")) if "msg" in j else None
296
+ except Exception:
297
+ pass
298
+ return r.status_code, body_code, body_msg
299
+
300
+
301
+ # ----------------------------- 监控主逻辑 -----------------------------
302
+
303
+ class Monitor:
304
+ def __init__(
305
+ self,
306
+ rtsp_url: str,
307
+ system_audio: str,
308
+ out_dir: str = "/data/alarms",
309
+ chunk_seconds: int = 10,
310
+ target: str = "BM1684X",
311
+ dev_id: int = 0,
312
+ system_phrases_path: Optional[str] = None
313
+ ) -> None:
314
+ self.rtsp_url = rtsp_url
315
+ self.system_audio = system_audio
316
+ self.out_dir = out_dir
317
+ self.chunk_seconds = int(chunk_seconds)
318
+ self.target = target
319
+ self.dev_id = dev_id
320
+ self.system_phrases = load_system_phrases(system_phrases_path)
321
+ # 预先归一化系统提示词,便于快速整句匹配
322
+ self._system_phrase_norm_set = {normalize_text(p) for p in self.system_phrases if p.strip()}
323
+
324
+ self.dir_video = os.path.join(self.out_dir, "video")
325
+ self.dir_audio_tmp = os.path.join(self.out_dir, "audio_tmp")
326
+ ensure_dir(self.dir_video)
327
+ ensure_dir(self.dir_audio_tmp)
328
+
329
+ self.segmenter = RtspSegmenter(self.rtsp_url, self.dir_video, self.chunk_seconds)
330
+ self.stop_event = threading.Event()
331
+ self.processed_files: set[str] = set()
332
+ self.ffmpeg_timeout = 15 # seconds for ffmpeg operations
333
+
334
+ # 上报异步队列
335
+ self._alert_q: "queue.Queue[Tuple[str, str, List[tuple]]]" = queue.Queue()
336
+ self._alert_thread = threading.Thread(target=self._alert_worker, name="alert-worker", daemon=True)
337
+
338
+ # 预处理系统参考音频路径(最小修改:仅修正路径,不做格式转换)
339
+ if os.path.isabs(self.system_audio):
340
+ self.sys_wav_16k = self.system_audio
341
+ else:
342
+ # 相对路径按脚本所在目录解析,避免此前 join 到 audio_tmp 目录导致找不到文件
343
+ script_dir = os.path.dirname(os.path.abspath(__file__))
344
+ self.sys_wav_16k = os.path.normpath(os.path.join(script_dir, self.system_audio))
345
+ # 如需强制转换为 16k 单声道,可取消下列注释:
346
+ # tmp_conv = os.path.join(self.dir_audio_tmp, "_system_ref_16k.wav")
347
+ # if ensure_wav_16k_mono(self.sys_wav_16k, tmp_conv, timeout=self.ffmpeg_timeout):
348
+ # self.sys_wav_16k = tmp_conv
349
+
350
+ # 初始化 FunASR 模型(与 offline.py 保持一致)
351
+ self.model = AutoModel(
352
+ model=f"speech_seaco_paraformer_large_asr_nat-zh-cn-16k-common-vocab8404/models/{self.target}",
353
+ vad_model=f"speech_fsmn_vad_zh-cn-16k-common/models/{self.target}",
354
+ punc_model=f"punc_ct-transformer_zh-cn-common-vocab272727/models/{self.target}",
355
+ spk_model=f"speech_campplus_sv_zh-cn_16k-common/models/{self.target}",
356
+ device="cpu",
357
+ disable_update=True,
358
+ disable_pbar=True,
359
+ dev_id=self.dev_id,
360
+ )
361
+
362
+ self.ip = get_local_ip_fallback()
363
+ # 存储限制配置
364
+ self.max_bytes = 1024 * 1024 * 1024 # 1G
365
+ self.max_age_sec = 24 * 3600 # 1天
366
+ self._last_cleanup_ts = 0.0
367
+ # 启动异步上报线程
368
+ self._alert_thread.start()
369
+
370
+ # --------- 匹配系统提示词 ---------
371
+ def is_system_phrase(self, text: str) -> bool:
372
+ """系统提示词匹配:
373
+ 1) 先进行整句归一化精确匹配;
374
+ 2) 若未命中,再回退到最长公共子串长度 (>=5) 判定;
375
+ """
376
+ if not self._system_phrase_norm_set:
377
+ return False
378
+ norm = normalize_text(text)
379
+ if not norm:
380
+ return False
381
+ # 精确匹配
382
+ if norm in self._system_phrase_norm_set:
383
+ return True
384
+ # 回退 LCS
385
+ for p in self.system_phrases:
386
+ if longest_common_substring_len(text, p) >= 5:
387
+ return True
388
+ return False
389
+
390
+ # --------- 主循环 ---------
391
+ def run(self) -> None:
392
+ # 启动分段
393
+ self.segmenter.start()
394
+ print("[monitor] RTSP 分段已启动")
395
+
396
+ try:
397
+ while not self.stop_event.is_set():
398
+ # 保活 ffmpeg
399
+ if not self.segmenter.is_running():
400
+ print("[monitor] ffmpeg 已退出,尝试重启...")
401
+ self.segmenter.start()
402
+
403
+ # 扫描新的视频段
404
+ try:
405
+ files = [
406
+ f
407
+ for f in os.listdir(self.dir_video)
408
+ if f.startswith("seg_") and f.endswith(".mp4")
409
+ ]
410
+ except FileNotFoundError:
411
+ files = []
412
+
413
+ # 计算每个文件的 mtime,并跳过当前最新(热点)文件,避免处理写入中的分段
414
+ mtimes: dict[str, float] = {}
415
+ latest_file: Optional[str] = None
416
+ latest_mtime: float = -1.0
417
+ for f in files:
418
+ fpath0 = os.path.join(self.dir_video, f)
419
+ try:
420
+ m = os.path.getmtime(fpath0)
421
+ mtimes[f] = m
422
+ if m > latest_mtime:
423
+ latest_mtime = m
424
+ latest_file = f
425
+ except FileNotFoundError:
426
+ continue
427
+
428
+ # 按 mtime 升序处理(从旧到新),进一步降低并发写入影响
429
+ files_sorted = sorted((f for f in mtimes.keys()), key=lambda x: mtimes[x])
430
+
431
+ now = time.time()
432
+ for fname in files_sorted:
433
+ # 跳过热点文件
434
+ if latest_file and fname == latest_file:
435
+ continue
436
+ if fname in self.processed_files:
437
+ continue
438
+ fpath = os.path.join(self.dir_video, fname)
439
+ # 避免处理正在写入的文件:至少间隔 1s
440
+ try:
441
+ mtime = os.path.getmtime(fpath)
442
+ except FileNotFoundError:
443
+ continue
444
+ # 保守等待:距最后修改至少 2.5s 且大小稳定
445
+ if now - mtime < 2.5 or not self._is_file_stable(fpath):
446
+ continue
447
+
448
+ # 处理该切片
449
+ try:
450
+ self._process_segment(fpath)
451
+ except Exception as e:
452
+ print(f"[monitor] 处理失败 {fname}: {e}")
453
+ finally:
454
+ self.processed_files.add(fname)
455
+
456
+ # processed_files 防膨胀
457
+ if len(self.processed_files) > 10000:
458
+ self.processed_files.clear()
459
+
460
+ # 定期清理:空间与时效
461
+ if time.time() - self._last_cleanup_ts > 30:
462
+ try:
463
+ self._enforce_retention_and_quota()
464
+ except Exception as e:
465
+ print(f"[monitor] 清理异常: {e}")
466
+ self._last_cleanup_ts = time.time()
467
+
468
+ time.sleep(0.2)
469
+ finally:
470
+ self.segmenter.stop()
471
+ # 通知并等待上报线程结束
472
+ self._stop_alert_worker()
473
+
474
+ def _process_segment(self, mp4_path: str) -> None:
475
+ base = os.path.splitext(os.path.basename(mp4_path))[0]
476
+ wav_path = os.path.join(self.dir_audio_tmp, base + ".wav")
477
+ joined_wav = os.path.join(self.dir_audio_tmp, base + "_joined.wav")
478
+
479
+ if not extract_wav_from_mp4(mp4_path, wav_path, timeout=self.ffmpeg_timeout):
480
+ print(f"[monitor] 提取音频失败: {mp4_path}")
481
+ return
482
+
483
+ if not concat_wav(self.sys_wav_16k, wav_path, joined_wav, timeout=self.ffmpeg_timeout):
484
+ print(f"[monitor] 拼接音频失败: {wav_path}")
485
+ return
486
+
487
+ # 识别
488
+ res = self.model.generate(input=joined_wav, batch_size_s=self.chunk_seconds)
489
+ suspicious = False
490
+ details = []
491
+
492
+ # 新判定逻辑:
493
+ # 1) 若所有说话人均为 0 => 直接通过(不上报)
494
+ # 2) 若出现非 0 说话人:
495
+ # - 针对其文本做系统提示词匹配
496
+ # - 若该文本匹配通过:将该分句的 spk 重写为 0
497
+ # - 若存在任意一条非 0 文本未匹配 => 触发告警 (suspicious=True)
498
+ # 3) 无句级信息时:整体文本若非系统提示词 => 告警
499
+ if isinstance(res, list) and res and isinstance(res[0], dict):
500
+ item = res[0]
501
+ if "sentence_info" in item and isinstance(item.get("sentence_info"), list) and item["sentence_info"]:
502
+ sentence_infos = item["sentence_info"]
503
+ # 先收集,后决定是否需要改写 spk
504
+ any_non_zero = False
505
+ tmp_details = [] # 暂存以便可能改写 spk
506
+ for si in sentence_infos:
507
+ spk = int(si.get("spk", -1))
508
+ text = str(si.get("text", ""))
509
+ if spk != 0:
510
+ any_non_zero = True
511
+ tmp_details.append([spk, text]) # 可修改
512
+
513
+ if not any_non_zero:
514
+ # 全 0 -> 直接通过
515
+ suspicious = False
516
+ else:
517
+ # 针对非0 说话人文本做匹配
518
+ for d in tmp_details:
519
+ spk, text = d
520
+ if spk != 0:
521
+ if self.is_system_phrase(text):
522
+ # 匹配通过,视作系统说话人,改写 spk=0
523
+ d[0] = 0
524
+ else:
525
+ suspicious = True # 发现未匹配文本,触发告警
526
+
527
+ # 写回 details(保证外部日志记录显示最终 spk 值)
528
+ details.extend([(spk, text) for spk, text in tmp_details])
529
+ else:
530
+ # 无句级信息:按整体文本兜底
531
+ text = str(item.get("text", ""))
532
+ details.append((0, text))
533
+ if text and not self.is_system_phrase(text):
534
+ suspicious = True
535
+
536
+ print(f"[monitor] {os.path.basename(mp4_path)} 识别结果: {details}")
537
+
538
+ if suspicious:
539
+ # 留存视频文件(文件已在 out_dir/video 下,无需再复制;直接构造 URL)
540
+ rel_path = os.path.relpath(mp4_path, self.out_dir)
541
+ # 如果不在 out_dir 下,移动到 out_dir/video
542
+ if rel_path.startswith(".."):
543
+ dst = os.path.join(self.dir_video, os.path.basename(mp4_path))
544
+ try:
545
+ shutil.move(mp4_path, dst)
546
+ rel_path = os.path.relpath(dst, self.out_dir)
547
+ except Exception:
548
+ # 复制失败也不影响上报
549
+ rel_path = os.path.basename(mp4_path)
550
+
551
+ safety_url = f"http://{self.ip}/static/{rel_path}"
552
+ # 从文件名提取时间,否则用当前时间
553
+ ts = self._datetime_from_filename(os.path.basename(mp4_path)) or dt.datetime.now()
554
+ datatime = ts.strftime("%Y-%m-%d %H:%M:%S")
555
+
556
+ print(f"[monitor] 触发告警 -> {safety_url} @ {datatime},已入队上报")
557
+ self._enqueue_alert(safety_url, datatime, details)
558
+
559
+ # 清理中间音频
560
+ for p in (wav_path, joined_wav):
561
+ try:
562
+ if os.path.exists(p):
563
+ os.remove(p)
564
+ except Exception:
565
+ pass
566
+
567
+ # 未触发告警则删除视频,避免占用空间
568
+ if not suspicious:
569
+ try:
570
+ if os.path.exists(mp4_path):
571
+ os.remove(mp4_path)
572
+ except Exception:
573
+ pass
574
+
575
+ def _is_file_stable(self, path: str, checks: int = 3, interval: float = 0.35) -> bool:
576
+ """检测文件大小在短时间内是否稳定,避免处理未完全写入的分段。"""
577
+ try:
578
+ last = os.path.getsize(path)
579
+ for _ in range(max(1, checks)):
580
+ time.sleep(max(0.05, interval))
581
+ cur = os.path.getsize(path)
582
+ if cur != last:
583
+ last = cur
584
+ return False
585
+ return True
586
+ except Exception:
587
+ return False
588
+
589
+ def _datetime_from_filename(self, fname: str) -> Optional[dt.datetime]:
590
+ # 形如 seg_YYYYmmdd_HHMMSS.mp4
591
+ m = re.match(r"seg_(\d{8})_(\d{6})", fname)
592
+ if not m:
593
+ return None
594
+ try:
595
+ return dt.datetime.strptime(m.group(1) + m.group(2), "%Y%m%d%H%M%S")
596
+ except Exception:
597
+ return None
598
+
599
+ def _append_alert_log(self, url: str, when: str, details: List[tuple], http_status: Optional[int], body_code: Optional[int], body_msg: Optional[str]) -> None:
600
+ log_dir = os.path.join(os.path.dirname(__file__), "alerts")
601
+ ensure_dir(log_dir)
602
+ log_path = os.path.join(log_dir, "alerts.log")
603
+ line = json.dumps({
604
+ "time": when,
605
+ "url": url,
606
+ "details": details,
607
+ "http_status": http_status,
608
+ "code": body_code,
609
+ "msg": body_msg,
610
+ }, ensure_ascii=False)
611
+ try:
612
+ with open(log_path, "a", encoding="utf-8") as f:
613
+ f.write(line + "\n")
614
+ except Exception:
615
+ pass
616
+
617
+ def _enforce_retention_and_quota(self) -> None:
618
+ """删除超期文件,并按时间从旧到新删除以满足空间上限。"""
619
+ # 1) 删除超过保存期的文件
620
+ now = time.time()
621
+ video_files = []
622
+ try:
623
+ for fname in os.listdir(self.dir_video):
624
+ if not fname.endswith(".mp4"):
625
+ continue
626
+ fpath = os.path.join(self.dir_video, fname)
627
+ try:
628
+ st = os.stat(fpath)
629
+ except FileNotFoundError:
630
+ continue
631
+ # 删除超龄
632
+ if now - st.st_mtime > self.max_age_sec:
633
+ try:
634
+ os.remove(fpath)
635
+ except Exception:
636
+ pass
637
+ else:
638
+ video_files.append((fpath, st.st_mtime, st.st_size))
639
+ except FileNotFoundError:
640
+ pass
641
+
642
+ # 2) 若空间超限,按时间从旧到新删除
643
+ total = sum(s for _, _, s in video_files)
644
+ if total > self.max_bytes:
645
+ # 按修改时间升序
646
+ video_files.sort(key=lambda x: x[1])
647
+ idx = 0
648
+ while total > self.max_bytes and idx < len(video_files):
649
+ fpath, _, sz = video_files[idx]
650
+ try:
651
+ os.remove(fpath)
652
+ total -= sz
653
+ except Exception:
654
+ pass
655
+ idx += 1
656
+
657
+ # ---------- 上报异步处理 ----------
658
+ def _enqueue_alert(self, url: str, when: str, details: List[tuple]) -> None:
659
+ try:
660
+ self._alert_q.put_nowait((url, when, details))
661
+ except Exception:
662
+ # 队列异常时直接同步上报作为兜底
663
+ http_status, body_code, body_msg = post_alert(url, when, timeout=2)
664
+ if body_code is not None:
665
+ print(f"[monitor] 上报返回 code={body_code}, msg={body_msg}")
666
+ else:
667
+ print(f"[monitor] 上报返回 http_status={http_status}")
668
+ self._append_alert_log(url, when, details, http_status, body_code, body_msg)
669
+
670
+ def _alert_worker(self) -> None:
671
+ while not self.stop_event.is_set() or not self._alert_q.empty():
672
+ try:
673
+ url, when, details = self._alert_q.get(timeout=0.5)
674
+ except queue.Empty:
675
+ continue
676
+ try:
677
+ http_status, body_code, body_msg = post_alert(url, when, timeout=2)
678
+ if body_code is not None:
679
+ print(f"[monitor] 上报返回 code={body_code}, msg={body_msg}")
680
+ else:
681
+ print(f"[monitor] 上报返回 http_status={http_status}")
682
+ self._append_alert_log(url, when, details, http_status, body_code, body_msg)
683
+ except Exception as e:
684
+ print(f"[monitor] 上报���常: {e}")
685
+ finally:
686
+ try:
687
+ self._alert_q.task_done()
688
+ except Exception:
689
+ pass
690
+
691
+ def _stop_alert_worker(self) -> None:
692
+ # 等待队列尽量清空
693
+ deadline = time.time() + 2.5
694
+ while not self._alert_q.empty() and time.time() < deadline:
695
+ time.sleep(0.1)
696
+ # 线程将根据 stop_event 退出
697
+ try:
698
+ if self._alert_thread.is_alive():
699
+ self._alert_thread.join(timeout=2)
700
+ except Exception:
701
+ pass
702
+
703
+
704
+ def parse_args() -> argparse.Namespace:
705
+ parser = argparse.ArgumentParser(description="监控场景下非系统人声检测与上报")
706
+ parser.add_argument("--rtsp", required=True, help="RTSP 地址,例如 rtsp://user:pass@ip:554/Streaming/Channels/101")
707
+ parser.add_argument(
708
+ "--system-audio",
709
+ default="../system_ref.wav",
710
+ help="系统参考音频,作为前置拼接,系统说话人 spk=0",
711
+ )
712
+ parser.add_argument("--out-dir", default="/data/alarms", help="告警本地保存目录 (已由 nginx 映射到 /static)")
713
+ parser.add_argument("--chunk-seconds", type=int, default=10, help="检测窗口秒数,默认 10s")
714
+ parser.add_argument("--target", default="BM1684X", help="模型目标平台目录名,如 BM1684X/BM1688")
715
+ parser.add_argument("--dev-id", type=int, default=0, help="设备 ID")
716
+ parser.add_argument(
717
+ "--system-phrases",
718
+ default="../system_phrases.txt",
719
+ help="系统提示词文本库(每行一条),用于过滤系统播报文本",
720
+ )
721
+ return parser.parse_args()
722
+
723
+
724
+ def main() -> None:
725
+ args = parse_args()
726
+
727
+ monitor = Monitor(
728
+ rtsp_url=args.rtsp,
729
+ system_audio=args.system_audio,
730
+ out_dir=args.out_dir,
731
+ chunk_seconds=args.chunk_seconds,
732
+ target=args.target,
733
+ dev_id=args.dev_id,
734
+ system_phrases_path=args.system_phrases
735
+ )
736
+
737
+ # 优雅退出
738
+ def handle_sig(signum, frame):
739
+ print("[monitor] 收到退出信号,正在停止...")
740
+ monitor.stop_event.set()
741
+
742
+ signal.signal(signal.SIGINT, handle_sig)
743
+ signal.signal(signal.SIGTERM, handle_sig)
744
+
745
+ monitor.run()
746
+
747
+
748
+ if __name__ == "__main__":
749
+ main()
bmodel/offline.py ADDED
@@ -0,0 +1,35 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ #!/bin/python3
2
+
3
+ import sys
4
+ sys.path.append("..")
5
+
6
+ from funasr import AutoModel
7
+ import time
8
+
9
+ file_path1 = "../system_ref.wav"
10
+
11
+ dev_id = 0
12
+ target = "BM1684X"
13
+
14
+ # offline asr demo
15
+ model = AutoModel(
16
+ model="speech_seaco_paraformer_large_asr_nat-zh-cn-16k-common-vocab8404/models/"+target, ## 语音识别模型
17
+ vad_model="speech_fsmn_vad_zh-cn-16k-common/models/"+target, ## 语音端点检测模型
18
+ punc_model="punc_ct-transformer_zh-cn-common-vocab272727/models/"+target, ## 标点恢复模型
19
+ spk_model="speech_campplus_sv_zh-cn_16k-common/models/"+target, ## 说话人识别模型
20
+ device="cpu",
21
+ disable_update=True,
22
+ disable_pbar=True,
23
+ dev_id=dev_id,
24
+ )
25
+
26
+ # inference
27
+ start_time = time.time()
28
+ res = model.generate(input=file_path1, batch_size_s=300,)
29
+ end_time = time.time()
30
+ if "sentence_info" in res[0].keys():
31
+ for si in res[0]["sentence_info"]:
32
+ print("["+format(si["start"],"7d")+"]["+format(si["end"],"7d")+"], spk="+format(si["spk"],'2d')+", text: "+si["text"])
33
+ else:
34
+ print(res[0]["text"])
35
+ print("generate time:", end_time-start_time)
bmodel/punc_ct-transformer_zh-cn-common-vocab272727/README.md ADDED
@@ -0,0 +1,25 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ ## 模型编译
2
+
3
+ 源模型需要编译成BModel才能在SOPHON TPU上运行,源模型在编译前要导出成onnx模型,具体可参考[导出ONNX](https://github.com/modelscope/FunASR/blob/main/README_zh.md#%E5%AF%BC%E5%87%BAonnx)。
4
+
5
+ 建议使用TPU-MLIR编译BModel,模型编译前需要安装TPU-MLIR编译环境,具体可参考[TPU-MLIR环境搭建](https://github.com/sophgo/sophon-demo/blob/release/docs/Environment_Install_Guide.md#1-tpu-mlir环境搭建)。安装好后需在TPU-MLIR环境中进入例程目录,并使用本例程提供的脚本将onnx模型编译为BModel。脚本中命令的详细说明可参考《TPU-MLIR开发手册》( 请从[算能官网](https://developer.sophgo.com/site/index.html?categoryActive=material)相应版本的SDK中获取)。
6
+
7
+ - 生成FP32 BModel
8
+
9
+ ​本例程在`scripts`目录下提供了TPU-MLIR编译FP32 BModel的脚本,请注意修改`gen_fp32bmodel_mlir.sh`中的onnx模型路径、生成模型目录和输入大小shapes等参数,并在执行时指定BModel运行的目标平台(**支持BM1684X/BM1688**),如:
10
+
11
+ ```bash
12
+ ./scripts/gen_fp32bmodel_mlir.sh bm1684x #bm1684x/bm1688
13
+ ```
14
+
15
+ ​执行上述命令会在`models/BM1684X`等文件夹下生成`punc_fp32.bmodel`文件,即转换好的FP32 BModel。
16
+
17
+ - 生成FP16 BModel
18
+
19
+ ​本例程在`scripts`目录下提供了TPU-MLIR编译FP16 BModel的脚本,请注意修改`gen_fp16bmodel_mlir.sh`中的onnx模型路径、生成模型目录和输入大小shapes等参数,并在执行时指定BModel运行的目标平台(**支持BM1684X/BM1688**),如:
20
+
21
+ ```bash
22
+ ./scripts/gen_fp16bmodel_mlir.sh bm1688 #bm1684x/bm1688
23
+ ```
24
+
25
+ ​执行上述命令会在`models/BM1688/`等文件夹下生成`punc_fp16.bmodel`文件,即转换好的FP16 BModel。
bmodel/punc_ct-transformer_zh-cn-common-vocab272727/models/BM1684X/config.yaml ADDED
@@ -0,0 +1,46 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ model: CTTransformer
2
+ model_conf:
3
+ ignore_id: 0
4
+ embed_unit: 256
5
+ att_unit: 256
6
+ dropout_rate: 0.1
7
+ punc_list:
8
+ - <unk>
9
+ - _
10
+ - ,
11
+ - 。
12
+ - ?
13
+ - 、
14
+ punc_weight:
15
+ - 1.0
16
+ - 1.0
17
+ - 1.0
18
+ - 1.0
19
+ - 1.0
20
+ - 1.0
21
+ sentence_end_id: 3
22
+
23
+ encoder: SANMEncoder
24
+ encoder_conf:
25
+ input_size: 256
26
+ output_size: 256
27
+ attention_heads: 8
28
+ linear_units: 1024
29
+ num_blocks: 4
30
+ dropout_rate: 0.1
31
+ positional_dropout_rate: 0.1
32
+ attention_dropout_rate: 0.0
33
+ input_layer: pe
34
+ pos_enc_class: SinusoidalPositionEncoder
35
+ normalize_before: true
36
+ kernel_size: 11
37
+ sanm_shfit: 0
38
+ selfattention_layer_type: sanm
39
+ padding_idx: 0
40
+
41
+ tokenizer: CharTokenizer
42
+ tokenizer_conf:
43
+ unk_symbol: <unk>
44
+
45
+
46
+
bmodel/punc_ct-transformer_zh-cn-common-vocab272727/models/BM1684X/punc_fp16.bmodel ADDED
@@ -0,0 +1,3 @@
 
 
 
 
1
+ version https://git-lfs.github.com/spec/v1
2
+ oid sha256:b6586f73359d912fc7a3363785987677803c54dde51040324b72beb23c36a400
3
+ size 149453880
bmodel/punc_ct-transformer_zh-cn-common-vocab272727/models/BM1684X/tokens.json ADDED
The diff for this file is too large to render. See raw diff
 
bmodel/punc_ct-transformer_zh-cn-common-vocab272727/scripts/download.sh ADDED
@@ -0,0 +1,35 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ #!/bin/bash
2
+ res=$(which unzip)
3
+ if [ $? != 0 ]; then
4
+ echo "Please install unzip on your system!"
5
+ echo "Please run the following command: sudo apt-get install unzip"
6
+ exit
7
+ fi
8
+ echo "unzip is installed in your system!"
9
+
10
+ pip3 install dfss -i https://pypi.tuna.tsinghua.edu.cn/simple --upgrade
11
+
12
+ scripts_dir=$(dirname $(readlink -f "$0"))
13
+ name=punc_ct-transformer_zh-cn-common-vocab272727
14
+ pushd $scripts_dir
15
+
16
+ # models
17
+ if [ ! -d "../models" ]; then
18
+ # mkdir -p ../models
19
+ # python3 -m dfss --url=open@sophgo.com:sophon-demo/FunASR/${name}/onnx.zip
20
+ # unzip onnx.zip -d ../models
21
+ # rm onnx.zip
22
+ # echo "onnx download!"
23
+ python3 -m dfss --url=open@sophgo.com:sophon-demo/FunASR/${name}/BM1684X.zip
24
+ unzip BM1684X.zip -d ../models
25
+ rm BM1684X.zip
26
+ echo "BM1684X model download!"
27
+ # python3 -m dfss --url=open@sophgo.com:sophon-demo/FunASR/${name}/BM1688.zip
28
+ # unzip BM1688.zip -d ../models
29
+ # rm BM1688.zip
30
+ # echo "BM1688 model download!"
31
+ else
32
+ echo "models folder exist! Remove it if you need to update."
33
+ fi
34
+
35
+ popd
bmodel/punc_ct-transformer_zh-cn-common-vocab272727/scripts/gen_fp16bmodel_mlir.sh ADDED
@@ -0,0 +1,51 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ #!/bin/bash
2
+ model_dir=$(dirname $(readlink -f "$0"))
3
+
4
+ if [ ! $1 ]; then
5
+ target=bm1684x
6
+ target_dir=BM1684X
7
+ else
8
+ target=${1,,}
9
+ target_dir=${target^^}
10
+ fi
11
+
12
+ name=punc
13
+ outdir=../models/$target_dir
14
+
15
+ function gen_mlir()
16
+ {
17
+ model_transform.py \
18
+ --model_name ${name} \
19
+ --model_def ../models/onnx/${name}.onnx \
20
+ --input_shapes [[1,200],[1]] \
21
+ --test_input input_0.npz \
22
+ --test_result ${name}_top_results.npz \
23
+ --dynamic \
24
+ --mlir ${name}.mlir
25
+ }
26
+
27
+ function gen_fp16bmodel()
28
+ {
29
+ model_deploy.py \
30
+ --mlir ${name}.mlir \
31
+ --quantize F16 \
32
+ --chip $target \
33
+ --dynamic \
34
+ --disable_layer_group \
35
+ --test_input ${name}_in_f32.npz \
36
+ --test_reference ${name}_top_results.npz \
37
+ --tolerance 0.99,0.99 \
38
+ --model ${name}_fp16.bmodel
39
+
40
+ mv ${name}_fp16.bmodel $outdir/
41
+ }
42
+
43
+ pushd $model_dir
44
+ if [ ! -d $outdir ]; then
45
+ mkdir -p $outdir
46
+ fi
47
+ # batch_size=1
48
+ gen_mlir
49
+ gen_fp16bmodel
50
+
51
+ popd
bmodel/punc_ct-transformer_zh-cn-common-vocab272727/scripts/gen_fp32bmodel_mlir.sh ADDED
@@ -0,0 +1,51 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ #!/bin/bash
2
+ model_dir=$(dirname $(readlink -f "$0"))
3
+
4
+ if [ ! $1 ]; then
5
+ target=bm1684x
6
+ target_dir=BM1684X
7
+ else
8
+ target=${1,,}
9
+ target_dir=${target^^}
10
+ fi
11
+
12
+ name=punc
13
+ outdir=../models/$target_dir
14
+
15
+ function gen_mlir()
16
+ {
17
+ model_transform.py \
18
+ --model_name ${name} \
19
+ --model_def ../models/onnx/${name}.onnx \
20
+ --input_shapes [[1,200],[1]] \
21
+ --test_input input_0.npz \
22
+ --test_result ${name}_top_results.npz \
23
+ --dynamic \
24
+ --mlir ${name}.mlir
25
+ }
26
+
27
+ function gen_fp32bmodel()
28
+ {
29
+ model_deploy.py \
30
+ --mlir ${name}.mlir \
31
+ --quantize F32 \
32
+ --chip $target \
33
+ --dynamic \
34
+ --disable_layer_group \
35
+ --test_input ${name}_in_f32.npz \
36
+ --test_reference ${name}_top_results.npz \
37
+ --tolerance 0.99,0.99 \
38
+ --model ${name}_fp32.bmodel
39
+
40
+ mv ${name}_fp32.bmodel $outdir/
41
+ }
42
+
43
+ pushd $model_dir
44
+ if [ ! -d $outdir ]; then
45
+ mkdir -p $outdir
46
+ fi
47
+ # batch_size=1
48
+ gen_mlir
49
+ gen_fp32bmodel
50
+
51
+ popd
bmodel/punc_ct-transformer_zh-cn-common-vocab272727/scripts/gen_input.py ADDED
@@ -0,0 +1,10 @@
 
 
 
 
 
 
 
 
 
 
 
1
+ #!/bin/python3
2
+ import torch
3
+ import numpy as np
4
+
5
+ length = 200
6
+ text_indexes = torch.randint(0, 272727, (1, length)).type(torch.int32)
7
+ text_indexes = text_indexes.detach().numpy()#.astype(np.float32)
8
+ text_lengths = torch.tensor([length], dtype=torch.int32)
9
+ text_lengths = text_lengths.detach().numpy()#.astype(np.float32)
10
+ np.savez("input_0.npz", inputs=text_indexes, text_lengths=text_lengths)
bmodel/speech_campplus_sv_zh-cn_16k-common/models/BM1684X/campplus_fp16_1b.bmodel ADDED
@@ -0,0 +1,3 @@
 
 
 
 
1
+ version https://git-lfs.github.com/spec/v1
2
+ oid sha256:cb31395a1d5e85c4529fade265f388cbbaa32e51ddeeb8b984a8b5fbbaa52eab
3
+ size 18343016
bmodel/speech_campplus_sv_zh-cn_16k-common/models/BM1684X/campplus_fp32_1b.bmodel ADDED
@@ -0,0 +1,3 @@
 
 
 
 
1
+ version https://git-lfs.github.com/spec/v1
2
+ oid sha256:5257a2b99c2cb65169464fd7b24a9fc8925e64ff645eab4f2a898599453afc51
3
+ size 31780256
bmodel/speech_campplus_sv_zh-cn_16k-common/models/BM1684X/config.yaml ADDED
@@ -0,0 +1,23 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # This is an example that demonstrates how to configure a model file.
2
+ # You can modify the configuration according to your own requirements.
3
+
4
+ # to print the register_table:
5
+ # from funasr.register import tables
6
+ # tables.print()
7
+
8
+ # network architecture
9
+ model: CAMPPlus
10
+ model_conf:
11
+ feat_dim: 80
12
+ embedding_size: 192
13
+ growth_rate: 32
14
+ bn_size: 4
15
+ init_channels: 128
16
+ config_str: 'batchnorm-relu'
17
+ memory_efficient: True
18
+ output_level: 'segment'
19
+
20
+ # frontend related
21
+ frontend: WavFrontend
22
+ frontend_conf:
23
+ fs: 16000
bmodel/speech_campplus_sv_zh-cn_16k-common/scripts/download.sh ADDED
@@ -0,0 +1,35 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ #!/bin/bash
2
+ res=$(which unzip)
3
+ if [ $? != 0 ]; then
4
+ echo "Please install unzip on your system!"
5
+ echo "Please run the following command: sudo apt-get install unzip"
6
+ exit
7
+ fi
8
+ echo "unzip is installed in your system!"
9
+
10
+ pip3 install dfss -i https://pypi.tuna.tsinghua.edu.cn/simple --upgrade
11
+
12
+ scripts_dir=$(dirname $(readlink -f "$0"))
13
+ name=speech_campplus_sv_zh-cn_16k-common
14
+ pushd $scripts_dir
15
+
16
+ # models
17
+ if [ ! -d "../models" ]; then
18
+ mkdir -p ../models
19
+ # python3 -m dfss --url=open@sophgo.com:sophon-demo/FunASR/${name}/onnx.zip
20
+ # unzip onnx.zip -d ../models
21
+ # rm onnx.zip
22
+ # echo "onnx download!"
23
+ python3 -m dfss --url=open@sophgo.com:sophon-demo/FunASR/${name}/BM1684X.zip
24
+ unzip BM1684X.zip -d ../models
25
+ rm BM1684X.zip
26
+ echo "BM1684X model download!"
27
+ # python3 -m dfss --url=open@sophgo.com:sophon-demo/FunASR/${name}/BM1688.zip
28
+ # unzip BM1688.zip -d ../models
29
+ # rm BM1688.zip
30
+ # echo "BM1688 model download!"
31
+ else
32
+ echo "models folder exist! Remove it if you need to update."
33
+ fi
34
+
35
+ popd
bmodel/speech_campplus_sv_zh-cn_16k-common/scripts/gen_fp16bmodel_mlir.sh ADDED
@@ -0,0 +1,49 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ #!/bin/bash
2
+ model_dir=$(dirname $(readlink -f "$0"))
3
+
4
+ if [ ! $1 ]; then
5
+ target=bm1684x
6
+ target_dir=BM1684X
7
+ else
8
+ target=${1,,}
9
+ target_dir=${target^^}
10
+ fi
11
+
12
+ name=campplus
13
+
14
+ outdir=../models/$target_dir
15
+
16
+ function gen_mlir()
17
+ {
18
+ model_transform.py \
19
+ --model_name $name \
20
+ --model_def ../models/onnx/${name}.onnx \
21
+ --input_shapes [[$1,148,80]] \
22
+ --mlir ${name}_$1b.mlir
23
+ }
24
+
25
+ function gen_fp16bmodel()
26
+ {
27
+ model_deploy.py \
28
+ --mlir ${name}_$1b.mlir \
29
+ --quantize F16 \
30
+ --chip $target \
31
+ --disable_layer_group \
32
+ --model ${name}_fp16_$1b.bmodel
33
+ mv ${name}_fp16_$1b.bmodel $outdir
34
+ }
35
+
36
+ pushd $model_dir
37
+ if [ ! -d "$outdir" ]; then
38
+ echo $pwd
39
+ mkdir $outdir
40
+ fi
41
+
42
+ # batch_size=1
43
+ gen_mlir 1
44
+ gen_fp16bmodel 1
45
+
46
+ # batch_size=4
47
+ #gen_mlir 4
48
+ #gen_fp16bmodel 4
49
+ popd
bmodel/speech_campplus_sv_zh-cn_16k-common/scripts/gen_fp32bmodel_mlir.sh ADDED
@@ -0,0 +1,49 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ #!/bin/bash
2
+ model_dir=$(dirname $(readlink -f "$0"))
3
+
4
+ if [ ! $1 ]; then
5
+ target=bm1684x
6
+ target_dir=BM1684X
7
+ else
8
+ target=${1,,}
9
+ target_dir=${target^^}
10
+ fi
11
+
12
+ name=campplus
13
+
14
+ outdir=../models/$target_dir
15
+
16
+ function gen_mlir()
17
+ {
18
+ model_transform.py \
19
+ --model_name $name \
20
+ --model_def ../models/onnx/${name}.onnx \
21
+ --input_shapes [[$1,148,80]] \
22
+ --mlir ${name}_$1b.mlir
23
+ }
24
+
25
+ function gen_fp32bmodel()
26
+ {
27
+ model_deploy.py \
28
+ --mlir ${name}_$1b.mlir \
29
+ --quantize F32 \
30
+ --chip $target \
31
+ --disable_layer_group \
32
+ --model ${name}_fp32_$1b.bmodel
33
+ mv ${name}_fp32_$1b.bmodel $outdir
34
+ }
35
+
36
+ pushd $model_dir
37
+ if [ ! -d "$outdir" ]; then
38
+ echo $pwd
39
+ mkdir $outdir
40
+ fi
41
+
42
+ # batch_size=1
43
+ gen_mlir 1
44
+ gen_fp32bmodel 1
45
+
46
+ # batch_size=4
47
+ #gen_mlir 4
48
+ #gen_fp32bmodel 4
49
+ popd
bmodel/speech_fsmn_vad_zh-cn-16k-common/README.md ADDED
@@ -0,0 +1,25 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ ## 模型编译
2
+
3
+ 源模型需要编译成BModel才能在SOPHON TPU上运行,源模型在编译前要导出成onnx模型,具体可参考[导出ONNX](https://github.com/modelscope/FunASR/blob/main/README_zh.md#%E5%AF%BC%E5%87%BAonnx)。
4
+
5
+ 建议使用TPU-MLIR编译BModel,模型编译前需要安装TPU-MLIR编译环境,具体可参考[TPU-MLIR环境搭建](https://github.com/sophgo/sophon-demo/blob/release/docs/Environment_Install_Guide.md#1-tpu-mlir环境搭建)。安装好后需在TPU-MLIR环境中进入例程目录,并使用本例程提供的脚本将onnx模型编译为BModel。脚本中命令的详细说明可参考《TPU-MLIR开发手册》( 请从[算能官网](https://developer.sophgo.com/site/index.html?categoryActive=material)相应版本的SDK中获取)。
6
+
7
+ - 生成FP32 BModel
8
+
9
+ ​本例程在`scripts`目录下提供了TPU-MLIR编译FP32 BModel的脚本,请注意修改`gen_fp32bmodel_mlir.sh`中的onnx模型路径、生成模型目录和输入大小shapes等参数,并在执行时指定BModel运行的目标平台(**支持BM1684X/BM1688**),如:
10
+
11
+ ```bash
12
+ ./scripts/gen_fp32bmodel_mlir.sh bm1684x #bm1684x/bm1688
13
+ ```
14
+
15
+ ​执行上述命令会在`models/BM1684X`等文件夹下生成`fsmn_fp32.bmodel`文件,即转换好的FP32 BModel。
16
+
17
+ - 生成FP16 BModel
18
+
19
+ ​本例程在`scripts`目录下提供了TPU-MLIR编译FP16 BModel的脚本,请注意修改`gen_fp16bmodel_mlir.sh`中的onnx模型路径、生成模型目录和输入大小shapes等参数,并在执行时指定BModel运行的目标平台(**支持BM1684X/BM1688**),如:
20
+
21
+ ```bash
22
+ ./scripts/gen_fp16bmodel_mlir.sh bm1688 #bm1684x/bm1688
23
+ ```
24
+
25
+ ​执行上述命令会在`models/BM1688/`等文件夹下生成`fsmn_fp16.bmodel`文件,即转换好的FP16 BModel。
bmodel/speech_fsmn_vad_zh-cn-16k-common/models/BM1684X/am.mvn ADDED
@@ -0,0 +1,8 @@
 
 
 
 
 
 
 
 
 
1
+ <Nnet>
2
+ <Splice> 400 400
3
+ [ 0 ]
4
+ <AddShift> 400 400
5
+ <LearnRateCoef> 0 [ -8.311879 -8.600912 -9.615928 -10.43595 -11.21292 -11.88333 -12.36243 -12.63706 -12.8818 -12.83066 -12.89103 -12.95666 -13.19763 -13.40598 -13.49113 -13.5546 -13.55639 -13.51915 -13.68284 -13.53289 -13.42107 -13.65519 -13.50713 -13.75251 -13.76715 -13.87408 -13.73109 -13.70412 -13.56073 -13.53488 -13.54895 -13.56228 -13.59408 -13.62047 -13.64198 -13.66109 -13.62669 -13.58297 -13.57387 -13.4739 -13.53063 -13.48348 -13.61047 -13.64716 -13.71546 -13.79184 -13.90614 -14.03098 -14.18205 -14.35881 -14.48419 -14.60172 -14.70591 -14.83362 -14.92122 -15.00622 -15.05122 -15.03119 -14.99028 -14.92302 -14.86927 -14.82691 -14.7972 -14.76909 -14.71356 -14.61277 -14.51696 -14.42252 -14.36405 -14.30451 -14.23161 -14.19851 -14.16633 -14.15649 -14.10504 -13.99518 -13.79562 -13.3996 -12.7767 -11.71208 -8.311879 -8.600912 -9.615928 -10.43595 -11.21292 -11.88333 -12.36243 -12.63706 -12.8818 -12.83066 -12.89103 -12.95666 -13.19763 -13.40598 -13.49113 -13.5546 -13.55639 -13.51915 -13.68284 -13.53289 -13.42107 -13.65519 -13.50713 -13.75251 -13.76715 -13.87408 -13.73109 -13.70412 -13.56073 -13.53488 -13.54895 -13.56228 -13.59408 -13.62047 -13.64198 -13.66109 -13.62669 -13.58297 -13.57387 -13.4739 -13.53063 -13.48348 -13.61047 -13.64716 -13.71546 -13.79184 -13.90614 -14.03098 -14.18205 -14.35881 -14.48419 -14.60172 -14.70591 -14.83362 -14.92122 -15.00622 -15.05122 -15.03119 -14.99028 -14.92302 -14.86927 -14.82691 -14.7972 -14.76909 -14.71356 -14.61277 -14.51696 -14.42252 -14.36405 -14.30451 -14.23161 -14.19851 -14.16633 -14.15649 -14.10504 -13.99518 -13.79562 -13.3996 -12.7767 -11.71208 -8.311879 -8.600912 -9.615928 -10.43595 -11.21292 -11.88333 -12.36243 -12.63706 -12.8818 -12.83066 -12.89103 -12.95666 -13.19763 -13.40598 -13.49113 -13.5546 -13.55639 -13.51915 -13.68284 -13.53289 -13.42107 -13.65519 -13.50713 -13.75251 -13.76715 -13.87408 -13.73109 -13.70412 -13.56073 -13.53488 -13.54895 -13.56228 -13.59408 -13.62047 -13.64198 -13.66109 -13.62669 -13.58297 -13.57387 -13.4739 -13.53063 -13.48348 -13.61047 -13.64716 -13.71546 -13.79184 -13.90614 -14.03098 -14.18205 -14.35881 -14.48419 -14.60172 -14.70591 -14.83362 -14.92122 -15.00622 -15.05122 -15.03119 -14.99028 -14.92302 -14.86927 -14.82691 -14.7972 -14.76909 -14.71356 -14.61277 -14.51696 -14.42252 -14.36405 -14.30451 -14.23161 -14.19851 -14.16633 -14.15649 -14.10504 -13.99518 -13.79562 -13.3996 -12.7767 -11.71208 -8.311879 -8.600912 -9.615928 -10.43595 -11.21292 -11.88333 -12.36243 -12.63706 -12.8818 -12.83066 -12.89103 -12.95666 -13.19763 -13.40598 -13.49113 -13.5546 -13.55639 -13.51915 -13.68284 -13.53289 -13.42107 -13.65519 -13.50713 -13.75251 -13.76715 -13.87408 -13.73109 -13.70412 -13.56073 -13.53488 -13.54895 -13.56228 -13.59408 -13.62047 -13.64198 -13.66109 -13.62669 -13.58297 -13.57387 -13.4739 -13.53063 -13.48348 -13.61047 -13.64716 -13.71546 -13.79184 -13.90614 -14.03098 -14.18205 -14.35881 -14.48419 -14.60172 -14.70591 -14.83362 -14.92122 -15.00622 -15.05122 -15.03119 -14.99028 -14.92302 -14.86927 -14.82691 -14.7972 -14.76909 -14.71356 -14.61277 -14.51696 -14.42252 -14.36405 -14.30451 -14.23161 -14.19851 -14.16633 -14.15649 -14.10504 -13.99518 -13.79562 -13.3996 -12.7767 -11.71208 -8.311879 -8.600912 -9.615928 -10.43595 -11.21292 -11.88333 -12.36243 -12.63706 -12.8818 -12.83066 -12.89103 -12.95666 -13.19763 -13.40598 -13.49113 -13.5546 -13.55639 -13.51915 -13.68284 -13.53289 -13.42107 -13.65519 -13.50713 -13.75251 -13.76715 -13.87408 -13.73109 -13.70412 -13.56073 -13.53488 -13.54895 -13.56228 -13.59408 -13.62047 -13.64198 -13.66109 -13.62669 -13.58297 -13.57387 -13.4739 -13.53063 -13.48348 -13.61047 -13.64716 -13.71546 -13.79184 -13.90614 -14.03098 -14.18205 -14.35881 -14.48419 -14.60172 -14.70591 -14.83362 -14.92122 -15.00622 -15.05122 -15.03119 -14.99028 -14.92302 -14.86927 -14.82691 -14.7972 -14.76909 -14.71356 -14.61277 -14.51696 -14.42252 -14.36405 -14.30451 -14.23161 -14.19851 -14.16633 -14.15649 -14.10504 -13.99518 -13.79562 -13.3996 -12.7767 -11.71208 ]
6
+ <Rescale> 400 400
7
+ <LearnRateCoef> 0 [ 0.155775 0.154484 0.1527379 0.1518718 0.1506028 0.1489256 0.147067 0.1447061 0.1436307 0.1443568 0.1451849 0.1455157 0.1452821 0.1445717 0.1439195 0.1435867 0.1436018 0.1438781 0.1442086 0.1448844 0.1454756 0.145663 0.146268 0.1467386 0.1472724 0.147664 0.1480913 0.1483739 0.1488841 0.1493636 0.1497088 0.1500379 0.1502916 0.1505389 0.1506787 0.1507102 0.1505992 0.1505445 0.1505938 0.1508133 0.1509569 0.1512396 0.1514625 0.1516195 0.1516156 0.1515561 0.1514966 0.1513976 0.1512612 0.151076 0.1510596 0.1510431 0.151077 0.1511168 0.1511917 0.151023 0.1508045 0.1505885 0.1503493 0.1502373 0.1501726 0.1500762 0.1500065 0.1499782 0.150057 0.1502658 0.150469 0.1505335 0.1505505 0.1505328 0.1504275 0.1502438 0.1499674 0.1497118 0.1494661 0.1493102 0.1493681 0.1495501 0.1499738 0.1509654 0.155775 0.154484 0.1527379 0.1518718 0.1506028 0.1489256 0.147067 0.1447061 0.1436307 0.1443568 0.1451849 0.1455157 0.1452821 0.1445717 0.1439195 0.1435867 0.1436018 0.1438781 0.1442086 0.1448844 0.1454756 0.145663 0.146268 0.1467386 0.1472724 0.147664 0.1480913 0.1483739 0.1488841 0.1493636 0.1497088 0.1500379 0.1502916 0.1505389 0.1506787 0.1507102 0.1505992 0.1505445 0.1505938 0.1508133 0.1509569 0.1512396 0.1514625 0.1516195 0.1516156 0.1515561 0.1514966 0.1513976 0.1512612 0.151076 0.1510596 0.1510431 0.151077 0.1511168 0.1511917 0.151023 0.1508045 0.1505885 0.1503493 0.1502373 0.1501726 0.1500762 0.1500065 0.1499782 0.150057 0.1502658 0.150469 0.1505335 0.1505505 0.1505328 0.1504275 0.1502438 0.1499674 0.1497118 0.1494661 0.1493102 0.1493681 0.1495501 0.1499738 0.1509654 0.155775 0.154484 0.1527379 0.1518718 0.1506028 0.1489256 0.147067 0.1447061 0.1436307 0.1443568 0.1451849 0.1455157 0.1452821 0.1445717 0.1439195 0.1435867 0.1436018 0.1438781 0.1442086 0.1448844 0.1454756 0.145663 0.146268 0.1467386 0.1472724 0.147664 0.1480913 0.1483739 0.1488841 0.1493636 0.1497088 0.1500379 0.1502916 0.1505389 0.1506787 0.1507102 0.1505992 0.1505445 0.1505938 0.1508133 0.1509569 0.1512396 0.1514625 0.1516195 0.1516156 0.1515561 0.1514966 0.1513976 0.1512612 0.151076 0.1510596 0.1510431 0.151077 0.1511168 0.1511917 0.151023 0.1508045 0.1505885 0.1503493 0.1502373 0.1501726 0.1500762 0.1500065 0.1499782 0.150057 0.1502658 0.150469 0.1505335 0.1505505 0.1505328 0.1504275 0.1502438 0.1499674 0.1497118 0.1494661 0.1493102 0.1493681 0.1495501 0.1499738 0.1509654 0.155775 0.154484 0.1527379 0.1518718 0.1506028 0.1489256 0.147067 0.1447061 0.1436307 0.1443568 0.1451849 0.1455157 0.1452821 0.1445717 0.1439195 0.1435867 0.1436018 0.1438781 0.1442086 0.1448844 0.1454756 0.145663 0.146268 0.1467386 0.1472724 0.147664 0.1480913 0.1483739 0.1488841 0.1493636 0.1497088 0.1500379 0.1502916 0.1505389 0.1506787 0.1507102 0.1505992 0.1505445 0.1505938 0.1508133 0.1509569 0.1512396 0.1514625 0.1516195 0.1516156 0.1515561 0.1514966 0.1513976 0.1512612 0.151076 0.1510596 0.1510431 0.151077 0.1511168 0.1511917 0.151023 0.1508045 0.1505885 0.1503493 0.1502373 0.1501726 0.1500762 0.1500065 0.1499782 0.150057 0.1502658 0.150469 0.1505335 0.1505505 0.1505328 0.1504275 0.1502438 0.1499674 0.1497118 0.1494661 0.1493102 0.1493681 0.1495501 0.1499738 0.1509654 0.155775 0.154484 0.1527379 0.1518718 0.1506028 0.1489256 0.147067 0.1447061 0.1436307 0.1443568 0.1451849 0.1455157 0.1452821 0.1445717 0.1439195 0.1435867 0.1436018 0.1438781 0.1442086 0.1448844 0.1454756 0.145663 0.146268 0.1467386 0.1472724 0.147664 0.1480913 0.1483739 0.1488841 0.1493636 0.1497088 0.1500379 0.1502916 0.1505389 0.1506787 0.1507102 0.1505992 0.1505445 0.1505938 0.1508133 0.1509569 0.1512396 0.1514625 0.1516195 0.1516156 0.1515561 0.1514966 0.1513976 0.1512612 0.151076 0.1510596 0.1510431 0.151077 0.1511168 0.1511917 0.151023 0.1508045 0.1505885 0.1503493 0.1502373 0.1501726 0.1500762 0.1500065 0.1499782 0.150057 0.1502658 0.150469 0.1505335 0.1505505 0.1505328 0.1504275 0.1502438 0.1499674 0.1497118 0.1494661 0.1493102 0.1493681 0.1495501 0.1499738 0.1509654 ]
8
+ </Nnet>
bmodel/speech_fsmn_vad_zh-cn-16k-common/models/BM1684X/config.yaml ADDED
@@ -0,0 +1,56 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ frontend: WavFrontendOnline
2
+ frontend_conf:
3
+ fs: 16000
4
+ window: hamming
5
+ n_mels: 80
6
+ frame_length: 25
7
+ frame_shift: 10
8
+ dither: 0.0
9
+ lfr_m: 5
10
+ lfr_n: 1
11
+
12
+ model: FsmnVADStreaming
13
+ model_conf:
14
+ sample_rate: 16000
15
+ detect_mode: 1
16
+ snr_mode: 0
17
+ max_end_silence_time: 800
18
+ max_start_silence_time: 3000
19
+ do_start_point_detection: True
20
+ do_end_point_detection: True
21
+ window_size_ms: 200
22
+ sil_to_speech_time_thres: 150
23
+ speech_to_sil_time_thres: 150
24
+ speech_2_noise_ratio: 1.0
25
+ do_extend: 1
26
+ lookback_time_start_point: 200
27
+ lookahead_time_end_point: 100
28
+ max_single_segment_time: 60000
29
+ snr_thres: -100.0
30
+ noise_frame_num_used_for_snr: 100
31
+ decibel_thres: -100.0
32
+ speech_noise_thres: 0.6
33
+ fe_prior_thres: 0.0001
34
+ silence_pdf_num: 1
35
+ sil_pdf_ids: [0]
36
+ speech_noise_thresh_low: -0.1
37
+ speech_noise_thresh_high: 0.3
38
+ output_frame_probs: False
39
+ frame_in_ms: 10
40
+ frame_length_ms: 25
41
+
42
+ encoder: FSMN
43
+ encoder_conf:
44
+ input_dim: 400
45
+ input_affine_dim: 140
46
+ fsmn_layers: 4
47
+ linear_dim: 250
48
+ proj_dim: 128
49
+ lorder: 20
50
+ rorder: 0
51
+ lstride: 1
52
+ rstride: 0
53
+ output_affine_dim: 140
54
+ output_dim: 248
55
+
56
+
bmodel/speech_fsmn_vad_zh-cn-16k-common/models/BM1684X/fsmn_fp16.bmodel ADDED
@@ -0,0 +1,3 @@
 
 
 
 
1
+ version https://git-lfs.github.com/spec/v1
2
+ oid sha256:169d75372f205958aabae7a5aac8639a1ddfeb97dd01f22d7de282715c9f7a36
3
+ size 4119372
bmodel/speech_fsmn_vad_zh-cn-16k-common/models/BM1684X/fsmn_fp32.bmodel ADDED
@@ -0,0 +1,3 @@
 
 
 
 
1
+ version https://git-lfs.github.com/spec/v1
2
+ oid sha256:d7e2eb6e2ca79e7074ef3a307d6da16719536213babddb36d480621633d19a10
3
+ size 4978516
bmodel/speech_fsmn_vad_zh-cn-16k-common/scripts/download.sh ADDED
@@ -0,0 +1,35 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ #!/bin/bash
2
+ res=$(which unzip)
3
+ if [ $? != 0 ]; then
4
+ echo "Please install unzip on your system!"
5
+ echo "Please run the following command: sudo apt-get install unzip"
6
+ exit
7
+ fi
8
+ echo "unzip is installed in your system!"
9
+
10
+ pip3 install dfss -i https://pypi.tuna.tsinghua.edu.cn/simple --upgrade
11
+
12
+ scripts_dir=$(dirname $(readlink -f "$0"))
13
+ name=speech_fsmn_vad_zh-cn-16k-common
14
+ pushd $scripts_dir
15
+
16
+ # models
17
+ if [ ! -d "../models" ]; then
18
+ mkdir -p ../models
19
+ # python3 -m dfss --url=open@sophgo.com:sophon-demo/FunASR/${name}/onnx.zip
20
+ # unzip onnx.zip -d ../models
21
+ # rm onnx.zip
22
+ # echo "onnx download!"
23
+ python3 -m dfss --url=open@sophgo.com:sophon-demo/FunASR/${name}/BM1684X.zip
24
+ unzip BM1684X.zip -d ../models
25
+ rm BM1684X.zip
26
+ echo "BM1684X model download!"
27
+ # python3 -m dfss --url=open@sophgo.com:sophon-demo/FunASR/${name}/BM1688.zip
28
+ # unzip BM1688.zip -d ../models
29
+ # rm BM1688.zip
30
+ # echo "BM1688 model download!"
31
+ else
32
+ echo "models folder exist! Remove it if you need to update."
33
+ fi
34
+
35
+ popd
bmodel/speech_fsmn_vad_zh-cn-16k-common/scripts/gen_fp16bmodel_mlir.sh ADDED
@@ -0,0 +1,51 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ #!/bin/bash
2
+ model_dir=$(dirname $(readlink -f "$0"))
3
+
4
+ if [ ! $1 ]; then
5
+ target=bm1684x
6
+ target_dir=BM1684X
7
+ else
8
+ target=${1,,}
9
+ target_dir=${target^^}
10
+ fi
11
+
12
+ name=fsmn
13
+ outdir=../models/$target_dir
14
+
15
+ function gen_mlir()
16
+ {
17
+ model_transform.py \
18
+ --model_name ${name} \
19
+ --model_def ../models/onnx/${name}.onnx \
20
+ --input_shapes [[1,6000,400],[1,128,19,1],[1,128,19,1],[1,128,19,1],[1,128,19,1]] \
21
+ --test_input input_0.npz \
22
+ --test_result ${name}_top_results.npz \
23
+ --dynamic \
24
+ --mlir ${name}.mlir
25
+ }
26
+
27
+ function gen_fp16bmodel()
28
+ {
29
+ model_deploy.py \
30
+ --mlir ${name}.mlir \
31
+ --quantize F16 \
32
+ --chip $target \
33
+ --dynamic \
34
+ --disable_layer_group \
35
+ --test_input ${name}_in_f32.npz \
36
+ --test_reference ${name}_top_results.npz \
37
+ --tolerance 0.99,0.99 \
38
+ --model ${name}_fp16.bmodel
39
+
40
+ mv ${name}_fp16.bmodel $outdir/
41
+ }
42
+
43
+ pushd $model_dir
44
+ if [ ! -d $outdir ]; then
45
+ mkdir -p $outdir
46
+ fi
47
+ # batch_size=1
48
+ gen_mlir
49
+ gen_fp16bmodel
50
+
51
+ popd
bmodel/speech_fsmn_vad_zh-cn-16k-common/scripts/gen_fp32bmodel_mlir.sh ADDED
@@ -0,0 +1,51 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ #!/bin/bash
2
+ model_dir=$(dirname $(readlink -f "$0"))
3
+
4
+ if [ ! $1 ]; then
5
+ target=bm1684x
6
+ target_dir=BM1684X
7
+ else
8
+ target=${1,,}
9
+ target_dir=${target^^}
10
+ fi
11
+
12
+ name=fsmn
13
+ outdir=../models/$target_dir
14
+
15
+ function gen_mlir()
16
+ {
17
+ model_transform.py \
18
+ --model_name ${name} \
19
+ --model_def ../models/onnx/${name}.onnx \
20
+ --input_shapes [[1,6000,400],[1,128,19,1],[1,128,19,1],[1,128,19,1],[1,128,19,1]] \
21
+ --test_input input_0.npz \
22
+ --test_result ${name}_top_results.npz \
23
+ --dynamic \
24
+ --mlir ${name}.mlir
25
+ }
26
+
27
+ function gen_fp32bmodel()
28
+ {
29
+ model_deploy.py \
30
+ --mlir ${name}.mlir \
31
+ --quantize F32 \
32
+ --chip $target \
33
+ --dynamic \
34
+ --disable_layer_group \
35
+ --test_input ${name}_in_f32.npz \
36
+ --test_reference ${name}_top_results.npz \
37
+ --tolerance 0.99,0.99 \
38
+ --model ${name}_fp32.bmodel
39
+
40
+ mv ${name}_fp32.bmodel $outdir/
41
+ }
42
+
43
+ pushd $model_dir
44
+ if [ ! -d $outdir ]; then
45
+ mkdir -p $outdir
46
+ fi
47
+ # batch_size=1
48
+ gen_mlir
49
+ gen_fp32bmodel
50
+
51
+ popd
bmodel/speech_fsmn_vad_zh-cn-16k-common/scripts/gen_input.py ADDED
@@ -0,0 +1,8 @@
 
 
 
 
 
 
 
 
 
1
+ import numpy as np
2
+
3
+ input1 = np.random.randn(1,6000,400).astype(np.float32)
4
+ input2 = np.random.randn(1,128,19,1).astype(np.float32)
5
+ input3 = np.random.randn(1,128,19,1).astype(np.float32)
6
+ input4 = np.random.randn(1,128,19,1).astype(np.float32)
7
+ input5 = np.random.randn(1,128,19,1).astype(np.float32)
8
+ np.savez("input_0.npz", speech=input1, in_cache0=input2, in_cache1=input3, in_cache2=input4, in_cache3=input5)
bmodel/speech_seaco_paraformer_large_asr_nat-zh-cn-16k-common-vocab8404/README.md ADDED
@@ -0,0 +1,4 @@
 
 
 
 
 
1
+ 当前该模型暂无编译方式提供,仅提供编译好的BM1684X模型供下载
2
+ ```bash
3
+ ./scripts/download.sh
4
+ ```
bmodel/speech_seaco_paraformer_large_asr_nat-zh-cn-16k-common-vocab8404/models/BM1684X/am.mvn ADDED
@@ -0,0 +1,8 @@
 
 
 
 
 
 
 
 
 
1
+ <Nnet>
2
+ <Splice> 560 560
3
+ [ 0 ]
4
+ <AddShift> 560 560
5
+ <LearnRateCoef> 0 [ -8.311879 -8.600912 -9.615928 -10.43595 -11.21292 -11.88333 -12.36243 -12.63706 -12.8818 -12.83066 -12.89103 -12.95666 -13.19763 -13.40598 -13.49113 -13.5546 -13.55639 -13.51915 -13.68284 -13.53289 -13.42107 -13.65519 -13.50713 -13.75251 -13.76715 -13.87408 -13.73109 -13.70412 -13.56073 -13.53488 -13.54895 -13.56228 -13.59408 -13.62047 -13.64198 -13.66109 -13.62669 -13.58297 -13.57387 -13.4739 -13.53063 -13.48348 -13.61047 -13.64716 -13.71546 -13.79184 -13.90614 -14.03098 -14.18205 -14.35881 -14.48419 -14.60172 -14.70591 -14.83362 -14.92122 -15.00622 -15.05122 -15.03119 -14.99028 -14.92302 -14.86927 -14.82691 -14.7972 -14.76909 -14.71356 -14.61277 -14.51696 -14.42252 -14.36405 -14.30451 -14.23161 -14.19851 -14.16633 -14.15649 -14.10504 -13.99518 -13.79562 -13.3996 -12.7767 -11.71208 -8.311879 -8.600912 -9.615928 -10.43595 -11.21292 -11.88333 -12.36243 -12.63706 -12.8818 -12.83066 -12.89103 -12.95666 -13.19763 -13.40598 -13.49113 -13.5546 -13.55639 -13.51915 -13.68284 -13.53289 -13.42107 -13.65519 -13.50713 -13.75251 -13.76715 -13.87408 -13.73109 -13.70412 -13.56073 -13.53488 -13.54895 -13.56228 -13.59408 -13.62047 -13.64198 -13.66109 -13.62669 -13.58297 -13.57387 -13.4739 -13.53063 -13.48348 -13.61047 -13.64716 -13.71546 -13.79184 -13.90614 -14.03098 -14.18205 -14.35881 -14.48419 -14.60172 -14.70591 -14.83362 -14.92122 -15.00622 -15.05122 -15.03119 -14.99028 -14.92302 -14.86927 -14.82691 -14.7972 -14.76909 -14.71356 -14.61277 -14.51696 -14.42252 -14.36405 -14.30451 -14.23161 -14.19851 -14.16633 -14.15649 -14.10504 -13.99518 -13.79562 -13.3996 -12.7767 -11.71208 -8.311879 -8.600912 -9.615928 -10.43595 -11.21292 -11.88333 -12.36243 -12.63706 -12.8818 -12.83066 -12.89103 -12.95666 -13.19763 -13.40598 -13.49113 -13.5546 -13.55639 -13.51915 -13.68284 -13.53289 -13.42107 -13.65519 -13.50713 -13.75251 -13.76715 -13.87408 -13.73109 -13.70412 -13.56073 -13.53488 -13.54895 -13.56228 -13.59408 -13.62047 -13.64198 -13.66109 -13.62669 -13.58297 -13.57387 -13.4739 -13.53063 -13.48348 -13.61047 -13.64716 -13.71546 -13.79184 -13.90614 -14.03098 -14.18205 -14.35881 -14.48419 -14.60172 -14.70591 -14.83362 -14.92122 -15.00622 -15.05122 -15.03119 -14.99028 -14.92302 -14.86927 -14.82691 -14.7972 -14.76909 -14.71356 -14.61277 -14.51696 -14.42252 -14.36405 -14.30451 -14.23161 -14.19851 -14.16633 -14.15649 -14.10504 -13.99518 -13.79562 -13.3996 -12.7767 -11.71208 -8.311879 -8.600912 -9.615928 -10.43595 -11.21292 -11.88333 -12.36243 -12.63706 -12.8818 -12.83066 -12.89103 -12.95666 -13.19763 -13.40598 -13.49113 -13.5546 -13.55639 -13.51915 -13.68284 -13.53289 -13.42107 -13.65519 -13.50713 -13.75251 -13.76715 -13.87408 -13.73109 -13.70412 -13.56073 -13.53488 -13.54895 -13.56228 -13.59408 -13.62047 -13.64198 -13.66109 -13.62669 -13.58297 -13.57387 -13.4739 -13.53063 -13.48348 -13.61047 -13.64716 -13.71546 -13.79184 -13.90614 -14.03098 -14.18205 -14.35881 -14.48419 -14.60172 -14.70591 -14.83362 -14.92122 -15.00622 -15.05122 -15.03119 -14.99028 -14.92302 -14.86927 -14.82691 -14.7972 -14.76909 -14.71356 -14.61277 -14.51696 -14.42252 -14.36405 -14.30451 -14.23161 -14.19851 -14.16633 -14.15649 -14.10504 -13.99518 -13.79562 -13.3996 -12.7767 -11.71208 -8.311879 -8.600912 -9.615928 -10.43595 -11.21292 -11.88333 -12.36243 -12.63706 -12.8818 -12.83066 -12.89103 -12.95666 -13.19763 -13.40598 -13.49113 -13.5546 -13.55639 -13.51915 -13.68284 -13.53289 -13.42107 -13.65519 -13.50713 -13.75251 -13.76715 -13.87408 -13.73109 -13.70412 -13.56073 -13.53488 -13.54895 -13.56228 -13.59408 -13.62047 -13.64198 -13.66109 -13.62669 -13.58297 -13.57387 -13.4739 -13.53063 -13.48348 -13.61047 -13.64716 -13.71546 -13.79184 -13.90614 -14.03098 -14.18205 -14.35881 -14.48419 -14.60172 -14.70591 -14.83362 -14.92122 -15.00622 -15.05122 -15.03119 -14.99028 -14.92302 -14.86927 -14.82691 -14.7972 -14.76909 -14.71356 -14.61277 -14.51696 -14.42252 -14.36405 -14.30451 -14.23161 -14.19851 -14.16633 -14.15649 -14.10504 -13.99518 -13.79562 -13.3996 -12.7767 -11.71208 -8.311879 -8.600912 -9.615928 -10.43595 -11.21292 -11.88333 -12.36243 -12.63706 -12.8818 -12.83066 -12.89103 -12.95666 -13.19763 -13.40598 -13.49113 -13.5546 -13.55639 -13.51915 -13.68284 -13.53289 -13.42107 -13.65519 -13.50713 -13.75251 -13.76715 -13.87408 -13.73109 -13.70412 -13.56073 -13.53488 -13.54895 -13.56228 -13.59408 -13.62047 -13.64198 -13.66109 -13.62669 -13.58297 -13.57387 -13.4739 -13.53063 -13.48348 -13.61047 -13.64716 -13.71546 -13.79184 -13.90614 -14.03098 -14.18205 -14.35881 -14.48419 -14.60172 -14.70591 -14.83362 -14.92122 -15.00622 -15.05122 -15.03119 -14.99028 -14.92302 -14.86927 -14.82691 -14.7972 -14.76909 -14.71356 -14.61277 -14.51696 -14.42252 -14.36405 -14.30451 -14.23161 -14.19851 -14.16633 -14.15649 -14.10504 -13.99518 -13.79562 -13.3996 -12.7767 -11.71208 -8.311879 -8.600912 -9.615928 -10.43595 -11.21292 -11.88333 -12.36243 -12.63706 -12.8818 -12.83066 -12.89103 -12.95666 -13.19763 -13.40598 -13.49113 -13.5546 -13.55639 -13.51915 -13.68284 -13.53289 -13.42107 -13.65519 -13.50713 -13.75251 -13.76715 -13.87408 -13.73109 -13.70412 -13.56073 -13.53488 -13.54895 -13.56228 -13.59408 -13.62047 -13.64198 -13.66109 -13.62669 -13.58297 -13.57387 -13.4739 -13.53063 -13.48348 -13.61047 -13.64716 -13.71546 -13.79184 -13.90614 -14.03098 -14.18205 -14.35881 -14.48419 -14.60172 -14.70591 -14.83362 -14.92122 -15.00622 -15.05122 -15.03119 -14.99028 -14.92302 -14.86927 -14.82691 -14.7972 -14.76909 -14.71356 -14.61277 -14.51696 -14.42252 -14.36405 -14.30451 -14.23161 -14.19851 -14.16633 -14.15649 -14.10504 -13.99518 -13.79562 -13.3996 -12.7767 -11.71208 ]
6
+ <Rescale> 560 560
7
+ <LearnRateCoef> 0 [ 0.155775 0.154484 0.1527379 0.1518718 0.1506028 0.1489256 0.147067 0.1447061 0.1436307 0.1443568 0.1451849 0.1455157 0.1452821 0.1445717 0.1439195 0.1435867 0.1436018 0.1438781 0.1442086 0.1448844 0.1454756 0.145663 0.146268 0.1467386 0.1472724 0.147664 0.1480913 0.1483739 0.1488841 0.1493636 0.1497088 0.1500379 0.1502916 0.1505389 0.1506787 0.1507102 0.1505992 0.1505445 0.1505938 0.1508133 0.1509569 0.1512396 0.1514625 0.1516195 0.1516156 0.1515561 0.1514966 0.1513976 0.1512612 0.151076 0.1510596 0.1510431 0.151077 0.1511168 0.1511917 0.151023 0.1508045 0.1505885 0.1503493 0.1502373 0.1501726 0.1500762 0.1500065 0.1499782 0.150057 0.1502658 0.150469 0.1505335 0.1505505 0.1505328 0.1504275 0.1502438 0.1499674 0.1497118 0.1494661 0.1493102 0.1493681 0.1495501 0.1499738 0.1509654 0.155775 0.154484 0.1527379 0.1518718 0.1506028 0.1489256 0.147067 0.1447061 0.1436307 0.1443568 0.1451849 0.1455157 0.1452821 0.1445717 0.1439195 0.1435867 0.1436018 0.1438781 0.1442086 0.1448844 0.1454756 0.145663 0.146268 0.1467386 0.1472724 0.147664 0.1480913 0.1483739 0.1488841 0.1493636 0.1497088 0.1500379 0.1502916 0.1505389 0.1506787 0.1507102 0.1505992 0.1505445 0.1505938 0.1508133 0.1509569 0.1512396 0.1514625 0.1516195 0.1516156 0.1515561 0.1514966 0.1513976 0.1512612 0.151076 0.1510596 0.1510431 0.151077 0.1511168 0.1511917 0.151023 0.1508045 0.1505885 0.1503493 0.1502373 0.1501726 0.1500762 0.1500065 0.1499782 0.150057 0.1502658 0.150469 0.1505335 0.1505505 0.1505328 0.1504275 0.1502438 0.1499674 0.1497118 0.1494661 0.1493102 0.1493681 0.1495501 0.1499738 0.1509654 0.155775 0.154484 0.1527379 0.1518718 0.1506028 0.1489256 0.147067 0.1447061 0.1436307 0.1443568 0.1451849 0.1455157 0.1452821 0.1445717 0.1439195 0.1435867 0.1436018 0.1438781 0.1442086 0.1448844 0.1454756 0.145663 0.146268 0.1467386 0.1472724 0.147664 0.1480913 0.1483739 0.1488841 0.1493636 0.1497088 0.1500379 0.1502916 0.1505389 0.1506787 0.1507102 0.1505992 0.1505445 0.1505938 0.1508133 0.1509569 0.1512396 0.1514625 0.1516195 0.1516156 0.1515561 0.1514966 0.1513976 0.1512612 0.151076 0.1510596 0.1510431 0.151077 0.1511168 0.1511917 0.151023 0.1508045 0.1505885 0.1503493 0.1502373 0.1501726 0.1500762 0.1500065 0.1499782 0.150057 0.1502658 0.150469 0.1505335 0.1505505 0.1505328 0.1504275 0.1502438 0.1499674 0.1497118 0.1494661 0.1493102 0.1493681 0.1495501 0.1499738 0.1509654 0.155775 0.154484 0.1527379 0.1518718 0.1506028 0.1489256 0.147067 0.1447061 0.1436307 0.1443568 0.1451849 0.1455157 0.1452821 0.1445717 0.1439195 0.1435867 0.1436018 0.1438781 0.1442086 0.1448844 0.1454756 0.145663 0.146268 0.1467386 0.1472724 0.147664 0.1480913 0.1483739 0.1488841 0.1493636 0.1497088 0.1500379 0.1502916 0.1505389 0.1506787 0.1507102 0.1505992 0.1505445 0.1505938 0.1508133 0.1509569 0.1512396 0.1514625 0.1516195 0.1516156 0.1515561 0.1514966 0.1513976 0.1512612 0.151076 0.1510596 0.1510431 0.151077 0.1511168 0.1511917 0.151023 0.1508045 0.1505885 0.1503493 0.1502373 0.1501726 0.1500762 0.1500065 0.1499782 0.150057 0.1502658 0.150469 0.1505335 0.1505505 0.1505328 0.1504275 0.1502438 0.1499674 0.1497118 0.1494661 0.1493102 0.1493681 0.1495501 0.1499738 0.1509654 0.155775 0.154484 0.1527379 0.1518718 0.1506028 0.1489256 0.147067 0.1447061 0.1436307 0.1443568 0.1451849 0.1455157 0.1452821 0.1445717 0.1439195 0.1435867 0.1436018 0.1438781 0.1442086 0.1448844 0.1454756 0.145663 0.146268 0.1467386 0.1472724 0.147664 0.1480913 0.1483739 0.1488841 0.1493636 0.1497088 0.1500379 0.1502916 0.1505389 0.1506787 0.1507102 0.1505992 0.1505445 0.1505938 0.1508133 0.1509569 0.1512396 0.1514625 0.1516195 0.1516156 0.1515561 0.1514966 0.1513976 0.1512612 0.151076 0.1510596 0.1510431 0.151077 0.1511168 0.1511917 0.151023 0.1508045 0.1505885 0.1503493 0.1502373 0.1501726 0.1500762 0.1500065 0.1499782 0.150057 0.1502658 0.150469 0.1505335 0.1505505 0.1505328 0.1504275 0.1502438 0.1499674 0.1497118 0.1494661 0.1493102 0.1493681 0.1495501 0.1499738 0.1509654 0.155775 0.154484 0.1527379 0.1518718 0.1506028 0.1489256 0.147067 0.1447061 0.1436307 0.1443568 0.1451849 0.1455157 0.1452821 0.1445717 0.1439195 0.1435867 0.1436018 0.1438781 0.1442086 0.1448844 0.1454756 0.145663 0.146268 0.1467386 0.1472724 0.147664 0.1480913 0.1483739 0.1488841 0.1493636 0.1497088 0.1500379 0.1502916 0.1505389 0.1506787 0.1507102 0.1505992 0.1505445 0.1505938 0.1508133 0.1509569 0.1512396 0.1514625 0.1516195 0.1516156 0.1515561 0.1514966 0.1513976 0.1512612 0.151076 0.1510596 0.1510431 0.151077 0.1511168 0.1511917 0.151023 0.1508045 0.1505885 0.1503493 0.1502373 0.1501726 0.1500762 0.1500065 0.1499782 0.150057 0.1502658 0.150469 0.1505335 0.1505505 0.1505328 0.1504275 0.1502438 0.1499674 0.1497118 0.1494661 0.1493102 0.1493681 0.1495501 0.1499738 0.1509654 0.155775 0.154484 0.1527379 0.1518718 0.1506028 0.1489256 0.147067 0.1447061 0.1436307 0.1443568 0.1451849 0.1455157 0.1452821 0.1445717 0.1439195 0.1435867 0.1436018 0.1438781 0.1442086 0.1448844 0.1454756 0.145663 0.146268 0.1467386 0.1472724 0.147664 0.1480913 0.1483739 0.1488841 0.1493636 0.1497088 0.1500379 0.1502916 0.1505389 0.1506787 0.1507102 0.1505992 0.1505445 0.1505938 0.1508133 0.1509569 0.1512396 0.1514625 0.1516195 0.1516156 0.1515561 0.1514966 0.1513976 0.1512612 0.151076 0.1510596 0.1510431 0.151077 0.1511168 0.1511917 0.151023 0.1508045 0.1505885 0.1503493 0.1502373 0.1501726 0.1500762 0.1500065 0.1499782 0.150057 0.1502658 0.150469 0.1505335 0.1505505 0.1505328 0.1504275 0.1502438 0.1499674 0.1497118 0.1494661 0.1493102 0.1493681 0.1495501 0.1499738 0.1509654 ]
8
+ </Nnet>
bmodel/speech_seaco_paraformer_large_asr_nat-zh-cn-16k-common-vocab8404/models/BM1684X/config.yaml ADDED
@@ -0,0 +1,160 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # This is an example that demonstrates how to configure a model file.
2
+ # You can modify the configuration according to your own requirements.
3
+
4
+ # to print the register_table:
5
+ # from funasr.utils.register import registry_tables
6
+ # registry_tables.print()
7
+
8
+ # network architecture
9
+ model: SeacoParaformer
10
+ model_conf:
11
+ ctc_weight: 0.0
12
+ lsm_weight: 0.1
13
+ length_normalized_loss: true
14
+ predictor_weight: 1.0
15
+ predictor_bias: 1
16
+ sampling_ratio: 0.75
17
+ inner_dim: 512
18
+ bias_encoder_type: lstm
19
+ bias_encoder_bid: false
20
+ seaco_lsm_weight: 0.1
21
+ seaco_length_normal: true
22
+ train_decoder: true
23
+ NO_BIAS: 8377
24
+
25
+ # encoder
26
+ encoder: SANMEncoder
27
+ encoder_conf:
28
+ output_size: 512
29
+ attention_heads: 4
30
+ linear_units: 2048
31
+ num_blocks: 50
32
+ dropout_rate: 0.1
33
+ positional_dropout_rate: 0.1
34
+ attention_dropout_rate: 0.1
35
+ input_layer: pe
36
+ pos_enc_class: SinusoidalPositionEncoder
37
+ normalize_before: true
38
+ kernel_size: 11
39
+ sanm_shfit: 0
40
+ selfattention_layer_type: sanm
41
+
42
+ # decoder
43
+ decoder: ParaformerSANMDecoder
44
+ decoder_conf:
45
+ attention_heads: 4
46
+ linear_units: 2048
47
+ num_blocks: 16
48
+ dropout_rate: 0.1
49
+ positional_dropout_rate: 0.1
50
+ self_attention_dropout_rate: 0.1
51
+ src_attention_dropout_rate: 0.1
52
+ att_layer_num: 16
53
+ kernel_size: 11
54
+ sanm_shfit: 0
55
+
56
+ # seaco decoder
57
+ seaco_decoder: ParaformerSANMDecoder
58
+ seaco_decoder_conf:
59
+ attention_heads: 4
60
+ linear_units: 1024
61
+ num_blocks: 4
62
+ dropout_rate: 0.1
63
+ positional_dropout_rate: 0.1
64
+ self_attention_dropout_rate: 0.1
65
+ src_attention_dropout_rate: 0.1
66
+ kernel_size: 21
67
+ sanm_shfit: 0
68
+ use_output_layer: false
69
+ wo_input_layer: true
70
+
71
+ predictor: CifPredictorV3
72
+ predictor_conf:
73
+ idim: 512
74
+ threshold: 1.0
75
+ l_order: 1
76
+ r_order: 1
77
+ tail_threshold: 0.45
78
+ smooth_factor2: 0.25
79
+ noise_threshold2: 0.01
80
+ upsample_times: 3
81
+ use_cif1_cnn: false
82
+ upsample_type: cnn_blstm
83
+
84
+ # frontend related
85
+ frontend: WavFrontend
86
+ frontend_conf:
87
+ fs: 16000
88
+ window: hamming
89
+ n_mels: 80
90
+ frame_length: 25
91
+ frame_shift: 10
92
+ lfr_m: 7
93
+ lfr_n: 6
94
+ dither: 0.0
95
+
96
+ specaug: SpecAugLFR
97
+ specaug_conf:
98
+ apply_time_warp: false
99
+ time_warp_window: 5
100
+ time_warp_mode: bicubic
101
+ apply_freq_mask: true
102
+ freq_mask_width_range:
103
+ - 0
104
+ - 30
105
+ lfr_rate: 6
106
+ num_freq_mask: 1
107
+ apply_time_mask: true
108
+ time_mask_width_range:
109
+ - 0
110
+ - 12
111
+ num_time_mask: 1
112
+
113
+ train_conf:
114
+ accum_grad: 1
115
+ grad_clip: 5
116
+ max_epoch: 150
117
+ val_scheduler_criterion:
118
+ - valid
119
+ - acc
120
+ best_model_criterion:
121
+ - - valid
122
+ - acc
123
+ - max
124
+ keep_nbest_models: 10
125
+ log_interval: 50
126
+ unused_parameters: true
127
+
128
+ optim: adam
129
+ optim_conf:
130
+ lr: 0.0005
131
+ scheduler: warmuplr
132
+ scheduler_conf:
133
+ warmup_steps: 30000
134
+
135
+ dataset: AudioDatasetHotword
136
+ dataset_conf:
137
+ seaco_id: 8377
138
+ index_ds: IndexDSJsonl
139
+ batch_sampler: DynamicBatchLocalShuffleSampler
140
+ batch_type: example # example or length
141
+ batch_size: 1 # if batch_type is example, batch_size is the numbers of samples; if length, batch_size is source_token_len+target_token_len;
142
+ max_token_length: 2048 # filter samples if source_token_len+target_token_len > max_token_length,
143
+ buffer_size: 500
144
+ shuffle: True
145
+ num_workers: 0
146
+
147
+ tokenizer: CharTokenizer
148
+ tokenizer_conf:
149
+ unk_symbol: <unk>
150
+ split_with_space: true
151
+
152
+
153
+ ctc_conf:
154
+ dropout_rate: 0.0
155
+ ctc_type: builtin
156
+ reduce: true
157
+ ignore_nan_grad: true
158
+
159
+ normalize: null
160
+
bmodel/speech_seaco_paraformer_large_asr_nat-zh-cn-16k-common-vocab8404/models/BM1684X/decoder_fp32_10b.bmodel ADDED
@@ -0,0 +1,3 @@
 
 
 
 
1
+ version https://git-lfs.github.com/spec/v1
2
+ oid sha256:8624c9a0eb55520c8c6e1137c97e74f73095fdab047329d8fe6cce44f18cadf2
3
+ size 231575760
bmodel/speech_seaco_paraformer_large_asr_nat-zh-cn-16k-common-vocab8404/models/BM1684X/encoder_fp16_10b.bmodel ADDED
@@ -0,0 +1,3 @@
 
 
 
 
1
+ version https://git-lfs.github.com/spec/v1
2
+ oid sha256:c9fdb24231338d5d887d28c640923402aa349b2e9b9fc7d130d99534089e6e40
3
+ size 329254752
bmodel/speech_seaco_paraformer_large_asr_nat-zh-cn-16k-common-vocab8404/models/BM1684X/predictor_fp16_10b.bmodel ADDED
@@ -0,0 +1,3 @@
 
 
 
 
1
+ version https://git-lfs.github.com/spec/v1
2
+ oid sha256:a56c768dbcace5f51e63bca6ba35dc2bd6a70239d62889bd31461be3223affe8
3
+ size 21588440
bmodel/speech_seaco_paraformer_large_asr_nat-zh-cn-16k-common-vocab8404/models/BM1684X/predictor_fp32_10b.bmodel ADDED
@@ -0,0 +1,3 @@
 
 
 
 
1
+ version https://git-lfs.github.com/spec/v1
2
+ oid sha256:f9abb19a933a78c4822ce52a8f8f5faceb17c55b58bfb3410d2d767c3d105805
3
+ size 23160312
bmodel/speech_seaco_paraformer_large_asr_nat-zh-cn-16k-common-vocab8404/models/BM1684X/seg_dict ADDED
The diff for this file is too large to render. See raw diff
 
bmodel/speech_seaco_paraformer_large_asr_nat-zh-cn-16k-common-vocab8404/models/BM1684X/tokens.json ADDED
The diff for this file is too large to render. See raw diff
 
bmodel/speech_seaco_paraformer_large_asr_nat-zh-cn-16k-common-vocab8404/scripts/download.sh ADDED
@@ -0,0 +1,27 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ #!/bin/bash
2
+ res=$(which unzip)
3
+ if [ $? != 0 ]; then
4
+ echo "Please install unzip on your system!"
5
+ echo "Please run the following command: sudo apt-get install unzip"
6
+ exit
7
+ fi
8
+ echo "unzip is installed in your system!"
9
+
10
+ pip3 install dfss -i https://pypi.tuna.tsinghua.edu.cn/simple --upgrade
11
+
12
+ scripts_dir=$(dirname $(readlink -f "$0"))
13
+ name=speech_seaco_paraformer_large_asr_nat-zh-cn-16k-common-vocab8404
14
+ pushd $scripts_dir
15
+
16
+ # models
17
+ if [ ! -d "../models" ]; then
18
+ mkdir -p ../models
19
+ python3 -m dfss --url=open@sophgo.com:sophon-demo/FunASR/${name}/BM1684X.zip
20
+ unzip BM1684X.zip -d ../models
21
+ rm BM1684X.zip
22
+ echo "BM1684X model download!"
23
+ else
24
+ echo "models folder exist! Remove it if you need to update."
25
+ fi
26
+
27
+ popd
bmodel/tpu_perf-1.2.35-py3-none-manylinux2014_aarch64.whl ADDED
@@ -0,0 +1,3 @@
 
 
 
 
1
+ version https://git-lfs.github.com/spec/v1
2
+ oid sha256:0608ae719c1701a022d6881c9d86c2cf290ce0de0ffeeff40fb089088a9e50c9
3
+ size 291470
funasr/__init__.py ADDED
@@ -0,0 +1,42 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ """Initialize funasr package."""
2
+
3
+ import os
4
+
5
+ dirname = os.path.dirname(__file__)
6
+ version_file = os.path.join(dirname, "version.txt")
7
+ with open(version_file, "r") as f:
8
+ __version__ = f.read().strip()
9
+
10
+
11
+ import importlib
12
+ import pkgutil
13
+
14
+
15
+ def import_submodules(package, recursive=True):
16
+ if isinstance(package, str):
17
+ try:
18
+ package = importlib.import_module(package)
19
+ except Exception as e:
20
+ # 如果想要看到导入错误的具体信息,可以取消注释下面的行
21
+ # print(f"Failed to import {package}: {e}")
22
+ pass
23
+ results = {}
24
+ if not isinstance(package, str):
25
+ for loader, name, is_pkg in pkgutil.walk_packages(package.__path__, package.__name__ + "."):
26
+ try:
27
+ results[name] = importlib.import_module(name)
28
+ except Exception as e:
29
+ # 如果想要看到导入错误的具体信息,可以取消注释下面的行
30
+ # print(f"Failed to import {name}: {e}")
31
+ pass
32
+ if recursive and is_pkg:
33
+ results.update(import_submodules(name))
34
+ return results
35
+
36
+
37
+ import_submodules(__name__)
38
+
39
+ from funasr.auto.auto_model import AutoModel
40
+ from funasr.auto.auto_frontend import AutoFrontend
41
+
42
+ os.environ["HYDRA_FULL_ERROR"] = "1"
funasr/auto/__init__.py ADDED
File without changes
funasr/auto/auto_frontend.py ADDED
@@ -0,0 +1,109 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ #!/usr/bin/env python3
2
+ # -*- encoding: utf-8 -*-
3
+ # Copyright FunASR (https://github.com/alibaba-damo-academy/FunASR). All Rights Reserved.
4
+ # MIT License (https://opensource.org/licenses/MIT)
5
+
6
+ import json
7
+ import time
8
+ import torch
9
+ import hydra
10
+ import random
11
+ import string
12
+ import logging
13
+ import os.path
14
+ from tqdm import tqdm
15
+ from omegaconf import DictConfig, OmegaConf, ListConfig
16
+
17
+ from funasr.register import tables
18
+ from funasr.utils.load_utils import load_bytes
19
+ from funasr.download.file import download_from_url
20
+ from funasr.auto.auto_model import prepare_data_iterator
21
+ from funasr.utils.timestamp_tools import timestamp_sentence
22
+ from funasr.download.download_model_from_hub import download_model
23
+ from funasr.utils.vad_utils import slice_padding_audio_samples
24
+ from funasr.train_utils.set_all_random_seed import set_all_random_seed
25
+ from funasr.train_utils.load_pretrained_model import load_pretrained_model
26
+ from funasr.utils.load_utils import load_audio_text_image_video, extract_fbank
27
+ from funasr.models.campplus.utils import sv_chunk, postprocess, distribute_spk
28
+
29
+
30
+ class AutoFrontend:
31
+ def __init__(self, **kwargs):
32
+ assert "model" in kwargs
33
+ if "model_conf" not in kwargs:
34
+ logging.info("download models from model hub: {}".format(kwargs.get("hub", "ms")))
35
+ kwargs = download_model(**kwargs)
36
+
37
+ # build frontend
38
+ frontend = kwargs.get("frontend", None)
39
+ if frontend is not None:
40
+ frontend_class = tables.frontend_classes.get(frontend)
41
+ frontend = frontend_class(**kwargs["frontend_conf"])
42
+
43
+ self.frontend = frontend
44
+ if "frontend" in kwargs:
45
+ del kwargs["frontend"]
46
+ self.kwargs = kwargs
47
+
48
+ def __call__(self, input, input_len=None, kwargs=None, **cfg):
49
+
50
+ kwargs = self.kwargs if kwargs is None else kwargs
51
+ kwargs.update(cfg)
52
+
53
+ key_list, data_list = prepare_data_iterator(input, input_len=input_len)
54
+ batch_size = kwargs.get("batch_size", 1)
55
+ device = kwargs.get("device", "cuda")
56
+ if device == "cpu":
57
+ batch_size = 1
58
+
59
+ meta_data = {}
60
+
61
+ result_list = []
62
+ num_samples = len(data_list)
63
+ # pbar = tqdm(colour="blue", total=num_samples + 1, dynamic_ncols=True)
64
+
65
+ time0 = time.perf_counter()
66
+ for beg_idx in range(0, num_samples, batch_size):
67
+ end_idx = min(num_samples, beg_idx + batch_size)
68
+ data_batch = data_list[beg_idx:end_idx]
69
+ key_batch = key_list[beg_idx:end_idx]
70
+
71
+ # extract fbank feats
72
+ time1 = time.perf_counter()
73
+ audio_sample_list = load_audio_text_image_video(
74
+ data_batch, fs=self.frontend.fs, audio_fs=kwargs.get("fs", 16000)
75
+ )
76
+ time2 = time.perf_counter()
77
+ meta_data["load_data"] = f"{time2 - time1:0.3f}"
78
+ speech, speech_lengths = extract_fbank(
79
+ audio_sample_list,
80
+ data_type=kwargs.get("data_type", "sound"),
81
+ frontend=self.frontend,
82
+ **kwargs,
83
+ )
84
+ time3 = time.perf_counter()
85
+ meta_data["extract_feat"] = f"{time3 - time2:0.3f}"
86
+ meta_data["batch_data_time"] = (
87
+ speech_lengths.sum().item() * self.frontend.frame_shift * self.frontend.lfr_n / 1000
88
+ )
89
+
90
+ if kwargs.get("return_pt", True):
91
+ speech, speech_lengths = speech.to(device=device), speech_lengths.to(device=device)
92
+ else:
93
+ speech, speech_lengths = speech.numpy(), speech_lengths.numpy()
94
+ batch = {
95
+ "input": speech,
96
+ "input_len": speech_lengths,
97
+ "key": key_batch,
98
+ "data_type": "fbank",
99
+ }
100
+ result_list.append(batch)
101
+
102
+ # pbar.update(1)
103
+ # description = f"{meta_data}, "
104
+ # pbar.set_description(description)
105
+
106
+ time_end = time.perf_counter()
107
+ # pbar.set_description(f"time escaped total: {time_end - time0:0.3f}")
108
+
109
+ return result_list
funasr/auto/auto_model.py ADDED
@@ -0,0 +1,684 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ #!/usr/bin/env python3
2
+ # -*- encoding: utf-8 -*-
3
+ # Copyright FunASR (https://github.com/alibaba-damo-academy/FunASR). All Rights Reserved.
4
+ # MIT License (https://opensource.org/licenses/MIT)
5
+
6
+ import json
7
+ import time
8
+ import copy
9
+ import torch
10
+ import random
11
+ import string
12
+ import logging
13
+ import os.path
14
+ import numpy as np
15
+ from tqdm import tqdm
16
+
17
+ from omegaconf import DictConfig, ListConfig
18
+ from funasr.utils.misc import deep_update
19
+ from funasr.register import tables
20
+ from funasr.utils.load_utils import load_bytes
21
+ from funasr.download.file import download_from_url
22
+ from funasr.utils.timestamp_tools import timestamp_sentence
23
+ from funasr.utils.timestamp_tools import timestamp_sentence_en
24
+ from funasr.download.download_model_from_hub import download_model
25
+ from funasr.utils.vad_utils import slice_padding_audio_samples
26
+ from funasr.utils.vad_utils import merge_vad
27
+ from funasr.utils.load_utils import load_audio_text_image_video
28
+ from funasr.train_utils.set_all_random_seed import set_all_random_seed
29
+ from funasr.train_utils.load_pretrained_model import load_pretrained_model
30
+ from funasr.utils import export_utils
31
+ from funasr.utils import misc
32
+
33
+ try:
34
+ from funasr.models.campplus.utils import sv_chunk, postprocess, distribute_spk
35
+ from funasr.models.campplus.cluster_backend import ClusterBackend
36
+ except:
37
+ pass
38
+
39
+
40
+ def prepare_data_iterator(data_in, input_len=None, data_type=None, key=None):
41
+ """ """
42
+ data_list = []
43
+ key_list = []
44
+ filelist = [".scp", ".txt", ".json", ".jsonl", ".text"]
45
+
46
+ chars = string.ascii_letters + string.digits
47
+ if isinstance(data_in, str):
48
+ if data_in.startswith("http://") or data_in.startswith("https://"): # url
49
+ data_in = download_from_url(data_in)
50
+
51
+ if isinstance(data_in, str) and os.path.exists(
52
+ data_in
53
+ ): # wav_path; filelist: wav.scp, file.jsonl;text.txt;
54
+ _, file_extension = os.path.splitext(data_in)
55
+ file_extension = file_extension.lower()
56
+ if file_extension in filelist: # filelist: wav.scp, file.jsonl;text.txt;
57
+ with open(data_in, encoding="utf-8") as fin:
58
+ for line in fin:
59
+ key = "rand_key_" + "".join(random.choice(chars) for _ in range(13))
60
+ if data_in.endswith(".jsonl"): # file.jsonl: json.dumps({"source": data})
61
+ lines = json.loads(line.strip())
62
+ data = lines["source"]
63
+ key = data["key"] if "key" in data else key
64
+ else: # filelist, wav.scp, text.txt: id \t data or data
65
+ lines = line.strip().split(maxsplit=1)
66
+ data = lines[1] if len(lines) > 1 else lines[0]
67
+ key = lines[0] if len(lines) > 1 else key
68
+
69
+ data_list.append(data)
70
+ key_list.append(key)
71
+ else:
72
+ if key is None:
73
+ # key = "rand_key_" + "".join(random.choice(chars) for _ in range(13))
74
+ key = misc.extract_filename_without_extension(data_in)
75
+ data_list = [data_in]
76
+ key_list = [key]
77
+ elif isinstance(data_in, (list, tuple)):
78
+ if data_type is not None and isinstance(data_type, (list, tuple)): # mutiple inputs
79
+ data_list_tmp = []
80
+ for data_in_i, data_type_i in zip(data_in, data_type):
81
+ key_list, data_list_i = prepare_data_iterator(
82
+ data_in=data_in_i, data_type=data_type_i
83
+ )
84
+ data_list_tmp.append(data_list_i)
85
+ data_list = []
86
+ for item in zip(*data_list_tmp):
87
+ data_list.append(item)
88
+ else:
89
+ # [audio sample point, fbank, text]
90
+ data_list = data_in
91
+ key_list = []
92
+ for data_i in data_in:
93
+ if isinstance(data_i, str) and os.path.exists(data_i):
94
+ key = misc.extract_filename_without_extension(data_i)
95
+ else:
96
+ if key is None:
97
+ key = "rand_key_" + "".join(random.choice(chars) for _ in range(13))
98
+ key_list.append(key)
99
+
100
+ else: # raw text; audio sample point, fbank; bytes
101
+ if isinstance(data_in, bytes): # audio bytes
102
+ data_in = load_bytes(data_in)
103
+ if key is None:
104
+ key = "rand_key_" + "".join(random.choice(chars) for _ in range(13))
105
+ data_list = [data_in]
106
+ key_list = [key]
107
+
108
+ return key_list, data_list
109
+
110
+
111
+ class AutoModel:
112
+
113
+ def __init__(self, **kwargs):
114
+
115
+ """
116
+ try:
117
+ from funasr.utils.version_checker import check_for_update
118
+
119
+ check_for_update(disable=kwargs.get("disable_update", False))
120
+ except:
121
+ pass
122
+ """
123
+
124
+ log_level = getattr(logging, kwargs.get("log_level", "INFO").upper())
125
+ logging.basicConfig(level=log_level)
126
+
127
+ model, kwargs = self.build_model(**kwargs)
128
+
129
+ # if vad_model is not None, build vad model else None
130
+ vad_model = kwargs.get("vad_model", None)
131
+ vad_kwargs = {} if kwargs.get("vad_kwargs", {}) is None else kwargs.get("vad_kwargs", {})
132
+ if vad_model is not None:
133
+ logging.info("Building VAD model.")
134
+ vad_kwargs["model"] = vad_model
135
+ vad_kwargs["model_revision"] = kwargs.get("vad_model_revision", "master")
136
+ vad_kwargs["device"] = kwargs["device"]
137
+ vad_kwargs["dev_id"] = kwargs["dev_id"]
138
+ vad_model, vad_kwargs = self.build_model(**vad_kwargs)
139
+
140
+ # if punc_model is not None, build punc model else None
141
+ punc_model = kwargs.get("punc_model", None)
142
+ punc_kwargs = {} if kwargs.get("punc_kwargs", {}) is None else kwargs.get("punc_kwargs", {})
143
+ if punc_model is not None:
144
+ logging.info("Building punc model.")
145
+ punc_kwargs["model"] = punc_model
146
+ punc_kwargs["model_revision"] = kwargs.get("punc_model_revision", "master")
147
+ punc_kwargs["device"] = kwargs["device"]
148
+ punc_kwargs["dev_id"] = kwargs["dev_id"]
149
+ punc_model, punc_kwargs = self.build_model(**punc_kwargs)
150
+
151
+ # if spk_model is not None, build spk model else None
152
+ spk_model = kwargs.get("spk_model", None)
153
+ spk_kwargs = {} if kwargs.get("spk_kwargs", {}) is None else kwargs.get("spk_kwargs", {})
154
+ cb_kwargs = (
155
+ {} if spk_kwargs.get("cb_kwargs", {}) is None else spk_kwargs.get("cb_kwargs", {})
156
+ )
157
+ if spk_model is not None:
158
+ logging.info("Building SPK model.")
159
+ spk_kwargs["model"] = spk_model
160
+ spk_kwargs["model_revision"] = kwargs.get("spk_model_revision", "master")
161
+ spk_kwargs["device"] = kwargs["device"]
162
+ spk_kwargs["dev_id"] = kwargs["dev_id"]
163
+ spk_model, spk_kwargs = self.build_model(**spk_kwargs)
164
+ self.cb_model = ClusterBackend(**cb_kwargs).to(kwargs["device"])
165
+ spk_mode = kwargs.get("spk_mode", "punc_segment")
166
+ if spk_mode not in ["default", "vad_segment", "punc_segment"]:
167
+ logging.error("spk_mode should be one of default, vad_segment and punc_segment.")
168
+ self.spk_mode = spk_mode
169
+
170
+ self.kwargs = kwargs
171
+ self.model = model
172
+ self.vad_model = vad_model
173
+ self.vad_kwargs = vad_kwargs
174
+ self.punc_model = punc_model
175
+ self.punc_kwargs = punc_kwargs
176
+ self.spk_model = spk_model
177
+ self.spk_kwargs = spk_kwargs
178
+ self.model_path = kwargs.get("model_path")
179
+
180
+ @staticmethod
181
+ def build_model(**kwargs):
182
+ assert "model" in kwargs
183
+ if "model_conf" not in kwargs:
184
+ logging.info("download models from model hub: {}".format(kwargs.get("hub", "ms")))
185
+ kwargs = download_model(**kwargs)
186
+
187
+ set_all_random_seed(kwargs.get("seed", 0))
188
+
189
+ device = kwargs.get("device", "cuda")
190
+ if not torch.cuda.is_available() or kwargs.get("ngpu", 1) == 0:
191
+ device = "cpu"
192
+ kwargs["batch_size"] = 1
193
+ kwargs["device"] = device
194
+
195
+ torch.set_num_threads(kwargs.get("ncpu", 4))
196
+
197
+ # build tokenizer
198
+ tokenizer = kwargs.get("tokenizer", None)
199
+ kwargs["tokenizer"] = tokenizer
200
+ kwargs["vocab_size"] = -1
201
+
202
+ if tokenizer is not None:
203
+ tokenizers = (
204
+ tokenizer.split(",") if isinstance(tokenizer, str) else tokenizer
205
+ ) # type of tokenizers is list!!!
206
+ tokenizers_conf = kwargs.get("tokenizer_conf", {})
207
+ tokenizers_build = []
208
+ vocab_sizes = []
209
+ token_lists = []
210
+
211
+ ### === only for kws ===
212
+ token_list_files = kwargs.get("token_lists", [])
213
+ seg_dicts = kwargs.get("seg_dicts", [])
214
+ ### === only for kws ===
215
+
216
+ if not isinstance(tokenizers_conf, (list, tuple, ListConfig)):
217
+ tokenizers_conf = [tokenizers_conf] * len(tokenizers)
218
+
219
+ for i, tokenizer in enumerate(tokenizers):
220
+ tokenizer_class = tables.tokenizer_classes.get(tokenizer)
221
+ tokenizer_conf = tokenizers_conf[i]
222
+
223
+ ### === only for kws ===
224
+ if len(token_list_files) > 1:
225
+ tokenizer_conf["token_list"] = token_list_files[i]
226
+ if len(seg_dicts) > 1:
227
+ tokenizer_conf["seg_dict"] = seg_dicts[i]
228
+ ### === only for kws ===
229
+
230
+ tokenizer = tokenizer_class(**tokenizer_conf)
231
+ tokenizers_build.append(tokenizer)
232
+ token_list = tokenizer.token_list if hasattr(tokenizer, "token_list") else None
233
+ token_list = (
234
+ tokenizer.get_vocab() if hasattr(tokenizer, "get_vocab") else token_list
235
+ )
236
+ vocab_size = -1
237
+ if token_list is not None:
238
+ vocab_size = len(token_list)
239
+
240
+ if vocab_size == -1 and hasattr(tokenizer, "get_vocab_size"):
241
+ vocab_size = tokenizer.get_vocab_size()
242
+ token_lists.append(token_list)
243
+ vocab_sizes.append(vocab_size)
244
+
245
+ if len(tokenizers_build) <= 1:
246
+ tokenizers_build = tokenizers_build[0]
247
+ token_lists = token_lists[0]
248
+ vocab_sizes = vocab_sizes[0]
249
+
250
+ kwargs["tokenizer"] = tokenizers_build
251
+ kwargs["vocab_size"] = vocab_sizes
252
+ kwargs["token_list"] = token_lists
253
+
254
+ # build frontend
255
+ frontend = kwargs.get("frontend", None)
256
+ kwargs["input_size"] = None
257
+ if frontend is not None:
258
+ frontend_class = tables.frontend_classes.get(frontend)
259
+ frontend = frontend_class(**kwargs.get("frontend_conf", {}))
260
+ kwargs["input_size"] = (
261
+ frontend.output_size() if hasattr(frontend, "output_size") else None
262
+ )
263
+ kwargs["frontend"] = frontend
264
+ # build model
265
+ model_class = tables.model_classes.get(kwargs["model"])
266
+ assert model_class is not None, f'{kwargs["model"]} is not registered'
267
+ model_conf = {}
268
+ deep_update(model_conf, kwargs.get("model_conf", {}))
269
+ deep_update(model_conf, kwargs)
270
+ model = model_class(**model_conf)
271
+
272
+ """
273
+ # init_param
274
+ init_param = kwargs.get("init_param", None)
275
+ if init_param is not None:
276
+ if os.path.exists(init_param):
277
+ logging.info(f"Loading pretrained params from {init_param}")
278
+ load_pretrained_model(
279
+ model=model,
280
+ path=init_param,
281
+ ignore_init_mismatch=kwargs.get("ignore_init_mismatch", True),
282
+ oss_bucket=kwargs.get("oss_bucket", None),
283
+ scope_map=kwargs.get("scope_map", []),
284
+ excludes=kwargs.get("excludes", None),
285
+ )
286
+ else:
287
+ print(f"error, init_param does not exist!: {init_param}")
288
+ """
289
+
290
+ # fp16
291
+ if kwargs.get("fp16", False):
292
+ model.to(torch.float16)
293
+ elif kwargs.get("bf16", False):
294
+ model.to(torch.bfloat16)
295
+ model.to(device)
296
+
297
+ if not kwargs.get("disable_log", True):
298
+ tables.print()
299
+
300
+ return model, kwargs
301
+
302
+ def __call__(self, *args, **cfg):
303
+ kwargs = self.kwargs
304
+ deep_update(kwargs, cfg)
305
+ res = self.model(*args, kwargs)
306
+ return res
307
+
308
+ def generate(self, input, input_len=None, **cfg):
309
+ if self.vad_model is None:
310
+ return self.inference(input, input_len=input_len, **cfg)
311
+
312
+ else:
313
+ return self.inference_with_vad(input, input_len=input_len, **cfg)
314
+
315
+ def inference(self, input, input_len=None, model=None, kwargs=None, key=None, **cfg):
316
+ kwargs = self.kwargs if kwargs is None else kwargs
317
+ if "cache" in kwargs:
318
+ kwargs.pop("cache")
319
+ deep_update(kwargs, cfg)
320
+ model = self.model if model is None else model
321
+ model.eval()
322
+
323
+ batch_size = kwargs.get("batch_size", 1)
324
+ # if kwargs.get("device", "cpu") == "cpu":
325
+ # batch_size = 1
326
+
327
+ key_list, data_list = prepare_data_iterator(
328
+ input, input_len=input_len, data_type=kwargs.get("data_type", None), key=key
329
+ )
330
+
331
+ speed_stats = {}
332
+ asr_result_list = []
333
+ num_samples = len(data_list)
334
+ disable_pbar = self.kwargs.get("disable_pbar", False)
335
+ pbar = (
336
+ tqdm(colour="blue", total=num_samples, dynamic_ncols=True) if not disable_pbar else None
337
+ )
338
+ time_speech_total = 0.0
339
+ time_escape_total = 0.0
340
+ for beg_idx in range(0, num_samples, batch_size):
341
+ end_idx = min(num_samples, beg_idx + batch_size)
342
+ data_batch = data_list[beg_idx:end_idx]
343
+ key_batch = key_list[beg_idx:end_idx]
344
+ batch = {"data_in": data_batch, "key": key_batch}
345
+
346
+ if (end_idx - beg_idx) == 1 and kwargs.get("data_type", None) == "fbank": # fbank
347
+ batch["data_in"] = data_batch[0]
348
+ batch["data_lengths"] = input_len
349
+
350
+ time1 = time.perf_counter()
351
+ with torch.no_grad():
352
+ res = model.inference(**batch, **kwargs)
353
+ if isinstance(res, (list, tuple)):
354
+ results = res[0] if len(res) > 0 else [{"text": ""}]
355
+ meta_data = res[1] if len(res) > 1 else {}
356
+ time2 = time.perf_counter()
357
+
358
+ asr_result_list.extend(results)
359
+
360
+ # batch_data_time = time_per_frame_s * data_batch_i["speech_lengths"].sum().item()
361
+ batch_data_time = meta_data.get("batch_data_time", -1)
362
+ time_escape = time2 - time1
363
+ speed_stats["load_data"] = meta_data.get("load_data", 0.0)
364
+ speed_stats["extract_feat"] = meta_data.get("extract_feat", 0.0)
365
+ speed_stats["forward"] = f"{time_escape:0.3f}"
366
+ speed_stats["batch_size"] = f"{len(results)}"
367
+ speed_stats["rtf"] = f"{(time_escape) / batch_data_time:0.3f}"
368
+ description = f"{speed_stats}, "
369
+ if pbar:
370
+ pbar.update(end_idx - beg_idx)
371
+ pbar.set_description(description)
372
+ time_speech_total += batch_data_time
373
+ time_escape_total += time_escape
374
+
375
+ if pbar:
376
+ # pbar.update(1)
377
+ pbar.set_description(f"rtf_avg: {time_escape_total/time_speech_total:0.3f}")
378
+
379
+ """
380
+ device = next(model.parameters()).device
381
+ if device.type == "cuda":
382
+ with torch.cuda.device(device):
383
+ torch.cuda.empty_cache()
384
+ """
385
+ return asr_result_list
386
+
387
+ def inference_with_vad(self, input, input_len=None, **cfg):
388
+ kwargs = self.kwargs
389
+ # step.1: compute the vad model
390
+ deep_update(self.vad_kwargs, cfg)
391
+ beg_vad = time.time()
392
+ res = self.inference(
393
+ input, input_len=input_len, model=self.vad_model, kwargs=self.vad_kwargs, **cfg
394
+ )
395
+ end_vad = time.time()
396
+
397
+ # FIX(gcf): concat the vad clips for sense vocie model for better aed
398
+ if cfg.get("merge_vad", False):
399
+ for i in range(len(res)):
400
+ res[i]["value"] = merge_vad(
401
+ res[i]["value"], kwargs.get("merge_length_s", 15) * 1000
402
+ )
403
+
404
+ # step.2 compute asr model
405
+ model = self.model
406
+ deep_update(kwargs, cfg)
407
+ batch_size = max(int(kwargs.get("batch_size_s", 300)) * 1000, 1)
408
+ batch_size_threshold_ms = int(kwargs.get("batch_size_threshold_s", 60)) * 1000
409
+ kwargs["batch_size"] = batch_size
410
+
411
+ key_list, data_list = prepare_data_iterator(
412
+ input, input_len=input_len, data_type=kwargs.get("data_type", None)
413
+ )
414
+ results_ret_list = []
415
+ time_speech_total_all_samples = 1e-6
416
+
417
+ beg_total = time.time()
418
+ pbar_total = (
419
+ tqdm(colour="red", total=len(res), dynamic_ncols=True)
420
+ if not kwargs.get("disable_pbar", False)
421
+ else None
422
+ )
423
+ for i in range(len(res)):
424
+ key = res[i]["key"]
425
+ vadsegments = res[i]["value"]
426
+ input_i = data_list[i]
427
+ fs = kwargs["frontend"].fs if hasattr(kwargs["frontend"], "fs") else 16000
428
+ speech = load_audio_text_image_video(input_i, fs=fs, audio_fs=kwargs.get("fs", 16000))
429
+ speech_lengths = len(speech)
430
+ n = len(vadsegments)
431
+ data_with_index = [(vadsegments[i], i) for i in range(n)]
432
+ sorted_data = sorted(data_with_index, key=lambda x: x[0][1] - x[0][0])
433
+ results_sorted = []
434
+
435
+ if not len(sorted_data):
436
+ results_ret_list.append({"key": key, "text": "", "timestamp": []})
437
+ logging.info("decoding, utt: {}, empty speech".format(key))
438
+ continue
439
+
440
+ if len(sorted_data) > 0 and len(sorted_data[0]) > 0:
441
+ batch_size = max(batch_size, sorted_data[0][0][1] - sorted_data[0][0][0])
442
+
443
+ """
444
+ if kwargs["device"] == "cpu":
445
+ batch_size = 0
446
+ """
447
+
448
+ beg_idx = 0
449
+ beg_asr_total = time.time()
450
+ time_speech_total_per_sample = speech_lengths / 16000
451
+ time_speech_total_all_samples += time_speech_total_per_sample
452
+
453
+ # pbar_sample = tqdm(colour="blue", total=n, dynamic_ncols=True)
454
+
455
+ all_segments = []
456
+ max_len_in_batch = 0
457
+ end_idx = 1
458
+ for j, _ in enumerate(range(0, n)):
459
+ # pbar_sample.update(1)
460
+ sample_length = sorted_data[j][0][1] - sorted_data[j][0][0]
461
+ potential_batch_length = max(max_len_in_batch, sample_length) * (j + 1 - beg_idx)
462
+ # batch_size_ms_cum += sorted_data[j][0][1] - sorted_data[j][0][0]
463
+ if (
464
+ j < n - 1
465
+ and sample_length < batch_size_threshold_ms
466
+ and potential_batch_length < batch_size
467
+ and j + 1 - beg_idx < 10
468
+ ):
469
+ max_len_in_batch = max(max_len_in_batch, sample_length)
470
+ end_idx += 1
471
+ continue
472
+
473
+ speech_j, speech_lengths_j = slice_padding_audio_samples(
474
+ speech, speech_lengths, sorted_data[beg_idx:end_idx]
475
+ )
476
+ results = self.inference(
477
+ speech_j, input_len=None, model=model, kwargs=kwargs, **cfg
478
+ )
479
+ if self.spk_model is not None:
480
+ # compose vad segments: [[start_time_sec, end_time_sec, speech], [...]]
481
+ for _b in range(len(speech_j)):
482
+ vad_segments = [
483
+ [
484
+ sorted_data[beg_idx:end_idx][_b][0][0] / 1000.0,
485
+ sorted_data[beg_idx:end_idx][_b][0][1] / 1000.0,
486
+ np.array(speech_j[_b]),
487
+ ]
488
+ ]
489
+ segments = sv_chunk(vad_segments)
490
+ all_segments.extend(segments)
491
+ speech_b = [i[2] for i in segments]
492
+ spk_res = self.inference(
493
+ speech_b, input_len=None, model=self.spk_model, kwargs=kwargs, **cfg
494
+ )
495
+ results[_b]["spk_embedding"] = spk_res[0]["spk_embedding"]
496
+ beg_idx = end_idx
497
+ end_idx += 1
498
+ max_len_in_batch = sample_length
499
+ if len(results) < 1:
500
+ continue
501
+ results_sorted.extend(results)
502
+
503
+ # end_asr_total = time.time()
504
+ # time_escape_total_per_sample = end_asr_total - beg_asr_total
505
+ # pbar_sample.update(1)
506
+ # pbar_sample.set_description(f"rtf_avg_per_sample: {time_escape_total_per_sample / time_speech_total_per_sample:0.3f}, "
507
+ # f"time_speech_total_per_sample: {time_speech_total_per_sample: 0.3f}, "
508
+ # f"time_escape_total_per_sample: {time_escape_total_per_sample:0.3f}")
509
+
510
+ if len(results_sorted) != n:
511
+ results_ret_list.append({"key": key, "text": "", "timestamp": []})
512
+ logging.info("decoding, utt: {}, empty result".format(key))
513
+ continue
514
+ restored_data = [0] * n
515
+ for j in range(n):
516
+ index = sorted_data[j][1]
517
+ restored_data[index] = results_sorted[j]
518
+ result = {}
519
+
520
+ # results combine for texts, timestamps, speaker embeddings and others
521
+ # TODO: rewrite for clean code
522
+ for j in range(n):
523
+ for k, v in restored_data[j].items():
524
+ if k.startswith("timestamp"):
525
+ if k not in result:
526
+ result[k] = []
527
+ for t in restored_data[j][k]:
528
+ t[0] += vadsegments[j][0]
529
+ t[1] += vadsegments[j][0]
530
+ result[k].extend(restored_data[j][k])
531
+ elif k == "spk_embedding":
532
+ if k not in result:
533
+ result[k] = restored_data[j][k]
534
+ else:
535
+ result[k] = torch.cat([result[k], restored_data[j][k]], dim=0)
536
+ elif "text" in k:
537
+ if k not in result:
538
+ result[k] = restored_data[j][k]
539
+ else:
540
+ result[k] += " " + restored_data[j][k]
541
+ else:
542
+ if k not in result:
543
+ result[k] = restored_data[j][k]
544
+ else:
545
+ result[k] += restored_data[j][k]
546
+
547
+ if not len(result["text"].strip()):
548
+ continue
549
+ return_raw_text = kwargs.get("return_raw_text", False)
550
+ # step.3 compute punc model
551
+ raw_text = None
552
+ if self.punc_model is not None:
553
+ deep_update(self.punc_kwargs, cfg)
554
+ punc_res = self.inference(
555
+ result["text"], model=self.punc_model, kwargs=self.punc_kwargs, **cfg
556
+ )
557
+ raw_text = copy.copy(result["text"])
558
+ if return_raw_text:
559
+ result["raw_text"] = raw_text
560
+ result["text"] = punc_res[0]["text"]
561
+
562
+ # speaker embedding cluster after resorted
563
+ if self.spk_model is not None and kwargs.get("return_spk_res", True):
564
+ if raw_text is None:
565
+ logging.error("Missing punc_model, which is required by spk_model.")
566
+ all_segments = sorted(all_segments, key=lambda x: x[0])
567
+ spk_embedding = result["spk_embedding"]
568
+ labels = self.cb_model(
569
+ spk_embedding.cpu(), oracle_num=kwargs.get("preset_spk_num", None)
570
+ )
571
+ # del result['spk_embedding']
572
+ sv_output = postprocess(all_segments, None, labels, spk_embedding.cpu())
573
+ if self.spk_mode == "vad_segment": # recover sentence_list
574
+ sentence_list = []
575
+ for rest, vadsegment in zip(restored_data, vadsegments):
576
+ if "timestamp" not in rest:
577
+ logging.error(
578
+ "Only 'iic/speech_paraformer-large-vad-punc_asr_nat-zh-cn-16k-common-vocab8404-pytorch' \
579
+ and 'iic/speech_seaco_paraformer_large_asr_nat-zh-cn-16k-common-vocab8404-pytorch'\
580
+ can predict timestamp, and speaker diarization relies on timestamps."
581
+ )
582
+ sentence_list.append(
583
+ {
584
+ "start": vadsegment[0],
585
+ "end": vadsegment[1],
586
+ "sentence": rest["text"],
587
+ "timestamp": rest["timestamp"],
588
+ }
589
+ )
590
+ elif self.spk_mode == "punc_segment":
591
+ if "timestamp" not in result:
592
+ logging.error(
593
+ "Only 'iic/speech_paraformer-large-vad-punc_asr_nat-zh-cn-16k-common-vocab8404-pytorch' \
594
+ and 'iic/speech_seaco_paraformer_large_asr_nat-zh-cn-16k-common-vocab8404-pytorch'\
595
+ can predict timestamp, and speaker diarization relies on timestamps."
596
+ )
597
+ if kwargs.get("en_post_proc", False):
598
+ sentence_list = timestamp_sentence_en(
599
+ punc_res[0]["punc_array"],
600
+ result["timestamp"],
601
+ raw_text,
602
+ return_raw_text=return_raw_text,
603
+ )
604
+ else:
605
+ sentence_list = timestamp_sentence(
606
+ punc_res[0]["punc_array"],
607
+ result["timestamp"],
608
+ raw_text,
609
+ return_raw_text=return_raw_text,
610
+ )
611
+ distribute_spk(sentence_list, sv_output)
612
+ result["sentence_info"] = sentence_list
613
+ elif kwargs.get("sentence_timestamp", False):
614
+ if not len(result["text"].strip()):
615
+ sentence_list = []
616
+ else:
617
+ if kwargs.get("en_post_proc", False):
618
+ sentence_list = timestamp_sentence_en(
619
+ punc_res[0]["punc_array"],
620
+ result["timestamp"],
621
+ raw_text,
622
+ return_raw_text=return_raw_text,
623
+ )
624
+ else:
625
+ sentence_list = timestamp_sentence(
626
+ punc_res[0]["punc_array"],
627
+ result["timestamp"],
628
+ raw_text,
629
+ return_raw_text=return_raw_text,
630
+ )
631
+ result["sentence_info"] = sentence_list
632
+ if "spk_embedding" in result:
633
+ del result["spk_embedding"]
634
+
635
+ result["key"] = key
636
+ results_ret_list.append(result)
637
+ end_asr_total = time.time()
638
+ time_escape_total_per_sample = end_asr_total - beg_asr_total
639
+ if pbar_total:
640
+ pbar_total.update(1)
641
+ pbar_total.set_description(
642
+ f"rtf_avg: {time_escape_total_per_sample / time_speech_total_per_sample:0.3f}, "
643
+ f"time_speech: {time_speech_total_per_sample: 0.3f}, "
644
+ f"time_escape: {time_escape_total_per_sample:0.3f}"
645
+ )
646
+
647
+ # end_total = time.time()
648
+ # time_escape_total_all_samples = end_total - beg_total
649
+ # print(f"rtf_avg_all: {time_escape_total_all_samples / time_speech_total_all_samples:0.3f}, "
650
+ # f"time_speech_all: {time_speech_total_all_samples: 0.3f}, "
651
+ # f"time_escape_all: {time_escape_total_all_samples:0.3f}")
652
+ return results_ret_list
653
+
654
+ def export(self, input=None, **cfg):
655
+ """
656
+
657
+ :param input:
658
+ :param type:
659
+ :param quantize:
660
+ :param fallback_num:
661
+ :param calib_num:
662
+ :param opset_version:
663
+ :param cfg:
664
+ :return:
665
+ """
666
+
667
+ device = cfg.get("device", "cpu")
668
+ model = self.model.to(device=device)
669
+ kwargs = self.kwargs
670
+ deep_update(kwargs, cfg)
671
+ kwargs["device"] = device
672
+ del kwargs["model"]
673
+ model.eval()
674
+
675
+ type = kwargs.get("type", "onnx")
676
+
677
+ key_list, data_list = prepare_data_iterator(
678
+ input, input_len=None, data_type=kwargs.get("data_type", None), key=None
679
+ )
680
+
681
+ with torch.no_grad():
682
+ export_dir = export_utils.export(model=model, data_in=data_list, **kwargs)
683
+
684
+ return export_dir
funasr/auto/auto_tokenizer.py ADDED
@@ -0,0 +1,7 @@
 
 
 
 
 
 
 
 
1
+ class AutoTokenizer:
2
+ """
3
+ Undo
4
+ """
5
+
6
+ def __init__(self):
7
+ pass
funasr/bin/__init__.py ADDED
File without changes
funasr/bin/compute_audio_cmvn.py ADDED
@@ -0,0 +1,136 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import os
2
+ import json
3
+ import numpy as np
4
+ import torch
5
+ import hydra
6
+ import logging
7
+ from omegaconf import DictConfig, OmegaConf
8
+
9
+ from funasr.register import tables
10
+ from funasr.download.download_model_from_hub import download_model
11
+ from funasr.train_utils.set_all_random_seed import set_all_random_seed
12
+
13
+
14
+ @hydra.main(config_name=None, version_base=None)
15
+ def main_hydra(kwargs: DictConfig):
16
+ if kwargs.get("debug", False):
17
+ import pdb
18
+
19
+ pdb.set_trace()
20
+
21
+ assert "model" in kwargs
22
+ if "model_conf" not in kwargs:
23
+ logging.info("download models from model hub: {}".format(kwargs.get("hub", "ms")))
24
+ kwargs = download_model(is_training=kwargs.get("is_training", True), **kwargs)
25
+
26
+ main(**kwargs)
27
+
28
+
29
+ def main(**kwargs):
30
+ print(kwargs)
31
+ # set random seed
32
+ # tables.print()
33
+ set_all_random_seed(kwargs.get("seed", 0))
34
+ torch.backends.cudnn.enabled = kwargs.get("cudnn_enabled", torch.backends.cudnn.enabled)
35
+ torch.backends.cudnn.benchmark = kwargs.get("cudnn_benchmark", torch.backends.cudnn.benchmark)
36
+ torch.backends.cudnn.deterministic = kwargs.get("cudnn_deterministic", True)
37
+
38
+ tokenizer = kwargs.get("tokenizer", None)
39
+
40
+ # build frontend if frontend is none None
41
+ frontend = kwargs.get("frontend", None)
42
+ if frontend is not None:
43
+ frontend_class = tables.frontend_classes.get(frontend)
44
+ frontend = frontend_class(**kwargs["frontend_conf"])
45
+ kwargs["frontend"] = frontend
46
+ kwargs["input_size"] = frontend.output_size()
47
+
48
+ # dataset
49
+ dataset_class = tables.dataset_classes.get(kwargs.get("dataset", "AudioDataset"))
50
+ dataset_train = dataset_class(
51
+ kwargs.get("train_data_set_list"),
52
+ frontend=frontend,
53
+ tokenizer=None,
54
+ is_training=False,
55
+ **kwargs.get("dataset_conf"),
56
+ )
57
+
58
+ # dataloader
59
+ batch_sampler = kwargs["dataset_conf"].get("batch_sampler", "BatchSampler")
60
+ batch_sampler_class = tables.batch_sampler_classes.get(batch_sampler)
61
+ dataset_conf = kwargs.get("dataset_conf")
62
+ dataset_conf["batch_type"] = "example"
63
+ dataset_conf["batch_size"] = 1
64
+ dataset_conf["num_workers"] = os.cpu_count() or 32
65
+ batch_sampler_train = batch_sampler_class(dataset_train, is_training=False, **dataset_conf)
66
+
67
+ dataloader_train = torch.utils.data.DataLoader(
68
+ dataset_train, collate_fn=dataset_train.collator, **batch_sampler_train
69
+ )
70
+
71
+ total_frames = 0
72
+ for batch_idx, batch in enumerate(dataloader_train):
73
+ iter_stop = int(kwargs.get("scale", -1.0) * len(dataloader_train))
74
+ log_step = iter_stop // 100
75
+ if batch_idx % log_step == 0:
76
+ logging.info(f"prcessed: {batch_idx}/{iter_stop}")
77
+ if batch_idx >= iter_stop and iter_stop > 0.0:
78
+ logging.info(f"prcessed: {iter_stop}/{iter_stop}")
79
+ break
80
+
81
+ fbank = batch["speech"].numpy()[0, :, :]
82
+ if total_frames == 0:
83
+ mean_stats = np.sum(fbank, axis=0)
84
+ var_stats = np.sum(np.square(fbank), axis=0)
85
+ else:
86
+ mean_stats += np.sum(fbank, axis=0)
87
+ var_stats += np.sum(np.square(fbank), axis=0)
88
+ total_frames += fbank.shape[0]
89
+
90
+ cmvn_info = {
91
+ "mean_stats": mean_stats.tolist(),
92
+ "var_stats": var_stats.tolist(),
93
+ "total_frames": total_frames,
94
+ }
95
+ cmvn_file = kwargs.get("cmvn_file", "cmvn.json")
96
+ # import pdb;pdb.set_trace()
97
+ with open(cmvn_file, "w") as fout:
98
+ fout.write(json.dumps(cmvn_info))
99
+
100
+ mean = -1.0 * mean_stats / total_frames
101
+ var = 1.0 / np.sqrt(var_stats / total_frames - mean * mean)
102
+ dims = mean.shape[0]
103
+ am_mvn = os.path.dirname(cmvn_file) + "/am.mvn"
104
+ with open(am_mvn, "w") as fout:
105
+ fout.write(
106
+ "<Nnet>"
107
+ + "\n"
108
+ + "<Splice> "
109
+ + str(dims)
110
+ + " "
111
+ + str(dims)
112
+ + "\n"
113
+ + "[ 0 ]"
114
+ + "\n"
115
+ + "<AddShift> "
116
+ + str(dims)
117
+ + " "
118
+ + str(dims)
119
+ + "\n"
120
+ )
121
+ fout.write("<LearnRateCoef> 0 [ " + " ".join([str(item) for item in mean]) + " ]\n")
122
+ fout.write("<Rescale> " + str(dims) + " " + str(dims) + "\n")
123
+ fout.write("<LearnRateCoef> 0 [ " + " ".join([str(item) for item in var]) + " ]\n")
124
+ fout.write("</Nnet>" + "\n")
125
+
126
+
127
+ """
128
+ python funasr/bin/compute_audio_cmvn.py \
129
+ --config-path "/Users/zhifu/funasr1.0/examples/aishell/paraformer/conf" \
130
+ --config-name "train_asr_paraformer_conformer_12e_6d_2048_256.yaml" \
131
+ ++train_data_set_list="/Users/zhifu/funasr1.0/data/list/audio_datasets.jsonl" \
132
+ ++cmvn_file="/Users/zhifu/funasr1.0/data/list/cmvn.json" \
133
+ ++dataset_conf.num_workers=0
134
+ """
135
+ if __name__ == "__main__":
136
+ main_hydra()
funasr/bin/export.py ADDED
@@ -0,0 +1,42 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import os
2
+ import hydra
3
+ import logging
4
+ from omegaconf import DictConfig, OmegaConf, ListConfig
5
+
6
+ from funasr.auto.auto_model import AutoModel
7
+
8
+
9
+ @hydra.main(config_name=None, version_base=None)
10
+ def main_hydra(cfg: DictConfig):
11
+ def to_plain_list(cfg_item):
12
+ if isinstance(cfg_item, ListConfig):
13
+ return OmegaConf.to_container(cfg_item, resolve=True)
14
+ elif isinstance(cfg_item, DictConfig):
15
+ return {k: to_plain_list(v) for k, v in cfg_item.items()}
16
+ else:
17
+ return cfg_item
18
+
19
+ kwargs = to_plain_list(cfg)
20
+
21
+ if kwargs.get("debug", False):
22
+ import pdb
23
+
24
+ pdb.set_trace()
25
+
26
+ if "device" not in kwargs:
27
+ kwargs["device"] = "cpu"
28
+ model = AutoModel(**kwargs)
29
+
30
+ res = model.export(
31
+ input=kwargs.get("input", None),
32
+ type=kwargs.get("type", "onnx"),
33
+ quantize=kwargs.get("quantize", False),
34
+ fallback_num=kwargs.get("fallback-num", 5),
35
+ calib_num=kwargs.get("calib_num", 100),
36
+ opset_version=kwargs.get("opset_version", 14),
37
+ )
38
+ print(res)
39
+
40
+
41
+ if __name__ == "__main__":
42
+ main_hydra()
funasr/bin/inference.py ADDED
@@ -0,0 +1,30 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import hydra
2
+ import logging
3
+ from omegaconf import DictConfig, OmegaConf, ListConfig
4
+
5
+ from funasr.auto.auto_model import AutoModel
6
+
7
+
8
+ @hydra.main(config_name=None, version_base=None)
9
+ def main_hydra(cfg: DictConfig):
10
+ def to_plain_list(cfg_item):
11
+ if isinstance(cfg_item, ListConfig):
12
+ return OmegaConf.to_container(cfg_item, resolve=True)
13
+ elif isinstance(cfg_item, DictConfig):
14
+ return {k: to_plain_list(v) for k, v in cfg_item.items()}
15
+ else:
16
+ return cfg_item
17
+
18
+ kwargs = to_plain_list(cfg)
19
+
20
+ if kwargs.get("debug", False):
21
+ import pdb
22
+
23
+ pdb.set_trace()
24
+ model = AutoModel(**kwargs)
25
+ res = model.generate(input=kwargs["input"])
26
+ print(res)
27
+
28
+
29
+ if __name__ == "__main__":
30
+ main_hydra()