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.

Files changed (55) hide show
  1. senko-0.1.0rc1/.github/FUNDING.yml +15 -0
  2. senko-0.1.0rc1/.gitignore +16 -0
  3. senko-0.1.0rc1/.python-version +1 -0
  4. senko-0.1.0rc1/BENCHMARK.md +10 -0
  5. senko-0.1.0rc1/CMakeLists.txt +18 -0
  6. senko-0.1.0rc1/DEV_SETUP.md +46 -0
  7. senko-0.1.0rc1/DOCS.md +97 -0
  8. senko-0.1.0rc1/LICENSE +21 -0
  9. senko-0.1.0rc1/PKG-INFO +162 -0
  10. senko-0.1.0rc1/README.md +104 -0
  11. senko-0.1.0rc1/THIRD_PARTY_LICENSES +231 -0
  12. senko-0.1.0rc1/examples/diarize.py +71 -0
  13. senko-0.1.0rc1/models/README.md +4 -0
  14. senko-0.1.0rc1/models/camplusplus_traced_cuda_optimized.pt +0 -0
  15. senko-0.1.0rc1/models/camplusplus_traced_mps_optimized.pt +0 -0
  16. senko-0.1.0rc1/models/pyannote_segmentation_3.0/config.yaml +19 -0
  17. senko-0.1.0rc1/models/pyannote_segmentation_3.0/pytorch_model.bin +0 -0
  18. senko-0.1.0rc1/models/speech_campplus_sv_zh_en_16k-common_advanced/campplus_cn_en_common.pt +0 -0
  19. senko-0.1.0rc1/pyproject.toml +150 -0
  20. senko-0.1.0rc1/senko/__init__.py +3 -0
  21. senko-0.1.0rc1/senko/camplusplus.py +210 -0
  22. senko-0.1.0rc1/senko/cluster/__init__.py +0 -0
  23. senko-0.1.0rc1/senko/cluster/cluster_cpu.py +205 -0
  24. senko-0.1.0rc1/senko/cluster/cluster_gpu.py +205 -0
  25. senko-0.1.0rc1/senko/cluster/conf/spectral.yaml +11 -0
  26. senko-0.1.0rc1/senko/cluster/conf/umap_hdbscan.yaml +11 -0
  27. senko-0.1.0rc1/senko/colors.py +118 -0
  28. senko-0.1.0rc1/senko/diarizer.py +465 -0
  29. senko-0.1.0rc1/senko/fbank_extractor/.gitignore +1 -0
  30. senko-0.1.0rc1/senko/fbank_extractor/CMakeLists.txt +39 -0
  31. senko-0.1.0rc1/senko/fbank_extractor/cpp/fbank_extractor.cpp +125 -0
  32. senko-0.1.0rc1/senko/fbank_extractor/cpp/fbank_extractor.h +18 -0
  33. senko-0.1.0rc1/senko/fbank_extractor/cpp/fbank_wrapper.cpp +74 -0
  34. senko-0.1.0rc1/senko/fbank_extractor/cpp/feature/fbank_computer.cpp +87 -0
  35. senko-0.1.0rc1/senko/fbank_extractor/cpp/feature/fbank_computer.h +31 -0
  36. senko-0.1.0rc1/senko/fbank_extractor/cpp/feature/fbank_options.h +48 -0
  37. senko-0.1.0rc1/senko/fbank_extractor/cpp/feature/fbank_utils.cpp +60 -0
  38. senko-0.1.0rc1/senko/fbank_extractor/cpp/feature/fbank_utils.h +18 -0
  39. senko-0.1.0rc1/senko/fbank_extractor/cpp/feature/frame_extraction_options.cpp +23 -0
  40. senko-0.1.0rc1/senko/fbank_extractor/cpp/feature/frame_extraction_options.h +61 -0
  41. senko-0.1.0rc1/senko/fbank_extractor/cpp/feature/frame_processor.cpp +76 -0
  42. senko-0.1.0rc1/senko/fbank_extractor/cpp/feature/frame_processor.h +30 -0
  43. senko-0.1.0rc1/senko/fbank_extractor/cpp/feature/melbank_options.h +32 -0
  44. senko-0.1.0rc1/senko/fbank_extractor/cpp/feature/melbank_processor.cpp +97 -0
  45. senko-0.1.0rc1/senko/fbank_extractor/cpp/feature/melbank_processor.h +33 -0
  46. senko-0.1.0rc1/senko/fbank_extractor/cpp/feature_computer.cpp +60 -0
  47. senko-0.1.0rc1/senko/fbank_extractor/cpp/feature_computer.h +19 -0
  48. senko-0.1.0rc1/senko/fbank_extractor/cpp/wav.h +238 -0
  49. senko-0.1.0rc1/senko/fbank_extractor/include/fbank_interface.h +35 -0
  50. senko-0.1.0rc1/senko/paths.py +50 -0
  51. senko-0.1.0rc1/senko/utils.py +74 -0
  52. senko-0.1.0rc1/tracing/.gitignore +1 -0
  53. senko-0.1.0rc1/tracing/README.md +25 -0
  54. senko-0.1.0rc1/tracing/optimize.py +124 -0
  55. 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,16 @@
1
+ **/__pycache__/
2
+ **/.DS_Store
3
+
4
+ .vscode/
5
+
6
+ dist/
7
+ build/
8
+ env/
9
+ .venv/
10
+
11
+ result/
12
+
13
+ *.wav
14
+ *.m4a
15
+ *.webm
16
+ *.mp3
@@ -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.
@@ -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
@@ -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