Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Update faster-whisper based on SYSTRAN fork #7

Open
wants to merge 55 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
55 commits
Select commit Hold shift + click to select a range
a67e0e4
Add support for distil-large-v3 (#755)
sanchit-gandhi Mar 26, 2024
e0c3a9e
Update project github link to SYSTRAN (#746)
trungkienbkhn Mar 27, 2024
8ae82c8
Bugfix: code breaks if audio is empty (#768)
Purfview Apr 2, 2024
b024972
Foolproof: Disable VAD if clip_timestamps is in use (#769)
Purfview Apr 2, 2024
91c8307
make faster_whisper.assets as a valid python package to distribute (#…
otakutyrant Apr 2, 2024
3d1de60
CUDA version and updated installation instructions (#785)
sidharthrajaram May 4, 2024
46080e5
Loosening tokenizers version constraint (#804)
Keating950 May 4, 2024
847fec4
Feature/add hotwords (#731)
jax-explorer May 4, 2024
6eec077
Add benchmarking logic for memory, wer and speed (#773)
trungkienbkhn May 4, 2024
8d5e6d5
Support initializing more whisper model args (#807)
trungkienbkhn May 4, 2024
49a80eb
Clarify documentation for hotwords (#817)
Keating950 May 6, 2024
e11d585
Allow av to include version 12. (#819)
ddorian May 6, 2024
2f6913e
Bump version to 1.0.2 (#816)
trungkienbkhn May 6, 2024
2036d12
Add Dockerfile example (#828)
trungkienbkhn May 13, 2024
a1c3583
Update README.md (#841)
peterk May 17, 2024
4acdb5c
Fix #839 incorrect clip_timestamps being used in model (#842)
nonnoxer May 17, 2024
f53be1e
Add distil models to WhisperModel init and download_model docstrings …
Napuh May 20, 2024
65551c0
Docker file improvements (#848)
fedirz May 20, 2024
bced5f0
docs: add 'faster-whisper-server' community integration (#861)
fedirz Jun 5, 2024
8d400e9
Upgrade to Silero-Vad V5 (#884)
hoonlight Jul 1, 2024
8862bee
Improve language detection when using clip_timestamps (#867)
ben91lin Jul 1, 2024
c22db51
Bump version to 1.0.3 (#887)
trungkienbkhn Jul 1, 2024
1195359
Filter out non_speech_tokens in suppressed tokens (#898)
jordimas Jul 5, 2024
fbcf58b
Fix language detection with non-speech audio (#895)
trungkienbkhn Jul 5, 2024
eb83902
New PR for Faster Whisper: Batching Support, Speed Boosts, and Qualit…
Jiltseb Jul 18, 2024
83a368e
Make vad-related parameters configurable for batched inference. (#923)
zh-plus Jul 24, 2024
d57c5b4
Remove the usage of `transformers.pipeline` from `BatchedInferencePip…
MahmoudAshraf97 Jul 27, 2024
42b8681
revert back to using PyAV instead of `torchaudio` (#961)
MahmoudAshraf97 Oct 23, 2024
574e256
Update Dockerfile to ensure compatibility with `CT2==4.5.0`
MahmoudAshraf97 Oct 23, 2024
2dbca5e
Use Silero VAD in Batched Mode (#936)
MahmoudAshraf97 Oct 24, 2024
b2da055
Add support for `turbo` model (#1090)
MahmoudAshraf97 Oct 25, 2024
c2a1da1
typo: trubo -> turbo (#1092)
heimoshuiyu Oct 25, 2024
2386843
Use correct features padding for encoder input (#1101)
MahmoudAshraf97 Oct 29, 2024
f978fa2
Revert CPU default threads to 4 (#965)
ozancaglayan Oct 30, 2024
814472f
Revert CPU default threads to 0
MahmoudAshraf97 Oct 30, 2024
203dddb
replace `NamedTuple` with `dataclass` (#1105)
MahmoudAshraf97 Nov 5, 2024
fb65cd3
Update cuda instructions in readme (#1125)
MahmoudAshraf97 Nov 12, 2024
c2bf036
change `language_detection_threshold` default value (#1134)
MahmoudAshraf97 Nov 13, 2024
8f01aee
Update WhisperModel documentation to list all available models (#1137)
MahmoudAshraf97 Nov 13, 2024
3e0ba86
Remove `torch` dependency, Faster numpy Feature extraction (#1106)
MahmoudAshraf97 Nov 14, 2024
85e61ea
Add progress bar to `WhisperModel.transcribe` (#1138)
MahmoudAshraf97 Nov 14, 2024
53bbe54
fix: Use correct `seek` value in output, fix word timestamps when the…
heimoshuiyu Nov 15, 2024
a6f8fba
Refactor of language detection functions (#1146)
MahmoudAshraf97 Nov 16, 2024
be9fb36
Cleanup of `BatchedInferencePipeline` (#1135)
MahmoudAshraf97 Nov 17, 2024
bcd8ce0
refactor `multilingual` option (#1148)
MahmoudAshraf97 Nov 19, 2024
f830c6f
Fix `list index out of range` in word timestamps (#1157)
MahmoudAshraf97 Nov 20, 2024
491852e
Add new tests (#1158)
MahmoudAshraf97 Nov 20, 2024
9c8ef76
use `jiwer` instead of `evaluate` in benchmarks (#1159)
MahmoudAshraf97 Nov 20, 2024
08f6900
remove `log_prob_low_threshold` (#1160)
MahmoudAshraf97 Nov 20, 2024
97a4785
Bump version to 1.1.0 and update benchmarks (#1161)
MahmoudAshraf97 Nov 21, 2024
22a5238
Upgrade CI to 3.9 and drop Python 3.8 support(#1184)
MahmoudAshraf97 Dec 1, 2024
8327d8c
Brings back original VAD parameters naming (#1181)
Purfview Dec 1, 2024
f32c0e8
Make batched suppress_tokens behaviour same as in sequential (#1194)
Purfview Dec 11, 2024
b568fae
Add Open-dubbing into community projects (#1034)
jordimas Dec 12, 2024
1b24f28
Reduce VAD memory usage (#1198)
Purfview Dec 12, 2024
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
24 changes: 12 additions & 12 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -15,12 +15,12 @@ jobs:
runs-on: ubuntu-latest

steps:
- uses: actions/checkout@v3
- uses: actions/checkout@v4

- name: Set up Python 3.8
uses: actions/setup-python@v4
- name: Set up Python 3.9
uses: actions/setup-python@v5
with:
python-version: 3.8
python-version: 3.9

- name: Install module
run: |
Expand All @@ -45,12 +45,12 @@ jobs:
runs-on: ubuntu-latest

steps:
- uses: actions/checkout@v3
- uses: actions/checkout@v4

- name: Set up Python 3.8
uses: actions/setup-python@v4
- name: Set up Python 3.9
uses: actions/setup-python@v5
with:
python-version: 3.8
python-version: 3.9

- name: Install module
run: |
Expand All @@ -67,12 +67,12 @@ jobs:
needs: [check-code-format, run-tests]

steps:
- uses: actions/checkout@v3
- uses: actions/checkout@v4

- name: Set up Python 3.8
uses: actions/setup-python@v4
- name: Set up Python 3.9
uses: actions/setup-python@v5
with:
python-version: 3.8
python-version: 3.9

- name: Install dependencies
run: |
Expand Down
2 changes: 1 addition & 1 deletion CONTRIBUTING.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ Contributions are welcome! Here are some pointers to help you install the librar
We recommend installing the module in editable mode with the `dev` extra requirements:

```bash
git clone https://github.com/guillaumekln/faster-whisper.git
git clone https://github.com/SYSTRAN/faster-whisper.git
cd faster-whisper/
pip install -e .[dev]
```
Expand Down
2 changes: 1 addition & 1 deletion LICENSE
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
MIT License

Copyright (c) 2023 Guillaume Klein
Copyright (c) 2023 SYSTRAN

Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
Expand Down
3 changes: 2 additions & 1 deletion MANIFEST.in
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
include faster_whisper/assets/silero_vad.onnx
include faster_whisper/assets/silero_encoder_v5.onnx
include faster_whisper/assets/silero_decoder_v5.onnx
include requirements.txt
include requirements.conversion.txt
136 changes: 78 additions & 58 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
[![CI](https://github.com/guillaumekln/faster-whisper/workflows/CI/badge.svg)](https://github.com/guillaumekln/faster-whisper/actions?query=workflow%3ACI) [![PyPI version](https://badge.fury.io/py/faster-whisper.svg)](https://badge.fury.io/py/faster-whisper)
[![CI](https://github.com/SYSTRAN/faster-whisper/workflows/CI/badge.svg)](https://github.com/SYSTRAN/faster-whisper/actions?query=workflow%3ACI) [![PyPI version](https://badge.fury.io/py/faster-whisper.svg)](https://badge.fury.io/py/faster-whisper)

# Faster Whisper transcription with CTranslate2

Expand All @@ -12,87 +12,81 @@ This implementation is up to 4 times faster than [openai/whisper](https://github

For reference, here's the time and memory usage that are required to transcribe [**13 minutes**](https://www.youtube.com/watch?v=0u7tTptBo9I) of audio using different implementations:

* [openai/whisper](https://github.com/openai/whisper)@[6dea21fd](https://github.com/openai/whisper/commit/6dea21fd7f7253bfe450f1e2512a0fe47ee2d258)
* [whisper.cpp](https://github.com/ggerganov/whisper.cpp)@[3b010f9](https://github.com/ggerganov/whisper.cpp/commit/3b010f9bed9a6068609e9faf52383aea792b0362)
* [faster-whisper](https://github.com/guillaumekln/faster-whisper)@[cce6b53e](https://github.com/guillaumekln/faster-whisper/commit/cce6b53e4554f71172dad188c45f10fb100f6e3e)
* [openai/whisper](https://github.com/openai/whisper)@[v20240930](https://github.com/openai/whisper/tree/v20240930)
* [whisper.cpp](https://github.com/ggerganov/whisper.cpp)@[v1.7.2](https://github.com/ggerganov/whisper.cpp/tree/v1.7.2)
* [transformers](https://github.com/huggingface/transformers)@[v4.46.3](https://github.com/huggingface/transformers/tree/v4.46.3)
* [faster-whisper](https://github.com/SYSTRAN/faster-whisper)@[v1.1.0](https://github.com/SYSTRAN/faster-whisper/tree/v1.1.0)

### Large-v2 model on GPU

| Implementation | Precision | Beam size | Time | Max. GPU memory | Max. CPU memory |
| --- | --- | --- | --- | --- | --- |
| openai/whisper | fp16 | 5 | 4m30s | 11325MB | 9439MB |
| faster-whisper | fp16 | 5 | 54s | 4755MB | 3244MB |
| faster-whisper | int8 | 5 | 59s | 3091MB | 3117MB |

*Executed with CUDA 11.7.1 on a NVIDIA Tesla V100S.*
| Implementation | Precision | Beam size | Time | VRAM Usage |
| --- | --- | --- | --- | --- |
| openai/whisper | fp16 | 5 | 2m23s | 4708MB |
| whisper.cpp (Flash Attention) | fp16 | 5 | 1m05s | 4127MB |
| transformers (SDPA)[^1] | fp16 | 5 | 1m52s | 4960MB |
| faster-whisper | fp16 | 5 | 1m03s | 4525MB |
| faster-whisper (`batch_size=8`) | fp16 | 5 | 17s | 6090MB |
| faster-whisper | int8 | 5 | 59s | 2926MB |
| faster-whisper (`batch_size=8`) | int8 | 5 | 16s | 4500MB |

### Small model on CPU
### distil-whisper-large-v3 model on GPU

| Implementation | Precision | Beam size | Time | Max. memory |
| Implementation | Precision | Beam size | Time | YT Commons WER |
| --- | --- | --- | --- | --- |
| openai/whisper | fp32 | 5 | 10m31s | 3101MB |
| whisper.cpp | fp32 | 5 | 17m42s | 1581MB |
| whisper.cpp | fp16 | 5 | 12m39s | 873MB |
| faster-whisper | fp32 | 5 | 2m44s | 1675MB |
| faster-whisper | int8 | 5 | 2m04s | 995MB |
| transformers (SDPA) (`batch_size=16`) | fp16 | 5 | 46m12s | 14.801 |
| faster-whisper (`batch_size=16`) | fp16 | 5 | 25m50s | 13.527 |

*Executed with 8 threads on a Intel(R) Xeon(R) Gold 6226R.*
*GPU Benchmarks are Executed with CUDA 12.4 on a NVIDIA RTX 3070 Ti 8GB.*
[^1]: transformers OOM for any batch size > 1

### Small model on CPU

### Distil-whisper

| Implementation | Precision | Beam size | Time | Gigaspeech WER |
| Implementation | Precision | Beam size | Time | RAM Usage |
| --- | --- | --- | --- | --- |
| distil-whisper/distil-large-v2 | fp16 | 4 |- | 10.36 |
| [faster-distil-large-v2](https://huggingface.co/Systran/faster-distil-whisper-large-v2) | fp16 | 5 | - | 10.28 |
| distil-whisper/distil-medium.en | fp16 | 4 | - | 11.21 |
| [faster-distil-medium.en](https://huggingface.co/Systran/faster-distil-whisper-medium.en) | fp16 | 5 | - | 11.21 |
| openai/whisper | fp32 | 5 | 6m58s | 2335MB |
| whisper.cpp | fp32 | 5 | 2m05s | 1049MB |
| whisper.cpp (OpenVINO) | fp32 | 5 | 1m45s | 1642MB |
| faster-whisper | fp32 | 5 | 2m37s | 2257MB |
| faster-whisper (`batch_size=8`) | fp32 | 5 | 1m06s | 4230MB |
| faster-whisper | int8 | 5 | 1m42s | 1477MB |
| faster-whisper (`batch_size=8`) | int8 | 5 | 51s | 3608MB |

*Executed with CUDA 11.4 on a NVIDIA 3090.*
*Executed with 8 threads on an Intel Core i7-12700K.*

<details>
<summary>testing details (click to expand)</summary>

For `distil-whisper/distil-large-v2`, the WER is tested with code sample from [link](https://huggingface.co/distil-whisper/distil-large-v2#evaluation). for `faster-distil-whisper`, the WER is tested with setting:
```python
from faster_whisper import WhisperModel

model_size = "distil-large-v2"
# model_size = "distil-medium.en"
# Run on GPU with FP16
model = WhisperModel(model_size, device="cuda", compute_type="float16")
segments, info = model.transcribe("audio.mp3", beam_size=5, language="en")
```
</details>

## Requirements

* Python 3.8 or greater
* Python 3.9 or greater

Unlike openai-whisper, FFmpeg does **not** need to be installed on the system. The audio is decoded with the Python library [PyAV](https://github.com/PyAV-Org/PyAV) which bundles the FFmpeg libraries in its package.

### GPU

GPU execution requires the following NVIDIA libraries to be installed:

* [cuBLAS for CUDA 11](https://developer.nvidia.com/cublas)
* [cuDNN 8 for CUDA 11](https://developer.nvidia.com/cudnn)
* [cuBLAS for CUDA 12](https://developer.nvidia.com/cublas)
* [cuDNN 9 for CUDA 12](https://developer.nvidia.com/cudnn)

**Note**: The latest versions of `ctranslate2` only support CUDA 12 and cuDNN 9. For CUDA 11 and cuDNN 8, the current workaround is downgrading to the `3.24.0` version of `ctranslate2`, for CUDA 12 and cuDNN 8, downgrade to the `4.4.0` version of `ctranslate2`, (This can be done with `pip install --force-reinstall ctranslate2==4.4.0` or specifying the version in a `requirements.txt`).

There are multiple ways to install these libraries. The recommended way is described in the official NVIDIA documentation, but we also suggest other installation methods below.
There are multiple ways to install the NVIDIA libraries mentioned above. The recommended way is described in the official NVIDIA documentation, but we also suggest other installation methods below.

<details>
<summary>Other installation methods (click to expand)</summary>


**Note:** For all these methods below, keep in mind the above note regarding CUDA versions. Depending on your setup, you may need to install the _CUDA 11_ versions of libraries that correspond to the CUDA 12 libraries listed in the instructions below.

#### Use Docker

The libraries are installed in this official NVIDIA Docker image: `nvidia/cuda:11.8.0-cudnn8-runtime-ubuntu22.04`.
The libraries (cuBLAS, cuDNN) are installed in this official NVIDIA CUDA Docker images: `nvidia/cuda:12.3.2-cudnn9-runtime-ubuntu22.04`.

#### Install with `pip` (Linux only)

On Linux these libraries can be installed with `pip`. Note that `LD_LIBRARY_PATH` must be set before launching Python.

```bash
pip install nvidia-cublas-cu11 nvidia-cudnn-cu11
pip install nvidia-cublas-cu12 nvidia-cudnn-cu12==9.*

export LD_LIBRARY_PATH=`python3 -c 'import os; import nvidia.cublas.lib; import nvidia.cudnn.lib; print(os.path.dirname(nvidia.cublas.lib.__file__) + ":" + os.path.dirname(nvidia.cudnn.lib.__file__))'`
```
Expand All @@ -117,13 +111,13 @@ pip install faster-whisper
### Install the master branch

```bash
pip install --force-reinstall "faster-whisper @ https://github.com/guillaumekln/faster-whisper/archive/refs/heads/master.tar.gz"
pip install --force-reinstall "faster-whisper @ https://github.com/SYSTRAN/faster-whisper/archive/refs/heads/master.tar.gz"
```

### Install a specific commit

```bash
pip install --force-reinstall "faster-whisper @ https://github.com/guillaumekln/faster-whisper/archive/a4f1cc8f11433e454c3934442b5e1a4ed5e865c3.tar.gz"
pip install --force-reinstall "faster-whisper @ https://github.com/SYSTRAN/faster-whisper/archive/a4f1cc8f11433e454c3934442b5e1a4ed5e865c3.tar.gz"
```

</details>
Expand Down Expand Up @@ -159,18 +153,40 @@ for segment in segments:
segments, _ = model.transcribe("audio.mp3")
segments = list(segments) # The transcription will actually run here.
```
### Faster-distil-whisper
For usage of `faster-distil-whisper`, please refer to: https://github.com/guillaumekln/faster-whisper/issues/533

### Batched Transcription
The following code snippet illustrates how to run batched transcription on an example audio file. `BatchedInferencePipeline.transcribe` is a drop-in replacement for `WhisperModel.transcribe`

```python
from faster_whisper import WhisperModel, BatchedInferencePipeline

model = WhisperModel("turbo", device="cuda", compute_type="float16")
batched_model = BatchedInferencePipeline(model=model)
segments, info = batched_model.transcribe("audio.mp3", batch_size=16)

for segment in segments:
print("[%.2fs -> %.2fs] %s" % (segment.start, segment.end, segment.text))
```

### Faster Distil-Whisper

The Distil-Whisper checkpoints are compatible with the Faster-Whisper package. In particular, the latest [distil-large-v3](https://huggingface.co/distil-whisper/distil-large-v3)
checkpoint is intrinsically designed to work with the Faster-Whisper transcription algorithm. The following code snippet
demonstrates how to run inference with distil-large-v3 on a specified audio file:

```python
model_size = "distil-large-v2"
# model_size = "distil-medium.en"
from faster_whisper import WhisperModel

model_size = "distil-large-v3"

model = WhisperModel(model_size, device="cuda", compute_type="float16")
segments, info = model.transcribe("audio.mp3", beam_size=5,
language="en", max_new_tokens=128, condition_on_previous_text=False)
segments, info = model.transcribe("audio.mp3", beam_size=5, language="en", condition_on_previous_text=False)

for segment in segments:
print("[%.2fs -> %.2fs] %s" % (segment.start, segment.end, segment.text))
```
NOTE: Empirically, `condition_on_previous_text=True` will degrade the performance of `faster-distil-whisper` for long audio. Degradation on the first chunk was observed with `initial_prompt` too.

For more information about the distil-large-v3 model, refer to the original [model card](https://huggingface.co/distil-whisper/distil-large-v3).

### Word-level timestamps

Expand All @@ -190,7 +206,7 @@ The library integrates the [Silero VAD](https://github.com/snakers4/silero-vad)
segments, _ = model.transcribe("audio.mp3", vad_filter=True)
```

The default behavior is conservative and only removes silence longer than 2 seconds. See the available VAD parameters and default values in the [source code](https://github.com/guillaumekln/faster-whisper/blob/master/faster_whisper/vad.py). They can be customized with the dictionary argument `vad_parameters`:
The default behavior is conservative and only removes silence longer than 2 seconds. See the available VAD parameters and default values in the [source code](https://github.com/SYSTRAN/faster-whisper/blob/master/faster_whisper/vad.py). They can be customized with the dictionary argument `vad_parameters`:

```python
segments, _ = model.transcribe(
Expand All @@ -199,6 +215,7 @@ segments, _ = model.transcribe(
vad_parameters=dict(min_silence_duration_ms=500),
)
```
Vad filter is enabled by default for batched transcription.

### Logging

Expand All @@ -213,13 +230,14 @@ logging.getLogger("faster_whisper").setLevel(logging.DEBUG)

### Going further

See more model and transcription options in the [`WhisperModel`](https://github.com/guillaumekln/faster-whisper/blob/master/faster_whisper/transcribe.py) class implementation.
See more model and transcription options in the [`WhisperModel`](https://github.com/SYSTRAN/faster-whisper/blob/master/faster_whisper/transcribe.py) class implementation.

## Community integrations

Here is a non exhaustive list of open-source projects using faster-whisper. Feel free to add your project to the list!


* [faster-whisper-server](https://github.com/fedirz/faster-whisper-server) is an OpenAI compatible server using `faster-whisper`. It's easily deployable with Docker, works with OpenAI SDKs/CLI, supports streaming, and live transcription.
* [WhisperX](https://github.com/m-bain/whisperX) is an award-winning Python library that offers speaker diarization and accurate word-level timestamps using wav2vec2 alignment
* [whisper-ctranslate2](https://github.com/Softcatala/whisper-ctranslate2) is a command line client based on faster-whisper and compatible with the original client from openai/whisper.
* [whisper-diarize](https://github.com/MahmoudAshraf97/whisper-diarization) is a speaker diarization tool that is based on faster-whisper and NVIDIA NeMo.
Expand All @@ -231,6 +249,7 @@ Here is a non exhaustive list of open-source projects using faster-whisper. Feel
* [Whisper-Streaming](https://github.com/ufal/whisper_streaming) implements real-time mode for offline Whisper-like speech-to-text models with faster-whisper as the most recommended back-end. It implements a streaming policy with self-adaptive latency based on the actual source complexity, and demonstrates the state of the art.
* [WhisperLive](https://github.com/collabora/WhisperLive) is a nearly-live implementation of OpenAI's Whisper which uses faster-whisper as the backend to transcribe audio in real-time.
* [Faster-Whisper-Transcriber](https://github.com/BBC-Esq/ctranslate2-faster-whisper-transcriber) is a simple but reliable voice transcriber that provides a user-friendly interface.
* [Open-dubbing](https://github.com/softcatala/open-dubbing) is open dubbing is an AI dubbing system which uses machine learning models to automatically translate and synchronize audio dialogue into different languages.

## Model conversion

Expand Down Expand Up @@ -269,6 +288,7 @@ model = faster_whisper.WhisperModel("username/whisper-large-v3-ct2")
If you are comparing the performance against other Whisper implementations, you should make sure to run the comparison with similar settings. In particular:

* Verify that the same transcription options are used, especially the same beam size. For example in openai/whisper, `model.transcribe` uses a default beam size of 1 but here we use a default beam size of 5.
* Transcription speed is closely affected by the number of words in the transcript, so ensure that other implementations have a similar WER (Word Error Rate) to this one.
* When running on CPU, make sure to set the same number of threads. Many frameworks will read the environment variable `OMP_NUM_THREADS`, which can be set when running your script:

```bash
Expand Down
Binary file added benchmark/benchmark.m4a
Binary file not shown.
Loading