devasheeshG
commited on
Commit
•
013bf1c
1
Parent(s):
c960644
edit ReadMe.md
Browse files- .gitignore +2 -1
- README.md +53 -30
- __init__.py +49 -49
.gitignore
CHANGED
@@ -1 +1,2 @@
|
|
1 |
-
__pycache__
|
|
|
|
1 |
+
__pycache__
|
2 |
+
.vscode
|
README.md
CHANGED
@@ -75,7 +75,7 @@ model-index:
|
|
75 |
value: 0
|
76 |
name: Test CER
|
77 |
description: Character Error Rate
|
78 |
-
|
79 |
- task:
|
80 |
type: automatic-speech-recognition
|
81 |
name: Automatic Speech Recognition
|
@@ -216,7 +216,6 @@ language:
|
|
216 |
- ba
|
217 |
- jw
|
218 |
- su
|
219 |
-
|
220 |
---
|
221 |
## Versions:
|
222 |
|
@@ -233,17 +232,18 @@ language:
|
|
233 |
- RAM: 2.8 GB (Original_Model: 5.5GB)
|
234 |
- VRAM: 1812 MB (Original_Model: 6GB)
|
235 |
- test.wav: 23 s (Multilingual Speech i.e. English+Hindi)
|
|
|
236 |
- **Time in seconds for Processing by each device**
|
237 |
|
238 |
-
| Device Name | float32 (Original)
|
239 |
-
| ----------------- |
|
240 |
-
| 3060 | 1.7
|
241 |
-
| 1660 Super | OOM
|
242 |
-
| Collab (Tesla T4) | 2.8
|
243 |
-
| Collab (CPU) | 35
|
244 |
-
| M1 (CPU) | -
|
245 |
-
| M1 (GPU -> 'mps') | -
|
246 |
-
|
247 |
|
248 |
- **NOTE: TensorCores are efficient in mixed-precision calculations**
|
249 |
- **CPU -> torch.float16 not supported on CPU (AMD Ryzen 5 3600 or Collab CPU)**
|
@@ -257,46 +257,66 @@ language:
|
|
257 |
- **WIP: Word Information Preserved**
|
258 |
- **CER: Character Error Rate**
|
259 |
|
260 |
-
### Hindi (test.tsv) [Common Voice 14.0](https://
|
|
|
261 |
**Test done on RTX 3060 on 2557 Samples**
|
262 |
-
| | WER | MER | WIL | WIP | CER |
|
263 |
-
| ----------------------- | -------------------- | ------- | --------- | ----------- | ----- |
|
264 |
-
| Original_Model (54 min) | 52.02 | 47.86 | 66.82 | 33.17 | 23.76 |
|
265 |
-
| This_Model (38 min) | 54.97 | 47.86 | 66.83 | 33.16 | 30.23 |
|
266 |
|
267 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
268 |
**Test done on RTX 3060 on __ Samples**
|
269 |
-
| | WER | MER | WIL | WIP | CER |
|
270 |
-
| ----------------- | -------------------- | ------- | --------- | ----------- | --- |
|
271 |
-
| Original_Model | - | - | - | - | - |
|
272 |
-
| This_Model | - | - | - | - | - |
|
273 |
|
274 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
275 |
**Test done on RTX 3060 on __ Samples**
|
276 |
-
|
277 |
-
|
278 |
-
|
279 |
-
|
|
|
280 |
|
281 |
- **'jiwer' library is used for calculations**
|
282 |
|
283 |
## Code for conversion:
|
284 |
-
|
|
|
285 |
|
286 |
## Usage
|
|
|
287 |
A file ``__init__.py`` is contained inside this repo which contains all the code to use this model.
|
288 |
|
289 |
Firstly, clone this repo and place all the files inside a folder.
|
|
|
290 |
### Make sure you have git-lfs installed (https://git-lfs.com)
|
|
|
291 |
```bash
|
292 |
git lfs install
|
293 |
git clone https://huggingface.co/devasheeshG/whisper_medium_fp16_transformers
|
294 |
```
|
|
|
295 |
**Please try in jupyter notebook**
|
296 |
|
297 |
```python
|
298 |
# Import the Model
|
299 |
-
from whisper_medium_fp16_transformers import Model
|
300 |
```
|
301 |
|
302 |
```python
|
@@ -310,12 +330,15 @@ model = Model(
|
|
310 |
|
311 |
```python
|
312 |
# Load Audio
|
313 |
-
audio =
|
|
|
314 |
```
|
315 |
|
316 |
```python
|
317 |
# Transcribe (First transcription takes time)
|
318 |
model.transcribe(audio)
|
319 |
```
|
|
|
320 |
## Credits
|
321 |
-
|
|
|
|
75 |
value: 0
|
76 |
name: Test CER
|
77 |
description: Character Error Rate
|
78 |
+
|
79 |
- task:
|
80 |
type: automatic-speech-recognition
|
81 |
name: Automatic Speech Recognition
|
|
|
216 |
- ba
|
217 |
- jw
|
218 |
- su
|
|
|
219 |
---
|
220 |
## Versions:
|
221 |
|
|
|
232 |
- RAM: 2.8 GB (Original_Model: 5.5GB)
|
233 |
- VRAM: 1812 MB (Original_Model: 6GB)
|
234 |
- test.wav: 23 s (Multilingual Speech i.e. English+Hindi)
|
235 |
+
|
236 |
- **Time in seconds for Processing by each device**
|
237 |
|
238 |
+
| Device Name | float32 (Original) | float16 | CudaCores | TensorCores |
|
239 |
+
| ----------------- | ------------------ | ------- | --------- | ----------- |
|
240 |
+
| 3060 | 1.7 | 1.1 | 3,584 | 112 |
|
241 |
+
| 1660 Super | OOM | 3.3 | 1,408 | N/A |
|
242 |
+
| Collab (Tesla T4) | 2.8 | 2.2 | 2,560 | 320 |
|
243 |
+
| Collab (CPU) | 35 | N/A | N/A | N/A |
|
244 |
+
| M1 (CPU) | - | - | - | - |
|
245 |
+
| M1 (GPU -> 'mps') | - | - | - | - |
|
246 |
+
|
247 |
|
248 |
- **NOTE: TensorCores are efficient in mixed-precision calculations**
|
249 |
- **CPU -> torch.float16 not supported on CPU (AMD Ryzen 5 3600 or Collab CPU)**
|
|
|
257 |
- **WIP: Word Information Preserved**
|
258 |
- **CER: Character Error Rate**
|
259 |
|
260 |
+
### Hindi to Hindi (test.tsv) [Common Voice 14.0](https://commonvoice.mozilla.org/en/datasets)
|
261 |
+
|
262 |
**Test done on RTX 3060 on 2557 Samples**
|
|
|
|
|
|
|
|
|
263 |
|
264 |
+
| | WER | MER | WIL | WIP | CER |
|
265 |
+
| ----------------------- | ----- | ----- | ----- | ----- | ----- |
|
266 |
+
| Original_Model (54 min) | 52.02 | 47.86 | 66.82 | 33.17 | 23.76 |
|
267 |
+
| This_Model (38 min) | 54.97 | 47.86 | 66.83 | 33.16 | 30.23 |
|
268 |
+
|
269 |
+
### Hindi to English (test.tsv) [Common Voice 14.0](https://commonvoice.mozilla.org/en/datasets)
|
270 |
+
|
271 |
+
**Test done on RTX 3060 on 1000 Samples**
|
272 |
+
|
273 |
+
| | WER | MER | WIL | WIP | CER |
|
274 |
+
| ----------------------- | --- | --- | --- | --- | --- |
|
275 |
+
| Original_Model (30 min) | - | - | - | - | - |
|
276 |
+
| This_Model (20 min) | - | - | - | - | - |
|
277 |
+
|
278 |
+
### English ([LibriSpeech](https://huggingface.co/datasets/librispeech_asr) -> test-clean)
|
279 |
+
|
280 |
**Test done on RTX 3060 on __ Samples**
|
|
|
|
|
|
|
|
|
281 |
|
282 |
+
| | WER | MER | WIL | WIP | CER |
|
283 |
+
| -------------- | --- | --- | --- | --- | --- |
|
284 |
+
| Original_Model | - | - | - | - | - |
|
285 |
+
| This_Model | - | - | - | - | - |
|
286 |
+
|
287 |
+
### English ([LibriSpeech](https://huggingface.co/datasets/librispeech_asr) -> test-other)
|
288 |
+
|
289 |
**Test done on RTX 3060 on __ Samples**
|
290 |
+
|
291 |
+
| | WER | MER | WIL | WIP | CER |
|
292 |
+
| -------------- | --- | --- | --- | --- | --- |
|
293 |
+
| Original_Model | - | - | - | - | - |
|
294 |
+
| This_Model | - | - | - | - | - |
|
295 |
|
296 |
- **'jiwer' library is used for calculations**
|
297 |
|
298 |
## Code for conversion:
|
299 |
+
|
300 |
+
- ### [Will be soon Uploaded on Github](https://github.com/devasheeshG)
|
301 |
|
302 |
## Usage
|
303 |
+
|
304 |
A file ``__init__.py`` is contained inside this repo which contains all the code to use this model.
|
305 |
|
306 |
Firstly, clone this repo and place all the files inside a folder.
|
307 |
+
|
308 |
### Make sure you have git-lfs installed (https://git-lfs.com)
|
309 |
+
|
310 |
```bash
|
311 |
git lfs install
|
312 |
git clone https://huggingface.co/devasheeshG/whisper_medium_fp16_transformers
|
313 |
```
|
314 |
+
|
315 |
**Please try in jupyter notebook**
|
316 |
|
317 |
```python
|
318 |
# Import the Model
|
319 |
+
from whisper_medium_fp16_transformers import Model, load_audio, pad_or_trim
|
320 |
```
|
321 |
|
322 |
```python
|
|
|
330 |
|
331 |
```python
|
332 |
# Load Audio
|
333 |
+
audio = load_audio('whisper_medium_fp16_transformers/test.wav')
|
334 |
+
audio = pad_or_trim(audio)
|
335 |
```
|
336 |
|
337 |
```python
|
338 |
# Transcribe (First transcription takes time)
|
339 |
model.transcribe(audio)
|
340 |
```
|
341 |
+
|
342 |
## Credits
|
343 |
+
|
344 |
+
It is fp16 version of ``openai/whisper-medium``
|
__init__.py
CHANGED
@@ -1,5 +1,5 @@
|
|
1 |
from transformers import (
|
2 |
-
WhisperForConditionalGeneration, WhisperProcessor, WhisperConfig
|
3 |
)
|
4 |
import torch
|
5 |
import ffmpeg
|
@@ -13,6 +13,52 @@ SAMPLE_RATE = 16000
|
|
13 |
CHUNK_LENGTH = 30 # 30-second chunks
|
14 |
N_SAMPLES = CHUNK_LENGTH * SAMPLE_RATE # 480000 samples in a 30-second chunk
|
15 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
16 |
class Model:
|
17 |
def __init__(self,
|
18 |
model_name_or_path: str,
|
@@ -49,54 +95,8 @@ class Model:
|
|
49 |
|
50 |
print('dtype of model acc to config: ', self.config.torch_dtype)
|
51 |
print('dtype of loaded model: ', self.model.dtype)
|
52 |
-
|
53 |
-
|
54 |
-
# audio = whisper.load_audio('test.wav')
|
55 |
-
def load_audio(self, file: str, sr: int = SAMPLE_RATE, start_time: int = 0, dtype=np.float16):
|
56 |
-
try:
|
57 |
-
# This launches a subprocess to decode audio while down-mixing and resampling as necessary.
|
58 |
-
# Requires the ffmpeg CLI and `ffmpeg-python` package to be installed.
|
59 |
-
out, _ = (
|
60 |
-
ffmpeg.input(file, ss=start_time, threads=0)
|
61 |
-
.output("-", format="s16le", acodec="pcm_s16le", ac=1, ar=sr)
|
62 |
-
.run(cmd=["ffmpeg", "-nostdin"], capture_stdout=True, capture_stderr=True)
|
63 |
-
)
|
64 |
-
except ffmpeg.Error as e:
|
65 |
-
raise RuntimeError(f"Failed to load audio: {e.stderr.decode()}") from e
|
66 |
-
|
67 |
-
# return np.frombuffer(out, np.int16).flatten().astype(np.float32) / 32768.0
|
68 |
-
return np.frombuffer(out, np.int16).flatten().astype(dtype) / 32768.0
|
69 |
-
|
70 |
-
|
71 |
-
# audio = whisper.pad_or_trim(audio)
|
72 |
-
def _pad_or_trim(self, array, length: int = N_SAMPLES, *, axis: int = -1):
|
73 |
-
"""
|
74 |
-
Pad or trim the audio array to N_SAMPLES, as expected by the encoder.
|
75 |
-
"""
|
76 |
-
if torch.is_tensor(array):
|
77 |
-
if array.shape[axis] > length:
|
78 |
-
array = array.index_select(
|
79 |
-
dim=axis, index=torch.arange(length, device=array.device)
|
80 |
-
)
|
81 |
-
|
82 |
-
if array.shape[axis] < length:
|
83 |
-
pad_widths = [(0, 0)] * array.ndim
|
84 |
-
pad_widths[axis] = (0, length - array.shape[axis])
|
85 |
-
array = F.pad(array, [pad for sizes in pad_widths[::-1] for pad in sizes])
|
86 |
-
else:
|
87 |
-
if array.shape[axis] > length:
|
88 |
-
array = array.take(indices=range(length), axis=axis)
|
89 |
-
|
90 |
-
if array.shape[axis] < length:
|
91 |
-
pad_widths = [(0, 0)] * array.ndim
|
92 |
-
pad_widths[axis] = (0, length - array.shape[axis])
|
93 |
-
array = np.pad(array, pad_widths)
|
94 |
-
|
95 |
-
return array
|
96 |
|
97 |
-
def transcribe(self, audio
|
98 |
-
# audio = load_audio(audio)
|
99 |
-
audio = self._pad_or_trim(audio)
|
100 |
input_features = self.processor(audio, sampling_rate=SAMPLE_RATE, return_tensors="pt").input_features.half().to(self.DEVICE)
|
101 |
with torch.no_grad():
|
102 |
predicted_ids = self.model.generate(
|
@@ -109,5 +109,5 @@ class Model:
|
|
109 |
return_timestamps=True,
|
110 |
)
|
111 |
|
112 |
-
transcription = self.tokenizer.batch_decode(predicted_ids, skip_special_tokens=
|
113 |
return transcription.strip()
|
|
|
1 |
from transformers import (
|
2 |
+
WhisperForConditionalGeneration, WhisperProcessor, WhisperConfig,
|
3 |
)
|
4 |
import torch
|
5 |
import ffmpeg
|
|
|
13 |
CHUNK_LENGTH = 30 # 30-second chunks
|
14 |
N_SAMPLES = CHUNK_LENGTH * SAMPLE_RATE # 480000 samples in a 30-second chunk
|
15 |
|
16 |
+
# audio = whisper.load_audio('test.wav')
|
17 |
+
def load_audio(file: str, sr: int = SAMPLE_RATE, start_time: int = 0, dtype=np.float16):
|
18 |
+
"""
|
19 |
+
Load an audio file into a numpy array at the specified sampling rate.
|
20 |
+
"""
|
21 |
+
try:
|
22 |
+
# This launches a subprocess to decode audio while down-mixing and resampling as necessary.
|
23 |
+
# Requires the ffmpeg CLI and `ffmpeg-python` package to be installed.
|
24 |
+
out, _ = (
|
25 |
+
ffmpeg.input(file, ss=start_time, threads=0)
|
26 |
+
.output("-", format="s16le", acodec="pcm_s16le", ac=1, ar=sr)
|
27 |
+
.run(cmd=["ffmpeg", "-nostdin"], capture_stdout=True, capture_stderr=True)
|
28 |
+
)
|
29 |
+
except ffmpeg.Error as e:
|
30 |
+
raise RuntimeError(f"Failed to load audio: {e.stderr.decode()}") from e
|
31 |
+
|
32 |
+
# return np.frombuffer(out, np.int16).flatten().astype(np.float32) / 32768.0
|
33 |
+
return np.frombuffer(out, np.int16).flatten().astype(dtype) / 32768.0
|
34 |
+
|
35 |
+
|
36 |
+
# audio = whisper.pad_or_trim(audio)
|
37 |
+
def pad_or_trim(array, length: int = N_SAMPLES, *, axis: int = -1):
|
38 |
+
"""
|
39 |
+
Pad or trim the audio array to N_SAMPLES, as expected by the encoder.
|
40 |
+
"""
|
41 |
+
if torch.is_tensor(array):
|
42 |
+
if array.shape[axis] > length:
|
43 |
+
array = array.index_select(
|
44 |
+
dim=axis, index=torch.arange(length, device=array.device)
|
45 |
+
)
|
46 |
+
|
47 |
+
if array.shape[axis] < length:
|
48 |
+
pad_widths = [(0, 0)] * array.ndim
|
49 |
+
pad_widths[axis] = (0, length - array.shape[axis])
|
50 |
+
array = F.pad(array, [pad for sizes in pad_widths[::-1] for pad in sizes])
|
51 |
+
else:
|
52 |
+
if array.shape[axis] > length:
|
53 |
+
array = array.take(indices=range(length), axis=axis)
|
54 |
+
|
55 |
+
if array.shape[axis] < length:
|
56 |
+
pad_widths = [(0, 0)] * array.ndim
|
57 |
+
pad_widths[axis] = (0, length - array.shape[axis])
|
58 |
+
array = np.pad(array, pad_widths)
|
59 |
+
|
60 |
+
return array
|
61 |
+
|
62 |
class Model:
|
63 |
def __init__(self,
|
64 |
model_name_or_path: str,
|
|
|
95 |
|
96 |
print('dtype of model acc to config: ', self.config.torch_dtype)
|
97 |
print('dtype of loaded model: ', self.model.dtype)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
98 |
|
99 |
+
def transcribe(self, audio, language: str = "english", skip_special_tokens: bool = True) -> str:
|
|
|
|
|
100 |
input_features = self.processor(audio, sampling_rate=SAMPLE_RATE, return_tensors="pt").input_features.half().to(self.DEVICE)
|
101 |
with torch.no_grad():
|
102 |
predicted_ids = self.model.generate(
|
|
|
109 |
return_timestamps=True,
|
110 |
)
|
111 |
|
112 |
+
transcription = self.tokenizer.batch_decode(predicted_ids, skip_special_tokens=skip_special_tokens)[0]
|
113 |
return transcription.strip()
|