-
Notifications
You must be signed in to change notification settings - Fork 103
/
Copy pathutils.py
143 lines (115 loc) · 4.16 KB
/
utils.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
#!/usr/bin/env python
# -*- coding: utf-8 -*-
import re
import os
import sys
import shutil
import logger
import subprocess
from stt import Model as SModel
from deepspeech import Model as DModel
_logger = logger.setup_applevel_logger(__name__)
_models = {
"ds": {
"model": "https://github.com/mozilla/DeepSpeech/releases/download/v0.9.3/deepspeech-0.9.3-models.pbmm",
"scorer": "https://github.com/mozilla/DeepSpeech/releases/download/v0.9.3/deepspeech-0.9.3-models.scorer"
},
"stt": {
"model": "https://github.com/coqui-ai/STT-models/releases/download/english/coqui/v0.9.3/model.tflite",
"scorer": "https://github.com/coqui-ai/STT-models/releases/download/english%2Fcoqui%2Fv1.0.0-huge-vocab/huge-vocabulary.scorer"
}
}
def sort_alphanumeric(data):
"""Sort function to sort os.listdir() alphanumerically
Helps to process audio files sequentially after splitting
Args:
data : file name
"""
convert = lambda text: int(text) if text.isdigit() else text.lower()
alphanum_key = lambda key: [convert(c) for c in re.split('([0-9]+)', key)]
return sorted(data, key=alphanum_key)
def clean_folder(folder):
"""Delete everything inside a folder
Args:
folder : target folder
"""
for filename in os.listdir(folder):
file_path = os.path.join(folder, filename)
try:
if os.path.isfile(file_path) or os.path.islink(file_path):
os.unlink(file_path)
elif os.path.isdir(file_path):
shutil.rmtree(file_path)
except Exception as e:
_logger.warn(f"Failed to delete {file_path}. Reason: {e}")
def download_model(engine, fname):
"""Download model files, if not available locally
Args:
engine : "ds" for DeepSpeech and "stt" for Coqui STT
fname : either of "model" or "scorer"
"""
_logger.info(f"{fname.capitalize()} not found locally. Downloading")
try:
_file = _models[engine][fname]
command = ["wget", _file, "-q", "--show-progress"]
ret = subprocess.run(command).returncode
except Exception as e:
_logger.error(str(e))
sys.exit(1)
return _file.split("/")[-1]
def get_model(args, arg_name):
"""Will prioritze supplied arguments but if not, try to find files
Args:
args : run-time arguments
arg_name : either model or scorer file
"""
if arg_name == "model":
if args.engine == "ds":
arg_extension = ".pbmm"
else:
arg_extension = ".tflite"
elif arg_name == "scorer":
arg_extension = ".scorer"
arg = args.__getattribute__(arg_name)
if arg is not None:
model = os.path.abspath(arg)
if not os.path.isfile(model):
_logger.error(f"Supplied file {arg} doesn't exist. Please supply a valid {arg_name} file via the --{arg_name} flag")
sys.exit(1)
else:
models = [file for file in os.listdir() if file.endswith(arg_extension)]
num_models = len(models)
if num_models == 0:
model = download_model(args.engine, arg_name)
elif num_models != 1:
_logger.warn(f"Detected {num_models} {arg_name} files in local dir")
if arg_name == 'model':
_logger.error("Must specify pbmm model")
sys.exit(1)
else:
_logger.warn("Please specify scorer using --scorer")
model = ''
else:
model = os.path.abspath(models[0])
_logger.info(f"{arg_name.capitalize()}: {model}")
return(model)
def create_model(engine, model, scorer):
"""Instantiate model and scorer
Args:
engine : "ds" for DeepSpeech and "stt" for Coqui STT
model : .pbmm model file
scorer : .scorer file
"""
try:
if engine == "ds":
ds = DModel(model)
else:
ds = SModel(model)
except:
_logger.error("Invalid model file")
sys.exit(1)
try:
ds.enableExternalScorer(scorer)
except:
_logger.warn("Invalid scorer file. Running inference using only model file")
return(ds)