senko 0.1.0rc1__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Potentially problematic release.
This version of senko might be problematic. Click here for more details.
- senko-0.1.0rc1/.github/FUNDING.yml +15 -0
- senko-0.1.0rc1/.gitignore +16 -0
- senko-0.1.0rc1/.python-version +1 -0
- senko-0.1.0rc1/BENCHMARK.md +10 -0
- senko-0.1.0rc1/CMakeLists.txt +18 -0
- senko-0.1.0rc1/DEV_SETUP.md +46 -0
- senko-0.1.0rc1/DOCS.md +97 -0
- senko-0.1.0rc1/LICENSE +21 -0
- senko-0.1.0rc1/PKG-INFO +162 -0
- senko-0.1.0rc1/README.md +104 -0
- senko-0.1.0rc1/THIRD_PARTY_LICENSES +231 -0
- senko-0.1.0rc1/examples/diarize.py +71 -0
- senko-0.1.0rc1/models/README.md +4 -0
- senko-0.1.0rc1/models/camplusplus_traced_cuda_optimized.pt +0 -0
- senko-0.1.0rc1/models/camplusplus_traced_mps_optimized.pt +0 -0
- senko-0.1.0rc1/models/pyannote_segmentation_3.0/config.yaml +19 -0
- senko-0.1.0rc1/models/pyannote_segmentation_3.0/pytorch_model.bin +0 -0
- senko-0.1.0rc1/models/speech_campplus_sv_zh_en_16k-common_advanced/campplus_cn_en_common.pt +0 -0
- senko-0.1.0rc1/pyproject.toml +150 -0
- senko-0.1.0rc1/senko/__init__.py +3 -0
- senko-0.1.0rc1/senko/camplusplus.py +210 -0
- senko-0.1.0rc1/senko/cluster/__init__.py +0 -0
- senko-0.1.0rc1/senko/cluster/cluster_cpu.py +205 -0
- senko-0.1.0rc1/senko/cluster/cluster_gpu.py +205 -0
- senko-0.1.0rc1/senko/cluster/conf/spectral.yaml +11 -0
- senko-0.1.0rc1/senko/cluster/conf/umap_hdbscan.yaml +11 -0
- senko-0.1.0rc1/senko/colors.py +118 -0
- senko-0.1.0rc1/senko/diarizer.py +465 -0
- senko-0.1.0rc1/senko/fbank_extractor/.gitignore +1 -0
- senko-0.1.0rc1/senko/fbank_extractor/CMakeLists.txt +39 -0
- senko-0.1.0rc1/senko/fbank_extractor/cpp/fbank_extractor.cpp +125 -0
- senko-0.1.0rc1/senko/fbank_extractor/cpp/fbank_extractor.h +18 -0
- senko-0.1.0rc1/senko/fbank_extractor/cpp/fbank_wrapper.cpp +74 -0
- senko-0.1.0rc1/senko/fbank_extractor/cpp/feature/fbank_computer.cpp +87 -0
- senko-0.1.0rc1/senko/fbank_extractor/cpp/feature/fbank_computer.h +31 -0
- senko-0.1.0rc1/senko/fbank_extractor/cpp/feature/fbank_options.h +48 -0
- senko-0.1.0rc1/senko/fbank_extractor/cpp/feature/fbank_utils.cpp +60 -0
- senko-0.1.0rc1/senko/fbank_extractor/cpp/feature/fbank_utils.h +18 -0
- senko-0.1.0rc1/senko/fbank_extractor/cpp/feature/frame_extraction_options.cpp +23 -0
- senko-0.1.0rc1/senko/fbank_extractor/cpp/feature/frame_extraction_options.h +61 -0
- senko-0.1.0rc1/senko/fbank_extractor/cpp/feature/frame_processor.cpp +76 -0
- senko-0.1.0rc1/senko/fbank_extractor/cpp/feature/frame_processor.h +30 -0
- senko-0.1.0rc1/senko/fbank_extractor/cpp/feature/melbank_options.h +32 -0
- senko-0.1.0rc1/senko/fbank_extractor/cpp/feature/melbank_processor.cpp +97 -0
- senko-0.1.0rc1/senko/fbank_extractor/cpp/feature/melbank_processor.h +33 -0
- senko-0.1.0rc1/senko/fbank_extractor/cpp/feature_computer.cpp +60 -0
- senko-0.1.0rc1/senko/fbank_extractor/cpp/feature_computer.h +19 -0
- senko-0.1.0rc1/senko/fbank_extractor/cpp/wav.h +238 -0
- senko-0.1.0rc1/senko/fbank_extractor/include/fbank_interface.h +35 -0
- senko-0.1.0rc1/senko/paths.py +50 -0
- senko-0.1.0rc1/senko/utils.py +74 -0
- senko-0.1.0rc1/tracing/.gitignore +1 -0
- senko-0.1.0rc1/tracing/README.md +25 -0
- senko-0.1.0rc1/tracing/optimize.py +124 -0
- senko-0.1.0rc1/tracing/trace.py +119 -0
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
# These are supported funding model platforms
|
|
2
|
+
|
|
3
|
+
github: [hamzaq2000] # Replace with up to 4 GitHub Sponsors-enabled usernames e.g., [user1, user2]
|
|
4
|
+
patreon: # Replace with a single Patreon username
|
|
5
|
+
open_collective: # Replace with a single Open Collective username
|
|
6
|
+
ko_fi: # Replace with a single Ko-fi username
|
|
7
|
+
tidelift: # Replace with a single Tidelift platform-name/package-name e.g., npm/babel
|
|
8
|
+
community_bridge: # Replace with a single Community Bridge project-name e.g., cloud-foundry
|
|
9
|
+
liberapay: # Replace with a single Liberapay username
|
|
10
|
+
issuehunt: # Replace with a single IssueHunt username
|
|
11
|
+
lfx_crowdfunding: # Replace with a single LFX Crowdfunding project-name e.g., cloud-foundry
|
|
12
|
+
polar: # Replace with a single Polar username
|
|
13
|
+
buy_me_a_coffee: # Replace with a single Buy Me a Coffee username
|
|
14
|
+
thanks_dev: # Replace with a single thanks.dev username
|
|
15
|
+
custom: # Replace with up to 4 custom sponsorship URLs e.g., ['link1', 'link2']
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
3.11.13
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
# Benchmarking
|
|
2
|
+
To get the figures listed in the README for time taken to diarize 1 hour of audio on an RTX 4090 + Ryzen 9 7950X machine and an M3 MacBook Air, as well as the CPU performance figure in the FAQ section using a Ryzen 9 9950X, the audio from [this](https://www.youtube.com/watch?v=GT_sXIUJPUo) video was used. It was downloaded and decompressed into a 16 KHz mono wav file in the following manner.
|
|
3
|
+
```
|
|
4
|
+
yt-dlp -f bestaudio GT_sXIUJPUo -o "temp_GT_sXIUJPUo.%(ext)s"
|
|
5
|
+
ffmpeg -i "temp_GT_sXIUJPUo."* -acodec pcm_s16le -ac 1 -ar 16000 cowen.wav
|
|
6
|
+
rm "temp_GT_sXIUJPUo."*
|
|
7
|
+
```
|
|
8
|
+
Then the `examples/diarize.py` script was run, and `cowen.wav` was entered after the warmup.
|
|
9
|
+
|
|
10
|
+
For the sake of reproducibility, the exact `cowen.wav` file used can be downloaded from [here](https://www.dropbox.com/scl/fi/77kgl6luhmsm6k30x1muf/cowen.wav?rlkey=n6goatgi3pjpgn7glna654f2a&dl=1).
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
cmake_minimum_required(VERSION 3.18)
|
|
2
|
+
project(senko LANGUAGES CXX)
|
|
3
|
+
|
|
4
|
+
# Set C++ standard
|
|
5
|
+
set(CMAKE_CXX_STANDARD 20)
|
|
6
|
+
set(CMAKE_CXX_STANDARD_REQUIRED ON)
|
|
7
|
+
|
|
8
|
+
# Find Python
|
|
9
|
+
find_package(Python COMPONENTS Interpreter Development.Module REQUIRED)
|
|
10
|
+
|
|
11
|
+
# Add the fbank_extractor subdirectory. This is where the C++ library is defined, built, and its installation is configured
|
|
12
|
+
add_subdirectory(senko/fbank_extractor)
|
|
13
|
+
|
|
14
|
+
# Only install in wheel builds (skip editable and sdist)
|
|
15
|
+
if(SKBUILD_STATE STREQUAL "wheel")
|
|
16
|
+
install(TARGETS fbank_extractor DESTINATION senko)
|
|
17
|
+
install(DIRECTORY models DESTINATION senko)
|
|
18
|
+
endif()
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
# Senko Development Setup Guide
|
|
2
|
+
## Pre-requisites
|
|
3
|
+
- `clang` if on Linux or WSL
|
|
4
|
+
- `sudo apt update; sudo apt install clang`
|
|
5
|
+
- `git`
|
|
6
|
+
- `sudo apt update; sudo apt install git` on Linux/WSL
|
|
7
|
+
- On macOS, should already have it if you have the Xcode Command Line Tools installed
|
|
8
|
+
- [`uv`](https://docs.astral.sh/uv/#installation)
|
|
9
|
+
|
|
10
|
+
## Development Setup Steps
|
|
11
|
+
First create and activate a Python virtual environment
|
|
12
|
+
```
|
|
13
|
+
uv venv --python 3.11.13 .venv
|
|
14
|
+
source .venv/bin/activate
|
|
15
|
+
```
|
|
16
|
+
Clone the Senko repository
|
|
17
|
+
```
|
|
18
|
+
git clone https://github.com/narcotic-sh/senko.git
|
|
19
|
+
```
|
|
20
|
+
Then install using editable mode (`-e`)
|
|
21
|
+
```bash
|
|
22
|
+
# For NVIDIA GPUs with CUDA compute capability >= 7.5 (~GTX 16 series and newer)
|
|
23
|
+
uv pip install -e "/path/to/cloned/senko[nvidia]"
|
|
24
|
+
|
|
25
|
+
# For NVIDIA GPUs with CUDA compute capability < 7.5 (~GTX 10 series and older)
|
|
26
|
+
uv pip install -e "/path/to/cloned/senko[nvidia-old]"
|
|
27
|
+
|
|
28
|
+
# For Macs (mps) and cpu execution on all other platforms
|
|
29
|
+
uv pip install -e "/path/to/cloned/senko"
|
|
30
|
+
```
|
|
31
|
+
For NVIDIA, make sure the installed driver is CUDA 12 capable (should see `CUDA Version: 12.x` in the top right of `nvidia-smi`)
|
|
32
|
+
|
|
33
|
+
Now you can modify the Senko code in the cloned repository folder; changes will be reflected immediately.
|
|
34
|
+
|
|
35
|
+
Use Senko like normal in scripts:
|
|
36
|
+
```python
|
|
37
|
+
from senko import Diarizer
|
|
38
|
+
import json
|
|
39
|
+
|
|
40
|
+
diarizer = Diarizer(torch_device='auto', warmup=True, quiet=False)
|
|
41
|
+
result = diarizer.diarize('audio.wav', generate_colors=False) # 16 KHz mono wav
|
|
42
|
+
|
|
43
|
+
with open('./audio_diarized.json', 'w') as f:
|
|
44
|
+
json.dump(result["merged_segments"], f, indent=2)
|
|
45
|
+
```
|
|
46
|
+
Also see `examples/diarize.py`.
|
senko-0.1.0rc1/DOCS.md
ADDED
|
@@ -0,0 +1,97 @@
|
|
|
1
|
+
# Senko Documentation
|
|
2
|
+
|
|
3
|
+
### `Diarizer`
|
|
4
|
+
```python
|
|
5
|
+
from senko import Diarizer
|
|
6
|
+
diarizer = Diarizer(torch_device='auto', warmup=True, quiet=True)
|
|
7
|
+
```
|
|
8
|
+
- `torch_device`: Device to use for PyTorch operations (`auto`, `cuda`, `mps`, `cpu`)
|
|
9
|
+
- `auto` automatically selects `cuda` if available, if not, then `mps` (Apple Silicon), if not, then `cpu`
|
|
10
|
+
- `warmup`: Warm up CAM++ embeddings model and clustering objects during initialization
|
|
11
|
+
- If warmup is not done, the first few runs of the pipeline will be a bit slower
|
|
12
|
+
- `quiet`: Suppress progress updates and all other output to stdout
|
|
13
|
+
|
|
14
|
+
### `diarize()`
|
|
15
|
+
```python
|
|
16
|
+
result_data = diarizer.diarize(wav_path='audio.wav', generate_colors=False)
|
|
17
|
+
```
|
|
18
|
+
#### Parameters
|
|
19
|
+
- `wav_path`: Path to the audio file (16 KHz mono WAV format)
|
|
20
|
+
- `generate_colors`: Whether to generate speaker color sets for visualization
|
|
21
|
+
|
|
22
|
+
#### Returns
|
|
23
|
+
Dictionary (`result_data`) containing keys:
|
|
24
|
+
- `raw_segments`: Raw diarization output
|
|
25
|
+
- A list of speaking segments (dictionaries) with keys `start`, `end`, `speaker`
|
|
26
|
+
- `merged_segments`: Cleaned diarization output
|
|
27
|
+
- Same format as `raw_segments`
|
|
28
|
+
- Segments <= 0.78 seconds in length are removed
|
|
29
|
+
- Adjacent segments of the same speaker that have a silence in between them of <= 4 seconds are merged into one segment
|
|
30
|
+
- `speaker_centroids`: Voice fingerprints for each detected speaker
|
|
31
|
+
- Dictionary mapping speaker IDs to 192-dimensional numpy arrays
|
|
32
|
+
- Each centroid is the mean of all audio embeddings for that speaker
|
|
33
|
+
- Can be used for speaker comparison/identification across different audio files
|
|
34
|
+
- `timing_stats`: Dictionary of how long each stage of the pipeline took in seconds, as well as the total time
|
|
35
|
+
- Keys: `total_time`, `vad_time`, `fbank_time`, `embeddings_time`, `clustering_time`
|
|
36
|
+
- `speaker_color_sets`: 10 sets of speaker colors (if requested)
|
|
37
|
+
|
|
38
|
+
### `speaker_similarity()`
|
|
39
|
+
```python
|
|
40
|
+
from senko import speaker_similarity
|
|
41
|
+
if speaker_similarity(centroid1, centroid2) >= 0.875:
|
|
42
|
+
print('Speakers are the same')
|
|
43
|
+
```
|
|
44
|
+
Calculate cosine similarity between two speaker centroids (voice fingerprints).
|
|
45
|
+
#### Parameters
|
|
46
|
+
- `centroid1`: First speaker centroid (192-dimensional numpy array)
|
|
47
|
+
- `centroid2`: Second speaker centroid (192-dimensional numpy array)
|
|
48
|
+
|
|
49
|
+
#### Returns
|
|
50
|
+
- `float`: Cosine similarity score between -1 and 1 (<1 rarely if ever happens with speaker embeddings)
|
|
51
|
+
|
|
52
|
+
### Output Format
|
|
53
|
+
Speaker segments (`raw_segments`/`merged_segments`):
|
|
54
|
+
```
|
|
55
|
+
[
|
|
56
|
+
{
|
|
57
|
+
"start": 0.0,
|
|
58
|
+
"end": 5.2,
|
|
59
|
+
"speaker": "SPEAKER_01"
|
|
60
|
+
},
|
|
61
|
+
{
|
|
62
|
+
"start": 5.2,
|
|
63
|
+
"end": 10.8,
|
|
64
|
+
"speaker": "SPEAKER_02"
|
|
65
|
+
},
|
|
66
|
+
...
|
|
67
|
+
]
|
|
68
|
+
```
|
|
69
|
+
Speaker centroids (`speaker_centroids`):
|
|
70
|
+
```
|
|
71
|
+
{
|
|
72
|
+
"SPEAKER_01": array([0.123, -0.456, 0.789, ...]), # 192-dimensional numpy array
|
|
73
|
+
"SPEAKER_02": array([-0.234, 0.567, -0.890, ...]), # 192-dimensional numpy array
|
|
74
|
+
...
|
|
75
|
+
}
|
|
76
|
+
```
|
|
77
|
+
Color sets (`speaker_color_sets`):
|
|
78
|
+
```
|
|
79
|
+
{
|
|
80
|
+
"0": {
|
|
81
|
+
"SPEAKER_01": "#ea759c",
|
|
82
|
+
"SPEAKER_02": "#579c3a",
|
|
83
|
+
"SPEAKER_03": "#100058",
|
|
84
|
+
},
|
|
85
|
+
"1": {
|
|
86
|
+
"SPEAKER_01": "#97de7b",
|
|
87
|
+
"SPEAKER_02": "#4c56b6",
|
|
88
|
+
"SPEAKER_03": "#480000",
|
|
89
|
+
},
|
|
90
|
+
"2": {
|
|
91
|
+
"SPEAKER_01": "#8393f9",
|
|
92
|
+
"SPEAKER_02": "#bf5d01",
|
|
93
|
+
"SPEAKER_03": "#003a38",
|
|
94
|
+
},
|
|
95
|
+
...
|
|
96
|
+
}
|
|
97
|
+
```
|
senko-0.1.0rc1/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2025 Narcotic Software
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
senko-0.1.0rc1/PKG-INFO
ADDED
|
@@ -0,0 +1,162 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: senko
|
|
3
|
+
Version: 0.1.0rc1
|
|
4
|
+
Summary: Very fast speaker diarization
|
|
5
|
+
Keywords: speaker-diarization,audio-processing,speech-processing,voice-activity-detection,speaker-verification,speech-analysis,cuda,gpu,machine-learning,audio-ai,pyannote,silero-vad,speaker-embeddings
|
|
6
|
+
Author-Email: Hamza Qayyum <mhamzaqayyum@icloud.com>
|
|
7
|
+
License-Expression: MIT
|
|
8
|
+
License-File: LICENSE
|
|
9
|
+
License-File: THIRD_PARTY_LICENSES
|
|
10
|
+
Classifier: Development Status :: 3 - Alpha
|
|
11
|
+
Classifier: Intended Audience :: Developers
|
|
12
|
+
Classifier: Intended Audience :: Science/Research
|
|
13
|
+
Classifier: Intended Audience :: Education
|
|
14
|
+
Classifier: Operating System :: OS Independent
|
|
15
|
+
Classifier: Programming Language :: Python :: 3
|
|
16
|
+
Classifier: Programming Language :: Python :: 3.11
|
|
17
|
+
Classifier: Programming Language :: C++
|
|
18
|
+
Classifier: Topic :: Scientific/Engineering :: Artificial Intelligence
|
|
19
|
+
Classifier: Topic :: Scientific/Engineering :: Information Analysis
|
|
20
|
+
Classifier: Topic :: Multimedia :: Sound/Audio :: Analysis
|
|
21
|
+
Classifier: Topic :: Multimedia :: Sound/Audio :: Speech
|
|
22
|
+
Classifier: Topic :: Software Development :: Libraries :: Python Modules
|
|
23
|
+
Classifier: Environment :: GPU :: NVIDIA CUDA
|
|
24
|
+
Project-URL: Homepage, https://github.com/narcotic-sh/senko
|
|
25
|
+
Project-URL: Repository, https://github.com/narcotic-sh/senko
|
|
26
|
+
Project-URL: Issues, https://github.com/narcotic-sh/senko/issues
|
|
27
|
+
Requires-Python: <3.12,>=3.9
|
|
28
|
+
Requires-Dist: numpy
|
|
29
|
+
Requires-Dist: scikit-learn
|
|
30
|
+
Requires-Dist: umap-learn
|
|
31
|
+
Requires-Dist: hdbscan
|
|
32
|
+
Requires-Dist: numba
|
|
33
|
+
Requires-Dist: llvmlite
|
|
34
|
+
Requires-Dist: pyyaml
|
|
35
|
+
Requires-Dist: soundfile
|
|
36
|
+
Requires-Dist: torch
|
|
37
|
+
Requires-Dist: silero-vad
|
|
38
|
+
Requires-Dist: termcolor
|
|
39
|
+
Requires-Dist: psutil
|
|
40
|
+
Requires-Dist: colour-science
|
|
41
|
+
Provides-Extra: nvidia-old
|
|
42
|
+
Requires-Dist: torchaudio; extra == "nvidia-old"
|
|
43
|
+
Requires-Dist: pyannote.audio; extra == "nvidia-old"
|
|
44
|
+
Provides-Extra: nvidia
|
|
45
|
+
Requires-Dist: torchaudio; extra == "nvidia"
|
|
46
|
+
Requires-Dist: pyannote.audio; extra == "nvidia"
|
|
47
|
+
Requires-Dist: cudf-cu12==25.8.*; extra == "nvidia"
|
|
48
|
+
Requires-Dist: dask-cudf-cu12==25.8.*; extra == "nvidia"
|
|
49
|
+
Requires-Dist: cuml-cu12==25.8.*; extra == "nvidia"
|
|
50
|
+
Requires-Dist: cugraph-cu12==25.8.*; extra == "nvidia"
|
|
51
|
+
Requires-Dist: nx-cugraph-cu12==25.8.*; extra == "nvidia"
|
|
52
|
+
Requires-Dist: cuxfilter-cu12==25.8.*; extra == "nvidia"
|
|
53
|
+
Requires-Dist: cucim-cu12==25.8.*; extra == "nvidia"
|
|
54
|
+
Requires-Dist: pylibraft-cu12==25.8.*; extra == "nvidia"
|
|
55
|
+
Requires-Dist: raft-dask-cu12==25.8.*; extra == "nvidia"
|
|
56
|
+
Requires-Dist: cuvs-cu12==25.8.*; extra == "nvidia"
|
|
57
|
+
Description-Content-Type: text/markdown
|
|
58
|
+
|
|
59
|
+
# Senko
|
|
60
|
+
> 閃光 (senkō) - a flash of light
|
|
61
|
+
|
|
62
|
+
A very fast speaker diarization pipeline.
|
|
63
|
+
|
|
64
|
+
1 hour of audio processed in 5 seconds (RTX 4090, Ryzen 9 7950X). ~17x faster than [Pyannote 3.1](https://huggingface.co/pyannote/speaker-diarization-3.1).
|
|
65
|
+
|
|
66
|
+
On M3 Macbook Air, 1 hour in 23.5 seconds (~14x faster).
|
|
67
|
+
|
|
68
|
+
This pipeline is used in the [Zanshin](https://github.com/narcotic-sh/zanshin) media player.
|
|
69
|
+
|
|
70
|
+
## Usage
|
|
71
|
+
```python
|
|
72
|
+
from senko import Diarizer
|
|
73
|
+
import json
|
|
74
|
+
|
|
75
|
+
diarizer = Diarizer(torch_device='auto', warmup=True, quiet=False)
|
|
76
|
+
result = diarizer.diarize('audio.wav', generate_colors=False) # 16 KHz mono wav
|
|
77
|
+
|
|
78
|
+
with open('./audio_diarized.json', 'w') as f:
|
|
79
|
+
json.dump(result["merged_segments"], f, indent=2)
|
|
80
|
+
```
|
|
81
|
+
See `examples/diarize.py` and `DOCS.md`.
|
|
82
|
+
|
|
83
|
+
## Installation
|
|
84
|
+
Senko has been tested to work on Linux, macOS, and WSL, with Python version `3.11.13`.
|
|
85
|
+
|
|
86
|
+
The official install method is using [uv](https://docs.astral.sh/uv/#installation). Have `clang` installed as well if on Linux/WSL.
|
|
87
|
+
```bash
|
|
88
|
+
# For NVIDIA GPUs with CUDA compute capability >= 7.5 (~GTX 16 series and newer)
|
|
89
|
+
uv pip install "senko[nvidia]"
|
|
90
|
+
|
|
91
|
+
# For NVIDIA GPUs with CUDA compute capability < 7.5 (~GTX 10 series and older)
|
|
92
|
+
uv pip install "senko[nvidia-old]"
|
|
93
|
+
|
|
94
|
+
# For Macs (mps) and cpu execution on all other platforms
|
|
95
|
+
uv pip install senko
|
|
96
|
+
```
|
|
97
|
+
For NVIDIA, make sure the installed driver is CUDA 12 capable (should see `CUDA Version: 12.x` in `nvidia-smi`).
|
|
98
|
+
|
|
99
|
+
For setting up Senko for development, see `DEV_SETUP.md`.
|
|
100
|
+
|
|
101
|
+
## Technical Details
|
|
102
|
+
Senko is a modified version of the speaker diarization pipeline found in the [3D-Speaker](https://github.com/modelscope/3D-Speaker/tree/main/egs/3dspeaker/speaker-diarization) project.
|
|
103
|
+
It consists of four stages: VAD (voice activity detection), Fbank feature extraction, speaker embeddings generation, and clustering (spectral or UMAP+HDBSCAN).
|
|
104
|
+
|
|
105
|
+
The following modifications have been made:
|
|
106
|
+
- VAD model has been swapped from FSMN-VAD to either Pyannote [segmentation-3.0](https://huggingface.co/pyannote/segmentation-3.0) (when running on NVIDIA) or [Silero VAD](https://github.com/snakers4/silero-vad) (non-NVIDIA)
|
|
107
|
+
- Fbank feature extraction is done fully upfront, in C++, using all available CPU cores
|
|
108
|
+
- Batched inference of CAM++ embeddings model
|
|
109
|
+
- Clustering when on NVIDIA (with a GPU of CUDA compute capability 7.0+) is done through [RAPIDS](https://docs.rapids.ai/api/cuml/stable/zero-code-change/)
|
|
110
|
+
|
|
111
|
+
## FAQ
|
|
112
|
+
<details>
|
|
113
|
+
<summary>Is there any way to visualize the output diarization data?</summary>
|
|
114
|
+
<br>
|
|
115
|
+
Absolutely. The <a href="https://github.com/narcotic-sh/zanshin">Zanshin</a> media player is entirely made for this purpose. Zanshin is powered by Senko, so the easiest way to visualize the diarization data is by simply using it. It's currently available for Mac (Apple Silicon) with packaging. It also works on Windows and Linux, but without packaging (coming soon); you'll need to clone the repo and launch it through the terminal. See <a href="https://github.com/narcotic-sh/zanshin/blob/main/DEV_SETUP.md">here</a> for instructions.
|
|
116
|
+
<br>
|
|
117
|
+
<br>
|
|
118
|
+
You can also load in the diarization data that Senko generates manually into Zanshin if you want. First, turn off diarization in Zanshin by going into Settings and turning off <code>Identify Speakers</code>. Then, after you add a media item, click on it and on the player page press the <code>H</code> key. In the textbox that appears, paste the contents of the output JSON file that <code>examples/diarize.py</code> generates.
|
|
119
|
+
</details>
|
|
120
|
+
<details>
|
|
121
|
+
<summary>Are overlapping speaker segments detected correctly?</summary>
|
|
122
|
+
<br>
|
|
123
|
+
The current output will not have any overlapping speaker segments; i.e. only one speaker max is reported to be speaking at any given time. However, despite this, the current pipeline still performs great in determining who the dominant speaker is at any given time in chaotic audio with speakers talking over each other (example: casual podcasts). That said, detecting overlapping speaker segments is a planned feature thanks to the Pyannote segmentation-3.0 model (which we currently only use for VAD) supporting it.
|
|
124
|
+
</details>
|
|
125
|
+
<details>
|
|
126
|
+
<summary>How fast is the pipeline on CPU (<code>cpu</code>)?</summary>
|
|
127
|
+
<br>
|
|
128
|
+
On a Ryzen 9 9950X it takes 42 seconds to process 1 hour of audio.
|
|
129
|
+
</details>
|
|
130
|
+
<details>
|
|
131
|
+
<summary>Does the entire pipeline run fully on the GPU, if available?</summary>
|
|
132
|
+
<br>
|
|
133
|
+
With <code>cuda</code>, all parts of the pipeline except Fbank feature extraction (which always runs on the CPU) do run on the GPU. However, CPU performance still significantly impacts overall speed even for the GPU-accelerated stages.
|
|
134
|
+
<br><br>
|
|
135
|
+
During the embeddings generation phase, for example, while the actual model inference happens on the GPU with minimal CPU-GPU memory transfers (just input/output), the CPU handles all the orchestration work: Python loops for batching, tensor preparation, padding operations dispatch, and managing the inference pipeline. All this orchestration runs single-threaded on the CPU. This means a faster CPU will improve performance even when using a powerful GPU, as the CPU coordinates all the GPU operations.
|
|
136
|
+
<br><br>
|
|
137
|
+
Therefore, for optimal performance, pair a fast GPU with a fast CPU. The CPU bottleneck becomes more noticeable with very fast GPUs (ex. RTX 4090) where the GPU can execute the batch preparation and inference faster than the CPU can orchestrate/dispatch these operations.
|
|
138
|
+
<br><br>
|
|
139
|
+
As for <code>mps</code>, the only part of the pipeline that runs on the GPU is the embeddings gen phase. All other parts run on the CPU.
|
|
140
|
+
</details>
|
|
141
|
+
<details>
|
|
142
|
+
<summary>Known limitations?</summary>
|
|
143
|
+
<br>
|
|
144
|
+
- The pipeline works best when the audio recording quality is good. Ideal setting: professional podcast studio. Heavy background noise, background music, or a generally low fidelity recording will degrade the diarization performance significantly.
|
|
145
|
+
<br><br>
|
|
146
|
+
- It is rare but possible that voices that sound very similar get clustered as one voice. This can happen if the voices are genuinely extremely similar, or, more commonly, if the audio recording fidelity is low.
|
|
147
|
+
<br><br>
|
|
148
|
+
- The same voice but recorded with >1 microphones or in >1 recording settings (within the same audio file) will often get detected as >1 speakers.
|
|
149
|
+
<br><br>
|
|
150
|
+
- Diarization performance (as in quality, not just speed) on NVIDIA is a bit better than on Mac and CPU. This is due to RAPIDS clustering yielding slightly better results than CPU clustering.
|
|
151
|
+
</details>
|
|
152
|
+
|
|
153
|
+
## Future Improvements & Directions
|
|
154
|
+
- Overlapping speaker segments support
|
|
155
|
+
- Improve speaker colors generation algorithm
|
|
156
|
+
- Support for Intel and AMD GPUs
|
|
157
|
+
- Experiment with `torch.compile()` (faster than current JIT tracing TorchScript approach?)
|
|
158
|
+
- Experiment with Modular [MAX](https://www.modular.com/blog/bring-your-own-pytorch-model) engine (faster CPU inference speed?)
|
|
159
|
+
- Measure DER (diarization error rate) of pipeline
|
|
160
|
+
- Experiment with [Resonate](https://alexandrefrancois.org/Resonate/) for superior audio feature extraction
|
|
161
|
+
- Background noise removal ([DeepFilterNet](https://github.com/Rikorose/DeepFilterNet))
|
|
162
|
+
- Live progress reporting
|
senko-0.1.0rc1/README.md
ADDED
|
@@ -0,0 +1,104 @@
|
|
|
1
|
+
# Senko
|
|
2
|
+
> 閃光 (senkō) - a flash of light
|
|
3
|
+
|
|
4
|
+
A very fast speaker diarization pipeline.
|
|
5
|
+
|
|
6
|
+
1 hour of audio processed in 5 seconds (RTX 4090, Ryzen 9 7950X). ~17x faster than [Pyannote 3.1](https://huggingface.co/pyannote/speaker-diarization-3.1).
|
|
7
|
+
|
|
8
|
+
On M3 Macbook Air, 1 hour in 23.5 seconds (~14x faster).
|
|
9
|
+
|
|
10
|
+
This pipeline is used in the [Zanshin](https://github.com/narcotic-sh/zanshin) media player.
|
|
11
|
+
|
|
12
|
+
## Usage
|
|
13
|
+
```python
|
|
14
|
+
from senko import Diarizer
|
|
15
|
+
import json
|
|
16
|
+
|
|
17
|
+
diarizer = Diarizer(torch_device='auto', warmup=True, quiet=False)
|
|
18
|
+
result = diarizer.diarize('audio.wav', generate_colors=False) # 16 KHz mono wav
|
|
19
|
+
|
|
20
|
+
with open('./audio_diarized.json', 'w') as f:
|
|
21
|
+
json.dump(result["merged_segments"], f, indent=2)
|
|
22
|
+
```
|
|
23
|
+
See `examples/diarize.py` and `DOCS.md`.
|
|
24
|
+
|
|
25
|
+
## Installation
|
|
26
|
+
Senko has been tested to work on Linux, macOS, and WSL, with Python version `3.11.13`.
|
|
27
|
+
|
|
28
|
+
The official install method is using [uv](https://docs.astral.sh/uv/#installation). Have `clang` installed as well if on Linux/WSL.
|
|
29
|
+
```bash
|
|
30
|
+
# For NVIDIA GPUs with CUDA compute capability >= 7.5 (~GTX 16 series and newer)
|
|
31
|
+
uv pip install "senko[nvidia]"
|
|
32
|
+
|
|
33
|
+
# For NVIDIA GPUs with CUDA compute capability < 7.5 (~GTX 10 series and older)
|
|
34
|
+
uv pip install "senko[nvidia-old]"
|
|
35
|
+
|
|
36
|
+
# For Macs (mps) and cpu execution on all other platforms
|
|
37
|
+
uv pip install senko
|
|
38
|
+
```
|
|
39
|
+
For NVIDIA, make sure the installed driver is CUDA 12 capable (should see `CUDA Version: 12.x` in `nvidia-smi`).
|
|
40
|
+
|
|
41
|
+
For setting up Senko for development, see `DEV_SETUP.md`.
|
|
42
|
+
|
|
43
|
+
## Technical Details
|
|
44
|
+
Senko is a modified version of the speaker diarization pipeline found in the [3D-Speaker](https://github.com/modelscope/3D-Speaker/tree/main/egs/3dspeaker/speaker-diarization) project.
|
|
45
|
+
It consists of four stages: VAD (voice activity detection), Fbank feature extraction, speaker embeddings generation, and clustering (spectral or UMAP+HDBSCAN).
|
|
46
|
+
|
|
47
|
+
The following modifications have been made:
|
|
48
|
+
- VAD model has been swapped from FSMN-VAD to either Pyannote [segmentation-3.0](https://huggingface.co/pyannote/segmentation-3.0) (when running on NVIDIA) or [Silero VAD](https://github.com/snakers4/silero-vad) (non-NVIDIA)
|
|
49
|
+
- Fbank feature extraction is done fully upfront, in C++, using all available CPU cores
|
|
50
|
+
- Batched inference of CAM++ embeddings model
|
|
51
|
+
- Clustering when on NVIDIA (with a GPU of CUDA compute capability 7.0+) is done through [RAPIDS](https://docs.rapids.ai/api/cuml/stable/zero-code-change/)
|
|
52
|
+
|
|
53
|
+
## FAQ
|
|
54
|
+
<details>
|
|
55
|
+
<summary>Is there any way to visualize the output diarization data?</summary>
|
|
56
|
+
<br>
|
|
57
|
+
Absolutely. The <a href="https://github.com/narcotic-sh/zanshin">Zanshin</a> media player is entirely made for this purpose. Zanshin is powered by Senko, so the easiest way to visualize the diarization data is by simply using it. It's currently available for Mac (Apple Silicon) with packaging. It also works on Windows and Linux, but without packaging (coming soon); you'll need to clone the repo and launch it through the terminal. See <a href="https://github.com/narcotic-sh/zanshin/blob/main/DEV_SETUP.md">here</a> for instructions.
|
|
58
|
+
<br>
|
|
59
|
+
<br>
|
|
60
|
+
You can also load in the diarization data that Senko generates manually into Zanshin if you want. First, turn off diarization in Zanshin by going into Settings and turning off <code>Identify Speakers</code>. Then, after you add a media item, click on it and on the player page press the <code>H</code> key. In the textbox that appears, paste the contents of the output JSON file that <code>examples/diarize.py</code> generates.
|
|
61
|
+
</details>
|
|
62
|
+
<details>
|
|
63
|
+
<summary>Are overlapping speaker segments detected correctly?</summary>
|
|
64
|
+
<br>
|
|
65
|
+
The current output will not have any overlapping speaker segments; i.e. only one speaker max is reported to be speaking at any given time. However, despite this, the current pipeline still performs great in determining who the dominant speaker is at any given time in chaotic audio with speakers talking over each other (example: casual podcasts). That said, detecting overlapping speaker segments is a planned feature thanks to the Pyannote segmentation-3.0 model (which we currently only use for VAD) supporting it.
|
|
66
|
+
</details>
|
|
67
|
+
<details>
|
|
68
|
+
<summary>How fast is the pipeline on CPU (<code>cpu</code>)?</summary>
|
|
69
|
+
<br>
|
|
70
|
+
On a Ryzen 9 9950X it takes 42 seconds to process 1 hour of audio.
|
|
71
|
+
</details>
|
|
72
|
+
<details>
|
|
73
|
+
<summary>Does the entire pipeline run fully on the GPU, if available?</summary>
|
|
74
|
+
<br>
|
|
75
|
+
With <code>cuda</code>, all parts of the pipeline except Fbank feature extraction (which always runs on the CPU) do run on the GPU. However, CPU performance still significantly impacts overall speed even for the GPU-accelerated stages.
|
|
76
|
+
<br><br>
|
|
77
|
+
During the embeddings generation phase, for example, while the actual model inference happens on the GPU with minimal CPU-GPU memory transfers (just input/output), the CPU handles all the orchestration work: Python loops for batching, tensor preparation, padding operations dispatch, and managing the inference pipeline. All this orchestration runs single-threaded on the CPU. This means a faster CPU will improve performance even when using a powerful GPU, as the CPU coordinates all the GPU operations.
|
|
78
|
+
<br><br>
|
|
79
|
+
Therefore, for optimal performance, pair a fast GPU with a fast CPU. The CPU bottleneck becomes more noticeable with very fast GPUs (ex. RTX 4090) where the GPU can execute the batch preparation and inference faster than the CPU can orchestrate/dispatch these operations.
|
|
80
|
+
<br><br>
|
|
81
|
+
As for <code>mps</code>, the only part of the pipeline that runs on the GPU is the embeddings gen phase. All other parts run on the CPU.
|
|
82
|
+
</details>
|
|
83
|
+
<details>
|
|
84
|
+
<summary>Known limitations?</summary>
|
|
85
|
+
<br>
|
|
86
|
+
- The pipeline works best when the audio recording quality is good. Ideal setting: professional podcast studio. Heavy background noise, background music, or a generally low fidelity recording will degrade the diarization performance significantly.
|
|
87
|
+
<br><br>
|
|
88
|
+
- It is rare but possible that voices that sound very similar get clustered as one voice. This can happen if the voices are genuinely extremely similar, or, more commonly, if the audio recording fidelity is low.
|
|
89
|
+
<br><br>
|
|
90
|
+
- The same voice but recorded with >1 microphones or in >1 recording settings (within the same audio file) will often get detected as >1 speakers.
|
|
91
|
+
<br><br>
|
|
92
|
+
- Diarization performance (as in quality, not just speed) on NVIDIA is a bit better than on Mac and CPU. This is due to RAPIDS clustering yielding slightly better results than CPU clustering.
|
|
93
|
+
</details>
|
|
94
|
+
|
|
95
|
+
## Future Improvements & Directions
|
|
96
|
+
- Overlapping speaker segments support
|
|
97
|
+
- Improve speaker colors generation algorithm
|
|
98
|
+
- Support for Intel and AMD GPUs
|
|
99
|
+
- Experiment with `torch.compile()` (faster than current JIT tracing TorchScript approach?)
|
|
100
|
+
- Experiment with Modular [MAX](https://www.modular.com/blog/bring-your-own-pytorch-model) engine (faster CPU inference speed?)
|
|
101
|
+
- Measure DER (diarization error rate) of pipeline
|
|
102
|
+
- Experiment with [Resonate](https://alexandrefrancois.org/Resonate/) for superior audio feature extraction
|
|
103
|
+
- Background noise removal ([DeepFilterNet](https://github.com/Rikorose/DeepFilterNet))
|
|
104
|
+
- Live progress reporting
|