diff --git a/.coveragerc b/.coveragerc index c8f35eab..566ba584 100644 --- a/.coveragerc +++ b/.coveragerc @@ -1,9 +1,12 @@ [run] omit = buzz/whisper_cpp/* + buzz/transcriber/local_whisper_cpp_server_transcriber.py *_test.py demucs/* - buzz/transcriber/local_whisper_cpp_server_transcriber.py + whisper_diarization/* + deepmultilingualpunctuation/* + ctc_forced_aligner/* [html] directory = coverage/html diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 010e183a..54e7158d 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -70,10 +70,10 @@ jobs: ~/AppData/Local/Buzz/Buzz/Cache key: whisper-models - - uses: AnimMouse/setup-ffmpeg@v1.2.1 + - uses: AnimMouse/setup-ffmpeg@v1 id: setup-ffmpeg with: - version: ${{ matrix.os == 'macos-15-intel' && '7.1.1' || matrix.os == 'macos-latest' && '71' || '7.1' }} + version: ${{ matrix.os == 'macos-15-intel' && '7.1.1' || matrix.os == 'macos-latest' && '80' || '8.0' }} - name: Test ffmpeg run: ffmpeg -i ./testdata/audio-long.mp3 ./testdata/audio-long.wav diff --git a/.github/workflows/snapcraft.yml b/.github/workflows/snapcraft.yml index 0b1ecec3..286fe59c 100644 --- a/.github/workflows/snapcraft.yml +++ b/.github/workflows/snapcraft.yml @@ -15,9 +15,22 @@ concurrency: jobs: build: runs-on: ubuntu-latest + timeout-minutes: 90 + env: + BUZZ_DISABLE_TELEMETRY: true outputs: snap: ${{ steps.snapcraft.outputs.snap }} steps: + # Ideas from https://github.com/orgs/community/discussions/25678 + - name: Remove unused build tools + run: | + sudo apt-get remove -y '^llvm-.*' + sudo apt-get remove -y 'php.*' + sudo apt-get remove -y azure-cli google-cloud-sdk hhvm google-chrome-stable firefox powershell mono-devel || true + sudo apt-get autoremove -y + sudo apt-get clean + python -m pip cache purge + rm -rf /opt/hostedtoolcache || true - name: Maximize build space uses: easimon/maximize-build-space@master with: diff --git a/.gitignore b/.gitignore index f0c01776..66f3b3ec 100644 --- a/.gitignore +++ b/.gitignore @@ -31,4 +31,5 @@ benchmarks.json /coverage/ /wheelhouse/ /.flatpak-builder -/repo \ No newline at end of file +/repo +/nemo_msdd_configs diff --git a/.gitmodules b/.gitmodules index fa83e220..1c0c8b24 100644 --- a/.gitmodules +++ b/.gitmodules @@ -1,3 +1,15 @@ [submodule "whisper.cpp"] path = whisper.cpp url = https://github.com/ggerganov/whisper.cpp +[submodule "whisper_diarization"] + path = whisper_diarization + url = https://github.com/MahmoudAshraf97/whisper-diarization +[submodule "demucs"] + path = demucs + url = https://github.com/MahmoudAshraf97/demucs.git +[submodule "deepmultilingualpunctuation"] + path = deepmultilingualpunctuation + url = https://github.com/oliverguhr/deepmultilingualpunctuation.git +[submodule "ctc_forced_aligner"] + path = ctc_forced_aligner + url = https://github.com/MahmoudAshraf97/ctc-forced-aligner.git diff --git a/Buzz.spec b/Buzz.spec index 0f4e8edb..c2d93bb1 100644 --- a/Buzz.spec +++ b/Buzz.spec @@ -30,7 +30,13 @@ datas += collect_data_files("transformers", include_py_files=True) datas += collect_data_files("faster_whisper", include_py_files=True) datas += collect_data_files("stable_whisper", include_py_files=True) datas += collect_data_files("whisper") -datas += [("demucs", "demucs")] +datas += collect_data_files("demucs", include_py_files=True) +datas += collect_data_files("whisper_diarization", include_py_files=True) +datas += collect_data_files("deepmultilingualpunctuation", include_py_files=True) +datas += collect_data_files("ctc_forced_aligner", include_py_files=True) +datas += collect_data_files("nemo", include_py_files=True) +datas += collect_data_files("lightning_fabric", include_py_files=True) +datas += collect_data_files("pytorch_lightning", include_py_files=True) datas += [("buzz/assets/*", "assets")] datas += [("buzz/locale", "locale")] datas += [("buzz/schema.sql", ".")] diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index d8a540cf..3b2fddf4 100755 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -53,8 +53,7 @@ sudo apt-get install --no-install-recommends libyaml-dev libtbb-dev libxkbcommon ``` On versions prior to Ubuntu 24.04 install `sudo apt-get install --no-install-recommends libegl1-mesa` 5. Install the dependencies `uv sync` -6. Build Buzz `uv build` -7. Run Buzz `uv run buzz` +6. Run Buzz `uv run buzz` #### Necessary dependencies for Faster Whisper on GPU @@ -81,8 +80,7 @@ On versions prior to Ubuntu 24.04 install `sudo apt-get install --no-install-rec 3. Install uv `curl -LsSf https://astral.sh/uv/install.sh | sh` (or `brew install uv`) 4. Install system dependencies you may be missing `brew install ffmpeg` 5. Install the dependencies `uv sync` -6. Build Buzz `uv build` -7. Run Buzz `uv run buzz` +6. Run Buzz `uv run buzz` diff --git a/Makefile b/Makefile index af2aa9a1..92315dbd 100644 --- a/Makefile +++ b/Makefile @@ -1,4 +1,5 @@ -version := 1.3.4 +# Change also in pyproject.toml and buzz/__version__.py +version := 1.4.0 mac_app_path := ./dist/Buzz.app mac_zip_path := ./dist/Buzz-${version}-mac.zip @@ -28,7 +29,7 @@ else rm -rf dist/* || true endif -COVERAGE_THRESHOLD := 75 +COVERAGE_THRESHOLD := 70 test: buzz/whisper_cpp pytest -s -vv --cov=buzz --cov-report=xml --cov-report=html --benchmark-skip --cov-fail-under=${COVERAGE_THRESHOLD} --cov-config=.coveragerc @@ -67,7 +68,7 @@ ifeq ($(shell uname -s), Linux) cp whisper.cpp/build/bin/whisper-server buzz/whisper_cpp/ || true cp whisper.cpp/build/src/libwhisper.so buzz/whisper_cpp/ || true cp whisper.cpp/build/src/libwhisper.so.1 buzz/whisper_cpp/ || true - cp whisper.cpp/build/src/libwhisper.so.1.7.6 buzz/whisper_cpp/ || true + cp whisper.cpp/build/src/libwhisper.so.1.8.2 buzz/whisper_cpp/ || true cp whisper.cpp/build/ggml/src/libggml.so buzz/whisper_cpp/ || true cp whisper.cpp/build/ggml/src/libggml-base.so buzz/whisper_cpp/ || true cp whisper.cpp/build/ggml/src/libggml-cpu.so buzz/whisper_cpp/ || true diff --git a/README.md b/README.md index 55c62f9d..7b5db725 100644 --- a/README.md +++ b/README.md @@ -14,7 +14,7 @@ OpenAI's [Whisper](https://github.com/openai/whisper). [![Github all releases](https://img.shields.io/github/downloads/chidiwilliams/buzz/total.svg)](https://GitHub.com/chidiwilliams/buzz/releases/)
-

Buzz is better on the App Store. Get a Mac-native version of Buzz with a cleaner look, audio playback, drag-and-drop import, transcript editing, search, and much more.

+

An older version of Buzz available on the App Store. Get a Mac-native version of Buzz with a cleaner look, audio playback, drag-and-drop import, transcript editing, search, and much more.

Download on the Mac App Store
diff --git a/buzz/__version__.py b/buzz/__version__.py index 4a16f216..af63e4ae 100644 --- a/buzz/__version__.py +++ b/buzz/__version__.py @@ -1 +1 @@ -VERSION = "1.3.4" +VERSION = "1.4.0" diff --git a/buzz/assets/speaker-identification.svg b/buzz/assets/speaker-identification.svg new file mode 100644 index 00000000..cfea8b41 --- /dev/null +++ b/buzz/assets/speaker-identification.svg @@ -0,0 +1,14 @@ + + + + + + + \ No newline at end of file diff --git a/buzz/buzz.py b/buzz/buzz.py index e6f755f7..6c4750d6 100644 --- a/buzz/buzz.py +++ b/buzz/buzz.py @@ -56,6 +56,17 @@ def main(): format=log_format, ) + # Silence noisy third-party library loggers + logging.getLogger("matplotlib").setLevel(logging.WARNING) + logging.getLogger("graphviz").setLevel(logging.WARNING) + logging.getLogger("nemo_logger").setLevel(logging.ERROR) + logging.getLogger("numba").setLevel(logging.WARNING) + logging.getLogger("torio._extension.utils").setLevel(logging.WARNING) + logging.getLogger("export_config_manager").setLevel(logging.WARNING) + logging.getLogger("training_telemetry_provider").setLevel(logging.ERROR) + logging.getLogger("default_recorder").setLevel(logging.WARNING) + logging.getLogger("config").setLevel(logging.WARNING) + if getattr(sys, "frozen", False) is False: stdout_handler = logging.StreamHandler(sys.stdout) stdout_handler.setLevel(logging.DEBUG) diff --git a/buzz/file_transcriber_queue_worker.py b/buzz/file_transcriber_queue_worker.py index f6cf91fb..b056981f 100644 --- a/buzz/file_transcriber_queue_worker.py +++ b/buzz/file_transcriber_queue_worker.py @@ -7,7 +7,7 @@ from uuid import UUID from PyQt6.QtCore import QObject, QThread, pyqtSignal, pyqtSlot -from demucs import api as demucsApi +from demucs.demucs import api as demucsApi from buzz.model_loader import ModelType from buzz.transcriber.file_transcriber import FileTranscriber diff --git a/buzz/locale/ca_ES/LC_MESSAGES/buzz.po b/buzz/locale/ca_ES/LC_MESSAGES/buzz.po index e88359f6..aaf56614 100644 --- a/buzz/locale/ca_ES/LC_MESSAGES/buzz.po +++ b/buzz/locale/ca_ES/LC_MESSAGES/buzz.po @@ -7,7 +7,7 @@ msgid "" msgstr "" "Project-Id-Version: buzz\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2025-11-28 16:49+0200\n" +"POT-Creation-Date: 2025-11-23 12:55+0200\n" "PO-Revision-Date: 2025-10-17 07:59+0200\n" "Last-Translator: Éric Duarte \n" "Language-Team: Catalan \n" @@ -554,64 +554,68 @@ msgstr "Veure" msgid "Timestamps" msgstr "Marqua de temps" -#: buzz/widgets/transcription_viewer/transcription_viewer_widget.py:211 +#: buzz/widgets/transcription_viewer/transcription_viewer_widget.py:215 msgid "Export" msgstr "Exporta" -#: buzz/widgets/transcription_viewer/transcription_viewer_widget.py:230 +#: buzz/widgets/transcription_viewer/transcription_viewer_widget.py:234 msgid "Translate" msgstr "Traduir" -#: buzz/widgets/transcription_viewer/transcription_viewer_widget.py:240 -#: buzz/widgets/transcription_viewer/transcription_resizer_widget.py:177 +#: buzz/widgets/transcription_viewer/transcription_viewer_widget.py:244 +#: buzz/widgets/transcription_viewer/transcription_resizer_widget.py:175 msgid "Resize" msgstr "Redimensionar" -#: buzz/widgets/transcription_viewer/transcription_viewer_widget.py:252 +#: buzz/widgets/transcription_viewer/transcription_viewer_widget.py:257 +msgid "Identify Speakers" +msgstr "" + +#: buzz/widgets/transcription_viewer/transcription_viewer_widget.py:269 msgid "Find" msgstr "Cerca" -#: buzz/widgets/transcription_viewer/transcription_viewer_widget.py:255 +#: buzz/widgets/transcription_viewer/transcription_viewer_widget.py:272 msgid "Show/Hide Search Bar (Ctrl+F)" msgstr "Mostra/amaga la barra de cerca (Ctrl+F)" -#: buzz/widgets/transcription_viewer/transcription_viewer_widget.py:320 +#: buzz/widgets/transcription_viewer/transcription_viewer_widget.py:337 msgid "Find:" msgstr "Cerca:" -#: buzz/widgets/transcription_viewer/transcription_viewer_widget.py:326 +#: buzz/widgets/transcription_viewer/transcription_viewer_widget.py:343 msgid "Enter text to find..." msgstr "Introduïu el text a cercar..." -#: buzz/widgets/transcription_viewer/transcription_viewer_widget.py:339 +#: buzz/widgets/transcription_viewer/transcription_viewer_widget.py:356 msgid "Previous match (Shift+Enter)" msgstr "Coincidència anterior (Maj+Retorn)" -#: buzz/widgets/transcription_viewer/transcription_viewer_widget.py:347 +#: buzz/widgets/transcription_viewer/transcription_viewer_widget.py:364 msgid "Next match (Enter)" msgstr "Coincidència següent (retorn)" -#: buzz/widgets/transcription_viewer/transcription_viewer_widget.py:355 +#: buzz/widgets/transcription_viewer/transcription_viewer_widget.py:372 msgid "Clear" msgstr "Neteja" -#: buzz/widgets/transcription_viewer/transcription_viewer_widget.py:382 +#: buzz/widgets/transcription_viewer/transcription_viewer_widget.py:399 msgid "Playback Controls:" msgstr "Controls de reproducció:" -#: buzz/widgets/transcription_viewer/transcription_viewer_widget.py:387 +#: buzz/widgets/transcription_viewer/transcription_viewer_widget.py:404 msgid "Loop Segment" msgstr "Segment de bucle" -#: buzz/widgets/transcription_viewer/transcription_viewer_widget.py:389 +#: buzz/widgets/transcription_viewer/transcription_viewer_widget.py:406 msgid "Enable/disable looping when clicking on transcript segments" msgstr "Activa/desactiva el bucle en fer clic als segments de transcripció" -#: buzz/widgets/transcription_viewer/transcription_viewer_widget.py:395 +#: buzz/widgets/transcription_viewer/transcription_viewer_widget.py:412 msgid "Follow Audio" msgstr "Segueix l'àudio" -#: buzz/widgets/transcription_viewer/transcription_viewer_widget.py:397 +#: buzz/widgets/transcription_viewer/transcription_viewer_widget.py:414 msgid "" "Enable/disable following the current audio position in the transcript. When " "enabled, automatically scrolls to current text." @@ -619,75 +623,146 @@ msgstr "" "Activa/desactiva seguint la posició d'àudio actual a la transcripció. Quan " "està activada, es desplaça automàticament al text actual." -#: buzz/widgets/transcription_viewer/transcription_viewer_widget.py:444 +#: buzz/widgets/transcription_viewer/transcription_viewer_widget.py:461 msgid "Scroll to Current" msgstr "Desplaça't fins a l'actual" -#: buzz/widgets/transcription_viewer/transcription_viewer_widget.py:446 +#: buzz/widgets/transcription_viewer/transcription_viewer_widget.py:463 msgid "Scroll to the currently spoken text" msgstr "Desplaçar-se fins al text que es parla actualment" -#: buzz/widgets/transcription_viewer/transcription_viewer_widget.py:768 +#: buzz/widgets/transcription_viewer/transcription_viewer_widget.py:785 msgid "1 of 100+ matches" msgstr "1 de més de 100 coincidències" -#: buzz/widgets/transcription_viewer/transcription_viewer_widget.py:770 +#: buzz/widgets/transcription_viewer/transcription_viewer_widget.py:787 msgid "1 of " msgstr "1 de " -#: buzz/widgets/transcription_viewer/transcription_viewer_widget.py:770 -#: buzz/widgets/transcription_viewer/transcription_viewer_widget.py:836 +#: buzz/widgets/transcription_viewer/transcription_viewer_widget.py:787 +#: buzz/widgets/transcription_viewer/transcription_viewer_widget.py:853 msgid " matches" msgstr " coincidències" -#: buzz/widgets/transcription_viewer/transcription_viewer_widget.py:775 +#: buzz/widgets/transcription_viewer/transcription_viewer_widget.py:792 msgid "No matches found" msgstr "No s'ha trobat cap coincidència" -#: buzz/widgets/transcription_viewer/transcription_viewer_widget.py:834 +#: buzz/widgets/transcription_viewer/transcription_viewer_widget.py:851 msgid " of 100+ matches" msgstr " de més de 100 coincidències" -#: buzz/widgets/transcription_viewer/transcription_viewer_widget.py:836 +#: buzz/widgets/transcription_viewer/transcription_viewer_widget.py:853 msgid " of " msgstr " de " -#: buzz/widgets/transcription_viewer/transcription_viewer_widget.py:1191 +#: buzz/widgets/transcription_viewer/transcription_viewer_widget.py:1208 msgid "API Key Required" msgstr "Clau API necessària" -#: buzz/widgets/transcription_viewer/transcription_viewer_widget.py:1192 +#: buzz/widgets/transcription_viewer/transcription_viewer_widget.py:1209 msgid "Please enter OpenAI API Key in preferences" msgstr "Introduïu la clau API d'OpenAI a les preferències" -#: buzz/widgets/transcription_viewer/transcription_resizer_widget.py:159 +#: buzz/widgets/transcription_viewer/transcription_resizer_widget.py:157 msgid "Resize Options" msgstr "Opcions de redimensionament" -#: buzz/widgets/transcription_viewer/transcription_resizer_widget.py:170 +#: buzz/widgets/transcription_viewer/transcription_resizer_widget.py:168 msgid "Desired subtitle length" msgstr "Longitud desitjada dels subtítols" -#: buzz/widgets/transcription_viewer/transcription_resizer_widget.py:195 +#: buzz/widgets/transcription_viewer/transcription_resizer_widget.py:193 msgid "Merge Options" msgstr "Opcions de fusió" -#: buzz/widgets/transcription_viewer/transcription_resizer_widget.py:206 +#: buzz/widgets/transcription_viewer/transcription_resizer_widget.py:204 msgid "Merge by gap" msgstr "Fusiona per buit" -#: buzz/widgets/transcription_viewer/transcription_resizer_widget.py:214 +#: buzz/widgets/transcription_viewer/transcription_resizer_widget.py:212 msgid "Split by punctuation" msgstr "Divideix per puntuació" -#: buzz/widgets/transcription_viewer/transcription_resizer_widget.py:222 +#: buzz/widgets/transcription_viewer/transcription_resizer_widget.py:220 msgid "Split by max length" msgstr "Divideix per la longitud màxima" -#: buzz/widgets/transcription_viewer/transcription_resizer_widget.py:234 +#: buzz/widgets/transcription_viewer/transcription_resizer_widget.py:232 msgid "Merge" msgstr "Fusiona" +#: buzz/widgets/transcription_viewer/speaker_identification_widget.py:92 +msgid "1/8 Collecting transcripts" +msgstr "" + +#: buzz/widgets/transcription_viewer/speaker_identification_widget.py:106 +msgid "2/8 Loading audio" +msgstr "" + +#: buzz/widgets/transcription_viewer/speaker_identification_widget.py:115 +msgid "3/8 Loading alignment model" +msgstr "" + +#: buzz/widgets/transcription_viewer/speaker_identification_widget.py:121 +msgid "4/8 Processing audio" +msgstr "" + +#: buzz/widgets/transcription_viewer/speaker_identification_widget.py:133 +#, fuzzy +msgid "5/8 Preparing transcripts" +msgstr "Cancel·la la transcripció" + +#: buzz/widgets/transcription_viewer/speaker_identification_widget.py:151 +msgid "6/8 Identifying speakers" +msgstr "" + +#: buzz/widgets/transcription_viewer/speaker_identification_widget.py:160 +msgid "0/0 Error identifying speakers" +msgstr "" + +#: buzz/widgets/transcription_viewer/speaker_identification_widget.py:168 +msgid "7/8 Mapping speakers to transcripts" +msgstr "" + +#: buzz/widgets/transcription_viewer/speaker_identification_widget.py:207 +msgid "8/8 Identification done" +msgstr "" + +#: buzz/widgets/transcription_viewer/speaker_identification_widget.py:243 +msgid "Step 1: Identify speakers" +msgstr "" + +#: buzz/widgets/transcription_viewer/speaker_identification_widget.py:255 +msgid "Identify" +msgstr "" + +#: buzz/widgets/transcription_viewer/speaker_identification_widget.py:265 +msgid "Ready to identify speakers" +msgstr "" + +#: buzz/widgets/transcription_viewer/speaker_identification_widget.py:267 +msgid "Audio file not found" +msgstr "" + +#: buzz/widgets/transcription_viewer/speaker_identification_widget.py:283 +msgid "Step 2: Name speakers" +msgstr "" + +#: buzz/widgets/transcription_viewer/speaker_identification_widget.py:298 +#: buzz/widgets/transcription_viewer/speaker_identification_widget.py:391 +msgid "Play sample" +msgstr "" + +#: buzz/widgets/transcription_viewer/speaker_identification_widget.py:313 +msgid "Merge speaker sentences" +msgstr "" + +#: buzz/widgets/transcription_viewer/speaker_identification_widget.py:318 +#, fuzzy +msgid "Save" +msgstr "Desa el fitxer" + #: buzz/widgets/transcription_viewer/export_transcription_menu.py:82 msgid "Save File" msgstr "Desa el fitxer" diff --git a/buzz/locale/da_DK/LC_MESSAGES/buzz.po b/buzz/locale/da_DK/LC_MESSAGES/buzz.po index 7d356c67..fe698374 100644 --- a/buzz/locale/da_DK/LC_MESSAGES/buzz.po +++ b/buzz/locale/da_DK/LC_MESSAGES/buzz.po @@ -2,7 +2,7 @@ msgid "" msgstr "" "Project-Id-Version: \n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2025-11-28 16:49+0200\n" +"POT-Creation-Date: 2025-11-23 12:55+0200\n" "PO-Revision-Date: \n" "Last-Translator: Ole Guldberg2 \n" "Language-Team: \n" @@ -552,138 +552,213 @@ msgstr "Vis" msgid "Timestamps" msgstr "Tidsstempler" -#: buzz/widgets/transcription_viewer/transcription_viewer_widget.py:211 +#: buzz/widgets/transcription_viewer/transcription_viewer_widget.py:215 msgid "Export" msgstr "Eksporter" -#: buzz/widgets/transcription_viewer/transcription_viewer_widget.py:230 +#: buzz/widgets/transcription_viewer/transcription_viewer_widget.py:234 msgid "Translate" msgstr "Oversæt" -#: buzz/widgets/transcription_viewer/transcription_viewer_widget.py:240 -#: buzz/widgets/transcription_viewer/transcription_resizer_widget.py:177 +#: buzz/widgets/transcription_viewer/transcription_viewer_widget.py:244 +#: buzz/widgets/transcription_viewer/transcription_resizer_widget.py:175 msgid "Resize" msgstr "Behandel størrelse" -#: buzz/widgets/transcription_viewer/transcription_viewer_widget.py:252 +#: buzz/widgets/transcription_viewer/transcription_viewer_widget.py:257 +msgid "Identify Speakers" +msgstr "" + +#: buzz/widgets/transcription_viewer/transcription_viewer_widget.py:269 msgid "Find" msgstr "" -#: buzz/widgets/transcription_viewer/transcription_viewer_widget.py:255 +#: buzz/widgets/transcription_viewer/transcription_viewer_widget.py:272 msgid "Show/Hide Search Bar (Ctrl+F)" msgstr "" -#: buzz/widgets/transcription_viewer/transcription_viewer_widget.py:320 +#: buzz/widgets/transcription_viewer/transcription_viewer_widget.py:337 msgid "Find:" msgstr "" -#: buzz/widgets/transcription_viewer/transcription_viewer_widget.py:326 +#: buzz/widgets/transcription_viewer/transcription_viewer_widget.py:343 msgid "Enter text to find..." msgstr "" -#: buzz/widgets/transcription_viewer/transcription_viewer_widget.py:339 +#: buzz/widgets/transcription_viewer/transcription_viewer_widget.py:356 msgid "Previous match (Shift+Enter)" msgstr "" -#: buzz/widgets/transcription_viewer/transcription_viewer_widget.py:347 +#: buzz/widgets/transcription_viewer/transcription_viewer_widget.py:364 msgid "Next match (Enter)" msgstr "" -#: buzz/widgets/transcription_viewer/transcription_viewer_widget.py:355 +#: buzz/widgets/transcription_viewer/transcription_viewer_widget.py:372 msgid "Clear" msgstr "" -#: buzz/widgets/transcription_viewer/transcription_viewer_widget.py:382 +#: buzz/widgets/transcription_viewer/transcription_viewer_widget.py:399 msgid "Playback Controls:" msgstr "" -#: buzz/widgets/transcription_viewer/transcription_viewer_widget.py:387 +#: buzz/widgets/transcription_viewer/transcription_viewer_widget.py:404 msgid "Loop Segment" msgstr "" -#: buzz/widgets/transcription_viewer/transcription_viewer_widget.py:389 +#: buzz/widgets/transcription_viewer/transcription_viewer_widget.py:406 msgid "Enable/disable looping when clicking on transcript segments" msgstr "" -#: buzz/widgets/transcription_viewer/transcription_viewer_widget.py:395 +#: buzz/widgets/transcription_viewer/transcription_viewer_widget.py:412 msgid "Follow Audio" msgstr "" -#: buzz/widgets/transcription_viewer/transcription_viewer_widget.py:397 +#: buzz/widgets/transcription_viewer/transcription_viewer_widget.py:414 msgid "" "Enable/disable following the current audio position in the transcript. When " "enabled, automatically scrolls to current text." msgstr "" -#: buzz/widgets/transcription_viewer/transcription_viewer_widget.py:444 +#: buzz/widgets/transcription_viewer/transcription_viewer_widget.py:461 msgid "Scroll to Current" msgstr "" -#: buzz/widgets/transcription_viewer/transcription_viewer_widget.py:446 +#: buzz/widgets/transcription_viewer/transcription_viewer_widget.py:463 msgid "Scroll to the currently spoken text" msgstr "" -#: buzz/widgets/transcription_viewer/transcription_viewer_widget.py:768 +#: buzz/widgets/transcription_viewer/transcription_viewer_widget.py:785 msgid "1 of 100+ matches" msgstr "" -#: buzz/widgets/transcription_viewer/transcription_viewer_widget.py:770 +#: buzz/widgets/transcription_viewer/transcription_viewer_widget.py:787 msgid "1 of " msgstr "" -#: buzz/widgets/transcription_viewer/transcription_viewer_widget.py:770 -#: buzz/widgets/transcription_viewer/transcription_viewer_widget.py:836 +#: buzz/widgets/transcription_viewer/transcription_viewer_widget.py:787 +#: buzz/widgets/transcription_viewer/transcription_viewer_widget.py:853 msgid " matches" msgstr "" -#: buzz/widgets/transcription_viewer/transcription_viewer_widget.py:775 +#: buzz/widgets/transcription_viewer/transcription_viewer_widget.py:792 msgid "No matches found" msgstr "" -#: buzz/widgets/transcription_viewer/transcription_viewer_widget.py:834 +#: buzz/widgets/transcription_viewer/transcription_viewer_widget.py:851 msgid " of 100+ matches" msgstr "" -#: buzz/widgets/transcription_viewer/transcription_viewer_widget.py:836 +#: buzz/widgets/transcription_viewer/transcription_viewer_widget.py:853 msgid " of " msgstr "" -#: buzz/widgets/transcription_viewer/transcription_viewer_widget.py:1191 +#: buzz/widgets/transcription_viewer/transcription_viewer_widget.py:1208 msgid "API Key Required" msgstr "API-nøgle påkrævet" -#: buzz/widgets/transcription_viewer/transcription_viewer_widget.py:1192 +#: buzz/widgets/transcription_viewer/transcription_viewer_widget.py:1209 msgid "Please enter OpenAI API Key in preferences" msgstr "Indtast venligst OpenAI API-nøgle i indstillinger" -#: buzz/widgets/transcription_viewer/transcription_resizer_widget.py:159 +#: buzz/widgets/transcription_viewer/transcription_resizer_widget.py:157 msgid "Resize Options" msgstr "Størrelsesindstillinger" -#: buzz/widgets/transcription_viewer/transcription_resizer_widget.py:170 +#: buzz/widgets/transcription_viewer/transcription_resizer_widget.py:168 msgid "Desired subtitle length" msgstr "Ønskede undertekst længde" -#: buzz/widgets/transcription_viewer/transcription_resizer_widget.py:195 +#: buzz/widgets/transcription_viewer/transcription_resizer_widget.py:193 msgid "Merge Options" msgstr "Sammenfletningsindstillinger" -#: buzz/widgets/transcription_viewer/transcription_resizer_widget.py:206 +#: buzz/widgets/transcription_viewer/transcription_resizer_widget.py:204 msgid "Merge by gap" msgstr "Sammenflet ved hul" -#: buzz/widgets/transcription_viewer/transcription_resizer_widget.py:214 +#: buzz/widgets/transcription_viewer/transcription_resizer_widget.py:212 msgid "Split by punctuation" msgstr "Split ved punktum" -#: buzz/widgets/transcription_viewer/transcription_resizer_widget.py:222 +#: buzz/widgets/transcription_viewer/transcription_resizer_widget.py:220 msgid "Split by max length" msgstr "Split ved max længde" -#: buzz/widgets/transcription_viewer/transcription_resizer_widget.py:234 +#: buzz/widgets/transcription_viewer/transcription_resizer_widget.py:232 msgid "Merge" msgstr "Sammenflet" +#: buzz/widgets/transcription_viewer/speaker_identification_widget.py:92 +msgid "1/8 Collecting transcripts" +msgstr "" + +#: buzz/widgets/transcription_viewer/speaker_identification_widget.py:106 +msgid "2/8 Loading audio" +msgstr "" + +#: buzz/widgets/transcription_viewer/speaker_identification_widget.py:115 +msgid "3/8 Loading alignment model" +msgstr "" + +#: buzz/widgets/transcription_viewer/speaker_identification_widget.py:121 +msgid "4/8 Processing audio" +msgstr "" + +#: buzz/widgets/transcription_viewer/speaker_identification_widget.py:133 +#, fuzzy +msgid "5/8 Preparing transcripts" +msgstr "Afbryd transkription" + +#: buzz/widgets/transcription_viewer/speaker_identification_widget.py:151 +msgid "6/8 Identifying speakers" +msgstr "" + +#: buzz/widgets/transcription_viewer/speaker_identification_widget.py:160 +msgid "0/0 Error identifying speakers" +msgstr "" + +#: buzz/widgets/transcription_viewer/speaker_identification_widget.py:168 +msgid "7/8 Mapping speakers to transcripts" +msgstr "" + +#: buzz/widgets/transcription_viewer/speaker_identification_widget.py:207 +msgid "8/8 Identification done" +msgstr "" + +#: buzz/widgets/transcription_viewer/speaker_identification_widget.py:243 +msgid "Step 1: Identify speakers" +msgstr "" + +#: buzz/widgets/transcription_viewer/speaker_identification_widget.py:255 +msgid "Identify" +msgstr "" + +#: buzz/widgets/transcription_viewer/speaker_identification_widget.py:265 +msgid "Ready to identify speakers" +msgstr "" + +#: buzz/widgets/transcription_viewer/speaker_identification_widget.py:267 +msgid "Audio file not found" +msgstr "" + +#: buzz/widgets/transcription_viewer/speaker_identification_widget.py:283 +msgid "Step 2: Name speakers" +msgstr "" + +#: buzz/widgets/transcription_viewer/speaker_identification_widget.py:298 +#: buzz/widgets/transcription_viewer/speaker_identification_widget.py:391 +msgid "Play sample" +msgstr "" + +#: buzz/widgets/transcription_viewer/speaker_identification_widget.py:313 +msgid "Merge speaker sentences" +msgstr "" + +#: buzz/widgets/transcription_viewer/speaker_identification_widget.py:318 +#, fuzzy +msgid "Save" +msgstr "Gem fil" + #: buzz/widgets/transcription_viewer/export_transcription_menu.py:82 msgid "Save File" msgstr "Gem fil" diff --git a/buzz/locale/de_DE/LC_MESSAGES/buzz.po b/buzz/locale/de_DE/LC_MESSAGES/buzz.po index 14ebc504..1b547455 100644 --- a/buzz/locale/de_DE/LC_MESSAGES/buzz.po +++ b/buzz/locale/de_DE/LC_MESSAGES/buzz.po @@ -6,7 +6,7 @@ msgid "" msgstr "" "Project-Id-Version: \n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2025-11-28 16:49+0200\n" +"POT-Creation-Date: 2025-11-23 12:55+0200\n" "PO-Revision-Date: 2025-03-05 14:41+0100\n" "Last-Translator: \n" "Language-Team: \n" @@ -552,138 +552,213 @@ msgstr "Anzeigen" msgid "Timestamps" msgstr "Zeitstempel" -#: buzz/widgets/transcription_viewer/transcription_viewer_widget.py:211 +#: buzz/widgets/transcription_viewer/transcription_viewer_widget.py:215 msgid "Export" msgstr "Export" -#: buzz/widgets/transcription_viewer/transcription_viewer_widget.py:230 +#: buzz/widgets/transcription_viewer/transcription_viewer_widget.py:234 msgid "Translate" msgstr "Übersetzen" -#: buzz/widgets/transcription_viewer/transcription_viewer_widget.py:240 -#: buzz/widgets/transcription_viewer/transcription_resizer_widget.py:177 +#: buzz/widgets/transcription_viewer/transcription_viewer_widget.py:244 +#: buzz/widgets/transcription_viewer/transcription_resizer_widget.py:175 msgid "Resize" msgstr "Größe ändern" -#: buzz/widgets/transcription_viewer/transcription_viewer_widget.py:252 +#: buzz/widgets/transcription_viewer/transcription_viewer_widget.py:257 +msgid "Identify Speakers" +msgstr "" + +#: buzz/widgets/transcription_viewer/transcription_viewer_widget.py:269 msgid "Find" msgstr "" -#: buzz/widgets/transcription_viewer/transcription_viewer_widget.py:255 +#: buzz/widgets/transcription_viewer/transcription_viewer_widget.py:272 msgid "Show/Hide Search Bar (Ctrl+F)" msgstr "" -#: buzz/widgets/transcription_viewer/transcription_viewer_widget.py:320 +#: buzz/widgets/transcription_viewer/transcription_viewer_widget.py:337 msgid "Find:" msgstr "" -#: buzz/widgets/transcription_viewer/transcription_viewer_widget.py:326 +#: buzz/widgets/transcription_viewer/transcription_viewer_widget.py:343 msgid "Enter text to find..." msgstr "" -#: buzz/widgets/transcription_viewer/transcription_viewer_widget.py:339 +#: buzz/widgets/transcription_viewer/transcription_viewer_widget.py:356 msgid "Previous match (Shift+Enter)" msgstr "" -#: buzz/widgets/transcription_viewer/transcription_viewer_widget.py:347 +#: buzz/widgets/transcription_viewer/transcription_viewer_widget.py:364 msgid "Next match (Enter)" msgstr "" -#: buzz/widgets/transcription_viewer/transcription_viewer_widget.py:355 +#: buzz/widgets/transcription_viewer/transcription_viewer_widget.py:372 msgid "Clear" msgstr "" -#: buzz/widgets/transcription_viewer/transcription_viewer_widget.py:382 +#: buzz/widgets/transcription_viewer/transcription_viewer_widget.py:399 msgid "Playback Controls:" msgstr "" -#: buzz/widgets/transcription_viewer/transcription_viewer_widget.py:387 +#: buzz/widgets/transcription_viewer/transcription_viewer_widget.py:404 msgid "Loop Segment" msgstr "" -#: buzz/widgets/transcription_viewer/transcription_viewer_widget.py:389 +#: buzz/widgets/transcription_viewer/transcription_viewer_widget.py:406 msgid "Enable/disable looping when clicking on transcript segments" msgstr "" -#: buzz/widgets/transcription_viewer/transcription_viewer_widget.py:395 +#: buzz/widgets/transcription_viewer/transcription_viewer_widget.py:412 msgid "Follow Audio" msgstr "" -#: buzz/widgets/transcription_viewer/transcription_viewer_widget.py:397 +#: buzz/widgets/transcription_viewer/transcription_viewer_widget.py:414 msgid "" "Enable/disable following the current audio position in the transcript. When " "enabled, automatically scrolls to current text." msgstr "" -#: buzz/widgets/transcription_viewer/transcription_viewer_widget.py:444 +#: buzz/widgets/transcription_viewer/transcription_viewer_widget.py:461 msgid "Scroll to Current" msgstr "" -#: buzz/widgets/transcription_viewer/transcription_viewer_widget.py:446 +#: buzz/widgets/transcription_viewer/transcription_viewer_widget.py:463 msgid "Scroll to the currently spoken text" msgstr "" -#: buzz/widgets/transcription_viewer/transcription_viewer_widget.py:768 +#: buzz/widgets/transcription_viewer/transcription_viewer_widget.py:785 msgid "1 of 100+ matches" msgstr "" -#: buzz/widgets/transcription_viewer/transcription_viewer_widget.py:770 +#: buzz/widgets/transcription_viewer/transcription_viewer_widget.py:787 msgid "1 of " msgstr "" -#: buzz/widgets/transcription_viewer/transcription_viewer_widget.py:770 -#: buzz/widgets/transcription_viewer/transcription_viewer_widget.py:836 +#: buzz/widgets/transcription_viewer/transcription_viewer_widget.py:787 +#: buzz/widgets/transcription_viewer/transcription_viewer_widget.py:853 msgid " matches" msgstr "" -#: buzz/widgets/transcription_viewer/transcription_viewer_widget.py:775 +#: buzz/widgets/transcription_viewer/transcription_viewer_widget.py:792 msgid "No matches found" msgstr "" -#: buzz/widgets/transcription_viewer/transcription_viewer_widget.py:834 +#: buzz/widgets/transcription_viewer/transcription_viewer_widget.py:851 msgid " of 100+ matches" msgstr "" -#: buzz/widgets/transcription_viewer/transcription_viewer_widget.py:836 +#: buzz/widgets/transcription_viewer/transcription_viewer_widget.py:853 msgid " of " msgstr "" -#: buzz/widgets/transcription_viewer/transcription_viewer_widget.py:1191 +#: buzz/widgets/transcription_viewer/transcription_viewer_widget.py:1208 msgid "API Key Required" msgstr "API-Schlüssel erforderlich" -#: buzz/widgets/transcription_viewer/transcription_viewer_widget.py:1192 +#: buzz/widgets/transcription_viewer/transcription_viewer_widget.py:1209 msgid "Please enter OpenAI API Key in preferences" msgstr "Bitte geben Sie den OpenAI-API-Schlüssel in den Einstellungen ein" -#: buzz/widgets/transcription_viewer/transcription_resizer_widget.py:159 +#: buzz/widgets/transcription_viewer/transcription_resizer_widget.py:157 msgid "Resize Options" msgstr "Größenänderungsoptionen" -#: buzz/widgets/transcription_viewer/transcription_resizer_widget.py:170 +#: buzz/widgets/transcription_viewer/transcription_resizer_widget.py:168 msgid "Desired subtitle length" msgstr "Gewünschte Untertitellänge" -#: buzz/widgets/transcription_viewer/transcription_resizer_widget.py:195 +#: buzz/widgets/transcription_viewer/transcription_resizer_widget.py:193 msgid "Merge Options" msgstr "Zusammenführungsoptionen" -#: buzz/widgets/transcription_viewer/transcription_resizer_widget.py:206 +#: buzz/widgets/transcription_viewer/transcription_resizer_widget.py:204 msgid "Merge by gap" msgstr "Nach Abstand zusammenführen" -#: buzz/widgets/transcription_viewer/transcription_resizer_widget.py:214 +#: buzz/widgets/transcription_viewer/transcription_resizer_widget.py:212 msgid "Split by punctuation" msgstr "Durch Satzzeichen getrennt" -#: buzz/widgets/transcription_viewer/transcription_resizer_widget.py:222 +#: buzz/widgets/transcription_viewer/transcription_resizer_widget.py:220 msgid "Split by max length" msgstr "Aufgeteilt nach maximaler Länge" -#: buzz/widgets/transcription_viewer/transcription_resizer_widget.py:234 +#: buzz/widgets/transcription_viewer/transcription_resizer_widget.py:232 msgid "Merge" msgstr "Vereinigen" +#: buzz/widgets/transcription_viewer/speaker_identification_widget.py:92 +msgid "1/8 Collecting transcripts" +msgstr "" + +#: buzz/widgets/transcription_viewer/speaker_identification_widget.py:106 +msgid "2/8 Loading audio" +msgstr "" + +#: buzz/widgets/transcription_viewer/speaker_identification_widget.py:115 +msgid "3/8 Loading alignment model" +msgstr "" + +#: buzz/widgets/transcription_viewer/speaker_identification_widget.py:121 +msgid "4/8 Processing audio" +msgstr "" + +#: buzz/widgets/transcription_viewer/speaker_identification_widget.py:133 +#, fuzzy +msgid "5/8 Preparing transcripts" +msgstr "Transkription abbrechen" + +#: buzz/widgets/transcription_viewer/speaker_identification_widget.py:151 +msgid "6/8 Identifying speakers" +msgstr "" + +#: buzz/widgets/transcription_viewer/speaker_identification_widget.py:160 +msgid "0/0 Error identifying speakers" +msgstr "" + +#: buzz/widgets/transcription_viewer/speaker_identification_widget.py:168 +msgid "7/8 Mapping speakers to transcripts" +msgstr "" + +#: buzz/widgets/transcription_viewer/speaker_identification_widget.py:207 +msgid "8/8 Identification done" +msgstr "" + +#: buzz/widgets/transcription_viewer/speaker_identification_widget.py:243 +msgid "Step 1: Identify speakers" +msgstr "" + +#: buzz/widgets/transcription_viewer/speaker_identification_widget.py:255 +msgid "Identify" +msgstr "" + +#: buzz/widgets/transcription_viewer/speaker_identification_widget.py:265 +msgid "Ready to identify speakers" +msgstr "" + +#: buzz/widgets/transcription_viewer/speaker_identification_widget.py:267 +msgid "Audio file not found" +msgstr "" + +#: buzz/widgets/transcription_viewer/speaker_identification_widget.py:283 +msgid "Step 2: Name speakers" +msgstr "" + +#: buzz/widgets/transcription_viewer/speaker_identification_widget.py:298 +#: buzz/widgets/transcription_viewer/speaker_identification_widget.py:391 +msgid "Play sample" +msgstr "" + +#: buzz/widgets/transcription_viewer/speaker_identification_widget.py:313 +msgid "Merge speaker sentences" +msgstr "" + +#: buzz/widgets/transcription_viewer/speaker_identification_widget.py:318 +#, fuzzy +msgid "Save" +msgstr "Datei speichern" + #: buzz/widgets/transcription_viewer/export_transcription_menu.py:82 msgid "Save File" msgstr "Datei speichern" diff --git a/buzz/locale/en_US/LC_MESSAGES/buzz.po b/buzz/locale/en_US/LC_MESSAGES/buzz.po index 87f47cea..02bac9f4 100644 --- a/buzz/locale/en_US/LC_MESSAGES/buzz.po +++ b/buzz/locale/en_US/LC_MESSAGES/buzz.po @@ -8,7 +8,7 @@ msgid "" msgstr "" "Project-Id-Version: PACKAGE VERSION\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2025-11-28 16:49+0200\n" +"POT-Creation-Date: 2025-11-23 12:55+0200\n" "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" "Last-Translator: FULL NAME \n" "Language-Team: LANGUAGE \n" @@ -540,138 +540,211 @@ msgstr "" msgid "Timestamps" msgstr "" -#: buzz/widgets/transcription_viewer/transcription_viewer_widget.py:211 +#: buzz/widgets/transcription_viewer/transcription_viewer_widget.py:215 msgid "Export" msgstr "" -#: buzz/widgets/transcription_viewer/transcription_viewer_widget.py:230 +#: buzz/widgets/transcription_viewer/transcription_viewer_widget.py:234 msgid "Translate" msgstr "" -#: buzz/widgets/transcription_viewer/transcription_viewer_widget.py:240 -#: buzz/widgets/transcription_viewer/transcription_resizer_widget.py:177 +#: buzz/widgets/transcription_viewer/transcription_viewer_widget.py:244 +#: buzz/widgets/transcription_viewer/transcription_resizer_widget.py:175 msgid "Resize" msgstr "" -#: buzz/widgets/transcription_viewer/transcription_viewer_widget.py:252 +#: buzz/widgets/transcription_viewer/transcription_viewer_widget.py:257 +msgid "Identify Speakers" +msgstr "" + +#: buzz/widgets/transcription_viewer/transcription_viewer_widget.py:269 msgid "Find" msgstr "" -#: buzz/widgets/transcription_viewer/transcription_viewer_widget.py:255 +#: buzz/widgets/transcription_viewer/transcription_viewer_widget.py:272 msgid "Show/Hide Search Bar (Ctrl+F)" msgstr "" -#: buzz/widgets/transcription_viewer/transcription_viewer_widget.py:320 +#: buzz/widgets/transcription_viewer/transcription_viewer_widget.py:337 msgid "Find:" msgstr "" -#: buzz/widgets/transcription_viewer/transcription_viewer_widget.py:326 +#: buzz/widgets/transcription_viewer/transcription_viewer_widget.py:343 msgid "Enter text to find..." msgstr "" -#: buzz/widgets/transcription_viewer/transcription_viewer_widget.py:339 +#: buzz/widgets/transcription_viewer/transcription_viewer_widget.py:356 msgid "Previous match (Shift+Enter)" msgstr "" -#: buzz/widgets/transcription_viewer/transcription_viewer_widget.py:347 +#: buzz/widgets/transcription_viewer/transcription_viewer_widget.py:364 msgid "Next match (Enter)" msgstr "" -#: buzz/widgets/transcription_viewer/transcription_viewer_widget.py:355 +#: buzz/widgets/transcription_viewer/transcription_viewer_widget.py:372 msgid "Clear" msgstr "" -#: buzz/widgets/transcription_viewer/transcription_viewer_widget.py:382 +#: buzz/widgets/transcription_viewer/transcription_viewer_widget.py:399 msgid "Playback Controls:" msgstr "" -#: buzz/widgets/transcription_viewer/transcription_viewer_widget.py:387 +#: buzz/widgets/transcription_viewer/transcription_viewer_widget.py:404 msgid "Loop Segment" msgstr "" -#: buzz/widgets/transcription_viewer/transcription_viewer_widget.py:389 +#: buzz/widgets/transcription_viewer/transcription_viewer_widget.py:406 msgid "Enable/disable looping when clicking on transcript segments" msgstr "" -#: buzz/widgets/transcription_viewer/transcription_viewer_widget.py:395 +#: buzz/widgets/transcription_viewer/transcription_viewer_widget.py:412 msgid "Follow Audio" msgstr "" -#: buzz/widgets/transcription_viewer/transcription_viewer_widget.py:397 +#: buzz/widgets/transcription_viewer/transcription_viewer_widget.py:414 msgid "" "Enable/disable following the current audio position in the transcript. When " "enabled, automatically scrolls to current text." msgstr "" -#: buzz/widgets/transcription_viewer/transcription_viewer_widget.py:444 +#: buzz/widgets/transcription_viewer/transcription_viewer_widget.py:461 msgid "Scroll to Current" msgstr "" -#: buzz/widgets/transcription_viewer/transcription_viewer_widget.py:446 +#: buzz/widgets/transcription_viewer/transcription_viewer_widget.py:463 msgid "Scroll to the currently spoken text" msgstr "" -#: buzz/widgets/transcription_viewer/transcription_viewer_widget.py:768 +#: buzz/widgets/transcription_viewer/transcription_viewer_widget.py:785 msgid "1 of 100+ matches" msgstr "" -#: buzz/widgets/transcription_viewer/transcription_viewer_widget.py:770 +#: buzz/widgets/transcription_viewer/transcription_viewer_widget.py:787 msgid "1 of " msgstr "" -#: buzz/widgets/transcription_viewer/transcription_viewer_widget.py:770 -#: buzz/widgets/transcription_viewer/transcription_viewer_widget.py:836 +#: buzz/widgets/transcription_viewer/transcription_viewer_widget.py:787 +#: buzz/widgets/transcription_viewer/transcription_viewer_widget.py:853 msgid " matches" msgstr "" -#: buzz/widgets/transcription_viewer/transcription_viewer_widget.py:775 +#: buzz/widgets/transcription_viewer/transcription_viewer_widget.py:792 msgid "No matches found" msgstr "" -#: buzz/widgets/transcription_viewer/transcription_viewer_widget.py:834 +#: buzz/widgets/transcription_viewer/transcription_viewer_widget.py:851 msgid " of 100+ matches" msgstr "" -#: buzz/widgets/transcription_viewer/transcription_viewer_widget.py:836 +#: buzz/widgets/transcription_viewer/transcription_viewer_widget.py:853 msgid " of " msgstr "" -#: buzz/widgets/transcription_viewer/transcription_viewer_widget.py:1191 +#: buzz/widgets/transcription_viewer/transcription_viewer_widget.py:1208 msgid "API Key Required" msgstr "" -#: buzz/widgets/transcription_viewer/transcription_viewer_widget.py:1192 +#: buzz/widgets/transcription_viewer/transcription_viewer_widget.py:1209 msgid "Please enter OpenAI API Key in preferences" msgstr "" -#: buzz/widgets/transcription_viewer/transcription_resizer_widget.py:159 +#: buzz/widgets/transcription_viewer/transcription_resizer_widget.py:157 msgid "Resize Options" msgstr "" -#: buzz/widgets/transcription_viewer/transcription_resizer_widget.py:170 +#: buzz/widgets/transcription_viewer/transcription_resizer_widget.py:168 msgid "Desired subtitle length" msgstr "" -#: buzz/widgets/transcription_viewer/transcription_resizer_widget.py:195 +#: buzz/widgets/transcription_viewer/transcription_resizer_widget.py:193 msgid "Merge Options" msgstr "" -#: buzz/widgets/transcription_viewer/transcription_resizer_widget.py:206 +#: buzz/widgets/transcription_viewer/transcription_resizer_widget.py:204 msgid "Merge by gap" msgstr "" -#: buzz/widgets/transcription_viewer/transcription_resizer_widget.py:214 +#: buzz/widgets/transcription_viewer/transcription_resizer_widget.py:212 msgid "Split by punctuation" msgstr "" -#: buzz/widgets/transcription_viewer/transcription_resizer_widget.py:222 +#: buzz/widgets/transcription_viewer/transcription_resizer_widget.py:220 msgid "Split by max length" msgstr "" -#: buzz/widgets/transcription_viewer/transcription_resizer_widget.py:234 +#: buzz/widgets/transcription_viewer/transcription_resizer_widget.py:232 msgid "Merge" msgstr "" +#: buzz/widgets/transcription_viewer/speaker_identification_widget.py:92 +msgid "1/8 Collecting transcripts" +msgstr "" + +#: buzz/widgets/transcription_viewer/speaker_identification_widget.py:106 +msgid "2/8 Loading audio" +msgstr "" + +#: buzz/widgets/transcription_viewer/speaker_identification_widget.py:115 +msgid "3/8 Loading alignment model" +msgstr "" + +#: buzz/widgets/transcription_viewer/speaker_identification_widget.py:121 +msgid "4/8 Processing audio" +msgstr "" + +#: buzz/widgets/transcription_viewer/speaker_identification_widget.py:133 +msgid "5/8 Preparing transcripts" +msgstr "" + +#: buzz/widgets/transcription_viewer/speaker_identification_widget.py:151 +msgid "6/8 Identifying speakers" +msgstr "" + +#: buzz/widgets/transcription_viewer/speaker_identification_widget.py:160 +msgid "0/0 Error identifying speakers" +msgstr "" + +#: buzz/widgets/transcription_viewer/speaker_identification_widget.py:168 +msgid "7/8 Mapping speakers to transcripts" +msgstr "" + +#: buzz/widgets/transcription_viewer/speaker_identification_widget.py:207 +msgid "8/8 Identification done" +msgstr "" + +#: buzz/widgets/transcription_viewer/speaker_identification_widget.py:243 +msgid "Step 1: Identify speakers" +msgstr "" + +#: buzz/widgets/transcription_viewer/speaker_identification_widget.py:255 +msgid "Identify" +msgstr "" + +#: buzz/widgets/transcription_viewer/speaker_identification_widget.py:265 +msgid "Ready to identify speakers" +msgstr "" + +#: buzz/widgets/transcription_viewer/speaker_identification_widget.py:267 +msgid "Audio file not found" +msgstr "" + +#: buzz/widgets/transcription_viewer/speaker_identification_widget.py:283 +msgid "Step 2: Name speakers" +msgstr "" + +#: buzz/widgets/transcription_viewer/speaker_identification_widget.py:298 +#: buzz/widgets/transcription_viewer/speaker_identification_widget.py:391 +msgid "Play sample" +msgstr "" + +#: buzz/widgets/transcription_viewer/speaker_identification_widget.py:313 +msgid "Merge speaker sentences" +msgstr "" + +#: buzz/widgets/transcription_viewer/speaker_identification_widget.py:318 +msgid "Save" +msgstr "" + #: buzz/widgets/transcription_viewer/export_transcription_menu.py:82 msgid "Save File" msgstr "" diff --git a/buzz/locale/es_ES/LC_MESSAGES/buzz.po b/buzz/locale/es_ES/LC_MESSAGES/buzz.po index 133209e1..1c7d3e0c 100644 --- a/buzz/locale/es_ES/LC_MESSAGES/buzz.po +++ b/buzz/locale/es_ES/LC_MESSAGES/buzz.po @@ -7,7 +7,7 @@ msgid "" msgstr "" "Project-Id-Version: \n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2025-11-28 16:49+0200\n" +"POT-Creation-Date: 2025-11-23 12:55+0200\n" "PO-Revision-Date: 2025-09-08 12:43+0200\n" "Last-Translator: Éric Duarte \n" "Language-Team: \n" @@ -589,66 +589,70 @@ msgstr "Ver" msgid "Timestamps" msgstr "Marcas de tiempo" -#: buzz/widgets/transcription_viewer/transcription_viewer_widget.py:211 +#: buzz/widgets/transcription_viewer/transcription_viewer_widget.py:215 msgid "Export" msgstr "Exportar" -#: buzz/widgets/transcription_viewer/transcription_viewer_widget.py:230 +#: buzz/widgets/transcription_viewer/transcription_viewer_widget.py:234 msgid "Translate" msgstr "Traducir" -#: buzz/widgets/transcription_viewer/transcription_viewer_widget.py:240 -#: buzz/widgets/transcription_viewer/transcription_resizer_widget.py:177 +#: buzz/widgets/transcription_viewer/transcription_viewer_widget.py:244 +#: buzz/widgets/transcription_viewer/transcription_resizer_widget.py:175 msgid "Resize" msgstr "Cambiar el tamaño" -#: buzz/widgets/transcription_viewer/transcription_viewer_widget.py:252 +#: buzz/widgets/transcription_viewer/transcription_viewer_widget.py:257 +msgid "Identify Speakers" +msgstr "" + +#: buzz/widgets/transcription_viewer/transcription_viewer_widget.py:269 msgid "Find" msgstr "Buscar" -#: buzz/widgets/transcription_viewer/transcription_viewer_widget.py:255 +#: buzz/widgets/transcription_viewer/transcription_viewer_widget.py:272 msgid "Show/Hide Search Bar (Ctrl+F)" msgstr "Mostrar/Ocultar barra de búsqueda (Ctrl+F)" -#: buzz/widgets/transcription_viewer/transcription_viewer_widget.py:320 +#: buzz/widgets/transcription_viewer/transcription_viewer_widget.py:337 msgid "Find:" msgstr "Encontrar:" -#: buzz/widgets/transcription_viewer/transcription_viewer_widget.py:326 +#: buzz/widgets/transcription_viewer/transcription_viewer_widget.py:343 msgid "Enter text to find..." msgstr "Introducir texto para encontrar..." -#: buzz/widgets/transcription_viewer/transcription_viewer_widget.py:339 +#: buzz/widgets/transcription_viewer/transcription_viewer_widget.py:356 msgid "Previous match (Shift+Enter)" msgstr "Coincidencia anterior (Mayús+Intro)" -#: buzz/widgets/transcription_viewer/transcription_viewer_widget.py:347 +#: buzz/widgets/transcription_viewer/transcription_viewer_widget.py:364 msgid "Next match (Enter)" msgstr "Siguiente coincidencia (Enter)" -#: buzz/widgets/transcription_viewer/transcription_viewer_widget.py:355 +#: buzz/widgets/transcription_viewer/transcription_viewer_widget.py:372 msgid "Clear" msgstr "Limpiar" -#: buzz/widgets/transcription_viewer/transcription_viewer_widget.py:382 +#: buzz/widgets/transcription_viewer/transcription_viewer_widget.py:399 msgid "Playback Controls:" msgstr "Controles de reproducción:" -#: buzz/widgets/transcription_viewer/transcription_viewer_widget.py:387 +#: buzz/widgets/transcription_viewer/transcription_viewer_widget.py:404 msgid "Loop Segment" msgstr "Segmento de bucle" -#: buzz/widgets/transcription_viewer/transcription_viewer_widget.py:389 +#: buzz/widgets/transcription_viewer/transcription_viewer_widget.py:406 msgid "Enable/disable looping when clicking on transcript segments" msgstr "" "Activar/desactivar la reproducción en bucle al hacer clic en segmentos de la " "transcripción" -#: buzz/widgets/transcription_viewer/transcription_viewer_widget.py:395 +#: buzz/widgets/transcription_viewer/transcription_viewer_widget.py:412 msgid "Follow Audio" msgstr "Seguir audio" -#: buzz/widgets/transcription_viewer/transcription_viewer_widget.py:397 +#: buzz/widgets/transcription_viewer/transcription_viewer_widget.py:414 msgid "" "Enable/disable following the current audio position in the transcript. When " "enabled, automatically scrolls to current text." @@ -657,75 +661,148 @@ msgstr "" "transcripción. Cuando está activado, se desplaza automáticamente al texto " "actual." -#: buzz/widgets/transcription_viewer/transcription_viewer_widget.py:444 +#: buzz/widgets/transcription_viewer/transcription_viewer_widget.py:461 msgid "Scroll to Current" msgstr "Desplácese hasta Actual" -#: buzz/widgets/transcription_viewer/transcription_viewer_widget.py:446 +#: buzz/widgets/transcription_viewer/transcription_viewer_widget.py:463 msgid "Scroll to the currently spoken text" msgstr "Desplazarse hasta el texto hablado actualmente" -#: buzz/widgets/transcription_viewer/transcription_viewer_widget.py:768 +#: buzz/widgets/transcription_viewer/transcription_viewer_widget.py:785 msgid "1 of 100+ matches" msgstr "1 de 100+ coincidencias" -#: buzz/widgets/transcription_viewer/transcription_viewer_widget.py:770 +#: buzz/widgets/transcription_viewer/transcription_viewer_widget.py:787 msgid "1 of " msgstr "1 de " -#: buzz/widgets/transcription_viewer/transcription_viewer_widget.py:770 -#: buzz/widgets/transcription_viewer/transcription_viewer_widget.py:836 +#: buzz/widgets/transcription_viewer/transcription_viewer_widget.py:787 +#: buzz/widgets/transcription_viewer/transcription_viewer_widget.py:853 msgid " matches" msgstr " coincidencias" -#: buzz/widgets/transcription_viewer/transcription_viewer_widget.py:775 +#: buzz/widgets/transcription_viewer/transcription_viewer_widget.py:792 msgid "No matches found" msgstr "No se encontraron coincidencias" -#: buzz/widgets/transcription_viewer/transcription_viewer_widget.py:834 +#: buzz/widgets/transcription_viewer/transcription_viewer_widget.py:851 msgid " of 100+ matches" msgstr " de 100+ coincidencias" -#: buzz/widgets/transcription_viewer/transcription_viewer_widget.py:836 +#: buzz/widgets/transcription_viewer/transcription_viewer_widget.py:853 msgid " of " msgstr " de " -#: buzz/widgets/transcription_viewer/transcription_viewer_widget.py:1191 +#: buzz/widgets/transcription_viewer/transcription_viewer_widget.py:1208 msgid "API Key Required" msgstr "Clave de API requerida" -#: buzz/widgets/transcription_viewer/transcription_viewer_widget.py:1192 +#: buzz/widgets/transcription_viewer/transcription_viewer_widget.py:1209 msgid "Please enter OpenAI API Key in preferences" msgstr "Ingrese la clave API de OpenAI en las preferencias" -#: buzz/widgets/transcription_viewer/transcription_resizer_widget.py:159 +#: buzz/widgets/transcription_viewer/transcription_resizer_widget.py:157 msgid "Resize Options" msgstr "Opciones de cambio de tamaño" -#: buzz/widgets/transcription_viewer/transcription_resizer_widget.py:170 +#: buzz/widgets/transcription_viewer/transcription_resizer_widget.py:168 msgid "Desired subtitle length" msgstr "Longitud deseada de los subtítulos" -#: buzz/widgets/transcription_viewer/transcription_resizer_widget.py:195 +#: buzz/widgets/transcription_viewer/transcription_resizer_widget.py:193 msgid "Merge Options" msgstr "Opciones de fusión" -#: buzz/widgets/transcription_viewer/transcription_resizer_widget.py:206 +#: buzz/widgets/transcription_viewer/transcription_resizer_widget.py:204 msgid "Merge by gap" msgstr "Fusión por hueco" -#: buzz/widgets/transcription_viewer/transcription_resizer_widget.py:214 +#: buzz/widgets/transcription_viewer/transcription_resizer_widget.py:212 msgid "Split by punctuation" msgstr "Dividido por puntuación" -#: buzz/widgets/transcription_viewer/transcription_resizer_widget.py:222 +#: buzz/widgets/transcription_viewer/transcription_resizer_widget.py:220 msgid "Split by max length" msgstr "Dividido por la longitud máxima" -#: buzz/widgets/transcription_viewer/transcription_resizer_widget.py:234 +#: buzz/widgets/transcription_viewer/transcription_resizer_widget.py:232 msgid "Merge" msgstr "Fusión" +#: buzz/widgets/transcription_viewer/speaker_identification_widget.py:92 +msgid "1/8 Collecting transcripts" +msgstr "" + +#: buzz/widgets/transcription_viewer/speaker_identification_widget.py:106 +msgid "2/8 Loading audio" +msgstr "" + +#: buzz/widgets/transcription_viewer/speaker_identification_widget.py:115 +msgid "3/8 Loading alignment model" +msgstr "" + +#: buzz/widgets/transcription_viewer/speaker_identification_widget.py:121 +msgid "4/8 Processing audio" +msgstr "" + +# automatic translation +#: buzz/widgets/transcription_viewer/speaker_identification_widget.py:133 +#, fuzzy +msgid "5/8 Preparing transcripts" +msgstr "Cancelar transcripción" + +#: buzz/widgets/transcription_viewer/speaker_identification_widget.py:151 +msgid "6/8 Identifying speakers" +msgstr "" + +#: buzz/widgets/transcription_viewer/speaker_identification_widget.py:160 +msgid "0/0 Error identifying speakers" +msgstr "" + +#: buzz/widgets/transcription_viewer/speaker_identification_widget.py:168 +msgid "7/8 Mapping speakers to transcripts" +msgstr "" + +#: buzz/widgets/transcription_viewer/speaker_identification_widget.py:207 +msgid "8/8 Identification done" +msgstr "" + +#: buzz/widgets/transcription_viewer/speaker_identification_widget.py:243 +msgid "Step 1: Identify speakers" +msgstr "" + +#: buzz/widgets/transcription_viewer/speaker_identification_widget.py:255 +msgid "Identify" +msgstr "" + +#: buzz/widgets/transcription_viewer/speaker_identification_widget.py:265 +msgid "Ready to identify speakers" +msgstr "" + +#: buzz/widgets/transcription_viewer/speaker_identification_widget.py:267 +msgid "Audio file not found" +msgstr "" + +#: buzz/widgets/transcription_viewer/speaker_identification_widget.py:283 +msgid "Step 2: Name speakers" +msgstr "" + +#: buzz/widgets/transcription_viewer/speaker_identification_widget.py:298 +#: buzz/widgets/transcription_viewer/speaker_identification_widget.py:391 +msgid "Play sample" +msgstr "" + +#: buzz/widgets/transcription_viewer/speaker_identification_widget.py:313 +msgid "Merge speaker sentences" +msgstr "" + +# automatic translation +#: buzz/widgets/transcription_viewer/speaker_identification_widget.py:318 +#, fuzzy +msgid "Save" +msgstr "Guardar archivo" + # automatic translation #: buzz/widgets/transcription_viewer/export_transcription_menu.py:82 msgid "Save File" diff --git a/buzz/locale/it_IT/LC_MESSAGES/buzz.po b/buzz/locale/it_IT/LC_MESSAGES/buzz.po index 127a3b0c..fd231e6a 100644 --- a/buzz/locale/it_IT/LC_MESSAGES/buzz.po +++ b/buzz/locale/it_IT/LC_MESSAGES/buzz.po @@ -6,7 +6,7 @@ msgid "" msgstr "" "Project-Id-Version: buzz\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2025-11-28 16:49+0200\n" +"POT-Creation-Date: 2025-11-23 12:55+0200\n" "PO-Revision-Date: 2025-11-09 20:22+0200\n" "Language-Team: (Italiano) Albano Battistella \n" "Language: it_IT\n" @@ -555,65 +555,69 @@ msgstr "Visualizza" msgid "Timestamps" msgstr "Timestamp" -#: buzz/widgets/transcription_viewer/transcription_viewer_widget.py:211 +#: buzz/widgets/transcription_viewer/transcription_viewer_widget.py:215 msgid "Export" msgstr "Esporta" -#: buzz/widgets/transcription_viewer/transcription_viewer_widget.py:230 +#: buzz/widgets/transcription_viewer/transcription_viewer_widget.py:234 msgid "Translate" msgstr "Tradurre" -#: buzz/widgets/transcription_viewer/transcription_viewer_widget.py:240 -#: buzz/widgets/transcription_viewer/transcription_resizer_widget.py:177 +#: buzz/widgets/transcription_viewer/transcription_viewer_widget.py:244 +#: buzz/widgets/transcription_viewer/transcription_resizer_widget.py:175 msgid "Resize" msgstr "Ridimensionare" -#: buzz/widgets/transcription_viewer/transcription_viewer_widget.py:252 +#: buzz/widgets/transcription_viewer/transcription_viewer_widget.py:257 +msgid "Identify Speakers" +msgstr "" + +#: buzz/widgets/transcription_viewer/transcription_viewer_widget.py:269 msgid "Find" msgstr "Trova" -#: buzz/widgets/transcription_viewer/transcription_viewer_widget.py:255 +#: buzz/widgets/transcription_viewer/transcription_viewer_widget.py:272 msgid "Show/Hide Search Bar (Ctrl+F)" msgstr "Mostra/Nascondi barra di ricerca (Ctrl+F)" -#: buzz/widgets/transcription_viewer/transcription_viewer_widget.py:320 +#: buzz/widgets/transcription_viewer/transcription_viewer_widget.py:337 msgid "Find:" msgstr "Trova:" -#: buzz/widgets/transcription_viewer/transcription_viewer_widget.py:326 +#: buzz/widgets/transcription_viewer/transcription_viewer_widget.py:343 msgid "Enter text to find..." msgstr "Inserisci il testo per trovare..." -#: buzz/widgets/transcription_viewer/transcription_viewer_widget.py:339 +#: buzz/widgets/transcription_viewer/transcription_viewer_widget.py:356 msgid "Previous match (Shift+Enter)" msgstr "Corrispondenza precedente (Maiusc+Invio)" -#: buzz/widgets/transcription_viewer/transcription_viewer_widget.py:347 +#: buzz/widgets/transcription_viewer/transcription_viewer_widget.py:364 msgid "Next match (Enter)" msgstr "Prossima corrispondenza (Invio)" -#: buzz/widgets/transcription_viewer/transcription_viewer_widget.py:355 +#: buzz/widgets/transcription_viewer/transcription_viewer_widget.py:372 msgid "Clear" msgstr "Elimina" -#: buzz/widgets/transcription_viewer/transcription_viewer_widget.py:382 +#: buzz/widgets/transcription_viewer/transcription_viewer_widget.py:399 msgid "Playback Controls:" msgstr "Controlli di riproduzione:" -#: buzz/widgets/transcription_viewer/transcription_viewer_widget.py:387 +#: buzz/widgets/transcription_viewer/transcription_viewer_widget.py:404 msgid "Loop Segment" msgstr "Ciclo di segmento" -#: buzz/widgets/transcription_viewer/transcription_viewer_widget.py:389 +#: buzz/widgets/transcription_viewer/transcription_viewer_widget.py:406 msgid "Enable/disable looping when clicking on transcript segments" msgstr "" "Abilita/disabilita il loop quando si fa clic sui segmenti della trascrizione" -#: buzz/widgets/transcription_viewer/transcription_viewer_widget.py:395 +#: buzz/widgets/transcription_viewer/transcription_viewer_widget.py:412 msgid "Follow Audio" msgstr "Segui Audio" -#: buzz/widgets/transcription_viewer/transcription_viewer_widget.py:397 +#: buzz/widgets/transcription_viewer/transcription_viewer_widget.py:414 msgid "" "Enable/disable following the current audio position in the transcript. When " "enabled, automatically scrolls to current text." @@ -622,75 +626,146 @@ msgstr "" "trascrizione. Quando abilitato, scorre automaticamente fino al testo " "corrente." -#: buzz/widgets/transcription_viewer/transcription_viewer_widget.py:444 +#: buzz/widgets/transcription_viewer/transcription_viewer_widget.py:461 msgid "Scroll to Current" msgstr "Scorri fino al Corrente" -#: buzz/widgets/transcription_viewer/transcription_viewer_widget.py:446 +#: buzz/widgets/transcription_viewer/transcription_viewer_widget.py:463 msgid "Scroll to the currently spoken text" msgstr "Scorrere fino al testo attualmente pronunciato" -#: buzz/widgets/transcription_viewer/transcription_viewer_widget.py:768 +#: buzz/widgets/transcription_viewer/transcription_viewer_widget.py:785 msgid "1 of 100+ matches" msgstr "1 di 100+ corrispondenze" -#: buzz/widgets/transcription_viewer/transcription_viewer_widget.py:770 +#: buzz/widgets/transcription_viewer/transcription_viewer_widget.py:787 msgid "1 of " msgstr "1 di" -#: buzz/widgets/transcription_viewer/transcription_viewer_widget.py:770 -#: buzz/widgets/transcription_viewer/transcription_viewer_widget.py:836 +#: buzz/widgets/transcription_viewer/transcription_viewer_widget.py:787 +#: buzz/widgets/transcription_viewer/transcription_viewer_widget.py:853 msgid " matches" msgstr "corrispondenze" -#: buzz/widgets/transcription_viewer/transcription_viewer_widget.py:775 +#: buzz/widgets/transcription_viewer/transcription_viewer_widget.py:792 msgid "No matches found" msgstr "Nessuna corrispondenza trovata" -#: buzz/widgets/transcription_viewer/transcription_viewer_widget.py:834 +#: buzz/widgets/transcription_viewer/transcription_viewer_widget.py:851 msgid " of 100+ matches" msgstr " di oltre 100 corrispondenze" -#: buzz/widgets/transcription_viewer/transcription_viewer_widget.py:836 +#: buzz/widgets/transcription_viewer/transcription_viewer_widget.py:853 msgid " of " msgstr " di " -#: buzz/widgets/transcription_viewer/transcription_viewer_widget.py:1191 +#: buzz/widgets/transcription_viewer/transcription_viewer_widget.py:1208 msgid "API Key Required" msgstr "Chiave API richiesta" -#: buzz/widgets/transcription_viewer/transcription_viewer_widget.py:1192 +#: buzz/widgets/transcription_viewer/transcription_viewer_widget.py:1209 msgid "Please enter OpenAI API Key in preferences" msgstr "Inserisci la chiave API OpenAI nelle preferenze" -#: buzz/widgets/transcription_viewer/transcription_resizer_widget.py:159 +#: buzz/widgets/transcription_viewer/transcription_resizer_widget.py:157 msgid "Resize Options" msgstr "Opzioni di ridimensionamento" -#: buzz/widgets/transcription_viewer/transcription_resizer_widget.py:170 +#: buzz/widgets/transcription_viewer/transcription_resizer_widget.py:168 msgid "Desired subtitle length" msgstr "Lunghezza desiderata dei sottotitoli" -#: buzz/widgets/transcription_viewer/transcription_resizer_widget.py:195 +#: buzz/widgets/transcription_viewer/transcription_resizer_widget.py:193 msgid "Merge Options" msgstr "Opzioni di unione" -#: buzz/widgets/transcription_viewer/transcription_resizer_widget.py:206 +#: buzz/widgets/transcription_viewer/transcription_resizer_widget.py:204 msgid "Merge by gap" msgstr "Unito per spazio" -#: buzz/widgets/transcription_viewer/transcription_resizer_widget.py:214 +#: buzz/widgets/transcription_viewer/transcription_resizer_widget.py:212 msgid "Split by punctuation" msgstr "Diviso per punteggiatura" -#: buzz/widgets/transcription_viewer/transcription_resizer_widget.py:222 +#: buzz/widgets/transcription_viewer/transcription_resizer_widget.py:220 msgid "Split by max length" msgstr "Diviso per lunghezza massima" -#: buzz/widgets/transcription_viewer/transcription_resizer_widget.py:234 +#: buzz/widgets/transcription_viewer/transcription_resizer_widget.py:232 msgid "Merge" msgstr "Unione" +#: buzz/widgets/transcription_viewer/speaker_identification_widget.py:92 +msgid "1/8 Collecting transcripts" +msgstr "" + +#: buzz/widgets/transcription_viewer/speaker_identification_widget.py:106 +msgid "2/8 Loading audio" +msgstr "" + +#: buzz/widgets/transcription_viewer/speaker_identification_widget.py:115 +msgid "3/8 Loading alignment model" +msgstr "" + +#: buzz/widgets/transcription_viewer/speaker_identification_widget.py:121 +msgid "4/8 Processing audio" +msgstr "" + +#: buzz/widgets/transcription_viewer/speaker_identification_widget.py:133 +#, fuzzy +msgid "5/8 Preparing transcripts" +msgstr "Inizio trascrizione..." + +#: buzz/widgets/transcription_viewer/speaker_identification_widget.py:151 +msgid "6/8 Identifying speakers" +msgstr "" + +#: buzz/widgets/transcription_viewer/speaker_identification_widget.py:160 +msgid "0/0 Error identifying speakers" +msgstr "" + +#: buzz/widgets/transcription_viewer/speaker_identification_widget.py:168 +msgid "7/8 Mapping speakers to transcripts" +msgstr "" + +#: buzz/widgets/transcription_viewer/speaker_identification_widget.py:207 +msgid "8/8 Identification done" +msgstr "" + +#: buzz/widgets/transcription_viewer/speaker_identification_widget.py:243 +msgid "Step 1: Identify speakers" +msgstr "" + +#: buzz/widgets/transcription_viewer/speaker_identification_widget.py:255 +msgid "Identify" +msgstr "" + +#: buzz/widgets/transcription_viewer/speaker_identification_widget.py:265 +msgid "Ready to identify speakers" +msgstr "" + +#: buzz/widgets/transcription_viewer/speaker_identification_widget.py:267 +msgid "Audio file not found" +msgstr "" + +#: buzz/widgets/transcription_viewer/speaker_identification_widget.py:283 +msgid "Step 2: Name speakers" +msgstr "" + +#: buzz/widgets/transcription_viewer/speaker_identification_widget.py:298 +#: buzz/widgets/transcription_viewer/speaker_identification_widget.py:391 +msgid "Play sample" +msgstr "" + +#: buzz/widgets/transcription_viewer/speaker_identification_widget.py:313 +msgid "Merge speaker sentences" +msgstr "" + +#: buzz/widgets/transcription_viewer/speaker_identification_widget.py:318 +#, fuzzy +msgid "Save" +msgstr "Salva file" + #: buzz/widgets/transcription_viewer/export_transcription_menu.py:82 msgid "Save File" msgstr "Salva file" diff --git a/buzz/locale/ja_JP/LC_MESSAGES/buzz.po b/buzz/locale/ja_JP/LC_MESSAGES/buzz.po index b5ec2b11..2bdda8b2 100644 --- a/buzz/locale/ja_JP/LC_MESSAGES/buzz.po +++ b/buzz/locale/ja_JP/LC_MESSAGES/buzz.po @@ -2,7 +2,7 @@ msgid "" msgstr "" "Project-Id-Version: \n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2025-11-28 16:49+0200\n" +"POT-Creation-Date: 2025-11-23 12:55+0200\n" "PO-Revision-Date: \n" "Last-Translator: nunawa <71294849+nunawa@users.noreply.github.com>\n" "Language-Team: \n" @@ -548,139 +548,214 @@ msgstr "表示" msgid "Timestamps" msgstr "タイムスタンプ" -#: buzz/widgets/transcription_viewer/transcription_viewer_widget.py:211 +#: buzz/widgets/transcription_viewer/transcription_viewer_widget.py:215 msgid "Export" msgstr "出力" -#: buzz/widgets/transcription_viewer/transcription_viewer_widget.py:230 +#: buzz/widgets/transcription_viewer/transcription_viewer_widget.py:234 msgid "Translate" msgstr "翻訳" -#: buzz/widgets/transcription_viewer/transcription_viewer_widget.py:240 -#: buzz/widgets/transcription_viewer/transcription_resizer_widget.py:177 +#: buzz/widgets/transcription_viewer/transcription_viewer_widget.py:244 +#: buzz/widgets/transcription_viewer/transcription_resizer_widget.py:175 msgid "Resize" msgstr "リサイズ" -#: buzz/widgets/transcription_viewer/transcription_viewer_widget.py:252 +#: buzz/widgets/transcription_viewer/transcription_viewer_widget.py:257 +msgid "Identify Speakers" +msgstr "" + +#: buzz/widgets/transcription_viewer/transcription_viewer_widget.py:269 msgid "Find" msgstr "" -#: buzz/widgets/transcription_viewer/transcription_viewer_widget.py:255 +#: buzz/widgets/transcription_viewer/transcription_viewer_widget.py:272 msgid "Show/Hide Search Bar (Ctrl+F)" msgstr "" -#: buzz/widgets/transcription_viewer/transcription_viewer_widget.py:320 +#: buzz/widgets/transcription_viewer/transcription_viewer_widget.py:337 msgid "Find:" msgstr "" -#: buzz/widgets/transcription_viewer/transcription_viewer_widget.py:326 +#: buzz/widgets/transcription_viewer/transcription_viewer_widget.py:343 msgid "Enter text to find..." msgstr "" -#: buzz/widgets/transcription_viewer/transcription_viewer_widget.py:339 +#: buzz/widgets/transcription_viewer/transcription_viewer_widget.py:356 msgid "Previous match (Shift+Enter)" msgstr "" -#: buzz/widgets/transcription_viewer/transcription_viewer_widget.py:347 +#: buzz/widgets/transcription_viewer/transcription_viewer_widget.py:364 msgid "Next match (Enter)" msgstr "" -#: buzz/widgets/transcription_viewer/transcription_viewer_widget.py:355 +#: buzz/widgets/transcription_viewer/transcription_viewer_widget.py:372 msgid "Clear" msgstr "" -#: buzz/widgets/transcription_viewer/transcription_viewer_widget.py:382 +#: buzz/widgets/transcription_viewer/transcription_viewer_widget.py:399 msgid "Playback Controls:" msgstr "" -#: buzz/widgets/transcription_viewer/transcription_viewer_widget.py:387 +#: buzz/widgets/transcription_viewer/transcription_viewer_widget.py:404 msgid "Loop Segment" msgstr "" -#: buzz/widgets/transcription_viewer/transcription_viewer_widget.py:389 +#: buzz/widgets/transcription_viewer/transcription_viewer_widget.py:406 msgid "Enable/disable looping when clicking on transcript segments" msgstr "" -#: buzz/widgets/transcription_viewer/transcription_viewer_widget.py:395 +#: buzz/widgets/transcription_viewer/transcription_viewer_widget.py:412 msgid "Follow Audio" msgstr "" -#: buzz/widgets/transcription_viewer/transcription_viewer_widget.py:397 +#: buzz/widgets/transcription_viewer/transcription_viewer_widget.py:414 msgid "" "Enable/disable following the current audio position in the transcript. When " "enabled, automatically scrolls to current text." msgstr "" -#: buzz/widgets/transcription_viewer/transcription_viewer_widget.py:444 +#: buzz/widgets/transcription_viewer/transcription_viewer_widget.py:461 msgid "Scroll to Current" msgstr "" -#: buzz/widgets/transcription_viewer/transcription_viewer_widget.py:446 +#: buzz/widgets/transcription_viewer/transcription_viewer_widget.py:463 msgid "Scroll to the currently spoken text" msgstr "" -#: buzz/widgets/transcription_viewer/transcription_viewer_widget.py:768 +#: buzz/widgets/transcription_viewer/transcription_viewer_widget.py:785 msgid "1 of 100+ matches" msgstr "" -#: buzz/widgets/transcription_viewer/transcription_viewer_widget.py:770 +#: buzz/widgets/transcription_viewer/transcription_viewer_widget.py:787 msgid "1 of " msgstr "" -#: buzz/widgets/transcription_viewer/transcription_viewer_widget.py:770 -#: buzz/widgets/transcription_viewer/transcription_viewer_widget.py:836 +#: buzz/widgets/transcription_viewer/transcription_viewer_widget.py:787 +#: buzz/widgets/transcription_viewer/transcription_viewer_widget.py:853 msgid " matches" msgstr "" -#: buzz/widgets/transcription_viewer/transcription_viewer_widget.py:775 +#: buzz/widgets/transcription_viewer/transcription_viewer_widget.py:792 msgid "No matches found" msgstr "" -#: buzz/widgets/transcription_viewer/transcription_viewer_widget.py:834 +#: buzz/widgets/transcription_viewer/transcription_viewer_widget.py:851 msgid " of 100+ matches" msgstr "" -#: buzz/widgets/transcription_viewer/transcription_viewer_widget.py:836 +#: buzz/widgets/transcription_viewer/transcription_viewer_widget.py:853 msgid " of " msgstr "" -#: buzz/widgets/transcription_viewer/transcription_viewer_widget.py:1191 +#: buzz/widgets/transcription_viewer/transcription_viewer_widget.py:1208 msgid "API Key Required" msgstr "APIキーが必要" -#: buzz/widgets/transcription_viewer/transcription_viewer_widget.py:1192 +#: buzz/widgets/transcription_viewer/transcription_viewer_widget.py:1209 msgid "Please enter OpenAI API Key in preferences" msgstr "設定画面でOpenAI APIキーを入力してください" -#: buzz/widgets/transcription_viewer/transcription_resizer_widget.py:159 +#: buzz/widgets/transcription_viewer/transcription_resizer_widget.py:157 #, fuzzy msgid "Resize Options" msgstr "リサイズ" -#: buzz/widgets/transcription_viewer/transcription_resizer_widget.py:170 +#: buzz/widgets/transcription_viewer/transcription_resizer_widget.py:168 msgid "Desired subtitle length" msgstr "希望する字幕の長さ" -#: buzz/widgets/transcription_viewer/transcription_resizer_widget.py:195 +#: buzz/widgets/transcription_viewer/transcription_resizer_widget.py:193 msgid "Merge Options" msgstr "" -#: buzz/widgets/transcription_viewer/transcription_resizer_widget.py:206 +#: buzz/widgets/transcription_viewer/transcription_resizer_widget.py:204 msgid "Merge by gap" msgstr "" -#: buzz/widgets/transcription_viewer/transcription_resizer_widget.py:214 +#: buzz/widgets/transcription_viewer/transcription_resizer_widget.py:212 msgid "Split by punctuation" msgstr "" -#: buzz/widgets/transcription_viewer/transcription_resizer_widget.py:222 +#: buzz/widgets/transcription_viewer/transcription_resizer_widget.py:220 msgid "Split by max length" msgstr "" -#: buzz/widgets/transcription_viewer/transcription_resizer_widget.py:234 +#: buzz/widgets/transcription_viewer/transcription_resizer_widget.py:232 msgid "Merge" msgstr "" +#: buzz/widgets/transcription_viewer/speaker_identification_widget.py:92 +msgid "1/8 Collecting transcripts" +msgstr "" + +#: buzz/widgets/transcription_viewer/speaker_identification_widget.py:106 +msgid "2/8 Loading audio" +msgstr "" + +#: buzz/widgets/transcription_viewer/speaker_identification_widget.py:115 +msgid "3/8 Loading alignment model" +msgstr "" + +#: buzz/widgets/transcription_viewer/speaker_identification_widget.py:121 +msgid "4/8 Processing audio" +msgstr "" + +#: buzz/widgets/transcription_viewer/speaker_identification_widget.py:133 +#, fuzzy +msgid "5/8 Preparing transcripts" +msgstr "文字起こしをキャンセルする" + +#: buzz/widgets/transcription_viewer/speaker_identification_widget.py:151 +msgid "6/8 Identifying speakers" +msgstr "" + +#: buzz/widgets/transcription_viewer/speaker_identification_widget.py:160 +msgid "0/0 Error identifying speakers" +msgstr "" + +#: buzz/widgets/transcription_viewer/speaker_identification_widget.py:168 +msgid "7/8 Mapping speakers to transcripts" +msgstr "" + +#: buzz/widgets/transcription_viewer/speaker_identification_widget.py:207 +msgid "8/8 Identification done" +msgstr "" + +#: buzz/widgets/transcription_viewer/speaker_identification_widget.py:243 +msgid "Step 1: Identify speakers" +msgstr "" + +#: buzz/widgets/transcription_viewer/speaker_identification_widget.py:255 +msgid "Identify" +msgstr "" + +#: buzz/widgets/transcription_viewer/speaker_identification_widget.py:265 +msgid "Ready to identify speakers" +msgstr "" + +#: buzz/widgets/transcription_viewer/speaker_identification_widget.py:267 +msgid "Audio file not found" +msgstr "" + +#: buzz/widgets/transcription_viewer/speaker_identification_widget.py:283 +msgid "Step 2: Name speakers" +msgstr "" + +#: buzz/widgets/transcription_viewer/speaker_identification_widget.py:298 +#: buzz/widgets/transcription_viewer/speaker_identification_widget.py:391 +msgid "Play sample" +msgstr "" + +#: buzz/widgets/transcription_viewer/speaker_identification_widget.py:313 +msgid "Merge speaker sentences" +msgstr "" + +#: buzz/widgets/transcription_viewer/speaker_identification_widget.py:318 +#, fuzzy +msgid "Save" +msgstr "ファイルを保存" + #: buzz/widgets/transcription_viewer/export_transcription_menu.py:82 msgid "Save File" msgstr "ファイルを保存" diff --git a/buzz/locale/lv_LV/LC_MESSAGES/buzz.po b/buzz/locale/lv_LV/LC_MESSAGES/buzz.po index 18f799f5..df528784 100644 --- a/buzz/locale/lv_LV/LC_MESSAGES/buzz.po +++ b/buzz/locale/lv_LV/LC_MESSAGES/buzz.po @@ -3,13 +3,12 @@ # This file is distributed under the same license as the PACKAGE package. # FIRST AUTHOR , YEAR. # -#, fuzzy msgid "" msgstr "" "Project-Id-Version: \n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2025-11-28 16:49+0200\n" -"PO-Revision-Date: 2025-11-28 16:50+0200\n" +"POT-Creation-Date: 2025-11-23 13:02+0200\n" +"PO-Revision-Date: 2025-11-23 12:58+0200\n" "Last-Translator: \n" "Language-Team: \n" "Language: lv_LV\n" @@ -558,64 +557,68 @@ msgstr "Skats" msgid "Timestamps" msgstr "Laiks" -#: buzz/widgets/transcription_viewer/transcription_viewer_widget.py:211 +#: buzz/widgets/transcription_viewer/transcription_viewer_widget.py:215 msgid "Export" msgstr "Eksportēt" -#: buzz/widgets/transcription_viewer/transcription_viewer_widget.py:230 +#: buzz/widgets/transcription_viewer/transcription_viewer_widget.py:234 msgid "Translate" msgstr "Tulkot" -#: buzz/widgets/transcription_viewer/transcription_viewer_widget.py:240 -#: buzz/widgets/transcription_viewer/transcription_resizer_widget.py:177 +#: buzz/widgets/transcription_viewer/transcription_viewer_widget.py:244 +#: buzz/widgets/transcription_viewer/transcription_resizer_widget.py:175 msgid "Resize" msgstr "Mainīt garumu" -#: buzz/widgets/transcription_viewer/transcription_viewer_widget.py:252 +#: buzz/widgets/transcription_viewer/transcription_viewer_widget.py:257 +msgid "Identify Speakers" +msgstr "Noteikt runātājus" + +#: buzz/widgets/transcription_viewer/transcription_viewer_widget.py:269 msgid "Find" msgstr "Meklēt" -#: buzz/widgets/transcription_viewer/transcription_viewer_widget.py:255 +#: buzz/widgets/transcription_viewer/transcription_viewer_widget.py:272 msgid "Show/Hide Search Bar (Ctrl+F)" msgstr "Rādīt/Slēpt meklēšanas joslu (Ctrl+F)" -#: buzz/widgets/transcription_viewer/transcription_viewer_widget.py:320 +#: buzz/widgets/transcription_viewer/transcription_viewer_widget.py:337 msgid "Find:" msgstr "Meklēt:" -#: buzz/widgets/transcription_viewer/transcription_viewer_widget.py:326 +#: buzz/widgets/transcription_viewer/transcription_viewer_widget.py:343 msgid "Enter text to find..." msgstr "Ievadiet meklējamo..." -#: buzz/widgets/transcription_viewer/transcription_viewer_widget.py:339 +#: buzz/widgets/transcription_viewer/transcription_viewer_widget.py:356 msgid "Previous match (Shift+Enter)" msgstr "Iepriekšējais rezultāts (Shift+Enter)" -#: buzz/widgets/transcription_viewer/transcription_viewer_widget.py:347 +#: buzz/widgets/transcription_viewer/transcription_viewer_widget.py:364 msgid "Next match (Enter)" msgstr "Nākamais rezultāts (Enter)" -#: buzz/widgets/transcription_viewer/transcription_viewer_widget.py:355 +#: buzz/widgets/transcription_viewer/transcription_viewer_widget.py:372 msgid "Clear" msgstr "Notīrīt" -#: buzz/widgets/transcription_viewer/transcription_viewer_widget.py:382 +#: buzz/widgets/transcription_viewer/transcription_viewer_widget.py:399 msgid "Playback Controls:" msgstr "Atskaņošanas iespējas:" -#: buzz/widgets/transcription_viewer/transcription_viewer_widget.py:387 +#: buzz/widgets/transcription_viewer/transcription_viewer_widget.py:404 msgid "Loop Segment" msgstr "Atkārtot segmentu" -#: buzz/widgets/transcription_viewer/transcription_viewer_widget.py:389 +#: buzz/widgets/transcription_viewer/transcription_viewer_widget.py:406 msgid "Enable/disable looping when clicking on transcript segments" msgstr "Nosaka vai atkārtot izvēlēto segmentu" -#: buzz/widgets/transcription_viewer/transcription_viewer_widget.py:395 +#: buzz/widgets/transcription_viewer/transcription_viewer_widget.py:412 msgid "Follow Audio" msgstr "Sekot audio" -#: buzz/widgets/transcription_viewer/transcription_viewer_widget.py:397 +#: buzz/widgets/transcription_viewer/transcription_viewer_widget.py:414 msgid "" "Enable/disable following the current audio position in the transcript. When " "enabled, automatically scrolls to current text." @@ -623,75 +626,144 @@ msgstr "" "Nosaka vai atskaņojot audio iezīmētajam segmentam vajadzētu automātiski " "sekot tam kas tiek atskaņots." -#: buzz/widgets/transcription_viewer/transcription_viewer_widget.py:444 +#: buzz/widgets/transcription_viewer/transcription_viewer_widget.py:461 msgid "Scroll to Current" msgstr "Pāriet uz tekošo" -#: buzz/widgets/transcription_viewer/transcription_viewer_widget.py:446 +#: buzz/widgets/transcription_viewer/transcription_viewer_widget.py:463 msgid "Scroll to the currently spoken text" msgstr "Pāriet uz šobrīd atskaņojamo tesktu" -#: buzz/widgets/transcription_viewer/transcription_viewer_widget.py:768 +#: buzz/widgets/transcription_viewer/transcription_viewer_widget.py:785 msgid "1 of 100+ matches" msgstr "1 no 100+ " -#: buzz/widgets/transcription_viewer/transcription_viewer_widget.py:770 +#: buzz/widgets/transcription_viewer/transcription_viewer_widget.py:787 msgid "1 of " msgstr "1 no " -#: buzz/widgets/transcription_viewer/transcription_viewer_widget.py:770 -#: buzz/widgets/transcription_viewer/transcription_viewer_widget.py:836 +#: buzz/widgets/transcription_viewer/transcription_viewer_widget.py:787 +#: buzz/widgets/transcription_viewer/transcription_viewer_widget.py:853 msgid " matches" msgstr " " -#: buzz/widgets/transcription_viewer/transcription_viewer_widget.py:775 +#: buzz/widgets/transcription_viewer/transcription_viewer_widget.py:792 msgid "No matches found" msgstr "Nekas nav atrasts" -#: buzz/widgets/transcription_viewer/transcription_viewer_widget.py:834 +#: buzz/widgets/transcription_viewer/transcription_viewer_widget.py:851 msgid " of 100+ matches" msgstr " no 100+" -#: buzz/widgets/transcription_viewer/transcription_viewer_widget.py:836 +#: buzz/widgets/transcription_viewer/transcription_viewer_widget.py:853 msgid " of " msgstr " no " -#: buzz/widgets/transcription_viewer/transcription_viewer_widget.py:1191 +#: buzz/widgets/transcription_viewer/transcription_viewer_widget.py:1208 msgid "API Key Required" msgstr "API atslēgas kļūda" -#: buzz/widgets/transcription_viewer/transcription_viewer_widget.py:1192 +#: buzz/widgets/transcription_viewer/transcription_viewer_widget.py:1209 msgid "Please enter OpenAI API Key in preferences" msgstr "Lūdzu ievadiet OpenAI API atslēgu iestatījumos" -#: buzz/widgets/transcription_viewer/transcription_resizer_widget.py:159 +#: buzz/widgets/transcription_viewer/transcription_resizer_widget.py:157 msgid "Resize Options" msgstr "Garuma maiņas iestatījumi" -#: buzz/widgets/transcription_viewer/transcription_resizer_widget.py:170 +#: buzz/widgets/transcription_viewer/transcription_resizer_widget.py:168 msgid "Desired subtitle length" msgstr "Vēlamais teksta garums" -#: buzz/widgets/transcription_viewer/transcription_resizer_widget.py:195 +#: buzz/widgets/transcription_viewer/transcription_resizer_widget.py:193 msgid "Merge Options" msgstr "Apvienošanas iestatījumi" -#: buzz/widgets/transcription_viewer/transcription_resizer_widget.py:206 +#: buzz/widgets/transcription_viewer/transcription_resizer_widget.py:204 msgid "Merge by gap" msgstr "Apvienot pēc attāluma" -#: buzz/widgets/transcription_viewer/transcription_resizer_widget.py:214 +#: buzz/widgets/transcription_viewer/transcription_resizer_widget.py:212 msgid "Split by punctuation" msgstr "Dalīt pie pieturzīmēm" -#: buzz/widgets/transcription_viewer/transcription_resizer_widget.py:222 +#: buzz/widgets/transcription_viewer/transcription_resizer_widget.py:220 msgid "Split by max length" msgstr "Dalīt pie maksimālā garuma" -#: buzz/widgets/transcription_viewer/transcription_resizer_widget.py:234 +#: buzz/widgets/transcription_viewer/transcription_resizer_widget.py:232 msgid "Merge" msgstr "Apvienot" +#: buzz/widgets/transcription_viewer/speaker_identification_widget.py:92 +msgid "1/8 Collecting transcripts" +msgstr "1/8 Apkopo transkripcijas" + +#: buzz/widgets/transcription_viewer/speaker_identification_widget.py:106 +msgid "2/8 Loading audio" +msgstr "2/8 Ielādē audio" + +#: buzz/widgets/transcription_viewer/speaker_identification_widget.py:115 +msgid "3/8 Loading alignment model" +msgstr "3/8 Ielādē identifikācijas modeli" + +#: buzz/widgets/transcription_viewer/speaker_identification_widget.py:121 +msgid "4/8 Processing audio" +msgstr "4/8 Apstrādā audio" + +#: buzz/widgets/transcription_viewer/speaker_identification_widget.py:133 +msgid "5/8 Preparing transcripts" +msgstr "5/8 Sagatavo transkripcijas" + +#: buzz/widgets/transcription_viewer/speaker_identification_widget.py:151 +msgid "6/8 Identifying speakers" +msgstr "6/8 Nosaka runātājus" + +#: buzz/widgets/transcription_viewer/speaker_identification_widget.py:160 +msgid "0/0 Error identifying speakers" +msgstr "0/0 Kļūda nosakot runātājus" + +#: buzz/widgets/transcription_viewer/speaker_identification_widget.py:168 +msgid "7/8 Mapping speakers to transcripts" +msgstr "7/8 Marķē runātāju teikumus" + +#: buzz/widgets/transcription_viewer/speaker_identification_widget.py:207 +msgid "8/8 Identification done" +msgstr "8/8 Runātāju noteikšana pabeigta" + +#: buzz/widgets/transcription_viewer/speaker_identification_widget.py:243 +msgid "Step 1: Identify speakers" +msgstr "1. solis: Runātāju noteikšana" + +#: buzz/widgets/transcription_viewer/speaker_identification_widget.py:255 +msgid "Identify" +msgstr "Noteikt" + +#: buzz/widgets/transcription_viewer/speaker_identification_widget.py:265 +msgid "Ready to identify speakers" +msgstr "Gatavs noteikt runātājus" + +#: buzz/widgets/transcription_viewer/speaker_identification_widget.py:267 +msgid "Audio file not found" +msgstr "Audio datne nav atrasta" + +#: buzz/widgets/transcription_viewer/speaker_identification_widget.py:283 +msgid "Step 2: Name speakers" +msgstr "2. solis: Runātāju identifikācija" + +#: buzz/widgets/transcription_viewer/speaker_identification_widget.py:298 +#: buzz/widgets/transcription_viewer/speaker_identification_widget.py:391 +msgid "Play sample" +msgstr "Atskaņot paraugu" + +#: buzz/widgets/transcription_viewer/speaker_identification_widget.py:313 +msgid "Merge speaker sentences" +msgstr "Apvienot secīgus runātāja teikumus" + +#: buzz/widgets/transcription_viewer/speaker_identification_widget.py:318 +msgid "Save" +msgstr "Saglabāt" + #: buzz/widgets/transcription_viewer/export_transcription_menu.py:82 msgid "Save File" msgstr "Saglabāt failu" diff --git a/buzz/locale/nl/LC_MESSAGES/buzz.po b/buzz/locale/nl/LC_MESSAGES/buzz.po index 2e21acc2..75b59ea1 100644 --- a/buzz/locale/nl/LC_MESSAGES/buzz.po +++ b/buzz/locale/nl/LC_MESSAGES/buzz.po @@ -8,7 +8,7 @@ msgid "" msgstr "" "Project-Id-Version: \n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2025-11-28 16:49+0200\n" +"POT-Creation-Date: 2025-11-23 12:55+0200\n" "PO-Revision-Date: 2025-03-20 18:30+0100\n" "Last-Translator: Heimen Stoffels \n" "Language-Team: none\n" @@ -552,138 +552,213 @@ msgstr "Bekijken" msgid "Timestamps" msgstr "Tijdstippen" -#: buzz/widgets/transcription_viewer/transcription_viewer_widget.py:211 +#: buzz/widgets/transcription_viewer/transcription_viewer_widget.py:215 msgid "Export" msgstr "Exporteren" -#: buzz/widgets/transcription_viewer/transcription_viewer_widget.py:230 +#: buzz/widgets/transcription_viewer/transcription_viewer_widget.py:234 msgid "Translate" msgstr "Vertalen" -#: buzz/widgets/transcription_viewer/transcription_viewer_widget.py:240 -#: buzz/widgets/transcription_viewer/transcription_resizer_widget.py:177 +#: buzz/widgets/transcription_viewer/transcription_viewer_widget.py:244 +#: buzz/widgets/transcription_viewer/transcription_resizer_widget.py:175 msgid "Resize" msgstr "Grootte" -#: buzz/widgets/transcription_viewer/transcription_viewer_widget.py:252 +#: buzz/widgets/transcription_viewer/transcription_viewer_widget.py:257 +msgid "Identify Speakers" +msgstr "" + +#: buzz/widgets/transcription_viewer/transcription_viewer_widget.py:269 msgid "Find" msgstr "" -#: buzz/widgets/transcription_viewer/transcription_viewer_widget.py:255 +#: buzz/widgets/transcription_viewer/transcription_viewer_widget.py:272 msgid "Show/Hide Search Bar (Ctrl+F)" msgstr "" -#: buzz/widgets/transcription_viewer/transcription_viewer_widget.py:320 +#: buzz/widgets/transcription_viewer/transcription_viewer_widget.py:337 msgid "Find:" msgstr "" -#: buzz/widgets/transcription_viewer/transcription_viewer_widget.py:326 +#: buzz/widgets/transcription_viewer/transcription_viewer_widget.py:343 msgid "Enter text to find..." msgstr "" -#: buzz/widgets/transcription_viewer/transcription_viewer_widget.py:339 +#: buzz/widgets/transcription_viewer/transcription_viewer_widget.py:356 msgid "Previous match (Shift+Enter)" msgstr "" -#: buzz/widgets/transcription_viewer/transcription_viewer_widget.py:347 +#: buzz/widgets/transcription_viewer/transcription_viewer_widget.py:364 msgid "Next match (Enter)" msgstr "" -#: buzz/widgets/transcription_viewer/transcription_viewer_widget.py:355 +#: buzz/widgets/transcription_viewer/transcription_viewer_widget.py:372 msgid "Clear" msgstr "" -#: buzz/widgets/transcription_viewer/transcription_viewer_widget.py:382 +#: buzz/widgets/transcription_viewer/transcription_viewer_widget.py:399 msgid "Playback Controls:" msgstr "" -#: buzz/widgets/transcription_viewer/transcription_viewer_widget.py:387 +#: buzz/widgets/transcription_viewer/transcription_viewer_widget.py:404 msgid "Loop Segment" msgstr "" -#: buzz/widgets/transcription_viewer/transcription_viewer_widget.py:389 +#: buzz/widgets/transcription_viewer/transcription_viewer_widget.py:406 msgid "Enable/disable looping when clicking on transcript segments" msgstr "" -#: buzz/widgets/transcription_viewer/transcription_viewer_widget.py:395 +#: buzz/widgets/transcription_viewer/transcription_viewer_widget.py:412 msgid "Follow Audio" msgstr "" -#: buzz/widgets/transcription_viewer/transcription_viewer_widget.py:397 +#: buzz/widgets/transcription_viewer/transcription_viewer_widget.py:414 msgid "" "Enable/disable following the current audio position in the transcript. When " "enabled, automatically scrolls to current text." msgstr "" -#: buzz/widgets/transcription_viewer/transcription_viewer_widget.py:444 +#: buzz/widgets/transcription_viewer/transcription_viewer_widget.py:461 msgid "Scroll to Current" msgstr "" -#: buzz/widgets/transcription_viewer/transcription_viewer_widget.py:446 +#: buzz/widgets/transcription_viewer/transcription_viewer_widget.py:463 msgid "Scroll to the currently spoken text" msgstr "" -#: buzz/widgets/transcription_viewer/transcription_viewer_widget.py:768 +#: buzz/widgets/transcription_viewer/transcription_viewer_widget.py:785 msgid "1 of 100+ matches" msgstr "" -#: buzz/widgets/transcription_viewer/transcription_viewer_widget.py:770 +#: buzz/widgets/transcription_viewer/transcription_viewer_widget.py:787 msgid "1 of " msgstr "" -#: buzz/widgets/transcription_viewer/transcription_viewer_widget.py:770 -#: buzz/widgets/transcription_viewer/transcription_viewer_widget.py:836 +#: buzz/widgets/transcription_viewer/transcription_viewer_widget.py:787 +#: buzz/widgets/transcription_viewer/transcription_viewer_widget.py:853 msgid " matches" msgstr "" -#: buzz/widgets/transcription_viewer/transcription_viewer_widget.py:775 +#: buzz/widgets/transcription_viewer/transcription_viewer_widget.py:792 msgid "No matches found" msgstr "" -#: buzz/widgets/transcription_viewer/transcription_viewer_widget.py:834 +#: buzz/widgets/transcription_viewer/transcription_viewer_widget.py:851 msgid " of 100+ matches" msgstr "" -#: buzz/widgets/transcription_viewer/transcription_viewer_widget.py:836 +#: buzz/widgets/transcription_viewer/transcription_viewer_widget.py:853 msgid " of " msgstr "" -#: buzz/widgets/transcription_viewer/transcription_viewer_widget.py:1191 +#: buzz/widgets/transcription_viewer/transcription_viewer_widget.py:1208 msgid "API Key Required" msgstr "Api-sleutel vereist" -#: buzz/widgets/transcription_viewer/transcription_viewer_widget.py:1192 +#: buzz/widgets/transcription_viewer/transcription_viewer_widget.py:1209 msgid "Please enter OpenAI API Key in preferences" msgstr "Voer de OpenAI-api-sleutel in in de instellingen" -#: buzz/widgets/transcription_viewer/transcription_resizer_widget.py:159 +#: buzz/widgets/transcription_viewer/transcription_resizer_widget.py:157 msgid "Resize Options" msgstr "Grootteopties" -#: buzz/widgets/transcription_viewer/transcription_resizer_widget.py:170 +#: buzz/widgets/transcription_viewer/transcription_resizer_widget.py:168 msgid "Desired subtitle length" msgstr "Voorkeurslengte van ondertiteling" -#: buzz/widgets/transcription_viewer/transcription_resizer_widget.py:195 +#: buzz/widgets/transcription_viewer/transcription_resizer_widget.py:193 msgid "Merge Options" msgstr "Samenvoegopties" -#: buzz/widgets/transcription_viewer/transcription_resizer_widget.py:206 +#: buzz/widgets/transcription_viewer/transcription_resizer_widget.py:204 msgid "Merge by gap" msgstr "Samenvoegen op basis van tussenruimte" -#: buzz/widgets/transcription_viewer/transcription_resizer_widget.py:214 +#: buzz/widgets/transcription_viewer/transcription_resizer_widget.py:212 msgid "Split by punctuation" msgstr "Splitsen op basis van leestekens" -#: buzz/widgets/transcription_viewer/transcription_resizer_widget.py:222 +#: buzz/widgets/transcription_viewer/transcription_resizer_widget.py:220 msgid "Split by max length" msgstr "Splitsen op basis van max. lengte" -#: buzz/widgets/transcription_viewer/transcription_resizer_widget.py:234 +#: buzz/widgets/transcription_viewer/transcription_resizer_widget.py:232 msgid "Merge" msgstr "Samenvoegen" +#: buzz/widgets/transcription_viewer/speaker_identification_widget.py:92 +msgid "1/8 Collecting transcripts" +msgstr "" + +#: buzz/widgets/transcription_viewer/speaker_identification_widget.py:106 +msgid "2/8 Loading audio" +msgstr "" + +#: buzz/widgets/transcription_viewer/speaker_identification_widget.py:115 +msgid "3/8 Loading alignment model" +msgstr "" + +#: buzz/widgets/transcription_viewer/speaker_identification_widget.py:121 +msgid "4/8 Processing audio" +msgstr "" + +#: buzz/widgets/transcription_viewer/speaker_identification_widget.py:133 +#, fuzzy +msgid "5/8 Preparing transcripts" +msgstr "Transcriptie wissen" + +#: buzz/widgets/transcription_viewer/speaker_identification_widget.py:151 +msgid "6/8 Identifying speakers" +msgstr "" + +#: buzz/widgets/transcription_viewer/speaker_identification_widget.py:160 +msgid "0/0 Error identifying speakers" +msgstr "" + +#: buzz/widgets/transcription_viewer/speaker_identification_widget.py:168 +msgid "7/8 Mapping speakers to transcripts" +msgstr "" + +#: buzz/widgets/transcription_viewer/speaker_identification_widget.py:207 +msgid "8/8 Identification done" +msgstr "" + +#: buzz/widgets/transcription_viewer/speaker_identification_widget.py:243 +msgid "Step 1: Identify speakers" +msgstr "" + +#: buzz/widgets/transcription_viewer/speaker_identification_widget.py:255 +msgid "Identify" +msgstr "" + +#: buzz/widgets/transcription_viewer/speaker_identification_widget.py:265 +msgid "Ready to identify speakers" +msgstr "" + +#: buzz/widgets/transcription_viewer/speaker_identification_widget.py:267 +msgid "Audio file not found" +msgstr "" + +#: buzz/widgets/transcription_viewer/speaker_identification_widget.py:283 +msgid "Step 2: Name speakers" +msgstr "" + +#: buzz/widgets/transcription_viewer/speaker_identification_widget.py:298 +#: buzz/widgets/transcription_viewer/speaker_identification_widget.py:391 +msgid "Play sample" +msgstr "" + +#: buzz/widgets/transcription_viewer/speaker_identification_widget.py:313 +msgid "Merge speaker sentences" +msgstr "" + +#: buzz/widgets/transcription_viewer/speaker_identification_widget.py:318 +#, fuzzy +msgid "Save" +msgstr "Bestand opslaan" + #: buzz/widgets/transcription_viewer/export_transcription_menu.py:82 msgid "Save File" msgstr "Bestand opslaan" diff --git a/buzz/locale/pl_PL/LC_MESSAGES/buzz.po b/buzz/locale/pl_PL/LC_MESSAGES/buzz.po index 2d452294..261fcd5b 100644 --- a/buzz/locale/pl_PL/LC_MESSAGES/buzz.po +++ b/buzz/locale/pl_PL/LC_MESSAGES/buzz.po @@ -7,7 +7,7 @@ msgid "" msgstr "" "Project-Id-Version: \n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2025-11-28 16:49+0200\n" +"POT-Creation-Date: 2025-11-23 12:55+0200\n" "PO-Revision-Date: 2024-03-17 20:50+0200\n" "Last-Translator: \n" "Language-Team: \n" @@ -561,138 +561,213 @@ msgstr "" msgid "Timestamps" msgstr "" -#: buzz/widgets/transcription_viewer/transcription_viewer_widget.py:211 +#: buzz/widgets/transcription_viewer/transcription_viewer_widget.py:215 msgid "Export" msgstr "" -#: buzz/widgets/transcription_viewer/transcription_viewer_widget.py:230 +#: buzz/widgets/transcription_viewer/transcription_viewer_widget.py:234 msgid "Translate" msgstr "" -#: buzz/widgets/transcription_viewer/transcription_viewer_widget.py:240 -#: buzz/widgets/transcription_viewer/transcription_resizer_widget.py:177 +#: buzz/widgets/transcription_viewer/transcription_viewer_widget.py:244 +#: buzz/widgets/transcription_viewer/transcription_resizer_widget.py:175 msgid "Resize" msgstr "" -#: buzz/widgets/transcription_viewer/transcription_viewer_widget.py:252 +#: buzz/widgets/transcription_viewer/transcription_viewer_widget.py:257 +msgid "Identify Speakers" +msgstr "" + +#: buzz/widgets/transcription_viewer/transcription_viewer_widget.py:269 msgid "Find" msgstr "" -#: buzz/widgets/transcription_viewer/transcription_viewer_widget.py:255 +#: buzz/widgets/transcription_viewer/transcription_viewer_widget.py:272 msgid "Show/Hide Search Bar (Ctrl+F)" msgstr "" -#: buzz/widgets/transcription_viewer/transcription_viewer_widget.py:320 +#: buzz/widgets/transcription_viewer/transcription_viewer_widget.py:337 msgid "Find:" msgstr "" -#: buzz/widgets/transcription_viewer/transcription_viewer_widget.py:326 +#: buzz/widgets/transcription_viewer/transcription_viewer_widget.py:343 msgid "Enter text to find..." msgstr "" -#: buzz/widgets/transcription_viewer/transcription_viewer_widget.py:339 +#: buzz/widgets/transcription_viewer/transcription_viewer_widget.py:356 msgid "Previous match (Shift+Enter)" msgstr "" -#: buzz/widgets/transcription_viewer/transcription_viewer_widget.py:347 +#: buzz/widgets/transcription_viewer/transcription_viewer_widget.py:364 msgid "Next match (Enter)" msgstr "" -#: buzz/widgets/transcription_viewer/transcription_viewer_widget.py:355 +#: buzz/widgets/transcription_viewer/transcription_viewer_widget.py:372 msgid "Clear" msgstr "" -#: buzz/widgets/transcription_viewer/transcription_viewer_widget.py:382 +#: buzz/widgets/transcription_viewer/transcription_viewer_widget.py:399 msgid "Playback Controls:" msgstr "" -#: buzz/widgets/transcription_viewer/transcription_viewer_widget.py:387 +#: buzz/widgets/transcription_viewer/transcription_viewer_widget.py:404 msgid "Loop Segment" msgstr "" -#: buzz/widgets/transcription_viewer/transcription_viewer_widget.py:389 +#: buzz/widgets/transcription_viewer/transcription_viewer_widget.py:406 msgid "Enable/disable looping when clicking on transcript segments" msgstr "" -#: buzz/widgets/transcription_viewer/transcription_viewer_widget.py:395 +#: buzz/widgets/transcription_viewer/transcription_viewer_widget.py:412 msgid "Follow Audio" msgstr "" -#: buzz/widgets/transcription_viewer/transcription_viewer_widget.py:397 +#: buzz/widgets/transcription_viewer/transcription_viewer_widget.py:414 msgid "" "Enable/disable following the current audio position in the transcript. When " "enabled, automatically scrolls to current text." msgstr "" -#: buzz/widgets/transcription_viewer/transcription_viewer_widget.py:444 +#: buzz/widgets/transcription_viewer/transcription_viewer_widget.py:461 msgid "Scroll to Current" msgstr "" -#: buzz/widgets/transcription_viewer/transcription_viewer_widget.py:446 +#: buzz/widgets/transcription_viewer/transcription_viewer_widget.py:463 msgid "Scroll to the currently spoken text" msgstr "" -#: buzz/widgets/transcription_viewer/transcription_viewer_widget.py:768 +#: buzz/widgets/transcription_viewer/transcription_viewer_widget.py:785 msgid "1 of 100+ matches" msgstr "" -#: buzz/widgets/transcription_viewer/transcription_viewer_widget.py:770 +#: buzz/widgets/transcription_viewer/transcription_viewer_widget.py:787 msgid "1 of " msgstr "" -#: buzz/widgets/transcription_viewer/transcription_viewer_widget.py:770 -#: buzz/widgets/transcription_viewer/transcription_viewer_widget.py:836 +#: buzz/widgets/transcription_viewer/transcription_viewer_widget.py:787 +#: buzz/widgets/transcription_viewer/transcription_viewer_widget.py:853 msgid " matches" msgstr "" -#: buzz/widgets/transcription_viewer/transcription_viewer_widget.py:775 +#: buzz/widgets/transcription_viewer/transcription_viewer_widget.py:792 msgid "No matches found" msgstr "" -#: buzz/widgets/transcription_viewer/transcription_viewer_widget.py:834 +#: buzz/widgets/transcription_viewer/transcription_viewer_widget.py:851 msgid " of 100+ matches" msgstr "" -#: buzz/widgets/transcription_viewer/transcription_viewer_widget.py:836 +#: buzz/widgets/transcription_viewer/transcription_viewer_widget.py:853 msgid " of " msgstr "" -#: buzz/widgets/transcription_viewer/transcription_viewer_widget.py:1191 +#: buzz/widgets/transcription_viewer/transcription_viewer_widget.py:1208 msgid "API Key Required" msgstr "" -#: buzz/widgets/transcription_viewer/transcription_viewer_widget.py:1192 +#: buzz/widgets/transcription_viewer/transcription_viewer_widget.py:1209 msgid "Please enter OpenAI API Key in preferences" msgstr "" -#: buzz/widgets/transcription_viewer/transcription_resizer_widget.py:159 +#: buzz/widgets/transcription_viewer/transcription_resizer_widget.py:157 msgid "Resize Options" msgstr "" -#: buzz/widgets/transcription_viewer/transcription_resizer_widget.py:170 +#: buzz/widgets/transcription_viewer/transcription_resizer_widget.py:168 msgid "Desired subtitle length" msgstr "" -#: buzz/widgets/transcription_viewer/transcription_resizer_widget.py:195 +#: buzz/widgets/transcription_viewer/transcription_resizer_widget.py:193 msgid "Merge Options" msgstr "" -#: buzz/widgets/transcription_viewer/transcription_resizer_widget.py:206 +#: buzz/widgets/transcription_viewer/transcription_resizer_widget.py:204 msgid "Merge by gap" msgstr "" -#: buzz/widgets/transcription_viewer/transcription_resizer_widget.py:214 +#: buzz/widgets/transcription_viewer/transcription_resizer_widget.py:212 msgid "Split by punctuation" msgstr "" -#: buzz/widgets/transcription_viewer/transcription_resizer_widget.py:222 +#: buzz/widgets/transcription_viewer/transcription_resizer_widget.py:220 msgid "Split by max length" msgstr "" -#: buzz/widgets/transcription_viewer/transcription_resizer_widget.py:234 +#: buzz/widgets/transcription_viewer/transcription_resizer_widget.py:232 msgid "Merge" msgstr "" +#: buzz/widgets/transcription_viewer/speaker_identification_widget.py:92 +msgid "1/8 Collecting transcripts" +msgstr "" + +#: buzz/widgets/transcription_viewer/speaker_identification_widget.py:106 +msgid "2/8 Loading audio" +msgstr "" + +#: buzz/widgets/transcription_viewer/speaker_identification_widget.py:115 +msgid "3/8 Loading alignment model" +msgstr "" + +#: buzz/widgets/transcription_viewer/speaker_identification_widget.py:121 +msgid "4/8 Processing audio" +msgstr "" + +#: buzz/widgets/transcription_viewer/speaker_identification_widget.py:133 +#, fuzzy +msgid "5/8 Preparing transcripts" +msgstr "Anuluj transkrypcję" + +#: buzz/widgets/transcription_viewer/speaker_identification_widget.py:151 +msgid "6/8 Identifying speakers" +msgstr "" + +#: buzz/widgets/transcription_viewer/speaker_identification_widget.py:160 +msgid "0/0 Error identifying speakers" +msgstr "" + +#: buzz/widgets/transcription_viewer/speaker_identification_widget.py:168 +msgid "7/8 Mapping speakers to transcripts" +msgstr "" + +#: buzz/widgets/transcription_viewer/speaker_identification_widget.py:207 +msgid "8/8 Identification done" +msgstr "" + +#: buzz/widgets/transcription_viewer/speaker_identification_widget.py:243 +msgid "Step 1: Identify speakers" +msgstr "" + +#: buzz/widgets/transcription_viewer/speaker_identification_widget.py:255 +msgid "Identify" +msgstr "" + +#: buzz/widgets/transcription_viewer/speaker_identification_widget.py:265 +msgid "Ready to identify speakers" +msgstr "" + +#: buzz/widgets/transcription_viewer/speaker_identification_widget.py:267 +msgid "Audio file not found" +msgstr "" + +#: buzz/widgets/transcription_viewer/speaker_identification_widget.py:283 +msgid "Step 2: Name speakers" +msgstr "" + +#: buzz/widgets/transcription_viewer/speaker_identification_widget.py:298 +#: buzz/widgets/transcription_viewer/speaker_identification_widget.py:391 +msgid "Play sample" +msgstr "" + +#: buzz/widgets/transcription_viewer/speaker_identification_widget.py:313 +msgid "Merge speaker sentences" +msgstr "" + +#: buzz/widgets/transcription_viewer/speaker_identification_widget.py:318 +#, fuzzy +msgid "Save" +msgstr "Zapisz plik" + #: buzz/widgets/transcription_viewer/export_transcription_menu.py:82 #, fuzzy msgid "Save File" diff --git a/buzz/locale/pt_BR/LC_MESSAGES/buzz.po b/buzz/locale/pt_BR/LC_MESSAGES/buzz.po index 25165acd..39ae4c38 100644 --- a/buzz/locale/pt_BR/LC_MESSAGES/buzz.po +++ b/buzz/locale/pt_BR/LC_MESSAGES/buzz.po @@ -7,7 +7,7 @@ msgid "" msgstr "" "Project-Id-Version: Buzz\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2025-11-28 16:49+0200\n" +"POT-Creation-Date: 2025-11-23 12:55+0200\n" "PO-Revision-Date: 2025-11-01 17:43-0300\n" "Last-Translator: Paulo Schopf \n" "Language-Team: none\n" @@ -552,64 +552,68 @@ msgstr "Visualizar" msgid "Timestamps" msgstr "Marcações de tempo" -#: buzz/widgets/transcription_viewer/transcription_viewer_widget.py:211 +#: buzz/widgets/transcription_viewer/transcription_viewer_widget.py:215 msgid "Export" msgstr "Exportar" -#: buzz/widgets/transcription_viewer/transcription_viewer_widget.py:230 +#: buzz/widgets/transcription_viewer/transcription_viewer_widget.py:234 msgid "Translate" msgstr "Traduzir" -#: buzz/widgets/transcription_viewer/transcription_viewer_widget.py:240 -#: buzz/widgets/transcription_viewer/transcription_resizer_widget.py:177 +#: buzz/widgets/transcription_viewer/transcription_viewer_widget.py:244 +#: buzz/widgets/transcription_viewer/transcription_resizer_widget.py:175 msgid "Resize" msgstr "Redimensionar" -#: buzz/widgets/transcription_viewer/transcription_viewer_widget.py:252 +#: buzz/widgets/transcription_viewer/transcription_viewer_widget.py:257 +msgid "Identify Speakers" +msgstr "" + +#: buzz/widgets/transcription_viewer/transcription_viewer_widget.py:269 msgid "Find" msgstr "Procurar" -#: buzz/widgets/transcription_viewer/transcription_viewer_widget.py:255 +#: buzz/widgets/transcription_viewer/transcription_viewer_widget.py:272 msgid "Show/Hide Search Bar (Ctrl+F)" msgstr "Mostrar/Ocultar a Barra de Pesquisa" -#: buzz/widgets/transcription_viewer/transcription_viewer_widget.py:320 +#: buzz/widgets/transcription_viewer/transcription_viewer_widget.py:337 msgid "Find:" msgstr "Procurar:" -#: buzz/widgets/transcription_viewer/transcription_viewer_widget.py:326 +#: buzz/widgets/transcription_viewer/transcription_viewer_widget.py:343 msgid "Enter text to find..." msgstr "Digite o texto a procurar..." -#: buzz/widgets/transcription_viewer/transcription_viewer_widget.py:339 +#: buzz/widgets/transcription_viewer/transcription_viewer_widget.py:356 msgid "Previous match (Shift+Enter)" msgstr "Encontro prévio (Shift+Enter)" -#: buzz/widgets/transcription_viewer/transcription_viewer_widget.py:347 +#: buzz/widgets/transcription_viewer/transcription_viewer_widget.py:364 msgid "Next match (Enter)" msgstr "Póximo encontro (Enter)" -#: buzz/widgets/transcription_viewer/transcription_viewer_widget.py:355 +#: buzz/widgets/transcription_viewer/transcription_viewer_widget.py:372 msgid "Clear" msgstr "Limpar" -#: buzz/widgets/transcription_viewer/transcription_viewer_widget.py:382 +#: buzz/widgets/transcription_viewer/transcription_viewer_widget.py:399 msgid "Playback Controls:" msgstr "Controles de Reprodução:" -#: buzz/widgets/transcription_viewer/transcription_viewer_widget.py:387 +#: buzz/widgets/transcription_viewer/transcription_viewer_widget.py:404 msgid "Loop Segment" msgstr "Segmento de Loop" -#: buzz/widgets/transcription_viewer/transcription_viewer_widget.py:389 +#: buzz/widgets/transcription_viewer/transcription_viewer_widget.py:406 msgid "Enable/disable looping when clicking on transcript segments" msgstr "Habilitar/desabilitar loop ao clicar em segmentos de transcrição" -#: buzz/widgets/transcription_viewer/transcription_viewer_widget.py:395 +#: buzz/widgets/transcription_viewer/transcription_viewer_widget.py:412 msgid "Follow Audio" msgstr "Siga o Áudio" -#: buzz/widgets/transcription_viewer/transcription_viewer_widget.py:397 +#: buzz/widgets/transcription_viewer/transcription_viewer_widget.py:414 msgid "" "Enable/disable following the current audio position in the transcript. When " "enabled, automatically scrolls to current text." @@ -617,75 +621,146 @@ msgstr "" "Ativar/desativar a opção de seguir a posição atual do áudio na transcrição. " "Quando ativado, rola automaticamente para o texto atual." -#: buzz/widgets/transcription_viewer/transcription_viewer_widget.py:444 +#: buzz/widgets/transcription_viewer/transcription_viewer_widget.py:461 msgid "Scroll to Current" msgstr "Rolar para o Atual" -#: buzz/widgets/transcription_viewer/transcription_viewer_widget.py:446 +#: buzz/widgets/transcription_viewer/transcription_viewer_widget.py:463 msgid "Scroll to the currently spoken text" msgstr "Role até o texto falado no momento" -#: buzz/widgets/transcription_viewer/transcription_viewer_widget.py:768 +#: buzz/widgets/transcription_viewer/transcription_viewer_widget.py:785 msgid "1 of 100+ matches" msgstr "1 de 100+ encontros" -#: buzz/widgets/transcription_viewer/transcription_viewer_widget.py:770 +#: buzz/widgets/transcription_viewer/transcription_viewer_widget.py:787 msgid "1 of " msgstr "1 de " -#: buzz/widgets/transcription_viewer/transcription_viewer_widget.py:770 -#: buzz/widgets/transcription_viewer/transcription_viewer_widget.py:836 +#: buzz/widgets/transcription_viewer/transcription_viewer_widget.py:787 +#: buzz/widgets/transcription_viewer/transcription_viewer_widget.py:853 msgid " matches" msgstr " encontros" -#: buzz/widgets/transcription_viewer/transcription_viewer_widget.py:775 +#: buzz/widgets/transcription_viewer/transcription_viewer_widget.py:792 msgid "No matches found" msgstr "Nada encontrado" -#: buzz/widgets/transcription_viewer/transcription_viewer_widget.py:834 +#: buzz/widgets/transcription_viewer/transcription_viewer_widget.py:851 msgid " of 100+ matches" msgstr " de 100+ encontros" -#: buzz/widgets/transcription_viewer/transcription_viewer_widget.py:836 +#: buzz/widgets/transcription_viewer/transcription_viewer_widget.py:853 msgid " of " msgstr " de " -#: buzz/widgets/transcription_viewer/transcription_viewer_widget.py:1191 +#: buzz/widgets/transcription_viewer/transcription_viewer_widget.py:1208 msgid "API Key Required" msgstr "Chave API Necessária" -#: buzz/widgets/transcription_viewer/transcription_viewer_widget.py:1192 +#: buzz/widgets/transcription_viewer/transcription_viewer_widget.py:1209 msgid "Please enter OpenAI API Key in preferences" msgstr "Insira a chave API OpenAI nas preferências" -#: buzz/widgets/transcription_viewer/transcription_resizer_widget.py:159 +#: buzz/widgets/transcription_viewer/transcription_resizer_widget.py:157 msgid "Resize Options" msgstr "Opções de Redimensionamento" -#: buzz/widgets/transcription_viewer/transcription_resizer_widget.py:170 +#: buzz/widgets/transcription_viewer/transcription_resizer_widget.py:168 msgid "Desired subtitle length" msgstr "Duração desejada da legenda" -#: buzz/widgets/transcription_viewer/transcription_resizer_widget.py:195 +#: buzz/widgets/transcription_viewer/transcription_resizer_widget.py:193 msgid "Merge Options" msgstr "Opções de Mesclagem" -#: buzz/widgets/transcription_viewer/transcription_resizer_widget.py:206 +#: buzz/widgets/transcription_viewer/transcription_resizer_widget.py:204 msgid "Merge by gap" msgstr "Mesclar por intervalo" -#: buzz/widgets/transcription_viewer/transcription_resizer_widget.py:214 +#: buzz/widgets/transcription_viewer/transcription_resizer_widget.py:212 msgid "Split by punctuation" msgstr "Dividir por pontuação" -#: buzz/widgets/transcription_viewer/transcription_resizer_widget.py:222 +#: buzz/widgets/transcription_viewer/transcription_resizer_widget.py:220 msgid "Split by max length" msgstr "Dividir por tamanho máximo" -#: buzz/widgets/transcription_viewer/transcription_resizer_widget.py:234 +#: buzz/widgets/transcription_viewer/transcription_resizer_widget.py:232 msgid "Merge" msgstr "Mesclar" +#: buzz/widgets/transcription_viewer/speaker_identification_widget.py:92 +msgid "1/8 Collecting transcripts" +msgstr "" + +#: buzz/widgets/transcription_viewer/speaker_identification_widget.py:106 +msgid "2/8 Loading audio" +msgstr "" + +#: buzz/widgets/transcription_viewer/speaker_identification_widget.py:115 +msgid "3/8 Loading alignment model" +msgstr "" + +#: buzz/widgets/transcription_viewer/speaker_identification_widget.py:121 +msgid "4/8 Processing audio" +msgstr "" + +#: buzz/widgets/transcription_viewer/speaker_identification_widget.py:133 +#, fuzzy +msgid "5/8 Preparing transcripts" +msgstr "Iniciando transcrição..." + +#: buzz/widgets/transcription_viewer/speaker_identification_widget.py:151 +msgid "6/8 Identifying speakers" +msgstr "" + +#: buzz/widgets/transcription_viewer/speaker_identification_widget.py:160 +msgid "0/0 Error identifying speakers" +msgstr "" + +#: buzz/widgets/transcription_viewer/speaker_identification_widget.py:168 +msgid "7/8 Mapping speakers to transcripts" +msgstr "" + +#: buzz/widgets/transcription_viewer/speaker_identification_widget.py:207 +msgid "8/8 Identification done" +msgstr "" + +#: buzz/widgets/transcription_viewer/speaker_identification_widget.py:243 +msgid "Step 1: Identify speakers" +msgstr "" + +#: buzz/widgets/transcription_viewer/speaker_identification_widget.py:255 +msgid "Identify" +msgstr "" + +#: buzz/widgets/transcription_viewer/speaker_identification_widget.py:265 +msgid "Ready to identify speakers" +msgstr "" + +#: buzz/widgets/transcription_viewer/speaker_identification_widget.py:267 +msgid "Audio file not found" +msgstr "" + +#: buzz/widgets/transcription_viewer/speaker_identification_widget.py:283 +msgid "Step 2: Name speakers" +msgstr "" + +#: buzz/widgets/transcription_viewer/speaker_identification_widget.py:298 +#: buzz/widgets/transcription_viewer/speaker_identification_widget.py:391 +msgid "Play sample" +msgstr "" + +#: buzz/widgets/transcription_viewer/speaker_identification_widget.py:313 +msgid "Merge speaker sentences" +msgstr "" + +#: buzz/widgets/transcription_viewer/speaker_identification_widget.py:318 +#, fuzzy +msgid "Save" +msgstr "Salvar Arquivo" + #: buzz/widgets/transcription_viewer/export_transcription_menu.py:82 msgid "Save File" msgstr "Salvar Arquivo" diff --git a/buzz/locale/uk_UA/LC_MESSAGES/buzz.po b/buzz/locale/uk_UA/LC_MESSAGES/buzz.po index f45a5184..2ef57f95 100644 --- a/buzz/locale/uk_UA/LC_MESSAGES/buzz.po +++ b/buzz/locale/uk_UA/LC_MESSAGES/buzz.po @@ -2,7 +2,7 @@ msgid "" msgstr "" "Project-Id-Version: \n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2025-11-28 16:49+0200\n" +"POT-Creation-Date: 2025-11-23 12:55+0200\n" "PO-Revision-Date: \n" "Last-Translator: Yevhen Popok \n" "Language-Team: \n" @@ -550,138 +550,213 @@ msgstr "Вигляд" msgid "Timestamps" msgstr "Позначки часу" -#: buzz/widgets/transcription_viewer/transcription_viewer_widget.py:211 +#: buzz/widgets/transcription_viewer/transcription_viewer_widget.py:215 msgid "Export" msgstr "Експорт" -#: buzz/widgets/transcription_viewer/transcription_viewer_widget.py:230 +#: buzz/widgets/transcription_viewer/transcription_viewer_widget.py:234 msgid "Translate" msgstr "Перекласти" -#: buzz/widgets/transcription_viewer/transcription_viewer_widget.py:240 -#: buzz/widgets/transcription_viewer/transcription_resizer_widget.py:177 +#: buzz/widgets/transcription_viewer/transcription_viewer_widget.py:244 +#: buzz/widgets/transcription_viewer/transcription_resizer_widget.py:175 msgid "Resize" msgstr "" -#: buzz/widgets/transcription_viewer/transcription_viewer_widget.py:252 +#: buzz/widgets/transcription_viewer/transcription_viewer_widget.py:257 +msgid "Identify Speakers" +msgstr "" + +#: buzz/widgets/transcription_viewer/transcription_viewer_widget.py:269 msgid "Find" msgstr "" -#: buzz/widgets/transcription_viewer/transcription_viewer_widget.py:255 +#: buzz/widgets/transcription_viewer/transcription_viewer_widget.py:272 msgid "Show/Hide Search Bar (Ctrl+F)" msgstr "" -#: buzz/widgets/transcription_viewer/transcription_viewer_widget.py:320 +#: buzz/widgets/transcription_viewer/transcription_viewer_widget.py:337 msgid "Find:" msgstr "" -#: buzz/widgets/transcription_viewer/transcription_viewer_widget.py:326 +#: buzz/widgets/transcription_viewer/transcription_viewer_widget.py:343 msgid "Enter text to find..." msgstr "" -#: buzz/widgets/transcription_viewer/transcription_viewer_widget.py:339 +#: buzz/widgets/transcription_viewer/transcription_viewer_widget.py:356 msgid "Previous match (Shift+Enter)" msgstr "" -#: buzz/widgets/transcription_viewer/transcription_viewer_widget.py:347 +#: buzz/widgets/transcription_viewer/transcription_viewer_widget.py:364 msgid "Next match (Enter)" msgstr "" -#: buzz/widgets/transcription_viewer/transcription_viewer_widget.py:355 +#: buzz/widgets/transcription_viewer/transcription_viewer_widget.py:372 msgid "Clear" msgstr "" -#: buzz/widgets/transcription_viewer/transcription_viewer_widget.py:382 +#: buzz/widgets/transcription_viewer/transcription_viewer_widget.py:399 msgid "Playback Controls:" msgstr "" -#: buzz/widgets/transcription_viewer/transcription_viewer_widget.py:387 +#: buzz/widgets/transcription_viewer/transcription_viewer_widget.py:404 msgid "Loop Segment" msgstr "" -#: buzz/widgets/transcription_viewer/transcription_viewer_widget.py:389 +#: buzz/widgets/transcription_viewer/transcription_viewer_widget.py:406 msgid "Enable/disable looping when clicking on transcript segments" msgstr "" -#: buzz/widgets/transcription_viewer/transcription_viewer_widget.py:395 +#: buzz/widgets/transcription_viewer/transcription_viewer_widget.py:412 msgid "Follow Audio" msgstr "" -#: buzz/widgets/transcription_viewer/transcription_viewer_widget.py:397 +#: buzz/widgets/transcription_viewer/transcription_viewer_widget.py:414 msgid "" "Enable/disable following the current audio position in the transcript. When " "enabled, automatically scrolls to current text." msgstr "" -#: buzz/widgets/transcription_viewer/transcription_viewer_widget.py:444 +#: buzz/widgets/transcription_viewer/transcription_viewer_widget.py:461 msgid "Scroll to Current" msgstr "" -#: buzz/widgets/transcription_viewer/transcription_viewer_widget.py:446 +#: buzz/widgets/transcription_viewer/transcription_viewer_widget.py:463 msgid "Scroll to the currently spoken text" msgstr "" -#: buzz/widgets/transcription_viewer/transcription_viewer_widget.py:768 +#: buzz/widgets/transcription_viewer/transcription_viewer_widget.py:785 msgid "1 of 100+ matches" msgstr "" -#: buzz/widgets/transcription_viewer/transcription_viewer_widget.py:770 +#: buzz/widgets/transcription_viewer/transcription_viewer_widget.py:787 msgid "1 of " msgstr "" -#: buzz/widgets/transcription_viewer/transcription_viewer_widget.py:770 -#: buzz/widgets/transcription_viewer/transcription_viewer_widget.py:836 +#: buzz/widgets/transcription_viewer/transcription_viewer_widget.py:787 +#: buzz/widgets/transcription_viewer/transcription_viewer_widget.py:853 msgid " matches" msgstr "" -#: buzz/widgets/transcription_viewer/transcription_viewer_widget.py:775 +#: buzz/widgets/transcription_viewer/transcription_viewer_widget.py:792 msgid "No matches found" msgstr "" -#: buzz/widgets/transcription_viewer/transcription_viewer_widget.py:834 +#: buzz/widgets/transcription_viewer/transcription_viewer_widget.py:851 msgid " of 100+ matches" msgstr "" -#: buzz/widgets/transcription_viewer/transcription_viewer_widget.py:836 +#: buzz/widgets/transcription_viewer/transcription_viewer_widget.py:853 msgid " of " msgstr "" -#: buzz/widgets/transcription_viewer/transcription_viewer_widget.py:1191 +#: buzz/widgets/transcription_viewer/transcription_viewer_widget.py:1208 msgid "API Key Required" msgstr "Потрібен API-ключ" -#: buzz/widgets/transcription_viewer/transcription_viewer_widget.py:1192 +#: buzz/widgets/transcription_viewer/transcription_viewer_widget.py:1209 msgid "Please enter OpenAI API Key in preferences" msgstr "Будь ласка, введіть API-ключ OpenAI в налаштуваннях" -#: buzz/widgets/transcription_viewer/transcription_resizer_widget.py:159 +#: buzz/widgets/transcription_viewer/transcription_resizer_widget.py:157 msgid "Resize Options" msgstr "" -#: buzz/widgets/transcription_viewer/transcription_resizer_widget.py:170 +#: buzz/widgets/transcription_viewer/transcription_resizer_widget.py:168 msgid "Desired subtitle length" msgstr "" -#: buzz/widgets/transcription_viewer/transcription_resizer_widget.py:195 +#: buzz/widgets/transcription_viewer/transcription_resizer_widget.py:193 msgid "Merge Options" msgstr "" -#: buzz/widgets/transcription_viewer/transcription_resizer_widget.py:206 +#: buzz/widgets/transcription_viewer/transcription_resizer_widget.py:204 msgid "Merge by gap" msgstr "" -#: buzz/widgets/transcription_viewer/transcription_resizer_widget.py:214 +#: buzz/widgets/transcription_viewer/transcription_resizer_widget.py:212 msgid "Split by punctuation" msgstr "" -#: buzz/widgets/transcription_viewer/transcription_resizer_widget.py:222 +#: buzz/widgets/transcription_viewer/transcription_resizer_widget.py:220 msgid "Split by max length" msgstr "" -#: buzz/widgets/transcription_viewer/transcription_resizer_widget.py:234 +#: buzz/widgets/transcription_viewer/transcription_resizer_widget.py:232 msgid "Merge" msgstr "" +#: buzz/widgets/transcription_viewer/speaker_identification_widget.py:92 +msgid "1/8 Collecting transcripts" +msgstr "" + +#: buzz/widgets/transcription_viewer/speaker_identification_widget.py:106 +msgid "2/8 Loading audio" +msgstr "" + +#: buzz/widgets/transcription_viewer/speaker_identification_widget.py:115 +msgid "3/8 Loading alignment model" +msgstr "" + +#: buzz/widgets/transcription_viewer/speaker_identification_widget.py:121 +msgid "4/8 Processing audio" +msgstr "" + +#: buzz/widgets/transcription_viewer/speaker_identification_widget.py:133 +#, fuzzy +msgid "5/8 Preparing transcripts" +msgstr "Скасувати транскрипцію" + +#: buzz/widgets/transcription_viewer/speaker_identification_widget.py:151 +msgid "6/8 Identifying speakers" +msgstr "" + +#: buzz/widgets/transcription_viewer/speaker_identification_widget.py:160 +msgid "0/0 Error identifying speakers" +msgstr "" + +#: buzz/widgets/transcription_viewer/speaker_identification_widget.py:168 +msgid "7/8 Mapping speakers to transcripts" +msgstr "" + +#: buzz/widgets/transcription_viewer/speaker_identification_widget.py:207 +msgid "8/8 Identification done" +msgstr "" + +#: buzz/widgets/transcription_viewer/speaker_identification_widget.py:243 +msgid "Step 1: Identify speakers" +msgstr "" + +#: buzz/widgets/transcription_viewer/speaker_identification_widget.py:255 +msgid "Identify" +msgstr "" + +#: buzz/widgets/transcription_viewer/speaker_identification_widget.py:265 +msgid "Ready to identify speakers" +msgstr "" + +#: buzz/widgets/transcription_viewer/speaker_identification_widget.py:267 +msgid "Audio file not found" +msgstr "" + +#: buzz/widgets/transcription_viewer/speaker_identification_widget.py:283 +msgid "Step 2: Name speakers" +msgstr "" + +#: buzz/widgets/transcription_viewer/speaker_identification_widget.py:298 +#: buzz/widgets/transcription_viewer/speaker_identification_widget.py:391 +msgid "Play sample" +msgstr "" + +#: buzz/widgets/transcription_viewer/speaker_identification_widget.py:313 +msgid "Merge speaker sentences" +msgstr "" + +#: buzz/widgets/transcription_viewer/speaker_identification_widget.py:318 +#, fuzzy +msgid "Save" +msgstr "Зберегти файл" + #: buzz/widgets/transcription_viewer/export_transcription_menu.py:82 msgid "Save File" msgstr "Зберегти файл" diff --git a/buzz/locale/zh_CN/LC_MESSAGES/buzz.po b/buzz/locale/zh_CN/LC_MESSAGES/buzz.po index 0e9154a2..5cdb3a7b 100644 --- a/buzz/locale/zh_CN/LC_MESSAGES/buzz.po +++ b/buzz/locale/zh_CN/LC_MESSAGES/buzz.po @@ -7,7 +7,7 @@ msgid "" msgstr "" "Project-Id-Version: \n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2025-11-28 16:49+0200\n" +"POT-Creation-Date: 2025-11-23 12:55+0200\n" "PO-Revision-Date: 2023-05-01 15:45+0800\n" "Last-Translator: \n" "Language-Team: lamb \n" @@ -562,139 +562,214 @@ msgstr "查看" msgid "Timestamps" msgstr "时间戳" -#: buzz/widgets/transcription_viewer/transcription_viewer_widget.py:211 +#: buzz/widgets/transcription_viewer/transcription_viewer_widget.py:215 msgid "Export" msgstr "导出" -#: buzz/widgets/transcription_viewer/transcription_viewer_widget.py:230 +#: buzz/widgets/transcription_viewer/transcription_viewer_widget.py:234 msgid "Translate" msgstr "翻译" -#: buzz/widgets/transcription_viewer/transcription_viewer_widget.py:240 -#: buzz/widgets/transcription_viewer/transcription_resizer_widget.py:177 +#: buzz/widgets/transcription_viewer/transcription_viewer_widget.py:244 +#: buzz/widgets/transcription_viewer/transcription_resizer_widget.py:175 msgid "Resize" msgstr "调整大小" -#: buzz/widgets/transcription_viewer/transcription_viewer_widget.py:252 +#: buzz/widgets/transcription_viewer/transcription_viewer_widget.py:257 +msgid "Identify Speakers" +msgstr "" + +#: buzz/widgets/transcription_viewer/transcription_viewer_widget.py:269 msgid "Find" msgstr "" -#: buzz/widgets/transcription_viewer/transcription_viewer_widget.py:255 +#: buzz/widgets/transcription_viewer/transcription_viewer_widget.py:272 msgid "Show/Hide Search Bar (Ctrl+F)" msgstr "" -#: buzz/widgets/transcription_viewer/transcription_viewer_widget.py:320 +#: buzz/widgets/transcription_viewer/transcription_viewer_widget.py:337 msgid "Find:" msgstr "" -#: buzz/widgets/transcription_viewer/transcription_viewer_widget.py:326 +#: buzz/widgets/transcription_viewer/transcription_viewer_widget.py:343 msgid "Enter text to find..." msgstr "" -#: buzz/widgets/transcription_viewer/transcription_viewer_widget.py:339 +#: buzz/widgets/transcription_viewer/transcription_viewer_widget.py:356 msgid "Previous match (Shift+Enter)" msgstr "" -#: buzz/widgets/transcription_viewer/transcription_viewer_widget.py:347 +#: buzz/widgets/transcription_viewer/transcription_viewer_widget.py:364 msgid "Next match (Enter)" msgstr "" -#: buzz/widgets/transcription_viewer/transcription_viewer_widget.py:355 +#: buzz/widgets/transcription_viewer/transcription_viewer_widget.py:372 msgid "Clear" msgstr "" -#: buzz/widgets/transcription_viewer/transcription_viewer_widget.py:382 +#: buzz/widgets/transcription_viewer/transcription_viewer_widget.py:399 msgid "Playback Controls:" msgstr "" -#: buzz/widgets/transcription_viewer/transcription_viewer_widget.py:387 +#: buzz/widgets/transcription_viewer/transcription_viewer_widget.py:404 msgid "Loop Segment" msgstr "" -#: buzz/widgets/transcription_viewer/transcription_viewer_widget.py:389 +#: buzz/widgets/transcription_viewer/transcription_viewer_widget.py:406 msgid "Enable/disable looping when clicking on transcript segments" msgstr "" -#: buzz/widgets/transcription_viewer/transcription_viewer_widget.py:395 +#: buzz/widgets/transcription_viewer/transcription_viewer_widget.py:412 msgid "Follow Audio" msgstr "" -#: buzz/widgets/transcription_viewer/transcription_viewer_widget.py:397 +#: buzz/widgets/transcription_viewer/transcription_viewer_widget.py:414 msgid "" "Enable/disable following the current audio position in the transcript. When " "enabled, automatically scrolls to current text." msgstr "" -#: buzz/widgets/transcription_viewer/transcription_viewer_widget.py:444 +#: buzz/widgets/transcription_viewer/transcription_viewer_widget.py:461 msgid "Scroll to Current" msgstr "" -#: buzz/widgets/transcription_viewer/transcription_viewer_widget.py:446 +#: buzz/widgets/transcription_viewer/transcription_viewer_widget.py:463 msgid "Scroll to the currently spoken text" msgstr "" -#: buzz/widgets/transcription_viewer/transcription_viewer_widget.py:768 +#: buzz/widgets/transcription_viewer/transcription_viewer_widget.py:785 msgid "1 of 100+ matches" msgstr "" -#: buzz/widgets/transcription_viewer/transcription_viewer_widget.py:770 +#: buzz/widgets/transcription_viewer/transcription_viewer_widget.py:787 msgid "1 of " msgstr "" -#: buzz/widgets/transcription_viewer/transcription_viewer_widget.py:770 -#: buzz/widgets/transcription_viewer/transcription_viewer_widget.py:836 +#: buzz/widgets/transcription_viewer/transcription_viewer_widget.py:787 +#: buzz/widgets/transcription_viewer/transcription_viewer_widget.py:853 msgid " matches" msgstr "" -#: buzz/widgets/transcription_viewer/transcription_viewer_widget.py:775 +#: buzz/widgets/transcription_viewer/transcription_viewer_widget.py:792 msgid "No matches found" msgstr "" -#: buzz/widgets/transcription_viewer/transcription_viewer_widget.py:834 +#: buzz/widgets/transcription_viewer/transcription_viewer_widget.py:851 msgid " of 100+ matches" msgstr "" -#: buzz/widgets/transcription_viewer/transcription_viewer_widget.py:836 +#: buzz/widgets/transcription_viewer/transcription_viewer_widget.py:853 msgid " of " msgstr "" -#: buzz/widgets/transcription_viewer/transcription_viewer_widget.py:1191 +#: buzz/widgets/transcription_viewer/transcription_viewer_widget.py:1208 msgid "API Key Required" msgstr "需要API Key" -#: buzz/widgets/transcription_viewer/transcription_viewer_widget.py:1192 +#: buzz/widgets/transcription_viewer/transcription_viewer_widget.py:1209 msgid "Please enter OpenAI API Key in preferences" msgstr "请在偏好设置中输入OpenAI API Key" -#: buzz/widgets/transcription_viewer/transcription_resizer_widget.py:159 +#: buzz/widgets/transcription_viewer/transcription_resizer_widget.py:157 #, fuzzy msgid "Resize Options" msgstr "调整大小" -#: buzz/widgets/transcription_viewer/transcription_resizer_widget.py:170 +#: buzz/widgets/transcription_viewer/transcription_resizer_widget.py:168 msgid "Desired subtitle length" msgstr "所需字幕长度" -#: buzz/widgets/transcription_viewer/transcription_resizer_widget.py:195 +#: buzz/widgets/transcription_viewer/transcription_resizer_widget.py:193 msgid "Merge Options" msgstr "合并选项" -#: buzz/widgets/transcription_viewer/transcription_resizer_widget.py:206 +#: buzz/widgets/transcription_viewer/transcription_resizer_widget.py:204 msgid "Merge by gap" msgstr "按间隔合并" -#: buzz/widgets/transcription_viewer/transcription_resizer_widget.py:214 +#: buzz/widgets/transcription_viewer/transcription_resizer_widget.py:212 msgid "Split by punctuation" msgstr "按标点符号拆分" -#: buzz/widgets/transcription_viewer/transcription_resizer_widget.py:222 +#: buzz/widgets/transcription_viewer/transcription_resizer_widget.py:220 msgid "Split by max length" msgstr "按最大长度拆分" -#: buzz/widgets/transcription_viewer/transcription_resizer_widget.py:234 +#: buzz/widgets/transcription_viewer/transcription_resizer_widget.py:232 msgid "Merge" msgstr "合并" +#: buzz/widgets/transcription_viewer/speaker_identification_widget.py:92 +msgid "1/8 Collecting transcripts" +msgstr "" + +#: buzz/widgets/transcription_viewer/speaker_identification_widget.py:106 +msgid "2/8 Loading audio" +msgstr "" + +#: buzz/widgets/transcription_viewer/speaker_identification_widget.py:115 +msgid "3/8 Loading alignment model" +msgstr "" + +#: buzz/widgets/transcription_viewer/speaker_identification_widget.py:121 +msgid "4/8 Processing audio" +msgstr "" + +#: buzz/widgets/transcription_viewer/speaker_identification_widget.py:133 +#, fuzzy +msgid "5/8 Preparing transcripts" +msgstr "取消识别" + +#: buzz/widgets/transcription_viewer/speaker_identification_widget.py:151 +msgid "6/8 Identifying speakers" +msgstr "" + +#: buzz/widgets/transcription_viewer/speaker_identification_widget.py:160 +msgid "0/0 Error identifying speakers" +msgstr "" + +#: buzz/widgets/transcription_viewer/speaker_identification_widget.py:168 +msgid "7/8 Mapping speakers to transcripts" +msgstr "" + +#: buzz/widgets/transcription_viewer/speaker_identification_widget.py:207 +msgid "8/8 Identification done" +msgstr "" + +#: buzz/widgets/transcription_viewer/speaker_identification_widget.py:243 +msgid "Step 1: Identify speakers" +msgstr "" + +#: buzz/widgets/transcription_viewer/speaker_identification_widget.py:255 +msgid "Identify" +msgstr "" + +#: buzz/widgets/transcription_viewer/speaker_identification_widget.py:265 +msgid "Ready to identify speakers" +msgstr "" + +#: buzz/widgets/transcription_viewer/speaker_identification_widget.py:267 +msgid "Audio file not found" +msgstr "" + +#: buzz/widgets/transcription_viewer/speaker_identification_widget.py:283 +msgid "Step 2: Name speakers" +msgstr "" + +#: buzz/widgets/transcription_viewer/speaker_identification_widget.py:298 +#: buzz/widgets/transcription_viewer/speaker_identification_widget.py:391 +msgid "Play sample" +msgstr "" + +#: buzz/widgets/transcription_viewer/speaker_identification_widget.py:313 +msgid "Merge speaker sentences" +msgstr "" + +#: buzz/widgets/transcription_viewer/speaker_identification_widget.py:318 +#, fuzzy +msgid "Save" +msgstr "保存文件" + #: buzz/widgets/transcription_viewer/export_transcription_menu.py:82 #, fuzzy msgid "Save File" diff --git a/buzz/locale/zh_TW/LC_MESSAGES/buzz.po b/buzz/locale/zh_TW/LC_MESSAGES/buzz.po index ed67c2c8..fd0fe400 100644 --- a/buzz/locale/zh_TW/LC_MESSAGES/buzz.po +++ b/buzz/locale/zh_TW/LC_MESSAGES/buzz.po @@ -7,7 +7,7 @@ msgid "" msgstr "" "Project-Id-Version: \n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2025-11-28 16:49+0200\n" +"POT-Creation-Date: 2025-11-23 12:55+0200\n" "PO-Revision-Date: 2023-05-01 15:45+0800\n" "Last-Translator: \n" "Language-Team: Lamb\n" @@ -557,138 +557,213 @@ msgstr "" msgid "Timestamps" msgstr "" -#: buzz/widgets/transcription_viewer/transcription_viewer_widget.py:211 +#: buzz/widgets/transcription_viewer/transcription_viewer_widget.py:215 msgid "Export" msgstr "" -#: buzz/widgets/transcription_viewer/transcription_viewer_widget.py:230 +#: buzz/widgets/transcription_viewer/transcription_viewer_widget.py:234 msgid "Translate" msgstr "" -#: buzz/widgets/transcription_viewer/transcription_viewer_widget.py:240 -#: buzz/widgets/transcription_viewer/transcription_resizer_widget.py:177 +#: buzz/widgets/transcription_viewer/transcription_viewer_widget.py:244 +#: buzz/widgets/transcription_viewer/transcription_resizer_widget.py:175 msgid "Resize" msgstr "" -#: buzz/widgets/transcription_viewer/transcription_viewer_widget.py:252 +#: buzz/widgets/transcription_viewer/transcription_viewer_widget.py:257 +msgid "Identify Speakers" +msgstr "" + +#: buzz/widgets/transcription_viewer/transcription_viewer_widget.py:269 msgid "Find" msgstr "" -#: buzz/widgets/transcription_viewer/transcription_viewer_widget.py:255 +#: buzz/widgets/transcription_viewer/transcription_viewer_widget.py:272 msgid "Show/Hide Search Bar (Ctrl+F)" msgstr "" -#: buzz/widgets/transcription_viewer/transcription_viewer_widget.py:320 +#: buzz/widgets/transcription_viewer/transcription_viewer_widget.py:337 msgid "Find:" msgstr "" -#: buzz/widgets/transcription_viewer/transcription_viewer_widget.py:326 +#: buzz/widgets/transcription_viewer/transcription_viewer_widget.py:343 msgid "Enter text to find..." msgstr "" -#: buzz/widgets/transcription_viewer/transcription_viewer_widget.py:339 +#: buzz/widgets/transcription_viewer/transcription_viewer_widget.py:356 msgid "Previous match (Shift+Enter)" msgstr "" -#: buzz/widgets/transcription_viewer/transcription_viewer_widget.py:347 +#: buzz/widgets/transcription_viewer/transcription_viewer_widget.py:364 msgid "Next match (Enter)" msgstr "" -#: buzz/widgets/transcription_viewer/transcription_viewer_widget.py:355 +#: buzz/widgets/transcription_viewer/transcription_viewer_widget.py:372 msgid "Clear" msgstr "" -#: buzz/widgets/transcription_viewer/transcription_viewer_widget.py:382 +#: buzz/widgets/transcription_viewer/transcription_viewer_widget.py:399 msgid "Playback Controls:" msgstr "" -#: buzz/widgets/transcription_viewer/transcription_viewer_widget.py:387 +#: buzz/widgets/transcription_viewer/transcription_viewer_widget.py:404 msgid "Loop Segment" msgstr "" -#: buzz/widgets/transcription_viewer/transcription_viewer_widget.py:389 +#: buzz/widgets/transcription_viewer/transcription_viewer_widget.py:406 msgid "Enable/disable looping when clicking on transcript segments" msgstr "" -#: buzz/widgets/transcription_viewer/transcription_viewer_widget.py:395 +#: buzz/widgets/transcription_viewer/transcription_viewer_widget.py:412 msgid "Follow Audio" msgstr "" -#: buzz/widgets/transcription_viewer/transcription_viewer_widget.py:397 +#: buzz/widgets/transcription_viewer/transcription_viewer_widget.py:414 msgid "" "Enable/disable following the current audio position in the transcript. When " "enabled, automatically scrolls to current text." msgstr "" -#: buzz/widgets/transcription_viewer/transcription_viewer_widget.py:444 +#: buzz/widgets/transcription_viewer/transcription_viewer_widget.py:461 msgid "Scroll to Current" msgstr "" -#: buzz/widgets/transcription_viewer/transcription_viewer_widget.py:446 +#: buzz/widgets/transcription_viewer/transcription_viewer_widget.py:463 msgid "Scroll to the currently spoken text" msgstr "" -#: buzz/widgets/transcription_viewer/transcription_viewer_widget.py:768 +#: buzz/widgets/transcription_viewer/transcription_viewer_widget.py:785 msgid "1 of 100+ matches" msgstr "" -#: buzz/widgets/transcription_viewer/transcription_viewer_widget.py:770 +#: buzz/widgets/transcription_viewer/transcription_viewer_widget.py:787 msgid "1 of " msgstr "" -#: buzz/widgets/transcription_viewer/transcription_viewer_widget.py:770 -#: buzz/widgets/transcription_viewer/transcription_viewer_widget.py:836 +#: buzz/widgets/transcription_viewer/transcription_viewer_widget.py:787 +#: buzz/widgets/transcription_viewer/transcription_viewer_widget.py:853 msgid " matches" msgstr "" -#: buzz/widgets/transcription_viewer/transcription_viewer_widget.py:775 +#: buzz/widgets/transcription_viewer/transcription_viewer_widget.py:792 msgid "No matches found" msgstr "" -#: buzz/widgets/transcription_viewer/transcription_viewer_widget.py:834 +#: buzz/widgets/transcription_viewer/transcription_viewer_widget.py:851 msgid " of 100+ matches" msgstr "" -#: buzz/widgets/transcription_viewer/transcription_viewer_widget.py:836 +#: buzz/widgets/transcription_viewer/transcription_viewer_widget.py:853 msgid " of " msgstr "" -#: buzz/widgets/transcription_viewer/transcription_viewer_widget.py:1191 +#: buzz/widgets/transcription_viewer/transcription_viewer_widget.py:1208 msgid "API Key Required" msgstr "" -#: buzz/widgets/transcription_viewer/transcription_viewer_widget.py:1192 +#: buzz/widgets/transcription_viewer/transcription_viewer_widget.py:1209 msgid "Please enter OpenAI API Key in preferences" msgstr "" -#: buzz/widgets/transcription_viewer/transcription_resizer_widget.py:159 +#: buzz/widgets/transcription_viewer/transcription_resizer_widget.py:157 msgid "Resize Options" msgstr "" -#: buzz/widgets/transcription_viewer/transcription_resizer_widget.py:170 +#: buzz/widgets/transcription_viewer/transcription_resizer_widget.py:168 msgid "Desired subtitle length" msgstr "" -#: buzz/widgets/transcription_viewer/transcription_resizer_widget.py:195 +#: buzz/widgets/transcription_viewer/transcription_resizer_widget.py:193 msgid "Merge Options" msgstr "" -#: buzz/widgets/transcription_viewer/transcription_resizer_widget.py:206 +#: buzz/widgets/transcription_viewer/transcription_resizer_widget.py:204 msgid "Merge by gap" msgstr "" -#: buzz/widgets/transcription_viewer/transcription_resizer_widget.py:214 +#: buzz/widgets/transcription_viewer/transcription_resizer_widget.py:212 msgid "Split by punctuation" msgstr "" -#: buzz/widgets/transcription_viewer/transcription_resizer_widget.py:222 +#: buzz/widgets/transcription_viewer/transcription_resizer_widget.py:220 msgid "Split by max length" msgstr "" -#: buzz/widgets/transcription_viewer/transcription_resizer_widget.py:234 +#: buzz/widgets/transcription_viewer/transcription_resizer_widget.py:232 msgid "Merge" msgstr "" +#: buzz/widgets/transcription_viewer/speaker_identification_widget.py:92 +msgid "1/8 Collecting transcripts" +msgstr "" + +#: buzz/widgets/transcription_viewer/speaker_identification_widget.py:106 +msgid "2/8 Loading audio" +msgstr "" + +#: buzz/widgets/transcription_viewer/speaker_identification_widget.py:115 +msgid "3/8 Loading alignment model" +msgstr "" + +#: buzz/widgets/transcription_viewer/speaker_identification_widget.py:121 +msgid "4/8 Processing audio" +msgstr "" + +#: buzz/widgets/transcription_viewer/speaker_identification_widget.py:133 +#, fuzzy +msgid "5/8 Preparing transcripts" +msgstr "取消錄製" + +#: buzz/widgets/transcription_viewer/speaker_identification_widget.py:151 +msgid "6/8 Identifying speakers" +msgstr "" + +#: buzz/widgets/transcription_viewer/speaker_identification_widget.py:160 +msgid "0/0 Error identifying speakers" +msgstr "" + +#: buzz/widgets/transcription_viewer/speaker_identification_widget.py:168 +msgid "7/8 Mapping speakers to transcripts" +msgstr "" + +#: buzz/widgets/transcription_viewer/speaker_identification_widget.py:207 +msgid "8/8 Identification done" +msgstr "" + +#: buzz/widgets/transcription_viewer/speaker_identification_widget.py:243 +msgid "Step 1: Identify speakers" +msgstr "" + +#: buzz/widgets/transcription_viewer/speaker_identification_widget.py:255 +msgid "Identify" +msgstr "" + +#: buzz/widgets/transcription_viewer/speaker_identification_widget.py:265 +msgid "Ready to identify speakers" +msgstr "" + +#: buzz/widgets/transcription_viewer/speaker_identification_widget.py:267 +msgid "Audio file not found" +msgstr "" + +#: buzz/widgets/transcription_viewer/speaker_identification_widget.py:283 +msgid "Step 2: Name speakers" +msgstr "" + +#: buzz/widgets/transcription_viewer/speaker_identification_widget.py:298 +#: buzz/widgets/transcription_viewer/speaker_identification_widget.py:391 +msgid "Play sample" +msgstr "" + +#: buzz/widgets/transcription_viewer/speaker_identification_widget.py:313 +msgid "Merge speaker sentences" +msgstr "" + +#: buzz/widgets/transcription_viewer/speaker_identification_widget.py:318 +#, fuzzy +msgid "Save" +msgstr "檔案" + #: buzz/widgets/transcription_viewer/export_transcription_menu.py:82 #, fuzzy msgid "Save File" diff --git a/buzz/transcriber/whisper_cpp.py b/buzz/transcriber/whisper_cpp.py index 8f12aec8..7bea69fb 100644 --- a/buzz/transcriber/whisper_cpp.py +++ b/buzz/transcriber/whisper_cpp.py @@ -4,7 +4,6 @@ import sys import logging import subprocess import json -import tempfile from typing import List from buzz.assets import APP_BASE_DIR from buzz.transcriber.transcriber import Segment, Task, FileTranscriptionTask @@ -58,9 +57,7 @@ class WhisperCpp: file_to_process = task.file_path if file_ext not in supported_formats: - # Create temporary WAV file - temp_dir = tempfile.gettempdir() - temp_file = os.path.join(temp_dir, f"buzz_temp_{os.path.basename(task.file_path)}.wav") + temp_file = task.file_path + ".wav" logging.info(f"Converting {task.file_path} to WAV format") diff --git a/buzz/widgets/icon.py b/buzz/widgets/icon.py index cac92525..1efca875 100644 --- a/buzz/widgets/icon.py +++ b/buzz/widgets/icon.py @@ -82,6 +82,10 @@ class ResizeIcon(Icon): def __init__(self, parent: QWidget): super().__init__(get_path("assets/resize_black.svg"), parent) +class SpeakerIdentificationIcon(Icon): + def __init__(self, parent: QWidget): + super().__init__(get_path("assets/speaker-identification.svg"), parent) + class VisibilityIcon(Icon): def __init__(self, parent: QWidget): super().__init__( diff --git a/buzz/widgets/transcription_viewer/speaker_identification_widget.py b/buzz/widgets/transcription_viewer/speaker_identification_widget.py new file mode 100644 index 00000000..cbbe6216 --- /dev/null +++ b/buzz/widgets/transcription_viewer/speaker_identification_widget.py @@ -0,0 +1,504 @@ +import re +import os +import logging +import faster_whisper +import torch +import random +from typing import Optional +from PyQt6.QtMultimedia import QMediaPlayer, QAudioOutput +from PyQt6.QtCore import Qt, QThread, QObject, pyqtSignal, QUrl, QTimer +from PyQt6.QtGui import QFont +from PyQt6.QtWidgets import ( + QWidget, + QFormLayout, + QVBoxLayout, + QHBoxLayout, + QLabel, + QProgressBar, + QPushButton, + QCheckBox, + QGroupBox, + QSpacerItem, + QSizePolicy, + QLayout, +) +from buzz.locale import _ +from buzz.db.entity.transcription import Transcription +from buzz.db.service.transcription_service import TranscriptionService +from buzz.paths import file_path_as_title +from buzz.settings.settings import Settings +from buzz.widgets.line_edit import LineEdit +from buzz.transcriber.transcriber import Segment + +from ctc_forced_aligner.ctc_forced_aligner import ( + generate_emissions, + get_alignments, + get_spans, + load_alignment_model, + postprocess_results, + preprocess_text, +) +from whisper_diarization.helpers import ( + get_realigned_ws_mapping_with_punctuation, + get_sentences_speaker_mapping, + get_words_speaker_mapping, + langs_to_iso, + punct_model_langs, +) +from deepmultilingualpunctuation.deepmultilingualpunctuation import PunctuationModel +from whisper_diarization.diarization import MSDDDiarizer + +SENTENCE_END = re.compile(r'.*[.!?。!?]') + +class IdentificationWorker(QObject): + finished = pyqtSignal(list) + progress_update = pyqtSignal(str) + + def __init__(self, transcription, transcription_service): + super().__init__() + self.transcription = transcription + self.transcription_service = transcription_service + + def get_transcript(self, audio, **kwargs) -> dict: + buzz_segments = self.transcription_service.get_transcription_segments( + transcription_id=self.transcription.id_as_uuid + ) + + segments = [] + words = [] + text = "" + for buzz_segment in buzz_segments: + words.append({ + 'word': buzz_segment.text + " ", + 'start': buzz_segment.start_time / 100, + 'end': buzz_segment.end_time / 100, + }) + text += buzz_segment.text + " " + + if SENTENCE_END.match(buzz_segment.text): + segments.append({ + 'text': text, + 'words': words + }) + words = [] + text = "" + + return { + 'language': self.transcription.language, + 'segments': segments + } + + def run(self): + self.progress_update.emit(_("1/8 Collecting transcripts")) + + # Step 1 - Get transcript + # TODO - Add detected language to the transcript, detect and store separately in metadata + # Will also be relevant for template parsing of transcript file names + # - See diarize.py for example on how to get this info from whisper transcript, maybe other whisper models also have it + language = self.transcription.language if self.transcription.language else "en" + + segments = self.transcription_service.get_transcription_segments( + transcription_id=self.transcription.id_as_uuid + ) + + full_transcript = "".join(segment.text for segment in segments) + + self.progress_update.emit(_("2/8 Loading audio")) + audio_waveform = faster_whisper.decode_audio(self.transcription.file) + + # Step 2 - Forced alignment + force_cpu = os.getenv("BUZZ_FORCE_CPU", "false") + use_cuda = torch.cuda.is_available() and force_cpu == "false" + device = "cuda" if use_cuda else "cpu" + torch_dtype = torch.float16 if use_cuda else torch.float32 + + self.progress_update.emit(_("3/8 Loading alignment model")) + alignment_model, alignment_tokenizer = load_alignment_model( + device, + dtype=torch_dtype, + ) + + self.progress_update.emit(_("4/8 Processing audio")) + emissions, stride = generate_emissions( + alignment_model, + torch.from_numpy(audio_waveform) + .to(alignment_model.dtype) + .to(alignment_model.device), + batch_size=8, + ) + + del alignment_model + torch.cuda.empty_cache() + + self.progress_update.emit(_("5/8 Preparing transcripts")) + tokens_starred, text_starred = preprocess_text( + full_transcript, + romanize=True, + language=langs_to_iso[language], + ) + + segments, scores, blank_token = get_alignments( + emissions, + tokens_starred, + alignment_tokenizer, + ) + + spans = get_spans(tokens_starred, segments, blank_token) + + word_timestamps = postprocess_results(text_starred, spans, stride, scores) + + # Step 3 - Diarization + self.progress_update.emit(_("6/8 Identifying speakers")) + + try: + diarizer_model = MSDDDiarizer(device) + speaker_ts = diarizer_model.diarize(torch.from_numpy(audio_waveform).unsqueeze(0)) + + except Exception as e: + self.progress_update.emit(_("0/0 Error identifying speakers")) + logging.error(f"Error during diarization: {e}") + return + finally: + del diarizer_model + torch.cuda.empty_cache() + + # Step 4 - Reading timestamps <> Speaker Labels mapping + self.progress_update.emit(_("7/8 Mapping speakers to transcripts")) + + wsm = get_words_speaker_mapping(word_timestamps, speaker_ts, "start") + + if language in punct_model_langs: + # restoring punctuation in the transcript to help realign the sentences + punct_model = PunctuationModel(model="kredor/punctuate-all") + + words_list = list(map(lambda x: x["word"], wsm)) + + labled_words = punct_model.predict(words_list, chunk_size=230) + + ending_puncts = ".?!。!?" + model_puncts = ".,;:!?。!?" + + # We don't want to punctuate U.S.A. with a period. Right? + is_acronym = lambda x: re.fullmatch(r"\b(?:[a-zA-Z]\.){2,}", x) + + for word_dict, labeled_tuple in zip(wsm, labled_words): + word = word_dict["word"] + if ( + word + and labeled_tuple[1] in ending_puncts + and (word[-1] not in model_puncts or is_acronym(word)) + ): + word += labeled_tuple[1] + if word.endswith(".."): + word = word.rstrip(".") + word_dict["word"] = word + + else: + logging.warning( + f"Punctuation restoration is not available for {language} language." + " Using the original punctuation." + ) + + wsm = get_realigned_ws_mapping_with_punctuation(wsm) + ssm = get_sentences_speaker_mapping(wsm, speaker_ts) + + self.progress_update.emit(_("8/8 Identification done")) + self.finished.emit(ssm) + + +class SpeakerIdentificationWidget(QWidget): + resize_button_clicked = pyqtSignal() + transcription: Transcription + settings = Settings() + + def __init__( + self, + transcription: Transcription, + transcription_service: TranscriptionService, + parent: Optional["QWidget"] = None, + flags: Qt.WindowType = Qt.WindowType.Widget, + transcriptions_updated_signal: Optional[pyqtSignal] = None, + ) -> None: + super().__init__(parent, flags) + self.transcription = transcription + self.transcription_service = transcription_service + self.transcriptions_updated_signal = transcriptions_updated_signal + + self.identification_result = None + + self.thread = None + self.worker = None + + self.setMinimumWidth(650) + self.setMinimumHeight(400) + + self.setWindowTitle(file_path_as_title(transcription.file)) + + layout = QFormLayout(self) + layout.setSizeConstraint(QLayout.SizeConstraint.SetMinAndMaxSize) + + # Step 1: Identify speakers + step_1_label = QLabel(_("Step 1: Identify speakers"), self) + font = step_1_label.font() + font.setWeight(QFont.Weight.Bold) + step_1_label.setFont(font) + layout.addRow(step_1_label) + + step_1_group_box = QGroupBox(self) + step_1_group_box.setSizePolicy(QSizePolicy.Policy.Expanding, QSizePolicy.Policy.Expanding) + step_1_layout = QVBoxLayout(step_1_group_box) + + self.step_1_row = QHBoxLayout() + + self.step_1_button = QPushButton(_("Identify")) + self.step_1_button.setMinimumWidth(200) + self.step_1_button.clicked.connect(self.on_identify_button_clicked) + + # Progress container with label and bar + progress_container = QVBoxLayout() + + self.progress_label = QLabel(self) + if os.path.isfile(self.transcription.file): + self.progress_label.setText(_("Ready to identify speakers")) + else: + self.progress_label.setText(_("Audio file not found")) + self.step_1_button.setEnabled(False) + + self.progress_bar = QProgressBar(self) + self.progress_bar.setMinimumWidth(400) + self.progress_bar.setRange(0, 8) + self.progress_bar.setValue(0) + + progress_container.addWidget(self.progress_label) + progress_container.addWidget(self.progress_bar) + + self.step_1_row.addLayout(progress_container) + + self.step_1_row.addWidget(self.step_1_button, alignment=Qt.AlignmentFlag.AlignTop) + + step_1_layout.addLayout(self.step_1_row) + + layout.addRow(step_1_group_box) + + # Spacer + spacer = QSpacerItem(0, 10, QSizePolicy.Policy.Minimum, QSizePolicy.Policy.Fixed) + layout.addItem(spacer) + + # Step 2: Name speakers + step_2_label = QLabel(_("Step 2: Name speakers"), self) + font = step_2_label.font() + font.setWeight(QFont.Weight.Bold) + step_2_label.setFont(font) + layout.addRow(step_2_label) + + self.step_2_group_box = QGroupBox(self) + self.step_2_group_box.setSizePolicy(QSizePolicy.Policy.Expanding, QSizePolicy.Policy.Expanding) + self.step_2_group_box.setEnabled(False) + step_2_layout = QVBoxLayout(self.step_2_group_box) + + self.speaker_preview_row = QVBoxLayout() + + self.speaker_0_input = LineEdit("Speaker 0", self) + + self.speaker_0_preview_button = QPushButton(_("Play sample")) + self.speaker_0_preview_button.setMinimumWidth(200) + self.speaker_0_preview_button.clicked.connect(lambda: self.on_speaker_preview("Speaker 0")) + + speaker_0_layout = QHBoxLayout() + speaker_0_layout.addWidget(self.speaker_0_input) + speaker_0_layout.addWidget(self.speaker_0_preview_button) + + self.speaker_preview_row.addLayout(speaker_0_layout) + + step_2_layout.addLayout(self.speaker_preview_row) + + layout.addRow(self.step_2_group_box) + + # Save button + self.merge_speaker_sentences = QCheckBox(_("Merge speaker sentences")) + self.merge_speaker_sentences.setChecked(True) + self.merge_speaker_sentences.setEnabled(False) + self.merge_speaker_sentences.setMinimumWidth(250) + + self.save_button = QPushButton(_("Save")) + self.save_button.setEnabled(False) + self.save_button.clicked.connect(self.on_save_button_clicked) + + layout.addRow(self.merge_speaker_sentences) + layout.addRow(self.save_button) + + self.setLayout(layout) + + # Invisible preview player + url = QUrl.fromLocalFile(self.transcription.file) + self.player = QMediaPlayer() + self.audio_output = QAudioOutput() + self.player.setAudioOutput(self.audio_output) + self.player.setSource(url) + self.player_timer = None + + def on_identify_button_clicked(self): + self.step_1_button.setEnabled(False) + + self.thread = QThread() + self.worker = IdentificationWorker( + self.transcription, + self.transcription_service + ) + self.worker.moveToThread(self.thread) + self.thread.started.connect(self.worker.run) + self.worker.finished.connect(self.thread.quit) + self.worker.finished.connect(self.worker.deleteLater) + self.thread.finished.connect(self.thread.deleteLater) + self.worker.finished.connect(self.on_identification_finished) + self.worker.progress_update.connect(self.on_progress_update) + + self.thread.start() + + def on_progress_update(self, progress): + self.progress_label.setText(progress) + + progress_value = 0 + if progress and progress[0].isdigit(): + progress_value = int(progress[0]) + self.progress_bar.setValue(progress_value) + else: + logging.error(f"Invalid progress format: {progress}") + + if progress_value == 8: + self.step_2_group_box.setEnabled(True) + self.merge_speaker_sentences.setEnabled(True) + self.save_button.setEnabled(True) + + def on_identification_finished(self, result): + self.identification_result = result + + unique_speakers = {entry['speaker'] for entry in result} + + while self.speaker_preview_row.count(): + item = self.speaker_preview_row.takeAt(0) + widget = item.widget() + if widget: + widget.deleteLater() + else: + layout = item.layout() + if layout: + while layout.count(): + sub_item = layout.takeAt(0) + sub_widget = sub_item.widget() + if sub_widget: + sub_widget.deleteLater() + + for speaker in sorted(unique_speakers): + speaker_input = LineEdit(speaker, self) + speaker_input.setMinimumWidth(200) + + speaker_preview_button = QPushButton(_("Play sample")) + speaker_preview_button.setMinimumWidth(200) + speaker_preview_button.clicked.connect(lambda checked, s=speaker: self.on_speaker_preview(s)) + + speaker_layout = QHBoxLayout() + speaker_layout.addWidget(speaker_input) + speaker_layout.addWidget(speaker_preview_button) + + self.speaker_preview_row.addLayout(speaker_layout) + + def on_speaker_preview(self, speaker_id): + if self.player_timer: + self.player_timer.stop() + + speaker_records = [record for record in self.identification_result if record['speaker'] == speaker_id] + + if speaker_records: + random_record = random.choice(speaker_records) + + start_time = random_record['start_time'] + end_time = random_record['end_time'] + + self.player.setPosition(int(start_time)) + self.player.play() + + self.player_timer = QTimer(self) + self.player_timer.setSingleShot(True) + self.player_timer.timeout.connect(self.player.stop) + self.player_timer.start(min(end_time, 10 * 1000)) # 10 seconds + + def on_save_button_clicked(self): + speaker_names = [] + for i in range(self.speaker_preview_row.count()): + item = self.speaker_preview_row.itemAt(i) + if item.layout(): + for j in range(item.layout().count()): + sub_item = item.layout().itemAt(j) + widget = sub_item.widget() + if isinstance(widget, LineEdit): + speaker_names.append(widget.text()) + + unique_speakers = {entry['speaker'] for entry in self.identification_result} + original_speakers = sorted(unique_speakers) + speaker_mapping = dict(zip(original_speakers, speaker_names)) + + segments = [] + if self.merge_speaker_sentences.isChecked(): + previous_segment = None + + for entry in self.identification_result: + speaker_name = speaker_mapping.get(entry['speaker'], entry['speaker']) + + if previous_segment and previous_segment['speaker'] == speaker_name: + previous_segment['end_time'] = entry['end_time'] + previous_segment['text'] += " " + entry['text'] + else: + if previous_segment: + segment = Segment( + start=previous_segment['start_time'], + end=previous_segment['end_time'], + text=f"{previous_segment['speaker']}: {previous_segment['text']}" + ) + segments.append(segment) + previous_segment = { + 'start_time': entry['start_time'], + 'end_time': entry['end_time'], + 'speaker': speaker_name, + 'text': entry['text'] + } + + if previous_segment: + segment = Segment( + start=previous_segment['start_time'], + end=previous_segment['end_time'], + text=f"{previous_segment['speaker']}: {previous_segment['text']}" + ) + segments.append(segment) + else: + for entry in self.identification_result: + speaker_name = speaker_mapping.get(entry['speaker'], entry['speaker']) + segment = Segment( + start=entry['start_time'], + end=entry['end_time'], + text=f"{speaker_name}: {entry['text']}" + ) + segments.append(segment) + + new_transcript_id = self.transcription_service.copy_transcription( + self.transcription.id_as_uuid + ) + + self.transcription_service.update_transcription_as_completed(new_transcript_id, segments) + + # TODO - See if we can get rows in the transcription viewer to be of variable height + # If text is longer they should expand + if self.transcriptions_updated_signal: + self.transcriptions_updated_signal.emit(new_transcript_id) + + self.player.stop() + + if self.player_timer: + self.player_timer.stop() + + self.close() + + def closeEvent(self, event): + self.hide() + + super().closeEvent(event) diff --git a/buzz/widgets/transcription_viewer/transcription_resizer_widget.py b/buzz/widgets/transcription_viewer/transcription_resizer_widget.py index a873eb0c..cb8dfcfc 100644 --- a/buzz/widgets/transcription_viewer/transcription_resizer_widget.py +++ b/buzz/widgets/transcription_viewer/transcription_resizer_widget.py @@ -37,8 +37,7 @@ from buzz.widgets.preferences_dialog.models.file_transcription_preferences impor SENTENCE_END = re.compile(r'.*[.!?。!?]') class TranscriptionWorker(QObject): - finished = pyqtSignal() - result_ready = pyqtSignal(list) + finished = pyqtSignal(list) def __init__(self, transcription, transcription_options, transcription_service, regroup_string: str): super().__init__() @@ -85,7 +84,7 @@ class TranscriptionWorker(QObject): if self.transcription_options.extract_speech and os.path.exists(speech_path): transcription_file = str(speech_path) transcription_file_exists = True - # TODO - Fix VAD and Silence suppression that fails to work/download VAd model in compilded form on Mac and Windows + # TODO - Fix VAD and Silence suppression that fails to work/download Vad model in compilded form on Mac and Windows try: result = stable_whisper.transcribe_any( @@ -113,8 +112,7 @@ class TranscriptionWorker(QObject): ) ) - self.result_ready.emit(segments) - self.finished.emit() + self.finished.emit(segments) class TranscriptionResizerWidget(QWidget): @@ -336,7 +334,7 @@ class TranscriptionResizerWidget(QWidget): self.worker.finished.connect(self.thread.quit) self.worker.finished.connect(self.worker.deleteLater) self.thread.finished.connect(self.thread.deleteLater) - self.worker.result_ready.connect(self.on_transcription_completed) + self.worker.finished.connect(self.on_transcription_completed) self.thread.start() diff --git a/buzz/widgets/transcription_viewer/transcription_viewer_widget.py b/buzz/widgets/transcription_viewer/transcription_viewer_widget.py index e77c2179..51b4e67c 100644 --- a/buzz/widgets/transcription_viewer/transcription_viewer_widget.py +++ b/buzz/widgets/transcription_viewer/transcription_viewer_widget.py @@ -1,5 +1,6 @@ import os import logging +import platform from typing import Optional from uuid import UUID @@ -38,6 +39,7 @@ from buzz.widgets.icon import ( ResizeIcon, ScrollToCurrentIcon, VisibilityIcon, + SpeakerIdentificationIcon, ) from buzz.translator import Translator from buzz.widgets.text_display_box import TextDisplayBox @@ -59,6 +61,10 @@ from buzz.widgets.transcription_viewer.transcription_view_mode_tool_button impor ) from buzz.widgets.transcription_viewer.transcription_resizer_widget import TranscriptionResizerWidget +# Underlying libs do not support intel Macs +if not (platform.system() == "Darwin" and platform.machine() == "x86_64"): + from buzz.widgets.transcription_viewer.speaker_identification_widget import SpeakerIdentificationWidget + class TranscriptionViewerWidget(QWidget): resize_button_clicked = pyqtSignal() @@ -85,6 +91,7 @@ class TranscriptionViewerWidget(QWidget): self.setWindowTitle(file_path_as_title(transcription.file)) self.transcription_resizer_dialog = None + self.speaker_identification_dialog = None self.transcriptions_updated_signal = transcriptions_updated_signal self.translation_thread = None @@ -98,7 +105,7 @@ class TranscriptionViewerWidget(QWidget): # Loop functionality self.segment_looping_enabled = self.settings.settings.value("transcription_viewer/segment_looping_enabled", False, type=bool) - + # UI visibility preferences self.playback_controls_visible = self.settings.settings.value("transcription_viewer/playback_controls_visible", False, type=bool) self.find_widget_visible = self.settings.settings.value("transcription_viewer/find_widget_visible", False, type=bool) @@ -165,18 +172,18 @@ class TranscriptionViewerWidget(QWidget): # Create a better current segment display that handles long text self.current_segment_frame = QFrame() self.current_segment_frame.setFrameStyle(QFrame.Shape.NoFrame) - + segment_layout = QVBoxLayout(self.current_segment_frame) segment_layout.setContentsMargins(4, 4, 4, 4) # Minimal margins for clean appearance segment_layout.setSpacing(0) # No spacing between elements - + # Text display - centered with scroll capability (no header label) self.current_segment_text = QLabel("") self.current_segment_text.setAlignment(Qt.AlignmentFlag.AlignHCenter | Qt.AlignmentFlag.AlignTop) self.current_segment_text.setWordWrap(True) self.current_segment_text.setStyleSheet("color: #666; line-height: 1.2; margin: 0; padding: 4px;") self.current_segment_text.setMinimumHeight(60) # Ensure minimum height for text - + # Make it scrollable for long text self.current_segment_scroll_area = QScrollArea() self.current_segment_scroll_area.setWidget(self.current_segment_text) @@ -185,13 +192,13 @@ class TranscriptionViewerWidget(QWidget): self.current_segment_scroll_area.setHorizontalScrollBarPolicy(Qt.ScrollBarPolicy.ScrollBarAlwaysOff) self.current_segment_scroll_area.setVerticalScrollBarPolicy(Qt.ScrollBarPolicy.ScrollBarAsNeeded) self.current_segment_scroll_area.setStyleSheet("QScrollBar:vertical { width: 12px; } QScrollBar::handle:vertical { background: #ccc; border-radius: 6px; }") - + # Ensure the text label can expand to show all content self.current_segment_text.setSizePolicy(QSizePolicy.Policy.Preferred, QSizePolicy.Policy.Preferred) - + # Add scroll area to layout (simplified single-widget layout) segment_layout.addWidget(self.current_segment_scroll_area) - + # Initially hide the frame until there's content self.current_segment_frame.hide() @@ -247,6 +254,19 @@ class TranscriptionViewerWidget(QWidget): toolbar.addWidget(resize_button) + # Underlying libs do not support intel Macs + if not (platform.system() == "Darwin" and platform.machine() == "x86_64"): + speaker_identification_button = QToolButton() + speaker_identification_button.setText(_("Identify Speakers")) + speaker_identification_button.setObjectName("speaker_identification_button") + speaker_identification_button.setIcon(SpeakerIdentificationIcon(self)) + speaker_identification_button.setToolButtonStyle( + Qt.ToolButtonStyle.ToolButtonTextBesideIcon + ) + speaker_identification_button.clicked.connect(self.on_speaker_identification_button_clicked) + + toolbar.addWidget(speaker_identification_button) + # Add Find button self.find_button = QToolButton() self.find_button.setText(_("Find")) @@ -267,14 +287,14 @@ class TranscriptionViewerWidget(QWidget): # Table widget should take the majority of the space layout.addWidget(self.table_widget, 1) # Stretch factor 1 (majority) - + # Loop controls section (minimal space) self.create_loop_controls() layout.addWidget(self.loop_controls_frame, 0) # Stretch factor 0 (minimal) - + # Audio player (minimal space) layout.addWidget(self.audio_player, 0) # Stretch factor 0 (minimal) - + # Text display box (minimal space) layout.addWidget(self.text_display_box, 0) # Stretch factor 0 (minimal) @@ -291,7 +311,7 @@ class TranscriptionViewerWidget(QWidget): # Restore UI state from settings self.restore_ui_state() - + # Restore geometry from settings self.load_geometry() @@ -302,7 +322,7 @@ class TranscriptionViewerWidget(QWidget): # Restore playback controls visibility if self.playback_controls_visible: self.show_loop_controls() - + # Restore find widget visibility if self.find_widget_visible: self.show_search_bar() @@ -312,28 +332,28 @@ class TranscriptionViewerWidget(QWidget): self.search_frame = QFrame() self.search_frame.setFrameStyle(QFrame.Shape.StyledPanel) self.search_frame.setMaximumHeight(60) - + search_layout = QHBoxLayout(self.search_frame) search_layout.setContentsMargins(10, 5, 10, 5) - + # Find label search_label = QLabel(_("Find:")) search_label.setStyleSheet("font-weight: bold;") search_layout.addWidget(search_label) - + # Find input - make it wider for better usability self.search_input = QLineEdit() self.search_input.setPlaceholderText(_("Enter text to find...")) self.search_input.textChanged.connect(self.on_search_text_changed) self.search_input.returnPressed.connect(self.search_next) self.search_input.setMinimumWidth(300) # Increased from 200 to 300 - + # Add keyboard shortcuts for search navigation from PyQt6.QtGui import QKeySequence self.search_input.installEventFilter(self) - + search_layout.addWidget(self.search_input) - + # Search buttons - make them consistent height and remove hardcoded font sizes self.search_prev_button = QPushButton("↑") self.search_prev_button.setToolTip(_("Previous match (Shift+Enter)")) @@ -342,7 +362,7 @@ class TranscriptionViewerWidget(QWidget): self.search_prev_button.setMaximumWidth(40) self.search_prev_button.setMinimumHeight(30) # Ensure consistent height search_layout.addWidget(self.search_prev_button) - + self.search_next_button = QPushButton("↓") self.search_next_button.setToolTip(_("Next match (Enter)")) self.search_next_button.clicked.connect(self.search_next) @@ -350,21 +370,21 @@ class TranscriptionViewerWidget(QWidget): self.search_next_button.setMaximumWidth(40) self.search_next_button.setMinimumHeight(30) # Ensure consistent height search_layout.addWidget(self.search_next_button) - + # Clear button - make it bigger to accommodate different language translations self.clear_search_button = QPushButton(_("Clear")) self.clear_search_button.clicked.connect(self.clear_search) self.clear_search_button.setMaximumWidth(80) # Increased from 60 to 80 self.clear_search_button.setMinimumHeight(30) # Ensure consistent height search_layout.addWidget(self.clear_search_button) - + # Results label self.search_results_label = QLabel("") self.search_results_label.setStyleSheet("color: #666;") search_layout.addWidget(self.search_results_label) - + search_layout.addStretch() - + # Initially hide the search bar self.search_frame.hide() @@ -373,23 +393,23 @@ class TranscriptionViewerWidget(QWidget): self.loop_controls_frame = QFrame() self.loop_controls_frame.setFrameStyle(QFrame.Shape.StyledPanel) self.loop_controls_frame.setMaximumHeight(50) - + loop_layout = QHBoxLayout(self.loop_controls_frame) loop_layout.setContentsMargins(10, 5, 10, 5) loop_layout.setSpacing(8) # Add some spacing between elements for better visual separation - + # Loop controls label loop_label = QLabel(_("Playback Controls:")) loop_label.setStyleSheet("font-weight: bold;") loop_layout.addWidget(loop_label) - + # Loop toggle button self.loop_toggle = QCheckBox(_("Loop Segment")) self.loop_toggle.setChecked(self.segment_looping_enabled) self.loop_toggle.setToolTip(_("Enable/disable looping when clicking on transcript segments")) self.loop_toggle.toggled.connect(self.on_loop_toggle_changed) loop_layout.addWidget(self.loop_toggle) - + # Follow audio toggle button self.follow_audio_enabled = self.settings.settings.value("transcription_viewer/follow_audio_enabled", False, type=bool) self.follow_audio_toggle = QCheckBox(_("Follow Audio")) @@ -397,19 +417,19 @@ class TranscriptionViewerWidget(QWidget): self.follow_audio_toggle.setToolTip(_("Enable/disable following the current audio position in the transcript. When enabled, automatically scrolls to current text.")) self.follow_audio_toggle.toggled.connect(self.on_follow_audio_toggle_changed) loop_layout.addWidget(self.follow_audio_toggle) - + # Visual separator separator1 = QFrame() separator1.setFrameShape(QFrame.Shape.VLine) separator1.setFrameShadow(QFrame.Shadow.Sunken) separator1.setMaximumHeight(20) loop_layout.addWidget(separator1) - + # Speed controls speed_label = QLabel("Speed:") speed_label.setStyleSheet("font-weight: bold;") loop_layout.addWidget(speed_label) - + self.speed_combo = QComboBox() self.speed_combo.setEditable(True) self.speed_combo.addItems(["0.5x", "0.75x", "1x", "1.25x", "1.5x", "2x"]) @@ -417,29 +437,29 @@ class TranscriptionViewerWidget(QWidget): self.speed_combo.currentTextChanged.connect(self.on_speed_changed) self.speed_combo.setMaximumWidth(80) loop_layout.addWidget(self.speed_combo) - + self.speed_down_btn = QPushButton("-") self.speed_down_btn.setMaximumWidth(40) # Match search button width self.speed_down_btn.setMinimumHeight(30) # Match search button height self.speed_down_btn.clicked.connect(self.decrease_speed) loop_layout.addWidget(self.speed_down_btn) - + self.speed_up_btn = QPushButton("+") self.speed_up_btn.setMaximumWidth(40) # Match speed down button width self.speed_up_btn.setMinimumHeight(30) # Match search button height self.speed_up_btn.clicked.connect(self.increase_speed) loop_layout.addWidget(self.speed_up_btn) - + # Initialize speed control with current value from audio player self.initialize_speed_control() - + # Visual separator separator2 = QFrame() separator2.setFrameShape(QFrame.Shape.VLine) separator2.setFrameShadow(QFrame.Shadow.Sunken) separator2.setMaximumHeight(20) loop_layout.addWidget(separator2) - + # Scroll to current button self.scroll_to_current_button = QPushButton(_("Scroll to Current")) self.scroll_to_current_button.setIcon(ScrollToCurrentIcon(self)) @@ -448,16 +468,16 @@ class TranscriptionViewerWidget(QWidget): self.scroll_to_current_button.setMinimumHeight(30) self.scroll_to_current_button.setStyleSheet("QPushButton { padding: 4px 8px; }") # Better padding loop_layout.addWidget(self.scroll_to_current_button) - + loop_layout.addStretch() - + # Initially hide the loop controls frame self.loop_controls_frame.hide() def show_loop_controls(self): """Show the loop controls when audio is playing""" self.loop_controls_frame.show() - + # Save the visibility state to settings self.playback_controls_visible = True self.settings.settings.setValue("transcription_viewer/playback_controls_visible", self.playback_controls_visible) @@ -465,7 +485,7 @@ class TranscriptionViewerWidget(QWidget): def hide_loop_controls(self): """Hide the loop controls when audio is not playing""" self.loop_controls_frame.hide() - + # Save the visibility state to settings self.playback_controls_visible = False self.settings.settings.setValue("transcription_viewer/playback_controls_visible", self.playback_controls_visible) @@ -600,7 +620,7 @@ class TranscriptionViewerWidget(QWidget): def on_audio_playback_state_changed(self, state): """Handle audio playback state changes to automatically show/hide playback controls""" from PyQt6.QtMultimedia import QMediaPlayer - + if state == QMediaPlayer.PlaybackState.PlayingState: # Show playback controls when audio starts playing if self.view_mode == ViewMode.TIMESTAMPS: @@ -630,25 +650,25 @@ class TranscriptionViewerWidget(QWidget): # Extract the numeric value from speed text (e.g., "1.5x" -> 1.5) clean_text = speed_text.replace('x', '').strip() speed_value = float(clean_text) - + # Clamp the speed value to valid range speed_value = max(0.1, min(5.0, speed_value)) - + # Update the combo box text to show the clamped value if not speed_text.endswith('x'): speed_text = f"{speed_value:.2f}x" - + # Block signals to prevent recursion self.speed_combo.blockSignals(True) self.speed_combo.setCurrentText(speed_text) self.speed_combo.blockSignals(False) - + # Set the playback rate on the audio player self.audio_player.media_player.setPlaybackRate(speed_value) - + # Save the new rate to settings self.settings.set_value(self.settings.Key.AUDIO_PLAYBACK_RATE, speed_value) - + except ValueError: logging.warning(f"Invalid speed value: {speed_text}") # Reset to current valid value @@ -680,14 +700,14 @@ class TranscriptionViewerWidget(QWidget): """Set the playback speed programmatically""" # Clamp the speed value to valid range speed = max(0.1, min(5.0, speed)) - + # Update the combo box speed_text = f"{speed:.2f}x" self.speed_combo.setCurrentText(speed_text) - + # Set the playback rate on the audio player self.audio_player.media_player.setPlaybackRate(speed) - + # Save the new rate to settings self.settings.set_value(self.settings.Key.AUDIO_PLAYBACK_RATE, speed) @@ -707,49 +727,49 @@ class TranscriptionViewerWidget(QWidget): """Perform the actual search based on current view mode""" self.search_results = [] self.current_search_index = 0 - + if self.view_mode == ViewMode.TIMESTAMPS: self.search_in_table() else: # TEXT or TRANSLATION mode self.search_in_text() - + self.update_search_ui() def search_in_table(self): """Search in the table view (segments)""" segments = self.table_widget.segments() search_text_lower = self.search_text.lower() - + # Limit search results to avoid performance issues with very long segments max_results = 100 - + for i, segment in enumerate(segments): if len(self.search_results) >= max_results: break - + text = segment.value("text").lower() if search_text_lower in text: self.search_results.append(("table", i, segment)) - + # Also search in translations if available if self.has_translations: for i, segment in enumerate(segments): if len(self.search_results) >= max_results: break - + translation = segment.value("translation").lower() if search_text_lower in translation: - self.search_results.append(("table", i, segment)) + self.search_results.append(("table", i, segment)) def search_in_text(self): """Search in the text display box""" text = self.text_display_box.toPlainText() search_text_lower = self.search_text.lower() text_lower = text.lower() - + # Limit search results to avoid performance issues with very long text max_results = 100 - + start = 0 result_count = 0 while True: @@ -780,9 +800,9 @@ class TranscriptionViewerWidget(QWidget): """Highlight the current search match""" if not self.search_results: return - + match_type, match_data, _ = self.search_results[self.current_search_index] - + if match_type == "table": # Highlight in table self.highlight_table_match(match_data) @@ -802,10 +822,10 @@ class TranscriptionViewerWidget(QWidget): cursor = QTextCursor(self.text_display_box.document()) cursor.setPosition(start_pos) cursor.setPosition(start_pos + len(self.search_text), QTextCursor.MoveMode.KeepAnchor) - + # Set the cursor to highlight the text self.text_display_box.setTextCursor(cursor) - + # Ensure the highlighted text is visible self.text_display_box.ensureCursorVisible() @@ -813,7 +833,7 @@ class TranscriptionViewerWidget(QWidget): """Go to next search result""" if not self.search_results: return - + self.current_search_index = (self.current_search_index + 1) % len(self.search_results) self.highlight_current_match() self.update_search_results_label() @@ -822,7 +842,7 @@ class TranscriptionViewerWidget(QWidget): """Go to previous search result""" if not self.search_results: return - + self.current_search_index = (self.current_search_index - 1) % len(self.search_results) self.highlight_current_match() self.update_search_results_label() @@ -845,13 +865,13 @@ class TranscriptionViewerWidget(QWidget): self.search_prev_button.setEnabled(False) self.search_next_button.setEnabled(False) - + # Clear text highlighting if self.view_mode in (ViewMode.TEXT, ViewMode.TRANSLATION): cursor = QTextCursor(self.text_display_box.document()) cursor.clearSelection() self.text_display_box.setTextCursor(cursor) - + # Keep search bar visible but clear the input self.search_input.setFocus() @@ -861,7 +881,7 @@ class TranscriptionViewerWidget(QWidget): self.find_button.setChecked(False) # Sync button state self.clear_search() self.search_input.clearFocus() - + # Save the visibility state to settings self.find_widget_visible = False self.settings.settings.setValue("transcription_viewer/find_widget_visible", False) @@ -869,11 +889,11 @@ class TranscriptionViewerWidget(QWidget): def setup_shortcuts(self): """Set up keyboard shortcuts""" from PyQt6.QtGui import QShortcut, QKeySequence - + # Search shortcut (Ctrl+F) search_shortcut = QShortcut(QKeySequence(self.shortcuts.get(Shortcut.SEARCH_TRANSCRIPT)), self) search_shortcut.activated.connect(self.focus_search_input) - + # Scroll to current text shortcut (Ctrl+G) scroll_to_current_shortcut = QShortcut(QKeySequence(self.shortcuts.get(Shortcut.SCROLL_TO_CURRENT_TEXT)), self) scroll_to_current_shortcut.activated.connect(self.on_scroll_to_current_button_clicked) @@ -912,7 +932,7 @@ class TranscriptionViewerWidget(QWidget): self.find_button.setChecked(True) # Sync button state self.search_input.setFocus() self.search_input.selectAll() - + # Save the visibility state to settings self.find_widget_visible = True self.settings.settings.setValue("transcription_viewer/find_widget_visible", True) @@ -923,7 +943,7 @@ class TranscriptionViewerWidget(QWidget): self.hide_search_bar() else: self.show_search_bar() - + # Save the visibility state to settings self.find_widget_visible = self.search_frame.isVisible() self.settings.settings.setValue("transcription_viewer/find_widget_visible", self.find_widget_visible) @@ -934,7 +954,7 @@ class TranscriptionViewerWidget(QWidget): self.find_button.setChecked(True) self.search_input.setFocus() self.search_input.selectAll() - + # Save the visibility state to settings self.find_widget_visible = True self.settings.settings.setValue("transcription_viewer/find_widget_visible", True) @@ -942,7 +962,7 @@ class TranscriptionViewerWidget(QWidget): def eventFilter(self, obj, event): """Event filter to handle keyboard shortcuts in search input""" from PyQt6.QtCore import QEvent, Qt - + if obj == self.search_input and event.type() == QEvent.Type.KeyPress: # The event is already a QKeyEvent, no need to create a new one if event.key() == Qt.Key.Key_Return and event.modifiers() == Qt.KeyboardModifier.ShiftModifier: @@ -999,7 +1019,7 @@ class TranscriptionViewerWidget(QWidget): self.loop_controls_frame.hide() # Hide current segment display in translation mode self.current_segment_frame.hide() - + # Refresh search if there's active search text if self.search_text: self.perform_search() @@ -1007,7 +1027,7 @@ class TranscriptionViewerWidget(QWidget): def on_view_mode_changed(self, view_mode: ViewMode) -> None: self.view_mode = view_mode self.reset_view() - + # Refresh search if there's active search text if self.search_text: self.perform_search() @@ -1091,17 +1111,17 @@ class TranscriptionViewerWidget(QWidget): if current_segment is not None: self.current_segment_text.setText(current_segment.value("text")) self.current_segment_frame.show() # Show the frame when there's a current segment - + # Force the text label to recalculate its size self.current_segment_text.adjustSize() - + # Resize the frame to fit the text content self.resize_current_segment_frame() - + # Ensure the scroll area updates properly and shows scrollbars when needed self.current_segment_scroll_area.updateGeometry() self.current_segment_scroll_area.verticalScrollBar().setVisible(True) # Ensure scrollbar is visible - + # Update highlighting based on follow audio and loop settings if self.follow_audio_enabled: # Follow audio mode: highlight the current segment based on audio position @@ -1143,30 +1163,30 @@ class TranscriptionViewerWidget(QWidget): # Calculate the height needed for the text area line_height = self.current_segment_text.fontMetrics().lineSpacing() max_visible_lines = 3 # Fixed at 3 lines for consistency and clean UI - + # Calculate the height needed for the maximum visible lines (25% larger) text_height = line_height * max_visible_lines * 1.25 - + # Add some vertical margins/padding margins = 8 # Increased from 2 to 8 for better spacing - + # Calculate total height needed (no header height anymore) total_height = text_height + margins - + # Convert to integer since Qt methods expect int values total_height = int(total_height) - + # Set maximum height to ensure consistent sizing, but allow minimum to be flexible self.current_segment_frame.setMaximumHeight(total_height) self.current_segment_frame.setMinimumHeight(total_height) - + # Convert text_height to integer since Qt methods expect int values text_height = int(text_height) - + # Allow the scroll area to be flexible in height for proper scrolling self.current_segment_scroll_area.setMinimumHeight(text_height) self.current_segment_scroll_area.setMaximumHeight(text_height) - + # Allow the text label to size naturally for proper scrolling self.current_segment_text.setMinimumHeight(text_height) @@ -1220,12 +1240,27 @@ class TranscriptionViewerWidget(QWidget): self.transcription_resizer_dialog.show() + def on_speaker_identification_button_clicked(self): + # Underlying libs do not support intel Macs + if not (platform.system() == "Darwin" and platform.machine() == "x86_64"): + self.speaker_identification_dialog = SpeakerIdentificationWidget( + transcription=self.transcription, + transcription_service=self.transcription_service, + transcriptions_updated_signal=self.transcriptions_updated_signal, + ) + + self.transcriptions_updated_signal.connect(self.close) + + self.speaker_identification_dialog.show() + + pass + def on_loop_toggle_changed(self, enabled: bool): """Handle loop toggle state change""" self.segment_looping_enabled = enabled # Save preference to settings self.settings.settings.setValue("transcription_viewer/segment_looping_enabled", enabled) - + if enabled: # If looping is re-enabled and we have a selected segment, return to it if self.currently_selected_segment is not None: @@ -1235,21 +1270,21 @@ class TranscriptionViewerWidget(QWidget): if segment.value("id") == self.currently_selected_segment.value("id"): # Highlight and scroll to the selected segment self.table_widget.highlight_and_scroll_to_row(i) - + # Get the segment timing start_time = self.currently_selected_segment.value("start_time") end_time = self.currently_selected_segment.value("end_time") - + # Set the loop range for the selected segment self.audio_player.set_range((start_time, end_time)) - + # If audio is currently playing and outside the range, jump to the start current_pos = self.audio_player.position_ms playback_state = self.audio_player.media_player.playbackState() - if (playback_state == QMediaPlayer.PlaybackState.PlayingState and + if (playback_state == QMediaPlayer.PlaybackState.PlayingState and (current_pos < start_time or current_pos > end_time)): self.audio_player.set_position(start_time) - + break else: # Clear any existing range if looping is disabled @@ -1260,7 +1295,7 @@ class TranscriptionViewerWidget(QWidget): self.follow_audio_enabled = enabled # Save preference to settings self.settings.settings.setValue("transcription_viewer/follow_audio_enabled", enabled) - + if enabled: # When follow audio is first enabled, automatically scroll to current position # This gives immediate feedback that the feature is working @@ -1310,17 +1345,17 @@ class TranscriptionViewerWidget(QWidget): # Only scroll if we're in timestamps view mode (table is visible) if self.view_mode != ViewMode.TIMESTAMPS: return - + current_pos = self.audio_player.position_ms segments = self.table_widget.segments() - + # Find the current segment based on audio position current_segment = next( - (segment for segment in segments + (segment for segment in segments if segment.value("start_time") <= current_pos < segment.value("end_time")), None ) - + if current_segment is not None: # Find the row index and scroll to it for i, segment in enumerate(segments): @@ -1329,7 +1364,7 @@ class TranscriptionViewerWidget(QWidget): # Method 1: Use the table widget's built-in scrolling method self.table_widget.highlight_and_scroll_to_row(i) break - + except Exception as e: pass # Silently handle any errors @@ -1346,6 +1381,9 @@ class TranscriptionViewerWidget(QWidget): if self.transcription_resizer_dialog: self.transcription_resizer_dialog.close() + if self.speaker_identification_dialog: + self.speaker_identification_dialog.close() + self.translator.stop() self.translation_thread.quit() diff --git a/ctc_forced_aligner b/ctc_forced_aligner new file mode 160000 index 00000000..1f0a5f86 --- /dev/null +++ b/ctc_forced_aligner @@ -0,0 +1 @@ +Subproject commit 1f0a5f860d3d9daf3d94edb1c7d18f90d1702e5b diff --git a/deepmultilingualpunctuation b/deepmultilingualpunctuation new file mode 160000 index 00000000..5a0dd7f4 --- /dev/null +++ b/deepmultilingualpunctuation @@ -0,0 +1 @@ +Subproject commit 5a0dd7f4fd56687f59405aa8eba1144393d8b74b diff --git a/demucs/.github/ISSUE_TEMPLATE/bug.md b/demucs/.github/ISSUE_TEMPLATE/bug.md new file mode 100644 index 00000000..217654a9 --- /dev/null +++ b/demucs/.github/ISSUE_TEMPLATE/bug.md @@ -0,0 +1,33 @@ +--- +name: 🐛 Bug Report +about: Submit a bug report to help us improve +labels: 'bug' +--- + +## 🐛 Bug Report + +(A clear and concise description of what the bug is) + +## To Reproduce + +(Write your steps here:) + +1. Step 1... +1. Step 2... +1. Step 3... + +## Expected behavior + +(Write what you thought would happen.) + +## Actual Behavior + +(Write what happened. Add screenshots, if applicable.) + +## Your Environment + + + +- Python and PyTorch version: +- Operating system and version (desktop or mobile): +- Hardware (gpu or cpu, amount of RAM etc.): diff --git a/demucs/.github/ISSUE_TEMPLATE/question.md b/demucs/.github/ISSUE_TEMPLATE/question.md new file mode 100644 index 00000000..85a007e4 --- /dev/null +++ b/demucs/.github/ISSUE_TEMPLATE/question.md @@ -0,0 +1,10 @@ +--- +name: "❓Questions/Help/Support" +about: If you have a question about the paper, code or algorithm, please ask here! +labels: question + +--- + +## ❓ Questions + +(Please ask your question here.) diff --git a/demucs/.github/workflows/linter.yml b/demucs/.github/workflows/linter.yml new file mode 100644 index 00000000..64f235fb --- /dev/null +++ b/demucs/.github/workflows/linter.yml @@ -0,0 +1,36 @@ +name: linter +on: + push: + branches: [ main ] + pull_request: + branches: [ main ] + workflow_dispatch: + +jobs: + build: + runs-on: ubuntu-latest + if: ${{ github.repository == 'facebookresearch/demucs' || github.event_name == 'workflow_dispatch' }} + steps: + - uses: actions/checkout@v2 + - uses: actions/setup-python@v2 + with: + python-version: 3.8 + + - uses: actions/cache@v2 + with: + path: env + key: env-${{ hashFiles('**/requirements.txt', '.github/workflows/*') }} + + - name: Install dependencies + run: | + python3 -m venv env + . env/bin/activate + python -m pip install --upgrade pip + pip install -r requirements.txt + pip install '.[dev]' + + + - name: Run linter + run: | + . env/bin/activate + make linter diff --git a/demucs/.github/workflows/tests.yml b/demucs/.github/workflows/tests.yml new file mode 100644 index 00000000..b31e3dd6 --- /dev/null +++ b/demucs/.github/workflows/tests.yml @@ -0,0 +1,36 @@ +name: tests +on: + push: + branches: [ main ] + pull_request: + branches: [ main ] + workflow_dispatch: + +jobs: + build: + runs-on: ubuntu-latest + if: ${{ github.repository == 'facebookresearch/demucs' || github.event_name == 'workflow_dispatch' }} + steps: + - uses: actions/checkout@v2 + - uses: actions/setup-python@v2 + with: + python-version: 3.8 + + - uses: actions/cache@v2 + with: + path: env + key: env-${{ hashFiles('**/requirements.txt', '.github/workflows/*') }} + + - name: Install dependencies + run: | + sudo apt-get update + sudo apt-get install -y ffmpeg + python3 -m venv env + . env/bin/activate + python -m pip install --upgrade pip + pip install -r requirements.txt + + - name: Run separation test + run: | + . env/bin/activate + make test_eval diff --git a/demucs/.gitignore b/demucs/.gitignore new file mode 100644 index 00000000..179cf0dd --- /dev/null +++ b/demucs/.gitignore @@ -0,0 +1,17 @@ +*.egg-info +__pycache__ +Session.vim +/build +/dist +/lab +/metadata +/notebooks +/outputs +/release +/release_models +/separated +/tests +/trash +/misc +/mdx +.mypy_cache diff --git a/demucs/CODE_OF_CONDUCT.md b/demucs/CODE_OF_CONDUCT.md new file mode 100644 index 00000000..f049d4c5 --- /dev/null +++ b/demucs/CODE_OF_CONDUCT.md @@ -0,0 +1,76 @@ +# Code of Conduct + +## Our Pledge + +In the interest of fostering an open and welcoming environment, we as +contributors and maintainers pledge to make participation in our project and +our community a harassment-free experience for everyone, regardless of age, body +size, disability, ethnicity, sex characteristics, gender identity and expression, +level of experience, education, socio-economic status, nationality, personal +appearance, race, religion, or sexual identity and orientation. + +## Our Standards + +Examples of behavior that contributes to creating a positive environment +include: + +* Using welcoming and inclusive language +* Being respectful of differing viewpoints and experiences +* Gracefully accepting constructive criticism +* Focusing on what is best for the community +* Showing empathy towards other community members + +Examples of unacceptable behavior by participants include: + +* The use of sexualized language or imagery and unwelcome sexual attention or + advances +* Trolling, insulting/derogatory comments, and personal or political attacks +* Public or private harassment +* Publishing others' private information, such as a physical or electronic + address, without explicit permission +* Other conduct which could reasonably be considered inappropriate in a + professional setting + +## Our Responsibilities + +Project maintainers are responsible for clarifying the standards of acceptable +behavior and are expected to take appropriate and fair corrective action in +response to any instances of unacceptable behavior. + +Project maintainers have the right and responsibility to remove, edit, or +reject comments, commits, code, wiki edits, issues, and other contributions +that are not aligned to this Code of Conduct, or to ban temporarily or +permanently any contributor for other behaviors that they deem inappropriate, +threatening, offensive, or harmful. + +## Scope + +This Code of Conduct applies within all project spaces, and it also applies when +an individual is representing the project or its community in public spaces. +Examples of representing a project or community include using an official +project e-mail address, posting via an official social media account, or acting +as an appointed representative at an online or offline event. Representation of +a project may be further defined and clarified by project maintainers. + +## Enforcement + +Instances of abusive, harassing, or otherwise unacceptable behavior may be +reported by contacting the project team at . All +complaints will be reviewed and investigated and will result in a response that +is deemed necessary and appropriate to the circumstances. The project team is +obligated to maintain confidentiality with regard to the reporter of an incident. +Further details of specific enforcement policies may be posted separately. + +Project maintainers who do not follow or enforce the Code of Conduct in good +faith may face temporary or permanent repercussions as determined by other +members of the project's leadership. + +## Attribution + +This Code of Conduct is adapted from the [Contributor Covenant][homepage], version 1.4, +available at https://www.contributor-covenant.org/version/1/4/code-of-conduct.html + +[homepage]: https://www.contributor-covenant.org + +For answers to common questions about this code of conduct, see +https://www.contributor-covenant.org/faq diff --git a/demucs/CONTRIBUTING.md b/demucs/CONTRIBUTING.md new file mode 100644 index 00000000..f14f4af3 --- /dev/null +++ b/demucs/CONTRIBUTING.md @@ -0,0 +1,23 @@ +# Contributing to Demucs + +## Pull Requests + +In order to accept your pull request, we need you to submit a CLA. You only need +to do this once to work on any of Facebook's open source projects. + +Complete your CLA here: + +Demucs is the implementation of a research paper. +Therefore, we do not plan on accepting many pull requests for new features. +We certainly welcome them for bug fixes. + + +## Issues + +We use GitHub issues to track public bugs. Please ensure your description is +clear and has sufficient instructions to be able to reproduce the issue. + + +## License +By contributing to this repository, you agree that your contributions will be licensed +under the LICENSE file in the root directory of this source tree. diff --git a/demucs/Demucs.ipynb b/demucs/Demucs.ipynb new file mode 100644 index 00000000..9ebcfd5a --- /dev/null +++ b/demucs/Demucs.ipynb @@ -0,0 +1,153 @@ +{ + "cells": [ + { + "cell_type": "markdown", + "metadata": { + "colab_type": "text", + "id": "Be9yoh-ILfRr" + }, + "source": [ + "# Hybrid Demucs\n", + "\n", + "Feel free to use the Colab version:\n", + "https://colab.research.google.com/drive/1dC9nVxk3V_VPjUADsnFu8EiT-xnU1tGH?usp=sharing" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "colab": { + "base_uri": "https://localhost:8080/", + "height": 139 + }, + "colab_type": "code", + "executionInfo": { + "elapsed": 12277, + "status": "ok", + "timestamp": 1583778134659, + "user": { + "displayName": "Marllus Lustosa", + "photoUrl": "https://lh3.googleusercontent.com/a-/AOh14GgLl2RbW64ZyWz3Y8IBku0zhHCMnt7fz7fEl0LTdA=s64", + "userId": "14811735256675200480" + }, + "user_tz": 180 + }, + "id": "kOjIPLlzhPfn", + "outputId": "c75f17ec-b576-4105-bc5b-c2ac9c1018a3" + }, + "outputs": [], + "source": [ + "!pip install -U demucs\n", + "# or for local development, if you have a clone of Demucs\n", + "# pip install -e ." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "colab": {}, + "colab_type": "code", + "id": "5lYOzKKCKAbJ" + }, + "outputs": [], + "source": [ + "# You can use the `demucs` command line to separate tracks\n", + "!demucs test.mp3" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "# You can also load directly the pretrained models,\n", + "# for instance for the MDX 2021 winning model of Track A:\n", + "from demucs import pretrained\n", + "model = pretrained.get_model('mdx')" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "# Because `model` is a bag of 4 models, you cannot directly call it on your data,\n", + "# but the `apply_model` will know what to do of it.\n", + "import torch\n", + "from demucs.apply import apply_model\n", + "x = torch.randn(1, 2, 44100 * 10) # ten seconds of white noise for the demo\n", + "out = apply_model(model, x)[0] # shape is [S, C, T] with S the number of sources\n", + "\n", + "# So let see, where is all the white noise content is going ?\n", + "for name, source in zip(model.sources, out):\n", + " print(name, source.std() / x.std())\n", + "# The outputs are quite weird to be fair, not what I would have expected." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "# now let's take a single model from the bag, and let's test it on a pure cosine\n", + "freq = 440 # in Hz\n", + "sr = model.samplerate\n", + "t = torch.arange(10 * sr).float() / sr\n", + "x = torch.cos(2 * 3.1416 * freq * t).expand(1, 2, -1)\n", + "sub_model = model.models[3]\n", + "out = sub_model(x)[0]\n", + "\n", + "# Same question where does it go?\n", + "for name, source in zip(model.sources, out):\n", + " print(name, source.std() / x.std())\n", + " \n", + "# Well now it makes much more sense, all the energy is going\n", + "# in the `other` source.\n", + "# Feel free to try lower pitch (try 80 Hz) to see what happens !" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "# For training or more fun, refer to the Demucs README on our repo\n", + "# https://github.com/facebookresearch/demucs/tree/main/demucs" + ] + } + ], + "metadata": { + "accelerator": "GPU", + "colab": { + "authorship_tag": "ABX9TyM9xpVr1M86NRcjtQ7g9tCx", + "collapsed_sections": [], + "name": "Demucs.ipynb", + "provenance": [] + }, + "kernelspec": { + "display_name": "Python 3", + "language": "python", + "name": "python3" + }, + "language_info": { + "codemirror_mode": { + "name": "ipython", + "version": 3 + }, + "file_extension": ".py", + "mimetype": "text/x-python", + "name": "python", + "nbconvert_exporter": "python", + "pygments_lexer": "ipython3", + "version": "3.8.8" + } + }, + "nbformat": 4, + "nbformat_minor": 1 +} diff --git a/demucs/LICENSE b/demucs/LICENSE new file mode 100644 index 00000000..a45a376f --- /dev/null +++ b/demucs/LICENSE @@ -0,0 +1,21 @@ +MIT License + +Copyright (c) Meta Platforms, Inc. and affiliates. + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. \ No newline at end of file diff --git a/demucs/MANIFEST.in b/demucs/MANIFEST.in new file mode 100644 index 00000000..96e5f54f --- /dev/null +++ b/demucs/MANIFEST.in @@ -0,0 +1,13 @@ +recursive-exclude env * +recursive-include conf *.yaml +include Makefile +include LICENSE +include demucs.png +include outputs.tar.gz +include test.mp3 +include requirements.txt +include requirements_minimal.txt +include mypy.ini +include demucs/py.typed +include demucs/remote/*.txt +include demucs/remote/*.yaml diff --git a/demucs/Makefile b/demucs/Makefile new file mode 100644 index 00000000..0474d587 --- /dev/null +++ b/demucs/Makefile @@ -0,0 +1,36 @@ +all: linter tests + +linter: + flake8 demucs + mypy demucs + +tests: test_train test_eval + +test_train: tests/musdb + _DORA_TEST_PATH=/tmp/demucs python3 -m dora run --clear \ + dset.musdb=./tests/musdb dset.segment=4 dset.shift=2 epochs=2 model=demucs \ + demucs.depth=2 demucs.channels=4 test.sdr=false misc.num_workers=0 test.workers=0 \ + test.shifts=0 + +test_eval: + python3 -m demucs -n demucs_unittest test.mp3 + python3 -m demucs -n demucs_unittest --two-stems=vocals test.mp3 + python3 -m demucs -n demucs_unittest --mp3 test.mp3 + python3 -m demucs -n demucs_unittest --flac --int24 test.mp3 + python3 -m demucs -n demucs_unittest --int24 --clip-mode clamp test.mp3 + python3 -m demucs -n demucs_unittest --segment 8 test.mp3 + python3 -m demucs.api -n demucs_unittest --segment 8 test.mp3 + python3 -m demucs --list-models + +tests/musdb: + test -e tests || mkdir tests + python3 -c 'import musdb; musdb.DB("tests/tmp", download=True)' + musdbconvert tests/tmp tests/musdb + +dist: + python3 setup.py sdist + +clean: + rm -r dist build *.egg-info + +.PHONY: linter dist test_train test_eval diff --git a/demucs/README.md b/demucs/README.md new file mode 100644 index 00000000..1bc16ee6 --- /dev/null +++ b/demucs/README.md @@ -0,0 +1,319 @@ +# Demucs Music Source Separation + +![tests badge](https://github.com/facebookresearch/demucs/workflows/tests/badge.svg) +![linter badge](https://github.com/facebookresearch/demucs/workflows/linter/badge.svg) + + +**This is the officially maintained Demucs** now that I (Alexandre Défossez) have left Meta to join [Kyutai](https://twitter.com/kyutai_labs). +Note that I'm not actively working on Demucs anymore, so expect slow replies and no new feature for now. + + + +This is the 4th release of Demucs (v4), featuring Hybrid Transformer based source separation. +**For the classic Hybrid Demucs (v3):** [Go this commit][demucs_v3]. +If you are experiencing issues and want the old Demucs back, please file an issue, and then you can get back to Demucs v3 with +`git checkout v3`. You can also go [Demucs v2][demucs_v2]. + + +Demucs is a state-of-the-art music source separation model, currently capable of separating +drums, bass, and vocals from the rest of the accompaniment. +Demucs is based on a U-Net convolutional architecture inspired by [Wave-U-Net][waveunet]. +The v4 version features [Hybrid Transformer Demucs][htdemucs], a hybrid spectrogram/waveform separation model using Transformers. +It is based on [Hybrid Demucs][hybrid_paper] (also provided in this repo), with the innermost layers +replaced by a cross-domain Transformer Encoder. This Transformer uses self-attention within each domain, +and cross-attention across domains. +The model achieves a SDR of 9.00 dB on the MUSDB HQ test set. Moreover, when using sparse attention +kernels to extend its receptive field and per source fine-tuning, we achieve state-of-the-art 9.20 dB of SDR. + +Samples are available [on our sample page](https://ai.honu.io/papers/htdemucs/index.html). +Checkout [our paper][htdemucs] for more information. +It has been trained on the [MUSDB HQ][musdb] dataset + an extra training dataset of 800 songs. +This model separates drums, bass and vocals and other stems for any song. + + +As Hybrid Transformer Demucs is brand new, it is not activated by default, you can activate it in the usual +commands described hereafter with `-n htdemucs_ft`. +The single, non fine-tuned model is provided as `-n htdemucs`, and the retrained baseline +as `-n hdemucs_mmi`. The Sparse Hybrid Transformer model decribed in our paper is not provided as its +requires custom CUDA code that is not ready for release yet. +We are also releasing an experimental 6 sources model, that adds a `guitar` and `piano` source. +Quick testing seems to show okay quality for `guitar`, but a lot of bleeding and artifacts for the `piano` source. + + +

+Schema representing the structure of Hybrid Transformer Demucs,
+    with a dual U-Net structure, one branch for the temporal domain,
+    and one branch for the spectral domain. There is a cross-domain Transformer between the Encoders and Decoders.

+ + + +## Important news if you are already using Demucs + +See the [release notes](./docs/release.md) for more details. + +- 22/02/2023: added support for the [SDX 2023 Challenge](https://www.aicrowd.com/challenges/sound-demixing-challenge-2023), + see the dedicated [doc page](./docs/sdx23.md) +- 07/12/2022: Demucs v4 now on PyPI. **htdemucs** model now used by default. Also releasing + a 6 sources models (adding `guitar` and `piano`, although the latter doesn't work so well at the moment). +- 16/11/2022: Added the new **Hybrid Transformer Demucs v4** models. + Adding support for the [torchaudio implementation of HDemucs](https://pytorch.org/audio/stable/tutorials/hybrid_demucs_tutorial.html). +- 30/08/2022: added reproducibility and ablation grids, along with an updated version of the paper. +- 17/08/2022: Releasing v3.0.5: Set split segment length to reduce memory. Compatible with pyTorch 1.12. +- 24/02/2022: Releasing v3.0.4: split into two stems (i.e. karaoke mode). + Export as float32 or int24. +- 17/12/2021: Releasing v3.0.3: bug fixes (thanks @keunwoochoi), memory drastically + reduced on GPU (thanks @famzah) and new multi-core evaluation on CPU (`-j` flag). +- 12/11/2021: Releasing **Demucs v3** with hybrid domain separation. Strong improvements + on all sources. This is the model that won Sony MDX challenge. +- 11/05/2021: Adding support for MusDB-HQ and arbitrary wav set, for the MDX challenge. For more information +on joining the challenge with Demucs see [the Demucs MDX instructions](docs/mdx.md) + + +## Comparison with other models + +We provide hereafter a summary of the different metrics presented in the paper. +You can also compare Hybrid Demucs (v3), [KUIELAB-MDX-Net][kuielab], [Spleeter][spleeter], Open-Unmix, Demucs (v1), and Conv-Tasnet on one of my favorite +songs on my [soundcloud playlist][soundcloud]. + +### Comparison of accuracy + +`Overall SDR` is the mean of the SDR for each of the 4 sources, `MOS Quality` is a rating from 1 to 5 +of the naturalness and absence of artifacts given by human listeners (5 = no artifacts), `MOS Contamination` +is a rating from 1 to 5 with 5 being zero contamination by other sources. We refer the reader to our [paper][hybrid_paper], +for more details. + +| Model | Domain | Extra data? | Overall SDR | MOS Quality | MOS Contamination | +|------------------------------|-------------|-------------------|-------------|-------------|-------------------| +| [Wave-U-Net][waveunet] | waveform | no | 3.2 | - | - | +| [Open-Unmix][openunmix] | spectrogram | no | 5.3 | - | - | +| [D3Net][d3net] | spectrogram | no | 6.0 | - | - | +| [Conv-Tasnet][demucs_v2] | waveform | no | 5.7 | - | | +| [Demucs (v2)][demucs_v2] | waveform | no | 6.3 | 2.37 | 2.36 | +| [ResUNetDecouple+][decouple] | spectrogram | no | 6.7 | - | - | +| [KUIELAB-MDX-Net][kuielab] | hybrid | no | 7.5 | **2.86** | 2.55 | +| [Band-Spit RNN][bandsplit] | spectrogram | no | **8.2** | - | - | +| **Hybrid Demucs (v3)** | hybrid | no | 7.7 | **2.83** | **3.04** | +| [MMDenseLSTM][mmdenselstm] | spectrogram | 804 songs | 6.0 | - | - | +| [D3Net][d3net] | spectrogram | 1.5k songs | 6.7 | - | - | +| [Spleeter][spleeter] | spectrogram | 25k songs | 5.9 | - | - | +| [Band-Spit RNN][bandsplit] | spectrogram | 1.7k (mixes only) | **9.0** | - | - | +| **HT Demucs f.t. (v4)** | hybrid | 800 songs | **9.0** | - | - | + + + +## Requirements + +You will need at least Python 3.8. See `requirements_minimal.txt` for requirements for separation only, +and `environment-[cpu|cuda].yml` (or `requirements.txt`) if you want to train a new model. + +### For Windows users + +Everytime you see `python3`, replace it with `python.exe`. You should always run commands from the +Anaconda console. + +### For musicians + +If you just want to use Demucs to separate tracks, you can install it with + +```bash +python3 -m pip install -U demucs +``` + +For bleeding edge versions, you can install directly from this repo using +```bash +python3 -m pip install -U git+https://github.com/facebookresearch/demucs#egg=demucs +``` + +Advanced OS support are provided on the following page, **you must read the page for your OS before posting an issues**: +- **If you are using Windows:** [Windows support](docs/windows.md). +- **If you are using macOS:** [macOS support](docs/mac.md). +- **If you are using Linux:** [Linux support](docs/linux.md). + +### For machine learning scientists + +If you have anaconda installed, you can run from the root of this repository: + +```bash +conda env update -f environment-cpu.yml # if you don't have GPUs +conda env update -f environment-cuda.yml # if you have GPUs +conda activate demucs +pip install -e . +``` + +This will create a `demucs` environment with all the dependencies installed. + +You will also need to install [soundstretch/soundtouch](https://www.surina.net/soundtouch/soundstretch.html): on macOS you can do `brew install sound-touch`, +and on Ubuntu `sudo apt-get install soundstretch`. This is used for the +pitch/tempo augmentation. + + +### Running in Docker + +Thanks to @xserrat, there is now a Docker image definition ready for using Demucs. This can ensure all libraries are correctly installed without interfering with the host OS. See his repo [Docker Facebook Demucs](https://github.com/xserrat/docker-facebook-demucs) for more information. + + +### Running from Colab + +I made a Colab to easily separate track with Demucs. Note that +transfer speeds with Colab are a bit slow for large media files, +but it will allow you to use Demucs without installing anything. + +[Demucs on Google Colab](https://colab.research.google.com/drive/1dC9nVxk3V_VPjUADsnFu8EiT-xnU1tGH?usp=sharing) + +### Web Demo + +Integrated to [Hugging Face Spaces](https://huggingface.co/spaces) with [Gradio](https://github.com/gradio-app/gradio). See demo: [![Hugging Face Spaces](https://img.shields.io/badge/%F0%9F%A4%97%20Hugging%20Face-Spaces-blue)](https://huggingface.co/spaces/akhaliq/demucs) + +### Graphical Interface + +@CarlGao4 has released a GUI for Demucs: [CarlGao4/Demucs-Gui](https://github.com/CarlGao4/Demucs-Gui). Downloads for Windows and macOS is available [here](https://github.com/CarlGao4/Demucs-Gui/releases). Use [FossHub mirror](https://fosshub.com/Demucs-GUI.html) to speed up your download. + +@Anjok07 is providing a self contained GUI in [UVR (Ultimate Vocal Remover)](https://github.com/facebookresearch/demucs/issues/334) that supports Demucs. + +### Other providers + +Audiostrip is providing free online separation with Demucs on their website [https://audiostrip.co.uk/](https://audiostrip.co.uk/). + +[MVSep](https://mvsep.com/) also provides free online separation, select `Demucs3 model B` for the best quality. + +[Neutone](https://neutone.space/) provides a realtime Demucs model in their free VST/AU plugin that can be used in your favorite DAW. + + +## Separating tracks + +In order to try Demucs, you can just run from any folder (as long as you properly installed it) + +```bash +demucs PATH_TO_AUDIO_FILE_1 [PATH_TO_AUDIO_FILE_2 ...] # for Demucs +# If you used `pip install --user` you might need to replace demucs with python3 -m demucs +python3 -m demucs --mp3 --mp3-bitrate BITRATE PATH_TO_AUDIO_FILE_1 # output files saved as MP3 + # use --mp3-preset to change encoder preset, 2 for best quality, 7 for fastest +# If your filename contain spaces don't forget to quote it !!! +demucs "my music/my favorite track.mp3" +# You can select different models with `-n` mdx_q is the quantized model, smaller but maybe a bit less accurate. +demucs -n mdx_q myfile.mp3 +# If you only want to separate vocals out of an audio, use `--two-stems=vocals` (You can also set to drums or bass) +demucs --two-stems=vocals myfile.mp3 +``` + + +If you have a GPU, but you run out of memory, please use `--segment SEGMENT` to reduce length of each split. `SEGMENT` should be changed to a integer describing the length of each segment in seconds. +A segment length of at least 10 is recommended (the bigger the number is, the more memory is required, but quality may increase). Note that the Hybrid Transformer models only support a maximum segment length of 7.8 seconds. +Creating an environment variable `PYTORCH_NO_CUDA_MEMORY_CACHING=1` is also helpful. If this still does not help, please add `-d cpu` to the command line. See the section hereafter for more details on the memory requirements for GPU acceleration. + +Separated tracks are stored in the `separated/MODEL_NAME/TRACK_NAME` folder. There you will find four stereo wav files sampled at 44.1 kHz: `drums.wav`, `bass.wav`, +`other.wav`, `vocals.wav` (or `.mp3` if you used the `--mp3` option). + +All audio formats supported by `torchaudio` can be processed (i.e. wav, mp3, flac, ogg/vorbis on Linux/macOS, etc.). On Windows, `torchaudio` has limited support, so we rely on `ffmpeg`, which should support pretty much anything. +Audio is resampled on the fly if necessary. +The output will be a wav file encoded as int16. +You can save as float32 wav files with `--float32`, or 24 bits integer wav with `--int24`. +You can pass `--mp3` to save as mp3 instead, and set the bitrate (in kbps) with `--mp3-bitrate` (default is 320). + +It can happen that the output would need clipping, in particular due to some separation artifacts. +Demucs will automatically rescale each output stem so as to avoid clipping. This can however break +the relative volume between stems. If instead you prefer hard clipping, pass `--clip-mode clamp`. +You can also try to reduce the volume of the input mixture before feeding it to Demucs. + + +Other pre-trained models can be selected with the `-n` flag. +The list of pre-trained models is: +- `htdemucs`: first version of Hybrid Transformer Demucs. Trained on MusDB + 800 songs. Default model. +- `htdemucs_ft`: fine-tuned version of `htdemucs`, separation will take 4 times more time + but might be a bit better. Same training set as `htdemucs`. +- `htdemucs_6s`: 6 sources version of `htdemucs`, with `piano` and `guitar` being added as sources. + Note that the `piano` source is not working great at the moment. +- `hdemucs_mmi`: Hybrid Demucs v3, retrained on MusDB + 800 songs. +- `mdx`: trained only on MusDB HQ, winning model on track A at the [MDX][mdx] challenge. +- `mdx_extra`: trained with extra training data (**including MusDB test set**), ranked 2nd on the track B + of the [MDX][mdx] challenge. +- `mdx_q`, `mdx_extra_q`: quantized version of the previous models. Smaller download and storage + but quality can be slightly worse. +- `SIG`: where `SIG` is a single model from the [model zoo](docs/training.md#model-zoo). + +The `--two-stems=vocals` option allows separating vocals from the rest of the accompaniment (i.e., karaoke mode). +`vocals` can be changed to any source in the selected model. +This will mix the files after separating the mix fully, so this won't be faster or use less memory. + +The `--shifts=SHIFTS` performs multiple predictions with random shifts (a.k.a the *shift trick*) of the input and average them. This makes prediction `SHIFTS` times +slower. Don't use it unless you have a GPU. + +The `--overlap` option controls the amount of overlap between prediction windows. Default is 0.25 (i.e. 25%) which is probably fine. +It can probably be reduced to 0.1 to improve a bit speed. + + +The `-j` flag allow to specify a number of parallel jobs (e.g. `demucs -j 2 myfile.mp3`). +This will multiply by the same amount the RAM used so be careful! + +### Memory requirements for GPU acceleration + +If you want to use GPU acceleration, you will need at least 3GB of RAM on your GPU for `demucs`. However, about 7GB of RAM will be required if you use the default arguments. Add `--segment SEGMENT` to change size of each split. If you only have 3GB memory, set SEGMENT to 8 (though quality may be worse if this argument is too small). Creating an environment variable `PYTORCH_NO_CUDA_MEMORY_CACHING=1` can help users with even smaller RAM such as 2GB (I separated a track that is 4 minutes but only 1.5GB is used), but this would make the separation slower. + +If you do not have enough memory on your GPU, simply add `-d cpu` to the command line to use the CPU. With Demucs, processing time should be roughly equal to 1.5 times the duration of the track. + +## Calling from another Python program + +The main function provides an `opt` parameter as a simple API. You can just pass the parsed command line as this parameter: +```python +# Assume that your command is `demucs --mp3 --two-stems vocals -n mdx_extra "track with space.mp3"` +# The following codes are same as the command above: +import demucs.separate +demucs.separate.main(["--mp3", "--two-stems", "vocals", "-n", "mdx_extra", "track with space.mp3"]) + +# Or like this +import demucs.separate +import shlex +demucs.separate.main(shlex.split('--mp3 --two-stems vocals -n mdx_extra "track with space.mp3"')) +``` + +To use more complicated APIs, see [API docs](docs/api.md) + +## Training Demucs + +If you want to train (Hybrid) Demucs, please follow the [training doc](docs/training.md). + +## MDX Challenge reproduction + +In order to reproduce the results from the Track A and Track B submissions, checkout the [MDX Hybrid Demucs submission repo][mdx_submission]. + + + +## How to cite + +``` +@inproceedings{rouard2022hybrid, + title={Hybrid Transformers for Music Source Separation}, + author={Rouard, Simon and Massa, Francisco and D{\'e}fossez, Alexandre}, + booktitle={ICASSP 23}, + year={2023} +} + +@inproceedings{defossez2021hybrid, + title={Hybrid Spectrogram and Waveform Source Separation}, + author={D{\'e}fossez, Alexandre}, + booktitle={Proceedings of the ISMIR 2021 Workshop on Music Source Separation}, + year={2021} +} +``` + +## License + +Demucs is released under the MIT license as found in the [LICENSE](LICENSE) file. + +[hybrid_paper]: https://arxiv.org/abs/2111.03600 +[waveunet]: https://github.com/f90/Wave-U-Net +[musdb]: https://sigsep.github.io/datasets/musdb.html +[openunmix]: https://github.com/sigsep/open-unmix-pytorch +[mmdenselstm]: https://arxiv.org/abs/1805.02410 +[demucs_v2]: https://github.com/facebookresearch/demucs/tree/v2 +[demucs_v3]: https://github.com/facebookresearch/demucs/tree/v3 +[spleeter]: https://github.com/deezer/spleeter +[soundcloud]: https://soundcloud.com/honualx/sets/source-separation-in-the-waveform-domain +[d3net]: https://arxiv.org/abs/2010.01733 +[mdx]: https://www.aicrowd.com/challenges/music-demixing-challenge-ismir-2021 +[kuielab]: https://github.com/kuielab/mdx-net-submission +[decouple]: https://arxiv.org/abs/2109.05418 +[mdx_submission]: https://github.com/adefossez/mdx21_demucs +[bandsplit]: https://arxiv.org/abs/2209.15174 +[htdemucs]: https://arxiv.org/abs/2211.08553 diff --git a/demucs/Readme.md b/demucs/Readme.md deleted file mode 100644 index 402d2b4a..00000000 --- a/demucs/Readme.md +++ /dev/null @@ -1 +0,0 @@ -Inlined demucs https://github.com/adefossez/demucs \ No newline at end of file diff --git a/demucs/conf/config.yaml b/demucs/conf/config.yaml new file mode 100644 index 00000000..d2597cb5 --- /dev/null +++ b/demucs/conf/config.yaml @@ -0,0 +1,304 @@ +defaults: + - _self_ + - dset: musdb44 + - svd: default + - variant: default + - override hydra/hydra_logging: colorlog + - override hydra/job_logging: colorlog + +dummy: +dset: + musdb: /checkpoint/defossez/datasets/musdbhq + musdb_samplerate: 44100 + use_musdb: true # set to false to not use musdb as training data. + wav: # path to custom wav dataset + wav2: # second custom wav dataset + segment: 11 + shift: 1 + train_valid: false + full_cv: true + samplerate: 44100 + channels: 2 + normalize: true + metadata: ./metadata + sources: ['drums', 'bass', 'other', 'vocals'] + valid_samples: # valid dataset size + backend: null # if provided select torchaudio backend. + +test: + save: False + best: True + workers: 2 + every: 20 + split: true + shifts: 1 + overlap: 0.25 + sdr: true + metric: 'loss' # metric used for best model selection on the valid set, can also be nsdr + nonhq: # path to non hq MusDB for evaluation + +epochs: 360 +batch_size: 64 +max_batches: # limit the number of batches per epoch, useful for debugging + # or if your dataset is gigantic. +optim: + lr: 3e-4 + momentum: 0.9 + beta2: 0.999 + loss: l1 # l1 or mse + optim: adam + weight_decay: 0 + clip_grad: 0 + +seed: 42 +debug: false +valid_apply: true +flag: +save_every: +weights: [1., 1., 1., 1.] # weights over each source for the training/valid loss. + +augment: + shift_same: false + repitch: + proba: 0.2 + max_tempo: 12 + remix: + proba: 1 + group_size: 4 + scale: + proba: 1 + min: 0.25 + max: 1.25 + flip: true + +continue_from: # continue from other XP, give the XP Dora signature. +continue_pretrained: # signature of a pretrained XP, this cannot be a bag of models. +pretrained_repo: # repo for pretrained model (default is official AWS) +continue_best: true +continue_opt: false + +misc: + num_workers: 10 + num_prints: 4 + show: false + verbose: false + +# List of decay for EMA at batch or epoch level, e.g. 0.999. +# Batch level EMA are kept on GPU for speed. +ema: + epoch: [] + batch: [] + +use_train_segment: true # to remove +model_segment: # override the segment parameter for the model, usually 4 times the training segment. +model: demucs # see demucs/train.py for the possibilities, and config for each model hereafter. +demucs: # see demucs/demucs.py for a detailed description + # Channels + channels: 64 + growth: 2 + # Main structure + depth: 6 + rewrite: true + lstm_layers: 0 + # Convolutions + kernel_size: 8 + stride: 4 + context: 1 + # Activations + gelu: true + glu: true + # Normalization + norm_groups: 4 + norm_starts: 4 + # DConv residual branch + dconv_depth: 2 + dconv_mode: 1 # 1 = branch in encoder, 2 = in decoder, 3 = in both. + dconv_comp: 4 + dconv_attn: 4 + dconv_lstm: 4 + dconv_init: 1e-4 + # Pre/post treatment + resample: true + normalize: false + # Weight init + rescale: 0.1 + +hdemucs: # see demucs/hdemucs.py for a detailed description + # Channels + channels: 48 + channels_time: + growth: 2 + # STFT + nfft: 4096 + wiener_iters: 0 + end_iters: 0 + wiener_residual: false + cac: true + # Main structure + depth: 6 + rewrite: true + hybrid: true + hybrid_old: false + # Frequency Branch + multi_freqs: [] + multi_freqs_depth: 3 + freq_emb: 0.2 + emb_scale: 10 + emb_smooth: true + # Convolutions + kernel_size: 8 + stride: 4 + time_stride: 2 + context: 1 + context_enc: 0 + # normalization + norm_starts: 4 + norm_groups: 4 + # DConv residual branch + dconv_mode: 1 + dconv_depth: 2 + dconv_comp: 4 + dconv_attn: 4 + dconv_lstm: 4 + dconv_init: 1e-3 + # Weight init + rescale: 0.1 + +# Torchaudio implementation of HDemucs +torch_hdemucs: +# Channels + channels: 48 + growth: 2 + # STFT + nfft: 4096 + # Main structure + depth: 6 + freq_emb: 0.2 + emb_scale: 10 + emb_smooth: true + # Convolutions + kernel_size: 8 + stride: 4 + time_stride: 2 + context: 1 + context_enc: 0 + # normalization + norm_starts: 4 + norm_groups: 4 + # DConv residual branch + dconv_depth: 2 + dconv_comp: 4 + dconv_attn: 4 + dconv_lstm: 4 + dconv_init: 1e-3 + +htdemucs: # see demucs/htdemucs.py for a detailed description + # Channels + channels: 48 + channels_time: + growth: 2 + # STFT + nfft: 4096 + wiener_iters: 0 + end_iters: 0 + wiener_residual: false + cac: true + # Main structure + depth: 4 + rewrite: true + # Frequency Branch + multi_freqs: [] + multi_freqs_depth: 3 + freq_emb: 0.2 + emb_scale: 10 + emb_smooth: true + # Convolutions + kernel_size: 8 + stride: 4 + time_stride: 2 + context: 1 + context_enc: 0 + # normalization + norm_starts: 4 + norm_groups: 4 + # DConv residual branch + dconv_mode: 1 + dconv_depth: 2 + dconv_comp: 8 + dconv_init: 1e-3 + # Before the Transformer + bottom_channels: 0 + # CrossTransformer + # ------ Common to all + # Regular parameters + t_layers: 5 + t_hidden_scale: 4.0 + t_heads: 8 + t_dropout: 0.0 + t_layer_scale: True + t_gelu: True + # ------------- Positional Embedding + t_emb: sin + t_max_positions: 10000 # for the scaled embedding + t_max_period: 10000.0 + t_weight_pos_embed: 1.0 + t_cape_mean_normalize: True + t_cape_augment: True + t_cape_glob_loc_scale: [5000.0, 1.0, 1.4] + t_sin_random_shift: 0 + # ------------- norm before a transformer encoder + t_norm_in: True + t_norm_in_group: False + # ------------- norm inside the encoder + t_group_norm: False + t_norm_first: True + t_norm_out: True + # ------------- optim + t_weight_decay: 0.0 + t_lr: + # ------------- sparsity + t_sparse_self_attn: False + t_sparse_cross_attn: False + t_mask_type: diag + t_mask_random_seed: 42 + t_sparse_attn_window: 400 + t_global_window: 100 + t_sparsity: 0.95 + t_auto_sparsity: False + # Cross Encoder First (False) + t_cross_first: False + # Weight init + rescale: 0.1 + +svd: # see svd.py for documentation + penalty: 0 + min_size: 0.1 + dim: 1 + niters: 2 + powm: false + proba: 1 + conv_only: false + convtr: false + bs: 1 + +quant: # quantization hyper params + diffq: # diffq penalty, typically 1e-4 or 3e-4 + qat: # use QAT with a fixed number of bits (not as good as diffq) + min_size: 0.2 + group_size: 8 + +dora: + dir: outputs + exclude: ["misc.*", "slurm.*", 'test.reval', 'flag', 'dset.backend'] + +slurm: + time: 4320 + constraint: volta32gb + setup: ['module load cudnn/v8.4.1.50-cuda.11.6 NCCL/2.11.4-6-cuda.11.6 cuda/11.6'] + +# Hydra config +hydra: + job_logging: + formatters: + colorlog: + datefmt: "%m-%d %H:%M:%S" diff --git a/demucs/conf/dset/aetl.yaml b/demucs/conf/dset/aetl.yaml new file mode 100644 index 00000000..7c983160 --- /dev/null +++ b/demucs/conf/dset/aetl.yaml @@ -0,0 +1,19 @@ +# @package _global_ + +# automix dataset with Musdb, extra training data and the test set of Musdb. +# This used even more remixes than auto_extra_test. +dset: + wav: /checkpoint/defossez/datasets/aetl + samplerate: 44100 + channels: 2 +epochs: 320 +max_batches: 500 + +augment: + shift_same: true + scale: + proba: 0. + remix: + proba: 0 + repitch: + proba: 0 diff --git a/demucs/conf/dset/auto_extra_test.yaml b/demucs/conf/dset/auto_extra_test.yaml new file mode 100644 index 00000000..056183a5 --- /dev/null +++ b/demucs/conf/dset/auto_extra_test.yaml @@ -0,0 +1,18 @@ +# @package _global_ + +# automix dataset with Musdb, extra training data and the test set of Musdb. +dset: + wav: /checkpoint/defossez/datasets/automix_extra_test2 + samplerate: 44100 + channels: 2 +epochs: 320 +max_batches: 500 + +augment: + shift_same: true + scale: + proba: 0. + remix: + proba: 0 + repitch: + proba: 0 diff --git a/demucs/conf/dset/auto_mus.yaml b/demucs/conf/dset/auto_mus.yaml new file mode 100644 index 00000000..9a2d9df5 --- /dev/null +++ b/demucs/conf/dset/auto_mus.yaml @@ -0,0 +1,20 @@ +# @package _global_ + +# Automix dataset based on musdb train set. +dset: + wav: /checkpoint/defossez/datasets/automix_musdb + samplerate: 44100 + channels: 2 +epochs: 360 +max_batches: 300 +test: + every: 4 + +augment: + shift_same: true + scale: + proba: 0.5 + remix: + proba: 0 + repitch: + proba: 0 diff --git a/demucs/conf/dset/extra44.yaml b/demucs/conf/dset/extra44.yaml new file mode 100644 index 00000000..f0adc467 --- /dev/null +++ b/demucs/conf/dset/extra44.yaml @@ -0,0 +1,8 @@ +# @package _global_ + +# Musdb + extra tracks +dset: + wav: /checkpoint/defossez/datasets/allstems_44/ + samplerate: 44100 + channels: 2 +epochs: 320 diff --git a/demucs/conf/dset/extra_mmi_goodclean.yaml b/demucs/conf/dset/extra_mmi_goodclean.yaml new file mode 100644 index 00000000..fe47bcf2 --- /dev/null +++ b/demucs/conf/dset/extra_mmi_goodclean.yaml @@ -0,0 +1,12 @@ +# @package _global_ + +# Musdb + extra tracks +dset: + wav: /checkpoint/defossez/datasets/allstems_44/ + wav2: /checkpoint/defossez/datasets/mmi44_goodclean + samplerate: 44100 + channels: 2 + wav2_weight: null + wav2_valid: false + valid_samples: 100 +epochs: 1200 diff --git a/demucs/conf/dset/extra_test.yaml b/demucs/conf/dset/extra_test.yaml new file mode 100644 index 00000000..1e7d05ad --- /dev/null +++ b/demucs/conf/dset/extra_test.yaml @@ -0,0 +1,12 @@ +# @package _global_ + +# Musdb + extra tracks + test set from musdb. +dset: + wav: /checkpoint/defossez/datasets/allstems_test_44/ + samplerate: 44100 + channels: 2 +epochs: 320 +max_batches: 700 +test: + sdr: false + every: 500 diff --git a/demucs/conf/dset/musdb44.yaml b/demucs/conf/dset/musdb44.yaml new file mode 100644 index 00000000..c5623468 --- /dev/null +++ b/demucs/conf/dset/musdb44.yaml @@ -0,0 +1,5 @@ +# @package _global_ + +dset: + samplerate: 44100 + channels: 2 \ No newline at end of file diff --git a/demucs/conf/dset/sdx23_bleeding.yaml b/demucs/conf/dset/sdx23_bleeding.yaml new file mode 100644 index 00000000..5f7fd1e4 --- /dev/null +++ b/demucs/conf/dset/sdx23_bleeding.yaml @@ -0,0 +1,10 @@ +# @package _global_ + +# Musdb + extra tracks +dset: + wav: /shared/home/defossez/data/datasets/moisesdb23_bleeding_v1.0/ + use_musdb: false + samplerate: 44100 + channels: 2 + backend: soundfile # must use soundfile as some mixture would clip with sox. +epochs: 320 diff --git a/demucs/conf/dset/sdx23_labelnoise.yaml b/demucs/conf/dset/sdx23_labelnoise.yaml new file mode 100644 index 00000000..367769e6 --- /dev/null +++ b/demucs/conf/dset/sdx23_labelnoise.yaml @@ -0,0 +1,10 @@ +# @package _global_ + +# Musdb + extra tracks +dset: + wav: /shared/home/defossez/data/datasets/moisesdb23_labelnoise_v1.0 + use_musdb: false + samplerate: 44100 + channels: 2 + backend: soundfile # must use soundfile as some mixture would clip with sox. +epochs: 320 diff --git a/demucs/conf/svd/base.yaml b/demucs/conf/svd/base.yaml new file mode 100644 index 00000000..e4de8685 --- /dev/null +++ b/demucs/conf/svd/base.yaml @@ -0,0 +1,14 @@ +# @package _global_ + +svd: + penalty: 0 + min_size: 1 + dim: 50 + niters: 4 + powm: false + proba: 1 + conv_only: false + convtr: false # ideally this should be true, but some models were trained with this to false. + +optim: + beta2: 0.9998 \ No newline at end of file diff --git a/demucs/conf/svd/base2.yaml b/demucs/conf/svd/base2.yaml new file mode 100644 index 00000000..b88a7519 --- /dev/null +++ b/demucs/conf/svd/base2.yaml @@ -0,0 +1,14 @@ +# @package _global_ + +svd: + penalty: 0 + min_size: 1 + dim: 100 + niters: 4 + powm: false + proba: 1 + conv_only: false + convtr: true + +optim: + beta2: 0.9998 \ No newline at end of file diff --git a/demucs/conf/svd/default.yaml b/demucs/conf/svd/default.yaml new file mode 100644 index 00000000..03bfe3db --- /dev/null +++ b/demucs/conf/svd/default.yaml @@ -0,0 +1 @@ +# @package _global_ diff --git a/demucs/conf/variant/default.yaml b/demucs/conf/variant/default.yaml new file mode 100644 index 00000000..03bfe3db --- /dev/null +++ b/demucs/conf/variant/default.yaml @@ -0,0 +1 @@ +# @package _global_ diff --git a/demucs/conf/variant/example.yaml b/demucs/conf/variant/example.yaml new file mode 100644 index 00000000..9b38aeca --- /dev/null +++ b/demucs/conf/variant/example.yaml @@ -0,0 +1,5 @@ +# @package _global_ + +model: hdemucs +hdemucs: + channels: 32 \ No newline at end of file diff --git a/demucs/conf/variant/finetune.yaml b/demucs/conf/variant/finetune.yaml new file mode 100644 index 00000000..c3ea21ed --- /dev/null +++ b/demucs/conf/variant/finetune.yaml @@ -0,0 +1,19 @@ +# @package _global_ + +epochs: 4 +batch_size: 16 +optim: + lr: 0.0006 +test: + every: 1 + sdr: false +dset: + segment: 28 + shift: 2 + +augment: + scale: + proba: 0 + shift_same: true + remix: + proba: 0 diff --git a/demucs/demucs.png b/demucs/demucs.png new file mode 100644 index 00000000..d043f644 Binary files /dev/null and b/demucs/demucs.png differ diff --git a/demucs/__init__.py b/demucs/demucs/__init__.py similarity index 100% rename from demucs/__init__.py rename to demucs/demucs/__init__.py diff --git a/demucs/__main__.py b/demucs/demucs/__main__.py similarity index 100% rename from demucs/__main__.py rename to demucs/demucs/__main__.py diff --git a/demucs/api.py b/demucs/demucs/api.py similarity index 100% rename from demucs/api.py rename to demucs/demucs/api.py diff --git a/demucs/apply.py b/demucs/demucs/apply.py similarity index 100% rename from demucs/apply.py rename to demucs/demucs/apply.py diff --git a/demucs/audio.py b/demucs/demucs/audio.py similarity index 100% rename from demucs/audio.py rename to demucs/demucs/audio.py diff --git a/demucs/audio_legacy.py b/demucs/demucs/audio_legacy.py similarity index 100% rename from demucs/audio_legacy.py rename to demucs/demucs/audio_legacy.py diff --git a/demucs/augment.py b/demucs/demucs/augment.py similarity index 100% rename from demucs/augment.py rename to demucs/demucs/augment.py diff --git a/demucs/demucs.py b/demucs/demucs/demucs.py similarity index 100% rename from demucs/demucs.py rename to demucs/demucs/demucs.py diff --git a/demucs/distrib.py b/demucs/demucs/distrib.py similarity index 100% rename from demucs/distrib.py rename to demucs/demucs/distrib.py diff --git a/demucs/ema.py b/demucs/demucs/ema.py similarity index 100% rename from demucs/ema.py rename to demucs/demucs/ema.py diff --git a/demucs/evaluate.py b/demucs/demucs/evaluate.py similarity index 100% rename from demucs/evaluate.py rename to demucs/demucs/evaluate.py diff --git a/demucs/grids/__init__.py b/demucs/demucs/grids/__init__.py similarity index 100% rename from demucs/grids/__init__.py rename to demucs/demucs/grids/__init__.py diff --git a/demucs/grids/_explorers.py b/demucs/demucs/grids/_explorers.py similarity index 100% rename from demucs/grids/_explorers.py rename to demucs/demucs/grids/_explorers.py diff --git a/demucs/grids/mdx.py b/demucs/demucs/grids/mdx.py similarity index 100% rename from demucs/grids/mdx.py rename to demucs/demucs/grids/mdx.py diff --git a/demucs/grids/mdx_extra.py b/demucs/demucs/grids/mdx_extra.py similarity index 100% rename from demucs/grids/mdx_extra.py rename to demucs/demucs/grids/mdx_extra.py diff --git a/demucs/grids/mdx_refine.py b/demucs/demucs/grids/mdx_refine.py similarity index 100% rename from demucs/grids/mdx_refine.py rename to demucs/demucs/grids/mdx_refine.py diff --git a/demucs/grids/mmi.py b/demucs/demucs/grids/mmi.py similarity index 100% rename from demucs/grids/mmi.py rename to demucs/demucs/grids/mmi.py diff --git a/demucs/grids/mmi_ft.py b/demucs/demucs/grids/mmi_ft.py similarity index 100% rename from demucs/grids/mmi_ft.py rename to demucs/demucs/grids/mmi_ft.py diff --git a/demucs/grids/repro.py b/demucs/demucs/grids/repro.py similarity index 100% rename from demucs/grids/repro.py rename to demucs/demucs/grids/repro.py diff --git a/demucs/grids/repro_ft.py b/demucs/demucs/grids/repro_ft.py similarity index 100% rename from demucs/grids/repro_ft.py rename to demucs/demucs/grids/repro_ft.py diff --git a/demucs/grids/sdx23.py b/demucs/demucs/grids/sdx23.py similarity index 100% rename from demucs/grids/sdx23.py rename to demucs/demucs/grids/sdx23.py diff --git a/demucs/hdemucs.py b/demucs/demucs/hdemucs.py similarity index 100% rename from demucs/hdemucs.py rename to demucs/demucs/hdemucs.py diff --git a/demucs/htdemucs.py b/demucs/demucs/htdemucs.py similarity index 100% rename from demucs/htdemucs.py rename to demucs/demucs/htdemucs.py diff --git a/demucs/pretrained.py b/demucs/demucs/pretrained.py similarity index 100% rename from demucs/pretrained.py rename to demucs/demucs/pretrained.py diff --git a/demucs/py.typed b/demucs/demucs/py.typed similarity index 100% rename from demucs/py.typed rename to demucs/demucs/py.typed diff --git a/demucs/remote/files.txt b/demucs/demucs/remote/files.txt similarity index 100% rename from demucs/remote/files.txt rename to demucs/demucs/remote/files.txt diff --git a/demucs/remote/hdemucs_mmi.yaml b/demucs/demucs/remote/hdemucs_mmi.yaml similarity index 100% rename from demucs/remote/hdemucs_mmi.yaml rename to demucs/demucs/remote/hdemucs_mmi.yaml diff --git a/demucs/remote/htdemucs.yaml b/demucs/demucs/remote/htdemucs.yaml similarity index 100% rename from demucs/remote/htdemucs.yaml rename to demucs/demucs/remote/htdemucs.yaml diff --git a/demucs/remote/htdemucs_6s.yaml b/demucs/demucs/remote/htdemucs_6s.yaml similarity index 100% rename from demucs/remote/htdemucs_6s.yaml rename to demucs/demucs/remote/htdemucs_6s.yaml diff --git a/demucs/remote/htdemucs_ft.yaml b/demucs/demucs/remote/htdemucs_ft.yaml similarity index 100% rename from demucs/remote/htdemucs_ft.yaml rename to demucs/demucs/remote/htdemucs_ft.yaml diff --git a/demucs/remote/mdx.yaml b/demucs/demucs/remote/mdx.yaml similarity index 100% rename from demucs/remote/mdx.yaml rename to demucs/demucs/remote/mdx.yaml diff --git a/demucs/remote/mdx_extra.yaml b/demucs/demucs/remote/mdx_extra.yaml similarity index 100% rename from demucs/remote/mdx_extra.yaml rename to demucs/demucs/remote/mdx_extra.yaml diff --git a/demucs/remote/mdx_extra_q.yaml b/demucs/demucs/remote/mdx_extra_q.yaml similarity index 100% rename from demucs/remote/mdx_extra_q.yaml rename to demucs/demucs/remote/mdx_extra_q.yaml diff --git a/demucs/remote/mdx_q.yaml b/demucs/demucs/remote/mdx_q.yaml similarity index 100% rename from demucs/remote/mdx_q.yaml rename to demucs/demucs/remote/mdx_q.yaml diff --git a/demucs/remote/repro_mdx_a.yaml b/demucs/demucs/remote/repro_mdx_a.yaml similarity index 100% rename from demucs/remote/repro_mdx_a.yaml rename to demucs/demucs/remote/repro_mdx_a.yaml diff --git a/demucs/remote/repro_mdx_a_hybrid_only.yaml b/demucs/demucs/remote/repro_mdx_a_hybrid_only.yaml similarity index 100% rename from demucs/remote/repro_mdx_a_hybrid_only.yaml rename to demucs/demucs/remote/repro_mdx_a_hybrid_only.yaml diff --git a/demucs/remote/repro_mdx_a_time_only.yaml b/demucs/demucs/remote/repro_mdx_a_time_only.yaml similarity index 100% rename from demucs/remote/repro_mdx_a_time_only.yaml rename to demucs/demucs/remote/repro_mdx_a_time_only.yaml diff --git a/demucs/repitch.py b/demucs/demucs/repitch.py similarity index 100% rename from demucs/repitch.py rename to demucs/demucs/repitch.py diff --git a/demucs/repo.py b/demucs/demucs/repo.py similarity index 100% rename from demucs/repo.py rename to demucs/demucs/repo.py diff --git a/demucs/separate.py b/demucs/demucs/separate.py similarity index 100% rename from demucs/separate.py rename to demucs/demucs/separate.py diff --git a/demucs/solver.py b/demucs/demucs/solver.py similarity index 100% rename from demucs/solver.py rename to demucs/demucs/solver.py diff --git a/demucs/spec.py b/demucs/demucs/spec.py similarity index 100% rename from demucs/spec.py rename to demucs/demucs/spec.py diff --git a/demucs/states.py b/demucs/demucs/states.py similarity index 100% rename from demucs/states.py rename to demucs/demucs/states.py diff --git a/demucs/svd.py b/demucs/demucs/svd.py similarity index 100% rename from demucs/svd.py rename to demucs/demucs/svd.py diff --git a/demucs/train.py b/demucs/demucs/train.py similarity index 100% rename from demucs/train.py rename to demucs/demucs/train.py diff --git a/demucs/transformer.py b/demucs/demucs/transformer.py similarity index 100% rename from demucs/transformer.py rename to demucs/demucs/transformer.py diff --git a/demucs/utils.py b/demucs/demucs/utils.py similarity index 100% rename from demucs/utils.py rename to demucs/demucs/utils.py diff --git a/demucs/wav.py b/demucs/demucs/wav.py similarity index 100% rename from demucs/wav.py rename to demucs/demucs/wav.py diff --git a/demucs/wdemucs.py b/demucs/demucs/wdemucs.py similarity index 100% rename from demucs/wdemucs.py rename to demucs/demucs/wdemucs.py diff --git a/demucs/docs/api.md b/demucs/docs/api.md new file mode 100644 index 00000000..dbd858a7 --- /dev/null +++ b/demucs/docs/api.md @@ -0,0 +1,204 @@ +# Demucs APIs + +## Quick start + +Notes: Type hints have been added to all API functions. It is recommended to check them before passing parameters to a function as some arguments only support limited types (e.g. parameter `repo` of method `load_model` only support type `pathlib.Path`). + +1. The first step is to import api module: + +```python +import demucs.api +``` + +2. Then initialize the `Separator`. Parameters which will be served as default values for methods can be passed. Model should be specified. + +```python +# Initialize with default parameters: +separator = demucs.api.Separator() + +# Use another model and segment: +separator = demucs.api.Separator(model="mdx_extra", segment=12) + +# You can also use other parameters defined +``` + +3. Separate it! + +```python +# Separating an audio file +origin, separated = separator.separate_audio_file("file.mp3") + +# Separating a loaded audio +origin, separated = separator.separate_tensor(audio) + +# If you encounter an error like CUDA out of memory, you can use this to change parameters like `segment`: +separator.update_parameter(segment=smaller_segment) +``` + +4. Save audio + +```python +# Remember to create the destination folder before calling `save_audio` +# Or you are likely to recieve `FileNotFoundError` +for file, sources in separated: + for stem, source in sources.items(): + demucs.api.save_audio(source, f"{stem}_{file}", samplerate=separator.samplerate) +``` + +## API References + +The types of each parameter and return value is not listed in this document. To know the exact type of them, please read the type hints in api.py (most modern code editors support inferring types based on type hints). + +### `class Separator` + +The base separator class + +##### Parameters + +model: Pretrained model name or signature. Default is htdemucs. + +repo: Folder containing all pre-trained models for use. + +segment: Length (in seconds) of each segment (only available if `split` is `True`). If not specified, will use the command line option. + +shifts: If > 0, will shift in time `wav` by a random amount between 0 and 0.5 sec and apply the oppositve shift to the output. This is repeated `shifts` time and all predictions are averaged. This effectively makes the model time equivariant and improves SDR by up to 0.2 points. If not specified, will use the command line option. + +split: If True, the input will be broken down into small chunks (length set by `segment`) and predictions will be performed individually on each and concatenated. Useful for model with large memory footprint like Tasnet. If not specified, will use the command line option. + +overlap: The overlap between the splits. If not specified, will use the command line option. + +device (torch.device, str, or None): If provided, device on which to execute the computation, otherwise `wav.device` is assumed. When `device` is different from `wav.device`, only local computations will be on `device`, while the entire tracks will be stored on `wav.device`. If not specified, will use the command line option. + +jobs: Number of jobs. This can increase memory usage but will be much faster when multiple cores are available. If not specified, will use the command line option. + +callback: A function will be called when the separation of a chunk starts or finished. The argument passed to the function will be a dict. For more information, please see the Callback section. + +callback_arg: A dict containing private parameters to be passed to callback function. For more information, please see the Callback section. + +progress: If true, show a progress bar. + +##### Notes for callback + +The function will be called with only one positional parameter whose type is `dict`. The `callback_arg` will be combined with information of current separation progress. The progress information will override the values in `callback_arg` if same key has been used. To abort the separation, raise an exception in `callback` which should be handled by yourself if you want your codes continue to function. + +Progress information contains several keys (These keys will always exist): +- `model_idx_in_bag`: The index of the submodel in `BagOfModels`. Starts from 0. +- `shift_idx`: The index of shifts. Starts from 0. +- `segment_offset`: The offset of current segment. If the number is 441000, it doesn't mean that it is at the 441000 second of the audio, but the "frame" of the tensor. +- `state`: Could be `"start"` or `"end"`. +- `audio_length`: Length of the audio (in "frame" of the tensor). +- `models`: Count of submodels in the model. + +#### `property samplerate` + +A read-only property saving sample rate of the model requires. Will raise a warning if the model is not loaded and return the default value. + +#### `property audio_channels` + +A read-only property saving audio channels of the model requires. Will raise a warning if the model is not loaded and return the default value. + +#### `property model` + +A read-only property saving the model. + +#### `method update_parameter()` + +Update the parameters of separation. + +##### Parameters + +segment: Length (in seconds) of each segment (only available if `split` is `True`). If not specified, will use the command line option. + +shifts: If > 0, will shift in time `wav` by a random amount between 0 and 0.5 sec and apply the oppositve shift to the output. This is repeated `shifts` time and all predictions are averaged. This effectively makes the model time equivariant and improves SDR by up to 0.2 points. If not specified, will use the command line option. + +split: If True, the input will be broken down into small chunks (length set by `segment`) and predictions will be performed individually on each and concatenated. Useful for model with large memory footprint like Tasnet. If not specified, will use the command line option. + +overlap: The overlap between the splits. If not specified, will use the command line option. + +device (torch.device, str, or None): If provided, device on which to execute the computation, otherwise `wav.device` is assumed. When `device` is different from `wav.device`, only local computations will be on `device`, while the entire tracks will be stored on `wav.device`. If not specified, will use the command line option. + +jobs: Number of jobs. This can increase memory usage but will be much faster when multiple cores are available. If not specified, will use the command line option. + +callback: A function will be called when the separation of a chunk starts or finished. The argument passed to the function will be a dict. For more information, please see the Callback section. + +callback_arg: A dict containing private parameters to be passed to callback function. For more information, please see the Callback section. + +progress: If true, show a progress bar. + +##### Notes for callback + +The function will be called with only one positional parameter whose type is `dict`. The `callback_arg` will be combined with information of current separation progress. The progress information will override the values in `callback_arg` if same key has been used. To abort the separation, raise an exception in `callback` which should be handled by yourself if you want your codes continue to function. + +Progress information contains several keys (These keys will always exist): +- `model_idx_in_bag`: The index of the submodel in `BagOfModels`. Starts from 0. +- `shift_idx`: The index of shifts. Starts from 0. +- `segment_offset`: The offset of current segment. If the number is 441000, it doesn't mean that it is at the 441000 second of the audio, but the "frame" of the tensor. +- `state`: Could be `"start"` or `"end"`. +- `audio_length`: Length of the audio (in "frame" of the tensor). +- `models`: Count of submodels in the model. + +#### `method separate_tensor()` + +Separate an audio. + +##### Parameters + +wav: Waveform of the audio. Should have 2 dimensions, the first is each audio channel, while the second is the waveform of each channel. e.g. `tuple(wav.shape) == (2, 884000)` means the audio has 2 channels. + +sr: Sample rate of the original audio, the wave will be resampled if it doesn't match the model. + +##### Returns + +A tuple, whose first element is the original wave and second element is a dict, whose keys are the name of stems and values are separated waves. The original wave will have already been resampled. + +##### Notes + +Use this function with cautiousness. This function does not provide data verifying. + +#### `method separate_audio_file()` + +Separate an audio file. The method will automatically read the file. + +##### Parameters + +wav: Path of the file to be separated. + +##### Returns + +A tuple, whose first element is the original wave and second element is a dict, whose keys are the name of stems and values are separated waves. The original wave will have already been resampled. + +### `function save_audio()` + +Save audio file. + +##### Parameters + +wav: Audio to be saved + +path: The file path to be saved. Ending must be one of `.mp3` and `.wav`. + +samplerate: File sample rate. + +bitrate: If the suffix of `path` is `.mp3`, it will be used to specify the bitrate of mp3. + +clip: Clipping preventing strategy. + +bits_per_sample: If the suffix of `path` is `.wav`, it will be used to specify the bit depth of wav. + +as_float: If it is True and the suffix of `path` is `.wav`, then `bits_per_sample` will be set to 32 and will write the wave file with float format. + +##### Returns + +None + +### `function list_models()` + +List the available models. Please remember that not all the returned models can be successfully loaded. + +##### Parameters + +repo: The repo whose models are to be listed. + +##### Returns + +A dict with two keys ("single" for single models and "bag" for bag of models). The values are lists whose components are strs. \ No newline at end of file diff --git a/demucs/docs/linux.md b/demucs/docs/linux.md new file mode 100644 index 00000000..31d9a695 --- /dev/null +++ b/demucs/docs/linux.md @@ -0,0 +1,28 @@ +# Linux support for Demucs + +If your distribution has at least Python 3.8, and you just wish to separate +tracks with Demucs, not train it, you can just run + +```bash +pip3 install --user -U demucs +# Then anytime you want to use demucs, just do +python3 -m demucs -d cpu PATH_TO_AUDIO_FILE_1 +# If you have added the user specific pip bin/ folder to your path, you can also do +demucs -d cpu PATH_TO_AUDIO_FILE_1 +``` + +If Python is too old, or you want to be able to train, I recommend [installing Miniconda][miniconda], with Python 3.8 or more. + +```bash +conda activate +pip3 install -U demucs +# Then anytime you want to use demucs, first do conda activate, then +demucs -d cpu PATH_TO_AUDIO_FILE_1 +``` + +Of course, you can also use a specific env for Demucs. + +**Important, torchaudio 0.12 update:** Torchaudio no longer supports decoding mp3s without ffmpeg installed. You must have ffmpeg installed, either through Anaconda (`conda install ffmpeg -c conda-forge`) or as a distribution package (e.g. `sudo apt-get install ffmpeg`). + + +[miniconda]: https://docs.conda.io/en/latest/miniconda.html#linux-installers diff --git a/demucs/docs/mac.md b/demucs/docs/mac.md new file mode 100644 index 00000000..62dd235e --- /dev/null +++ b/demucs/docs/mac.md @@ -0,0 +1,28 @@ +# macOS support for Demucs + +If you have a sufficiently recent version of macOS, you can just run + +```bash +python3 -m pip install --user -U demucs +# Then anytime you want to use demucs, just do +python3 -m demucs -d cpu PATH_TO_AUDIO_FILE_1 +# If you have added the user specific pip bin/ folder to your path, you can also do +demucs -d cpu PATH_TO_AUDIO_FILE_1 +``` + +If you do not already have Anaconda installed or much experience with the terminal on macOS, here are some detailed instructions: + +1. Download [Anaconda 3.8 (or more recent) 64-bit for macOS][anaconda]: +2. Open [Anaconda Prompt in macOS][prompt] +3. Follow these commands: +```bash +conda activate +pip3 install -U demucs +# Then anytime you want to use demucs, first do conda activate, then +demucs -d cpu PATH_TO_AUDIO_FILE_1 +``` + +**Important, torchaudio 0.12 update:** Torchaudio no longer supports decoding mp3s without ffmpeg installed. You must have ffmpeg installed, either through Anaconda (`conda install ffmpeg -c conda-forge`) or with Homebrew for instance (`brew install ffmpeg`). + +[anaconda]: https://www.anaconda.com/download +[prompt]: https://docs.anaconda.com/anaconda/user-guide/getting-started/#open-nav-mac diff --git a/demucs/docs/mdx.md b/demucs/docs/mdx.md new file mode 100644 index 00000000..2a20f9cb --- /dev/null +++ b/demucs/docs/mdx.md @@ -0,0 +1,73 @@ +# Music DemiXing challenge (MDX) + +If you want to use Demucs for the [MDX challenge](https://www.aicrowd.com/challenges/music-demixing-challenge-ismir-2021), +please follow the instructions hereafter + +## Installing Demucs + +Follow the instructions from the [main README](https://github.com/facebookresearch/demucs#requirements) +in order to setup Demucs using Anaconda. You will need the full setup up for training, including soundstretch. + +## Getting MusDB-HQ + +Download [MusDB-HQ](https://zenodo.org/record/3338373) to some folder and unzip it. + +## Training Demucs + +Train Demucs (you might need to change the batch size depending on the number of GPUs available). +It seems 48 channels is enough to get the best performance on MusDB-HQ, and training will faster +and less memory demanding. In any case, the 64 channels versions is timing out on the challenge. +```bash +./run.py --channels=48 --batch_size 64 --musdb=PATH_TO_MUSDB --is_wav [EXTRA_FLAGS] +``` + +### Post training + +Once the training is completed, a new model file will be exported in `models/`. + +You can look at the SDR on the MusDB dataset using `python result_table.py`. + + +### Evaluate and export a model before training is over + +If you want to export a model before training is complete, use the following command: +```bash +python -m demucs [ALL EXACT TRAINING FLAGS] --save_model +``` +You can also pass the `--half` flag, in order to save weights in half precision. This will divide the model size by 2 and won't impact SDR. + +Once this is done, you can partially evaluate a model with +```bash +./run.py --test NAME_OF_MODEL.th --musdb=PATH_TO_MUSDB --is_wav +``` + +**Note:** `NAME_OF_MODEL.th` is given relative to the models folder (given by `--models`, defaults to `models/`), so don't include it in the name. + + +### Training smaller models + +If you want to quickly test idea, I would recommend training a 16 kHz model, and testing if things work there or not, before training the full 44kHz model. You can train one of those with +```bash +./run.py --channels=32 --samplerate 16000 --samples 160000 --data_stride 16000 --depth=5 --batch_size 64 --repitch=0 --musdb=PATH_TO_MUSDB --is_wav [EXTRA_FLAGS] +``` +(repitch must be turned off, because things will break at 16kHz). + +## Submitting your model + +1. Git clone [the Music Demixing Challenge - Starter Kit - Demucs Edition](https://github.com/adefossez/music-demixing-challenge-starter-kit). +2. Inside the starter kit, create a `models/` folder and copy over the trained model from the Demucs repo (renaming +it for instance `my_model.th`) +3. Inside the `test_demuc.py` file, change the function `prediction_setup`: comment the loading +of the pre-trained model, and uncomment the code to load your own model. +4. Edit the file `aicrowd.json` with your username. +5. Install [git-lfs](https://git-lfs.github.com/). Then run + +```bash +git lfs install +git add models/ +git add -u . +git commit -m "My Demucs submission" +``` +6. Follow the [submission instructions](https://github.com/AIcrowd/music-demixing-challenge-starter-kit/blob/master/docs/SUBMISSION.md). + +Best of luck 🤞 diff --git a/demucs/docs/release.md b/demucs/docs/release.md new file mode 100644 index 00000000..df8f122f --- /dev/null +++ b/demucs/docs/release.md @@ -0,0 +1,114 @@ +# Release notes for Demucs + +## V4.1.0a, TBD + +Get models list + +Check segment of HTDemucs inside BagOfModels + +Added api.py to be called from another program + +Use api in separate.py + +Added `--other-method`: method to get `no_{STEM}`, add up all the other stems (add), original track substract the specific stem (minus), and discard (none) + +Added type `HTDemucs` to type alias `AnyModel`. + +Improving recent torchaudio versions support (Thanks @CarlGao4) + +## V4.0.1, 8th of September 2023 + +**From this version, Python 3.7 is no longer supported. This is not a problem since the latest PyTorch 2.0.0 no longer support it either.** + +Various improvements by @CarlGao4. Support for `segment` param inside of HTDemucs +model. + +Made diffq an optional dependency, with an error message if not installed. + +Added output format flac (Free Lossless Audio Codec) + +Will use CPU for complex numbers, when using MPS device (all other computations are performed by mps). + +Optimize codes to save memory + +Allow changing preset of MP3 + +## V4.0.0, 7th of December 2022 + +Adding hybrid transformer Demucs model. + +Added support for [Torchaudio implementation of HDemucs](https://pytorch.org/audio/main/tutorials/hybrid_demucs_tutorial.html), thanks @skim0514. + +Added experimental 6 sources model `htdemucs_6s` (`drums`, `bass`, `other`, `vocals`, `piano`, `guitar`). + +## V3.0.6, 16th of November 2022 + +Option to customize output path of stems (@CarlGao4) + +Fixed bug in pad1d leading to failure sometimes. + +## V3.0.5, 17th of August 2022 + +Added `--segment` flag to customize the segment length and use less memory (thanks @CarlGao4). + +Fix reflect padding bug on small inputs. + +Compatible with pyTorch 1.12 + +## V3.0.4, 24th of February 2022 + +Added option to split into two stems (i.e. vocals, vs. non vocals), thanks to @CarlGao4. + +Added `--float32`, `--int24` and `--clip-mode` options to customize how output stems are saved. + +## V3.0.3, 2nd of December 2021 + +Fix bug in weights used for different sources. Thanks @keunwoochoi for the report and fix. + +Improving drastically memory usage on GPU for long files. Thanks a lot @famzah for providing this. + +Adding multithread evaluation on CPU (`-j` option). + +(v3.0.2 had a bug with the CPU pool and is skipped.) + +## V3.0.1, 12th of November 2021 + +Release of Demucs v3, featuring hybrid domain separation and much more. +This drops support for Conv-Tasnet and training on the non HQ MusDB dataset. +There is no version 3.0.0 because I messed up. + +## V2.0.2, 26th of May 2021 + +- Fix in Tasnet (PR #178) +- Use ffmpeg in priority when available instead of torchaudio to avoid small shift in MP3 data. +- other minor fixes + +## v2.0.1, 11th of May 2021 + +MusDB HQ support added. Custom wav dataset support added. +Minor changes: issue with padding of mp3 and torchaudio reading, in order to limit that, +Demucs now uses ffmpeg in priority and fallback to torchaudio. +Replaced pre-trained demucs model with one trained on more recent codebase. + +## v2.0.0, 28th of April 2021 + +This is a big release, with at lof of breaking changes. You will likely +need to install Demucs from scratch. + + + +- Demucs now supports on the fly resampling by a factor of 2. +This improves SDR almost 0.3 points. +- Random scaling of each source added (From Uhlich et al. 2017). +- Random pitch and tempo augmentation addded, from [Cohen-Hadria et al. 2019]. +- With extra augmentation, the best performing Demucs model now has only 64 channels +instead of 100, so model size goes from 2.4GB to 1GB. Also SDR is up from 5.6 SDR to 6.3 when trained only on MusDB. +- Quantized model using [DiffQ](https://github.com/facebookresearch/diffq) has been added. Model size is 150MB, no loss in quality as far as I, or the metrics, +can say. +- Pretrained models are now using the TorchHub interface. +- Overlap mode for separation, to limit inconsitencies at + frame boundaries, with linear transition over the overlap. Overlap is currently + at 25%. Not that this is only done for separation, not training, because + I added that quite late to the code. For Conv-TasNet this can improve + SDR quite a bit (+0.3 points, to 6.0). +- PyPI hosting, for separation, not training! diff --git a/demucs/docs/sdx23.md b/demucs/docs/sdx23.md new file mode 100644 index 00000000..65c5df9a --- /dev/null +++ b/demucs/docs/sdx23.md @@ -0,0 +1,61 @@ +# SDX 23 challenge + +Checkout [the challenge page](https://www.aicrowd.com/challenges/sound-demixing-challenge-2023) +for more information. This page is specifically on training models for the [MDX'23 sub-challenge](https://www.aicrowd.com/challenges/sound-demixing-challenge-2023/problems/music-demixing-track-mdx-23). +There are two tracks: one trained on a dataset with bleeding, and the other with label mixups. + +This gives instructions on training an Hybrid Demucs model on those datasets. +I haven't tried the HT Demucs model, as it typically requires quite a bit of training data but the same could be done with it. + +You will need to work from an up to date clone of this repo. See the [generic training instructions](./training.md) for more information. + +## Getting the data + +Register on the challenge, then checkout the [Resources page](https://www.aicrowd.com/challenges/sound-demixing-challenge-2023/problems/music-demixing-track-mdx-23/dataset_files) and download the dataset you are +interested in. + +Update the `conf/dset/sdx23_bleeding.yaml` and `conf/dset/sdx23_labelnoise.yaml` files to point to the right path. + +**Make sure soundfile** is installed (`conda install -c conda-forge libsndfile; pip install soundfile`). + +### Create proper train / valid structure + +Demucs requires a valid set to work properly. Go to the folder where you extracted the tracks then do: + +```shell +mkdir train +mv * train # there will be a warning saying cannot move train to itself but that's fine the other tracks should have. +mkdir valid +cd train +mv 5640831d-7853-4d06-8166-988e2844b652 bc964128-da16-4e4c-af95-4d1211e78c70 \ + cc7f7675-d3c8-4a49-a2d7-a8959b694004 f40ffd10-4e8b-41e6-bd8a-971929ca9138 \ + bc1f2967-f834-43bd-aadc-95afc897cfe7 cc3e4991-6cce-40fe-a917-81a4fbb92ea6 \ + ed90a89a-bf22-444d-af3d-d9ac3896ebd2 f4b735de-14b1-4091-a9ba-c8b30c0740a7 ../valid +``` + +## Training + +See `dora grid sdx23` for a starting point. You can do `dora grid sdx23 --init --dry_run` then `dora run -f SIG -d` with `SIG` one of the signature +to train on a machine with GPUs if you do not have a SLURM cluster. + +Keep in mind that the valid tracks and train tracks are corrupted in different ways for those tasks, so do not expect +the valid loss to go down as smoothly as with normal training on the clean MusDB. + +I only trained Hybrid Demucs baselines as Hybrid Transformer typically requires more data. + + +## Exporting models + +Run +``` +python -m tools.export SIG +``` + +This will export the trained model into the `release_models` folder. + +## Submitting a model + +Clone the [Demucs Starter Kit for SDX23](https://github.com/adefossez/sdx23). Follow the instructions there. + +You will to copy the models under `release_models` in the `sdx23/models/` folder before you can use them. +Make sure you have git-lfs properly installed and setup before adding those files to your fork of `sdx23`. diff --git a/demucs/docs/training.md b/demucs/docs/training.md new file mode 100644 index 00000000..fa046070 --- /dev/null +++ b/demucs/docs/training.md @@ -0,0 +1,290 @@ +# Training (Hybrid) Demucs + +## Install all the dependencies + +You should install all the dependencies either with either Anaconda (using the env file `environment-cuda.yml` ) +or `pip`, with `requirements.txt`. + +## Datasets + +### MusDB HQ + +Note that we do not support MusDB non HQ training anymore. +Get the [Musdb HQ](https://zenodo.org/record/3338373) dataset, and update the path to it in two places: +- The `dset.musdb` key inside `conf/config.yaml`. +- The variable `MUSDB_PATH` inside `tools/automix.py`. + +### Create the fine tuning datasets + +**This is only for the MDX 2021 competition models** + +I use a fine tuning on a dataset crafted by remixing songs in a musically plausible way. +The automix script will make sure that BPM, first beat and pitches are aligned. +In the file `tools/automix.py`, edit `OUTPATH` to suit your setup, as well as the `MUSDB_PATH` +to point to your copy of MusDB HQ. Then run + +```bash +export NUMBA_NUM_THREADS=1; python3 -m tools.automix +``` + +**Important:** the script will show many errors, those are normals. They just indicate when two stems + do not batch due to BPM or music scale difference. + +Finally, edit the file `conf/dset/auto_mus.yaml` and replace `dset.wav` to the value of `OUTPATH`. + +If you have a custom dataset, you can also uncomment the lines `dset2 = ...` and +`dset3 = ...` to add your custom wav data and the test set of MusDB for Track B models. +You can then replace the paths in `conf/dset/auto_extra.yaml`, `conf/dset/auto_extra_test.yaml` +and `conf/dset/aetl.yaml` (this last one was using 10 mixes instead of 6 for each song). + +### Dataset metadata cache + +Datasets are scanned the first time they are used to determine the files and their durations. +If you change a dataset and need a rescan, just delete the `metadata` folder. + +## A short intro to Dora + +I use [Dora][dora] for all the of experiments (XPs) management. You should have a look at the Dora README +to learn about the tool. Here is a quick summary of what to know: + +- An XP is a unique set of hyper-parameters with a given signature. The signature is a hash of + those hyper-parameters. I will always refer to an XP with its signature, e.g. `9357e12e`. + We will see after that you can retrieve the hyper-params and re-rerun it in a single command. +- In fact, the hash is defined as a delta between the base config and the one obtained with + the config overrides you passed from the command line. + **This means you must never change the `conf/**.yaml` files directly.**, + except for editing things like paths. Changing the default values in the config files means + the XP signature won't reflect that change, and wrong checkpoints might be reused. + I know, this is annoying, but the reason is that otherwise, any change to the config file would + mean that all XPs ran so far would see their signature change. + +### Dora commands + +Run `tar xvf outputs.tar.gz`. This will initialize the Dora XP repository, so that Dora knows +which hyper-params match the signature like `9357e12e`. Once you have done that, you should be able +to run the following: + +```bash +dora info -f 81de367c # this will show the hyper-parameter used by a specific XP. + # Be careful some overrides might present twice, and the right most one + # will give you the right value for it. +dora run -d -f 81de367c # run an XP with the hyper-parameters from XP 81de367c. + # `-d` is for distributed, it will use all available GPUs. +dora run -d -f 81de367c hdemucs.channels=32 # start from the config of XP 81de367c but change some hyper-params. + # This will give you a new XP with a new signature (here 3fe9c332). +``` + +An XP runs from a specific folder based on its signature, by default under the `outputs/` folder. +You can safely interrupt a training and resume it, it will reuse any existing checkpoint, as it will +reuse the same folder. +If you made some change to the code and need to ignore a previous checkpoint you can use `dora run --clear [RUN ARGS]`. + +If you have a Slurm cluster, you can also use the `dora grid` command, e.g. `dora grid mdx`. +Please refer to the [Dora documentation][dora] for more information. + +## Hyper parameters + +Have a look at [conf/config.yaml](../conf/config.yaml) for a list of all the hyper-parameters you can override. +If you are not familiar with [Hydra](https://github.com/facebookresearch/hydra), go checkout their page +to be familiar with how to provide overrides for your trainings. + + +## Model architecture + +A number of architectures are supported. You can select one with `model=NAME`, and have a look +in [conf/config.yaml'(../conf/config.yaml) for each architecture specific hyperparams. +Those specific params will be always prefixed with the architecture name when passing the override +from the command line or in grid files. Here is the list of models: + +- demucs: original time-only Demucs. +- hdemucs: Hybrid Demucs (v3). +- torch_hdemucs: Same as Hybrid Demucs, but using [torchaudio official implementation](https://pytorch.org/audio/stable/tutorials/hybrid_demucs_tutorial.html). +- htdemucs: Hybrid Transformer Demucs (v4). + +### Storing config in files + +As mentioned earlier, you should never change the base config files. However, you can use Hydra config groups +in order to store variants you often use. If you want to create a new variant combining multiple hyper-params, +copy the file `conf/variant/example.yaml` to `conf/variant/my_variant.yaml`, and then you can use it with + +```bash +dora run -d variant=my_variant +``` + +Once you have created this file, you should not edit it once you have started training models with it. + + +## Fine tuning + +If a first model is trained, you can fine tune it with other settings (e.g. automix dataset) with + +```bash +dora run -d -f 81de367c continue_from=81de367c dset=auto_mus variant=finetune +```` + +Note that you need both `-f 81de367c` and `continue_from=81de367c`. The first one indicates +that the hyper-params of `81de367c` should be used as a starting point for the config. +The second indicates that the weights from `81de367c` should be used as a starting point for the solver. + + +## Model evaluation + +Your model will be evaluated automatically with the new SDR definition from MDX every 20 epochs. +Old style SDR (which is quite slow) will only happen at the end of training. + +## Model Export + + +In order to use your models with other commands (such as the `demucs` command for separation) you must +export it. For that run + +```bash +python3 -m tools.export 9357e12e [OTHER SIGS ...] # replace with the appropriate signatures. +``` + +The models will be stored under `release_models/`. You can use them with the `demucs` separation command with the following flags: +```bash +demucs --repo ./release_models -n 9357e12e my_track.mp3 +``` + +### Bag of models + +If you want to combine multiple models, potentially with different weights for each source, you can copy +`demucs/remote/mdx.yaml` to `./release_models/my_bag.yaml`. You can then edit the list of models (all models used should have been exported first) and the weights per source and model (list of list, outer list is over models, inner list is over sources). You can then use your bag of model as + +```bash +demucs --repo ./release_models -n my_bag my_track.mp3 +``` + +## Model evaluation + +You can evaluate any pre-trained model or bag of models using the following command: +```bash +python3 -m tools.test_pretrained -n NAME_OF_MODEL [EXTRA ARGS] +``` +where `NAME_OF_MODEL` is either the name of the bag (e.g. `mdx`, `repro_mdx_a`), +or a single Dora signature of one of the model of the bags. You can pass `EXTRA ARGS` to customize +the test options, like the number of random shifts (e.g. `test.shifts=2`). This will compute the old-style +SDR and can take quite bit of time. + +For custom models that were trained locally, you will need to indicate that you wish +to use the local model repositories, with the `--repo ./release_models` flag, e.g., +```bash +python3 -m tools.test_pretrained --repo ./release_models -n my_bag +``` + + +## API to retrieve the model + +You can retrieve officially released models in Python using the following API: +```python +from demucs import pretrained +from demucs.apply import apply_model +bag = pretrained.get_model('htdemucs') # for a bag of models or a named model + # (which is just a bag with 1 model). +model = pretrained.get_model('955717e8') # using the signature for single models. + +bag.models # list of individual models +stems = apply_model(model, mix) # apply the model to the given mix. +``` + +## Model Zoo + +### Hybrid Transformer Demucs + +The configuration for the Hybrid Transformer models are available in: + +```shell +dora grid mmi --dry_run --init +dora grid mmi_ft --dry_run --init # fined tuned on each sources. +``` + +We release in particular `955717e8`, Hybrid Transformer Demucs using 5 layers, 512 channels, 10 seconds training segment length. We also release its fine tuned version, with one model +for each source `f7e0c4bc`, `d12395a8`, `92cfc3b6`, `04573f0d` (drums, bass, other, vocals). +The model `955717e8` is also named `htdemucs`, while the bag of models is provided +as `htdemucs_ft`. + +We also release `75fc33f5`, a regular Hybrid Demucs trained on the same dataset, +available as `hdemucs_mmi`. + + + +### Models from the MDX Competition 2021 + + +Here is a short descriptions of the models used for the MDX submission, either Track A (MusDB HQ only) +or Track B (extra training data allowed). Training happen in two stage, with the second stage +being the fine tunining on the automix generated dataset. +All the fine tuned models are available on our AWS repository +(you can retrieve it with `demucs.pretrained.get_model(SIG)`). The bag of models are available +by doing `demucs.pretrained.get_model(NAME)` with `NAME` begin either `mdx` (for Track A) or `mdx_extra` +(for Track B). + +#### Track A + +The 4 models are: + +- `0d19c1c6`: fine-tuned on automix dataset from `9357e12e` +- `7ecf8ec1`: fine-tuned on automix dataset from `e312f349` +- `c511e2ab`: fine-tuned on automix dataset from `81de367c` +- `7d865c68`: fine-tuned on automix dataset from `80a68df8` + +The 4 initial models (before fine tuning are): + +- `9357e12e`: 64ch time domain only improved Demucs, with new residual branches, group norm, + and singular value penalty. +- `e312f349`: 64ch time domain only improved, with new residual branches, group norm, + and singular value penalty, trained with a loss that focus only on drums and bass. +- `81de367c`: 48ch hybrid model , with residual branches, group norm, + singular value penalty penalty and amplitude spectrogram. +- `80a68df8`: same as b5559babb but using CaC and different + random seed, as well different weigths per frequency bands in outermost layers. + +The hybrid models are combined with equal weights for all sources except for the bass. +`0d19c1c6` (time domain) is used for both drums and bass. `7ecf8ec1` is used only for the bass. + +You can see all the hyper parameters at once with (one common line for all common hyper params, and then only shows +the hyper parameters that differs), along with the DiffQ variants that are used for the `mdx_q` models: +``` +dora grid mdx --dry_run --init +dora grid mdx --dry_run --init +``` + +#### Track B + +- `e51eebcc` +- `a1d90b5c` +- `5d2d6c55` +- `cfa93e08` + +All the models are 48ch hybrid demucs with different random seeds. Two of them +are using CaC, and two are using amplitude spectrograms with masking. +All the models are combined with equal weights for all sources. + +Things are a bit messy for Track B, there was a lot of fine tuning +over different datasets. I won't describe the entire genealogy of models here, +but all the information can be accessed with the `dora info -f SIG` command. + +Similarly you can do (those will contain a few extra lines, for training without the MusDB test set as training, and extra DiffQ XPs): +``` +dora grid mdx_extra --dry_run --init +``` + +### Reproducibility and Ablation + +I updated the paper to report numbers with a more homogeneous setup than the one used for the competition. +On MusDB HQ, I still need to use a combination of time only and hybrid models to achieve the best performance. +The experiments are provided in the grids [repro.py](../demucs/grids/repro.py) and +[repro_ft._py](../demucs/grids/repro_ft.py) for the fine tuning on the realistic mix datasets. + +The new bag of models reaches an SDR of 7.64 (vs. 7.68 for the original track A model). It uses +2 time only models trained with residual branches, local attention and the SVD penalty, +along with 2 hybrid models, with the same features, and using CaC representation. +We average the performance of all the models with the same weight over all sources, unlike +what was done for the original track A model. We trained for 600 epochs, against 360 before. + +The new bag of model is available as part of the pretrained model as `repro_mdx_a`. +The time only bag is named `repro_mdx_a_time_only`, and the hybrid only `repro_mdx_a_hybrid_only`. +Checkout the paper for more information on the training. + +[dora]: https://github.com/facebookresearch/dora diff --git a/demucs/docs/windows.md b/demucs/docs/windows.md new file mode 100644 index 00000000..b259b765 --- /dev/null +++ b/demucs/docs/windows.md @@ -0,0 +1,67 @@ +# Windows support for Demucs + +## Installation and usage + +If you don't have much experience with Anaconda, python or the shell, here are more detailed instructions. Note that **Demucs is not supported on 32bits systems** (as Pytorch is not available there). + +- First install Anaconda with **Python 3.8** or more recent, which you can find [here][install]. +- Start the [Anaconda prompt][prompt]. + +Then, all commands that follow must be run from this prompt. + +
+ I have no coding experience and these are too difficult for me + +> Then a GUI is suitable for you. See [Demucs GUI](https://github.com/CarlGao4/Demucs-Gui) + +
+ +### If you want to use your GPU + +If you have graphic cards produced by NVIDIA with more than 2GiB of memory, you can separate tracks with GPU acceleration. To achieve this, you must install Pytorch with CUDA. If Pytorch was already installed (you already installed Demucs for instance), first run `python.exe -m pip uninstall torch torchaudio`. +Then visit [Pytorch Home Page](https://pytorch.org/get-started/locally/) and follow the guide on it to install with CUDA support. Please make sure that the version of torchaudio should no greater than 2.1 (which is the latest version when this document is written, but 2.2.0 is sure unsupported) + +### Installation + +Start the Anaconda prompt, and run the following + +```cmd +conda install -c conda-forge ffmpeg +python.exe -m pip install -U demucs SoundFile +``` + +### Upgrade + +To upgrade Demucs, simply run `python.exe -m pip install -U demucs`, from the Anaconda prompt. + +### Usage + +Then to use Demucs, just start the **Anaconda prompt** and run: +``` +demucs -d cpu "PATH_TO_AUDIO_FILE_1" ["PATH_TO_AUDIO_FILE_2" ...] +``` +The `"` around the filename are required if the path contains spaces. A simple way to input these paths is draging a file from a folder into the terminal. + +To find out the separated files, you can run this command and open the folders: +``` +explorer separated +``` + +### Separating an entire folder + +You can use the following command to separate an entire folder of mp3s for instance (replace the extension `.mp3` if needs be for other file types) +``` +cd FOLDER +for %i in (*.mp3) do (demucs -d cpu "%i") +``` + +## Potential errors + +If you have an error saying that `mkl_intel_thread.dll` cannot be found, you can try to first run +`conda install -c defaults intel-openmp -f`. Then try again to run the `demucs` command. If it still doesn't work, you can try to run first `set CONDA_DLL_SEARCH_MODIFICATION_ENABLE=1`, then again the `demucs` command and hopefully it will work 🙏. + +**If you get a permission error**, please try starting the Anaconda Prompt as administrator. + + +[install]: https://www.anaconda.com/download +[prompt]: https://docs.anaconda.com/anaconda/user-guide/getting-started/#open-prompt-win diff --git a/demucs/environment-cpu.yml b/demucs/environment-cpu.yml new file mode 100644 index 00000000..2419bf35 --- /dev/null +++ b/demucs/environment-cpu.yml @@ -0,0 +1,28 @@ +name: demucs + +channels: + - pytorch + - conda-forge + +dependencies: + - python>=3.8,<3.10 + - ffmpeg>=4.2 + - pytorch>=1.8.1 + - torchaudio>=0.8 + - tqdm>=4.36 + - pip + - pip: + - diffq>=0.2 + - dora-search + - einops + - hydra-colorlog>=1.1 + - hydra-core>=1.1 + - julius>=0.2.3 + - lameenc>=1.2 + - openunmix + - musdb>=0.4.0 + - museval>=0.4.0 + - soundfile + - submitit + - treetable>=0.2.3 + diff --git a/demucs/environment-cuda.yml b/demucs/environment-cuda.yml new file mode 100644 index 00000000..0d61d33d --- /dev/null +++ b/demucs/environment-cuda.yml @@ -0,0 +1,28 @@ +name: demucs + +channels: + - pytorch + - conda-forge + +dependencies: + - python>=3.8,<3.10 + - ffmpeg>=4.2 + - pytorch>=1.8.1 + - torchaudio>=0.8 + - cudatoolkit>=10 + - tqdm>=4.36 + - pip + - pip: + - diffq>=0.2 + - dora-search + - einops + - hydra-colorlog>=1.1 + - hydra-core>=1.1 + - julius>=0.2.3 + - lameenc>=1.2 + - openunmix + - musdb>=0.4.0 + - museval>=0.4.0 + - soundfile + - submitit + - treetable>=0.2.3 diff --git a/demucs/hubconf.py b/demucs/hubconf.py new file mode 100644 index 00000000..0cdb553e --- /dev/null +++ b/demucs/hubconf.py @@ -0,0 +1,11 @@ +# Copyright (c) Meta Platforms, Inc. and affiliates. +# All rights reserved. +# +# This source code is licensed under the license found in the +# LICENSE file in the root directory of this source tree. + +dependencies = ['dora-search', 'julius', 'lameenc', 'openunmix', 'pyyaml', + 'torch', 'torchaudio', 'tqdm'] + +from demucs.pretrained import get_model + diff --git a/demucs/mypy.ini b/demucs/mypy.ini new file mode 100644 index 00000000..c4e17f16 --- /dev/null +++ b/demucs/mypy.ini @@ -0,0 +1,5 @@ +[mypy] + +[mypy-treetable,torchaudio.*,diffq,yaml,tqdm,lameenc,musdb,museval,openunmix.*,einops,xformers.*] +ignore_missing_imports = True + diff --git a/demucs/outputs.tar.gz b/demucs/outputs.tar.gz new file mode 100644 index 00000000..51933ac9 Binary files /dev/null and b/demucs/outputs.tar.gz differ diff --git a/demucs/requirements.txt b/demucs/requirements.txt new file mode 100644 index 00000000..4f7bcbb1 --- /dev/null +++ b/demucs/requirements.txt @@ -0,0 +1,19 @@ +# please make sure you have already a pytorch install that is cuda enabled! +dora-search>=0.1.12 +diffq>=0.2.1 +einops +flake8 +hydra-colorlog>=1.1 +hydra-core>=1.1 +julius>=0.2.3 +lameenc>=1.2 +museval +mypy +openunmix +pyyaml +submitit +torch>=1.8.1 +torchaudio>=0.8 +tqdm +treetable +soundfile>=0.10.3 diff --git a/demucs/requirements_minimal.txt b/demucs/requirements_minimal.txt new file mode 100644 index 00000000..8c6f1e57 --- /dev/null +++ b/demucs/requirements_minimal.txt @@ -0,0 +1,10 @@ +# please make sure you have already a pytorch install that is cuda enabled! +dora-search +einops +julius>=0.2.3 +lameenc>=1.2 +openunmix +pyyaml +torch>=1.8.1 +torchaudio>=0.8 +tqdm diff --git a/demucs/setup.cfg b/demucs/setup.cfg new file mode 100644 index 00000000..d54d56a0 --- /dev/null +++ b/demucs/setup.cfg @@ -0,0 +1,8 @@ +[pep8] +max-line-length = 100 + +[flake8] +max-line-length = 100 + +[yapf] +column_limit = 100 diff --git a/demucs/setup.py b/demucs/setup.py new file mode 100644 index 00000000..47163d79 --- /dev/null +++ b/demucs/setup.py @@ -0,0 +1,75 @@ +# Copyright (c) Meta Platforms, Inc. and affiliates. +# All rights reserved. +# +# This source code is licensed under the license found in the +# LICENSE file in the root directory of this source tree. +# author: adefossez +# Inspired from https://github.com/kennethreitz/setup.py + +from pathlib import Path + +from setuptools import setup + + +NAME = 'demucs' +DESCRIPTION = 'Music source separation in the waveform domain.' + +URL = 'https://github.com/facebookresearch/demucs' +EMAIL = 'defossez@fb.com' +AUTHOR = 'Alexandre Défossez' +REQUIRES_PYTHON = '>=3.8.0' + +HERE = Path(__file__).parent + +# Get version without explicitely loading the module. +for line in open('demucs/__init__.py'): + line = line.strip() + if '__version__' in line: + context = {} + exec(line, context) + VERSION = context['__version__'] + + +def load_requirements(name): + required = [i.strip() for i in open(HERE / name)] + required = [i for i in required if not i.startswith('#')] + return required + + +REQUIRED = load_requirements('requirements_minimal.txt') +ALL_REQUIRED = load_requirements('requirements.txt') + +try: + with open(HERE / "README.md", encoding='utf-8') as f: + long_description = '\n' + f.read() +except FileNotFoundError: + long_description = DESCRIPTION + +setup( + name=NAME, + version=VERSION, + description=DESCRIPTION, + long_description=long_description, + long_description_content_type='text/markdown', + author=AUTHOR, + author_email=EMAIL, + python_requires=REQUIRES_PYTHON, + url=URL, + packages=['demucs'], + extras_require={ + 'dev': ALL_REQUIRED, + }, + install_requires=REQUIRED, + include_package_data=True, + entry_points={ + 'console_scripts': ['demucs=demucs.separate:main'], + }, + license='MIT License', + classifiers=[ + # Trove classifiers + # Full list: https://pypi.python.org/pypi?%3Aaction=list_classifiers + 'License :: OSI Approved :: MIT License', + 'Topic :: Multimedia :: Sound/Audio', + 'Topic :: Scientific/Engineering :: Artificial Intelligence', + ], +) diff --git a/demucs/test.mp3 b/demucs/test.mp3 new file mode 100644 index 00000000..668604d8 Binary files /dev/null and b/demucs/test.mp3 differ diff --git a/demucs/tools/__init__.py b/demucs/tools/__init__.py new file mode 100644 index 00000000..0952fcc3 --- /dev/null +++ b/demucs/tools/__init__.py @@ -0,0 +1,5 @@ +# Copyright (c) Meta Platforms, Inc. and affiliates. +# All rights reserved. +# +# This source code is licensed under the license found in the +# LICENSE file in the root directory of this source tree. diff --git a/demucs/tools/automix.py b/demucs/tools/automix.py new file mode 100644 index 00000000..a839345e --- /dev/null +++ b/demucs/tools/automix.py @@ -0,0 +1,343 @@ +# Copyright (c) Meta Platforms, Inc. and affiliates. +# All rights reserved. +# +# This source code is licensed under the license found in the +# LICENSE file in the root directory of this source tree. + +""" +This script creates realistic mixes with stems from different songs. +In particular, it will align BPM, sync up the first beat and perform pitch +shift to maximize pitches overlap. +In order to limit artifacts, only parts that can be mixed with less than 15% +tempo shift, and 3 semitones of pitch shift are mixed together. +""" +from collections import namedtuple +from concurrent.futures import ProcessPoolExecutor +import hashlib +from pathlib import Path +import random +import shutil +import tqdm +import pickle + +from librosa.beat import beat_track +from librosa.feature import chroma_cqt +import numpy as np +import torch +from torch.nn import functional as F + +from dora.utils import try_load +from demucs.audio import save_audio +from demucs.repitch import repitch +from demucs.pretrained import SOURCES +from demucs.wav import build_metadata, Wavset, _get_musdb_valid + + +MUSDB_PATH = '/checkpoint/defossez/datasets/musdbhq' +EXTRA_WAV_PATH = "/checkpoint/defossez/datasets/allstems_44" +# WARNING: OUTPATH will be completely erased. +OUTPATH = Path.home() / 'tmp/demucs_mdx/automix_musdb/' +CACHE = Path.home() / 'tmp/automix_cache' # cache BPM and pitch information. +CHANNELS = 2 +SR = 44100 +MAX_PITCH = 3 # maximum allowable pitch shift in semi tones +MAX_TEMPO = 0.15 # maximum allowable tempo shift + + +Spec = namedtuple("Spec", "tempo onsets kr track index") + + +def rms(wav, window=10000): + """efficient rms computed for each time step over a given window.""" + half = window // 2 + window = 2 * half + 1 + wav = F.pad(wav, (half, half)) + tot = wav.pow(2).cumsum(dim=-1) + return ((tot[..., window - 1:] - tot[..., :-window + 1]) / window).sqrt() + + +def analyse_track(dset, index): + """analyse track, extract bpm and distribution of notes from the bass line.""" + track = dset[index] + mix = track.sum(0).mean(0) + ref = mix.std() + + starts = (abs(mix) >= 1e-2 * ref).float().argmax().item() + track = track[..., starts:] + + cache = CACHE / dset.sig + cache.mkdir(exist_ok=True, parents=True) + + cache_file = cache / f"{index}.pkl" + cached = None + if cache_file.exists(): + cached = try_load(cache_file) + if cached is not None: + tempo, events, hist_kr = cached + + if cached is None: + drums = track[0].mean(0) + if drums.std() > 1e-2 * ref: + tempo, events = beat_track(y=drums.numpy(), units='time', sr=SR) + else: + print("failed drums", drums.std(), ref) + return None, track + + bass = track[1].mean(0) + r = rms(bass) + peak = r.max() + mask = r >= 0.05 * peak + bass = bass[mask] + if bass.std() > 1e-2 * ref: + kr = torch.from_numpy(chroma_cqt(y=bass.numpy(), sr=SR)) + hist_kr = (kr.max(dim=0, keepdim=True)[0] == kr).float().mean(1) + else: + print("failed bass", bass.std(), ref) + return None, track + + pickle.dump([tempo, events, hist_kr], open(cache_file, 'wb')) + spec = Spec(tempo, events, hist_kr, track, index) + return spec, None + + +def best_pitch_shift(kr_a, kr_b): + """find the best pitch shift between two chroma distributions.""" + deltas = [] + for p in range(12): + deltas.append((kr_a - kr_b).abs().mean()) + kr_b = kr_b.roll(1, 0) + + ps = np.argmin(deltas) + if ps > 6: + ps = ps - 12 + return ps + + +def align_stems(stems): + """Align the first beats of the stems. + This is a naive implementation. A grid with a time definition 10ms is defined and + each beat onset is represented as a gaussian over this grid. + Then, we try each possible time shift to make two grids align the best. + We repeat for all sources. + """ + sources = len(stems) + width = 5e-3 # grid of 10ms + limit = 5 + std = 2 + x = torch.arange(-limit, limit + 1, 1).float() + gauss = torch.exp(-x**2 / (2 * std**2)) + + grids = [] + for wav, onsets in stems: + le = wav.shape[-1] + dur = le / SR + grid = torch.zeros(int(le / width / SR)) + for onset in onsets: + pos = int(onset / width) + if onset >= dur - 1: + continue + if onset < 1: + continue + grid[pos - limit:pos + limit + 1] += gauss + grids.append(grid) + + shifts = [0] + for s in range(1, sources): + max_shift = int(4 / width) + dots = [] + for shift in range(-max_shift, max_shift): + other = grids[s] + ref = grids[0] + if shift >= 0: + other = other[shift:] + else: + ref = ref[shift:] + le = min(len(other), len(ref)) + dots.append((ref[:le].dot(other[:le]), int(shift * width * SR))) + + _, shift = max(dots) + shifts.append(-shift) + + outs = [] + new_zero = min(shifts) + for (wav, _), shift in zip(stems, shifts): + offset = shift - new_zero + wav = F.pad(wav, (offset, 0)) + outs.append(wav) + + le = min(x.shape[-1] for x in outs) + + outs = [w[..., :le] for w in outs] + return torch.stack(outs) + + +def find_candidate(spec_ref, catalog, pitch_match=True): + """Given reference track, this finds a track in the catalog that + is a potential match (pitch and tempo delta must be within the allowable limits). + """ + candidates = list(catalog) + random.shuffle(candidates) + + for spec in candidates: + ok = False + for scale in [1/4, 1/2, 1, 2, 4]: + tempo = spec.tempo * scale + delta_tempo = spec_ref.tempo / tempo - 1 + if abs(delta_tempo) < MAX_TEMPO: + ok = True + break + if not ok: + print(delta_tempo, spec_ref.tempo, spec.tempo, "FAILED TEMPO") + # too much of a tempo difference + continue + spec = spec._replace(tempo=tempo) + + ps = 0 + if pitch_match: + ps = best_pitch_shift(spec_ref.kr, spec.kr) + if abs(ps) > MAX_PITCH: + print("Failed pitch", ps) + # too much pitch difference + continue + return spec, delta_tempo, ps + + +def get_part(spec, source, dt, dp): + """Apply given delta of tempo and delta of pitch to a stem.""" + wav = spec.track[source] + if dt or dp: + wav = repitch(wav, dp, dt * 100, samplerate=SR, voice=source == 3) + spec = spec._replace(onsets=spec.onsets / (1 + dt)) + return wav, spec + + +def build_track(ref_index, catalog): + """Given the reference track index and a catalog of track, builds + a completely new track. One of the source at random from the ref track will + be kept and other sources will be drawn from the catalog. + """ + order = list(range(len(SOURCES))) + random.shuffle(order) + + stems = [None] * len(order) + indexes = [None] * len(order) + origs = [None] * len(order) + dps = [None] * len(order) + dts = [None] * len(order) + + first = order[0] + spec_ref = catalog[ref_index] + stems[first] = (spec_ref.track[first], spec_ref.onsets) + indexes[first] = ref_index + origs[first] = spec_ref.track[first] + dps[first] = 0 + dts[first] = 0 + + pitch_match = order != 0 + + for src in order[1:]: + spec, dt, dp = find_candidate(spec_ref, catalog, pitch_match=pitch_match) + if not pitch_match: + spec_ref = spec_ref._replace(kr=spec.kr) + pitch_match = True + dps[src] = dp + dts[src] = dt + wav, spec = get_part(spec, src, dt, dp) + stems[src] = (wav, spec.onsets) + indexes[src] = spec.index + origs.append(spec.track[src]) + print("FINAL CHOICES", ref_index, indexes, dps, dts) + stems = align_stems(stems) + return stems, origs + + +def get_musdb_dataset(part='train'): + root = Path(MUSDB_PATH) / part + ext = '.wav' + metadata = build_metadata(root, SOURCES, ext=ext, normalize=False) + valid_tracks = _get_musdb_valid() + metadata_train = {name: meta for name, meta in metadata.items() if name not in valid_tracks} + train_set = Wavset( + root, metadata_train, SOURCES, samplerate=SR, channels=CHANNELS, + normalize=False, ext=ext) + sig = hashlib.sha1(str(root).encode()).hexdigest()[:8] + train_set.sig = sig + return train_set + + +def get_wav_dataset(): + root = Path(EXTRA_WAV_PATH) + ext = '.wav' + metadata = _build_metadata(root, SOURCES, ext=ext, normalize=False) + train_set = Wavset( + root, metadata, SOURCES, samplerate=SR, channels=CHANNELS, + normalize=False, ext=ext) + sig = hashlib.sha1(str(root).encode()).hexdigest()[:8] + train_set.sig = sig + return train_set + + +def main(): + random.seed(4321) + if OUTPATH.exists(): + shutil.rmtree(OUTPATH) + OUTPATH.mkdir(exist_ok=True, parents=True) + (OUTPATH / 'train').mkdir(exist_ok=True, parents=True) + (OUTPATH / 'valid').mkdir(exist_ok=True, parents=True) + out = OUTPATH / 'train' + + dset = get_musdb_dataset() + # dset2 = get_wav_dataset() + # dset3 = get_musdb_dataset('test') + dset2 = None + dset3 = None + pendings = [] + copies = 6 + copies_rej = 2 + + with ProcessPoolExecutor(20) as pool: + for index in range(len(dset)): + pendings.append(pool.submit(analyse_track, dset, index)) + + if dset2: + for index in range(len(dset2)): + pendings.append(pool.submit(analyse_track, dset2, index)) + if dset3: + for index in range(len(dset3)): + pendings.append(pool.submit(analyse_track, dset3, index)) + + catalog = [] + rej = 0 + for pending in tqdm.tqdm(pendings, ncols=120): + spec, track = pending.result() + if spec is not None: + catalog.append(spec) + else: + mix = track.sum(0) + for copy in range(copies_rej): + folder = out / f'rej_{rej}_{copy}' + folder.mkdir() + save_audio(mix, folder / "mixture.wav", SR) + for stem, source in zip(track, SOURCES): + save_audio(stem, folder / f"{source}.wav", SR, clip='clamp') + rej += 1 + + for copy in range(copies): + for index in range(len(catalog)): + track, origs = build_track(index, catalog) + mix = track.sum(0) + mx = mix.abs().max() + scale = max(1, 1.01 * mx) + mix = mix / scale + track = track / scale + folder = out / f'{copy}_{index}' + folder.mkdir() + save_audio(mix, folder / "mixture.wav", SR) + for stem, source, orig in zip(track, SOURCES, origs): + save_audio(stem, folder / f"{source}.wav", SR, clip='clamp') + # save_audio(stem.std() * orig / (1e-6 + orig.std()), folder / f"{source}_orig.wav", + # SR, clip='clamp') + + +if __name__ == '__main__': + main() diff --git a/demucs/tools/bench.py b/demucs/tools/bench.py new file mode 100644 index 00000000..762a7c3f --- /dev/null +++ b/demucs/tools/bench.py @@ -0,0 +1,78 @@ +# Copyright (c) Meta Platforms, Inc. and affiliates. +# All rights reserved. +# +# This source code is licensed under the license found in the +# LICENSE file in the root directory of this source tree. + +""" +benchmarking script, useful to check for OOM, reasonable train time, +and for the MDX competion, estimate if we will match the time limit.""" +from contextlib import contextmanager +import logging +import sys +import time +import torch + +from demucs.train import get_solver, main +from demucs.apply import apply_model + +logging.basicConfig(level=logging.INFO, stream=sys.stderr) + + +class Result: + pass + + +@contextmanager +def bench(): + import gc + gc.collect() + torch.cuda.reset_max_memory_allocated() + torch.cuda.empty_cache() + result = Result() + # before = torch.cuda.memory_allocated() + before = 0 + begin = time.time() + try: + yield result + finally: + torch.cuda.synchronize() + mem = (torch.cuda.max_memory_allocated() - before) / 2 ** 20 + tim = time.time() - begin + result.mem = mem + result.tim = tim + + +xp = main.get_xp_from_sig(sys.argv[1]) +xp = main.get_xp(xp.argv + sys.argv[2:]) +with xp.enter(): + solver = get_solver(xp.cfg) + if getattr(solver.model, 'use_train_segment', False): + batch = solver.augment(next(iter(solver.loaders['train']))) + solver.model.segment = Fraction(batch.shape[-1], solver.model.samplerate) + train_segment = solver.model.segment + solver.model.eval() + model = solver.model + model.cuda() + x = torch.randn(2, xp.cfg.dset.channels, int(10 * model.samplerate), device='cuda') + with bench() as res: + y = model(x) + y.sum().backward() + del y + for p in model.parameters(): + p.grad = None + print(f"FB: {res.mem:.1f} MB, {res.tim * 1000:.1f} ms") + + x = torch.randn(1, xp.cfg.dset.channels, int(model.segment * model.samplerate), device='cuda') + with bench() as res: + with torch.no_grad(): + y = model(x) + del y + print(f"FV: {res.mem:.1f} MB, {res.tim * 1000:.1f} ms") + + model.cpu() + torch.set_num_threads(1) + test = torch.randn(1, xp.cfg.dset.channels, model.samplerate * 40) + b = time.time() + apply_model(model, test, split=True, shifts=1) + print("CPU 40 sec:", time.time() - b) diff --git a/demucs/tools/convert.py b/demucs/tools/convert.py new file mode 100644 index 00000000..dfc022f8 --- /dev/null +++ b/demucs/tools/convert.py @@ -0,0 +1,152 @@ +# Copyright (c) Meta Platforms, Inc. and affiliates. +# All rights reserved. +# +# This source code is licensed under the license found in the +# LICENSE file in the root directory of this source tree. + +# Script to convert option names and model args from the dev branch to +# the cleanup release one. There should be no reaso to use that anymore. + +import argparse +import io +import json +from pathlib import Path +import subprocess as sp + +import torch + +from demucs import train, pretrained, states + +DEV_REPO = Path.home() / 'tmp/release_demucs_mdx' + + +TO_REMOVE = [ + 'demucs.dconv_kw.gelu=True', + 'demucs.dconv_kw.nfreqs=0', + 'demucs.dconv_kw.nfreqs=0', + 'demucs.dconv_kw.version=4', + 'demucs.norm=gn', + 'wdemucs.nice=True', + 'wdemucs.good=True', + 'wdemucs.freq_emb=-0.2', + 'special=True', + 'special=False', +] + +TO_REPLACE = [ + ('power', 'svd'), + ('wdemucs', 'hdemucs'), + ('hdemucs.hybrid=True', 'hdemucs.hybrid_old=True'), + ('hdemucs.hybrid=2', 'hdemucs.hybrid=True'), +] + +TO_INJECT = [ + ('model=hdemucs', ['hdemucs.cac=False']), + ('model=hdemucs', ['hdemucs.norm_starts=999']), +] + + +def get_original_argv(sig): + return json.load(open(Path(DEV_REPO) / f'outputs/xps/{sig}/.argv.json')) + + +def transform(argv, mappings, verbose=False): + for rm in TO_REMOVE: + while rm in argv: + argv.remove(rm) + + for old, new in TO_REPLACE: + argv[:] = [a.replace(old, new) for a in argv] + + for condition, args in TO_INJECT: + if condition in argv: + argv[:] = args + argv + + for idx, arg in enumerate(argv): + if 'continue_from=' in arg: + dep_sig = arg.split('=')[1] + if dep_sig.startswith('"'): + dep_sig = eval(dep_sig) + if verbose: + print("Need to recursively convert dependency XP", dep_sig) + new_sig = convert(dep_sig, mappings, verbose).sig + argv[idx] = f'continue_from="{new_sig}"' + + +def convert(sig, mappings, verbose=False): + argv = get_original_argv(sig) + if verbose: + print("Original argv", argv) + transform(argv, mappings, verbose) + if verbose: + print("New argv", argv) + xp = train.main.get_xp(argv) + train.main.init_xp(xp) + if verbose: + print("Mapping", sig, "->", xp.sig) + mappings[sig] = xp.sig + return xp + + +def _eval_old(old_sig, x): + script = ( + 'from demucs import pretrained; import torch; import sys; import io; ' + 'buf = io.BytesIO(sys.stdin.buffer.read()); ' + 'x = torch.load(buf); m = pretrained.load_pretrained_model(' + f'"{old_sig}"); torch.save(m(x), sys.stdout.buffer)') + + buf = io.BytesIO() + torch.save(x, buf) + proc = sp.run( + ['python3', '-c', script], input=buf.getvalue(), capture_output=True, cwd=DEV_REPO) + if proc.returncode != 0: + print("Error", proc.stderr.decode()) + assert False + + buf = io.BytesIO(proc.stdout) + return torch.load(buf) + + +def compare(old_sig, model): + test = torch.randn(1, 2, 44100 * 10) + old_out = _eval_old(old_sig, test) + out = model(test) + + delta = 20 * torch.log10((out - old_out).norm() / out.norm()).item() + return delta + + +def main(): + torch.manual_seed(1234) + parser = argparse.ArgumentParser('convert') + parser.add_argument('sigs', nargs='*') + parser.add_argument('-o', '--output', type=Path, default=Path('release_models')) + parser.add_argument('-d', '--dump', action='store_true') + parser.add_argument('-c', '--compare', action='store_true') + parser.add_argument('-v', '--verbose', action='store_true') + args = parser.parse_args() + + args.output.mkdir(exist_ok=True, parents=True) + mappings = {} + for sig in args.sigs: + xp = convert(sig, mappings, args.verbose) + if args.dump or args.compare: + old_pkg = pretrained._load_package(sig, old=True) + model = train.get_model(xp.cfg) + model.load_state_dict(old_pkg['state']) + if args.dump: + pkg = states.serialize_model(model, xp.cfg) + states.save_with_checksum(pkg, args.output / f'{xp.sig}.th') + if args.compare: + delta = compare(sig, model) + print("Delta for", sig, xp.sig, delta) + + mappings[sig] = xp.sig + + print("FINAL MAPPINGS") + for old, new in mappings.items(): + print(old, " ", new) + + +if __name__ == '__main__': + main() diff --git a/demucs/tools/export.py b/demucs/tools/export.py new file mode 100644 index 00000000..15795855 --- /dev/null +++ b/demucs/tools/export.py @@ -0,0 +1,71 @@ +# Copyright (c) Meta Platforms, Inc. and affiliates. +# All rights reserved. +# +# This source code is licensed under the license found in the +# LICENSE file in the root directory of this source tree. + +"""Export a trained model from the full checkpoint (with optimizer etc.) to +a final checkpoint, with only the model itself. The model is always stored as +half float to gain space, and because this has zero impact on the final loss. +When DiffQ was used for training, the model will actually be quantized and bitpacked.""" +from argparse import ArgumentParser +from fractions import Fraction +import logging +from pathlib import Path +import sys +import torch + +from demucs import train +from demucs.states import serialize_model, save_with_checksum + + +logger = logging.getLogger(__name__) + + +def main(): + logging.basicConfig(level=logging.INFO, stream=sys.stderr) + + parser = ArgumentParser("tools.export", description="Export trained models from XP sigs.") + parser.add_argument('signatures', nargs='*', help='XP signatures.') + parser.add_argument('-o', '--out', type=Path, default=Path("release_models"), + help="Path where to store release models (default release_models)") + parser.add_argument('-s', '--sign', action='store_true', + help='Add sha256 prefix checksum to the filename.') + + args = parser.parse_args() + args.out.mkdir(exist_ok=True, parents=True) + + for sig in args.signatures: + xp = train.main.get_xp_from_sig(sig) + name = train.main.get_name(xp) + logger.info('Handling %s/%s', sig, name) + + out_path = args.out / (sig + ".th") + + solver = train.get_solver_from_sig(sig) + if len(solver.history) < solver.args.epochs: + logger.warning( + 'Model %s has less epoch than expected (%d / %d)', + sig, len(solver.history), solver.args.epochs) + + solver.model.load_state_dict(solver.best_state) + pkg = serialize_model(solver.model, solver.args, solver.quantizer, half=True) + if getattr(solver.model, 'use_train_segment', False): + batch = solver.augment(next(iter(solver.loaders['train']))) + pkg['kwargs']['segment'] = Fraction(batch.shape[-1], solver.model.samplerate) + print("Override", pkg['kwargs']['segment']) + valid, test = None, None + for m in solver.history: + if 'valid' in m: + valid = m['valid'] + if 'test' in m: + test = m['test'] + pkg['metrics'] = (valid, test) + if args.sign: + save_with_checksum(pkg, out_path) + else: + torch.save(pkg, out_path) + + +if __name__ == '__main__': + main() diff --git a/demucs/tools/test_pretrained.py b/demucs/tools/test_pretrained.py new file mode 100644 index 00000000..fb80cf5a --- /dev/null +++ b/demucs/tools/test_pretrained.py @@ -0,0 +1,43 @@ +# Copyright (c) Meta Platforms, Inc. and affiliates. +# All rights reserved. +# +# This source code is licensed under the license found in the +# LICENSE file in the root directory of this source tree. + +# Script to evaluate pretrained models. + +from argparse import ArgumentParser +import logging +import sys + +import torch + +from demucs import train, pretrained, evaluate + + +def main(): + torch.set_num_threads(1) + logging.basicConfig(stream=sys.stderr, level=logging.INFO) + parser = ArgumentParser("tools.test_pretrained", + description="Evaluate pre-trained models or bags of models " + "on MusDB.") + pretrained.add_model_flags(parser) + parser.add_argument('overrides', nargs='*', + help='Extra overrides, e.g. test.shifts=2.') + args = parser.parse_args() + + xp = train.main.get_xp(args.overrides) + with xp.enter(): + solver = train.get_solver(xp.cfg) + + model = pretrained.get_model_from_args(args) + solver.model = model.to(solver.device) + solver.model.eval() + + with torch.no_grad(): + results = evaluate.evaluate(solver, xp.cfg.test.sdr) + print(results) + + +if __name__ == '__main__': + main() diff --git a/docs/docs/preferences.md b/docs/docs/preferences.md index 9ef6dfb1..1e48e9de 100644 --- a/docs/docs/preferences.md +++ b/docs/docs/preferences.md @@ -100,7 +100,7 @@ combined to produce the final answer. **BUZZ_TRANSLATION_API_KEY** - Api key of OpenAI compatible API to use for translation. -**BUZZ_MODEL_ROOT** - Root directory to store model files. +**BUZZ_MODEL_ROOT** - Root directory to store model files. You may also want to set `HF_HOME` to the same folder as some libraries used in Buzz download their models independently. Defaults to [user_cache_dir](https://pypi.org/project/platformdirs/). **BUZZ_FAVORITE_LANGUAGES** - Coma separated list of supported language codes to show on top of language list. diff --git a/docs/docs/usage/1_file_import.md b/docs/docs/usage/1_file_import.md index 91ccc672..a811fddc 100644 --- a/docs/docs/usage/1_file_import.md +++ b/docs/docs/usage/1_file_import.md @@ -25,3 +25,5 @@ To reduce misspellings you can pass some commonly misspelled words in an `Initia (See the [Live Recording section](https://chidiwilliams.github.io/buzz/docs/usage/live_recording) for more information about the task, language, and quality settings.) [![Media File Import on Buzz](https://cdn.loom.com/sessions/thumbnails/cf263b099ac3481082bb56d19b7c87fe-with-play.gif)](https://www.loom.com/share/cf263b099ac3481082bb56d19b7c87fe "Media File Import on Buzz") + +**💡 Tip:** It is recommended to always select language to transcribe to as automatic language detection may result in unexpected results. diff --git a/docs/docs/usage/5_speaker_identification.md b/docs/docs/usage/5_speaker_identification.md new file mode 100644 index 00000000..72dc7ee6 --- /dev/null +++ b/docs/docs/usage/5_speaker_identification.md @@ -0,0 +1,9 @@ +--- +title: Speaker identification +--- + +When transcript of some audio or video file is generated you can identify speakers in the transcript. Double-click the transcript in the list of transcripts to see additional options for editing and exporting. + +Transcription view screen has option to identify speakers. Click on the "Identify speakers" button so see available options. + +If audio file is still present on the system speaker identification will mark each speakers sentences with appropriate label. You can preview 10 seconds of some random sentence of the identified speaker and rename the automatically identified label to speakers real name. If "Merge speaker sentences" checkbox is selected when you save the speaker labels, all consecutive sentences of the same speaker will be merged into one segment. Speaker identification is available since version 1.4.0 on all platforms except Intel macOS. \ No newline at end of file diff --git a/flatpak/run-buzz.sh b/flatpak/run-buzz.sh index fa136c3b..f32217ec 100644 --- a/flatpak/run-buzz.sh +++ b/flatpak/run-buzz.sh @@ -1,3 +1,5 @@ #!/bin/sh echo "Running buzz..." +echo "Note: ffmpeg errors are safe to ignore" + python -m buzz \ No newline at end of file diff --git a/hatch_build.py b/hatch_build.py index b3469d36..d95e4c66 100644 --- a/hatch_build.py +++ b/hatch_build.py @@ -79,6 +79,21 @@ class CustomBuildHook(BuildHookInterface): print(result.stderr, file=sys.stderr) print("Successfully compiled translation files") + # Build ctc_forced_aligner C++ extension in-place + print("Building ctc_forced_aligner C++ extension...") + ctc_aligner_dir = project_root / "ctc_forced_aligner" + result = subprocess.run( + [sys.executable, "setup.py", "build_ext", "--inplace"], + cwd=ctc_aligner_dir, + check=True, + capture_output=True, + text=True + ) + print(result.stdout) + if result.stderr: + print(result.stderr, file=sys.stderr) + print("Successfully built ctc_forced_aligner C++ extension") + # Force include all files in buzz/whisper_cpp directory whisper_cpp_dir = project_root / "buzz" / "whisper_cpp" if whisper_cpp_dir.exists(): @@ -142,6 +157,28 @@ class CustomBuildHook(BuildHookInterface): else: print(f"Warning: {locale_dir} does not exist", file=sys.stderr) + # Force include compiled extensions from ctc_forced_aligner + ctc_aligner_pkg = project_root / "ctc_forced_aligner" / "ctc_forced_aligner" + if ctc_aligner_pkg.exists(): + # Get all compiled extension files (.so, .pyd, .dll) + extension_patterns = ["*.so", "*.pyd", "*.dll"] + extension_files = [] + for pattern in extension_patterns: + extension_files.extend(glob.glob(str(ctc_aligner_pkg / pattern))) + + # Add them to force_include + if 'force_include' not in build_data: + build_data['force_include'] = {} + + for file_path in extension_files: + # Convert to relative path from project root + rel_path = Path(file_path).relative_to(project_root) + build_data['force_include'][str(rel_path)] = str(rel_path) + + print(f"Force including {len(extension_files)} compiled extension(s) from ctc_forced_aligner/") + else: + print(f"Warning: {ctc_aligner_pkg} does not exist", file=sys.stderr) + except subprocess.CalledProcessError as e: print(f"Error building whisper.cpp: {e}", file=sys.stderr) print(f"stdout: {e.stdout}", file=sys.stderr) diff --git a/pyproject.toml b/pyproject.toml index 094ffccd..90c8ce6e 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -1,6 +1,7 @@ [project] name = "buzz-captions" -version = "1.3.4" +# Change also in Makefile and buzz/__version__.py +version = "1.4.0" description = "" authors = [{ name = "Chidi Williams", email = "williamschidi1@gmail.com" }] requires-python = ">=3.12,<3.13" @@ -62,6 +63,11 @@ dependencies = [ "hf-xet>=1.1.5,<2", "hatchling>=1.27.0", "cmake>=3.31.6", + "nemo-toolkit[asr]>=2.5.3; sys_platform != 'darwin' or platform_machine != 'x86_64'", + "nltk>=3.9.2", + "uroman>=1.3.1.1", + "lhotse==1.31.1", + "coverage==7.6.1", ] repository = "https://github.com/chidiwilliams/buzz" documentation = "https://chidiwilliams.github.io/buzz/docs" @@ -131,6 +137,9 @@ include = [ "buzz/whisper_cpp/*", "buzz/locale/*/LC_MESSAGES/buzz.mo", "demucs", + "whisper_diarization", + "deepmultilingualpunctuation", + "ctc_forced_aligner", ] [tool.hatch.build.targets.wheel] @@ -139,12 +148,15 @@ include = [ "buzz/whisper_cpp/*", "buzz/locale/*/LC_MESSAGES/buzz.mo", "demucs", + "whisper_diarization", + "deepmultilingualpunctuation", + "ctc_forced_aligner", ] [tool.hatch.build.hooks.custom] [build-system] -requires = ["hatchling", "cmake>=3.26.4,<4", "polib>=1.2.0,<2"] +requires = ["hatchling", "cmake>=3.26.4,<4", "polib>=1.2.0,<2", "pybind11", "setuptools>=42"] build-backend = "hatchling.build" [tool.ruff] diff --git a/pytest.ini b/pytest.ini index abd57212..36fdeb2a 100644 --- a/pytest.ini +++ b/pytest.ini @@ -7,5 +7,6 @@ log_date_format = %Y-%m-%d %H:%M:%S addopts = -x -p no:xdist -p no:pytest_parallel timeout = 600 timeout_method = thread +testpaths = tests markers = timeout: set a timeout on a test function. \ No newline at end of file diff --git a/share/applications/buzz.desktop b/share/applications/buzz.desktop new file mode 100644 index 00000000..1e8cf81d --- /dev/null +++ b/share/applications/buzz.desktop @@ -0,0 +1,17 @@ +[Desktop Entry] + +Type=Application + +Encoding=UTF-8 + +Name=Buzz + +Comment=Buzz transcribes and translates audio offline on your personal computer. + +Path=/opt/buzz + +Exec=/opt/buzz/Buzz + +Icon=buzz + +Terminal=false diff --git a/snap/snapcraft.yaml b/snap/snapcraft.yaml index 53cc91db..b574b1ae 100644 --- a/snap/snapcraft.yaml +++ b/snap/snapcraft.yaml @@ -80,15 +80,10 @@ parts: - libportaudio2 - libpulse0 - libasound2 + - libasound2-dev - libasound2-plugins - libasound2-plugins-extra - libyaml-dev - - gstreamer1.0-plugins-good - - gstreamer1.0-plugins-base-apps - - gstreamer1.0-pulseaudio - - libgstreamer1.0-0 - - libgstreamer-plugins-base1.0-0 - - libgstreamer-plugins-good1.0-0 - liboss4-salsa2 # Display - libxkbcommon-x11-0 @@ -121,7 +116,10 @@ parts: # Copy source files cp -r $CRAFT_PART_BUILD/buzz $CRAFT_PART_INSTALL/ + cp -r $CRAFT_PART_BUILD/ctc_forced_aligner $CRAFT_PART_INSTALL/ + cp -r $CRAFT_PART_BUILD/deepmultilingualpunctuation $CRAFT_PART_INSTALL/ cp -r $CRAFT_PART_BUILD/demucs $CRAFT_PART_INSTALL/ + cp -r $CRAFT_PART_BUILD/whisper_diarization $CRAFT_PART_INSTALL/ # Create desktop file mkdir -p $CRAFT_PART_INSTALL/usr/share/applications @@ -155,7 +153,7 @@ apps: PATH: $SNAP/usr/bin:$SNAP/bin:$PATH LD_LIBRARY_PATH: $SNAP/lib/python3.12/site-packages/nvidia/cudnn/lib:$SNAP/lib/python3.12/site-packages/PyQt6:$SNAP/lib/python3.12/site-packages/PyQt6/Qt6/lib:$SNAP/usr/lib/$CRAFT_ARCH_TRIPLET_BUILD_FOR/lapack:$SNAP/usr/lib/$CRAFT_ARCH_TRIPLET_BUILD_FOR/blas:$SNAP/usr/lib/$CRAFT_ARCH_TRIPLET_BUILD_FOR/oss4-libsalsa:$SNAP/usr/lib/$CRAFT_ARCH_TRIPLET_BUILD_FOR/libproxy:$SNAP:$LD_LIBRARY_PATH PYTHONPATH: $SNAP:$SNAP/lib/python3.12/site-packages/PyQt6:$SNAP/lib/python3.12/site-packages/PyQt6/Qt6/lib:$SNAP/usr/lib/python3/dist-packages:$SNAP/usr/lib/python3.12/site-packages:$SNAP/usr/local/lib/python3.12/dist-packages:$SNAP/usr/lib/python3.12/dist-packages:$PYTHONPATH - QT_MEDIA_BACKEND: gstreamer + QT_MEDIA_BACKEND: ffmpeg PULSE_LATENCY_MSEC: "30" ALSA_CONFIG_PATH: $SNAP/etc/asound.conf plugs: diff --git a/tests/gui_test.py b/tests/gui_test.py index e4ebfb9a..a5e7fda6 100644 --- a/tests/gui_test.py +++ b/tests/gui_test.py @@ -34,7 +34,10 @@ from tests.mock_sounddevice import MockInputStream, mock_query_devices from .mock_qt import MockNetworkAccessManager, MockNetworkReply if platform.system() == "Linux": - multiprocessing.set_start_method("spawn") + try: + multiprocessing.set_start_method("spawn", force=True) + except RuntimeError: + pass @pytest.fixture(scope="module", autouse=True) diff --git a/tests/transcriber/file_transcriber_queue_worker_test.py b/tests/transcriber/file_transcriber_queue_worker_test.py index e48bccb9..da351ee2 100644 --- a/tests/transcriber/file_transcriber_queue_worker_test.py +++ b/tests/transcriber/file_transcriber_queue_worker_test.py @@ -70,10 +70,10 @@ def test_transcription_with_whisper_cpp_tiny_with_speech_extraction(worker): task = FileTranscriptionTask(file_path=str(test_multibyte_utf8_audio_path), transcription_options=options, file_transcription_options=FileTranscriptionOptions(), model_path="mock_path") - with unittest.mock.patch('demucs.api.Separator') as mock_separator_class, \ - unittest.mock.patch('demucs.api.save_audio') as mock_save_audio, \ + with unittest.mock.patch('demucs.demucs.api.Separator') as mock_separator_class, \ + unittest.mock.patch('demucs.demucs.api.save_audio') as mock_save_audio, \ unittest.mock.patch.object(WhisperFileTranscriber, 'run') as mock_run: - # Mock demucs.api.Separator and save_audio + # Mock demucs.demucs.api.Separator and save_audio mock_separator_instance = unittest.mock.Mock() mock_separator_instance.separate_audio_file.return_value = (None, {"vocals": "mock_vocals_data"}) mock_separator_instance.samplerate = 44100 diff --git a/tests/transcriber/whisper_cpp_test.py b/tests/transcriber/whisper_cpp_test.py index 722db718..203421fc 100644 --- a/tests/transcriber/whisper_cpp_test.py +++ b/tests/transcriber/whisper_cpp_test.py @@ -58,5 +58,5 @@ class TestWhisperCpp: segments = WhisperCpp.transcribe(task=task) assert "Mani" in segments[0].text - assert "uzstrau" in segments[1].text + assert "uzstrau" or "ustrau" in segments[1].text assert "laikabstāk" in segments[2].text \ No newline at end of file diff --git a/tests/widgets/speaker_identification_widget_test.py b/tests/widgets/speaker_identification_widget_test.py new file mode 100644 index 00000000..946948dc --- /dev/null +++ b/tests/widgets/speaker_identification_widget_test.py @@ -0,0 +1,90 @@ +import logging +import platform +import time +import uuid +import pytest +from pytestqt.qtbot import QtBot +from unittest.mock import MagicMock, patch +from buzz.db.entity.transcription import Transcription +from buzz.db.entity.transcription_segment import TranscriptionSegment +from buzz.model_loader import ModelType, WhisperModelSize +from buzz.transcriber.transcriber import Task +# Underlying libs do not support intel Macs +if not (platform.system() == "Darwin" and platform.machine() == "x86_64"): + from buzz.widgets.transcription_viewer.speaker_identification_widget import ( + SpeakerIdentificationWidget, + IdentificationWorker, + ) +from tests.audio import test_audio_path + +@pytest.mark.skipif( + platform.system() == "Darwin" and platform.machine() == "x86_64", + reason="Skip speaker identification tests on macOS x86_64" +) +class TestSpeakerIdentificationWidget: + @pytest.fixture() + def transcription( + self, transcription_dao, transcription_segment_dao + ) -> Transcription: + id = uuid.uuid4() + transcription_dao.insert( + Transcription( + id=str(id), + status="completed", + file=test_audio_path, + task=Task.TRANSCRIBE.value, + model_type=ModelType.WHISPER.value, + whisper_model_size=WhisperModelSize.SMALL.value, + ) + ) + transcription_segment_dao.insert(TranscriptionSegment(40, 299, "Bien", "", str(id))) + transcription_segment_dao.insert( + TranscriptionSegment(299, 329, "venue dans", "", str(id)) + ) + + return transcription_dao.find_by_id(str(id)) + + def test_widget_initialization(self, qtbot: QtBot, transcription, transcription_service): + """Test the initialization of SpeakerIdentificationWidget.""" + widget = SpeakerIdentificationWidget( + transcription=transcription, + transcription_service=transcription_service, + ) + qtbot.addWidget(widget) + + assert widget.transcription == transcription + assert widget.transcription_service == transcription_service + assert widget.progress_bar.value() == 0 + + widget.close() + + # Wait to clean-up threads + time.sleep(3) + + @pytest.mark.skipif( + platform.system() == "Linux", + reason="Skip speaker identification worker test on Linux, CI freezes" + ) + @patch("buzz.widgets.transcription_viewer.speaker_identification_widget.IdentificationWorker") + def test_identification_worker_run(self, qtbot: QtBot, transcription, transcription_service): + """Test the IdentificationWorker's run method and capture the finished signal result.""" + worker = IdentificationWorker( + transcription=transcription, + transcription_service=transcription_service, + ) + + result = [] + + def capture_result(data): + result.append(data) + + worker.finished.connect(capture_result) + + with qtbot.waitSignal(worker.finished, timeout= 300000): #5 min timeout + worker.run() + + assert worker.transcription == transcription + assert len(result) == 1 + assert isinstance(result[0], list) + assert result == [[{'end_time': 8904, 'speaker': 'Speaker 0', 'start_time': 140, 'text': 'Bienvenue dans. '}]] + diff --git a/tests/widgets/transcription_viewer_test.py b/tests/widgets/transcription_viewer_test.py index 13d87bc8..a688c40b 100644 --- a/tests/widgets/transcription_viewer_test.py +++ b/tests/widgets/transcription_viewer_test.py @@ -202,9 +202,7 @@ class TestTranscriptionViewerWidget: return_value=mock_result) as mock_transcribe_any, \ patch( 'buzz.widgets.transcription_viewer.transcription_resizer_widget.whisper_audio.load_audio') as mock_load_audio: - result_ready_spy = MagicMock() finished_spy = MagicMock() - worker.result_ready.connect(result_ready_spy) worker.finished.connect(finished_spy) worker.run() @@ -220,15 +218,13 @@ class TestTranscriptionViewerWidget: assert call_kwargs['vad'] is False assert call_kwargs['suppress_silence'] is False - result_ready_spy.assert_called_once() - emitted_segments = result_ready_spy.call_args[0][0] + finished_spy.assert_called_once() + emitted_segments = finished_spy.call_args[0][0] assert len(emitted_segments) == 1 assert emitted_segments[0].start == 100 assert emitted_segments[0].end == 200 assert emitted_segments[0].text == "Hello" - finished_spy.assert_called_once() - # TODO - Fix this test on Windows, should work. # Possibly the `on_loop_toggle_changed` gets triggered on setChecked @pytest.mark.skipif(sys.platform.startswith("win"), reason="Skipping on Windows") diff --git a/uv.lock b/uv.lock index 0c326aa8..644e35b9 100644 --- a/uv.lock +++ b/uv.lock @@ -5,10 +5,20 @@ resolution-markers = [ "platform_machine == 'x86_64' and sys_platform == 'darwin'", "platform_machine == 'arm64' and sys_platform == 'darwin'", "platform_machine != 'arm64' and platform_machine != 'x86_64' and sys_platform == 'darwin'", - "(platform_machine != 'aarch64' and sys_platform == 'linux') or (platform_python_implementation != 'CPython' and sys_platform == 'linux') or (sys_platform != 'darwin' and sys_platform != 'linux')", + "(platform_machine != 'aarch64' and sys_platform == 'linux') or (platform_python_implementation != 'CPython' and sys_platform == 'linux')", + "sys_platform != 'darwin' and sys_platform != 'linux'", "platform_machine == 'aarch64' and platform_python_implementation == 'CPython' and sys_platform == 'linux'", ] +[[package]] +name = "absl-py" +version = "2.3.1" +source = { registry = "https://pypi.org/simple/" } +sdist = { url = "https://files.pythonhosted.org/packages/10/2a/c93173ffa1b39c1d0395b7e842bbdc62e556ca9d8d3b5572926f3e4ca752/absl_py-2.3.1.tar.gz", hash = "sha256:a97820526f7fbfd2ec1bce83f3f25e3a14840dac0d8e02a0b71cd75db3f77fc9", size = 116588, upload-time = "2025-07-03T09:31:44.05Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/8f/aa/ba0014cc4659328dc818a28827be78e6d97312ab0cb98105a770924dc11e/absl_py-2.3.1-py3-none-any.whl", hash = "sha256:eeecf07f0c2a93ace0772c92e596ace6d3d3996c042b2128459aaae2a76de11d", size = 135811, upload-time = "2025-07-03T09:31:42.253Z" }, +] + [[package]] name = "accelerate" version = "1.11.0" @@ -29,6 +39,76 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/77/85/85951bc0f9843e2c10baaa1b6657227056095de08f4d1eea7d8b423a6832/accelerate-1.11.0-py3-none-any.whl", hash = "sha256:a628fa6beb069b8e549460fc449135d5bd8d73e7a11fd09f0bc9fc4ace7f06f1", size = 375777, upload-time = "2025-10-20T14:42:23.256Z" }, ] +[[package]] +name = "aiohappyeyeballs" +version = "2.6.1" +source = { registry = "https://pypi.org/simple/" } +sdist = { url = "https://files.pythonhosted.org/packages/26/30/f84a107a9c4331c14b2b586036f40965c128aa4fee4dda5d3d51cb14ad54/aiohappyeyeballs-2.6.1.tar.gz", hash = "sha256:c3f9d0113123803ccadfdf3f0faa505bc78e6a72d1cc4806cbd719826e943558", size = 22760, upload-time = "2025-03-12T01:42:48.764Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/0f/15/5bf3b99495fb160b63f95972b81750f18f7f4e02ad051373b669d17d44f2/aiohappyeyeballs-2.6.1-py3-none-any.whl", hash = "sha256:f349ba8f4b75cb25c99c5c2d84e997e485204d2902a9597802b0371f09331fb8", size = 15265, upload-time = "2025-03-12T01:42:47.083Z" }, +] + +[[package]] +name = "aiohttp" +version = "3.13.2" +source = { registry = "https://pypi.org/simple/" } +dependencies = [ + { name = "aiohappyeyeballs", marker = "platform_machine != 'x86_64' or sys_platform != 'darwin'" }, + { name = "aiosignal", marker = "platform_machine != 'x86_64' or sys_platform != 'darwin'" }, + { name = "attrs", marker = "platform_machine != 'x86_64' or sys_platform != 'darwin'" }, + { name = "frozenlist", marker = "platform_machine != 'x86_64' or sys_platform != 'darwin'" }, + { name = "multidict", marker = "platform_machine != 'x86_64' or sys_platform != 'darwin'" }, + { name = "propcache", marker = "platform_machine != 'x86_64' or sys_platform != 'darwin'" }, + { name = "yarl", marker = "platform_machine != 'x86_64' or sys_platform != 'darwin'" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/1c/ce/3b83ebba6b3207a7135e5fcaba49706f8a4b6008153b4e30540c982fae26/aiohttp-3.13.2.tar.gz", hash = "sha256:40176a52c186aefef6eb3cad2cdd30cd06e3afbe88fe8ab2af9c0b90f228daca", size = 7837994, upload-time = "2025-10-28T20:59:39.937Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/29/9b/01f00e9856d0a73260e86dd8ed0c2234a466c5c1712ce1c281548df39777/aiohttp-3.13.2-cp312-cp312-macosx_10_13_universal2.whl", hash = "sha256:b1e56bab2e12b2b9ed300218c351ee2a3d8c8fdab5b1ec6193e11a817767e47b", size = 737623, upload-time = "2025-10-28T20:56:30.797Z" }, + { url = "https://files.pythonhosted.org/packages/5a/1b/4be39c445e2b2bd0aab4ba736deb649fabf14f6757f405f0c9685019b9e9/aiohttp-3.13.2-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:364e25edaabd3d37b1db1f0cbcee8c73c9a3727bfa262b83e5e4cf3489a2a9dc", size = 492664, upload-time = "2025-10-28T20:56:32.708Z" }, + { url = "https://files.pythonhosted.org/packages/28/66/d35dcfea8050e131cdd731dff36434390479b4045a8d0b9d7111b0a968f1/aiohttp-3.13.2-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:c5c94825f744694c4b8db20b71dba9a257cd2ba8e010a803042123f3a25d50d7", size = 491808, upload-time = "2025-10-28T20:56:34.57Z" }, + { url = "https://files.pythonhosted.org/packages/00/29/8e4609b93e10a853b65f8291e64985de66d4f5848c5637cddc70e98f01f8/aiohttp-3.13.2-cp312-cp312-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:ba2715d842ffa787be87cbfce150d5e88c87a98e0b62e0f5aa489169a393dbbb", size = 1738863, upload-time = "2025-10-28T20:56:36.377Z" }, + { url = "https://files.pythonhosted.org/packages/9d/fa/4ebdf4adcc0def75ced1a0d2d227577cd7b1b85beb7edad85fcc87693c75/aiohttp-3.13.2-cp312-cp312-manylinux2014_armv7l.manylinux_2_17_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:585542825c4bc662221fb257889e011a5aa00f1ae4d75d1d246a5225289183e3", size = 1700586, upload-time = "2025-10-28T20:56:38.034Z" }, + { url = "https://files.pythonhosted.org/packages/da/04/73f5f02ff348a3558763ff6abe99c223381b0bace05cd4530a0258e52597/aiohttp-3.13.2-cp312-cp312-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:39d02cb6025fe1aabca329c5632f48c9532a3dabccd859e7e2f110668972331f", size = 1768625, upload-time = "2025-10-28T20:56:39.75Z" }, + { url = "https://files.pythonhosted.org/packages/f8/49/a825b79ffec124317265ca7d2344a86bcffeb960743487cb11988ffb3494/aiohttp-3.13.2-cp312-cp312-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:e67446b19e014d37342f7195f592a2a948141d15a312fe0e700c2fd2f03124f6", size = 1867281, upload-time = "2025-10-28T20:56:41.471Z" }, + { url = "https://files.pythonhosted.org/packages/b9/48/adf56e05f81eac31edcfae45c90928f4ad50ef2e3ea72cb8376162a368f8/aiohttp-3.13.2-cp312-cp312-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:4356474ad6333e41ccefd39eae869ba15a6c5299c9c01dfdcfdd5c107be4363e", size = 1752431, upload-time = "2025-10-28T20:56:43.162Z" }, + { url = "https://files.pythonhosted.org/packages/30/ab/593855356eead019a74e862f21523db09c27f12fd24af72dbc3555b9bfd9/aiohttp-3.13.2-cp312-cp312-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:eeacf451c99b4525f700f078becff32c32ec327b10dcf31306a8a52d78166de7", size = 1562846, upload-time = "2025-10-28T20:56:44.85Z" }, + { url = "https://files.pythonhosted.org/packages/39/0f/9f3d32271aa8dc35036e9668e31870a9d3b9542dd6b3e2c8a30931cb27ae/aiohttp-3.13.2-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:d8a9b889aeabd7a4e9af0b7f4ab5ad94d42e7ff679aaec6d0db21e3b639ad58d", size = 1699606, upload-time = "2025-10-28T20:56:46.519Z" }, + { url = "https://files.pythonhosted.org/packages/2c/3c/52d2658c5699b6ef7692a3f7128b2d2d4d9775f2a68093f74bca06cf01e1/aiohttp-3.13.2-cp312-cp312-musllinux_1_2_armv7l.whl", hash = "sha256:fa89cb11bc71a63b69568d5b8a25c3ca25b6d54c15f907ca1c130d72f320b76b", size = 1720663, upload-time = "2025-10-28T20:56:48.528Z" }, + { url = "https://files.pythonhosted.org/packages/9b/d4/8f8f3ff1fb7fb9e3f04fcad4e89d8a1cd8fc7d05de67e3de5b15b33008ff/aiohttp-3.13.2-cp312-cp312-musllinux_1_2_ppc64le.whl", hash = "sha256:8aa7c807df234f693fed0ecd507192fc97692e61fee5702cdc11155d2e5cadc8", size = 1737939, upload-time = "2025-10-28T20:56:50.77Z" }, + { url = "https://files.pythonhosted.org/packages/03/d3/ddd348f8a27a634daae39a1b8e291ff19c77867af438af844bf8b7e3231b/aiohttp-3.13.2-cp312-cp312-musllinux_1_2_riscv64.whl", hash = "sha256:9eb3e33fdbe43f88c3c75fa608c25e7c47bbd80f48d012763cb67c47f39a7e16", size = 1555132, upload-time = "2025-10-28T20:56:52.568Z" }, + { url = "https://files.pythonhosted.org/packages/39/b8/46790692dc46218406f94374903ba47552f2f9f90dad554eed61bfb7b64c/aiohttp-3.13.2-cp312-cp312-musllinux_1_2_s390x.whl", hash = "sha256:9434bc0d80076138ea986833156c5a48c9c7a8abb0c96039ddbb4afc93184169", size = 1764802, upload-time = "2025-10-28T20:56:54.292Z" }, + { url = "https://files.pythonhosted.org/packages/ba/e4/19ce547b58ab2a385e5f0b8aa3db38674785085abcf79b6e0edd1632b12f/aiohttp-3.13.2-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:ff15c147b2ad66da1f2cbb0622313f2242d8e6e8f9b79b5206c84523a4473248", size = 1719512, upload-time = "2025-10-28T20:56:56.428Z" }, + { url = "https://files.pythonhosted.org/packages/70/30/6355a737fed29dcb6dfdd48682d5790cb5eab050f7b4e01f49b121d3acad/aiohttp-3.13.2-cp312-cp312-win32.whl", hash = "sha256:27e569eb9d9e95dbd55c0fc3ec3a9335defbf1d8bc1d20171a49f3c4c607b93e", size = 426690, upload-time = "2025-10-28T20:56:58.736Z" }, + { url = "https://files.pythonhosted.org/packages/0a/0d/b10ac09069973d112de6ef980c1f6bb31cb7dcd0bc363acbdad58f927873/aiohttp-3.13.2-cp312-cp312-win_amd64.whl", hash = "sha256:8709a0f05d59a71f33fd05c17fc11fcb8c30140506e13c2f5e8ee1b8964e1b45", size = 453465, upload-time = "2025-10-28T20:57:00.795Z" }, +] + +[[package]] +name = "aiosignal" +version = "1.4.0" +source = { registry = "https://pypi.org/simple/" } +dependencies = [ + { name = "frozenlist", marker = "platform_machine != 'x86_64' or sys_platform != 'darwin'" }, + { name = "typing-extensions", marker = "platform_machine != 'x86_64' or sys_platform != 'darwin'" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/61/62/06741b579156360248d1ec624842ad0edf697050bbaf7c3e46394e106ad1/aiosignal-1.4.0.tar.gz", hash = "sha256:f47eecd9468083c2029cc99945502cb7708b082c232f9aca65da147157b251c7", size = 25007, upload-time = "2025-07-03T22:54:43.528Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/fb/76/641ae371508676492379f16e2fa48f4e2c11741bd63c48be4b12a6b09cba/aiosignal-1.4.0-py3-none-any.whl", hash = "sha256:053243f8b92b990551949e63930a839ff0cf0b0ebbe0597b0f3fb19e1a0fe82e", size = 7490, upload-time = "2025-07-03T22:54:42.156Z" }, +] + +[[package]] +name = "alembic" +version = "1.17.2" +source = { registry = "https://pypi.org/simple/" } +dependencies = [ + { name = "mako", marker = "platform_machine != 'x86_64' or sys_platform != 'darwin'" }, + { name = "sqlalchemy", marker = "platform_machine != 'x86_64' or sys_platform != 'darwin'" }, + { name = "typing-extensions", marker = "platform_machine != 'x86_64' or sys_platform != 'darwin'" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/02/a6/74c8cadc2882977d80ad756a13857857dbcf9bd405bc80b662eb10651282/alembic-1.17.2.tar.gz", hash = "sha256:bbe9751705c5e0f14877f02d46c53d10885e377e3d90eda810a016f9baa19e8e", size = 1988064, upload-time = "2025-11-14T20:35:04.057Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/ba/88/6237e97e3385b57b5f1528647addea5cc03d4d65d5979ab24327d41fb00d/alembic-1.17.2-py3-none-any.whl", hash = "sha256:f483dd1fe93f6c5d49217055e4d15b905b425b6af906746abb35b69c1996c4e6", size = 248554, upload-time = "2025-11-14T20:35:05.699Z" }, +] + [[package]] name = "altgraph" version = "0.17.4" @@ -80,6 +160,15 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/16/b6/c0b5394ec6149e0129421f1a762b805e0e583974bc3cd65e3c7ce7c95444/astroid-2.15.8-py3-none-any.whl", hash = "sha256:1aa149fc5c6589e3d0ece885b4491acd80af4f087baafa3fb5203b113e68cd3c", size = 278329, upload-time = "2023-09-26T12:40:25.988Z" }, ] +[[package]] +name = "asttokens" +version = "3.0.1" +source = { registry = "https://pypi.org/simple/" } +sdist = { url = "https://files.pythonhosted.org/packages/be/a5/8e3f9b6771b0b408517c82d97aed8f2036509bc247d46114925e32fe33f0/asttokens-3.0.1.tar.gz", hash = "sha256:71a4ee5de0bde6a31d64f6b13f2293ac190344478f081c3d1bccfcf5eacb0cb7", size = 62308, upload-time = "2025-11-15T16:43:48.578Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/d2/39/e7eaf1799466a4aef85b6a4fe7bd175ad2b1c6345066aa33f1f58d4b18d0/asttokens-3.0.1-py3-none-any.whl", hash = "sha256:15a3ebc0f43c2d0a50eeafea25e19046c68398e487b9f1f5b517f7c0f40f976a", size = 27047, upload-time = "2025-11-15T16:43:16.109Z" }, +] + [[package]] name = "attrs" version = "25.4.0" @@ -89,6 +178,15 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/3a/2a/7cc015f5b9f5db42b7d48157e23356022889fc354a2813c15934b7cb5c0e/attrs-25.4.0-py3-none-any.whl", hash = "sha256:adcf7e2a1fb3b36ac48d97835bb6d8ade15b8dcce26aba8bf1d14847b57a3373", size = 67615, upload-time = "2025-10-06T13:54:43.17Z" }, ] +[[package]] +name = "audioread" +version = "3.1.0" +source = { registry = "https://pypi.org/simple/" } +sdist = { url = "https://files.pythonhosted.org/packages/a1/4a/874ecf9b472f998130c2b5e145dcdb9f6131e84786111489103b66772143/audioread-3.1.0.tar.gz", hash = "sha256:1c4ab2f2972764c896a8ac61ac53e261c8d29f0c6ccd652f84e18f08a4cab190", size = 20082, upload-time = "2025-10-26T19:44:13.484Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/7e/16/fbe8e1e185a45042f7cd3a282def5bb8d95bb69ab9e9ef6a5368aa17e426/audioread-3.1.0-py3-none-any.whl", hash = "sha256:b30d1df6c5d3de5dcef0fb0e256f6ea17bdcf5f979408df0297d8a408e2971b4", size = 23143, upload-time = "2025-10-26T19:44:12.016Z" }, +] + [[package]] name = "autopep8" version = "1.7.0" @@ -126,13 +224,36 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/df/73/b6e24bd22e6720ca8ee9a85a0c4a2971af8497d8f3193fa05390cbd46e09/backoff-2.2.1-py3-none-any.whl", hash = "sha256:63579f9a0628e06278f7e47b7d7d5b6ce20dc65c5e96a6f3ca99a6adca0396e8", size = 15148, upload-time = "2022-10-05T19:19:30.546Z" }, ] +[[package]] +name = "bitsandbytes" +version = "0.46.0" +source = { registry = "https://pypi.org/simple/" } +dependencies = [ + { name = "numpy", marker = "(platform_machine != 'aarch64' and sys_platform == 'linux') or (platform_python_implementation != 'CPython' and sys_platform == 'linux') or (sys_platform != 'darwin' and sys_platform != 'linux')" }, + { name = "torch", version = "2.7.1+cu128", source = { registry = "https://download.pytorch.org/whl/cu128" }, marker = "(platform_machine != 'aarch64' and sys_platform == 'linux') or (platform_python_implementation != 'CPython' and sys_platform == 'linux') or (sys_platform != 'darwin' and sys_platform != 'linux')" }, +] +wheels = [ + { url = "https://files.pythonhosted.org/packages/72/27/ec6ee3408e09e01ab05db07af5a97dc76db7bc18824cf5f5dbc98e1e08a4/bitsandbytes-0.46.0-py3-none-manylinux_2_24_x86_64.whl", hash = "sha256:ef38883cfd26f36a0dfff1715f620f87cee3813431f33e10e9658205160cb89b", size = 67047276, upload-time = "2025-05-27T21:25:31.299Z" }, + { url = "https://files.pythonhosted.org/packages/f3/06/2ef5f6b28d8fa442c670b5acc1eb09dd57d4edb00b435b35529c3f09936c/bitsandbytes-0.46.0-py3-none-win_amd64.whl", hash = "sha256:121820a6df80ae3b7e361f7ef193279c3204c361a7e21eb43b5ffa7293403979", size = 66452401, upload-time = "2025-05-27T21:25:35.552Z" }, +] + +[[package]] +name = "braceexpand" +version = "0.1.7" +source = { registry = "https://pypi.org/simple/" } +sdist = { url = "https://files.pythonhosted.org/packages/54/93/badd4f5ccf25209f3fef2573073da9fe4a45a3da99fca2f800f942130c0f/braceexpand-0.1.7.tar.gz", hash = "sha256:e6e539bd20eaea53547472ff94f4fb5c3d3bf9d0a89388c4b56663aba765f705", size = 7777, upload-time = "2021-05-07T13:49:07.323Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/fa/93/e8c04e80e82391a6e51f218ca49720f64236bc824e92152a2633b74cf7ab/braceexpand-0.1.7-py2.py3-none-any.whl", hash = "sha256:91332d53de7828103dcae5773fb43bc34950b0c8160e35e0f44c4427a3b85014", size = 5923, upload-time = "2021-05-07T13:49:05.146Z" }, +] + [[package]] name = "buzz-captions" -version = "1.3.3" +version = "1.4.0" source = { editable = "." } dependencies = [ { name = "accelerate" }, { name = "cmake" }, + { name = "coverage" }, { name = "ctranslate2", version = "4.3.1", source = { registry = "https://pypi.org/simple/" }, marker = "platform_machine == 'x86_64' and sys_platform == 'darwin'" }, { name = "ctranslate2", version = "4.6.0", source = { registry = "https://pypi.org/simple/" }, marker = "platform_machine == 'arm64' or sys_platform != 'darwin'" }, { name = "darkdetect" }, @@ -150,8 +271,11 @@ dependencies = [ { name = "julius" }, { name = "keyring" }, { name = "lameenc" }, + { name = "lhotse" }, { name = "museval" }, { name = "mypy" }, + { name = "nemo-toolkit", extra = ["asr"], marker = "platform_machine != 'x86_64' or sys_platform != 'darwin'" }, + { name = "nltk" }, { name = "numpy" }, { name = "onnxruntime" }, { name = "openai" }, @@ -181,6 +305,7 @@ dependencies = [ { name = "transformers" }, { name = "treetable" }, { name = "urllib3" }, + { name = "uroman" }, { name = "vulkan" }, { name = "yt-dlp" }, ] @@ -212,6 +337,7 @@ dev = [ requires-dist = [ { name = "accelerate", specifier = ">=1.0.1,<2" }, { name = "cmake", specifier = ">=3.31.6" }, + { name = "coverage", specifier = "==7.6.1" }, { name = "ctranslate2", marker = "sys_platform != 'darwin'", specifier = ">=4.6.0,<5" }, { name = "ctranslate2", marker = "platform_machine == 'arm64' and sys_platform == 'darwin'", specifier = ">=4.6.0,<5" }, { name = "ctranslate2", marker = "platform_machine == 'x86_64' and sys_platform == 'darwin'", specifier = "==4.3.1" }, @@ -230,8 +356,11 @@ requires-dist = [ { name = "julius", specifier = ">=0.2.7,<0.3" }, { name = "keyring", specifier = ">=25.0.0,<26" }, { name = "lameenc", specifier = ">=1.8.1,<2" }, + { name = "lhotse", specifier = "==1.31.1" }, { name = "museval", specifier = ">=0.4.1,<0.5" }, { name = "mypy", specifier = ">=1.15.0,<2" }, + { name = "nemo-toolkit", extras = ["asr"], marker = "platform_machine != 'x86_64' or sys_platform != 'darwin'", specifier = ">=2.5.3" }, + { name = "nltk", specifier = ">=3.9.2" }, { name = "numpy", specifier = ">=1.21.2,<2" }, { name = "onnxruntime", specifier = "==1.18.1" }, { name = "openai", specifier = ">=1.14.2,<2" }, @@ -260,6 +389,7 @@ requires-dist = [ { name = "transformers", specifier = ">=4.49.0,<5" }, { name = "treetable", specifier = ">=0.2.5,<0.3" }, { name = "urllib3", specifier = ">=2.3.0,<3" }, + { name = "uroman", specifier = ">=1.3.1.1" }, { name = "vulkan", specifier = ">=1.3.275.1,<2" }, { name = "yt-dlp", specifier = ">=2025.2.19,<2026" }, ] @@ -353,6 +483,18 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/0a/4c/925909008ed5a988ccbb72dcc897407e5d6d3bd72410d69e051fc0c14647/charset_normalizer-3.4.4-py3-none-any.whl", hash = "sha256:7a32c560861a02ff789ad905a2fe94e3f840803362c84fecf1851cb4cf3dc37f", size = 53402, upload-time = "2025-10-14T04:42:31.76Z" }, ] +[[package]] +name = "click" +version = "8.3.1" +source = { registry = "https://pypi.org/simple/" } +dependencies = [ + { name = "colorama", marker = "sys_platform == 'win32'" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/3d/fa/656b739db8587d7b5dfa22e22ed02566950fbfbcdc20311993483657a5c0/click-8.3.1.tar.gz", hash = "sha256:12ff4785d337a1bb490bb7e9c2b1ee5da3112e94a8622f26a6c77f5d2fc6842a", size = 295065, upload-time = "2025-11-15T20:45:42.706Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/98/78/01c019cdb5d6498122777c1a43056ebb3ebfeef2076d9d026bfe15583b2b/click-8.3.1-py3-none-any.whl", hash = "sha256:981153a64e25f12d547d3426c367a4857371575ee7ad18df2a6183ab0545b2a6", size = 108274, upload-time = "2025-11-15T20:45:41.139Z" }, +] + [[package]] name = "cloudpickle" version = "3.1.1" @@ -421,25 +563,43 @@ wheels = [ ] [[package]] -name = "coverage" -version = "7.11.0" +name = "contourpy" +version = "1.3.3" source = { registry = "https://pypi.org/simple/" } -sdist = { url = "https://files.pythonhosted.org/packages/1c/38/ee22495420457259d2f3390309505ea98f98a5eed40901cf62196abad006/coverage-7.11.0.tar.gz", hash = "sha256:167bd504ac1ca2af7ff3b81d245dfea0292c5032ebef9d66cc08a7d28c1b8050", size = 811905, upload-time = "2025-10-15T15:15:08.542Z" } +dependencies = [ + { name = "numpy", marker = "platform_machine != 'x86_64' or sys_platform != 'darwin'" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/58/01/1253e6698a07380cd31a736d248a3f2a50a7c88779a1813da27503cadc2a/contourpy-1.3.3.tar.gz", hash = "sha256:083e12155b210502d0bca491432bb04d56dc3432f95a979b429f2848c3dbe880", size = 13466174, upload-time = "2025-07-26T12:03:12.549Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/c4/db/86f6906a7c7edc1a52b2c6682d6dd9be775d73c0dfe2b84f8923dfea5784/coverage-7.11.0-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:9c49e77811cf9d024b95faf86c3f059b11c0c9be0b0d61bc598f453703bd6fd1", size = 216098, upload-time = "2025-10-15T15:13:02.916Z" }, - { url = "https://files.pythonhosted.org/packages/21/54/e7b26157048c7ba555596aad8569ff903d6cd67867d41b75287323678ede/coverage-7.11.0-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:a61e37a403a778e2cda2a6a39abcc895f1d984071942a41074b5c7ee31642007", size = 216331, upload-time = "2025-10-15T15:13:04.403Z" }, - { url = "https://files.pythonhosted.org/packages/b9/19/1ce6bf444f858b83a733171306134a0544eaddf1ca8851ede6540a55b2ad/coverage-7.11.0-cp312-cp312-manylinux1_i686.manylinux_2_28_i686.manylinux_2_5_i686.whl", hash = "sha256:c79cae102bb3b1801e2ef1511fb50e91ec83a1ce466b2c7c25010d884336de46", size = 247825, upload-time = "2025-10-15T15:13:05.92Z" }, - { url = "https://files.pythonhosted.org/packages/71/0b/d3bcbbc259fcced5fb67c5d78f6e7ee965f49760c14afd931e9e663a83b2/coverage-7.11.0-cp312-cp312-manylinux1_x86_64.manylinux_2_28_x86_64.manylinux_2_5_x86_64.whl", hash = "sha256:16ce17ceb5d211f320b62df002fa7016b7442ea0fd260c11cec8ce7730954893", size = 250573, upload-time = "2025-10-15T15:13:07.471Z" }, - { url = "https://files.pythonhosted.org/packages/58/8d/b0ff3641a320abb047258d36ed1c21d16be33beed4152628331a1baf3365/coverage-7.11.0-cp312-cp312-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:80027673e9d0bd6aef86134b0771845e2da85755cf686e7c7c59566cf5a89115", size = 251706, upload-time = "2025-10-15T15:13:09.4Z" }, - { url = "https://files.pythonhosted.org/packages/59/c8/5a586fe8c7b0458053d9c687f5cff515a74b66c85931f7fe17a1c958b4ac/coverage-7.11.0-cp312-cp312-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:4d3ffa07a08657306cd2215b0da53761c4d73cb54d9143b9303a6481ec0cd415", size = 248221, upload-time = "2025-10-15T15:13:10.964Z" }, - { url = "https://files.pythonhosted.org/packages/d0/ff/3a25e3132804ba44cfa9a778cdf2b73dbbe63ef4b0945e39602fc896ba52/coverage-7.11.0-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:a3b6a5f8b2524fd6c1066bc85bfd97e78709bb5e37b5b94911a6506b65f47186", size = 249624, upload-time = "2025-10-15T15:13:12.5Z" }, - { url = "https://files.pythonhosted.org/packages/c5/12/ff10c8ce3895e1b17a73485ea79ebc1896a9e466a9d0f4aef63e0d17b718/coverage-7.11.0-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:fcc0a4aa589de34bc56e1a80a740ee0f8c47611bdfb28cd1849de60660f3799d", size = 247744, upload-time = "2025-10-15T15:13:14.554Z" }, - { url = "https://files.pythonhosted.org/packages/16/02/d500b91f5471b2975947e0629b8980e5e90786fe316b6d7299852c1d793d/coverage-7.11.0-cp312-cp312-musllinux_1_2_riscv64.whl", hash = "sha256:dba82204769d78c3fd31b35c3d5f46e06511936c5019c39f98320e05b08f794d", size = 247325, upload-time = "2025-10-15T15:13:16.438Z" }, - { url = "https://files.pythonhosted.org/packages/77/11/dee0284fbbd9cd64cfce806b827452c6df3f100d9e66188e82dfe771d4af/coverage-7.11.0-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:81b335f03ba67309a95210caf3eb43bd6fe75a4e22ba653ef97b4696c56c7ec2", size = 249180, upload-time = "2025-10-15T15:13:17.959Z" }, - { url = "https://files.pythonhosted.org/packages/59/1b/cdf1def928f0a150a057cab03286774e73e29c2395f0d30ce3d9e9f8e697/coverage-7.11.0-cp312-cp312-win32.whl", hash = "sha256:037b2d064c2f8cc8716fe4d39cb705779af3fbf1ba318dc96a1af858888c7bb5", size = 218479, upload-time = "2025-10-15T15:13:19.608Z" }, - { url = "https://files.pythonhosted.org/packages/ff/55/e5884d55e031da9c15b94b90a23beccc9d6beee65e9835cd6da0a79e4f3a/coverage-7.11.0-cp312-cp312-win_amd64.whl", hash = "sha256:d66c0104aec3b75e5fd897e7940188ea1892ca1d0235316bf89286d6a22568c0", size = 219290, upload-time = "2025-10-15T15:13:21.593Z" }, - { url = "https://files.pythonhosted.org/packages/23/a8/faa930cfc71c1d16bc78f9a19bb73700464f9c331d9e547bfbc1dbd3a108/coverage-7.11.0-cp312-cp312-win_arm64.whl", hash = "sha256:d91ebeac603812a09cf6a886ba6e464f3bbb367411904ae3790dfe28311b15ad", size = 217924, upload-time = "2025-10-15T15:13:23.39Z" }, - { url = "https://files.pythonhosted.org/packages/5f/04/642c1d8a448ae5ea1369eac8495740a79eb4e581a9fb0cbdce56bbf56da1/coverage-7.11.0-py3-none-any.whl", hash = "sha256:4b7589765348d78fb4e5fb6ea35d07564e387da2fc5efff62e0222971f155f68", size = 207761, upload-time = "2025-10-15T15:15:06.439Z" }, + { url = "https://files.pythonhosted.org/packages/be/45/adfee365d9ea3d853550b2e735f9d66366701c65db7855cd07621732ccfc/contourpy-1.3.3-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:b08a32ea2f8e42cf1d4be3169a98dd4be32bafe4f22b6c4cb4ba810fa9e5d2cb", size = 293419, upload-time = "2025-07-26T12:01:21.16Z" }, + { url = "https://files.pythonhosted.org/packages/53/3e/405b59cfa13021a56bba395a6b3aca8cec012b45bf177b0eaf7a202cde2c/contourpy-1.3.3-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:556dba8fb6f5d8742f2923fe9457dbdd51e1049c4a43fd3986a0b14a1d815fc6", size = 273979, upload-time = "2025-07-26T12:01:22.448Z" }, + { url = "https://files.pythonhosted.org/packages/d4/1c/a12359b9b2ca3a845e8f7f9ac08bdf776114eb931392fcad91743e2ea17b/contourpy-1.3.3-cp312-cp312-manylinux_2_26_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:92d9abc807cf7d0e047b95ca5d957cf4792fcd04e920ca70d48add15c1a90ea7", size = 332653, upload-time = "2025-07-26T12:01:24.155Z" }, + { url = "https://files.pythonhosted.org/packages/63/12/897aeebfb475b7748ea67b61e045accdfcf0d971f8a588b67108ed7f5512/contourpy-1.3.3-cp312-cp312-manylinux_2_26_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:b2e8faa0ed68cb29af51edd8e24798bb661eac3bd9f65420c1887b6ca89987c8", size = 379536, upload-time = "2025-07-26T12:01:25.91Z" }, + { url = "https://files.pythonhosted.org/packages/43/8a/a8c584b82deb248930ce069e71576fc09bd7174bbd35183b7943fb1064fd/contourpy-1.3.3-cp312-cp312-manylinux_2_26_s390x.manylinux_2_28_s390x.whl", hash = "sha256:626d60935cf668e70a5ce6ff184fd713e9683fb458898e4249b63be9e28286ea", size = 384397, upload-time = "2025-07-26T12:01:27.152Z" }, + { url = "https://files.pythonhosted.org/packages/cc/8f/ec6289987824b29529d0dfda0d74a07cec60e54b9c92f3c9da4c0ac732de/contourpy-1.3.3-cp312-cp312-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:4d00e655fcef08aba35ec9610536bfe90267d7ab5ba944f7032549c55a146da1", size = 362601, upload-time = "2025-07-26T12:01:28.808Z" }, + { url = "https://files.pythonhosted.org/packages/05/0a/a3fe3be3ee2dceb3e615ebb4df97ae6f3828aa915d3e10549ce016302bd1/contourpy-1.3.3-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:451e71b5a7d597379ef572de31eeb909a87246974d960049a9848c3bc6c41bf7", size = 1331288, upload-time = "2025-07-26T12:01:31.198Z" }, + { url = "https://files.pythonhosted.org/packages/33/1d/acad9bd4e97f13f3e2b18a3977fe1b4a37ecf3d38d815333980c6c72e963/contourpy-1.3.3-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:459c1f020cd59fcfe6650180678a9993932d80d44ccde1fa1868977438f0b411", size = 1403386, upload-time = "2025-07-26T12:01:33.947Z" }, + { url = "https://files.pythonhosted.org/packages/cf/8f/5847f44a7fddf859704217a99a23a4f6417b10e5ab1256a179264561540e/contourpy-1.3.3-cp312-cp312-win32.whl", hash = "sha256:023b44101dfe49d7d53932be418477dba359649246075c996866106da069af69", size = 185018, upload-time = "2025-07-26T12:01:35.64Z" }, + { url = "https://files.pythonhosted.org/packages/19/e8/6026ed58a64563186a9ee3f29f41261fd1828f527dd93d33b60feca63352/contourpy-1.3.3-cp312-cp312-win_amd64.whl", hash = "sha256:8153b8bfc11e1e4d75bcb0bff1db232f9e10b274e0929de9d608027e0d34ff8b", size = 226567, upload-time = "2025-07-26T12:01:36.804Z" }, + { url = "https://files.pythonhosted.org/packages/d1/e2/f05240d2c39a1ed228d8328a78b6f44cd695f7ef47beb3e684cf93604f86/contourpy-1.3.3-cp312-cp312-win_arm64.whl", hash = "sha256:07ce5ed73ecdc4a03ffe3e1b3e3c1166db35ae7584be76f65dbbe28a7791b0cc", size = 193655, upload-time = "2025-07-26T12:01:37.999Z" }, +] + +[[package]] +name = "coverage" +version = "7.6.1" +source = { registry = "https://pypi.org/simple/" } +sdist = { url = "https://files.pythonhosted.org/packages/f7/08/7e37f82e4d1aead42a7443ff06a1e406aabf7302c4f00a546e4b320b994c/coverage-7.6.1.tar.gz", hash = "sha256:953510dfb7b12ab69d20135a0662397f077c59b1e6379a768e97c59d852ee51d", size = 798791, upload-time = "2024-08-04T19:45:30.9Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/7e/d4/300fc921dff243cd518c7db3a4c614b7e4b2431b0d1145c1e274fd99bd70/coverage-7.6.1-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:95cae0efeb032af8458fc27d191f85d1717b1d4e49f7cb226cf526ff28179778", size = 206983, upload-time = "2024-08-04T19:43:49.082Z" }, + { url = "https://files.pythonhosted.org/packages/e1/ab/6bf00de5327ecb8db205f9ae596885417a31535eeda6e7b99463108782e1/coverage-7.6.1-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:5621a9175cf9d0b0c84c2ef2b12e9f5f5071357c4d2ea6ca1cf01814f45d2391", size = 207221, upload-time = "2024-08-04T19:43:52.15Z" }, + { url = "https://files.pythonhosted.org/packages/92/8f/2ead05e735022d1a7f3a0a683ac7f737de14850395a826192f0288703472/coverage-7.6.1-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:260933720fdcd75340e7dbe9060655aff3af1f0c5d20f46b57f262ab6c86a5e8", size = 240342, upload-time = "2024-08-04T19:43:53.746Z" }, + { url = "https://files.pythonhosted.org/packages/0f/ef/94043e478201ffa85b8ae2d2c79b4081e5a1b73438aafafccf3e9bafb6b5/coverage-7.6.1-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:07e2ca0ad381b91350c0ed49d52699b625aab2b44b65e1b4e02fa9df0e92ad2d", size = 237371, upload-time = "2024-08-04T19:43:55.993Z" }, + { url = "https://files.pythonhosted.org/packages/1f/0f/c890339dd605f3ebc269543247bdd43b703cce6825b5ed42ff5f2d6122c7/coverage-7.6.1-cp312-cp312-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:c44fee9975f04b33331cb8eb272827111efc8930cfd582e0320613263ca849ca", size = 239455, upload-time = "2024-08-04T19:43:57.618Z" }, + { url = "https://files.pythonhosted.org/packages/d1/04/7fd7b39ec7372a04efb0f70c70e35857a99b6a9188b5205efb4c77d6a57a/coverage-7.6.1-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:877abb17e6339d96bf08e7a622d05095e72b71f8afd8a9fefc82cf30ed944163", size = 238924, upload-time = "2024-08-04T19:44:00.012Z" }, + { url = "https://files.pythonhosted.org/packages/ed/bf/73ce346a9d32a09cf369f14d2a06651329c984e106f5992c89579d25b27e/coverage-7.6.1-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:3e0cadcf6733c09154b461f1ca72d5416635e5e4ec4e536192180d34ec160f8a", size = 237252, upload-time = "2024-08-04T19:44:01.713Z" }, + { url = "https://files.pythonhosted.org/packages/86/74/1dc7a20969725e917b1e07fe71a955eb34bc606b938316bcc799f228374b/coverage-7.6.1-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:c3c02d12f837d9683e5ab2f3d9844dc57655b92c74e286c262e0fc54213c216d", size = 238897, upload-time = "2024-08-04T19:44:03.898Z" }, + { url = "https://files.pythonhosted.org/packages/b6/e9/d9cc3deceb361c491b81005c668578b0dfa51eed02cd081620e9a62f24ec/coverage-7.6.1-cp312-cp312-win32.whl", hash = "sha256:e05882b70b87a18d937ca6768ff33cc3f72847cbc4de4491c8e73880766718e5", size = 209606, upload-time = "2024-08-04T19:44:05.532Z" }, + { url = "https://files.pythonhosted.org/packages/47/c8/5a2e41922ea6740f77d555c4d47544acd7dc3f251fe14199c09c0f5958d3/coverage-7.6.1-cp312-cp312-win_amd64.whl", hash = "sha256:b5d7b556859dd85f3a541db6a4e0167b86e7273e1cdc973e5b175166bb634fdb", size = 210373, upload-time = "2024-08-04T19:44:07.079Z" }, ] [[package]] @@ -447,7 +607,7 @@ name = "cryptography" version = "46.0.3" source = { registry = "https://pypi.org/simple/" } dependencies = [ - { name = "cffi", marker = "platform_python_implementation != 'PyPy' and sys_platform != 'darwin'" }, + { name = "cffi", marker = "platform_python_implementation != 'PyPy' and sys_platform == 'linux'" }, ] sdist = { url = "https://files.pythonhosted.org/packages/9f/33/c00162f49c0e2fe8064a62cb92b93e50c74a72bc370ab92f86112b33ff62/cryptography-46.0.3.tar.gz", hash = "sha256:a8b17438104fed022ce745b362294d9ce35b4c2e45c1d958ad4a4b019285f4a1", size = 749258, upload-time = "2025-10-15T23:18:31.74Z" } wheels = [ @@ -475,6 +635,17 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/cd/c7/f65027c2810e14c3e7268353b1681932b87e5a48e65505d8cc17c99e36ae/cryptography-46.0.3-cp38-abi3-musllinux_1_2_x86_64.whl", hash = "sha256:3b51b8ca4f1c6453d8829e1eb7299499ca7f313900dd4d89a24b8b87c0a780d4", size = 4686573, upload-time = "2025-10-15T23:18:06.908Z" }, ] +[[package]] +name = "ctc-segmentation" +version = "1.7.4" +source = { registry = "https://pypi.org/simple/" } +dependencies = [ + { name = "cython", marker = "platform_machine != 'x86_64' or sys_platform != 'darwin'" }, + { name = "numpy", marker = "platform_machine != 'x86_64' or sys_platform != 'darwin'" }, + { name = "setuptools", marker = "platform_machine != 'x86_64' or sys_platform != 'darwin'" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/f4/ed/78dd82e0b022ed4cb047188c0b8cead62fa0c27700737fd34e3263d83882/ctc_segmentation-1.7.4.tar.gz", hash = "sha256:19d383ea5f22438ebb1699d72b22078b63f351a33fa50bedb19c14077ba6a116", size = 73584, upload-time = "2022-10-11T19:25:00.575Z" } + [[package]] name = "ctranslate2" version = "4.3.1" @@ -498,7 +669,8 @@ source = { registry = "https://pypi.org/simple/" } resolution-markers = [ "platform_machine == 'arm64' and sys_platform == 'darwin'", "platform_machine != 'arm64' and platform_machine != 'x86_64' and sys_platform == 'darwin'", - "(platform_machine != 'aarch64' and sys_platform == 'linux') or (platform_python_implementation != 'CPython' and sys_platform == 'linux') or (sys_platform != 'darwin' and sys_platform != 'linux')", + "(platform_machine != 'aarch64' and sys_platform == 'linux') or (platform_python_implementation != 'CPython' and sys_platform == 'linux')", + "sys_platform != 'darwin' and sys_platform != 'linux'", "platform_machine == 'aarch64' and platform_python_implementation == 'CPython' and sys_platform == 'linux'", ] dependencies = [ @@ -523,6 +695,15 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/07/92/f344ba59f3aeb3bb37d05c445229b2a8c25d7bfa61e2759cde7f14a64d9a/ctypesgen-1.1.1-py3-none-any.whl", hash = "sha256:94cc6c89ccdd93a72a4c915266cde9a82bfe693331d9d880f66fe9d82af1fc87", size = 124193, upload-time = "2022-10-19T07:00:53.227Z" }, ] +[[package]] +name = "cycler" +version = "0.12.1" +source = { registry = "https://pypi.org/simple/" } +sdist = { url = "https://files.pythonhosted.org/packages/a9/95/a3dbbb5028f35eafb79008e7522a75244477d2838f38cbb722248dabc2a8/cycler-0.12.1.tar.gz", hash = "sha256:88bb128f02ba341da8ef447245a9e138fae777f6a23943da4540077d3601eb1c", size = 7615, upload-time = "2023-10-07T05:32:18.335Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/e7/05/c19819d5e3d95294a6f5947fb9b9629efb316b96de511b418c53d245aae6/cycler-0.12.1-py3-none-any.whl", hash = "sha256:85cef7cff222d8644161529808465972e51340599459b8ac3ccbac5a854e0d30", size = 8321, upload-time = "2023-10-07T05:32:16.783Z" }, +] + [[package]] name = "cython" version = "3.1.6" @@ -542,6 +723,37 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/18/d5/7a04640bf559bb890455ffb28978daf7d44f667c3f04a4d422c655c1ba92/cython-3.1.6-py3-none-any.whl", hash = "sha256:91dcf7eb9b6a089ce4e9e1140e571d84c3bca834afb77ec269be7aa9d31a8157", size = 1223550, upload-time = "2025-10-23T12:38:16.732Z" }, ] +[[package]] +name = "cytoolz" +version = "1.1.0" +source = { registry = "https://pypi.org/simple/" } +dependencies = [ + { name = "toolz" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/bd/d4/16916f3dc20a3f5455b63c35dcb260b3716f59ce27a93586804e70e431d5/cytoolz-1.1.0.tar.gz", hash = "sha256:13a7bf254c3c0d28b12e2290b82aed0f0977a4c2a2bf84854fcdc7796a29f3b0", size = 642510, upload-time = "2025-10-19T00:44:56.174Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/c6/ec/01426224f7acf60183d3921b25e1a8e71713d3d39cb464d64ac7aace6ea6/cytoolz-1.1.0-cp312-cp312-macosx_10_13_universal2.whl", hash = "sha256:99f8e134c9be11649342853ec8c90837af4089fc8ff1e8f9a024a57d1fa08514", size = 1327800, upload-time = "2025-10-19T00:40:48.674Z" }, + { url = "https://files.pythonhosted.org/packages/b4/07/e07e8fedd332ac9626ad58bea31416dda19bfd14310731fa38b16a97e15f/cytoolz-1.1.0-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:0a6f44cf9319c30feb9a50aa513d777ef51efec16f31c404409e7deb8063df64", size = 997118, upload-time = "2025-10-19T00:40:50.919Z" }, + { url = "https://files.pythonhosted.org/packages/ab/72/c0f766d63ed2f9ea8dc8e1628d385d99b41fb834ce17ac3669e3f91e115d/cytoolz-1.1.0-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:945580dc158c557172fca899a35a99a16fbcebf6db0c77cb6621084bc82189f9", size = 991169, upload-time = "2025-10-19T00:40:52.887Z" }, + { url = "https://files.pythonhosted.org/packages/df/4b/1f757353d1bf33e56a7391ecc9bc49c1e529803b93a9d2f67fe5f92906fe/cytoolz-1.1.0-cp312-cp312-manylinux1_i686.manylinux_2_28_i686.manylinux_2_5_i686.whl", hash = "sha256:257905ec050d04f2f856854620d1e25556fd735064cebd81b460f54939b9f9d5", size = 2700680, upload-time = "2025-10-19T00:40:54.597Z" }, + { url = "https://files.pythonhosted.org/packages/25/73/9b25bb7ed8d419b9d6ff2ae0b3d06694de79a3f98f5169a1293ff7ad3a3f/cytoolz-1.1.0-cp312-cp312-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:82779049f352fb3ab5e8c993ab45edbb6e02efb1f17f0b50f4972c706cc51d76", size = 2824951, upload-time = "2025-10-19T00:40:56.137Z" }, + { url = "https://files.pythonhosted.org/packages/0c/93/9c787f7c909e75670fff467f2504725d06d8c3f51d6dfe22c55a08c8ccd4/cytoolz-1.1.0-cp312-cp312-manylinux2014_armv7l.manylinux_2_17_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:7d3e405e435320e08c5a1633afaf285a392e2d9cef35c925d91e2a31dfd7a688", size = 2679635, upload-time = "2025-10-19T00:40:57.799Z" }, + { url = "https://files.pythonhosted.org/packages/50/aa/9ee92c302cccf7a41a7311b325b51ebeff25d36c1f82bdc1bbe3f58dc947/cytoolz-1.1.0-cp312-cp312-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:923df8f5591e0d20543060c29909c149ab1963a7267037b39eee03a83dbc50a8", size = 2938352, upload-time = "2025-10-19T00:40:59.49Z" }, + { url = "https://files.pythonhosted.org/packages/6a/a3/3b58c5c1692c3bacd65640d0d5c7267a7ebb76204f7507aec29de7063d2f/cytoolz-1.1.0-cp312-cp312-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:25db9e4862f22ea0ae2e56c8bec9fc9fd756b655ae13e8c7b5625d7ed1c582d4", size = 3022121, upload-time = "2025-10-19T00:41:01.209Z" }, + { url = "https://files.pythonhosted.org/packages/e1/93/c647bc3334355088c57351a536c2d4a83dd45f7de591fab383975e45bff9/cytoolz-1.1.0-cp312-cp312-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:c7a98deb11ccd8e5d9f9441ef2ff3352aab52226a2b7d04756caaa53cd612363", size = 2857656, upload-time = "2025-10-19T00:41:03.456Z" }, + { url = "https://files.pythonhosted.org/packages/b2/c2/43fea146bf4141deea959e19dcddf268c5ed759dec5c2ed4a6941d711933/cytoolz-1.1.0-cp312-cp312-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:dce4ee9fc99104bc77efdea80f32ca5a650cd653bcc8a1d984a931153d3d9b58", size = 2551284, upload-time = "2025-10-19T00:41:05.347Z" }, + { url = "https://files.pythonhosted.org/packages/6f/df/cdc7a81ce5cfcde7ef523143d545635fc37e80ccacce140ae58483a21da3/cytoolz-1.1.0-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:80d6da158f7d20c15819701bbda1c041f0944ede2f564f5c739b1bc80a9ffb8b", size = 2721673, upload-time = "2025-10-19T00:41:07.528Z" }, + { url = "https://files.pythonhosted.org/packages/45/be/f8524bb9ad8812ad375e61238dcaa3177628234d1b908ad0b74e3657cafd/cytoolz-1.1.0-cp312-cp312-musllinux_1_2_armv7l.whl", hash = "sha256:3b5c5a192abda123ad45ef716ec9082b4cf7d95e9ada8291c5c2cc5558be858b", size = 2722884, upload-time = "2025-10-19T00:41:09.698Z" }, + { url = "https://files.pythonhosted.org/packages/23/e6/6bb8e4f9c267ad42d1ff77b6d2e4984665505afae50a216290e1d7311431/cytoolz-1.1.0-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:5b399ce7d967b1cb6280250818b786be652aa8ddffd3c0bb5c48c6220d945ab5", size = 2685486, upload-time = "2025-10-19T00:41:11.349Z" }, + { url = "https://files.pythonhosted.org/packages/d7/dd/88619f9c8d2b682562c0c886bbb7c35720cb83fda2ac9a41bdd14073d9bd/cytoolz-1.1.0-cp312-cp312-musllinux_1_2_ppc64le.whl", hash = "sha256:e7e29a1a03f00b4322196cfe8e2c38da9a6c8d573566052c586df83aacc5663c", size = 2839661, upload-time = "2025-10-19T00:41:13.053Z" }, + { url = "https://files.pythonhosted.org/packages/b8/8d/4478ebf471ee78dd496d254dc0f4ad729cd8e6ba8257de4f0a98a2838ef2/cytoolz-1.1.0-cp312-cp312-musllinux_1_2_riscv64.whl", hash = "sha256:5291b117d71652a817ec164e7011f18e6a51f8a352cc9a70ed5b976c51102fda", size = 2547095, upload-time = "2025-10-19T00:41:16.054Z" }, + { url = "https://files.pythonhosted.org/packages/e6/68/f1dea33367b0b3f64e199c230a14a6b6f243c189020effafd31e970ca527/cytoolz-1.1.0-cp312-cp312-musllinux_1_2_s390x.whl", hash = "sha256:8caef62f846a9011676c51bda9189ae394cdd6bb17f2946ecaedc23243268320", size = 2870901, upload-time = "2025-10-19T00:41:17.727Z" }, + { url = "https://files.pythonhosted.org/packages/4a/9a/33591c09dfe799b8fb692cf2ad383e2c41ab6593cc960b00d1fc8a145655/cytoolz-1.1.0-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:de425c5a8e3be7bb3a195e19191d28d9eb3c2038046064a92edc4505033ec9cb", size = 2765422, upload-time = "2025-10-19T00:41:20.075Z" }, + { url = "https://files.pythonhosted.org/packages/60/2b/a8aa233c9416df87f004e57ae4280bd5e1f389b4943d179f01020c6ec629/cytoolz-1.1.0-cp312-cp312-win32.whl", hash = "sha256:296440a870e8d1f2e1d1edf98f60f1532b9d3ab8dfbd4b25ec08cd76311e79e5", size = 901933, upload-time = "2025-10-19T00:41:21.646Z" }, + { url = "https://files.pythonhosted.org/packages/ad/33/4c9bdf8390dc01d2617c7f11930697157164a52259b6818ddfa2f94f89f4/cytoolz-1.1.0-cp312-cp312-win_amd64.whl", hash = "sha256:07156987f224c6dac59aa18fb8bf91e1412f5463961862716a3381bf429c8699", size = 947989, upload-time = "2025-10-19T00:41:23.288Z" }, + { url = "https://files.pythonhosted.org/packages/35/ac/6e2708835875f5acb52318462ed296bf94ed0cb8c7cb70e62fbd03f709e3/cytoolz-1.1.0-cp312-cp312-win_arm64.whl", hash = "sha256:23e616b38f5b3160c7bb45b0f84a8f3deb4bd26b29fb2dfc716f241c738e27b8", size = 903913, upload-time = "2025-10-19T00:41:24.992Z" }, +] + [[package]] name = "darkdetect" version = "0.8.0" @@ -564,6 +776,40 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/c3/be/d0d44e092656fe7a06b55e6103cbce807cdbdee17884a5367c68c9860853/dataclasses_json-0.6.7-py3-none-any.whl", hash = "sha256:0dbf33f26c8d5305befd61b39d2b3414e8a407bedc2834dea9b8d642666fb40a", size = 28686, upload-time = "2024-06-09T16:20:16.715Z" }, ] +[[package]] +name = "datasets" +version = "4.4.1" +source = { registry = "https://pypi.org/simple/" } +dependencies = [ + { name = "dill", marker = "platform_machine != 'x86_64' or sys_platform != 'darwin'" }, + { name = "filelock", marker = "platform_machine != 'x86_64' or sys_platform != 'darwin'" }, + { name = "fsspec", extra = ["http"], marker = "platform_machine != 'x86_64' or sys_platform != 'darwin'" }, + { name = "httpx", marker = "platform_machine != 'x86_64' or sys_platform != 'darwin'" }, + { name = "huggingface-hub", marker = "platform_machine != 'x86_64' or sys_platform != 'darwin'" }, + { name = "multiprocess", marker = "platform_machine != 'x86_64' or sys_platform != 'darwin'" }, + { name = "numpy", marker = "platform_machine != 'x86_64' or sys_platform != 'darwin'" }, + { name = "packaging", marker = "platform_machine != 'x86_64' or sys_platform != 'darwin'" }, + { name = "pandas", marker = "platform_machine != 'x86_64' or sys_platform != 'darwin'" }, + { name = "pyarrow", marker = "platform_machine != 'x86_64' or sys_platform != 'darwin'" }, + { name = "pyyaml", marker = "platform_machine != 'x86_64' or sys_platform != 'darwin'" }, + { name = "requests", marker = "platform_machine != 'x86_64' or sys_platform != 'darwin'" }, + { name = "tqdm", marker = "platform_machine != 'x86_64' or sys_platform != 'darwin'" }, + { name = "xxhash", marker = "platform_machine != 'x86_64' or sys_platform != 'darwin'" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/93/bf/0dae295d6d1ba0b1a200a9dd216838464b5bbd05da01407cb1330b377445/datasets-4.4.1.tar.gz", hash = "sha256:80322699aa8c0bbbdb7caa87906da689c3c2e29523cff698775c67f28fdab1fc", size = 585341, upload-time = "2025-11-05T16:00:38.162Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/3b/5e/6f8d874366788ad5d549e9ba258037d974dda6e004843be1bda794571701/datasets-4.4.1-py3-none-any.whl", hash = "sha256:c1163de5211e42546079ab355cc0250c7e6db16eb209ac5ac6252f801f596c44", size = 511591, upload-time = "2025-11-05T16:00:36.365Z" }, +] + +[[package]] +name = "decorator" +version = "5.2.1" +source = { registry = "https://pypi.org/simple/" } +sdist = { url = "https://files.pythonhosted.org/packages/43/fa/6d96a0978d19e17b68d634497769987b16c8f4cd0a7a05048bec693caa6b/decorator-5.2.1.tar.gz", hash = "sha256:65f266143752f734b0a7cc83c46f4618af75b8c5911b00ccb61d0ac9b6da0360", size = 56711, upload-time = "2025-02-24T04:41:34.073Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/4e/8c/f3147f5c4b73e7550fe5f9352eaa956ae838d5c51eb58e7a25b9f3e2643b/decorator-5.2.1-py3-none-any.whl", hash = "sha256:d316bb415a2d9e2d2b3abcc4084c6502fc09240e292cd76a76afc106a1c8e04a", size = 9190, upload-time = "2025-02-24T04:41:32.565Z" }, +] + [[package]] name = "diffq" version = "0.2.4" @@ -604,6 +850,12 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/12/b3/231ffd4ab1fc9d679809f356cebee130ac7daa00d6d6f3206dd4fd137e9e/distro-1.9.0-py3-none-any.whl", hash = "sha256:7bffd925d65168f85027d8da9af6bddab658135b840670a223589bc0c8ef02b2", size = 20277, upload-time = "2023-12-24T09:54:30.421Z" }, ] +[[package]] +name = "docopt" +version = "0.6.2" +source = { registry = "https://pypi.org/simple/" } +sdist = { url = "https://files.pythonhosted.org/packages/a2/55/8f8cab2afd404cf578136ef2cc5dfb50baa1761b68c9da1fb1e4eed343c9/docopt-0.6.2.tar.gz", hash = "sha256:49b3a825280bd66b3aa83585ef59c4a8c82f2c8a522dbe754a8bc8d08c85c491", size = 25901, upload-time = "2014-06-16T11:18:57.406Z" } + [[package]] name = "dora-search" version = "0.1.12" @@ -619,6 +871,25 @@ dependencies = [ ] sdist = { url = "https://files.pythonhosted.org/packages/d5/9d/9a13947db237375486c0690f4741dd2b7e1eee20e0ffcb55dbd1b21cc600/dora_search-0.1.12.tar.gz", hash = "sha256:2956fd2c4c7e4b9a4830e83f0d4cf961be45cfba1a2f0570281e91d15ac516fb", size = 87111, upload-time = "2023-05-23T14:36:24.743Z" } +[[package]] +name = "editdistance" +version = "0.8.1" +source = { registry = "https://pypi.org/simple/" } +sdist = { url = "https://files.pythonhosted.org/packages/d5/18/9f4f975ca87a390832b1c22478f3702fcdf739f83211e24d054b7551270d/editdistance-0.8.1.tar.gz", hash = "sha256:d1cdf80a5d5014b0c9126a69a42ce55a457b457f6986ff69ca98e4fe4d2d8fed", size = 50006, upload-time = "2024-02-10T07:44:53.914Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/cb/4c/7f195588949b4e72436dc7fc902632381f96e586af829685b56daebb38b8/editdistance-0.8.1-cp312-cp312-macosx_10_9_universal2.whl", hash = "sha256:b04af61b3fcdd287a07c15b6ae3b02af01c5e3e9c3aca76b8c1d13bd266b6f57", size = 106723, upload-time = "2024-02-10T07:43:50.268Z" }, + { url = "https://files.pythonhosted.org/packages/8d/82/31dc1640d830cd7d36865098329f34e4dad3b77f31cfb9404b347e700196/editdistance-0.8.1-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:18fc8b6eaae01bfd9cf999af726c1e8dcf667d120e81aa7dbd515bea7427f62f", size = 80998, upload-time = "2024-02-10T07:43:51.259Z" }, + { url = "https://files.pythonhosted.org/packages/ea/2a/6b823e71cef694d6f070a1d82be2842706fa193541aab8856a8f42044cd0/editdistance-0.8.1-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:6a87839450a5987028738d061ffa5ef6a68bac2ddc68c9147a8aae9806629c7f", size = 79248, upload-time = "2024-02-10T07:43:52.873Z" }, + { url = "https://files.pythonhosted.org/packages/e1/31/bfb8e590f922089dc3471ed7828a6da2fc9453eba38c332efa9ee8749fd7/editdistance-0.8.1-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:24b5f9c9673c823d91b5973d0af8b39f883f414a55ade2b9d097138acd10f31e", size = 415262, upload-time = "2024-02-10T07:43:54.498Z" }, + { url = "https://files.pythonhosted.org/packages/a9/c7/57423942b2f847cdbbb46494568d00cd8a45500904ea026f0aad6ca01bc7/editdistance-0.8.1-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:c59248eabfad603f0fba47b0c263d5dc728fb01c2b6b50fb6ca187cec547fdb3", size = 418905, upload-time = "2024-02-10T07:43:55.779Z" }, + { url = "https://files.pythonhosted.org/packages/1b/05/dfa4cdcce063596cbf0d7a32c46cd0f4fa70980311b7da64d35f33ad02a0/editdistance-0.8.1-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:84e239d88ff52821cf64023fabd06a1d9a07654f364b64bf1284577fd3a79d0e", size = 412511, upload-time = "2024-02-10T07:43:57.567Z" }, + { url = "https://files.pythonhosted.org/packages/0e/14/39608ff724a9523f187c4e28926d78bc68f2798f74777ac6757981108345/editdistance-0.8.1-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:2f7f71698f83e8c83839ac0d876a0f4ef996c86c5460aebd26d85568d4afd0db", size = 917293, upload-time = "2024-02-10T07:43:59.559Z" }, + { url = "https://files.pythonhosted.org/packages/df/92/4a1c61d72da40dedfd0ff950fdc71ae83f478330c58a8bccfd776518bd67/editdistance-0.8.1-cp312-cp312-musllinux_1_1_i686.whl", hash = "sha256:04e229d6f4ce0c12abc9f4cd4023a5b5fa9620226e0207b119c3c2778b036250", size = 975580, upload-time = "2024-02-10T07:44:01.328Z" }, + { url = "https://files.pythonhosted.org/packages/47/3d/9877566e724c8a37f2228a84ec5cbf66dbfd0673515baf68a0fe07caff40/editdistance-0.8.1-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:e16721636da6d6b68a2c09eaced35a94f4a4a704ec09f45756d4fd5e128ed18d", size = 929121, upload-time = "2024-02-10T07:44:02.764Z" }, + { url = "https://files.pythonhosted.org/packages/d2/f5/8c50757d198b8ca30ddb91e8b8f0247a8dca04ff2ec30755245f0ab1ff0c/editdistance-0.8.1-cp312-cp312-win32.whl", hash = "sha256:87533cf2ebc3777088d991947274cd7e1014b9c861a8aa65257bcdc0ee492526", size = 81039, upload-time = "2024-02-10T07:44:04.134Z" }, + { url = "https://files.pythonhosted.org/packages/28/f0/65101e51dc7c850e7b7581a5d8fa8721a1d7479a0dca6c08386328e19882/editdistance-0.8.1-cp312-cp312-win_amd64.whl", hash = "sha256:09f01ed51746d90178af7dd7ea4ebb41497ef19f53c7f327e864421743dffb0a", size = 79853, upload-time = "2024-02-10T07:44:05.687Z" }, +] + [[package]] name = "einops" version = "0.8.1" @@ -628,6 +899,15 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/87/62/9773de14fe6c45c23649e98b83231fffd7b9892b6cf863251dc2afa73643/einops-0.8.1-py3-none-any.whl", hash = "sha256:919387eb55330f5757c6bea9165c5ff5cfe63a642682ea788a6d472576d81737", size = 64359, upload-time = "2025-02-09T03:17:01.998Z" }, ] +[[package]] +name = "executing" +version = "2.2.1" +source = { registry = "https://pypi.org/simple/" } +sdist = { url = "https://files.pythonhosted.org/packages/cc/28/c14e053b6762b1044f34a13aab6859bbf40456d37d23aa286ac24cfd9a5d/executing-2.2.1.tar.gz", hash = "sha256:3632cc370565f6648cc328b32435bd120a1e4ebb20c77e3fdde9a13cd1e533c4", size = 1129488, upload-time = "2025-09-01T09:48:10.866Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/c1/ea/53f2148663b321f21b5a606bd5f191517cf40b7072c0497d3c92c4a13b1e/executing-2.2.1-py2.py3-none-any.whl", hash = "sha256:760643d3452b4d777d295bb167ccc74c64a81df23fb5e08eff250c425a4b2017", size = 28317, upload-time = "2025-09-01T09:48:08.5Z" }, +] + [[package]] name = "faster-whisper" version = "1.2.0" @@ -658,6 +938,21 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/d7/0c/56be52741f75bad4dc6555991fabd2e07b432d333da82c11ad701123888a/ffmpeg_python-0.2.0-py3-none-any.whl", hash = "sha256:ac441a0404e053f8b6a1113a77c0f452f1cfc62f6344a769475ffdc0f56c23c5", size = 25024, upload-time = "2019-07-06T00:19:07.215Z" }, ] +[[package]] +name = "fiddle" +version = "0.3.0" +source = { registry = "https://pypi.org/simple/" } +dependencies = [ + { name = "absl-py", marker = "platform_machine != 'x86_64' or sys_platform != 'darwin'" }, + { name = "graphviz", marker = "platform_machine != 'x86_64' or sys_platform != 'darwin'" }, + { name = "libcst", marker = "platform_machine != 'x86_64' or sys_platform != 'darwin'" }, + { name = "typing-extensions", marker = "platform_machine != 'x86_64' or sys_platform != 'darwin'" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/73/36/7a4fac76351619b36bbc7937abf59f7b601326dc4efc253b3c16819f782a/fiddle-0.3.0.tar.gz", hash = "sha256:5d083d3299a479868345513385a6c5546141bd92086c15d3dcbf8008a90075d3", size = 277884, upload-time = "2024-04-09T17:23:58.974Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/3b/98/a38e949a91ff9e15874487fd8329ff53c25f3413c0cfc809eb6ff7eb7fa1/fiddle-0.3.0-py3-none-any.whl", hash = "sha256:f4824541c103a94a2f33f6c93eeddf6007c3a7300440087a95907f3e74362e61", size = 419830, upload-time = "2024-04-09T17:23:56.7Z" }, +] + [[package]] name = "filelock" version = "3.20.0" @@ -691,11 +986,59 @@ wheels = [ ] [[package]] -name = "fsspec" -version = "2025.9.0" -source = { registry = "https://download.pytorch.org/whl/cu128" } +name = "fonttools" +version = "4.60.1" +source = { registry = "https://pypi.org/simple/" } +sdist = { url = "https://files.pythonhosted.org/packages/4b/42/97a13e47a1e51a5a7142475bbcf5107fe3a68fc34aef331c897d5fb98ad0/fonttools-4.60.1.tar.gz", hash = "sha256:ef00af0439ebfee806b25f24c8f92109157ff3fac5731dc7867957812e87b8d9", size = 3559823, upload-time = "2025-09-29T21:13:27.129Z" } wheels = [ - { url = "https://download.pytorch.org/whl/fsspec-2025.9.0-py3-none-any.whl" }, + { url = "https://files.pythonhosted.org/packages/e3/f7/a10b101b7a6f8836a5adb47f2791f2075d044a6ca123f35985c42edc82d8/fonttools-4.60.1-cp312-cp312-macosx_10_13_universal2.whl", hash = "sha256:7b0c6d57ab00dae9529f3faf187f2254ea0aa1e04215cf2f1a8ec277c96661bc", size = 2832953, upload-time = "2025-09-29T21:11:39.616Z" }, + { url = "https://files.pythonhosted.org/packages/ed/fe/7bd094b59c926acf2304d2151354ddbeb74b94812f3dc943c231db09cb41/fonttools-4.60.1-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:839565cbf14645952d933853e8ade66a463684ed6ed6c9345d0faf1f0e868877", size = 2352706, upload-time = "2025-09-29T21:11:41.826Z" }, + { url = "https://files.pythonhosted.org/packages/c0/ca/4bb48a26ed95a1e7eba175535fe5805887682140ee0a0d10a88e1de84208/fonttools-4.60.1-cp312-cp312-manylinux1_x86_64.manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_5_x86_64.whl", hash = "sha256:8177ec9676ea6e1793c8a084a90b65a9f778771998eb919d05db6d4b1c0b114c", size = 4923716, upload-time = "2025-09-29T21:11:43.893Z" }, + { url = "https://files.pythonhosted.org/packages/b8/9f/2cb82999f686c1d1ddf06f6ae1a9117a880adbec113611cc9d22b2fdd465/fonttools-4.60.1-cp312-cp312-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:996a4d1834524adbb423385d5a629b868ef9d774670856c63c9a0408a3063401", size = 4968175, upload-time = "2025-09-29T21:11:46.439Z" }, + { url = "https://files.pythonhosted.org/packages/18/79/be569699e37d166b78e6218f2cde8c550204f2505038cdd83b42edc469b9/fonttools-4.60.1-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:a46b2f450bc79e06ef3b6394f0c68660529ed51692606ad7f953fc2e448bc903", size = 4911031, upload-time = "2025-09-29T21:11:48.977Z" }, + { url = "https://files.pythonhosted.org/packages/cc/9f/89411cc116effaec5260ad519162f64f9c150e5522a27cbb05eb62d0c05b/fonttools-4.60.1-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:6ec722ee589e89a89f5b7574f5c45604030aa6ae24cb2c751e2707193b466fed", size = 5062966, upload-time = "2025-09-29T21:11:54.344Z" }, + { url = "https://files.pythonhosted.org/packages/62/a1/f888221934b5731d46cb9991c7a71f30cb1f97c0ef5fcf37f8da8fce6c8e/fonttools-4.60.1-cp312-cp312-win32.whl", hash = "sha256:b2cf105cee600d2de04ca3cfa1f74f1127f8455b71dbad02b9da6ec266e116d6", size = 2218750, upload-time = "2025-09-29T21:11:56.601Z" }, + { url = "https://files.pythonhosted.org/packages/88/8f/a55b5550cd33cd1028601df41acd057d4be20efa5c958f417b0c0613924d/fonttools-4.60.1-cp312-cp312-win_amd64.whl", hash = "sha256:992775c9fbe2cf794786fa0ffca7f09f564ba3499b8fe9f2f80bd7197db60383", size = 2267026, upload-time = "2025-09-29T21:11:58.852Z" }, + { url = "https://files.pythonhosted.org/packages/c7/93/0dd45cd283c32dea1545151d8c3637b4b8c53cdb3a625aeb2885b184d74d/fonttools-4.60.1-py3-none-any.whl", hash = "sha256:906306ac7afe2156fcf0042173d6ebbb05416af70f6b370967b47f8f00103bbb", size = 1143175, upload-time = "2025-09-29T21:13:24.134Z" }, +] + +[[package]] +name = "frozenlist" +version = "1.8.0" +source = { registry = "https://pypi.org/simple/" } +sdist = { url = "https://files.pythonhosted.org/packages/2d/f5/c831fac6cc817d26fd54c7eaccd04ef7e0288806943f7cc5bbf69f3ac1f0/frozenlist-1.8.0.tar.gz", hash = "sha256:3ede829ed8d842f6cd48fc7081d7a41001a56f1f38603f9d49bf3020d59a31ad", size = 45875, upload-time = "2025-10-06T05:38:17.865Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/69/29/948b9aa87e75820a38650af445d2ef2b6b8a6fab1a23b6bb9e4ef0be2d59/frozenlist-1.8.0-cp312-cp312-macosx_10_13_universal2.whl", hash = "sha256:78f7b9e5d6f2fdb88cdde9440dc147259b62b9d3b019924def9f6478be254ac1", size = 87782, upload-time = "2025-10-06T05:36:06.649Z" }, + { url = "https://files.pythonhosted.org/packages/64/80/4f6e318ee2a7c0750ed724fa33a4bdf1eacdc5a39a7a24e818a773cd91af/frozenlist-1.8.0-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:229bf37d2e4acdaf808fd3f06e854a4a7a3661e871b10dc1f8f1896a3b05f18b", size = 50594, upload-time = "2025-10-06T05:36:07.69Z" }, + { url = "https://files.pythonhosted.org/packages/2b/94/5c8a2b50a496b11dd519f4a24cb5496cf125681dd99e94c604ccdea9419a/frozenlist-1.8.0-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:f833670942247a14eafbb675458b4e61c82e002a148f49e68257b79296e865c4", size = 50448, upload-time = "2025-10-06T05:36:08.78Z" }, + { url = "https://files.pythonhosted.org/packages/6a/bd/d91c5e39f490a49df14320f4e8c80161cfcce09f1e2cde1edd16a551abb3/frozenlist-1.8.0-cp312-cp312-manylinux1_x86_64.manylinux_2_28_x86_64.manylinux_2_5_x86_64.whl", hash = "sha256:494a5952b1c597ba44e0e78113a7266e656b9794eec897b19ead706bd7074383", size = 242411, upload-time = "2025-10-06T05:36:09.801Z" }, + { url = "https://files.pythonhosted.org/packages/8f/83/f61505a05109ef3293dfb1ff594d13d64a2324ac3482be2cedc2be818256/frozenlist-1.8.0-cp312-cp312-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:96f423a119f4777a4a056b66ce11527366a8bb92f54e541ade21f2374433f6d4", size = 243014, upload-time = "2025-10-06T05:36:11.394Z" }, + { url = "https://files.pythonhosted.org/packages/d8/cb/cb6c7b0f7d4023ddda30cf56b8b17494eb3a79e3fda666bf735f63118b35/frozenlist-1.8.0-cp312-cp312-manylinux2014_armv7l.manylinux_2_17_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:3462dd9475af2025c31cc61be6652dfa25cbfb56cbbf52f4ccfe029f38decaf8", size = 234909, upload-time = "2025-10-06T05:36:12.598Z" }, + { url = "https://files.pythonhosted.org/packages/31/c5/cd7a1f3b8b34af009fb17d4123c5a778b44ae2804e3ad6b86204255f9ec5/frozenlist-1.8.0-cp312-cp312-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:c4c800524c9cd9bac5166cd6f55285957fcfc907db323e193f2afcd4d9abd69b", size = 250049, upload-time = "2025-10-06T05:36:14.065Z" }, + { url = "https://files.pythonhosted.org/packages/c0/01/2f95d3b416c584a1e7f0e1d6d31998c4a795f7544069ee2e0962a4b60740/frozenlist-1.8.0-cp312-cp312-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:d6a5df73acd3399d893dafc71663ad22534b5aa4f94e8a2fabfe856c3c1b6a52", size = 256485, upload-time = "2025-10-06T05:36:15.39Z" }, + { url = "https://files.pythonhosted.org/packages/ce/03/024bf7720b3abaebcff6d0793d73c154237b85bdf67b7ed55e5e9596dc9a/frozenlist-1.8.0-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:405e8fe955c2280ce66428b3ca55e12b3c4e9c336fb2103a4937e891c69a4a29", size = 237619, upload-time = "2025-10-06T05:36:16.558Z" }, + { url = "https://files.pythonhosted.org/packages/69/fa/f8abdfe7d76b731f5d8bd217827cf6764d4f1d9763407e42717b4bed50a0/frozenlist-1.8.0-cp312-cp312-musllinux_1_2_armv7l.whl", hash = "sha256:908bd3f6439f2fef9e85031b59fd4f1297af54415fb60e4254a95f75b3cab3f3", size = 250320, upload-time = "2025-10-06T05:36:17.821Z" }, + { url = "https://files.pythonhosted.org/packages/f5/3c/b051329f718b463b22613e269ad72138cc256c540f78a6de89452803a47d/frozenlist-1.8.0-cp312-cp312-musllinux_1_2_ppc64le.whl", hash = "sha256:294e487f9ec720bd8ffcebc99d575f7eff3568a08a253d1ee1a0378754b74143", size = 246820, upload-time = "2025-10-06T05:36:19.046Z" }, + { url = "https://files.pythonhosted.org/packages/0f/ae/58282e8f98e444b3f4dd42448ff36fa38bef29e40d40f330b22e7108f565/frozenlist-1.8.0-cp312-cp312-musllinux_1_2_s390x.whl", hash = "sha256:74c51543498289c0c43656701be6b077f4b265868fa7f8a8859c197006efb608", size = 250518, upload-time = "2025-10-06T05:36:20.763Z" }, + { url = "https://files.pythonhosted.org/packages/8f/96/007e5944694d66123183845a106547a15944fbbb7154788cbf7272789536/frozenlist-1.8.0-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:776f352e8329135506a1d6bf16ac3f87bc25b28e765949282dcc627af36123aa", size = 239096, upload-time = "2025-10-06T05:36:22.129Z" }, + { url = "https://files.pythonhosted.org/packages/66/bb/852b9d6db2fa40be96f29c0d1205c306288f0684df8fd26ca1951d461a56/frozenlist-1.8.0-cp312-cp312-win32.whl", hash = "sha256:433403ae80709741ce34038da08511d4a77062aa924baf411ef73d1146e74faf", size = 39985, upload-time = "2025-10-06T05:36:23.661Z" }, + { url = "https://files.pythonhosted.org/packages/b8/af/38e51a553dd66eb064cdf193841f16f077585d4d28394c2fa6235cb41765/frozenlist-1.8.0-cp312-cp312-win_amd64.whl", hash = "sha256:34187385b08f866104f0c0617404c8eb08165ab1272e884abc89c112e9c00746", size = 44591, upload-time = "2025-10-06T05:36:24.958Z" }, + { url = "https://files.pythonhosted.org/packages/a7/06/1dc65480ab147339fecc70797e9c2f69d9cea9cf38934ce08df070fdb9cb/frozenlist-1.8.0-cp312-cp312-win_arm64.whl", hash = "sha256:fe3c58d2f5db5fbd18c2987cba06d51b0529f52bc3a6cdc33d3f4eab725104bd", size = 40102, upload-time = "2025-10-06T05:36:26.333Z" }, + { url = "https://files.pythonhosted.org/packages/9a/9a/e35b4a917281c0b8419d4207f4334c8e8c5dbf4f3f5f9ada73958d937dcc/frozenlist-1.8.0-py3-none-any.whl", hash = "sha256:0c18a16eab41e82c295618a77502e17b195883241c563b00f0aa5106fc4eaa0d", size = 13409, upload-time = "2025-10-06T05:38:16.721Z" }, +] + +[[package]] +name = "fsspec" +version = "2024.12.0" +source = { registry = "https://pypi.org/simple/" } +sdist = { url = "https://files.pythonhosted.org/packages/ee/11/de70dee31455c546fbc88301971ec03c328f3d1138cfba14263f651e9551/fsspec-2024.12.0.tar.gz", hash = "sha256:670700c977ed2fb51e0d9f9253177ed20cbde4a3e5c0283cc5385b5870c8533f", size = 291600, upload-time = "2024-12-19T19:57:30.333Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/de/86/5486b0188d08aa643e127774a99bac51ffa6cf343e3deb0583956dca5b22/fsspec-2024.12.0-py3-none-any.whl", hash = "sha256:b520aed47ad9804237ff878b504267a3b0b441e97508bd6d2d8774e3db85cee2", size = 183862, upload-time = "2024-12-19T19:57:28.258Z" }, +] + +[package.optional-dependencies] +http = [ + { name = "aiohttp", marker = "platform_machine != 'x86_64' or sys_platform != 'darwin'" }, ] [[package]] @@ -707,6 +1050,79 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/da/71/ae30dadffc90b9006d77af76b393cb9dfbfc9629f339fc1574a1c52e6806/future-1.0.0-py3-none-any.whl", hash = "sha256:929292d34f5872e70396626ef385ec22355a1fae8ad29e1a734c3e43f9fbc216", size = 491326, upload-time = "2024-02-21T11:52:35.956Z" }, ] +[[package]] +name = "gitdb" +version = "4.0.12" +source = { registry = "https://pypi.org/simple/" } +dependencies = [ + { name = "smmap", marker = "platform_machine != 'x86_64' or sys_platform != 'darwin'" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/72/94/63b0fc47eb32792c7ba1fe1b694daec9a63620db1e313033d18140c2320a/gitdb-4.0.12.tar.gz", hash = "sha256:5ef71f855d191a3326fcfbc0d5da835f26b13fbcba60c32c21091c349ffdb571", size = 394684, upload-time = "2025-01-02T07:20:46.413Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/a0/61/5c78b91c3143ed5c14207f463aecfc8f9dbb5092fb2869baf37c273b2705/gitdb-4.0.12-py3-none-any.whl", hash = "sha256:67073e15955400952c6565cc3e707c554a4eea2e428946f7a4c162fab9bd9bcf", size = 62794, upload-time = "2025-01-02T07:20:43.624Z" }, +] + +[[package]] +name = "gitpython" +version = "3.1.45" +source = { registry = "https://pypi.org/simple/" } +dependencies = [ + { name = "gitdb", marker = "platform_machine != 'x86_64' or sys_platform != 'darwin'" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/9a/c8/dd58967d119baab745caec2f9d853297cec1989ec1d63f677d3880632b88/gitpython-3.1.45.tar.gz", hash = "sha256:85b0ee964ceddf211c41b9f27a49086010a190fd8132a24e21f362a4b36a791c", size = 215076, upload-time = "2025-07-24T03:45:54.871Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/01/61/d4b89fec821f72385526e1b9d9a3a0385dda4a72b206d28049e2c7cd39b8/gitpython-3.1.45-py3-none-any.whl", hash = "sha256:8908cb2e02fb3b93b7eb0f2827125cb699869470432cc885f019b8fd0fccff77", size = 208168, upload-time = "2025-07-24T03:45:52.517Z" }, +] + +[[package]] +name = "graphviz" +version = "0.21" +source = { registry = "https://pypi.org/simple/" } +sdist = { url = "https://files.pythonhosted.org/packages/f8/b3/3ac91e9be6b761a4b30d66ff165e54439dcd48b83f4e20d644867215f6ca/graphviz-0.21.tar.gz", hash = "sha256:20743e7183be82aaaa8ad6c93f8893c923bd6658a04c32ee115edb3c8a835f78", size = 200434, upload-time = "2025-06-15T09:35:05.824Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/91/4c/e0ce1ef95d4000ebc1c11801f9b944fa5910ecc15b5e351865763d8657f8/graphviz-0.21-py3-none-any.whl", hash = "sha256:54f33de9f4f911d7e84e4191749cac8cc5653f815b06738c54db9a15ab8b1e42", size = 47300, upload-time = "2025-06-15T09:35:04.433Z" }, +] + +[[package]] +name = "greenlet" +version = "3.2.4" +source = { registry = "https://pypi.org/simple/" } +sdist = { url = "https://files.pythonhosted.org/packages/03/b8/704d753a5a45507a7aab61f18db9509302ed3d0a27ac7e0359ec2905b1a6/greenlet-3.2.4.tar.gz", hash = "sha256:0dca0d95ff849f9a364385f36ab49f50065d76964944638be9691e1832e9f86d", size = 188260, upload-time = "2025-08-07T13:24:33.51Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/44/69/9b804adb5fd0671f367781560eb5eb586c4d495277c93bde4307b9e28068/greenlet-3.2.4-cp312-cp312-macosx_11_0_universal2.whl", hash = "sha256:3b67ca49f54cede0186854a008109d6ee71f66bd57bb36abd6d0a0267b540cdd", size = 274079, upload-time = "2025-08-07T13:15:45.033Z" }, + { url = "https://files.pythonhosted.org/packages/46/e9/d2a80c99f19a153eff70bc451ab78615583b8dac0754cfb942223d2c1a0d/greenlet-3.2.4-cp312-cp312-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:ddf9164e7a5b08e9d22511526865780a576f19ddd00d62f8a665949327fde8bb", size = 640997, upload-time = "2025-08-07T13:42:56.234Z" }, + { url = "https://files.pythonhosted.org/packages/3b/16/035dcfcc48715ccd345f3a93183267167cdd162ad123cd93067d86f27ce4/greenlet-3.2.4-cp312-cp312-manylinux2014_ppc64le.manylinux_2_17_ppc64le.whl", hash = "sha256:f28588772bb5fb869a8eb331374ec06f24a83a9c25bfa1f38b6993afe9c1e968", size = 655185, upload-time = "2025-08-07T13:45:27.624Z" }, + { url = "https://files.pythonhosted.org/packages/31/da/0386695eef69ffae1ad726881571dfe28b41970173947e7c558d9998de0f/greenlet-3.2.4-cp312-cp312-manylinux2014_s390x.manylinux_2_17_s390x.whl", hash = "sha256:5c9320971821a7cb77cfab8d956fa8e39cd07ca44b6070db358ceb7f8797c8c9", size = 649926, upload-time = "2025-08-07T13:53:15.251Z" }, + { url = "https://files.pythonhosted.org/packages/68/88/69bf19fd4dc19981928ceacbc5fd4bb6bc2215d53199e367832e98d1d8fe/greenlet-3.2.4-cp312-cp312-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:c60a6d84229b271d44b70fb6e5fa23781abb5d742af7b808ae3f6efd7c9c60f6", size = 651839, upload-time = "2025-08-07T13:18:30.281Z" }, + { url = "https://files.pythonhosted.org/packages/19/0d/6660d55f7373b2ff8152401a83e02084956da23ae58cddbfb0b330978fe9/greenlet-3.2.4-cp312-cp312-manylinux_2_24_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:3b3812d8d0c9579967815af437d96623f45c0f2ae5f04e366de62a12d83a8fb0", size = 607586, upload-time = "2025-08-07T13:18:28.544Z" }, + { url = "https://files.pythonhosted.org/packages/8e/1a/c953fdedd22d81ee4629afbb38d2f9d71e37d23caace44775a3a969147d4/greenlet-3.2.4-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:abbf57b5a870d30c4675928c37278493044d7c14378350b3aa5d484fa65575f0", size = 1123281, upload-time = "2025-08-07T13:42:39.858Z" }, + { url = "https://files.pythonhosted.org/packages/3f/c7/12381b18e21aef2c6bd3a636da1088b888b97b7a0362fac2e4de92405f97/greenlet-3.2.4-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:20fb936b4652b6e307b8f347665e2c615540d4b42b3b4c8a321d8286da7e520f", size = 1151142, upload-time = "2025-08-07T13:18:22.981Z" }, + { url = "https://files.pythonhosted.org/packages/27/45/80935968b53cfd3f33cf99ea5f08227f2646e044568c9b1555b58ffd61c2/greenlet-3.2.4-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:ee7a6ec486883397d70eec05059353b8e83eca9168b9f3f9a361971e77e0bcd0", size = 1564846, upload-time = "2025-11-04T12:42:15.191Z" }, + { url = "https://files.pythonhosted.org/packages/69/02/b7c30e5e04752cb4db6202a3858b149c0710e5453b71a3b2aec5d78a1aab/greenlet-3.2.4-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:326d234cbf337c9c3def0676412eb7040a35a768efc92504b947b3e9cfc7543d", size = 1633814, upload-time = "2025-11-04T12:42:17.175Z" }, + { url = "https://files.pythonhosted.org/packages/e9/08/b0814846b79399e585f974bbeebf5580fbe59e258ea7be64d9dfb253c84f/greenlet-3.2.4-cp312-cp312-win_amd64.whl", hash = "sha256:a7d4e128405eea3814a12cc2605e0e6aedb4035bf32697f72deca74de4105e02", size = 299899, upload-time = "2025-08-07T13:38:53.448Z" }, +] + +[[package]] +name = "grpcio" +version = "1.76.0" +source = { registry = "https://pypi.org/simple/" } +dependencies = [ + { name = "typing-extensions", marker = "platform_machine != 'x86_64' or sys_platform != 'darwin'" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/b6/e0/318c1ce3ae5a17894d5791e87aea147587c9e702f24122cc7a5c8bbaeeb1/grpcio-1.76.0.tar.gz", hash = "sha256:7be78388d6da1a25c0d5ec506523db58b18be22d9c37d8d3a32c08be4987bd73", size = 12785182, upload-time = "2025-10-21T16:23:12.106Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/bf/05/8e29121994b8d959ffa0afd28996d452f291b48cfc0875619de0bde2c50c/grpcio-1.76.0-cp312-cp312-linux_armv7l.whl", hash = "sha256:81fd9652b37b36f16138611c7e884eb82e0cec137c40d3ef7c3f9b3ed00f6ed8", size = 5799718, upload-time = "2025-10-21T16:21:17.939Z" }, + { url = "https://files.pythonhosted.org/packages/d9/75/11d0e66b3cdf998c996489581bdad8900db79ebd83513e45c19548f1cba4/grpcio-1.76.0-cp312-cp312-macosx_11_0_universal2.whl", hash = "sha256:04bbe1bfe3a68bbfd4e52402ab7d4eb59d72d02647ae2042204326cf4bbad280", size = 11825627, upload-time = "2025-10-21T16:21:20.466Z" }, + { url = "https://files.pythonhosted.org/packages/28/50/2f0aa0498bc188048f5d9504dcc5c2c24f2eb1a9337cd0fa09a61a2e75f0/grpcio-1.76.0-cp312-cp312-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:d388087771c837cdb6515539f43b9d4bf0b0f23593a24054ac16f7a960be16f4", size = 6359167, upload-time = "2025-10-21T16:21:23.122Z" }, + { url = "https://files.pythonhosted.org/packages/66/e5/bbf0bb97d29ede1d59d6588af40018cfc345b17ce979b7b45424628dc8bb/grpcio-1.76.0-cp312-cp312-manylinux2014_i686.manylinux_2_17_i686.whl", hash = "sha256:9f8f757bebaaea112c00dba718fc0d3260052ce714e25804a03f93f5d1c6cc11", size = 7044267, upload-time = "2025-10-21T16:21:25.995Z" }, + { url = "https://files.pythonhosted.org/packages/f5/86/f6ec2164f743d9609691115ae8ece098c76b894ebe4f7c94a655c6b03e98/grpcio-1.76.0-cp312-cp312-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:980a846182ce88c4f2f7e2c22c56aefd515daeb36149d1c897f83cf57999e0b6", size = 6573963, upload-time = "2025-10-21T16:21:28.631Z" }, + { url = "https://files.pythonhosted.org/packages/60/bc/8d9d0d8505feccfdf38a766d262c71e73639c165b311c9457208b56d92ae/grpcio-1.76.0-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:f92f88e6c033db65a5ae3d97905c8fea9c725b63e28d5a75cb73b49bda5024d8", size = 7164484, upload-time = "2025-10-21T16:21:30.837Z" }, + { url = "https://files.pythonhosted.org/packages/67/e6/5d6c2fc10b95edf6df9b8f19cf10a34263b7fd48493936fffd5085521292/grpcio-1.76.0-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:4baf3cbe2f0be3289eb68ac8ae771156971848bb8aaff60bad42005539431980", size = 8127777, upload-time = "2025-10-21T16:21:33.577Z" }, + { url = "https://files.pythonhosted.org/packages/3f/c8/dce8ff21c86abe025efe304d9e31fdb0deaaa3b502b6a78141080f206da0/grpcio-1.76.0-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:615ba64c208aaceb5ec83bfdce7728b80bfeb8be97562944836a7a0a9647d882", size = 7594014, upload-time = "2025-10-21T16:21:41.882Z" }, + { url = "https://files.pythonhosted.org/packages/e0/42/ad28191ebf983a5d0ecef90bab66baa5a6b18f2bfdef9d0a63b1973d9f75/grpcio-1.76.0-cp312-cp312-win32.whl", hash = "sha256:45d59a649a82df5718fd9527ce775fd66d1af35e6d31abdcdc906a49c6822958", size = 3984750, upload-time = "2025-10-21T16:21:44.006Z" }, + { url = "https://files.pythonhosted.org/packages/9e/00/7bd478cbb851c04a48baccaa49b75abaa8e4122f7d86da797500cccdd771/grpcio-1.76.0-cp312-cp312-win_amd64.whl", hash = "sha256:c088e7a90b6017307f423efbb9d1ba97a22aa2170876223f9709e9d1de0b5347", size = 4704003, upload-time = "2025-10-21T16:21:46.244Z" }, +] + [[package]] name = "h11" version = "0.16.0" @@ -859,6 +1275,28 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/0e/61/66938bbb5fc52dbdf84594873d5b51fb1f7c7794e9c0f5bd885f30bc507b/idna-3.11-py3-none-any.whl", hash = "sha256:771a87f49d9defaf64091e6e6fe9c18d4833f140bd19464795bc32d966ca37ea", size = 71008, upload-time = "2025-10-12T14:55:18.883Z" }, ] +[[package]] +name = "indic-numtowords" +version = "1.1.0" +source = { registry = "https://pypi.org/simple/" } +sdist = { url = "https://files.pythonhosted.org/packages/aa/46/683e92580d9c1752917d2f9ec2a44d2adc21cdfe4deeaa0fe87fc23dbea8/indic_numtowords-1.1.0.tar.gz", hash = "sha256:d1addc21444c332e05bfd8726af427960c096c2a16776d98bee4fbc36ade5d25", size = 44220, upload-time = "2025-08-18T12:24:13.075Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/1e/16/b2b6491d95a15bda712163b4e27428f2cb1ac3a1b4fb59b140dbc76f6ce5/indic_numtowords-1.1.0-py3-none-any.whl", hash = "sha256:bf4b7b9e539323d9b00bc868caa2d9369170b8f3ac4d19619bf9c6cdc6f89572", size = 71635, upload-time = "2025-08-18T12:24:11.065Z" }, +] + +[[package]] +name = "inflect" +version = "7.5.0" +source = { registry = "https://pypi.org/simple/" } +dependencies = [ + { name = "more-itertools", marker = "platform_machine != 'x86_64' or sys_platform != 'darwin'" }, + { name = "typeguard", marker = "platform_machine != 'x86_64' or sys_platform != 'darwin'" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/78/c6/943357d44a21fd995723d07ccaddd78023eace03c1846049a2645d4324a3/inflect-7.5.0.tar.gz", hash = "sha256:faf19801c3742ed5a05a8ce388e0d8fe1a07f8d095c82201eb904f5d27ad571f", size = 73751, upload-time = "2024-12-28T17:11:18.897Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/8a/eb/427ed2b20a38a4ee29f24dbe4ae2dafab198674fe9a85e3d6adf9e5f5f41/inflect-7.5.0-py3-none-any.whl", hash = "sha256:2aea70e5e70c35d8350b8097396ec155ffd68def678c7ff97f51aa69c1d92344", size = 35197, upload-time = "2024-12-28T17:11:15.931Z" }, +] + [[package]] name = "iniconfig" version = "2.3.0" @@ -868,6 +1306,48 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/cb/b1/3846dd7f199d53cb17f49cba7e651e9ce294d8497c8c150530ed11865bb8/iniconfig-2.3.0-py3-none-any.whl", hash = "sha256:f631c04d2c48c52b84d0d0549c99ff3859c98df65b3101406327ecc7d53fbf12", size = 7484, upload-time = "2025-10-18T21:55:41.639Z" }, ] +[[package]] +name = "intervaltree" +version = "3.1.0" +source = { registry = "https://pypi.org/simple/" } +dependencies = [ + { name = "sortedcontainers" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/50/fb/396d568039d21344639db96d940d40eb62befe704ef849b27949ded5c3bb/intervaltree-3.1.0.tar.gz", hash = "sha256:902b1b88936918f9b2a19e0e5eb7ccb430ae45cde4f39ea4b36932920d33952d", size = 32861, upload-time = "2020-08-03T08:01:11.392Z" } + +[[package]] +name = "ipython" +version = "9.7.0" +source = { registry = "https://pypi.org/simple/" } +dependencies = [ + { name = "colorama", marker = "sys_platform == 'win32'" }, + { name = "decorator", marker = "platform_machine != 'x86_64' or sys_platform != 'darwin'" }, + { name = "ipython-pygments-lexers", marker = "platform_machine != 'x86_64' or sys_platform != 'darwin'" }, + { name = "jedi", marker = "platform_machine != 'x86_64' or sys_platform != 'darwin'" }, + { name = "matplotlib-inline", marker = "platform_machine != 'x86_64' or sys_platform != 'darwin'" }, + { name = "pexpect", marker = "(platform_machine != 'x86_64' and sys_platform == 'darwin') or (sys_platform != 'darwin' and sys_platform != 'emscripten' and sys_platform != 'win32')" }, + { name = "prompt-toolkit", marker = "platform_machine != 'x86_64' or sys_platform != 'darwin'" }, + { name = "pygments", marker = "platform_machine != 'x86_64' or sys_platform != 'darwin'" }, + { name = "stack-data", marker = "platform_machine != 'x86_64' or sys_platform != 'darwin'" }, + { name = "traitlets", marker = "platform_machine != 'x86_64' or sys_platform != 'darwin'" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/29/e6/48c74d54039241a456add616464ea28c6ebf782e4110d419411b83dae06f/ipython-9.7.0.tar.gz", hash = "sha256:5f6de88c905a566c6a9d6c400a8fed54a638e1f7543d17aae2551133216b1e4e", size = 4422115, upload-time = "2025-11-05T12:18:54.646Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/05/aa/62893d6a591d337aa59dcc4c6f6c842f1fe20cd72c8c5c1f980255243252/ipython-9.7.0-py3-none-any.whl", hash = "sha256:bce8ac85eb9521adc94e1845b4c03d88365fd6ac2f4908ec4ed1eb1b0a065f9f", size = 618911, upload-time = "2025-11-05T12:18:52.484Z" }, +] + +[[package]] +name = "ipython-pygments-lexers" +version = "1.1.1" +source = { registry = "https://pypi.org/simple/" } +dependencies = [ + { name = "pygments", marker = "platform_machine != 'x86_64' or sys_platform != 'darwin'" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/ef/4c/5dd1d8af08107f88c7f741ead7a40854b8ac24ddf9ae850afbcf698aa552/ipython_pygments_lexers-1.1.1.tar.gz", hash = "sha256:09c0138009e56b6854f9535736f4171d855c8c08a563a0dcd8022f78355c7e81", size = 8393, upload-time = "2025-01-17T11:24:34.505Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/d9/33/1f075bf72b0b747cb3288d011319aaf64083cf2efef8354174e3ed4540e2/ipython_pygments_lexers-1.1.1-py3-none-any.whl", hash = "sha256:a9462224a505ade19a605f71f8fa63c2048833ce50abc86768a0d81d876dc81c", size = 8074, upload-time = "2025-01-17T11:24:33.271Z" }, +] + [[package]] name = "isort" version = "5.13.2" @@ -910,6 +1390,18 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/b4/09/726f168acad366b11e420df31bf1c702a54d373a83f968d94141a8c3fde0/jaraco_functools-4.3.0-py3-none-any.whl", hash = "sha256:227ff8ed6f7b8f62c56deff101545fa7543cf2c8e7b82a7c2116e672f29c26e8", size = 10408, upload-time = "2025-08-18T20:05:08.69Z" }, ] +[[package]] +name = "jedi" +version = "0.19.2" +source = { registry = "https://pypi.org/simple/" } +dependencies = [ + { name = "parso", marker = "platform_machine != 'x86_64' or sys_platform != 'darwin'" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/72/3a/79a912fbd4d8dd6fbb02bf69afd3bb72cf0c729bb3063c6f4498603db17a/jedi-0.19.2.tar.gz", hash = "sha256:4770dc3de41bde3966b02eb84fbcf557fb33cce26ad23da12c742fb50ecb11f0", size = 1231287, upload-time = "2024-11-11T01:41:42.873Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/c0/5a/9cac0c82afec3d09ccd97c8b6502d48f165f9124db81b4bcb90b4af974ee/jedi-0.19.2-py2.py3-none-any.whl", hash = "sha256:a8ef22bde8490f57fe5c7681a3c83cb58874daf72b4784de3cce5b6ef6edb5b9", size = 1572278, upload-time = "2024-11-11T01:41:40.175Z" }, +] + [[package]] name = "jeepney" version = "0.9.0" @@ -955,6 +1447,28 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/d9/71/71408b02c6133153336d29fa3ba53000f1e1a3f78bb2fc2d1a1865d2e743/jiter-0.11.1-graalpy312-graalpy250_312_native-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:18c77aaa9117510d5bdc6a946baf21b1f0cfa58ef04d31c8d016f206f2118960", size = 343697, upload-time = "2025-10-17T11:31:13.773Z" }, ] +[[package]] +name = "jiwer" +version = "3.1.0" +source = { registry = "https://pypi.org/simple/" } +dependencies = [ + { name = "click", marker = "platform_machine != 'x86_64' or sys_platform != 'darwin'" }, + { name = "rapidfuzz", marker = "platform_machine != 'x86_64' or sys_platform != 'darwin'" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/85/3e/71b95cf0e2179fb5de8744a79fd36c8bd4e02e1803129a16d423884b6654/jiwer-3.1.0.tar.gz", hash = "sha256:dc492d09e570f1baba98c76aba09baf8e09c06e6808a4ba412dd4bde67fb79ac", size = 103187, upload-time = "2025-01-31T12:14:10.86Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/ba/f4/35634d9eeff3b0bab51f5b9474ee569b1186bf29cf0d9d67b84acc80c53d/jiwer-3.1.0-py3-none-any.whl", hash = "sha256:5a14b5bba4692e1946ca3c6946435f7d90b1b526076ccb6c12be763e2146237d", size = 22303, upload-time = "2025-01-31T12:14:08.893Z" }, +] + +[[package]] +name = "joblib" +version = "1.5.2" +source = { registry = "https://pypi.org/simple/" } +sdist = { url = "https://files.pythonhosted.org/packages/e8/5d/447af5ea094b9e4c4054f82e223ada074c552335b9b4b2d14bd9b35a67c4/joblib-1.5.2.tar.gz", hash = "sha256:3faa5c39054b2f03ca547da9b2f52fde67c06240c31853f306aea97f13647b55", size = 331077, upload-time = "2025-08-27T12:15:46.575Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/1e/e8/685f47e0d754320684db4425a0967f7d3fa70126bffd76110b7009a0090f/joblib-1.5.2-py3-none-any.whl", hash = "sha256:4e1f0bdbb987e6d843c70cf43714cb276623def372df3c22fe5266b2670bc241", size = 308396, upload-time = "2025-08-27T12:15:45.188Z" }, +] + [[package]] name = "jsonschema" version = "4.25.1" @@ -993,6 +1507,15 @@ dependencies = [ ] sdist = { url = "https://files.pythonhosted.org/packages/a1/19/c9e1596b5572c786b93428d0904280e964c930fae7e6c9368ed9e1b63922/julius-0.2.7.tar.gz", hash = "sha256:3c0f5f5306d7d6016fcc95196b274cae6f07e2c9596eed314e4e7641554fbb08", size = 59640, upload-time = "2022-09-19T16:13:34.2Z" } +[[package]] +name = "kaldi-python-io" +version = "1.2.2" +source = { registry = "https://pypi.org/simple/" } +dependencies = [ + { name = "numpy", marker = "platform_machine != 'x86_64' or sys_platform != 'darwin'" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/80/45/e3e542ffa8970ebd782fcece35e2295de9c60e8c396c2c1a403410d1b24e/kaldi-python-io-1.2.2.tar.gz", hash = "sha256:4ebb4029c6c58296cc0abf96edff02832ba341d290ed37624a8d00105f0f7c00", size = 8814, upload-time = "2021-03-18T12:02:05.832Z" } + [[package]] name = "keyring" version = "25.6.0" @@ -1010,6 +1533,27 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/d3/32/da7f44bcb1105d3e88a0b74ebdca50c59121d2ddf71c9e34ba47df7f3a56/keyring-25.6.0-py3-none-any.whl", hash = "sha256:552a3f7af126ece7ed5c89753650eec89c7eaae8617d0aa4d9ad2b75111266bd", size = 39085, upload-time = "2024-12-25T15:26:44.377Z" }, ] +[[package]] +name = "kiwisolver" +version = "1.4.9" +source = { registry = "https://pypi.org/simple/" } +sdist = { url = "https://files.pythonhosted.org/packages/5c/3c/85844f1b0feb11ee581ac23fe5fce65cd049a200c1446708cc1b7f922875/kiwisolver-1.4.9.tar.gz", hash = "sha256:c3b22c26c6fd6811b0ae8363b95ca8ce4ea3c202d3d0975b2914310ceb1bcc4d", size = 97564, upload-time = "2025-08-10T21:27:49.279Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/86/c9/13573a747838aeb1c76e3267620daa054f4152444d1f3d1a2324b78255b5/kiwisolver-1.4.9-cp312-cp312-macosx_10_13_universal2.whl", hash = "sha256:ac5a486ac389dddcc5bef4f365b6ae3ffff2c433324fb38dd35e3fab7c957999", size = 123686, upload-time = "2025-08-10T21:26:10.034Z" }, + { url = "https://files.pythonhosted.org/packages/51/ea/2ecf727927f103ffd1739271ca19c424d0e65ea473fbaeea1c014aea93f6/kiwisolver-1.4.9-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:f2ba92255faa7309d06fe44c3a4a97efe1c8d640c2a79a5ef728b685762a6fd2", size = 66460, upload-time = "2025-08-10T21:26:11.083Z" }, + { url = "https://files.pythonhosted.org/packages/5b/5a/51f5464373ce2aeb5194508298a508b6f21d3867f499556263c64c621914/kiwisolver-1.4.9-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:4a2899935e724dd1074cb568ce7ac0dce28b2cd6ab539c8e001a8578eb106d14", size = 64952, upload-time = "2025-08-10T21:26:12.058Z" }, + { url = "https://files.pythonhosted.org/packages/70/90/6d240beb0f24b74371762873e9b7f499f1e02166a2d9c5801f4dbf8fa12e/kiwisolver-1.4.9-cp312-cp312-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:f6008a4919fdbc0b0097089f67a1eb55d950ed7e90ce2cc3e640abadd2757a04", size = 1474756, upload-time = "2025-08-10T21:26:13.096Z" }, + { url = "https://files.pythonhosted.org/packages/12/42/f36816eaf465220f683fb711efdd1bbf7a7005a2473d0e4ed421389bd26c/kiwisolver-1.4.9-cp312-cp312-manylinux_2_24_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:67bb8b474b4181770f926f7b7d2f8c0248cbcb78b660fdd41a47054b28d2a752", size = 1276404, upload-time = "2025-08-10T21:26:14.457Z" }, + { url = "https://files.pythonhosted.org/packages/2e/64/bc2de94800adc830c476dce44e9b40fd0809cddeef1fde9fcf0f73da301f/kiwisolver-1.4.9-cp312-cp312-manylinux_2_24_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:2327a4a30d3ee07d2fbe2e7933e8a37c591663b96ce42a00bc67461a87d7df77", size = 1294410, upload-time = "2025-08-10T21:26:15.73Z" }, + { url = "https://files.pythonhosted.org/packages/5f/42/2dc82330a70aa8e55b6d395b11018045e58d0bb00834502bf11509f79091/kiwisolver-1.4.9-cp312-cp312-manylinux_2_24_s390x.manylinux_2_28_s390x.whl", hash = "sha256:7a08b491ec91b1d5053ac177afe5290adacf1f0f6307d771ccac5de30592d198", size = 1343631, upload-time = "2025-08-10T21:26:17.045Z" }, + { url = "https://files.pythonhosted.org/packages/22/fd/f4c67a6ed1aab149ec5a8a401c323cee7a1cbe364381bb6c9c0d564e0e20/kiwisolver-1.4.9-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:d8fc5c867c22b828001b6a38d2eaeb88160bf5783c6cb4a5e440efc981ce286d", size = 2224963, upload-time = "2025-08-10T21:26:18.737Z" }, + { url = "https://files.pythonhosted.org/packages/45/aa/76720bd4cb3713314677d9ec94dcc21ced3f1baf4830adde5bb9b2430a5f/kiwisolver-1.4.9-cp312-cp312-musllinux_1_2_ppc64le.whl", hash = "sha256:3b3115b2581ea35bb6d1f24a4c90af37e5d9b49dcff267eeed14c3893c5b86ab", size = 2321295, upload-time = "2025-08-10T21:26:20.11Z" }, + { url = "https://files.pythonhosted.org/packages/80/19/d3ec0d9ab711242f56ae0dc2fc5d70e298bb4a1f9dfab44c027668c673a1/kiwisolver-1.4.9-cp312-cp312-musllinux_1_2_s390x.whl", hash = "sha256:858e4c22fb075920b96a291928cb7dea5644e94c0ee4fcd5af7e865655e4ccf2", size = 2487987, upload-time = "2025-08-10T21:26:21.49Z" }, + { url = "https://files.pythonhosted.org/packages/39/e9/61e4813b2c97e86b6fdbd4dd824bf72d28bcd8d4849b8084a357bc0dd64d/kiwisolver-1.4.9-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:ed0fecd28cc62c54b262e3736f8bb2512d8dcfdc2bcf08be5f47f96bf405b145", size = 2291817, upload-time = "2025-08-10T21:26:22.812Z" }, + { url = "https://files.pythonhosted.org/packages/a0/41/85d82b0291db7504da3c2defe35c9a8a5c9803a730f297bd823d11d5fb77/kiwisolver-1.4.9-cp312-cp312-win_amd64.whl", hash = "sha256:f68208a520c3d86ea51acf688a3e3002615a7f0238002cccc17affecc86a8a54", size = 73895, upload-time = "2025-08-10T21:26:24.37Z" }, + { url = "https://files.pythonhosted.org/packages/e2/92/5f3068cf15ee5cb624a0c7596e67e2a0bb2adee33f71c379054a491d07da/kiwisolver-1.4.9-cp312-cp312-win_arm64.whl", hash = "sha256:2c1a4f57df73965f3f14df20b80ee29e6a7930a57d2d9e8491a25f676e197c60", size = 64992, upload-time = "2025-08-10T21:26:25.732Z" }, +] + [[package]] name = "lameenc" version = "1.8.1" @@ -1023,6 +1567,18 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/3f/c6/919e890cc135d590dc3b041414ef5a94997f3bc2f614afa16b7c2f0f73ee/lameenc-1.8.1-cp312-cp312-win_amd64.whl", hash = "sha256:715e0e72ed5429f00042379e48a7903e54ee5dc01069db34338536f3595059c3", size = 152019, upload-time = "2025-01-01T22:07:33.231Z" }, ] +[[package]] +name = "lazy-loader" +version = "0.4" +source = { registry = "https://pypi.org/simple/" } +dependencies = [ + { name = "packaging", marker = "platform_machine != 'x86_64' or sys_platform != 'darwin'" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/6f/6b/c875b30a1ba490860c93da4cabf479e03f584eba06fe5963f6f6644653d8/lazy_loader-0.4.tar.gz", hash = "sha256:47c75182589b91a4e1a85a136c074285a5ad4d9f39c63e0d7fb76391c4574cd1", size = 15431, upload-time = "2024-04-05T13:03:12.261Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/83/60/d497a310bde3f01cb805196ac61b7ad6dc5dcf8dce66634dc34364b20b4f/lazy_loader-0.4-py3-none-any.whl", hash = "sha256:342aa8e14d543a154047afb4ba8ef17f5563baad3fc610d7b15b213b0f119efc", size = 12097, upload-time = "2024-04-05T13:03:10.514Z" }, +] + [[package]] name = "lazy-object-proxy" version = "1.12.0" @@ -1037,6 +1593,147 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/5d/aa/f02be9bbfb270e13ee608c2b28b8771f20a5f64356c6d9317b20043c6129/lazy_object_proxy-1.12.0-cp312-cp312-win_amd64.whl", hash = "sha256:53c7fd99eb156bbb82cbc5d5188891d8fdd805ba6c1e3b92b90092da2a837073", size = 26563, upload-time = "2025-08-22T13:42:43.685Z" }, ] +[[package]] +name = "levenshtein" +version = "0.27.3" +source = { registry = "https://pypi.org/simple/" } +dependencies = [ + { name = "rapidfuzz", marker = "platform_machine != 'x86_64' or sys_platform != 'darwin'" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/82/56/dcf68853b062e3b94bdc3d011cc4198779abc5b9dc134146a062920ce2e2/levenshtein-0.27.3.tar.gz", hash = "sha256:1ac326b2c84215795163d8a5af471188918b8797b4953ec87aaba22c9c1f9fc0", size = 393269, upload-time = "2025-11-01T12:14:31.04Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/7c/8e/3be9d8e0245704e3af5258fb6cb157c3d59902e1351e95edf6ed8a8c0434/levenshtein-0.27.3-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:2de7f095b0ca8e44de9de986ccba661cd0dec3511c751b499e76b60da46805e9", size = 169622, upload-time = "2025-11-01T12:13:10.026Z" }, + { url = "https://files.pythonhosted.org/packages/a6/42/a2b2fda5e8caf6ecd5aac142f946a77574a3961e65da62c12fd7e48e5cb1/levenshtein-0.27.3-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:d9b8b29e5d5145a3c958664c85151b1bb4b26e4ca764380b947e6a96a321217c", size = 159183, upload-time = "2025-11-01T12:13:11.197Z" }, + { url = "https://files.pythonhosted.org/packages/eb/c4/f083fabbd61c449752df1746533538f4a8629e8811931b52f66e6c4290ad/levenshtein-0.27.3-cp312-cp312-manylinux_2_24_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:fc975465a51b1c5889eadee1a583b81fba46372b4b22df28973e49e8ddb8f54a", size = 133120, upload-time = "2025-11-01T12:13:12.363Z" }, + { url = "https://files.pythonhosted.org/packages/4e/e5/b6421e04cb0629615b8efd6d4d167dd2b1afb5097b87bb83cd992004dcca/levenshtein-0.27.3-cp312-cp312-manylinux_2_24_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:57573ed885118554770979fdee584071b66103f6d50beddeabb54607a1213d81", size = 114988, upload-time = "2025-11-01T12:13:13.486Z" }, + { url = "https://files.pythonhosted.org/packages/e5/77/39ee0e8d3028e90178e1031530ccc98563f8f2f0d905ec784669dcf0fa90/levenshtein-0.27.3-cp312-cp312-manylinux_2_24_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:23aff800a6dd5d91bb3754a6092085aa7ad46b28e497682c155c74f681cfaa2d", size = 153346, upload-time = "2025-11-01T12:13:14.744Z" }, + { url = "https://files.pythonhosted.org/packages/3c/0d/c0f367bbd260dbd7a4e134fd21f459e0f5eac43deac507952b46a1d8a93a/levenshtein-0.27.3-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:c08a952432b8ad9dccb145f812176db94c52cda732311ddc08d29fd3bf185b0a", size = 1114538, upload-time = "2025-11-01T12:13:15.851Z" }, + { url = "https://files.pythonhosted.org/packages/d8/ef/ae71433f7b4db0bd2af7974785e36cdec899919203fb82e647c5a6109c07/levenshtein-0.27.3-cp312-cp312-musllinux_1_2_armv7l.whl", hash = "sha256:3bfcb2d78ab9cc06a1e75da8fcfb7a430fe513d66cfe54c07e50f32805e5e6db", size = 1009734, upload-time = "2025-11-01T12:13:17.212Z" }, + { url = "https://files.pythonhosted.org/packages/27/dc/62c28b812dcb0953fc32ab7adf3d0e814e43c8560bb28d9269a44d874adf/levenshtein-0.27.3-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:ba7235f6dcb31a217247468295e2dd4c6c1d3ac81629dc5d355d93e1a5f4c185", size = 1185581, upload-time = "2025-11-01T12:13:18.661Z" }, + { url = "https://files.pythonhosted.org/packages/56/e8/2e7ab9c565793220edb8e5432f9a846386a157075bdd032a90e9585bce38/levenshtein-0.27.3-cp312-cp312-win32.whl", hash = "sha256:ea80d70f1d18c161a209be556b9094968627cbaae620e102459ef9c320a98cbb", size = 84660, upload-time = "2025-11-01T12:13:19.87Z" }, + { url = "https://files.pythonhosted.org/packages/2c/a6/907a1fc8587dc91c40156973e09d106ab064c06eb28dc4700ba0fe54d654/levenshtein-0.27.3-cp312-cp312-win_amd64.whl", hash = "sha256:fbaa1219d9b2d955339a37e684256a861e9274a3fe3a6ee1b8ea8724c3231ed9", size = 94909, upload-time = "2025-11-01T12:13:21.323Z" }, + { url = "https://files.pythonhosted.org/packages/d5/d6/e04f0ddf6a71df3cdd1817b71703490ac874601ed460b2af172d3752c321/levenshtein-0.27.3-cp312-cp312-win_arm64.whl", hash = "sha256:2edbaa84f887ea1d9d8e4440af3fdda44769a7855d581c6248d7ee51518402a8", size = 87358, upload-time = "2025-11-01T12:13:22.393Z" }, +] + +[[package]] +name = "lhotse" +version = "1.31.1" +source = { registry = "https://pypi.org/simple/" } +dependencies = [ + { name = "audioread" }, + { name = "click" }, + { name = "cytoolz" }, + { name = "intervaltree" }, + { name = "lilcom" }, + { name = "numpy" }, + { name = "packaging" }, + { name = "pyyaml" }, + { name = "soundfile" }, + { name = "tabulate" }, + { name = "torch", version = "2.2.2", source = { registry = "https://pypi.org/simple/" }, marker = "platform_machine == 'x86_64' and sys_platform == 'darwin'" }, + { name = "torch", version = "2.7.1", source = { registry = "https://pypi.org/simple/" }, marker = "platform_machine != 'x86_64' and sys_platform == 'darwin'" }, + { name = "torch", version = "2.7.1+cu128", source = { registry = "https://download.pytorch.org/whl/cu128" }, marker = "sys_platform != 'darwin'" }, + { name = "tqdm" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/03/28/ef2fb33e424e29dec83d2a150d76fb1920418a5d93d5268e6ce401cc33ad/lhotse-1.31.1.tar.gz", hash = "sha256:2ebc3c103c3e09313dff0c4e8740584e28ec35d74e985412c6b37279144a9716", size = 654706, upload-time = "2025-09-18T21:43:51.262Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/cb/dd/4a3698be19e7eca530312afefada5cef524b397d69f8eca5e7cd26a1e4d1/lhotse-1.31.1-py3-none-any.whl", hash = "sha256:d1a8a3d79f7b1ec8d2a9daecc871514999b721bee8ab354db6063864362cc857", size = 866472, upload-time = "2025-09-18T21:43:49.365Z" }, +] + +[[package]] +name = "libcst" +version = "1.8.6" +source = { registry = "https://pypi.org/simple/" } +dependencies = [ + { name = "pyyaml", marker = "platform_machine != 'x86_64' or sys_platform != 'darwin'" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/de/cd/337df968b38d94c5aabd3e1b10630f047a2b345f6e1d4456bd9fe7417537/libcst-1.8.6.tar.gz", hash = "sha256:f729c37c9317126da9475bdd06a7208eb52fcbd180a6341648b45a56b4ba708b", size = 891354, upload-time = "2025-11-03T22:33:30.621Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/0c/3c/93365c17da3d42b055a8edb0e1e99f1c60c776471db6c9b7f1ddf6a44b28/libcst-1.8.6-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:0c13d5bd3d8414a129e9dccaf0e5785108a4441e9b266e1e5e9d1f82d1b943c9", size = 2206166, upload-time = "2025-11-03T22:32:16.012Z" }, + { url = "https://files.pythonhosted.org/packages/1d/cb/7530940e6ac50c6dd6022349721074e19309eb6aa296e942ede2213c1a19/libcst-1.8.6-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:f1472eeafd67cdb22544e59cf3bfc25d23dc94058a68cf41f6654ff4fcb92e09", size = 2083726, upload-time = "2025-11-03T22:32:17.312Z" }, + { url = "https://files.pythonhosted.org/packages/1b/cf/7e5eaa8c8f2c54913160671575351d129170db757bb5e4b7faffed022271/libcst-1.8.6-cp312-cp312-manylinux_2_28_aarch64.whl", hash = "sha256:089c58e75cb142ec33738a1a4ea7760a28b40c078ab2fd26b270dac7d2633a4d", size = 2235755, upload-time = "2025-11-03T22:32:18.859Z" }, + { url = "https://files.pythonhosted.org/packages/55/54/570ec2b0e9a3de0af9922e3bb1b69a5429beefbc753a7ea770a27ad308bd/libcst-1.8.6-cp312-cp312-manylinux_2_28_x86_64.whl", hash = "sha256:c9d7aeafb1b07d25a964b148c0dda9451efb47bbbf67756e16eeae65004b0eb5", size = 2301473, upload-time = "2025-11-03T22:32:20.499Z" }, + { url = "https://files.pythonhosted.org/packages/11/4c/163457d1717cd12181c421a4cca493454bcabd143fc7e53313bc6a4ad82a/libcst-1.8.6-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:207481197afd328aa91d02670c15b48d0256e676ce1ad4bafb6dc2b593cc58f1", size = 2298899, upload-time = "2025-11-03T22:32:21.765Z" }, + { url = "https://files.pythonhosted.org/packages/35/1d/317ddef3669883619ef3d3395ea583305f353ef4ad87d7a5ac1c39be38e3/libcst-1.8.6-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:375965f34cc6f09f5f809244d3ff9bd4f6cb6699f571121cebce53622e7e0b86", size = 2408239, upload-time = "2025-11-03T22:32:23.275Z" }, + { url = "https://files.pythonhosted.org/packages/9a/a1/f47d8cccf74e212dd6044b9d6dbc223636508da99acff1d54786653196bc/libcst-1.8.6-cp312-cp312-win_amd64.whl", hash = "sha256:da95b38693b989eaa8d32e452e8261cfa77fe5babfef1d8d2ac25af8c4aa7e6d", size = 2119660, upload-time = "2025-11-03T22:32:24.822Z" }, + { url = "https://files.pythonhosted.org/packages/19/d0/dd313bf6a7942cdf951828f07ecc1a7695263f385065edc75ef3016a3cb5/libcst-1.8.6-cp312-cp312-win_arm64.whl", hash = "sha256:bff00e1c766658adbd09a175267f8b2f7616e5ee70ce45db3d7c4ce6d9f6bec7", size = 1999824, upload-time = "2025-11-03T22:32:26.131Z" }, +] + +[[package]] +name = "librosa" +version = "0.11.0" +source = { registry = "https://pypi.org/simple/" } +dependencies = [ + { name = "audioread", marker = "platform_machine != 'x86_64' or sys_platform != 'darwin'" }, + { name = "decorator", marker = "platform_machine != 'x86_64' or sys_platform != 'darwin'" }, + { name = "joblib", marker = "platform_machine != 'x86_64' or sys_platform != 'darwin'" }, + { name = "lazy-loader", marker = "platform_machine != 'x86_64' or sys_platform != 'darwin'" }, + { name = "msgpack", marker = "platform_machine != 'x86_64' or sys_platform != 'darwin'" }, + { name = "numba", marker = "platform_machine != 'x86_64' or sys_platform != 'darwin'" }, + { name = "numpy", marker = "platform_machine != 'x86_64' or sys_platform != 'darwin'" }, + { name = "pooch", marker = "platform_machine != 'x86_64' or sys_platform != 'darwin'" }, + { name = "scikit-learn", marker = "platform_machine != 'x86_64' or sys_platform != 'darwin'" }, + { name = "scipy", marker = "platform_machine != 'x86_64' or sys_platform != 'darwin'" }, + { name = "soundfile", marker = "platform_machine != 'x86_64' or sys_platform != 'darwin'" }, + { name = "soxr", marker = "platform_machine != 'x86_64' or sys_platform != 'darwin'" }, + { name = "typing-extensions", marker = "platform_machine != 'x86_64' or sys_platform != 'darwin'" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/64/36/360b5aafa0238e29758729e9486c6ed92a6f37fa403b7875e06c115cdf4a/librosa-0.11.0.tar.gz", hash = "sha256:f5ed951ca189b375bbe2e33b2abd7e040ceeee302b9bbaeeffdfddb8d0ace908", size = 327001, upload-time = "2025-03-11T15:09:54.884Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/b5/ba/c63c5786dfee4c3417094c4b00966e61e4a63efecee22cb7b4c0387dda83/librosa-0.11.0-py3-none-any.whl", hash = "sha256:0b6415c4fd68bff4c29288abe67c6d80b587e0e1e2cfb0aad23e4559504a7fa1", size = 260749, upload-time = "2025-03-11T15:09:52.982Z" }, +] + +[[package]] +name = "lightning" +version = "2.4.0" +source = { registry = "https://pypi.org/simple/" } +dependencies = [ + { name = "fsspec", extra = ["http"], marker = "platform_machine != 'x86_64' or sys_platform != 'darwin'" }, + { name = "lightning-utilities", marker = "platform_machine != 'x86_64' or sys_platform != 'darwin'" }, + { name = "packaging", marker = "platform_machine != 'x86_64' or sys_platform != 'darwin'" }, + { name = "pytorch-lightning", marker = "platform_machine != 'x86_64' or sys_platform != 'darwin'" }, + { name = "pyyaml", marker = "platform_machine != 'x86_64' or sys_platform != 'darwin'" }, + { name = "torch", version = "2.7.1", source = { registry = "https://pypi.org/simple/" }, marker = "platform_machine != 'x86_64' and sys_platform == 'darwin'" }, + { name = "torch", version = "2.7.1+cu128", source = { registry = "https://download.pytorch.org/whl/cu128" }, marker = "sys_platform != 'darwin'" }, + { name = "torchmetrics", marker = "platform_machine != 'x86_64' or sys_platform != 'darwin'" }, + { name = "tqdm", marker = "platform_machine != 'x86_64' or sys_platform != 'darwin'" }, + { name = "typing-extensions", marker = "platform_machine != 'x86_64' or sys_platform != 'darwin'" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/56/d0/78ea244ac044cd4df15aa8294a50ff3561fb177e7e5ba788aaa542046cae/lightning-2.4.0.tar.gz", hash = "sha256:9156604cc56e4b2b603f34fa7f0fe5107375c8e6d85e74544b319a15faa9ed0e", size = 620632, upload-time = "2024-08-07T09:46:44.399Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/a3/2c/85eaf42c983b0cd81bcda5876da2c8e2a9fd347908666ea9855724369171/lightning-2.4.0-py3-none-any.whl", hash = "sha256:560163af9711cf59055c448232c473150a299089efce0d2be3cc3288082d8768", size = 810971, upload-time = "2024-08-07T09:46:39.874Z" }, +] + +[[package]] +name = "lightning-utilities" +version = "0.15.2" +source = { registry = "https://pypi.org/simple/" } +dependencies = [ + { name = "packaging", marker = "platform_machine != 'x86_64' or sys_platform != 'darwin'" }, + { name = "setuptools", marker = "platform_machine != 'x86_64' or sys_platform != 'darwin'" }, + { name = "typing-extensions", marker = "platform_machine != 'x86_64' or sys_platform != 'darwin'" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/b8/39/6fc58ca81492db047149b4b8fd385aa1bfb8c28cd7cacb0c7eb0c44d842f/lightning_utilities-0.15.2.tar.gz", hash = "sha256:cdf12f530214a63dacefd713f180d1ecf5d165338101617b4742e8f22c032e24", size = 31090, upload-time = "2025-08-06T13:57:39.242Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/de/73/3d757cb3fc16f0f9794dd289bcd0c4a031d9cf54d8137d6b984b2d02edf3/lightning_utilities-0.15.2-py3-none-any.whl", hash = "sha256:ad3ab1703775044bbf880dbf7ddaaac899396c96315f3aa1779cec9d618a9841", size = 29431, upload-time = "2025-08-06T13:57:38.046Z" }, +] + +[[package]] +name = "lilcom" +version = "1.8.1" +source = { registry = "https://pypi.org/simple/" } +dependencies = [ + { name = "numpy" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/8b/b5/97422825e61a2683dd39d78165fc470c1153b4a908dd5cd0711c0e9d262c/lilcom-1.8.1.tar.gz", hash = "sha256:69c62037c92e71e601ac3bb3ae19811f22ceffbdf58b0fdbf81cc6a0ec6fc3c5", size = 45813, upload-time = "2025-04-02T02:49:55.591Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/78/1e/4bca706dc50230146b168d5c52403ec4e144650999fae2150a0e60ed7303/lilcom-1.8.1-cp312-cp312-macosx_10_13_universal2.whl", hash = "sha256:b0ace9d4f95199266a36d1144214ff2056679ddb44462f75326a0b9fbf296928", size = 124607, upload-time = "2025-04-02T02:49:22.243Z" }, + { url = "https://files.pythonhosted.org/packages/20/80/0d07c944a09bfed9038121bf3d662e4f5cf56f7f8c2be3669269ceec429b/lilcom-1.8.1-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:834df2155ee7cad41cc5cc482bae764c89ebbaee623cb4788a3b7bbdcd2d22d3", size = 86841, upload-time = "2025-04-02T02:50:18.109Z" }, + { url = "https://files.pythonhosted.org/packages/7c/0d/f8be338de1d45d6a6fc26a24d0ad9f6be0a94130b5b7687c2cc08a5be099/lilcom-1.8.1-cp312-cp312-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:23b45cb5b966999826eb1aa80154d392550902ef26374dc628a8c576d844d548", size = 98796, upload-time = "2025-04-02T02:54:47.92Z" }, + { url = "https://files.pythonhosted.org/packages/e3/6e/7868a5a90e66fefa60642682f5551cb75e489c603f155367003b88363af3/lilcom-1.8.1-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:08ba2cf1cd9a175ec3b791ea727e981a1cd25a03d39c32264d651bc52e7e5c33", size = 92958, upload-time = "2025-04-02T02:54:48.822Z" }, + { url = "https://files.pythonhosted.org/packages/db/94/9553e967a067e0579dd9be9658a428ae78aebde19d7c56d7478bf68cf48b/lilcom-1.8.1-cp312-cp312-win_amd64.whl", hash = "sha256:1eefd5b4735fca240aa35000dbe8a71e843fb00d64ccdc468c61eab03f23cf86", size = 69719, upload-time = "2025-04-02T02:50:48.892Z" }, +] + [[package]] name = "llvmlite" version = "0.45.1" @@ -1050,6 +1747,19 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/33/94/9ba4ebcf4d541a325fd8098ddc073b663af75cc8b065b6059848f7d4dce7/llvmlite-0.45.1-cp312-cp312-win_amd64.whl", hash = "sha256:9e6c9949baf25d9aa9cd7cf0f6d011b9ca660dd17f5ba2b23bdbdb77cc86b116", size = 38132231, upload-time = "2025-10-01T18:05:03.664Z" }, ] +[[package]] +name = "loguru" +version = "0.7.3" +source = { registry = "https://pypi.org/simple/" } +dependencies = [ + { name = "colorama", marker = "sys_platform == 'win32'" }, + { name = "win32-setctime", marker = "sys_platform == 'win32'" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/3a/05/a1dae3dffd1116099471c643b8924f5aa6524411dc6c63fdae648c4f1aca/loguru-0.7.3.tar.gz", hash = "sha256:19480589e77d47b8d85b2c827ad95d49bf31b0dcde16593892eb51dd18706eb6", size = 63559, upload-time = "2024-12-06T11:20:56.608Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/0c/29/0348de65b8cc732daa3e33e67806420b2ae89bdce2b04af740289c5c6c8c/loguru-0.7.3-py3-none-any.whl", hash = "sha256:31a33c10c8e1e10422bfd431aeb5d351c7cf7fa671e3c4df004162264b28220c", size = 61595, upload-time = "2024-12-06T11:20:54.538Z" }, +] + [[package]] name = "macholib" version = "1.16.3" @@ -1062,6 +1772,39 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/d1/5d/c059c180c84f7962db0aeae7c3b9303ed1d73d76f2bfbc32bc231c8be314/macholib-1.16.3-py2.py3-none-any.whl", hash = "sha256:0e315d7583d38b8c77e815b1ecbdbf504a8258d8b3e17b61165c6feb60d18f2c", size = 38094, upload-time = "2023-09-25T09:10:14.188Z" }, ] +[[package]] +name = "mako" +version = "1.3.10" +source = { registry = "https://pypi.org/simple/" } +dependencies = [ + { name = "markupsafe", marker = "platform_machine != 'x86_64' or sys_platform != 'darwin'" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/9e/38/bd5b78a920a64d708fe6bc8e0a2c075e1389d53bef8413725c63ba041535/mako-1.3.10.tar.gz", hash = "sha256:99579a6f39583fa7e5630a28c3c1f440e4e97a414b80372649c0ce338da2ea28", size = 392474, upload-time = "2025-04-10T12:44:31.16Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/87/fb/99f81ac72ae23375f22b7afdb7642aba97c00a713c217124420147681a2f/mako-1.3.10-py3-none-any.whl", hash = "sha256:baef24a52fc4fc514a0887ac600f9f1cff3d82c61d4d700a1fa84d597b88db59", size = 78509, upload-time = "2025-04-10T12:50:53.297Z" }, +] + +[[package]] +name = "markdown" +version = "3.10" +source = { registry = "https://pypi.org/simple/" } +sdist = { url = "https://files.pythonhosted.org/packages/7d/ab/7dd27d9d863b3376fcf23a5a13cb5d024aed1db46f963f1b5735ae43b3be/markdown-3.10.tar.gz", hash = "sha256:37062d4f2aa4b2b6b32aefb80faa300f82cc790cb949a35b8caede34f2b68c0e", size = 364931, upload-time = "2025-11-03T19:51:15.007Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/70/81/54e3ce63502cd085a0c556652a4e1b919c45a446bd1e5300e10c44c8c521/markdown-3.10-py3-none-any.whl", hash = "sha256:b5b99d6951e2e4948d939255596523444c0e677c669700b1d17aa4a8a464cb7c", size = 107678, upload-time = "2025-11-03T19:51:13.887Z" }, +] + +[[package]] +name = "markdown-it-py" +version = "4.0.0" +source = { registry = "https://pypi.org/simple/" } +dependencies = [ + { name = "mdurl", marker = "platform_machine != 'x86_64' or sys_platform != 'darwin'" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/5b/f5/4ec618ed16cc4f8fb3b701563655a69816155e79e24a17b651541804721d/markdown_it_py-4.0.0.tar.gz", hash = "sha256:cb0a2b4aa34f932c007117b194e945bd74e0ec24133ceb5bac59009cda1cb9f3", size = 73070, upload-time = "2025-08-11T12:57:52.854Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/94/54/e7d793b573f298e1c9013b8c4dade17d481164aa517d1d7148619c2cedbf/markdown_it_py-4.0.0-py3-none-any.whl", hash = "sha256:87327c59b172c5011896038353a81343b6754500a08cd7a4973bb48c6d578147", size = 87321, upload-time = "2025-08-11T12:57:51.923Z" }, +] + [[package]] name = "markupsafe" version = "3.0.3" @@ -1093,6 +1836,44 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/34/75/51952c7b2d3873b44a0028b1bd26a25078c18f92f256608e8d1dc61b39fd/marshmallow-3.26.1-py3-none-any.whl", hash = "sha256:3350409f20a70a7e4e11a27661187b77cdcaeb20abca41c1454fe33636bea09c", size = 50878, upload-time = "2025-02-03T15:32:22.295Z" }, ] +[[package]] +name = "matplotlib" +version = "3.10.7" +source = { registry = "https://pypi.org/simple/" } +dependencies = [ + { name = "contourpy", marker = "platform_machine != 'x86_64' or sys_platform != 'darwin'" }, + { name = "cycler", marker = "platform_machine != 'x86_64' or sys_platform != 'darwin'" }, + { name = "fonttools", marker = "platform_machine != 'x86_64' or sys_platform != 'darwin'" }, + { name = "kiwisolver", marker = "platform_machine != 'x86_64' or sys_platform != 'darwin'" }, + { name = "numpy", marker = "platform_machine != 'x86_64' or sys_platform != 'darwin'" }, + { name = "packaging", marker = "platform_machine != 'x86_64' or sys_platform != 'darwin'" }, + { name = "pillow", marker = "platform_machine != 'x86_64' or sys_platform != 'darwin'" }, + { name = "pyparsing", marker = "platform_machine != 'x86_64' or sys_platform != 'darwin'" }, + { name = "python-dateutil", marker = "platform_machine != 'x86_64' or sys_platform != 'darwin'" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/ae/e2/d2d5295be2f44c678ebaf3544ba32d20c1f9ef08c49fe47f496180e1db15/matplotlib-3.10.7.tar.gz", hash = "sha256:a06ba7e2a2ef9131c79c49e63dad355d2d878413a0376c1727c8b9335ff731c7", size = 34804865, upload-time = "2025-10-09T00:28:00.669Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/be/b3/09eb0f7796932826ec20c25b517d568627754f6c6462fca19e12c02f2e12/matplotlib-3.10.7-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:7a0edb7209e21840e8361e91ea84ea676658aa93edd5f8762793dec77a4a6748", size = 8272389, upload-time = "2025-10-09T00:26:42.474Z" }, + { url = "https://files.pythonhosted.org/packages/11/0b/1ae80ddafb8652fd8046cb5c8460ecc8d4afccb89e2c6d6bec61e04e1eaf/matplotlib-3.10.7-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:c380371d3c23e0eadf8ebff114445b9f970aff2010198d498d4ab4c3b41eea4f", size = 8128247, upload-time = "2025-10-09T00:26:44.77Z" }, + { url = "https://files.pythonhosted.org/packages/7d/18/95ae2e242d4a5c98bd6e90e36e128d71cf1c7e39b0874feaed3ef782e789/matplotlib-3.10.7-cp312-cp312-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:d5f256d49fea31f40f166a5e3131235a5d2f4b7f44520b1cf0baf1ce568ccff0", size = 8696996, upload-time = "2025-10-09T00:26:46.792Z" }, + { url = "https://files.pythonhosted.org/packages/7e/3d/5b559efc800bd05cb2033aa85f7e13af51958136a48327f7c261801ff90a/matplotlib-3.10.7-cp312-cp312-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:11ae579ac83cdf3fb72573bb89f70e0534de05266728740d478f0f818983c695", size = 9530153, upload-time = "2025-10-09T00:26:49.07Z" }, + { url = "https://files.pythonhosted.org/packages/88/57/eab4a719fd110312d3c220595d63a3c85ec2a39723f0f4e7fa7e6e3f74ba/matplotlib-3.10.7-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:4c14b6acd16cddc3569a2d515cfdd81c7a68ac5639b76548cfc1a9e48b20eb65", size = 9593093, upload-time = "2025-10-09T00:26:51.067Z" }, + { url = "https://files.pythonhosted.org/packages/31/3c/80816f027b3a4a28cd2a0a6ef7f89a2db22310e945cd886ec25bfb399221/matplotlib-3.10.7-cp312-cp312-win_amd64.whl", hash = "sha256:0d8c32b7ea6fb80b1aeff5a2ceb3fb9778e2759e899d9beff75584714afcc5ee", size = 8122771, upload-time = "2025-10-09T00:26:53.296Z" }, + { url = "https://files.pythonhosted.org/packages/de/77/ef1fc78bfe99999b2675435cc52120887191c566b25017d78beaabef7f2d/matplotlib-3.10.7-cp312-cp312-win_arm64.whl", hash = "sha256:5f3f6d315dcc176ba7ca6e74c7768fb7e4cf566c49cb143f6bc257b62e634ed8", size = 7992812, upload-time = "2025-10-09T00:26:54.882Z" }, +] + +[[package]] +name = "matplotlib-inline" +version = "0.2.1" +source = { registry = "https://pypi.org/simple/" } +dependencies = [ + { name = "traitlets", marker = "platform_machine != 'x86_64' or sys_platform != 'darwin'" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/c7/74/97e72a36efd4ae2bccb3463284300f8953f199b5ffbc04cbbb0ec78f74b1/matplotlib_inline-0.2.1.tar.gz", hash = "sha256:e1ee949c340d771fc39e241ea75683deb94762c8fa5f2927ec57c83c4dffa9fe", size = 8110, upload-time = "2025-10-23T09:00:22.126Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/af/33/ee4519fa02ed11a94aef9559552f3b17bb863f2ecfe1a35dc7f548cde231/matplotlib_inline-0.2.1-py3-none-any.whl", hash = "sha256:d56ce5156ba6085e00a9d54fead6ed29a9c47e215cd1bba2e976ef39f5710a76", size = 9516, upload-time = "2025-10-23T09:00:20.675Z" }, +] + [[package]] name = "mccabe" version = "0.7.0" @@ -1102,6 +1883,46 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/27/1a/1f68f9ba0c207934b35b86a8ca3aad8395a3d6dd7921c0686e23853ff5a9/mccabe-0.7.0-py2.py3-none-any.whl", hash = "sha256:6c2d30ab6be0e4a46919781807b4f0d834ebdd6c6e3dca0bda5a15f863427b6e", size = 7350, upload-time = "2022-01-24T01:14:49.62Z" }, ] +[[package]] +name = "mdurl" +version = "0.1.2" +source = { registry = "https://pypi.org/simple/" } +sdist = { url = "https://files.pythonhosted.org/packages/d6/54/cfe61301667036ec958cb99bd3efefba235e65cdeb9c84d24a8293ba1d90/mdurl-0.1.2.tar.gz", hash = "sha256:bb413d29f5eea38f31dd4754dd7377d4465116fb207585f97bf925588687c1ba", size = 8729, upload-time = "2022-08-14T12:40:10.846Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/b3/38/89ba8ad64ae25be8de66a6d463314cf1eb366222074cfda9ee839c56a4b4/mdurl-0.1.2-py3-none-any.whl", hash = "sha256:84008a41e51615a49fc9966191ff91509e3c40b939176e643fd50a5c2196b8f8", size = 9979, upload-time = "2022-08-14T12:40:09.779Z" }, +] + +[[package]] +name = "mediapy" +version = "1.1.6" +source = { registry = "https://pypi.org/simple/" } +dependencies = [ + { name = "ipython", marker = "platform_machine != 'x86_64' or sys_platform != 'darwin'" }, + { name = "matplotlib", marker = "platform_machine != 'x86_64' or sys_platform != 'darwin'" }, + { name = "numpy", marker = "platform_machine != 'x86_64' or sys_platform != 'darwin'" }, + { name = "pillow", marker = "platform_machine != 'x86_64' or sys_platform != 'darwin'" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/9e/b2/451be65c13d2d69b7601eded7ddd3f150884486715a9b3a705ffb08d0177/mediapy-1.1.6.tar.gz", hash = "sha256:9f44b760400964d8bea5121a213f94dc9a225d026d6a819901283a695e585634", size = 25459, upload-time = "2023-02-24T13:08:42.429Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/e3/a0/0d55c59ea8a5f1b13b3eb931e1c0eab9c2a07322cad79cb51a596d2d2a5c/mediapy-1.1.6-py3-none-any.whl", hash = "sha256:c74370808b445666f95272bfdf0eb5707a43b7e05e5527f2dd0830e6892f976f", size = 24955, upload-time = "2023-02-24T13:08:40.53Z" }, +] + +[[package]] +name = "ml-dtypes" +version = "0.5.4" +source = { registry = "https://pypi.org/simple/" } +dependencies = [ + { name = "numpy", marker = "platform_machine != 'x86_64' or sys_platform != 'darwin'" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/0e/4a/c27b42ed9b1c7d13d9ba8b6905dece787d6259152f2309338aed29b2447b/ml_dtypes-0.5.4.tar.gz", hash = "sha256:8ab06a50fb9bf9666dd0fe5dfb4676fa2b0ac0f31ecff72a6c3af8e22c063453", size = 692314, upload-time = "2025-11-17T22:32:31.031Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/a8/b8/3c70881695e056f8a32f8b941126cf78775d9a4d7feba8abcb52cb7b04f2/ml_dtypes-0.5.4-cp312-cp312-macosx_10_13_universal2.whl", hash = "sha256:a174837a64f5b16cab6f368171a1a03a27936b31699d167684073ff1c4237dac", size = 676927, upload-time = "2025-11-17T22:31:48.182Z" }, + { url = "https://files.pythonhosted.org/packages/54/0f/428ef6881782e5ebb7eca459689448c0394fa0a80bea3aa9262cba5445ea/ml_dtypes-0.5.4-cp312-cp312-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:a7f7c643e8b1320fd958bf098aa7ecf70623a42ec5154e3be3be673f4c34d900", size = 5028464, upload-time = "2025-11-17T22:31:50.135Z" }, + { url = "https://files.pythonhosted.org/packages/3a/cb/28ce52eb94390dda42599c98ea0204d74799e4d8047a0eb559b6fd648056/ml_dtypes-0.5.4-cp312-cp312-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:9ad459e99793fa6e13bd5b7e6792c8f9190b4e5a1b45c63aba14a4d0a7f1d5ff", size = 5009002, upload-time = "2025-11-17T22:31:52.001Z" }, + { url = "https://files.pythonhosted.org/packages/f5/f0/0cfadd537c5470378b1b32bd859cf2824972174b51b873c9d95cfd7475a5/ml_dtypes-0.5.4-cp312-cp312-win_amd64.whl", hash = "sha256:c1a953995cccb9e25a4ae19e34316671e4e2edaebe4cf538229b1fc7109087b7", size = 212222, upload-time = "2025-11-17T22:31:53.742Z" }, + { url = "https://files.pythonhosted.org/packages/16/2e/9acc86985bfad8f2c2d30291b27cd2bb4c74cea08695bd540906ed744249/ml_dtypes-0.5.4-cp312-cp312-win_arm64.whl", hash = "sha256:9bad06436568442575beb2d03389aa7456c690a5b05892c471215bfd8cf39460", size = 160793, upload-time = "2025-11-17T22:31:55.358Z" }, +] + [[package]] name = "monotonic" version = "1.6" @@ -1128,6 +1949,66 @@ wheels = [ { url = "https://download.pytorch.org/whl/mpmath-1.3.0-py3-none-any.whl", hash = "sha256:a0b2b9fe80bbcd81a6647ff13108738cfb482d481d826cc0e02f5b35e5c88d2c" }, ] +[[package]] +name = "msgpack" +version = "1.1.2" +source = { registry = "https://pypi.org/simple/" } +sdist = { url = "https://files.pythonhosted.org/packages/4d/f2/bfb55a6236ed8725a96b0aa3acbd0ec17588e6a2c3b62a93eb513ed8783f/msgpack-1.1.2.tar.gz", hash = "sha256:3b60763c1373dd60f398488069bcdc703cd08a711477b5d480eecc9f9626f47e", size = 173581, upload-time = "2025-10-08T09:15:56.596Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/ad/bd/8b0d01c756203fbab65d265859749860682ccd2a59594609aeec3a144efa/msgpack-1.1.2-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:70a0dff9d1f8da25179ffcf880e10cf1aad55fdb63cd59c9a49a1b82290062aa", size = 81939, upload-time = "2025-10-08T09:15:01.472Z" }, + { url = "https://files.pythonhosted.org/packages/34/68/ba4f155f793a74c1483d4bdef136e1023f7bcba557f0db4ef3db3c665cf1/msgpack-1.1.2-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:446abdd8b94b55c800ac34b102dffd2f6aa0ce643c55dfc017ad89347db3dbdb", size = 85064, upload-time = "2025-10-08T09:15:03.764Z" }, + { url = "https://files.pythonhosted.org/packages/f2/60/a064b0345fc36c4c3d2c743c82d9100c40388d77f0b48b2f04d6041dbec1/msgpack-1.1.2-cp312-cp312-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:c63eea553c69ab05b6747901b97d620bb2a690633c77f23feb0c6a947a8a7b8f", size = 417131, upload-time = "2025-10-08T09:15:05.136Z" }, + { url = "https://files.pythonhosted.org/packages/65/92/a5100f7185a800a5d29f8d14041f61475b9de465ffcc0f3b9fba606e4505/msgpack-1.1.2-cp312-cp312-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:372839311ccf6bdaf39b00b61288e0557916c3729529b301c52c2d88842add42", size = 427556, upload-time = "2025-10-08T09:15:06.837Z" }, + { url = "https://files.pythonhosted.org/packages/f5/87/ffe21d1bf7d9991354ad93949286f643b2bb6ddbeab66373922b44c3b8cc/msgpack-1.1.2-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:2929af52106ca73fcb28576218476ffbb531a036c2adbcf54a3664de124303e9", size = 404920, upload-time = "2025-10-08T09:15:08.179Z" }, + { url = "https://files.pythonhosted.org/packages/ff/41/8543ed2b8604f7c0d89ce066f42007faac1eaa7d79a81555f206a5cdb889/msgpack-1.1.2-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:be52a8fc79e45b0364210eef5234a7cf8d330836d0a64dfbb878efa903d84620", size = 415013, upload-time = "2025-10-08T09:15:09.83Z" }, + { url = "https://files.pythonhosted.org/packages/41/0d/2ddfaa8b7e1cee6c490d46cb0a39742b19e2481600a7a0e96537e9c22f43/msgpack-1.1.2-cp312-cp312-win32.whl", hash = "sha256:1fff3d825d7859ac888b0fbda39a42d59193543920eda9d9bea44d958a878029", size = 65096, upload-time = "2025-10-08T09:15:11.11Z" }, + { url = "https://files.pythonhosted.org/packages/8c/ec/d431eb7941fb55a31dd6ca3404d41fbb52d99172df2e7707754488390910/msgpack-1.1.2-cp312-cp312-win_amd64.whl", hash = "sha256:1de460f0403172cff81169a30b9a92b260cb809c4cb7e2fc79ae8d0510c78b6b", size = 72708, upload-time = "2025-10-08T09:15:12.554Z" }, + { url = "https://files.pythonhosted.org/packages/c5/31/5b1a1f70eb0e87d1678e9624908f86317787b536060641d6798e3cf70ace/msgpack-1.1.2-cp312-cp312-win_arm64.whl", hash = "sha256:be5980f3ee0e6bd44f3a9e9dea01054f175b50c3e6cdb692bc9424c0bbb8bf69", size = 64119, upload-time = "2025-10-08T09:15:13.589Z" }, +] + +[[package]] +name = "multidict" +version = "6.7.0" +source = { registry = "https://pypi.org/simple/" } +sdist = { url = "https://files.pythonhosted.org/packages/80/1e/5492c365f222f907de1039b91f922b93fa4f764c713ee858d235495d8f50/multidict-6.7.0.tar.gz", hash = "sha256:c6e99d9a65ca282e578dfea819cfa9c0a62b2499d8677392e09feaf305e9e6f5", size = 101834, upload-time = "2025-10-06T14:52:30.657Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/c2/9e/9f61ac18d9c8b475889f32ccfa91c9f59363480613fc807b6e3023d6f60b/multidict-6.7.0-cp312-cp312-macosx_10_13_universal2.whl", hash = "sha256:8a3862568a36d26e650a19bb5cbbba14b71789032aebc0423f8cc5f150730184", size = 76877, upload-time = "2025-10-06T14:49:20.884Z" }, + { url = "https://files.pythonhosted.org/packages/38/6f/614f09a04e6184f8824268fce4bc925e9849edfa654ddd59f0b64508c595/multidict-6.7.0-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:960c60b5849b9b4f9dcc9bea6e3626143c252c74113df2c1540aebce70209b45", size = 45467, upload-time = "2025-10-06T14:49:22.054Z" }, + { url = "https://files.pythonhosted.org/packages/b3/93/c4f67a436dd026f2e780c433277fff72be79152894d9fc36f44569cab1a6/multidict-6.7.0-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:2049be98fb57a31b4ccf870bf377af2504d4ae35646a19037ec271e4c07998aa", size = 43834, upload-time = "2025-10-06T14:49:23.566Z" }, + { url = "https://files.pythonhosted.org/packages/7f/f5/013798161ca665e4a422afbc5e2d9e4070142a9ff8905e482139cd09e4d0/multidict-6.7.0-cp312-cp312-manylinux1_i686.manylinux_2_28_i686.manylinux_2_5_i686.whl", hash = "sha256:0934f3843a1860dd465d38895c17fce1f1cb37295149ab05cd1b9a03afacb2a7", size = 250545, upload-time = "2025-10-06T14:49:24.882Z" }, + { url = "https://files.pythonhosted.org/packages/71/2f/91dbac13e0ba94669ea5119ba267c9a832f0cb65419aca75549fcf09a3dc/multidict-6.7.0-cp312-cp312-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:b3e34f3a1b8131ba06f1a73adab24f30934d148afcd5f5de9a73565a4404384e", size = 258305, upload-time = "2025-10-06T14:49:26.778Z" }, + { url = "https://files.pythonhosted.org/packages/ef/b0/754038b26f6e04488b48ac621f779c341338d78503fb45403755af2df477/multidict-6.7.0-cp312-cp312-manylinux2014_armv7l.manylinux_2_17_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:efbb54e98446892590dc2458c19c10344ee9a883a79b5cec4bc34d6656e8d546", size = 242363, upload-time = "2025-10-06T14:49:28.562Z" }, + { url = "https://files.pythonhosted.org/packages/87/15/9da40b9336a7c9fa606c4cf2ed80a649dffeb42b905d4f63a1d7eb17d746/multidict-6.7.0-cp312-cp312-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:a35c5fc61d4f51eb045061e7967cfe3123d622cd500e8868e7c0c592a09fedc4", size = 268375, upload-time = "2025-10-06T14:49:29.96Z" }, + { url = "https://files.pythonhosted.org/packages/82/72/c53fcade0cc94dfaad583105fd92b3a783af2091eddcb41a6d5a52474000/multidict-6.7.0-cp312-cp312-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:29fe6740ebccba4175af1b9b87bf553e9c15cd5868ee967e010efcf94e4fd0f1", size = 269346, upload-time = "2025-10-06T14:49:31.404Z" }, + { url = "https://files.pythonhosted.org/packages/0d/e2/9baffdae21a76f77ef8447f1a05a96ec4bc0a24dae08767abc0a2fe680b8/multidict-6.7.0-cp312-cp312-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:123e2a72e20537add2f33a79e605f6191fba2afda4cbb876e35c1a7074298a7d", size = 256107, upload-time = "2025-10-06T14:49:32.974Z" }, + { url = "https://files.pythonhosted.org/packages/3c/06/3f06f611087dc60d65ef775f1fb5aca7c6d61c6db4990e7cda0cef9b1651/multidict-6.7.0-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:b284e319754366c1aee2267a2036248b24eeb17ecd5dc16022095e747f2f4304", size = 253592, upload-time = "2025-10-06T14:49:34.52Z" }, + { url = "https://files.pythonhosted.org/packages/20/24/54e804ec7945b6023b340c412ce9c3f81e91b3bf5fa5ce65558740141bee/multidict-6.7.0-cp312-cp312-musllinux_1_2_armv7l.whl", hash = "sha256:803d685de7be4303b5a657b76e2f6d1240e7e0a8aa2968ad5811fa2285553a12", size = 251024, upload-time = "2025-10-06T14:49:35.956Z" }, + { url = "https://files.pythonhosted.org/packages/14/48/011cba467ea0b17ceb938315d219391d3e421dfd35928e5dbdc3f4ae76ef/multidict-6.7.0-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:c04a328260dfd5db8c39538f999f02779012268f54614902d0afc775d44e0a62", size = 251484, upload-time = "2025-10-06T14:49:37.631Z" }, + { url = "https://files.pythonhosted.org/packages/0d/2f/919258b43bb35b99fa127435cfb2d91798eb3a943396631ef43e3720dcf4/multidict-6.7.0-cp312-cp312-musllinux_1_2_ppc64le.whl", hash = "sha256:8a19cdb57cd3df4cd865849d93ee14920fb97224300c88501f16ecfa2604b4e0", size = 263579, upload-time = "2025-10-06T14:49:39.502Z" }, + { url = "https://files.pythonhosted.org/packages/31/22/a0e884d86b5242b5a74cf08e876bdf299e413016b66e55511f7a804a366e/multidict-6.7.0-cp312-cp312-musllinux_1_2_s390x.whl", hash = "sha256:9b2fd74c52accced7e75de26023b7dccee62511a600e62311b918ec5c168fc2a", size = 259654, upload-time = "2025-10-06T14:49:41.32Z" }, + { url = "https://files.pythonhosted.org/packages/b2/e5/17e10e1b5c5f5a40f2fcbb45953c9b215f8a4098003915e46a93f5fcaa8f/multidict-6.7.0-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:3e8bfdd0e487acf992407a140d2589fe598238eaeffa3da8448d63a63cd363f8", size = 251511, upload-time = "2025-10-06T14:49:46.021Z" }, + { url = "https://files.pythonhosted.org/packages/e3/9a/201bb1e17e7af53139597069c375e7b0dcbd47594604f65c2d5359508566/multidict-6.7.0-cp312-cp312-win32.whl", hash = "sha256:dd32a49400a2c3d52088e120ee00c1e3576cbff7e10b98467962c74fdb762ed4", size = 41895, upload-time = "2025-10-06T14:49:48.718Z" }, + { url = "https://files.pythonhosted.org/packages/46/e2/348cd32faad84eaf1d20cce80e2bb0ef8d312c55bca1f7fa9865e7770aaf/multidict-6.7.0-cp312-cp312-win_amd64.whl", hash = "sha256:92abb658ef2d7ef22ac9f8bb88e8b6c3e571671534e029359b6d9e845923eb1b", size = 46073, upload-time = "2025-10-06T14:49:50.28Z" }, + { url = "https://files.pythonhosted.org/packages/25/ec/aad2613c1910dce907480e0c3aa306905830f25df2e54ccc9dea450cb5aa/multidict-6.7.0-cp312-cp312-win_arm64.whl", hash = "sha256:490dab541a6a642ce1a9d61a4781656b346a55c13038f0b1244653828e3a83ec", size = 43226, upload-time = "2025-10-06T14:49:52.304Z" }, + { url = "https://files.pythonhosted.org/packages/b7/da/7d22601b625e241d4f23ef1ebff8acfc60da633c9e7e7922e24d10f592b3/multidict-6.7.0-py3-none-any.whl", hash = "sha256:394fc5c42a333c9ffc3e421a4c85e08580d990e08b99f6bf35b4132114c5dcb3", size = 12317, upload-time = "2025-10-06T14:52:29.272Z" }, +] + +[[package]] +name = "multiprocess" +version = "0.70.18" +source = { registry = "https://pypi.org/simple/" } +dependencies = [ + { name = "dill", marker = "platform_machine != 'x86_64' or sys_platform != 'darwin'" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/72/fd/2ae3826f5be24c6ed87266bc4e59c46ea5b059a103f3d7e7eb76a52aeecb/multiprocess-0.70.18.tar.gz", hash = "sha256:f9597128e6b3e67b23956da07cf3d2e5cba79e2f4e0fba8d7903636663ec6d0d", size = 1798503, upload-time = "2025-04-17T03:11:27.742Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/ba/d8/0cba6cf51a1a31f20471fbc823a716170c73012ddc4fb85d706630ed6e8f/multiprocess-0.70.18-py310-none-any.whl", hash = "sha256:60c194974c31784019c1f459d984e8f33ee48f10fcf42c309ba97b30d9bd53ea", size = 134948, upload-time = "2025-04-17T03:11:20.223Z" }, + { url = "https://files.pythonhosted.org/packages/4b/88/9039f2fed1012ef584751d4ceff9ab4a51e5ae264898f0b7cbf44340a859/multiprocess-0.70.18-py311-none-any.whl", hash = "sha256:5aa6eef98e691281b3ad923be2832bf1c55dd2c859acd73e5ec53a66aae06a1d", size = 144462, upload-time = "2025-04-17T03:11:21.657Z" }, + { url = "https://files.pythonhosted.org/packages/bf/b6/5f922792be93b82ec6b5f270bbb1ef031fd0622847070bbcf9da816502cc/multiprocess-0.70.18-py312-none-any.whl", hash = "sha256:9b78f8e5024b573730bfb654783a13800c2c0f2dfc0c25e70b40d184d64adaa2", size = 150287, upload-time = "2025-04-17T03:11:22.69Z" }, + { url = "https://files.pythonhosted.org/packages/3b/c3/ca84c19bd14cdfc21c388fdcebf08b86a7a470ebc9f5c3c084fc2dbc50f7/multiprocess-0.70.18-py38-none-any.whl", hash = "sha256:dbf705e52a154fe5e90fb17b38f02556169557c2dd8bb084f2e06c2784d8279b", size = 132636, upload-time = "2025-04-17T03:11:24.936Z" }, + { url = "https://files.pythonhosted.org/packages/6c/28/dd72947e59a6a8c856448a5e74da6201cb5502ddff644fbc790e4bd40b9a/multiprocess-0.70.18-py39-none-any.whl", hash = "sha256:e78ca805a72b1b810c690b6b4cc32579eba34f403094bbbae962b7b5bf9dfcb8", size = 133478, upload-time = "2025-04-17T03:11:26.253Z" }, +] + [[package]] name = "musdb" version = "0.4.3" @@ -1190,6 +2071,82 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/79/7b/2c79738432f5c924bef5071f933bcc9efd0473bac3b4aa584a6f7c1c8df8/mypy_extensions-1.1.0-py3-none-any.whl", hash = "sha256:1be4cccdb0f2482337c4743e60421de3a356cd97508abadd57d47403e94f5505", size = 4963, upload-time = "2025-04-22T14:54:22.983Z" }, ] +[[package]] +name = "nemo-toolkit" +version = "2.5.3" +source = { registry = "https://pypi.org/simple/" } +dependencies = [ + { name = "fsspec", marker = "platform_machine != 'x86_64' or sys_platform != 'darwin'" }, + { name = "huggingface-hub", marker = "platform_machine != 'x86_64' or sys_platform != 'darwin'" }, + { name = "numba", marker = "platform_machine != 'x86_64' or sys_platform != 'darwin'" }, + { name = "numpy", marker = "platform_machine != 'x86_64' or sys_platform != 'darwin'" }, + { name = "onnx", marker = "platform_machine != 'x86_64' or sys_platform != 'darwin'" }, + { name = "protobuf", marker = "platform_machine != 'x86_64' or sys_platform != 'darwin'" }, + { name = "python-dateutil", marker = "platform_machine != 'x86_64' or sys_platform != 'darwin'" }, + { name = "ruamel-yaml", marker = "platform_machine != 'x86_64' or sys_platform != 'darwin'" }, + { name = "scikit-learn", marker = "platform_machine != 'x86_64' or sys_platform != 'darwin'" }, + { name = "setuptools", marker = "platform_machine != 'x86_64' or sys_platform != 'darwin'" }, + { name = "tensorboard", marker = "platform_machine != 'x86_64' or sys_platform != 'darwin'" }, + { name = "text-unidecode", marker = "platform_machine != 'x86_64' or sys_platform != 'darwin'" }, + { name = "torch", version = "2.7.1", source = { registry = "https://pypi.org/simple/" }, marker = "platform_machine != 'x86_64' and sys_platform == 'darwin'" }, + { name = "torch", version = "2.7.1+cu128", source = { registry = "https://download.pytorch.org/whl/cu128" }, marker = "sys_platform != 'darwin'" }, + { name = "tqdm", marker = "platform_machine != 'x86_64' or sys_platform != 'darwin'" }, + { name = "wget", marker = "platform_machine != 'x86_64' or sys_platform != 'darwin'" }, + { name = "wrapt", marker = "platform_machine != 'x86_64' or sys_platform != 'darwin'" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/8a/6c/c6ec69f6bd009f7faf784bcaa473d2ba0c7154f77af898d6236c5f0f6c9b/nemo_toolkit-2.5.3.tar.gz", hash = "sha256:50309a400162cc3dda8fa5eebfe585f51a5cdcbdafc207ac3b56866dd50ff51b", size = 4144730, upload-time = "2025-11-10T22:46:33.535Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/6c/2a/d5f68c753705c6d8f2767c753df60bdb70301669039d54aadcec760831be/nemo_toolkit-2.5.3-py3-none-any.whl", hash = "sha256:17fb705e002cb38c753c0d0804d66b8cec4d0d86f878ba8a41049bcd9c7ae7d6", size = 5924546, upload-time = "2025-11-10T22:46:29.678Z" }, +] + +[package.optional-dependencies] +asr = [ + { name = "bitsandbytes", marker = "platform_machine == 'x86_64' and sys_platform != 'darwin'" }, + { name = "braceexpand", marker = "platform_machine != 'x86_64' or sys_platform != 'darwin'" }, + { name = "cloudpickle", marker = "platform_machine != 'x86_64' or sys_platform != 'darwin'" }, + { name = "ctc-segmentation", marker = "platform_machine != 'x86_64' or sys_platform != 'darwin'" }, + { name = "datasets", marker = "platform_machine != 'x86_64' or sys_platform != 'darwin'" }, + { name = "editdistance", marker = "platform_machine != 'x86_64' or sys_platform != 'darwin'" }, + { name = "einops", marker = "platform_machine != 'x86_64' or sys_platform != 'darwin'" }, + { name = "fiddle", marker = "platform_machine != 'x86_64' or sys_platform != 'darwin'" }, + { name = "hydra-core", marker = "platform_machine != 'x86_64' or sys_platform != 'darwin'" }, + { name = "inflect", marker = "platform_machine != 'x86_64' or sys_platform != 'darwin'" }, + { name = "jiwer", marker = "platform_machine != 'x86_64' or sys_platform != 'darwin'" }, + { name = "kaldi-python-io", marker = "platform_machine != 'x86_64' or sys_platform != 'darwin'" }, + { name = "lhotse", marker = "platform_machine != 'x86_64' or sys_platform != 'darwin'" }, + { name = "librosa", marker = "platform_machine != 'x86_64' or sys_platform != 'darwin'" }, + { name = "lightning", marker = "platform_machine != 'x86_64' or sys_platform != 'darwin'" }, + { name = "marshmallow", marker = "platform_machine != 'x86_64' or sys_platform != 'darwin'" }, + { name = "mediapy", marker = "platform_machine != 'x86_64' or sys_platform != 'darwin'" }, + { name = "num2words", marker = "platform_machine != 'x86_64' or sys_platform != 'darwin'" }, + { name = "numpy", marker = "platform_machine != 'x86_64' or sys_platform != 'darwin'" }, + { name = "nv-one-logger-core", marker = "platform_machine != 'x86_64' or sys_platform != 'darwin'" }, + { name = "nv-one-logger-pytorch-lightning-integration", marker = "platform_machine != 'x86_64' or sys_platform != 'darwin'" }, + { name = "nv-one-logger-training-telemetry", marker = "platform_machine != 'x86_64' or sys_platform != 'darwin'" }, + { name = "omegaconf", marker = "platform_machine != 'x86_64' or sys_platform != 'darwin'" }, + { name = "optuna", marker = "platform_machine != 'x86_64' or sys_platform != 'darwin'" }, + { name = "packaging", marker = "platform_machine != 'x86_64' or sys_platform != 'darwin'" }, + { name = "pandas", marker = "platform_machine != 'x86_64' or sys_platform != 'darwin'" }, + { name = "peft", marker = "platform_machine != 'x86_64' or sys_platform != 'darwin'" }, + { name = "pyannote-core", marker = "platform_machine != 'x86_64' or sys_platform != 'darwin'" }, + { name = "pyannote-metrics", marker = "platform_machine != 'x86_64' or sys_platform != 'darwin'" }, + { name = "pydub", marker = "platform_machine != 'x86_64' or sys_platform != 'darwin'" }, + { name = "pyloudnorm", marker = "platform_machine != 'x86_64' or sys_platform != 'darwin'" }, + { name = "resampy", marker = "platform_machine != 'x86_64' or sys_platform != 'darwin'" }, + { name = "ruamel-yaml", marker = "platform_machine != 'x86_64' or sys_platform != 'darwin'" }, + { name = "sacremoses", marker = "platform_machine != 'x86_64' or sys_platform != 'darwin'" }, + { name = "scipy", marker = "platform_machine != 'x86_64' or sys_platform != 'darwin'" }, + { name = "sentencepiece", marker = "platform_machine != 'x86_64' or sys_platform != 'darwin'" }, + { name = "soundfile", marker = "platform_machine != 'x86_64' or sys_platform != 'darwin'" }, + { name = "sox", marker = "platform_machine != 'x86_64' or sys_platform != 'darwin'" }, + { name = "texterrors", marker = "platform_machine != 'x86_64' or sys_platform != 'darwin'" }, + { name = "torchmetrics", marker = "platform_machine != 'x86_64' or sys_platform != 'darwin'" }, + { name = "transformers", marker = "platform_machine != 'x86_64' or sys_platform != 'darwin'" }, + { name = "wandb", marker = "platform_machine != 'x86_64' or sys_platform != 'darwin'" }, + { name = "webdataset", marker = "platform_machine != 'x86_64' or sys_platform != 'darwin'" }, + { name = "whisper-normalizer", marker = "platform_machine != 'x86_64' or sys_platform != 'darwin'" }, +] + [[package]] name = "networkx" version = "3.5" @@ -1198,6 +2155,21 @@ wheels = [ { url = "https://download.pytorch.org/whl/networkx-3.5-py3-none-any.whl" }, ] +[[package]] +name = "nltk" +version = "3.9.2" +source = { registry = "https://pypi.org/simple/" } +dependencies = [ + { name = "click" }, + { name = "joblib" }, + { name = "regex" }, + { name = "tqdm" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/f9/76/3a5e4312c19a028770f86fd7c058cf9f4ec4321c6cf7526bab998a5b683c/nltk-3.9.2.tar.gz", hash = "sha256:0f409e9b069ca4177c1903c3e843eef90c7e92992fa4931ae607da6de49e1419", size = 2887629, upload-time = "2025-10-01T07:19:23.764Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/60/90/81ac364ef94209c100e12579629dc92bf7a709a84af32f8c551b02c07e94/nltk-3.9.2-py3-none-any.whl", hash = "sha256:1e209d2b3009110635ed9709a67a1a3e33a10f799490fa71cf4bec218c11c88a", size = 1513404, upload-time = "2025-10-01T07:19:21.648Z" }, +] + [[package]] name = "nodeenv" version = "1.9.1" @@ -1207,6 +2179,18 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/d2/1d/1b658dbd2b9fa9c4c9f32accbfc0205d532c8c6194dc0f2a4c0428e7128a/nodeenv-1.9.1-py2.py3-none-any.whl", hash = "sha256:ba11c9782d29c27c70ffbdda2d7415098754709be8a7056d79a737cd901155c9", size = 22314, upload-time = "2024-06-04T18:44:08.352Z" }, ] +[[package]] +name = "num2words" +version = "0.5.14" +source = { registry = "https://pypi.org/simple/" } +dependencies = [ + { name = "docopt", marker = "platform_machine != 'x86_64' or sys_platform != 'darwin'" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/f6/58/ad645bd38b4b648eb2fc2ba1b909398e54eb0cbb6a7dbd2b4953e38c9621/num2words-0.5.14.tar.gz", hash = "sha256:b066ec18e56b6616a3b38086b5747daafbaa8868b226a36127e0451c0cf379c6", size = 218213, upload-time = "2024-12-17T20:17:10.191Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/d6/5b/545e9267a1cc080c8a1be2746113a063e34bcdd0f5173fd665a5c13cb234/num2words-0.5.14-py3-none-any.whl", hash = "sha256:1c8e5b00142fc2966fd8d685001e36c4a9911e070d1b120e1beb721fa1edb33d", size = 163525, upload-time = "2024-12-17T20:17:06.074Z" }, +] + [[package]] name = "numba" version = "0.62.1" @@ -1240,6 +2224,52 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/16/2e/86f24451c2d530c88daf997cb8d6ac622c1d40d19f5a031ed68a4b73a374/numpy-1.26.4-cp312-cp312-win_amd64.whl", hash = "sha256:08beddf13648eb95f8d867350f6a018a4be2e5ad54c8d8caed89ebca558b2818", size = 15517754, upload-time = "2024-02-05T23:58:36.364Z" }, ] +[[package]] +name = "nv-one-logger-core" +version = "2.3.1" +source = { registry = "https://pypi.org/simple/" } +dependencies = [ + { name = "overrides", marker = "platform_machine != 'x86_64' or sys_platform != 'darwin'" }, + { name = "pydantic", marker = "platform_machine != 'x86_64' or sys_platform != 'darwin'" }, + { name = "strenum", marker = "platform_machine != 'x86_64' or sys_platform != 'darwin'" }, + { name = "toml", marker = "platform_machine != 'x86_64' or sys_platform != 'darwin'" }, + { name = "typing-extensions", marker = "platform_machine != 'x86_64' or sys_platform != 'darwin'" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/3b/37/963095797035f371e0db6ea761f5aaccb624fc786af217115b423baeb0e2/nv_one_logger_core-2.3.1.tar.gz", hash = "sha256:cbb2f87604c78b96a302f32d87199902129d76153a73a20f8455a250b3246c1d", size = 52640, upload-time = "2025-10-29T21:11:55.812Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/ee/c4/ea91554c4fcbff66057f667690101d7a4b965605741350ac661b03fa6c46/nv_one_logger_core-2.3.1-py3-none-any.whl", hash = "sha256:0c8b77bcdac4daa1ea913bf8d4afd2a057bd5526e3654ac39f67caba157341a6", size = 63066, upload-time = "2025-10-29T21:11:52.753Z" }, +] + +[[package]] +name = "nv-one-logger-pytorch-lightning-integration" +version = "2.3.1" +source = { registry = "https://pypi.org/simple/" } +dependencies = [ + { name = "lightning", marker = "platform_machine != 'x86_64' or sys_platform != 'darwin'" }, + { name = "nv-one-logger-core", marker = "platform_machine != 'x86_64' or sys_platform != 'darwin'" }, + { name = "nv-one-logger-training-telemetry", marker = "platform_machine != 'x86_64' or sys_platform != 'darwin'" }, + { name = "setuptools", marker = "platform_machine != 'x86_64' or sys_platform != 'darwin'" }, + { name = "strenum", marker = "platform_machine != 'x86_64' or sys_platform != 'darwin'" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/0c/d0/3475b7ab17d367362f650fb0419e8669f41e63c1018f4a8ac2fbecfd2e85/nv_one_logger_pytorch_lightning_integration-2.3.1.tar.gz", hash = "sha256:b32d99b6a8f02a16538bcade939b0a7edd7249e936aacefe336b5519447340c3", size = 10979, upload-time = "2025-10-29T21:22:10.464Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/f0/56/01a55efb365b6864646b4ac941a1d9de66f024e880764510ba5a7a63f62c/nv_one_logger_pytorch_lightning_integration-2.3.1-py3-none-any.whl", hash = "sha256:f92904055fb0082516480cc1e3dd0bb6cedb2b033985ebfd4814b9cbf7da2cb2", size = 9822, upload-time = "2025-10-29T21:22:09.37Z" }, +] + +[[package]] +name = "nv-one-logger-training-telemetry" +version = "2.3.1" +source = { registry = "https://pypi.org/simple/" } +dependencies = [ + { name = "nv-one-logger-core", marker = "platform_machine != 'x86_64' or sys_platform != 'darwin'" }, + { name = "strenum", marker = "platform_machine != 'x86_64' or sys_platform != 'darwin'" }, + { name = "typing-extensions", marker = "platform_machine != 'x86_64' or sys_platform != 'darwin'" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/c5/21/016fa067967734d52f1ccf5a2a37a1a65216f2d7053bc2b85872cce956ca/nv_one_logger_training_telemetry-2.3.1.tar.gz", hash = "sha256:8c67940ea71799afaf1f46df3ba2f52f93aea26321c6f1c1d54aae02efc2a4af", size = 44435, upload-time = "2025-10-29T21:21:42.035Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/e5/15/97e6e4ddfe5fc35bcee74a45b7c33fb73abb83713c7dfa26420b971a86c3/nv_one_logger_training_telemetry-2.3.1-py3-none-any.whl", hash = "sha256:5319443829b59378a498c3c62ac98973e14f31be675c229ff2b14e2fe109aa0b", size = 44140, upload-time = "2025-10-29T21:21:40.72Z" }, +] + [[package]] name = "nvidia-cublas-cu12" version = "12.8.3.14" @@ -1277,7 +2307,7 @@ name = "nvidia-cudnn-cu12" version = "9.7.1.26" source = { registry = "https://download.pytorch.org/whl/cu128" } dependencies = [ - { name = "nvidia-cublas-cu12", marker = "(platform_machine != 'aarch64' and sys_platform == 'linux') or (platform_python_implementation != 'CPython' and sys_platform == 'linux') or (sys_platform != 'darwin' and sys_platform != 'linux')" }, + { name = "nvidia-cublas-cu12", marker = "(platform_machine != 'aarch64' and sys_platform == 'linux') or (platform_python_implementation != 'CPython' and sys_platform == 'linux')" }, ] wheels = [ { url = "https://download.pytorch.org/whl/cu128/nvidia_cudnn_cu12-9.7.1.26-py3-none-manylinux_2_27_x86_64.whl", hash = "sha256:6d011159a158f3cfc47bf851aea79e31bcff60d530b70ef70474c84cac484d07" }, @@ -1288,7 +2318,7 @@ name = "nvidia-cufft-cu12" version = "11.3.3.41" source = { registry = "https://download.pytorch.org/whl/cu128" } dependencies = [ - { name = "nvidia-nvjitlink-cu12", marker = "(platform_machine != 'aarch64' and sys_platform == 'linux') or (platform_python_implementation != 'CPython' and sys_platform == 'linux') or (sys_platform != 'darwin' and sys_platform != 'linux')" }, + { name = "nvidia-nvjitlink-cu12", marker = "(platform_machine != 'aarch64' and sys_platform == 'linux') or (platform_python_implementation != 'CPython' and sys_platform == 'linux')" }, ] wheels = [ { url = "https://download.pytorch.org/whl/cu128/nvidia_cufft_cu12-11.3.3.41-py3-none-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:da650080ab79fcdf7a4b06aa1b460e99860646b176a43f6208099bdc17836b6a" }, @@ -1315,9 +2345,9 @@ name = "nvidia-cusolver-cu12" version = "11.7.2.55" source = { registry = "https://download.pytorch.org/whl/cu128" } dependencies = [ - { name = "nvidia-cublas-cu12", marker = "(platform_machine != 'aarch64' and sys_platform == 'linux') or (platform_python_implementation != 'CPython' and sys_platform == 'linux') or (sys_platform != 'darwin' and sys_platform != 'linux')" }, - { name = "nvidia-cusparse-cu12", marker = "(platform_machine != 'aarch64' and sys_platform == 'linux') or (platform_python_implementation != 'CPython' and sys_platform == 'linux') or (sys_platform != 'darwin' and sys_platform != 'linux')" }, - { name = "nvidia-nvjitlink-cu12", marker = "(platform_machine != 'aarch64' and sys_platform == 'linux') or (platform_python_implementation != 'CPython' and sys_platform == 'linux') or (sys_platform != 'darwin' and sys_platform != 'linux')" }, + { name = "nvidia-cublas-cu12", marker = "(platform_machine != 'aarch64' and sys_platform == 'linux') or (platform_python_implementation != 'CPython' and sys_platform == 'linux')" }, + { name = "nvidia-cusparse-cu12", marker = "(platform_machine != 'aarch64' and sys_platform == 'linux') or (platform_python_implementation != 'CPython' and sys_platform == 'linux')" }, + { name = "nvidia-nvjitlink-cu12", marker = "(platform_machine != 'aarch64' and sys_platform == 'linux') or (platform_python_implementation != 'CPython' and sys_platform == 'linux')" }, ] wheels = [ { url = "https://download.pytorch.org/whl/cu128/nvidia_cusolver_cu12-11.7.2.55-py3-none-manylinux_2_27_x86_64.whl", hash = "sha256:4d1354102f1e922cee9db51920dba9e2559877cf6ff5ad03a00d853adafb191b" }, @@ -1328,7 +2358,7 @@ name = "nvidia-cusparse-cu12" version = "12.5.7.53" source = { registry = "https://download.pytorch.org/whl/cu128" } dependencies = [ - { name = "nvidia-nvjitlink-cu12", marker = "(platform_machine != 'aarch64' and sys_platform == 'linux') or (platform_python_implementation != 'CPython' and sys_platform == 'linux') or (sys_platform != 'darwin' and sys_platform != 'linux')" }, + { name = "nvidia-nvjitlink-cu12", marker = "(platform_machine != 'aarch64' and sys_platform == 'linux') or (platform_python_implementation != 'CPython' and sys_platform == 'linux')" }, ] wheels = [ { url = "https://download.pytorch.org/whl/cu128/nvidia_cusparse_cu12-12.5.7.53-py3-none-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:3c1b61eb8c85257ea07e9354606b26397612627fdcd327bfd91ccf6155e7c86d" }, @@ -1380,6 +2410,26 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/e3/94/1843518e420fa3ed6919835845df698c7e27e183cb997394e4a670973a65/omegaconf-2.3.0-py3-none-any.whl", hash = "sha256:7b4df175cdb08ba400f45cae3bdcae7ba8365db4d165fc65fd04b050ab63b46b", size = 79500, upload-time = "2022-12-08T20:59:19.686Z" }, ] +[[package]] +name = "onnx" +version = "1.19.1" +source = { registry = "https://pypi.org/simple/" } +dependencies = [ + { name = "ml-dtypes", marker = "platform_machine != 'x86_64' or sys_platform != 'darwin'" }, + { name = "numpy", marker = "platform_machine != 'x86_64' or sys_platform != 'darwin'" }, + { name = "protobuf", marker = "platform_machine != 'x86_64' or sys_platform != 'darwin'" }, + { name = "typing-extensions", marker = "platform_machine != 'x86_64' or sys_platform != 'darwin'" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/27/2f/c619eb65769357e9b6de9212c9a821ab39cd484448e5d6b3fb5fb0a64c6d/onnx-1.19.1.tar.gz", hash = "sha256:737524d6eb3907d3499ea459c6f01c5a96278bb3a0f2ff8ae04786fb5d7f1ed5", size = 12033525, upload-time = "2025-10-10T04:01:34.342Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/50/07/f6c5b2cffef8c29e739616d1415aea22f7b7ef1f19c17f02b7cff71f5498/onnx-1.19.1-cp312-cp312-macosx_12_0_universal2.whl", hash = "sha256:3612193a89ddbce5c4e86150869b9258780a82fb8c4ca197723a4460178a6ce9", size = 18327840, upload-time = "2025-10-10T04:00:24.259Z" }, + { url = "https://files.pythonhosted.org/packages/93/20/0568ebd52730287ae80cac8ac893a7301c793ea1630984e2519ee92b02a9/onnx-1.19.1-cp312-cp312-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:6c2fd2f744e7a3880ad0c262efa2edf6d965d0bd02b8f327ec516ad4cb0f2f15", size = 18042539, upload-time = "2025-10-10T04:00:27.693Z" }, + { url = "https://files.pythonhosted.org/packages/14/fd/cd7a0fd10a04f8cc5ae436b63e0022e236fe51b9dbb8ee6317fd48568c72/onnx-1.19.1-cp312-cp312-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:485d3674d50d789e0ee72fa6f6e174ab81cb14c772d594f992141bd744729d8a", size = 18218271, upload-time = "2025-10-10T04:00:30.495Z" }, + { url = "https://files.pythonhosted.org/packages/65/68/cc8b8c05469fe08384b446304ad7e6256131ca0463bf6962366eebec98c0/onnx-1.19.1-cp312-cp312-win32.whl", hash = "sha256:638bc56ff1a5718f7441e887aeb4e450f37a81c6eac482040381b140bd9ba601", size = 16345111, upload-time = "2025-10-10T04:00:34.982Z" }, + { url = "https://files.pythonhosted.org/packages/c7/5e/d1cb16693598a512c2cf9ffe0841d8d8fd2c83ae8e889efd554f5aa427cf/onnx-1.19.1-cp312-cp312-win_amd64.whl", hash = "sha256:bc7e2e4e163e679721e547958b5a7db875bf822cad371b7c1304aa4401a7c7a4", size = 16465621, upload-time = "2025-10-10T04:00:39.107Z" }, + { url = "https://files.pythonhosted.org/packages/90/32/da116cc61fdef334782aa7f87a1738431dd1af1a5d1a44bd95d6d51ad260/onnx-1.19.1-cp312-cp312-win_arm64.whl", hash = "sha256:17c215b1c0f20fe93b4cbe62668247c1d2294b9bc7f6be0ca9ced28e980c07b7", size = 16437505, upload-time = "2025-10-10T04:00:42.255Z" }, +] + [[package]] name = "onnxruntime" version = "1.18.1" @@ -1457,12 +2507,39 @@ wheels = [ ] [[package]] -name = "packaging" -version = "25.0" +name = "optuna" +version = "4.6.0" source = { registry = "https://pypi.org/simple/" } -sdist = { url = "https://files.pythonhosted.org/packages/a1/d4/1fc4078c65507b51b96ca8f8c3ba19e6a61c8253c72794544580a7b6c24d/packaging-25.0.tar.gz", hash = "sha256:d443872c98d677bf60f6a1f2f8c1cb748e8fe762d2bf9d3148b5599295b0fc4f", size = 165727, upload-time = "2025-04-19T11:48:59.673Z" } +dependencies = [ + { name = "alembic", marker = "platform_machine != 'x86_64' or sys_platform != 'darwin'" }, + { name = "colorlog", marker = "platform_machine != 'x86_64' or sys_platform != 'darwin'" }, + { name = "numpy", marker = "platform_machine != 'x86_64' or sys_platform != 'darwin'" }, + { name = "packaging", marker = "platform_machine != 'x86_64' or sys_platform != 'darwin'" }, + { name = "pyyaml", marker = "platform_machine != 'x86_64' or sys_platform != 'darwin'" }, + { name = "sqlalchemy", marker = "platform_machine != 'x86_64' or sys_platform != 'darwin'" }, + { name = "tqdm", marker = "platform_machine != 'x86_64' or sys_platform != 'darwin'" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/6b/81/08f90f194eed78178064a9383432eca95611e2c5331e7b01e2418ce4b15a/optuna-4.6.0.tar.gz", hash = "sha256:89e38c2447c7f793a726617b8043f01e31f0bad54855040db17eb3b49404a369", size = 477444, upload-time = "2025-11-10T05:14:30.151Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/20/12/38679034af332785aac8774540895e234f4d07f7545804097de4b666afd8/packaging-25.0-py3-none-any.whl", hash = "sha256:29572ef2b1f17581046b3a2227d5c611fb25ec70ca1ba8554b24b0e69331a484", size = 66469, upload-time = "2025-04-19T11:48:57.875Z" }, + { url = "https://files.pythonhosted.org/packages/58/de/3d8455b08cb6312f8cc46aacdf16c71d4d881a1db4a4140fc5ef31108422/optuna-4.6.0-py3-none-any.whl", hash = "sha256:4c3a9facdef2b2dd7e3e2a8ae3697effa70fae4056fcf3425cfc6f5a40feb069", size = 404708, upload-time = "2025-11-10T05:14:28.6Z" }, +] + +[[package]] +name = "overrides" +version = "7.7.0" +source = { registry = "https://pypi.org/simple/" } +sdist = { url = "https://files.pythonhosted.org/packages/36/86/b585f53236dec60aba864e050778b25045f857e17f6e5ea0ae95fe80edd2/overrides-7.7.0.tar.gz", hash = "sha256:55158fa3d93b98cc75299b1e67078ad9003ca27945c76162c1c0766d6f91820a", size = 22812, upload-time = "2024-01-27T21:01:33.423Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/2c/ab/fc8290c6a4c722e5514d80f62b2dc4c4df1a68a41d1364e625c35990fcf3/overrides-7.7.0-py3-none-any.whl", hash = "sha256:c7ed9d062f78b8e4c1a7b70bd8796b35ead4d9f510227ef9c5dc7626c60d7e49", size = 17832, upload-time = "2024-01-27T21:01:31.393Z" }, +] + +[[package]] +name = "packaging" +version = "24.2" +source = { registry = "https://pypi.org/simple/" } +sdist = { url = "https://files.pythonhosted.org/packages/d0/63/68dbb6eb2de9cb10ee4c9c14a0148804425e13c4fb20d61cce69f53106da/packaging-24.2.tar.gz", hash = "sha256:c228a6dc5e932d346bc5739379109d49e8853dd8223571c7c5b55260edc0b97f", size = 163950, upload-time = "2024-11-08T09:47:47.202Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/88/ef/eb23f262cca3c0c4eb7ab1933c3b1f03d021f2c48f54763065b6f0e321be/packaging-24.2-py3-none-any.whl", hash = "sha256:09abb1bccd265c01f4a3aa3f7a7db064b36514d2cba19a2f694fe6150451a759", size = 65451, upload-time = "2024-11-08T09:47:44.722Z" }, ] [[package]] @@ -1486,6 +2563,15 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/86/41/585a168330ff063014880a80d744219dbf1dd7a1c706e75ab3425a987384/pandas-2.3.3-cp312-cp312-win_amd64.whl", hash = "sha256:a16dcec078a01eeef8ee61bf64074b4e524a2a3f4b3be9326420cabe59c4778b", size = 10992722, upload-time = "2025-09-29T23:20:54.139Z" }, ] +[[package]] +name = "parso" +version = "0.8.5" +source = { registry = "https://pypi.org/simple/" } +sdist = { url = "https://files.pythonhosted.org/packages/d4/de/53e0bcf53d13e005bd8c92e7855142494f41171b34c2536b86187474184d/parso-0.8.5.tar.gz", hash = "sha256:034d7354a9a018bdce352f48b2a8a450f05e9d6ee85db84764e9b6bd96dafe5a", size = 401205, upload-time = "2025-08-23T15:15:28.028Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/16/32/f8e3c85d1d5250232a5d3477a2a28cc291968ff175caeadaf3cc19ce0e4a/parso-0.8.5-py2.py3-none-any.whl", hash = "sha256:646204b5ee239c396d040b90f9e272e9a8017c630092bf59980beb62fd033887", size = 106668, upload-time = "2025-08-23T15:15:25.663Z" }, +] + [[package]] name = "pathspec" version = "0.12.1" @@ -1504,6 +2590,68 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/55/26/d0ad8b448476d0a1e8d3ea5622dc77b916db84c6aa3cb1e1c0965af948fc/pefile-2023.2.7-py3-none-any.whl", hash = "sha256:da185cd2af68c08a6cd4481f7325ed600a88f6a813bad9dea07ab3ef73d8d8d6", size = 71791, upload-time = "2023-02-07T12:28:36.678Z" }, ] +[[package]] +name = "peft" +version = "0.18.0" +source = { registry = "https://pypi.org/simple/" } +dependencies = [ + { name = "accelerate", marker = "platform_machine != 'x86_64' or sys_platform != 'darwin'" }, + { name = "huggingface-hub", marker = "platform_machine != 'x86_64' or sys_platform != 'darwin'" }, + { name = "numpy", marker = "platform_machine != 'x86_64' or sys_platform != 'darwin'" }, + { name = "packaging", marker = "platform_machine != 'x86_64' or sys_platform != 'darwin'" }, + { name = "psutil", marker = "platform_machine != 'x86_64' or sys_platform != 'darwin'" }, + { name = "pyyaml", marker = "platform_machine != 'x86_64' or sys_platform != 'darwin'" }, + { name = "safetensors", marker = "platform_machine != 'x86_64' or sys_platform != 'darwin'" }, + { name = "torch", version = "2.7.1", source = { registry = "https://pypi.org/simple/" }, marker = "platform_machine != 'x86_64' and sys_platform == 'darwin'" }, + { name = "torch", version = "2.7.1+cu128", source = { registry = "https://download.pytorch.org/whl/cu128" }, marker = "sys_platform != 'darwin'" }, + { name = "tqdm", marker = "platform_machine != 'x86_64' or sys_platform != 'darwin'" }, + { name = "transformers", marker = "platform_machine != 'x86_64' or sys_platform != 'darwin'" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/4b/0c/f2938db546ac7fc961ab5917cd50fcf5d0d70b406de93e3faccaa504e152/peft-0.18.0.tar.gz", hash = "sha256:c81c80b2056ab40c23d58ef25f74daab417ac653970718589a11a8af28218588", size = 634141, upload-time = "2025-11-13T11:13:06.603Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/0f/55/481bf25613d40ef53534f664deba7b138fe566356b6ca10304e2b3b2529c/peft-0.18.0-py3-none-any.whl", hash = "sha256:624f69ca6393b765ccc6734adda7ca57d80b238f0900a42c357d8b67a03d62ff", size = 556427, upload-time = "2025-11-13T11:13:03.664Z" }, +] + +[[package]] +name = "pexpect" +version = "4.9.0" +source = { registry = "https://pypi.org/simple/" } +dependencies = [ + { name = "ptyprocess", marker = "platform_machine != 'x86_64' or sys_platform != 'darwin'" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/42/92/cc564bf6381ff43ce1f4d06852fc19a2f11d180f23dc32d9588bee2f149d/pexpect-4.9.0.tar.gz", hash = "sha256:ee7d41123f3c9911050ea2c2dac107568dc43b2d3b0c7557a33212c398ead30f", size = 166450, upload-time = "2023-11-25T09:07:26.339Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/9e/c3/059298687310d527a58bb01f3b1965787ee3b40dce76752eda8b44e9a2c5/pexpect-4.9.0-py2.py3-none-any.whl", hash = "sha256:7236d1e080e4936be2dc3e326cec0af72acf9212a7e1d060210e70a47e253523", size = 63772, upload-time = "2023-11-25T06:56:14.81Z" }, +] + +[[package]] +name = "pillow" +version = "12.0.0" +source = { registry = "https://pypi.org/simple/" } +sdist = { url = "https://files.pythonhosted.org/packages/5a/b0/cace85a1b0c9775a9f8f5d5423c8261c858760e2466c79b2dd184638b056/pillow-12.0.0.tar.gz", hash = "sha256:87d4f8125c9988bfbed67af47dd7a953e2fc7b0cc1e7800ec6d2080d490bb353", size = 47008828, upload-time = "2025-10-15T18:24:14.008Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/2c/90/4fcce2c22caf044e660a198d740e7fbc14395619e3cb1abad12192c0826c/pillow-12.0.0-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:53561a4ddc36facb432fae7a9d8afbfaf94795414f5cdc5fc52f28c1dca90371", size = 5249377, upload-time = "2025-10-15T18:22:05.993Z" }, + { url = "https://files.pythonhosted.org/packages/fd/e0/ed960067543d080691d47d6938ebccbf3976a931c9567ab2fbfab983a5dd/pillow-12.0.0-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:71db6b4c1653045dacc1585c1b0d184004f0d7e694c7b34ac165ca70c0838082", size = 4650343, upload-time = "2025-10-15T18:22:07.718Z" }, + { url = "https://files.pythonhosted.org/packages/e7/a1/f81fdeddcb99c044bf7d6faa47e12850f13cee0849537a7d27eeab5534d4/pillow-12.0.0-cp312-cp312-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:2fa5f0b6716fc88f11380b88b31fe591a06c6315e955c096c35715788b339e3f", size = 6232981, upload-time = "2025-10-15T18:22:09.287Z" }, + { url = "https://files.pythonhosted.org/packages/88/e1/9098d3ce341a8750b55b0e00c03f1630d6178f38ac191c81c97a3b047b44/pillow-12.0.0-cp312-cp312-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:82240051c6ca513c616f7f9da06e871f61bfd7805f566275841af15015b8f98d", size = 8041399, upload-time = "2025-10-15T18:22:10.872Z" }, + { url = "https://files.pythonhosted.org/packages/a7/62/a22e8d3b602ae8cc01446d0c57a54e982737f44b6f2e1e019a925143771d/pillow-12.0.0-cp312-cp312-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:55f818bd74fe2f11d4d7cbc65880a843c4075e0ac7226bc1a23261dbea531953", size = 6347740, upload-time = "2025-10-15T18:22:12.769Z" }, + { url = "https://files.pythonhosted.org/packages/4f/87/424511bdcd02c8d7acf9f65caa09f291a519b16bd83c3fb3374b3d4ae951/pillow-12.0.0-cp312-cp312-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:b87843e225e74576437fd5b6a4c2205d422754f84a06942cfaf1dc32243e45a8", size = 7040201, upload-time = "2025-10-15T18:22:14.813Z" }, + { url = "https://files.pythonhosted.org/packages/dc/4d/435c8ac688c54d11755aedfdd9f29c9eeddf68d150fe42d1d3dbd2365149/pillow-12.0.0-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:c607c90ba67533e1b2355b821fef6764d1dd2cbe26b8c1005ae84f7aea25ff79", size = 6462334, upload-time = "2025-10-15T18:22:16.375Z" }, + { url = "https://files.pythonhosted.org/packages/2b/f2/ad34167a8059a59b8ad10bc5c72d4d9b35acc6b7c0877af8ac885b5f2044/pillow-12.0.0-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:21f241bdd5080a15bc86d3466a9f6074a9c2c2b314100dd896ac81ee6db2f1ba", size = 7134162, upload-time = "2025-10-15T18:22:17.996Z" }, + { url = "https://files.pythonhosted.org/packages/0c/b1/a7391df6adacf0a5c2cf6ac1cf1fcc1369e7d439d28f637a847f8803beb3/pillow-12.0.0-cp312-cp312-win32.whl", hash = "sha256:dd333073e0cacdc3089525c7df7d39b211bcdf31fc2824e49d01c6b6187b07d0", size = 6298769, upload-time = "2025-10-15T18:22:19.923Z" }, + { url = "https://files.pythonhosted.org/packages/a2/0b/d87733741526541c909bbf159e338dcace4f982daac6e5a8d6be225ca32d/pillow-12.0.0-cp312-cp312-win_amd64.whl", hash = "sha256:9fe611163f6303d1619bbcb653540a4d60f9e55e622d60a3108be0d5b441017a", size = 7001107, upload-time = "2025-10-15T18:22:21.644Z" }, + { url = "https://files.pythonhosted.org/packages/bc/96/aaa61ce33cc98421fb6088af2a03be4157b1e7e0e87087c888e2370a7f45/pillow-12.0.0-cp312-cp312-win_arm64.whl", hash = "sha256:7dfb439562f234f7d57b1ac6bc8fe7f838a4bd49c79230e0f6a1da93e82f1fad", size = 2436012, upload-time = "2025-10-15T18:22:23.621Z" }, +] + +[[package]] +name = "plac" +version = "1.4.5" +source = { registry = "https://pypi.org/simple/" } +sdist = { url = "https://files.pythonhosted.org/packages/23/09/26ef2d614cabdcc52a7f383d0dc7967bf46be3c9700898c594e37b710c3d/plac-1.4.5.tar.gz", hash = "sha256:5f05bf85235c017fcd76c73c8101d4ff8e96beb3dc58b9a37de49cac7de82d14", size = 38988, upload-time = "2025-04-04T14:03:25.651Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/15/36/38676114a0dbee137ec366daa86603d667a07e9a52667d5ebf5c580100ba/plac-1.4.5-py2.py3-none-any.whl", hash = "sha256:87187786b4e446688b1cf5112e18fed8a23ab3b316c25fe91266a10bd1736b16", size = 22468, upload-time = "2025-04-04T14:03:24.761Z" }, +] + [[package]] name = "platformdirs" version = "4.5.0" @@ -1531,6 +2679,20 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/6b/99/45bb1f9926efe370c6dbe324741c749658e44cb060124f28dad201202274/polib-1.2.0-py2.py3-none-any.whl", hash = "sha256:1c77ee1b81feb31df9bca258cbc58db1bbb32d10214b173882452c73af06d62d", size = 20634, upload-time = "2023-02-23T17:53:59.919Z" }, ] +[[package]] +name = "pooch" +version = "1.8.2" +source = { registry = "https://pypi.org/simple/" } +dependencies = [ + { name = "packaging", marker = "platform_machine != 'x86_64' or sys_platform != 'darwin'" }, + { name = "platformdirs", marker = "platform_machine != 'x86_64' or sys_platform != 'darwin'" }, + { name = "requests", marker = "platform_machine != 'x86_64' or sys_platform != 'darwin'" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/c6/77/b3d3e00c696c16cf99af81ef7b1f5fe73bd2a307abca41bd7605429fe6e5/pooch-1.8.2.tar.gz", hash = "sha256:76561f0de68a01da4df6af38e9955c4c9d1a5c90da73f7e40276a5728ec83d10", size = 59353, upload-time = "2024-06-06T16:53:46.224Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/a8/87/77cc11c7a9ea9fd05503def69e3d18605852cd0d4b0d3b8f15bbeb3ef1d1/pooch-1.8.2-py3-none-any.whl", hash = "sha256:3529a57096f7198778a5ceefd5ac3ef0e4d06a6ddaf9fc2d609b806f25302c47", size = 64574, upload-time = "2024-06-06T16:53:44.343Z" }, +] + [[package]] name = "posthog" version = "3.25.0" @@ -1565,18 +2727,53 @@ wheels = [ ] [[package]] -name = "protobuf" -version = "6.33.0" +name = "prompt-toolkit" +version = "3.0.52" source = { registry = "https://pypi.org/simple/" } -sdist = { url = "https://files.pythonhosted.org/packages/19/ff/64a6c8f420818bb873713988ca5492cba3a7946be57e027ac63495157d97/protobuf-6.33.0.tar.gz", hash = "sha256:140303d5c8d2037730c548f8c7b93b20bb1dc301be280c378b82b8894589c954", size = 443463, upload-time = "2025-10-15T20:39:52.159Z" } +dependencies = [ + { name = "wcwidth", marker = "platform_machine != 'x86_64' or sys_platform != 'darwin'" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/a1/96/06e01a7b38dce6fe1db213e061a4602dd6032a8a97ef6c1a862537732421/prompt_toolkit-3.0.52.tar.gz", hash = "sha256:28cde192929c8e7321de85de1ddbe736f1375148b02f2e17edd840042b1be855", size = 434198, upload-time = "2025-08-27T15:24:02.057Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/7e/ee/52b3fa8feb6db4a833dfea4943e175ce645144532e8a90f72571ad85df4e/protobuf-6.33.0-cp310-abi3-win32.whl", hash = "sha256:d6101ded078042a8f17959eccd9236fb7a9ca20d3b0098bbcb91533a5680d035", size = 425593, upload-time = "2025-10-15T20:39:40.29Z" }, - { url = "https://files.pythonhosted.org/packages/7b/c6/7a465f1825872c55e0341ff4a80198743f73b69ce5d43ab18043699d1d81/protobuf-6.33.0-cp310-abi3-win_amd64.whl", hash = "sha256:9a031d10f703f03768f2743a1c403af050b6ae1f3480e9c140f39c45f81b13ee", size = 436882, upload-time = "2025-10-15T20:39:42.841Z" }, - { url = "https://files.pythonhosted.org/packages/e1/a9/b6eee662a6951b9c3640e8e452ab3e09f117d99fc10baa32d1581a0d4099/protobuf-6.33.0-cp39-abi3-macosx_10_9_universal2.whl", hash = "sha256:905b07a65f1a4b72412314082c7dbfae91a9e8b68a0cc1577515f8df58ecf455", size = 427521, upload-time = "2025-10-15T20:39:43.803Z" }, - { url = "https://files.pythonhosted.org/packages/10/35/16d31e0f92c6d2f0e77c2a3ba93185130ea13053dd16200a57434c882f2b/protobuf-6.33.0-cp39-abi3-manylinux2014_aarch64.whl", hash = "sha256:e0697ece353e6239b90ee43a9231318302ad8353c70e6e45499fa52396debf90", size = 324445, upload-time = "2025-10-15T20:39:44.932Z" }, - { url = "https://files.pythonhosted.org/packages/e6/eb/2a981a13e35cda8b75b5585aaffae2eb904f8f351bdd3870769692acbd8a/protobuf-6.33.0-cp39-abi3-manylinux2014_s390x.whl", hash = "sha256:e0a1715e4f27355afd9570f3ea369735afc853a6c3951a6afe1f80d8569ad298", size = 339159, upload-time = "2025-10-15T20:39:46.186Z" }, - { url = "https://files.pythonhosted.org/packages/21/51/0b1cbad62074439b867b4e04cc09b93f6699d78fd191bed2bbb44562e077/protobuf-6.33.0-cp39-abi3-manylinux2014_x86_64.whl", hash = "sha256:35be49fd3f4fefa4e6e2aacc35e8b837d6703c37a2168a55ac21e9b1bc7559ef", size = 323172, upload-time = "2025-10-15T20:39:47.465Z" }, - { url = "https://files.pythonhosted.org/packages/07/d1/0a28c21707807c6aacd5dc9c3704b2aa1effbf37adebd8caeaf68b17a636/protobuf-6.33.0-py3-none-any.whl", hash = "sha256:25c9e1963c6734448ea2d308cfa610e692b801304ba0908d7bfa564ac5132995", size = 170477, upload-time = "2025-10-15T20:39:51.311Z" }, + { url = "https://files.pythonhosted.org/packages/84/03/0d3ce49e2505ae70cf43bc5bb3033955d2fc9f932163e84dc0779cc47f48/prompt_toolkit-3.0.52-py3-none-any.whl", hash = "sha256:9aac639a3bbd33284347de5ad8d68ecc044b91a762dc39b7c21095fcd6a19955", size = 391431, upload-time = "2025-08-27T15:23:59.498Z" }, +] + +[[package]] +name = "propcache" +version = "0.4.1" +source = { registry = "https://pypi.org/simple/" } +sdist = { url = "https://files.pythonhosted.org/packages/9e/da/e9fc233cf63743258bff22b3dfa7ea5baef7b5bc324af47a0ad89b8ffc6f/propcache-0.4.1.tar.gz", hash = "sha256:f48107a8c637e80362555f37ecf49abe20370e557cc4ab374f04ec4423c97c3d", size = 46442, upload-time = "2025-10-08T19:49:02.291Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/a2/0f/f17b1b2b221d5ca28b4b876e8bb046ac40466513960646bda8e1853cdfa2/propcache-0.4.1-cp312-cp312-macosx_10_13_universal2.whl", hash = "sha256:e153e9cd40cc8945138822807139367f256f89c6810c2634a4f6902b52d3b4e2", size = 80061, upload-time = "2025-10-08T19:46:46.075Z" }, + { url = "https://files.pythonhosted.org/packages/76/47/8ccf75935f51448ba9a16a71b783eb7ef6b9ee60f5d14c7f8a8a79fbeed7/propcache-0.4.1-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:cd547953428f7abb73c5ad82cbb32109566204260d98e41e5dfdc682eb7f8403", size = 46037, upload-time = "2025-10-08T19:46:47.23Z" }, + { url = "https://files.pythonhosted.org/packages/0a/b6/5c9a0e42df4d00bfb4a3cbbe5cf9f54260300c88a0e9af1f47ca5ce17ac0/propcache-0.4.1-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:f048da1b4f243fc44f205dfd320933a951b8d89e0afd4c7cacc762a8b9165207", size = 47324, upload-time = "2025-10-08T19:46:48.384Z" }, + { url = "https://files.pythonhosted.org/packages/9e/d3/6c7ee328b39a81ee877c962469f1e795f9db87f925251efeb0545e0020d0/propcache-0.4.1-cp312-cp312-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:ec17c65562a827bba85e3872ead335f95405ea1674860d96483a02f5c698fa72", size = 225505, upload-time = "2025-10-08T19:46:50.055Z" }, + { url = "https://files.pythonhosted.org/packages/01/5d/1c53f4563490b1d06a684742cc6076ef944bc6457df6051b7d1a877c057b/propcache-0.4.1-cp312-cp312-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:405aac25c6394ef275dee4c709be43745d36674b223ba4eb7144bf4d691b7367", size = 230242, upload-time = "2025-10-08T19:46:51.815Z" }, + { url = "https://files.pythonhosted.org/packages/20/e1/ce4620633b0e2422207c3cb774a0ee61cac13abc6217763a7b9e2e3f4a12/propcache-0.4.1-cp312-cp312-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:0013cb6f8dde4b2a2f66903b8ba740bdfe378c943c4377a200551ceb27f379e4", size = 238474, upload-time = "2025-10-08T19:46:53.208Z" }, + { url = "https://files.pythonhosted.org/packages/46/4b/3aae6835b8e5f44ea6a68348ad90f78134047b503765087be2f9912140ea/propcache-0.4.1-cp312-cp312-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:15932ab57837c3368b024473a525e25d316d8353016e7cc0e5ba9eb343fbb1cf", size = 221575, upload-time = "2025-10-08T19:46:54.511Z" }, + { url = "https://files.pythonhosted.org/packages/6e/a5/8a5e8678bcc9d3a1a15b9a29165640d64762d424a16af543f00629c87338/propcache-0.4.1-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:031dce78b9dc099f4c29785d9cf5577a3faf9ebf74ecbd3c856a7b92768c3df3", size = 216736, upload-time = "2025-10-08T19:46:56.212Z" }, + { url = "https://files.pythonhosted.org/packages/f1/63/b7b215eddeac83ca1c6b934f89d09a625aa9ee4ba158338854c87210cc36/propcache-0.4.1-cp312-cp312-musllinux_1_2_armv7l.whl", hash = "sha256:ab08df6c9a035bee56e31af99be621526bd237bea9f32def431c656b29e41778", size = 213019, upload-time = "2025-10-08T19:46:57.595Z" }, + { url = "https://files.pythonhosted.org/packages/57/74/f580099a58c8af587cac7ba19ee7cb418506342fbbe2d4a4401661cca886/propcache-0.4.1-cp312-cp312-musllinux_1_2_ppc64le.whl", hash = "sha256:4d7af63f9f93fe593afbf104c21b3b15868efb2c21d07d8732c0c4287e66b6a6", size = 220376, upload-time = "2025-10-08T19:46:59.067Z" }, + { url = "https://files.pythonhosted.org/packages/c4/ee/542f1313aff7eaf19c2bb758c5d0560d2683dac001a1c96d0774af799843/propcache-0.4.1-cp312-cp312-musllinux_1_2_s390x.whl", hash = "sha256:cfc27c945f422e8b5071b6e93169679e4eb5bf73bbcbf1ba3ae3a83d2f78ebd9", size = 226988, upload-time = "2025-10-08T19:47:00.544Z" }, + { url = "https://files.pythonhosted.org/packages/8f/18/9c6b015dd9c6930f6ce2229e1f02fb35298b847f2087ea2b436a5bfa7287/propcache-0.4.1-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:35c3277624a080cc6ec6f847cbbbb5b49affa3598c4535a0a4682a697aaa5c75", size = 215615, upload-time = "2025-10-08T19:47:01.968Z" }, + { url = "https://files.pythonhosted.org/packages/80/9e/e7b85720b98c45a45e1fca6a177024934dc9bc5f4d5dd04207f216fc33ed/propcache-0.4.1-cp312-cp312-win32.whl", hash = "sha256:671538c2262dadb5ba6395e26c1731e1d52534bfe9ae56d0b5573ce539266aa8", size = 38066, upload-time = "2025-10-08T19:47:03.503Z" }, + { url = "https://files.pythonhosted.org/packages/54/09/d19cff2a5aaac632ec8fc03737b223597b1e347416934c1b3a7df079784c/propcache-0.4.1-cp312-cp312-win_amd64.whl", hash = "sha256:cb2d222e72399fcf5890d1d5cc1060857b9b236adff2792ff48ca2dfd46c81db", size = 41655, upload-time = "2025-10-08T19:47:04.973Z" }, + { url = "https://files.pythonhosted.org/packages/68/ab/6b5c191bb5de08036a8c697b265d4ca76148efb10fa162f14af14fb5f076/propcache-0.4.1-cp312-cp312-win_arm64.whl", hash = "sha256:204483131fb222bdaaeeea9f9e6c6ed0cac32731f75dfc1d4a567fc1926477c1", size = 37789, upload-time = "2025-10-08T19:47:06.077Z" }, + { url = "https://files.pythonhosted.org/packages/5b/5a/bc7b4a4ef808fa59a816c17b20c4bef6884daebbdf627ff2a161da67da19/propcache-0.4.1-py3-none-any.whl", hash = "sha256:af2a6052aeb6cf17d3e46ee169099044fd8224cbaf75c76a2ef596e8163e2237", size = 13305, upload-time = "2025-10-08T19:49:00.792Z" }, +] + +[[package]] +name = "protobuf" +version = "5.29.5" +source = { registry = "https://pypi.org/simple/" } +sdist = { url = "https://files.pythonhosted.org/packages/43/29/d09e70352e4e88c9c7a198d5645d7277811448d76c23b00345670f7c8a38/protobuf-5.29.5.tar.gz", hash = "sha256:bc1463bafd4b0929216c35f437a8e28731a2b7fe3d98bb77a600efced5a15c84", size = 425226, upload-time = "2025-05-28T23:51:59.82Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/5f/11/6e40e9fc5bba02988a214c07cf324595789ca7820160bfd1f8be96e48539/protobuf-5.29.5-cp310-abi3-win32.whl", hash = "sha256:3f1c6468a2cfd102ff4703976138844f78ebd1fb45f49011afc5139e9e283079", size = 422963, upload-time = "2025-05-28T23:51:41.204Z" }, + { url = "https://files.pythonhosted.org/packages/81/7f/73cefb093e1a2a7c3ffd839e6f9fcafb7a427d300c7f8aef9c64405d8ac6/protobuf-5.29.5-cp310-abi3-win_amd64.whl", hash = "sha256:3f76e3a3675b4a4d867b52e4a5f5b78a2ef9565549d4037e06cf7b0942b1d3fc", size = 434818, upload-time = "2025-05-28T23:51:44.297Z" }, + { url = "https://files.pythonhosted.org/packages/dd/73/10e1661c21f139f2c6ad9b23040ff36fee624310dc28fba20d33fdae124c/protobuf-5.29.5-cp38-abi3-macosx_10_9_universal2.whl", hash = "sha256:e38c5add5a311f2a6eb0340716ef9b039c1dfa428b28f25a7838ac329204a671", size = 418091, upload-time = "2025-05-28T23:51:45.907Z" }, + { url = "https://files.pythonhosted.org/packages/6c/04/98f6f8cf5b07ab1294c13f34b4e69b3722bb609c5b701d6c169828f9f8aa/protobuf-5.29.5-cp38-abi3-manylinux2014_aarch64.whl", hash = "sha256:fa18533a299d7ab6c55a238bf8629311439995f2e7eca5caaff08663606e9015", size = 319824, upload-time = "2025-05-28T23:51:47.545Z" }, + { url = "https://files.pythonhosted.org/packages/85/e4/07c80521879c2d15f321465ac24c70efe2381378c00bf5e56a0f4fbac8cd/protobuf-5.29.5-cp38-abi3-manylinux2014_x86_64.whl", hash = "sha256:63848923da3325e1bf7e9003d680ce6e14b07e55d0473253a690c3a8b8fd6e61", size = 319942, upload-time = "2025-05-28T23:51:49.11Z" }, + { url = "https://files.pythonhosted.org/packages/7e/cc/7e77861000a0691aeea8f4566e5d3aa716f2b1dece4a24439437e41d3d25/protobuf-5.29.5-py3-none-any.whl", hash = "sha256:6cf42630262c59b2d8de33954443d94b746c952b01434fc58a417fdbd2e84bd5", size = 172823, upload-time = "2025-05-28T23:51:58.157Z" }, ] [[package]] @@ -1595,6 +2792,24 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/0a/8d/8a9a45c8b655851f216c1d44f68e3533dc8d2c752ccd0f61f1aa73be4893/psutil-7.1.1-cp37-abi3-win_arm64.whl", hash = "sha256:5457cf741ca13da54624126cd5d333871b454ab133999a9a103fb097a7d7d21a", size = 243944, upload-time = "2025-10-19T15:44:20.666Z" }, ] +[[package]] +name = "ptyprocess" +version = "0.7.0" +source = { registry = "https://pypi.org/simple/" } +sdist = { url = "https://files.pythonhosted.org/packages/20/e5/16ff212c1e452235a90aeb09066144d0c5a6a8c0834397e03f5224495c4e/ptyprocess-0.7.0.tar.gz", hash = "sha256:5c5d0a3b48ceee0b48485e0c26037c0acd7d29765ca3fbb5cb3831d347423220", size = 70762, upload-time = "2020-12-28T15:15:30.155Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/22/a6/858897256d0deac81a172289110f31629fc4cee19b6f01283303e18c8db3/ptyprocess-0.7.0-py2.py3-none-any.whl", hash = "sha256:4b41f3967fce3af57cc7e94b888626c18bf37a083e3651ca8feeb66d492fef35", size = 13993, upload-time = "2020-12-28T15:15:28.35Z" }, +] + +[[package]] +name = "pure-eval" +version = "0.2.3" +source = { registry = "https://pypi.org/simple/" } +sdist = { url = "https://files.pythonhosted.org/packages/cd/05/0a34433a064256a578f1783a10da6df098ceaa4a57bbeaa96a6c0352786b/pure_eval-0.2.3.tar.gz", hash = "sha256:5f4e983f40564c576c7c8635ae88db5956bb2229d7e9237d03b3c0b0190eaf42", size = 19752, upload-time = "2024-07-21T12:58:21.801Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/8e/37/efad0257dc6e593a18957422533ff0f87ede7c9c6ea010a2177d738fb82f/pure_eval-0.2.3-py3-none-any.whl", hash = "sha256:1db8e35b67b3d218d818ae653e27f06c3aa420901fa7b081ca98cbedc874e0d0", size = 11842, upload-time = "2024-07-21T12:58:20.04Z" }, +] + [[package]] name = "py-cpuinfo" version = "9.0.0" @@ -1616,6 +2831,81 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/a8/ee/a878f2ad010cbccb311f947f0f2f09d38f613938ee28c34e60fceecc75a1/pyaml-25.7.0-py3-none-any.whl", hash = "sha256:ce5d7867cc2b455efdb9b0448324ff7b9f74d99f64650f12ca570102db6b985f", size = 26418, upload-time = "2025-07-10T18:44:50.679Z" }, ] +[[package]] +name = "pyannote-core" +version = "5.0.0" +source = { registry = "https://pypi.org/simple/" } +dependencies = [ + { name = "numpy", marker = "platform_machine != 'x86_64' or sys_platform != 'darwin'" }, + { name = "scipy", marker = "platform_machine != 'x86_64' or sys_platform != 'darwin'" }, + { name = "sortedcontainers", marker = "platform_machine != 'x86_64' or sys_platform != 'darwin'" }, + { name = "typing-extensions", marker = "platform_machine != 'x86_64' or sys_platform != 'darwin'" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/65/03/feaf7534206f02c75baf151ce4b8c322b402a6f477c2be82f69d9269cbe6/pyannote.core-5.0.0.tar.gz", hash = "sha256:1a55bcc8bd680ba6be5fa53efa3b6f3d2cdd67144c07b6b4d8d66d5cb0d2096f", size = 59247, upload-time = "2022-12-15T13:02:05.312Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/84/c4/370bc8ba66815a5832ece753a1009388bb07ea353d21c83f2d5a1a436f2c/pyannote.core-5.0.0-py3-none-any.whl", hash = "sha256:04920a6754492242ce0dc6017545595ab643870fe69a994f20c1a5f2da0544d0", size = 58475, upload-time = "2022-12-15T13:02:03.265Z" }, +] + +[[package]] +name = "pyannote-database" +version = "5.1.3" +source = { registry = "https://pypi.org/simple/" } +dependencies = [ + { name = "pandas", marker = "platform_machine != 'x86_64' or sys_platform != 'darwin'" }, + { name = "pyannote-core", marker = "platform_machine != 'x86_64' or sys_platform != 'darwin'" }, + { name = "pyyaml", marker = "platform_machine != 'x86_64' or sys_platform != 'darwin'" }, + { name = "typer", marker = "platform_machine != 'x86_64' or sys_platform != 'darwin'" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/a9/ae/de36413d69a46be87cb612ebbcdc4eacbeebce3bc809124603e44a88fe26/pyannote.database-5.1.3.tar.gz", hash = "sha256:0eaf64c1cc506718de60d2d702f1359b1ae7ff252ee3e4799f1c5e378cd52c31", size = 49957, upload-time = "2025-01-15T20:28:26.437Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/a1/64/92d51a3a05615ba58be8ba62a43f9f9f952d9f3646f7e4fb7826e5a3a24e/pyannote.database-5.1.3-py3-none-any.whl", hash = "sha256:37887844c7dfbcc075cb591eddc00aff45fae1ed905344e1f43e0090e63bd40a", size = 48127, upload-time = "2025-01-15T20:28:25.326Z" }, +] + +[[package]] +name = "pyannote-metrics" +version = "3.2.1" +source = { registry = "https://pypi.org/simple/" } +dependencies = [ + { name = "docopt", marker = "platform_machine != 'x86_64' or sys_platform != 'darwin'" }, + { name = "matplotlib", marker = "platform_machine != 'x86_64' or sys_platform != 'darwin'" }, + { name = "numpy", marker = "platform_machine != 'x86_64' or sys_platform != 'darwin'" }, + { name = "pandas", marker = "platform_machine != 'x86_64' or sys_platform != 'darwin'" }, + { name = "pyannote-core", marker = "platform_machine != 'x86_64' or sys_platform != 'darwin'" }, + { name = "pyannote-database", marker = "platform_machine != 'x86_64' or sys_platform != 'darwin'" }, + { name = "scikit-learn", marker = "platform_machine != 'x86_64' or sys_platform != 'darwin'" }, + { name = "scipy", marker = "platform_machine != 'x86_64' or sys_platform != 'darwin'" }, + { name = "sympy", marker = "platform_machine != 'x86_64' or sys_platform != 'darwin'" }, + { name = "tabulate", marker = "platform_machine != 'x86_64' or sys_platform != 'darwin'" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/39/2b/6c5f01d3c49aa1c160765946e23782ca6436ae8b9bc514b56319ff5f16e7/pyannote.metrics-3.2.1.tar.gz", hash = "sha256:08024255a3550e96a8e9da4f5f4af326886548480de891414567c8900920ee5c", size = 49086, upload-time = "2022-06-20T14:10:34.618Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/6c/7d/035b370ab834b30e849fe9cd092b7bd7f321fcc4a2c56b84e96476b7ede5/pyannote.metrics-3.2.1-py3-none-any.whl", hash = "sha256:46be797cdade26c82773e5018659ae610145260069c7c5bf3d3c8a029ade8e22", size = 51386, upload-time = "2022-06-20T14:10:32.621Z" }, +] + +[[package]] +name = "pyarrow" +version = "22.0.0" +source = { registry = "https://pypi.org/simple/" } +sdist = { url = "https://files.pythonhosted.org/packages/30/53/04a7fdc63e6056116c9ddc8b43bc28c12cdd181b85cbeadb79278475f3ae/pyarrow-22.0.0.tar.gz", hash = "sha256:3d600dc583260d845c7d8a6db540339dd883081925da2bd1c5cb808f720b3cd9", size = 1151151, upload-time = "2025-10-24T12:30:00.762Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/af/63/ba23862d69652f85b615ca14ad14f3bcfc5bf1b99ef3f0cd04ff93fdad5a/pyarrow-22.0.0-cp312-cp312-macosx_12_0_arm64.whl", hash = "sha256:bea79263d55c24a32b0d79c00a1c58bb2ee5f0757ed95656b01c0fb310c5af3d", size = 34211578, upload-time = "2025-10-24T10:05:21.583Z" }, + { url = "https://files.pythonhosted.org/packages/b1/d0/f9ad86fe809efd2bcc8be32032fa72e8b0d112b01ae56a053006376c5930/pyarrow-22.0.0-cp312-cp312-macosx_12_0_x86_64.whl", hash = "sha256:12fe549c9b10ac98c91cf791d2945e878875d95508e1a5d14091a7aaa66d9cf8", size = 35989906, upload-time = "2025-10-24T10:05:29.485Z" }, + { url = "https://files.pythonhosted.org/packages/b4/a8/f910afcb14630e64d673f15904ec27dd31f1e009b77033c365c84e8c1e1d/pyarrow-22.0.0-cp312-cp312-manylinux_2_28_aarch64.whl", hash = "sha256:334f900ff08ce0423407af97e6c26ad5d4e3b0763645559ece6fbf3747d6a8f5", size = 45021677, upload-time = "2025-10-24T10:05:38.274Z" }, + { url = "https://files.pythonhosted.org/packages/13/95/aec81f781c75cd10554dc17a25849c720d54feafb6f7847690478dcf5ef8/pyarrow-22.0.0-cp312-cp312-manylinux_2_28_x86_64.whl", hash = "sha256:c6c791b09c57ed76a18b03f2631753a4960eefbbca80f846da8baefc6491fcfe", size = 47726315, upload-time = "2025-10-24T10:05:47.314Z" }, + { url = "https://files.pythonhosted.org/packages/bb/d4/74ac9f7a54cfde12ee42734ea25d5a3c9a45db78f9def949307a92720d37/pyarrow-22.0.0-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:c3200cb41cdbc65156e5f8c908d739b0dfed57e890329413da2748d1a2cd1a4e", size = 47990906, upload-time = "2025-10-24T10:05:58.254Z" }, + { url = "https://files.pythonhosted.org/packages/2e/71/fedf2499bf7a95062eafc989ace56572f3343432570e1c54e6599d5b88da/pyarrow-22.0.0-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:ac93252226cf288753d8b46280f4edf3433bf9508b6977f8dd8526b521a1bbb9", size = 50306783, upload-time = "2025-10-24T10:06:08.08Z" }, + { url = "https://files.pythonhosted.org/packages/68/ed/b202abd5a5b78f519722f3d29063dda03c114711093c1995a33b8e2e0f4b/pyarrow-22.0.0-cp312-cp312-win_amd64.whl", hash = "sha256:44729980b6c50a5f2bfcc2668d36c569ce17f8b17bccaf470c4313dcbbf13c9d", size = 27972883, upload-time = "2025-10-24T10:06:14.204Z" }, +] + +[[package]] +name = "pybind11" +version = "3.0.1" +source = { registry = "https://pypi.org/simple/" } +sdist = { url = "https://files.pythonhosted.org/packages/2f/7b/a6d8dcb83c457e24a9df1e4d8fd5fb8034d4bbc62f3c324681e8a9ba57c2/pybind11-3.0.1.tar.gz", hash = "sha256:9c0f40056a016da59bab516efb523089139fcc6f2ba7e4930854c61efb932051", size = 546914, upload-time = "2025-08-22T20:09:27.265Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/cd/8a/37362fc2b949d5f733a8b0f2ff51ba423914cabefe69f1d1b6aab710f5fe/pybind11-3.0.1-py3-none-any.whl", hash = "sha256:aa8f0aa6e0a94d3b64adfc38f560f33f15e589be2175e103c0a33c6bce55ee89", size = 293611, upload-time = "2025-08-22T20:09:25.235Z" }, +] + [[package]] name = "pycodestyle" version = "2.14.0" @@ -1678,6 +2968,15 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/2b/c6/db8d13a1f8ab3f1eb08c88bd00fd62d44311e3456d1e85c0e59e0a0376e7/pydantic_core-2.41.4-graalpy312-graalpy250_312_native-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:bd8a5028425820731d8c6c098ab642d7b8b999758e24acae03ed38a66eca8335", size = 2139008, upload-time = "2025-10-14T10:23:04.539Z" }, ] +[[package]] +name = "pydub" +version = "0.25.1" +source = { registry = "https://pypi.org/simple/" } +sdist = { url = "https://files.pythonhosted.org/packages/fe/9a/e6bca0eed82db26562c73b5076539a4a08d3cffd19c3cc5913a3e61145fd/pydub-0.25.1.tar.gz", hash = "sha256:980a33ce9949cab2a569606b65674d748ecbca4f0796887fd6f46173a7b0d30f", size = 38326, upload-time = "2021-03-10T02:09:54.659Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/a6/53/d78dc063216e62fc55f6b2eebb447f6a4b0a59f55c8406376f76bf959b08/pydub-0.25.1-py2.py3-none-any.whl", hash = "sha256:65617e33033874b59d87db603aa1ed450633288aefead953b30bded59cb599a6", size = 32327, upload-time = "2021-03-10T02:09:53.503Z" }, +] + [[package]] name = "pyflakes" version = "3.4.0" @@ -1687,6 +2986,15 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/c2/2f/81d580a0fb83baeb066698975cb14a618bdbed7720678566f1b046a95fe8/pyflakes-3.4.0-py2.py3-none-any.whl", hash = "sha256:f742a7dbd0d9cb9ea41e9a24a918996e8170c799fa528688d40dd582c8265f4f", size = 63551, upload-time = "2025-06-20T18:45:26.937Z" }, ] +[[package]] +name = "pygments" +version = "2.19.2" +source = { registry = "https://pypi.org/simple/" } +sdist = { url = "https://files.pythonhosted.org/packages/b0/77/a5b8c569bf593b0140bde72ea885a803b82086995367bf2037de0159d924/pygments-2.19.2.tar.gz", hash = "sha256:636cb2477cec7f8952536970bc533bc43743542f70392ae026374600add5b887", size = 4968631, upload-time = "2025-06-21T13:39:12.283Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/c7/21/705964c7812476f378728bdf590ca4b771ec72385c533964653c68e86bdc/pygments-2.19.2-py3-none-any.whl", hash = "sha256:86540386c03d588bb81d44bc3928634ff26449851e99741617ecb9037ee5ec0b", size = 1225217, upload-time = "2025-06-21T13:39:07.939Z" }, +] + [[package]] name = "pyinstaller" version = "6.16.0" @@ -1746,6 +3054,29 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/b4/49/cea450a83079445a84f16050e571a7c383d3f474b13c5caedfebd4e35def/pylint-2.17.7-py3-none-any.whl", hash = "sha256:27a8d4c7ddc8c2f8c18aa0050148f89ffc09838142193fdbe98f172781a3ff87", size = 537178, upload-time = "2023-09-30T21:25:07.527Z" }, ] +[[package]] +name = "pyloudnorm" +version = "0.1.1" +source = { registry = "https://pypi.org/simple/" } +dependencies = [ + { name = "future", marker = "platform_machine != 'x86_64' or sys_platform != 'darwin'" }, + { name = "numpy", marker = "platform_machine != 'x86_64' or sys_platform != 'darwin'" }, + { name = "scipy", marker = "platform_machine != 'x86_64' or sys_platform != 'darwin'" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/75/b5/39d59c44ecd828fabfdbd796b50a561e6543ca90ef440ab307374f107856/pyloudnorm-0.1.1.tar.gz", hash = "sha256:63cd4e197dea4e7795160ea08ed02d318091bce883e436a6dbc5963326b71e1e", size = 8588, upload-time = "2023-01-05T16:11:28.601Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/58/f5/6724805521ab4e723a12182f92374031032aff28a8a89dc8505c52b79032/pyloudnorm-0.1.1-py3-none-any.whl", hash = "sha256:d7f12ebdd097a464d87ce2878fc4d942f15f8233e26cc03f33fefa226f869a14", size = 9636, upload-time = "2023-01-05T16:11:27.331Z" }, +] + +[[package]] +name = "pyparsing" +version = "3.2.5" +source = { registry = "https://pypi.org/simple/" } +sdist = { url = "https://files.pythonhosted.org/packages/f2/a5/181488fc2b9d093e3972d2a472855aae8a03f000592dbfce716a512b3359/pyparsing-3.2.5.tar.gz", hash = "sha256:2df8d5b7b2802ef88e8d016a2eb9c7aeaa923529cd251ed0fe4608275d4105b6", size = 1099274, upload-time = "2025-09-21T04:11:06.277Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/10/5e/1aa9a93198c6b64513c9d7752de7422c06402de6600a8767da1524f9570b/pyparsing-3.2.5-py3-none-any.whl", hash = "sha256:e38a4f02064cf41fe6593d328d0512495ad1f3d8a91c4f73fc401b3079a59a5e", size = 113890, upload-time = "2025-09-21T04:11:04.117Z" }, +] + [[package]] name = "pyqt6" version = "6.9.1" @@ -1902,6 +3233,26 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/ec/57/56b9bcc3c9c6a792fcbaf139543cee77261f3651ca9da0c93f5c1221264b/python_dateutil-2.9.0.post0-py2.py3-none-any.whl", hash = "sha256:a8b2bc7bffae282281c8140a97d3aa9c14da0b136dfe83f850eea9a5f7470427", size = 229892, upload-time = "2024-03-01T18:36:18.57Z" }, ] +[[package]] +name = "pytorch-lightning" +version = "2.5.6" +source = { registry = "https://pypi.org/simple/" } +dependencies = [ + { name = "fsspec", extra = ["http"], marker = "platform_machine != 'x86_64' or sys_platform != 'darwin'" }, + { name = "lightning-utilities", marker = "platform_machine != 'x86_64' or sys_platform != 'darwin'" }, + { name = "packaging", marker = "platform_machine != 'x86_64' or sys_platform != 'darwin'" }, + { name = "pyyaml", marker = "platform_machine != 'x86_64' or sys_platform != 'darwin'" }, + { name = "torch", version = "2.7.1", source = { registry = "https://pypi.org/simple/" }, marker = "platform_machine != 'x86_64' and sys_platform == 'darwin'" }, + { name = "torch", version = "2.7.1+cu128", source = { registry = "https://download.pytorch.org/whl/cu128" }, marker = "sys_platform != 'darwin'" }, + { name = "torchmetrics", marker = "platform_machine != 'x86_64' or sys_platform != 'darwin'" }, + { name = "tqdm", marker = "platform_machine != 'x86_64' or sys_platform != 'darwin'" }, + { name = "typing-extensions", marker = "platform_machine != 'x86_64' or sys_platform != 'darwin'" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/0a/1f/94a441d30779e1ffa5f7dc2ac5fa374c142d8b96c347a49a30226264124e/pytorch_lightning-2.5.6.tar.gz", hash = "sha256:c428faaceef74be50b870814d0d7e9f9c6ee748b8769a2afd3366bc69daf3a0f", size = 642830, upload-time = "2025-11-05T20:53:04.871Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/17/e4/32ed2f33c1b634f7c2895369222f4f8cb345044f4642bbff718e7dd1e0b7/pytorch_lightning-2.5.6-py3-none-any.whl", hash = "sha256:037bad1e2fd94d5eb6c5144f045fd4c1070c3d38fc9c14d9f3774a3a9be54dff", size = 831555, upload-time = "2025-11-05T20:53:03.316Z" }, +] + [[package]] name = "pytz" version = "2025.2" @@ -1947,6 +3298,25 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/1a/08/67bd04656199bbb51dbed1439b7f27601dfb576fb864099c7ef0c3e55531/pyyaml-6.0.3-cp312-cp312-win_arm64.whl", hash = "sha256:64386e5e707d03a7e172c0701abfb7e10f0fb753ee1d773128192742712a98fd", size = 140344, upload-time = "2025-09-25T21:32:22.617Z" }, ] +[[package]] +name = "rapidfuzz" +version = "3.14.3" +source = { registry = "https://pypi.org/simple/" } +sdist = { url = "https://files.pythonhosted.org/packages/d3/28/9d808fe62375b9aab5ba92fa9b29371297b067c2790b2d7cda648b1e2f8d/rapidfuzz-3.14.3.tar.gz", hash = "sha256:2491937177868bc4b1e469087601d53f925e8d270ccc21e07404b4b5814b7b5f", size = 57863900, upload-time = "2025-11-01T11:54:52.321Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/fa/8e/3c215e860b458cfbedb3ed73bc72e98eb7e0ed72f6b48099604a7a3260c2/rapidfuzz-3.14.3-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:685c93ea961d135893b5984a5a9851637d23767feabe414ec974f43babbd8226", size = 1945306, upload-time = "2025-11-01T11:53:06.452Z" }, + { url = "https://files.pythonhosted.org/packages/36/d9/31b33512015c899f4a6e6af64df8dfe8acddf4c8b40a4b3e0e6e1bcd00e5/rapidfuzz-3.14.3-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:fa7c8f26f009f8c673fbfb443792f0cf8cf50c4e18121ff1e285b5e08a94fbdb", size = 1390788, upload-time = "2025-11-01T11:53:08.721Z" }, + { url = "https://files.pythonhosted.org/packages/a9/67/2ee6f8de6e2081ccd560a571d9c9063184fe467f484a17fa90311a7f4a2e/rapidfuzz-3.14.3-cp312-cp312-manylinux_2_26_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:57f878330c8d361b2ce76cebb8e3e1dc827293b6abf404e67d53260d27b5d941", size = 1374580, upload-time = "2025-11-01T11:53:10.164Z" }, + { url = "https://files.pythonhosted.org/packages/30/83/80d22997acd928eda7deadc19ccd15883904622396d6571e935993e0453a/rapidfuzz-3.14.3-cp312-cp312-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:6c5f545f454871e6af05753a0172849c82feaf0f521c5ca62ba09e1b382d6382", size = 3154947, upload-time = "2025-11-01T11:53:12.093Z" }, + { url = "https://files.pythonhosted.org/packages/5b/cf/9f49831085a16384695f9fb096b99662f589e30b89b4a589a1ebc1a19d34/rapidfuzz-3.14.3-cp312-cp312-manylinux_2_31_armv7l.whl", hash = "sha256:07aa0b5d8863e3151e05026a28e0d924accf0a7a3b605da978f0359bb804df43", size = 1223872, upload-time = "2025-11-01T11:53:13.664Z" }, + { url = "https://files.pythonhosted.org/packages/c8/0f/41ee8034e744b871c2e071ef0d360686f5ccfe5659f4fd96c3ec406b3c8b/rapidfuzz-3.14.3-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:73b07566bc7e010e7b5bd490fb04bb312e820970180df6b5655e9e6224c137db", size = 2392512, upload-time = "2025-11-01T11:53:15.109Z" }, + { url = "https://files.pythonhosted.org/packages/da/86/280038b6b0c2ccec54fb957c732ad6b41cc1fd03b288d76545b9cf98343f/rapidfuzz-3.14.3-cp312-cp312-musllinux_1_2_armv7l.whl", hash = "sha256:6de00eb84c71476af7d3110cf25d8fe7c792d7f5fa86764ef0b4ca97e78ca3ed", size = 2521398, upload-time = "2025-11-01T11:53:17.146Z" }, + { url = "https://files.pythonhosted.org/packages/fa/7b/05c26f939607dca0006505e3216248ae2de631e39ef94dd63dbbf0860021/rapidfuzz-3.14.3-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:d7843a1abf0091773a530636fdd2a49a41bcae22f9910b86b4f903e76ddc82dc", size = 4259416, upload-time = "2025-11-01T11:53:19.34Z" }, + { url = "https://files.pythonhosted.org/packages/40/eb/9e3af4103d91788f81111af1b54a28de347cdbed8eaa6c91d5e98a889aab/rapidfuzz-3.14.3-cp312-cp312-win32.whl", hash = "sha256:dea97ac3ca18cd3ba8f3d04b5c1fe4aa60e58e8d9b7793d3bd595fdb04128d7a", size = 1709527, upload-time = "2025-11-01T11:53:20.949Z" }, + { url = "https://files.pythonhosted.org/packages/b8/63/d06ecce90e2cf1747e29aeab9f823d21e5877a4c51b79720b2d3be7848f8/rapidfuzz-3.14.3-cp312-cp312-win_amd64.whl", hash = "sha256:b5100fd6bcee4d27f28f4e0a1c6b5127bc8ba7c2a9959cad9eab0bf4a7ab3329", size = 1538989, upload-time = "2025-11-01T11:53:22.428Z" }, + { url = "https://files.pythonhosted.org/packages/fc/6d/beee32dcda64af8128aab3ace2ccb33d797ed58c434c6419eea015fec779/rapidfuzz-3.14.3-cp312-cp312-win_arm64.whl", hash = "sha256:4e49c9e992bc5fc873bd0fff7ef16a4405130ec42f2ce3d2b735ba5d3d4eb70f", size = 811161, upload-time = "2025-11-01T11:53:23.811Z" }, +] + [[package]] name = "referencing" version = "0.37.0" @@ -1998,6 +3368,19 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/1e/db/4254e3eabe8020b458f1a747140d32277ec7a271daf1d235b70dc0b4e6e3/requests-2.32.5-py3-none-any.whl", hash = "sha256:2462f94637a34fd532264295e186976db0f5d453d1cdd31473c85a6a161affb6", size = 64738, upload-time = "2025-08-18T20:46:00.542Z" }, ] +[[package]] +name = "resampy" +version = "0.4.3" +source = { registry = "https://pypi.org/simple/" } +dependencies = [ + { name = "numba", marker = "platform_machine != 'x86_64' or sys_platform != 'darwin'" }, + { name = "numpy", marker = "platform_machine != 'x86_64' or sys_platform != 'darwin'" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/29/f1/34be702a69a5d272e844c98cee82351f880985cfbca0cc86378011078497/resampy-0.4.3.tar.gz", hash = "sha256:a0d1c28398f0e55994b739650afef4e3974115edbe96cd4bb81968425e916e47", size = 3080604, upload-time = "2024-03-05T20:36:08.119Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/4d/b9/3b00ac340a1aab3389ebcc52c779914a44aadf7b0cb7a3bf053195735607/resampy-0.4.3-py3-none-any.whl", hash = "sha256:ad2ed64516b140a122d96704e32bc0f92b23f45419e8b8f478e5a05f83edcebd", size = 3076529, upload-time = "2024-03-05T20:36:02.439Z" }, +] + [[package]] name = "retrying" version = "1.4.2" @@ -2007,6 +3390,19 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/67/f3/6cd296376653270ac1b423bb30bd70942d9916b6978c6f40472d6ac038e7/retrying-1.4.2-py3-none-any.whl", hash = "sha256:bbc004aeb542a74f3569aeddf42a2516efefcdaff90df0eb38fbfbf19f179f59", size = 10859, upload-time = "2025-08-03T03:35:23.829Z" }, ] +[[package]] +name = "rich" +version = "14.2.0" +source = { registry = "https://pypi.org/simple/" } +dependencies = [ + { name = "markdown-it-py", marker = "platform_machine != 'x86_64' or sys_platform != 'darwin'" }, + { name = "pygments", marker = "platform_machine != 'x86_64' or sys_platform != 'darwin'" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/fb/d2/8920e102050a0de7bfabeb4c4614a49248cf8d5d7a8d01885fbb24dc767a/rich-14.2.0.tar.gz", hash = "sha256:73ff50c7c0c1c77c8243079283f4edb376f0f6442433aecb8ce7e6d0b92d1fe4", size = 219990, upload-time = "2025-10-09T14:16:53.064Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/25/7a/b0178788f8dc6cafce37a212c99565fa1fe7872c70c6c9c1e1a372d9d88f/rich-14.2.0-py3-none-any.whl", hash = "sha256:76bc51fe2e57d2b1be1f96c524b890b816e334ab4c1e45888799bfaab0021edd", size = 243393, upload-time = "2025-10-09T14:16:51.245Z" }, +] + [[package]] name = "rpds-py" version = "0.28.0" @@ -2030,6 +3426,36 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/57/91/f3fb250d7e73de71080f9a221d19bd6a1c1eb0d12a1ea26513f6c1052ad6/rpds_py-0.28.0-cp312-cp312-win_arm64.whl", hash = "sha256:1f0cfd1c69e2d14f8c892b893997fa9a60d890a0c8a603e88dca4955f26d1edd", size = 217624, upload-time = "2025-10-22T22:22:26.914Z" }, ] +[[package]] +name = "ruamel-yaml" +version = "0.18.16" +source = { registry = "https://pypi.org/simple/" } +dependencies = [ + { name = "ruamel-yaml-clib", marker = "(platform_machine != 'x86_64' and platform_python_implementation == 'CPython') or (platform_python_implementation == 'CPython' and sys_platform != 'darwin')" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/9f/c7/ee630b29e04a672ecfc9b63227c87fd7a37eb67c1bf30fe95376437f897c/ruamel.yaml-0.18.16.tar.gz", hash = "sha256:a6e587512f3c998b2225d68aa1f35111c29fad14aed561a26e73fab729ec5e5a", size = 147269, upload-time = "2025-10-22T17:54:02.346Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/0f/73/bb1bc2529f852e7bf64a2dec885e89ff9f5cc7bbf6c9340eed30ff2c69c5/ruamel.yaml-0.18.16-py3-none-any.whl", hash = "sha256:048f26d64245bae57a4f9ef6feb5b552a386830ef7a826f235ffb804c59efbba", size = 119858, upload-time = "2025-10-22T17:53:59.012Z" }, +] + +[[package]] +name = "ruamel-yaml-clib" +version = "0.2.15" +source = { registry = "https://pypi.org/simple/" } +sdist = { url = "https://files.pythonhosted.org/packages/ea/97/60fda20e2fb54b83a61ae14648b0817c8f5d84a3821e40bfbdae1437026a/ruamel_yaml_clib-0.2.15.tar.gz", hash = "sha256:46e4cc8c43ef6a94885f72512094e482114a8a706d3c555a34ed4b0d20200600", size = 225794, upload-time = "2025-11-16T16:12:59.761Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/72/4b/5fde11a0722d676e469d3d6f78c6a17591b9c7e0072ca359801c4bd17eee/ruamel_yaml_clib-0.2.15-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:cb15a2e2a90c8475df45c0949793af1ff413acfb0a716b8b94e488ea95ce7cff", size = 149088, upload-time = "2025-11-16T16:13:22.836Z" }, + { url = "https://files.pythonhosted.org/packages/85/82/4d08ac65ecf0ef3b046421985e66301a242804eb9a62c93ca3437dc94ee0/ruamel_yaml_clib-0.2.15-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:64da03cbe93c1e91af133f5bec37fd24d0d4ba2418eaf970d7166b0a26a148a2", size = 134553, upload-time = "2025-11-16T16:13:24.151Z" }, + { url = "https://files.pythonhosted.org/packages/b9/cb/22366d68b280e281a932403b76da7a988108287adff2bfa5ce881200107a/ruamel_yaml_clib-0.2.15-cp312-cp312-manylinux1_i686.manylinux_2_28_i686.manylinux_2_5_i686.whl", hash = "sha256:f6d3655e95a80325b84c4e14c080b2470fe4f33b6846f288379ce36154993fb1", size = 737468, upload-time = "2025-11-16T20:22:47.335Z" }, + { url = "https://files.pythonhosted.org/packages/71/73/81230babf8c9e33770d43ed9056f603f6f5f9665aea4177a2c30ae48e3f3/ruamel_yaml_clib-0.2.15-cp312-cp312-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:71845d377c7a47afc6592aacfea738cc8a7e876d586dfba814501d8c53c1ba60", size = 753349, upload-time = "2025-11-16T16:13:26.269Z" }, + { url = "https://files.pythonhosted.org/packages/61/62/150c841f24cda9e30f588ef396ed83f64cfdc13b92d2f925bb96df337ba9/ruamel_yaml_clib-0.2.15-cp312-cp312-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:11e5499db1ccbc7f4b41f0565e4f799d863ea720e01d3e99fa0b7b5fcd7802c9", size = 788211, upload-time = "2025-11-16T16:13:27.441Z" }, + { url = "https://files.pythonhosted.org/packages/30/93/e79bd9cbecc3267499d9ead919bd61f7ddf55d793fb5ef2b1d7d92444f35/ruamel_yaml_clib-0.2.15-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:4b293a37dc97e2b1e8a1aec62792d1e52027087c8eea4fc7b5abd2bdafdd6642", size = 743203, upload-time = "2025-11-16T16:13:28.671Z" }, + { url = "https://files.pythonhosted.org/packages/8d/06/1eb640065c3a27ce92d76157f8efddb184bd484ed2639b712396a20d6dce/ruamel_yaml_clib-0.2.15-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:512571ad41bba04eac7268fe33f7f4742210ca26a81fe0c75357fa682636c690", size = 747292, upload-time = "2025-11-16T20:22:48.584Z" }, + { url = "https://files.pythonhosted.org/packages/a5/21/ee353e882350beab65fcc47a91b6bdc512cace4358ee327af2962892ff16/ruamel_yaml_clib-0.2.15-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:e5e9f630c73a490b758bf14d859a39f375e6999aea5ddd2e2e9da89b9953486a", size = 771624, upload-time = "2025-11-16T16:13:29.853Z" }, + { url = "https://files.pythonhosted.org/packages/57/34/cc1b94057aa867c963ecf9ea92ac59198ec2ee3a8d22a126af0b4d4be712/ruamel_yaml_clib-0.2.15-cp312-cp312-win32.whl", hash = "sha256:f4421ab780c37210a07d138e56dd4b51f8642187cdfb433eb687fe8c11de0144", size = 100342, upload-time = "2025-11-16T16:13:31.067Z" }, + { url = "https://files.pythonhosted.org/packages/b3/e5/8925a4208f131b218f9a7e459c0d6fcac8324ae35da269cb437894576366/ruamel_yaml_clib-0.2.15-cp312-cp312-win_amd64.whl", hash = "sha256:2b216904750889133d9222b7b873c199d48ecbb12912aca78970f84a5aa1a4bc", size = 119013, upload-time = "2025-11-16T16:13:32.164Z" }, +] + [[package]] name = "ruff" version = "0.1.15" @@ -2054,6 +3480,21 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/c9/bd/c196493563d6bf8fe960f10b83926a3fae3a43a96eac6b263aecb96c61d7/ruff-0.1.15-py3-none-win_arm64.whl", hash = "sha256:9a933dfb1c14ec7a33cceb1e49ec4a16b51ce3c20fd42663198746efc0427360", size = 6998592, upload-time = "2024-01-29T23:06:01.904Z" }, ] +[[package]] +name = "sacremoses" +version = "0.1.1" +source = { registry = "https://pypi.org/simple/" } +dependencies = [ + { name = "click", marker = "platform_machine != 'x86_64' or sys_platform != 'darwin'" }, + { name = "joblib", marker = "platform_machine != 'x86_64' or sys_platform != 'darwin'" }, + { name = "regex", marker = "platform_machine != 'x86_64' or sys_platform != 'darwin'" }, + { name = "tqdm", marker = "platform_machine != 'x86_64' or sys_platform != 'darwin'" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/1d/51/fbdc4af4f6e85d26169e28be3763fe50ddfd0d4bf8b871422b0788dcc4d2/sacremoses-0.1.1.tar.gz", hash = "sha256:b6fd5d3a766b02154ed80b962ddca91e1fd25629c0978c7efba21ebccf663934", size = 883188, upload-time = "2023-10-30T15:56:20.187Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/0b/f0/89ee2bc9da434bd78464f288fdb346bc2932f2ee80a90b2a4bbbac262c74/sacremoses-0.1.1-py3-none-any.whl", hash = "sha256:31e04c98b169bfd902144824d191825cd69220cdb4ae4bcf1ec58a7db5587b1a", size = 897476, upload-time = "2023-10-30T15:56:18.121Z" }, +] + [[package]] name = "safetensors" version = "0.6.2" @@ -2076,6 +3517,25 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/2c/c3/c0be1135726618dc1e28d181b8c442403d8dbb9e273fd791de2d4384bcdd/safetensors-0.6.2-cp38-abi3-win_amd64.whl", hash = "sha256:c7b214870df923cbc1593c3faee16bec59ea462758699bd3fee399d00aac072c", size = 320192, upload-time = "2025-08-08T13:13:59.467Z" }, ] +[[package]] +name = "scikit-learn" +version = "1.7.2" +source = { registry = "https://pypi.org/simple/" } +dependencies = [ + { name = "joblib", marker = "platform_machine != 'x86_64' or sys_platform != 'darwin'" }, + { name = "numpy", marker = "platform_machine != 'x86_64' or sys_platform != 'darwin'" }, + { name = "scipy", marker = "platform_machine != 'x86_64' or sys_platform != 'darwin'" }, + { name = "threadpoolctl", marker = "platform_machine != 'x86_64' or sys_platform != 'darwin'" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/98/c2/a7855e41c9d285dfe86dc50b250978105dce513d6e459ea66a6aeb0e1e0c/scikit_learn-1.7.2.tar.gz", hash = "sha256:20e9e49ecd130598f1ca38a1d85090e1a600147b9c02fa6f15d69cb53d968fda", size = 7193136, upload-time = "2025-09-09T08:21:29.075Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/a7/aa/3996e2196075689afb9fce0410ebdb4a09099d7964d061d7213700204409/scikit_learn-1.7.2-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:8d91a97fa2b706943822398ab943cde71858a50245e31bc71dba62aab1d60a96", size = 9259818, upload-time = "2025-09-09T08:20:43.19Z" }, + { url = "https://files.pythonhosted.org/packages/43/5d/779320063e88af9c4a7c2cf463ff11c21ac9c8bd730c4a294b0000b666c9/scikit_learn-1.7.2-cp312-cp312-macosx_12_0_arm64.whl", hash = "sha256:acbc0f5fd2edd3432a22c69bed78e837c70cf896cd7993d71d51ba6708507476", size = 8636997, upload-time = "2025-09-09T08:20:45.468Z" }, + { url = "https://files.pythonhosted.org/packages/5c/d0/0c577d9325b05594fdd33aa970bf53fb673f051a45496842caee13cfd7fe/scikit_learn-1.7.2-cp312-cp312-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:e5bf3d930aee75a65478df91ac1225ff89cd28e9ac7bd1196853a9229b6adb0b", size = 9478381, upload-time = "2025-09-09T08:20:47.982Z" }, + { url = "https://files.pythonhosted.org/packages/82/70/8bf44b933837ba8494ca0fc9a9ab60f1c13b062ad0197f60a56e2fc4c43e/scikit_learn-1.7.2-cp312-cp312-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:b4d6e9deed1a47aca9fe2f267ab8e8fe82ee20b4526b2c0cd9e135cea10feb44", size = 9300296, upload-time = "2025-09-09T08:20:50.366Z" }, + { url = "https://files.pythonhosted.org/packages/c6/99/ed35197a158f1fdc2fe7c3680e9c70d0128f662e1fee4ed495f4b5e13db0/scikit_learn-1.7.2-cp312-cp312-win_amd64.whl", hash = "sha256:6088aa475f0785e01bcf8529f55280a3d7d298679f50c0bb70a2364a82d0b290", size = 8731256, upload-time = "2025-09-09T08:20:52.627Z" }, +] + [[package]] name = "scipy" version = "1.16.2" @@ -2102,14 +3562,43 @@ name = "secretstorage" version = "3.4.0" source = { registry = "https://pypi.org/simple/" } dependencies = [ - { name = "cryptography", marker = "sys_platform != 'darwin'" }, - { name = "jeepney", marker = "sys_platform != 'darwin'" }, + { name = "cryptography", marker = "sys_platform == 'linux'" }, + { name = "jeepney", marker = "sys_platform == 'linux'" }, ] sdist = { url = "https://files.pythonhosted.org/packages/31/9f/11ef35cf1027c1339552ea7bfe6aaa74a8516d8b5caf6e7d338daf54fd80/secretstorage-3.4.0.tar.gz", hash = "sha256:c46e216d6815aff8a8a18706a2fbfd8d53fcbb0dce99301881687a1b0289ef7c", size = 19748, upload-time = "2025-09-09T16:42:13.859Z" } wheels = [ { url = "https://files.pythonhosted.org/packages/91/ff/2e2eed29e02c14a5cb6c57f09b2d5b40e65d6cc71f45b52e0be295ccbc2f/secretstorage-3.4.0-py3-none-any.whl", hash = "sha256:0e3b6265c2c63509fb7415717607e4b2c9ab767b7f344a57473b779ca13bd02e", size = 15272, upload-time = "2025-09-09T16:42:12.744Z" }, ] +[[package]] +name = "sentencepiece" +version = "0.2.1" +source = { registry = "https://pypi.org/simple/" } +sdist = { url = "https://files.pythonhosted.org/packages/15/15/2e7a025fc62d764b151ae6d0f2a92f8081755ebe8d4a64099accc6f77ba6/sentencepiece-0.2.1.tar.gz", hash = "sha256:8138cec27c2f2282f4a34d9a016e3374cd40e5c6e9cb335063db66a0a3b71fad", size = 3228515, upload-time = "2025-08-12T07:00:51.718Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/4a/be/32ce495aa1d0e0c323dcb1ba87096037358edee539cac5baf8755a6bd396/sentencepiece-0.2.1-cp312-cp312-macosx_10_13_universal2.whl", hash = "sha256:57cae326c8727de58c85977b175af132a7138d84c764635d7e71bbee7e774133", size = 1943152, upload-time = "2025-08-12T06:59:40.048Z" }, + { url = "https://files.pythonhosted.org/packages/88/7e/ff23008899a58678e98c6ff592bf4d368eee5a71af96d0df6b38a039dd4f/sentencepiece-0.2.1-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:56dd39a3c4d6493db3cdca7e8cc68c6b633f0d4195495cbadfcf5af8a22d05a6", size = 1325651, upload-time = "2025-08-12T06:59:41.536Z" }, + { url = "https://files.pythonhosted.org/packages/19/84/42eb3ce4796777a1b5d3699dfd4dca85113e68b637f194a6c8d786f16a04/sentencepiece-0.2.1-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:d9381351182ff9888cc80e41c632e7e274b106f450de33d67a9e8f6043da6f76", size = 1253645, upload-time = "2025-08-12T06:59:42.903Z" }, + { url = "https://files.pythonhosted.org/packages/89/fa/d3d5ebcba3cb9e6d3775a096251860c41a6bc53a1b9461151df83fe93255/sentencepiece-0.2.1-cp312-cp312-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:99f955df238021bf11f0fc37cdb54fd5e5b5f7fd30ecc3d93fb48b6815437167", size = 1316273, upload-time = "2025-08-12T06:59:44.476Z" }, + { url = "https://files.pythonhosted.org/packages/04/88/14f2f4a2b922d8b39be45bf63d79e6cd3a9b2f248b2fcb98a69b12af12f5/sentencepiece-0.2.1-cp312-cp312-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:0cdfecef430d985f1c2bcbfff3defd1d95dae876fbd0173376012d2d7d24044b", size = 1387881, upload-time = "2025-08-12T06:59:46.09Z" }, + { url = "https://files.pythonhosted.org/packages/fd/b8/903e5ccb77b4ef140605d5d71b4f9e0ad95d456d6184688073ed11712809/sentencepiece-0.2.1-cp312-cp312-win32.whl", hash = "sha256:a483fd29a34c3e34c39ac5556b0a90942bec253d260235729e50976f5dba1068", size = 999540, upload-time = "2025-08-12T06:59:48.023Z" }, + { url = "https://files.pythonhosted.org/packages/2d/81/92df5673c067148c2545b1bfe49adfd775bcc3a169a047f5a0e6575ddaca/sentencepiece-0.2.1-cp312-cp312-win_amd64.whl", hash = "sha256:4cdc7c36234fda305e85c32949c5211faaf8dd886096c7cea289ddc12a2d02de", size = 1054671, upload-time = "2025-08-12T06:59:49.895Z" }, + { url = "https://files.pythonhosted.org/packages/fe/02/c5e3bc518655d714622bec87d83db9cdba1cd0619a4a04e2109751c4f47f/sentencepiece-0.2.1-cp312-cp312-win_arm64.whl", hash = "sha256:daeb5e9e9fcad012324807856113708614d534f596d5008638eb9b40112cd9e4", size = 1033923, upload-time = "2025-08-12T06:59:51.952Z" }, +] + +[[package]] +name = "sentry-sdk" +version = "2.45.0" +source = { registry = "https://pypi.org/simple/" } +dependencies = [ + { name = "certifi", marker = "platform_machine != 'x86_64' or sys_platform != 'darwin'" }, + { name = "urllib3", marker = "platform_machine != 'x86_64' or sys_platform != 'darwin'" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/61/89/1561b3dc8e28bf7978d031893297e89be266f53650c87bb14a29406a9791/sentry_sdk-2.45.0.tar.gz", hash = "sha256:e9bbfe69d5f6742f48bad22452beffb525bbc5b797d817c7f1b1f7d210cdd271", size = 373631, upload-time = "2025-11-18T13:23:22.475Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/94/c6/039121a0355bc1b5bcceef0dabf211b021fd435d0ee5c46393717bb1c09f/sentry_sdk-2.45.0-py2.py3-none-any.whl", hash = "sha256:86c8ab05dc3e8666aece77a5c747b45b25aa1d5f35f06cde250608f495d50f23", size = 404791, upload-time = "2025-11-18T13:23:20.533Z" }, +] + [[package]] name = "setuptools" version = "80.9.0" @@ -2119,6 +3608,15 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/a3/dc/17031897dae0efacfea57dfd3a82fdd2a2aeb58e0ff71b77b87e44edc772/setuptools-80.9.0-py3-none-any.whl", hash = "sha256:062d34222ad13e0cc312a4c02d73f059e86a4acbfbdea8f8f76b28c99f306922", size = 1201486, upload-time = "2025-05-27T00:56:49.664Z" }, ] +[[package]] +name = "shellingham" +version = "1.5.4" +source = { registry = "https://pypi.org/simple/" } +sdist = { url = "https://files.pythonhosted.org/packages/58/15/8b3609fd3830ef7b27b655beb4b4e9c62313a4e8da8c676e142cc210d58e/shellingham-1.5.4.tar.gz", hash = "sha256:8dbca0739d487e5bd35ab3ca4b36e11c4078f3a234bfce294b0a0291363404de", size = 10310, upload-time = "2023-10-24T04:13:40.426Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/e0/f9/0595336914c5619e5f28a1fb793285925a8cd4b432c9da0a987836c7f822/shellingham-1.5.4-py2.py3-none-any.whl", hash = "sha256:7ecfff8f2fd72616f7481040475a65b2bf8af90a56c89140852d1120324e8686", size = 9755, upload-time = "2023-10-24T04:13:38.866Z" }, +] + [[package]] name = "simplejson" version = "3.20.2" @@ -2150,6 +3648,15 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/b7/ce/149a00dd41f10bc29e5921b496af8b574d8413afcd5e30dfa0ed46c2cc5e/six-1.17.0-py2.py3-none-any.whl", hash = "sha256:4721f391ed90541fddacab5acf947aa0d3dc7d27b2e1e8eda2be8970586c3274", size = 11050, upload-time = "2024-12-04T17:35:26.475Z" }, ] +[[package]] +name = "smmap" +version = "5.0.2" +source = { registry = "https://pypi.org/simple/" } +sdist = { url = "https://files.pythonhosted.org/packages/44/cd/a040c4b3119bbe532e5b0732286f805445375489fceaec1f48306068ee3b/smmap-5.0.2.tar.gz", hash = "sha256:26ea65a03958fa0c8a1c7e8c7a58fdc77221b8910f6be2131affade476898ad5", size = 22329, upload-time = "2025-01-02T07:14:40.909Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/04/be/d09147ad1ec7934636ad912901c5fd7667e1c858e19d355237db0d0cd5e4/smmap-5.0.2-py3-none-any.whl", hash = "sha256:b30115f0def7d7531d22a0fb6502488d879e75b260a9db4d0819cfb25403af5e", size = 24303, upload-time = "2025-01-02T07:14:38.724Z" }, +] + [[package]] name = "sniffio" version = "1.3.1" @@ -2159,6 +3666,15 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/e9/44/75a9c9421471a6c4805dbf2356f7c181a29c1879239abab1ea2cc8f38b40/sniffio-1.3.1-py3-none-any.whl", hash = "sha256:2f6da418d1f1e0fddd844478f41680e794e6051915791a034ff65e5f100525a2", size = 10235, upload-time = "2024-02-25T23:20:01.196Z" }, ] +[[package]] +name = "sortedcontainers" +version = "2.4.0" +source = { registry = "https://pypi.org/simple/" } +sdist = { url = "https://files.pythonhosted.org/packages/e8/c4/ba2f8066cceb6f23394729afe52f3bf7adec04bf9ed2c820b39e19299111/sortedcontainers-2.4.0.tar.gz", hash = "sha256:25caa5a06cc30b6b83d11423433f65d1f9d76c4c6a0c90e3379eaa43b9bfdb88", size = 30594, upload-time = "2021-05-16T22:03:42.897Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/32/46/9cb0e58b2deb7f82b84065f37f3bffeb12413f947f9388e4cac22c4621ce/sortedcontainers-2.4.0-py2.py3-none-any.whl", hash = "sha256:a163dcaede0f1c021485e957a39245190e74249897e2ae4b2aa38595db237ee0", size = 29575, upload-time = "2021-05-16T22:03:41.177Z" }, +] + [[package]] name = "sounddevice" version = "0.4.7" @@ -2193,6 +3709,53 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/14/e9/6b761de83277f2f02ded7e7ea6f07828ec78e4b229b80e4ca55dd205b9dc/soundfile-0.13.1-py2.py3-none-win_amd64.whl", hash = "sha256:1e70a05a0626524a69e9f0f4dd2ec174b4e9567f4d8b6c11d38b5c289be36ee9", size = 1019162, upload-time = "2025-01-25T09:16:59.573Z" }, ] +[[package]] +name = "sox" +version = "1.5.0" +source = { registry = "https://pypi.org/simple/" } +dependencies = [ + { name = "numpy", marker = "platform_machine != 'x86_64' or sys_platform != 'darwin'" }, + { name = "typing-extensions", marker = "platform_machine != 'x86_64' or sys_platform != 'darwin'" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/3d/a2/d8e0d8fd7abf509ead4a2cb0fb24e5758b5330166bf9223d5cb9f98a7e8d/sox-1.5.0.tar.gz", hash = "sha256:12c7be5bb1f548d891fe11e82c08cf5f1a1d74e225298f60082e5aeb2469ada0", size = 63905, upload-time = "2024-03-20T16:59:37.385Z" } + +[[package]] +name = "soxr" +version = "1.0.0" +source = { registry = "https://pypi.org/simple/" } +dependencies = [ + { name = "numpy", marker = "platform_machine != 'x86_64' or sys_platform != 'darwin'" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/42/7e/f4b461944662ad75036df65277d6130f9411002bfb79e9df7dff40a31db9/soxr-1.0.0.tar.gz", hash = "sha256:e07ee6c1d659bc6957034f4800c60cb8b98de798823e34d2a2bba1caa85a4509", size = 171415, upload-time = "2025-09-07T13:22:21.317Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/c5/c7/f92b81f1a151c13afb114f57799b86da9330bec844ea5a0d3fe6a8732678/soxr-1.0.0-cp312-abi3-macosx_10_14_x86_64.whl", hash = "sha256:abecf4e39017f3fadb5e051637c272ae5778d838e5c3926a35db36a53e3a607f", size = 205508, upload-time = "2025-09-07T13:22:01.252Z" }, + { url = "https://files.pythonhosted.org/packages/ff/1d/c945fea9d83ea1f2be9d116b3674dbaef26ed090374a77c394b31e3b083b/soxr-1.0.0-cp312-abi3-macosx_11_0_arm64.whl", hash = "sha256:e973d487ee46aa8023ca00a139db6e09af053a37a032fe22f9ff0cc2e19c94b4", size = 163568, upload-time = "2025-09-07T13:22:03.558Z" }, + { url = "https://files.pythonhosted.org/packages/b5/80/10640970998a1d2199bef6c4d92205f36968cddaf3e4d0e9fe35ddd405bd/soxr-1.0.0-cp312-abi3-manylinux_2_26_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:e8ce273cca101aff3d8c387db5a5a41001ba76ef1837883438d3c652507a9ccc", size = 204707, upload-time = "2025-09-07T13:22:05.125Z" }, + { url = "https://files.pythonhosted.org/packages/b1/87/2726603c13c2126cb8ded9e57381b7377f4f0df6ba4408e1af5ddbfdc3dd/soxr-1.0.0-cp312-abi3-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:e8f2a69686f2856d37823bbb7b78c3d44904f311fe70ba49b893af11d6b6047b", size = 238032, upload-time = "2025-09-07T13:22:06.428Z" }, + { url = "https://files.pythonhosted.org/packages/ce/04/530252227f4d0721a5524a936336485dfb429bb206a66baf8e470384f4a2/soxr-1.0.0-cp312-abi3-win_amd64.whl", hash = "sha256:2a3b77b115ae7c478eecdbd060ed4f61beda542dfb70639177ac263aceda42a2", size = 172070, upload-time = "2025-09-07T13:22:07.62Z" }, +] + +[[package]] +name = "sqlalchemy" +version = "2.0.44" +source = { registry = "https://pypi.org/simple/" } +dependencies = [ + { name = "greenlet", marker = "platform_machine == 'AMD64' or platform_machine == 'WIN32' or platform_machine == 'aarch64' or platform_machine == 'amd64' or platform_machine == 'ppc64le' or platform_machine == 'win32' or (platform_machine == 'x86_64' and sys_platform != 'darwin')" }, + { name = "typing-extensions", marker = "platform_machine != 'x86_64' or sys_platform != 'darwin'" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/f0/f2/840d7b9496825333f532d2e3976b8eadbf52034178aac53630d09fe6e1ef/sqlalchemy-2.0.44.tar.gz", hash = "sha256:0ae7454e1ab1d780aee69fd2aae7d6b8670a581d8847f2d1e0f7ddfbf47e5a22", size = 9819830, upload-time = "2025-10-10T14:39:12.935Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/62/c4/59c7c9b068e6813c898b771204aad36683c96318ed12d4233e1b18762164/sqlalchemy-2.0.44-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:72fea91746b5890f9e5e0997f16cbf3d53550580d76355ba2d998311b17b2250", size = 2139675, upload-time = "2025-10-10T16:03:31.064Z" }, + { url = "https://files.pythonhosted.org/packages/d6/ae/eeb0920537a6f9c5a3708e4a5fc55af25900216bdb4847ec29cfddf3bf3a/sqlalchemy-2.0.44-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:585c0c852a891450edbb1eaca8648408a3cc125f18cf433941fa6babcc359e29", size = 2127726, upload-time = "2025-10-10T16:03:35.934Z" }, + { url = "https://files.pythonhosted.org/packages/d8/d5/2ebbabe0379418eda8041c06b0b551f213576bfe4c2f09d77c06c07c8cc5/sqlalchemy-2.0.44-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:9b94843a102efa9ac68a7a30cd46df3ff1ed9c658100d30a725d10d9c60a2f44", size = 3327603, upload-time = "2025-10-10T15:35:28.322Z" }, + { url = "https://files.pythonhosted.org/packages/45/e5/5aa65852dadc24b7d8ae75b7efb8d19303ed6ac93482e60c44a585930ea5/sqlalchemy-2.0.44-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:119dc41e7a7defcefc57189cfa0e61b1bf9c228211aba432b53fb71ef367fda1", size = 3337842, upload-time = "2025-10-10T15:43:45.431Z" }, + { url = "https://files.pythonhosted.org/packages/41/92/648f1afd3f20b71e880ca797a960f638d39d243e233a7082c93093c22378/sqlalchemy-2.0.44-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:0765e318ee9179b3718c4fd7ba35c434f4dd20332fbc6857a5e8df17719c24d7", size = 3264558, upload-time = "2025-10-10T15:35:29.93Z" }, + { url = "https://files.pythonhosted.org/packages/40/cf/e27d7ee61a10f74b17740918e23cbc5bc62011b48282170dc4c66da8ec0f/sqlalchemy-2.0.44-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:2e7b5b079055e02d06a4308d0481658e4f06bc7ef211567edc8f7d5dce52018d", size = 3301570, upload-time = "2025-10-10T15:43:48.407Z" }, + { url = "https://files.pythonhosted.org/packages/3b/3d/3116a9a7b63e780fb402799b6da227435be878b6846b192f076d2f838654/sqlalchemy-2.0.44-cp312-cp312-win32.whl", hash = "sha256:846541e58b9a81cce7dee8329f352c318de25aa2f2bbe1e31587eb1f057448b4", size = 2103447, upload-time = "2025-10-10T15:03:21.678Z" }, + { url = "https://files.pythonhosted.org/packages/25/83/24690e9dfc241e6ab062df82cc0df7f4231c79ba98b273fa496fb3dd78ed/sqlalchemy-2.0.44-cp312-cp312-win_amd64.whl", hash = "sha256:7cbcb47fd66ab294703e1644f78971f6f2f1126424d2b300678f419aa73c7b6e", size = 2130912, upload-time = "2025-10-10T15:03:24.656Z" }, + { url = "https://files.pythonhosted.org/packages/9c/5e/6a29fa884d9fb7ddadf6b69490a9d45fded3b38541713010dad16b77d015/sqlalchemy-2.0.44-py3-none-any.whl", hash = "sha256:19de7ca1246fbef9f9d1bff8f1ab25641569df226364a0e40457dc5457c54b05", size = 1928718, upload-time = "2025-10-10T15:29:45.32Z" }, +] + [[package]] name = "srt" version = "3.5.3" @@ -2229,6 +3792,20 @@ dependencies = [ ] sdist = { url = "https://files.pythonhosted.org/packages/94/d9/d326f9dbbb7da6806aa8cfc080342e5f78dc33552f4339bdc8a6251d11a3/stable_ts-2.19.1.tar.gz", hash = "sha256:0ecaf1ed93e029839569618d2da9a57b883ad04db21f0680146e0650caaf4f52", size = 189132, upload-time = "2025-08-16T16:53:48.811Z" } +[[package]] +name = "stack-data" +version = "0.6.3" +source = { registry = "https://pypi.org/simple/" } +dependencies = [ + { name = "asttokens", marker = "platform_machine != 'x86_64' or sys_platform != 'darwin'" }, + { name = "executing", marker = "platform_machine != 'x86_64' or sys_platform != 'darwin'" }, + { name = "pure-eval", marker = "platform_machine != 'x86_64' or sys_platform != 'darwin'" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/28/e3/55dcc2cfbc3ca9c29519eb6884dd1415ecb53b0e934862d3559ddcb7e20b/stack_data-0.6.3.tar.gz", hash = "sha256:836a778de4fec4dcd1dcd89ed8abff8a221f58308462e1c4aa2a3cf30148f0b9", size = 44707, upload-time = "2023-09-30T13:58:05.479Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/f1/7b/ce1eafaf1a76852e2ec9b22edecf1daa58175c090266e9f6c64afcd81d91/stack_data-0.6.3-py3-none-any.whl", hash = "sha256:d5558e0c25a4cb0853cddad3d77da9891a08cb85dd9f9f91b9f8cd66e511e695", size = 24521, upload-time = "2023-09-30T13:58:03.53Z" }, +] + [[package]] name = "stempeg" version = "0.2.4" @@ -2242,6 +3819,15 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/af/07/ce07799f7cc0af533d58b5380957638cc049d66a6a18736094b78cd08d1a/stempeg-0.2.4-py3-none-any.whl", hash = "sha256:83c9e4ac73edcc61a2a807eded0ae2c9f0b99ea3110e46756b3fff153a063838", size = 963032, upload-time = "2025-05-28T08:42:11.181Z" }, ] +[[package]] +name = "strenum" +version = "0.4.15" +source = { registry = "https://pypi.org/simple/" } +sdist = { url = "https://files.pythonhosted.org/packages/85/ad/430fb60d90e1d112a62ff57bdd1f286ec73a2a0331272febfddd21f330e1/StrEnum-0.4.15.tar.gz", hash = "sha256:878fb5ab705442070e4dd1929bb5e2249511c0bcf2b0eeacf3bcd80875c82eff", size = 23384, upload-time = "2023-06-29T22:02:58.399Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/81/69/297302c5f5f59c862faa31e6cb9a4cd74721cd1e052b38e464c5b402df8b/StrEnum-0.4.15-py3-none-any.whl", hash = "sha256:a30cda4af7cc6b5bf52c8055bc4bf4b2b6b14a93b574626da33df53cf7740659", size = 8851, upload-time = "2023-06-29T22:02:56.947Z" }, +] + [[package]] name = "submitit" version = "1.5.3" @@ -2266,6 +3852,87 @@ wheels = [ { url = "https://download.pytorch.org/whl/sympy-1.14.0-py3-none-any.whl" }, ] +[[package]] +name = "tabulate" +version = "0.9.0" +source = { registry = "https://pypi.org/simple/" } +sdist = { url = "https://files.pythonhosted.org/packages/ec/fe/802052aecb21e3797b8f7902564ab6ea0d60ff8ca23952079064155d1ae1/tabulate-0.9.0.tar.gz", hash = "sha256:0095b12bf5966de529c0feb1fa08671671b3368eec77d7ef7ab114be2c068b3c", size = 81090, upload-time = "2022-10-06T17:21:48.54Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/40/44/4a5f08c96eb108af5cb50b41f76142f0afa346dfa99d5296fe7202a11854/tabulate-0.9.0-py3-none-any.whl", hash = "sha256:024ca478df22e9340661486f85298cff5f6dcdba14f3813e8830015b9ed1948f", size = 35252, upload-time = "2022-10-06T17:21:44.262Z" }, +] + +[[package]] +name = "tensorboard" +version = "2.20.0" +source = { registry = "https://pypi.org/simple/" } +dependencies = [ + { name = "absl-py", marker = "platform_machine != 'x86_64' or sys_platform != 'darwin'" }, + { name = "grpcio", marker = "platform_machine != 'x86_64' or sys_platform != 'darwin'" }, + { name = "markdown", marker = "platform_machine != 'x86_64' or sys_platform != 'darwin'" }, + { name = "numpy", marker = "platform_machine != 'x86_64' or sys_platform != 'darwin'" }, + { name = "packaging", marker = "platform_machine != 'x86_64' or sys_platform != 'darwin'" }, + { name = "pillow", marker = "platform_machine != 'x86_64' or sys_platform != 'darwin'" }, + { name = "protobuf", marker = "platform_machine != 'x86_64' or sys_platform != 'darwin'" }, + { name = "setuptools", marker = "platform_machine != 'x86_64' or sys_platform != 'darwin'" }, + { name = "tensorboard-data-server", marker = "platform_machine != 'x86_64' or sys_platform != 'darwin'" }, + { name = "werkzeug", marker = "platform_machine != 'x86_64' or sys_platform != 'darwin'" }, +] +wheels = [ + { url = "https://files.pythonhosted.org/packages/9c/d9/a5db55f88f258ac669a92858b70a714bbbd5acd993820b41ec4a96a4d77f/tensorboard-2.20.0-py3-none-any.whl", hash = "sha256:9dc9f978cb84c0723acf9a345d96c184f0293d18f166bb8d59ee098e6cfaaba6", size = 5525680, upload-time = "2025-07-17T19:20:49.638Z" }, +] + +[[package]] +name = "tensorboard-data-server" +version = "0.7.2" +source = { registry = "https://pypi.org/simple/" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/7a/13/e503968fefabd4c6b2650af21e110aa8466fe21432cd7c43a84577a89438/tensorboard_data_server-0.7.2-py3-none-any.whl", hash = "sha256:7e0610d205889588983836ec05dc098e80f97b7e7bbff7e994ebb78f578d0ddb", size = 2356, upload-time = "2023-10-23T21:23:32.16Z" }, + { url = "https://files.pythonhosted.org/packages/b7/85/dabeaf902892922777492e1d253bb7e1264cadce3cea932f7ff599e53fea/tensorboard_data_server-0.7.2-py3-none-macosx_10_9_x86_64.whl", hash = "sha256:9fe5d24221b29625dbc7328b0436ca7fc1c23de4acf4d272f1180856e32f9f60", size = 4823598, upload-time = "2023-10-23T21:23:33.714Z" }, + { url = "https://files.pythonhosted.org/packages/73/c6/825dab04195756cf8ff2e12698f22513b3db2f64925bdd41671bfb33aaa5/tensorboard_data_server-0.7.2-py3-none-manylinux_2_31_x86_64.whl", hash = "sha256:ef687163c24185ae9754ed5650eb5bc4d84ff257aabdc33f0cc6f74d8ba54530", size = 6590363, upload-time = "2023-10-23T21:23:35.583Z" }, +] + +[[package]] +name = "termcolor" +version = "3.2.0" +source = { registry = "https://pypi.org/simple/" } +sdist = { url = "https://files.pythonhosted.org/packages/87/56/ab275c2b56a5e2342568838f0d5e3e66a32354adcc159b495e374cda43f5/termcolor-3.2.0.tar.gz", hash = "sha256:610e6456feec42c4bcd28934a8c87a06c3fa28b01561d46aa09a9881b8622c58", size = 14423, upload-time = "2025-10-25T19:11:42.586Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/f9/d5/141f53d7c1eb2a80e6d3e9a390228c3222c27705cbe7f048d3623053f3ca/termcolor-3.2.0-py3-none-any.whl", hash = "sha256:a10343879eba4da819353c55cb8049b0933890c2ebf9ad5d3ecd2bb32ea96ea6", size = 7698, upload-time = "2025-10-25T19:11:41.536Z" }, +] + +[[package]] +name = "text-unidecode" +version = "1.3" +source = { registry = "https://pypi.org/simple/" } +sdist = { url = "https://files.pythonhosted.org/packages/ab/e2/e9a00f0ccb71718418230718b3d900e71a5d16e701a3dae079a21e9cd8f8/text-unidecode-1.3.tar.gz", hash = "sha256:bad6603bb14d279193107714b288be206cac565dfa49aa5b105294dd5c4aab93", size = 76885, upload-time = "2019-08-30T21:36:45.405Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/a6/a5/c0b6468d3824fe3fde30dbb5e1f687b291608f9473681bbf7dabbf5a87d7/text_unidecode-1.3-py2.py3-none-any.whl", hash = "sha256:1311f10e8b895935241623731c2ba64f4c455287888b18189350b67134a822e8", size = 78154, upload-time = "2019-08-30T21:37:03.543Z" }, +] + +[[package]] +name = "texterrors" +version = "0.5.1" +source = { registry = "https://pypi.org/simple/" } +dependencies = [ + { name = "levenshtein", marker = "platform_machine != 'x86_64' or sys_platform != 'darwin'" }, + { name = "loguru", marker = "platform_machine != 'x86_64' or sys_platform != 'darwin'" }, + { name = "numpy", marker = "platform_machine != 'x86_64' or sys_platform != 'darwin'" }, + { name = "plac", marker = "platform_machine != 'x86_64' or sys_platform != 'darwin'" }, + { name = "pybind11", marker = "platform_machine != 'x86_64' or sys_platform != 'darwin'" }, + { name = "regex", marker = "platform_machine != 'x86_64' or sys_platform != 'darwin'" }, + { name = "termcolor", marker = "platform_machine != 'x86_64' or sys_platform != 'darwin'" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/9b/47/9a391643961698df3c804172f005e8b56c9693c14c4170abd9d3c961e971/texterrors-0.5.1.tar.gz", hash = "sha256:7fa24b2ca6ed5e05681b5cfdbb6c1fd0e4ae6518f8939e9782294f620d4eb3b1", size = 23813, upload-time = "2024-06-19T15:43:06.889Z" } + +[[package]] +name = "threadpoolctl" +version = "3.6.0" +source = { registry = "https://pypi.org/simple/" } +sdist = { url = "https://files.pythonhosted.org/packages/b7/4d/08c89e34946fce2aec4fbb45c9016efd5f4d7f24af8e5d93296e935631d8/threadpoolctl-3.6.0.tar.gz", hash = "sha256:8ab8b4aa3491d812b623328249fab5302a68d2d71745c8a4c719a2fcaba9f44e", size = 21274, upload-time = "2025-03-13T13:49:23.031Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/32/d5/f9a850d79b0851d1d4ef6456097579a9005b31fea68726a4ae5f2d82ddd9/threadpoolctl-3.6.0-py3-none-any.whl", hash = "sha256:43a0b8fd5a2928500110039e43a5eed8480b918967083ea48dc3ab9f13c4a7fb", size = 18638, upload-time = "2025-03-13T13:49:21.846Z" }, +] + [[package]] name = "tiktoken" version = "0.12.0" @@ -2287,27 +3954,27 @@ wheels = [ [[package]] name = "tokenizers" -version = "0.22.1" +version = "0.21.4" source = { registry = "https://pypi.org/simple/" } dependencies = [ { name = "huggingface-hub" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/1c/46/fb6854cec3278fbfa4a75b50232c77622bc517ac886156e6afbfa4d8fc6e/tokenizers-0.22.1.tar.gz", hash = "sha256:61de6522785310a309b3407bac22d99c4db5dba349935e99e4d15ea2226af2d9", size = 363123, upload-time = "2025-09-19T09:49:23.424Z" } +sdist = { url = "https://files.pythonhosted.org/packages/c2/2f/402986d0823f8d7ca139d969af2917fefaa9b947d1fb32f6168c509f2492/tokenizers-0.21.4.tar.gz", hash = "sha256:fa23f85fbc9a02ec5c6978da172cdcbac23498c3ca9f3645c5c68740ac007880", size = 351253, upload-time = "2025-07-28T15:48:54.325Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/bf/33/f4b2d94ada7ab297328fc671fed209368ddb82f965ec2224eb1892674c3a/tokenizers-0.22.1-cp39-abi3-macosx_10_12_x86_64.whl", hash = "sha256:59fdb013df17455e5f950b4b834a7b3ee2e0271e6378ccb33aa74d178b513c73", size = 3069318, upload-time = "2025-09-19T09:49:11.848Z" }, - { url = "https://files.pythonhosted.org/packages/1c/58/2aa8c874d02b974990e89ff95826a4852a8b2a273c7d1b4411cdd45a4565/tokenizers-0.22.1-cp39-abi3-macosx_11_0_arm64.whl", hash = "sha256:8d4e484f7b0827021ac5f9f71d4794aaef62b979ab7608593da22b1d2e3c4edc", size = 2926478, upload-time = "2025-09-19T09:49:09.759Z" }, - { url = "https://files.pythonhosted.org/packages/1e/3b/55e64befa1e7bfea963cf4b787b2cea1011362c4193f5477047532ce127e/tokenizers-0.22.1-cp39-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:19d2962dd28bc67c1f205ab180578a78eef89ac60ca7ef7cbe9635a46a56422a", size = 3256994, upload-time = "2025-09-19T09:48:56.701Z" }, - { url = "https://files.pythonhosted.org/packages/71/0b/fbfecf42f67d9b7b80fde4aabb2b3110a97fac6585c9470b5bff103a80cb/tokenizers-0.22.1-cp39-abi3-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:38201f15cdb1f8a6843e6563e6e79f4abd053394992b9bbdf5213ea3469b4ae7", size = 3153141, upload-time = "2025-09-19T09:48:59.749Z" }, - { url = "https://files.pythonhosted.org/packages/17/a9/b38f4e74e0817af8f8ef925507c63c6ae8171e3c4cb2d5d4624bf58fca69/tokenizers-0.22.1-cp39-abi3-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:d1cbe5454c9a15df1b3443c726063d930c16f047a3cc724b9e6e1a91140e5a21", size = 3508049, upload-time = "2025-09-19T09:49:05.868Z" }, - { url = "https://files.pythonhosted.org/packages/d2/48/dd2b3dac46bb9134a88e35d72e1aa4869579eacc1a27238f1577270773ff/tokenizers-0.22.1-cp39-abi3-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:e7d094ae6312d69cc2a872b54b91b309f4f6fbce871ef28eb27b52a98e4d0214", size = 3710730, upload-time = "2025-09-19T09:49:01.832Z" }, - { url = "https://files.pythonhosted.org/packages/93/0e/ccabc8d16ae4ba84a55d41345207c1e2ea88784651a5a487547d80851398/tokenizers-0.22.1-cp39-abi3-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:afd7594a56656ace95cdd6df4cca2e4059d294c5cfb1679c57824b605556cb2f", size = 3412560, upload-time = "2025-09-19T09:49:03.867Z" }, - { url = "https://files.pythonhosted.org/packages/d0/c6/dc3a0db5a6766416c32c034286d7c2d406da1f498e4de04ab1b8959edd00/tokenizers-0.22.1-cp39-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:e2ef6063d7a84994129732b47e7915e8710f27f99f3a3260b8a38fc7ccd083f4", size = 3250221, upload-time = "2025-09-19T09:49:07.664Z" }, - { url = "https://files.pythonhosted.org/packages/d7/a6/2c8486eef79671601ff57b093889a345dd3d576713ef047776015dc66de7/tokenizers-0.22.1-cp39-abi3-musllinux_1_2_aarch64.whl", hash = "sha256:ba0a64f450b9ef412c98f6bcd2a50c6df6e2443b560024a09fa6a03189726879", size = 9345569, upload-time = "2025-09-19T09:49:14.214Z" }, - { url = "https://files.pythonhosted.org/packages/6b/16/32ce667f14c35537f5f605fe9bea3e415ea1b0a646389d2295ec348d5657/tokenizers-0.22.1-cp39-abi3-musllinux_1_2_armv7l.whl", hash = "sha256:331d6d149fa9c7d632cde4490fb8bbb12337fa3a0232e77892be656464f4b446", size = 9271599, upload-time = "2025-09-19T09:49:16.639Z" }, - { url = "https://files.pythonhosted.org/packages/51/7c/a5f7898a3f6baa3fc2685c705e04c98c1094c523051c805cdd9306b8f87e/tokenizers-0.22.1-cp39-abi3-musllinux_1_2_i686.whl", hash = "sha256:607989f2ea68a46cb1dfbaf3e3aabdf3f21d8748312dbeb6263d1b3b66c5010a", size = 9533862, upload-time = "2025-09-19T09:49:19.146Z" }, - { url = "https://files.pythonhosted.org/packages/36/65/7e75caea90bc73c1dd8d40438adf1a7bc26af3b8d0a6705ea190462506e1/tokenizers-0.22.1-cp39-abi3-musllinux_1_2_x86_64.whl", hash = "sha256:a0f307d490295717726598ef6fa4f24af9d484809223bbc253b201c740a06390", size = 9681250, upload-time = "2025-09-19T09:49:21.501Z" }, - { url = "https://files.pythonhosted.org/packages/30/2c/959dddef581b46e6209da82df3b78471e96260e2bc463f89d23b1bf0e52a/tokenizers-0.22.1-cp39-abi3-win32.whl", hash = "sha256:b5120eed1442765cd90b903bb6cfef781fd8fe64e34ccaecbae4c619b7b12a82", size = 2472003, upload-time = "2025-09-19T09:49:27.089Z" }, - { url = "https://files.pythonhosted.org/packages/b3/46/e33a8c93907b631a99377ef4c5f817ab453d0b34f93529421f42ff559671/tokenizers-0.22.1-cp39-abi3-win_amd64.whl", hash = "sha256:65fd6e3fb11ca1e78a6a93602490f134d1fdeb13bcef99389d5102ea318ed138", size = 2674684, upload-time = "2025-09-19T09:49:24.953Z" }, + { url = "https://files.pythonhosted.org/packages/98/c6/fdb6f72bf6454f52eb4a2510be7fb0f614e541a2554d6210e370d85efff4/tokenizers-0.21.4-cp39-abi3-macosx_10_12_x86_64.whl", hash = "sha256:2ccc10a7c3bcefe0f242867dc914fc1226ee44321eb618cfe3019b5df3400133", size = 2863987, upload-time = "2025-07-28T15:48:44.877Z" }, + { url = "https://files.pythonhosted.org/packages/8d/a6/28975479e35ddc751dc1ddc97b9b69bf7fcf074db31548aab37f8116674c/tokenizers-0.21.4-cp39-abi3-macosx_11_0_arm64.whl", hash = "sha256:5e2f601a8e0cd5be5cc7506b20a79112370b9b3e9cb5f13f68ab11acd6ca7d60", size = 2732457, upload-time = "2025-07-28T15:48:43.265Z" }, + { url = "https://files.pythonhosted.org/packages/aa/8f/24f39d7b5c726b7b0be95dca04f344df278a3fe3a4deb15a975d194cbb32/tokenizers-0.21.4-cp39-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:39b376f5a1aee67b4d29032ee85511bbd1b99007ec735f7f35c8a2eb104eade5", size = 3012624, upload-time = "2025-07-28T13:22:43.895Z" }, + { url = "https://files.pythonhosted.org/packages/58/47/26358925717687a58cb74d7a508de96649544fad5778f0cd9827398dc499/tokenizers-0.21.4-cp39-abi3-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:2107ad649e2cda4488d41dfd031469e9da3fcbfd6183e74e4958fa729ffbf9c6", size = 2939681, upload-time = "2025-07-28T13:22:47.499Z" }, + { url = "https://files.pythonhosted.org/packages/99/6f/cc300fea5db2ab5ddc2c8aea5757a27b89c84469899710c3aeddc1d39801/tokenizers-0.21.4-cp39-abi3-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:3c73012da95afafdf235ba80047699df4384fdc481527448a078ffd00e45a7d9", size = 3247445, upload-time = "2025-07-28T15:48:39.711Z" }, + { url = "https://files.pythonhosted.org/packages/be/bf/98cb4b9c3c4afd8be89cfa6423704337dc20b73eb4180397a6e0d456c334/tokenizers-0.21.4-cp39-abi3-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:f23186c40395fc390d27f519679a58023f368a0aad234af145e0f39ad1212732", size = 3428014, upload-time = "2025-07-28T13:22:49.569Z" }, + { url = "https://files.pythonhosted.org/packages/75/c7/96c1cc780e6ca7f01a57c13235dd05b7bc1c0f3588512ebe9d1331b5f5ae/tokenizers-0.21.4-cp39-abi3-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:cc88bb34e23a54cc42713d6d98af5f1bf79c07653d24fe984d2d695ba2c922a2", size = 3193197, upload-time = "2025-07-28T13:22:51.471Z" }, + { url = "https://files.pythonhosted.org/packages/f2/90/273b6c7ec78af547694eddeea9e05de771278bd20476525ab930cecaf7d8/tokenizers-0.21.4-cp39-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:51b7eabb104f46c1c50b486520555715457ae833d5aee9ff6ae853d1130506ff", size = 3115426, upload-time = "2025-07-28T15:48:41.439Z" }, + { url = "https://files.pythonhosted.org/packages/91/43/c640d5a07e95f1cf9d2c92501f20a25f179ac53a4f71e1489a3dcfcc67ee/tokenizers-0.21.4-cp39-abi3-musllinux_1_2_aarch64.whl", hash = "sha256:714b05b2e1af1288bd1bc56ce496c4cebb64a20d158ee802887757791191e6e2", size = 9089127, upload-time = "2025-07-28T15:48:46.472Z" }, + { url = "https://files.pythonhosted.org/packages/44/a1/dd23edd6271d4dca788e5200a807b49ec3e6987815cd9d0a07ad9c96c7c2/tokenizers-0.21.4-cp39-abi3-musllinux_1_2_armv7l.whl", hash = "sha256:1340ff877ceedfa937544b7d79f5b7becf33a4cfb58f89b3b49927004ef66f78", size = 9055243, upload-time = "2025-07-28T15:48:48.539Z" }, + { url = "https://files.pythonhosted.org/packages/21/2b/b410d6e9021c4b7ddb57248304dc817c4d4970b73b6ee343674914701197/tokenizers-0.21.4-cp39-abi3-musllinux_1_2_i686.whl", hash = "sha256:3c1f4317576e465ac9ef0d165b247825a2a4078bcd01cba6b54b867bdf9fdd8b", size = 9298237, upload-time = "2025-07-28T15:48:50.443Z" }, + { url = "https://files.pythonhosted.org/packages/b7/0a/42348c995c67e2e6e5c89ffb9cfd68507cbaeb84ff39c49ee6e0a6dd0fd2/tokenizers-0.21.4-cp39-abi3-musllinux_1_2_x86_64.whl", hash = "sha256:c212aa4e45ec0bb5274b16b6f31dd3f1c41944025c2358faaa5782c754e84c24", size = 9461980, upload-time = "2025-07-28T15:48:52.325Z" }, + { url = "https://files.pythonhosted.org/packages/3d/d3/dacccd834404cd71b5c334882f3ba40331ad2120e69ded32cf5fda9a7436/tokenizers-0.21.4-cp39-abi3-win32.whl", hash = "sha256:6c42a930bc5f4c47f4ea775c91de47d27910881902b0f20e4990ebe045a415d0", size = 2329871, upload-time = "2025-07-28T15:48:56.841Z" }, + { url = "https://files.pythonhosted.org/packages/41/f2/fd673d979185f5dcbac4be7d09461cbb99751554ffb6718d0013af8604cb/tokenizers-0.21.4-cp39-abi3-win_amd64.whl", hash = "sha256:475d807a5c3eb72c59ad9b5fcdb254f6e17f53dfcbb9903233b0dfa9c943b597", size = 2507568, upload-time = "2025-07-28T15:48:55.456Z" }, ] [[package]] @@ -2328,6 +3995,15 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/bd/75/8539d011f6be8e29f339c42e633aae3cb73bffa95dd0f9adec09b9c58e85/tomlkit-0.13.3-py3-none-any.whl", hash = "sha256:c89c649d79ee40629a9fda55f8ace8c6a1b42deb912b2a8fd8d942ddadb606b0", size = 38901, upload-time = "2025-06-05T07:13:43.546Z" }, ] +[[package]] +name = "toolz" +version = "1.1.0" +source = { registry = "https://pypi.org/simple/" } +sdist = { url = "https://files.pythonhosted.org/packages/11/d6/114b492226588d6ff54579d95847662fc69196bdeec318eb45393b24c192/toolz-1.1.0.tar.gz", hash = "sha256:27a5c770d068c110d9ed9323f24f1543e83b2f300a687b7891c1a6d56b697b5b", size = 52613, upload-time = "2025-10-17T04:03:21.661Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/fb/12/5911ae3eeec47800503a238d971e51722ccea5feb8569b735184d5fcdbc0/toolz-1.1.0-py3-none-any.whl", hash = "sha256:15ccc861ac51c53696de0a5d6d4607f99c210739caf987b5d2054f3efed429d8", size = 58093, upload-time = "2025-10-17T04:03:20.435Z" }, +] + [[package]] name = "torch" version = "2.2.2" @@ -2373,7 +4049,8 @@ name = "torch" version = "2.7.1+cu128" source = { registry = "https://download.pytorch.org/whl/cu128" } resolution-markers = [ - "(platform_machine != 'aarch64' and sys_platform == 'linux') or (platform_python_implementation != 'CPython' and sys_platform == 'linux') or (sys_platform != 'darwin' and sys_platform != 'linux')", + "(platform_machine != 'aarch64' and sys_platform == 'linux') or (platform_python_implementation != 'CPython' and sys_platform == 'linux')", + "sys_platform != 'darwin' and sys_platform != 'linux'", "platform_machine == 'aarch64' and platform_python_implementation == 'CPython' and sys_platform == 'linux'", ] dependencies = [ @@ -2454,7 +4131,8 @@ version = "2.7.1+cu128" source = { registry = "https://download.pytorch.org/whl/cu128" } resolution-markers = [ "platform_machine != 'arm64' and platform_machine != 'x86_64' and sys_platform == 'darwin'", - "(platform_machine != 'aarch64' and sys_platform == 'linux') or (platform_python_implementation != 'CPython' and sys_platform == 'linux') or (sys_platform != 'darwin' and sys_platform != 'linux')", + "(platform_machine != 'aarch64' and sys_platform == 'linux') or (platform_python_implementation != 'CPython' and sys_platform == 'linux')", + "sys_platform != 'darwin' and sys_platform != 'linux'", ] dependencies = [ { name = "torch", version = "2.7.1", source = { registry = "https://pypi.org/simple/" }, marker = "platform_machine != 'arm64' and platform_machine != 'x86_64' and sys_platform == 'darwin'" }, @@ -2465,6 +4143,22 @@ wheels = [ { url = "https://download.pytorch.org/whl/cu128/torchaudio-2.7.1%2Bcu128-cp312-cp312-win_amd64.whl", hash = "sha256:4586e3106701b06a4f9377f5c1da9e1d8555e16bd58fd7d810aa3f6cf50bd713" }, ] +[[package]] +name = "torchmetrics" +version = "1.8.2" +source = { registry = "https://pypi.org/simple/" } +dependencies = [ + { name = "lightning-utilities", marker = "platform_machine != 'x86_64' or sys_platform != 'darwin'" }, + { name = "numpy", marker = "platform_machine != 'x86_64' or sys_platform != 'darwin'" }, + { name = "packaging", marker = "platform_machine != 'x86_64' or sys_platform != 'darwin'" }, + { name = "torch", version = "2.7.1", source = { registry = "https://pypi.org/simple/" }, marker = "platform_machine != 'x86_64' and sys_platform == 'darwin'" }, + { name = "torch", version = "2.7.1+cu128", source = { registry = "https://download.pytorch.org/whl/cu128" }, marker = "sys_platform != 'darwin'" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/85/2e/48a887a59ecc4a10ce9e8b35b3e3c5cef29d902c4eac143378526e7485cb/torchmetrics-1.8.2.tar.gz", hash = "sha256:cf64a901036bf107f17a524009eea7781c9c5315d130713aeca5747a686fe7a5", size = 580679, upload-time = "2025-09-03T14:00:54.077Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/02/21/aa0f434434c48490f91b65962b1ce863fdcce63febc166ca9fe9d706c2b6/torchmetrics-1.8.2-py3-none-any.whl", hash = "sha256:08382fd96b923e39e904c4d570f3d49e2cc71ccabd2a94e0f895d1f0dac86242", size = 983161, upload-time = "2025-09-03T14:00:51.921Z" }, +] + [[package]] name = "tqdm" version = "4.67.1" @@ -2477,9 +4171,18 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/d0/30/dc54f88dd4a2b5dc8a0279bdd7270e735851848b762aeb1c1184ed1f6b14/tqdm-4.67.1-py3-none-any.whl", hash = "sha256:26445eca388f82e72884e0d580d5464cd801a3ea01e63e5601bdff9ba6a48de2", size = 78540, upload-time = "2024-11-24T20:12:19.698Z" }, ] +[[package]] +name = "traitlets" +version = "5.14.3" +source = { registry = "https://pypi.org/simple/" } +sdist = { url = "https://files.pythonhosted.org/packages/eb/79/72064e6a701c2183016abbbfedaba506d81e30e232a68c9f0d6f6fcd1574/traitlets-5.14.3.tar.gz", hash = "sha256:9ed0579d3502c94b4b3732ac120375cda96f923114522847de4b3bb98b96b6b7", size = 161621, upload-time = "2024-04-19T11:11:49.746Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/00/c0/8f5d070730d7836adc9c9b6408dec68c6ced86b304a9b26a14df072a6e8c/traitlets-5.14.3-py3-none-any.whl", hash = "sha256:b74e89e397b1ed28cc831db7aea759ba6640cb3de13090ca145426688ff1ac4f", size = 85359, upload-time = "2024-04-19T11:11:46.763Z" }, +] + [[package]] name = "transformers" -version = "4.57.1" +version = "4.53.3" source = { registry = "https://pypi.org/simple/" } dependencies = [ { name = "filelock" }, @@ -2493,9 +4196,9 @@ dependencies = [ { name = "tokenizers" }, { name = "tqdm" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/d6/68/a39307bcc4116a30b2106f2e689130a48de8bd8a1e635b5e1030e46fcd9e/transformers-4.57.1.tar.gz", hash = "sha256:f06c837959196c75039809636cd964b959f6604b75b8eeec6fdfc0440b89cc55", size = 10142511, upload-time = "2025-10-14T15:39:26.18Z" } +sdist = { url = "https://files.pythonhosted.org/packages/f1/5c/49182918b58eaa0b4c954fd0e37c79fc299e5643e69d70089d0b0eb0cd9b/transformers-4.53.3.tar.gz", hash = "sha256:b2eda1a261de79b78b97f7888fe2005fc0c3fabf5dad33d52cc02983f9f675d8", size = 9197478, upload-time = "2025-07-22T07:30:51.51Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/71/d3/c16c3b3cf7655a67db1144da94b021c200ac1303f82428f2beef6c2e72bb/transformers-4.57.1-py3-none-any.whl", hash = "sha256:b10d05da8fa67dc41644dbbf9bc45a44cb86ae33da6f9295f5fbf5b7890bd267", size = 11990925, upload-time = "2025-10-14T15:39:23.085Z" }, + { url = "https://files.pythonhosted.org/packages/41/b1/d7520cc5cb69c825599042eb3a7c986fa9baa8a8d2dea9acd78e152c81e2/transformers-4.53.3-py3-none-any.whl", hash = "sha256:5aba81c92095806b6baf12df35d756cf23b66c356975fb2a7fa9e536138d7c75", size = 10826382, upload-time = "2025-07-22T07:30:48.458Z" }, ] [[package]] @@ -2528,6 +4231,33 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/e1/85/a4ff8758c66f1fc32aa5e9a145908394bf9cf1c79ffd1113cfdeb77e74e4/trove_classifiers-2025.9.11.17-py3-none-any.whl", hash = "sha256:5d392f2d244deb1866556457d6f3516792124a23d1c3a463a2e8668a5d1c15dd", size = 14158, upload-time = "2025-09-11T17:07:49.886Z" }, ] +[[package]] +name = "typeguard" +version = "4.4.4" +source = { registry = "https://pypi.org/simple/" } +dependencies = [ + { name = "typing-extensions", marker = "platform_machine != 'x86_64' or sys_platform != 'darwin'" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/c7/68/71c1a15b5f65f40e91b65da23b8224dad41349894535a97f63a52e462196/typeguard-4.4.4.tar.gz", hash = "sha256:3a7fd2dffb705d4d0efaed4306a704c89b9dee850b688f060a8b1615a79e5f74", size = 75203, upload-time = "2025-06-18T09:56:07.624Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/1b/a9/e3aee762739c1d7528da1c3e06d518503f8b6c439c35549b53735ba52ead/typeguard-4.4.4-py3-none-any.whl", hash = "sha256:b5f562281b6bfa1f5492470464730ef001646128b180769880468bd84b68b09e", size = 34874, upload-time = "2025-06-18T09:56:05.999Z" }, +] + +[[package]] +name = "typer" +version = "0.20.0" +source = { registry = "https://pypi.org/simple/" } +dependencies = [ + { name = "click", marker = "platform_machine != 'x86_64' or sys_platform != 'darwin'" }, + { name = "rich", marker = "platform_machine != 'x86_64' or sys_platform != 'darwin'" }, + { name = "shellingham", marker = "platform_machine != 'x86_64' or sys_platform != 'darwin'" }, + { name = "typing-extensions", marker = "platform_machine != 'x86_64' or sys_platform != 'darwin'" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/8f/28/7c85c8032b91dbe79725b6f17d2fffc595dff06a35c7a30a37bef73a1ab4/typer-0.20.0.tar.gz", hash = "sha256:1aaf6494031793e4876fb0bacfa6a912b551cf43c1e63c800df8b1a866720c37", size = 106492, upload-time = "2025-10-20T17:03:49.445Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/78/64/7713ffe4b5983314e9d436a90d5bd4f63b6054e2aca783a3cfc44cb95bbf/typer-0.20.0-py3-none-any.whl", hash = "sha256:5b463df6793ec1dca6213a3cf4c0f03bc6e322ac5e16e13ddd622a889489784a", size = 47028, upload-time = "2025-10-20T17:03:47.617Z" }, +] + [[package]] name = "typing-extensions" version = "4.15.0" @@ -2578,6 +4308,18 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/a7/c2/fe1e52489ae3122415c51f387e221dd0773709bad6c6cdaa599e8a2c5185/urllib3-2.5.0-py3-none-any.whl", hash = "sha256:e6b01673c0fa6a13e374b50871808eb3bf7046c4b125b216f6bf1cc604cff0dc", size = 129795, upload-time = "2025-06-18T14:07:40.39Z" }, ] +[[package]] +name = "uroman" +version = "1.3.1.1" +source = { registry = "https://pypi.org/simple/" } +dependencies = [ + { name = "regex" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/73/03/7d23f79d9b259861c31437ed76007eb8dc6f6c419b709f5b2ef37d4fa7da/uroman-1.3.1.1.tar.gz", hash = "sha256:6aaf2d5265f24f15201cbbf92c86720b2b804ac53294ce43a3307fcd242387d5", size = 896697, upload-time = "2024-06-28T06:03:34.868Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/78/e1/43722c41eebab0592c6f83410e5e35edc1d6e333f44feb0a543bd38dba3e/uroman-1.3.1.1-py3-none-any.whl", hash = "sha256:394f965f7011fd56a84aca098a6c3b50082f365324f5d94c992852137918c8f5", size = 930684, upload-time = "2024-06-28T06:03:32.578Z" }, +] + [[package]] name = "virtualenv" version = "20.35.3" @@ -2604,6 +4346,99 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/f7/e5/7b28a123d33fc9c3d55383628fc38322c890a97dfa2c538a7638cd71d57f/vulkan-1.3.275.1-py3-none-any.whl", hash = "sha256:e1e0ddf57d3a7d19f79ebf1e192b20dbd378172b027cad4f495d961b51409586", size = 399747, upload-time = "2024-02-27T10:12:32.705Z" }, ] +[[package]] +name = "wandb" +version = "0.23.0" +source = { registry = "https://pypi.org/simple/" } +dependencies = [ + { name = "click", marker = "platform_machine != 'x86_64' or sys_platform != 'darwin'" }, + { name = "gitpython", marker = "platform_machine != 'x86_64' or sys_platform != 'darwin'" }, + { name = "packaging", marker = "platform_machine != 'x86_64' or sys_platform != 'darwin'" }, + { name = "platformdirs", marker = "platform_machine != 'x86_64' or sys_platform != 'darwin'" }, + { name = "protobuf", marker = "platform_machine != 'x86_64' or sys_platform != 'darwin'" }, + { name = "pydantic", marker = "platform_machine != 'x86_64' or sys_platform != 'darwin'" }, + { name = "pyyaml", marker = "platform_machine != 'x86_64' or sys_platform != 'darwin'" }, + { name = "requests", marker = "platform_machine != 'x86_64' or sys_platform != 'darwin'" }, + { name = "sentry-sdk", marker = "platform_machine != 'x86_64' or sys_platform != 'darwin'" }, + { name = "typing-extensions", marker = "platform_machine != 'x86_64' or sys_platform != 'darwin'" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/ef/8b/db2d44395c967cd452517311fd6ede5d1e07310769f448358d4874248512/wandb-0.23.0.tar.gz", hash = "sha256:e5f98c61a8acc3ee84583ca78057f64344162ce026b9f71cb06eea44aec27c93", size = 44413921, upload-time = "2025-11-11T21:06:30.737Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/41/61/a3220c7fa4cadfb2b2a5c09e3fa401787326584ade86d7c1f58bf1cd43bd/wandb-0.23.0-py3-none-macosx_12_0_arm64.whl", hash = "sha256:b682ec5e38fc97bd2e868ac7615a0ab4fc6a15220ee1159e87270a5ebb7a816d", size = 18992250, upload-time = "2025-11-11T21:06:03.412Z" }, + { url = "https://files.pythonhosted.org/packages/90/16/e69333cf3d11e7847f424afc6c8ae325e1f6061b2e5118d7a17f41b6525d/wandb-0.23.0-py3-none-macosx_12_0_x86_64.whl", hash = "sha256:ec094eb71b778e77db8c188da19e52c4f96cb9d5b4421d7dc05028afc66fd7e7", size = 20045616, upload-time = "2025-11-11T21:06:07.109Z" }, + { url = "https://files.pythonhosted.org/packages/62/79/42dc6c7bb0b425775fe77f1a3f1a22d75d392841a06b43e150a3a7f2553a/wandb-0.23.0-py3-none-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:4e43f1f04b98c34f407dcd2744cec0a590abce39bed14a61358287f817514a7b", size = 18758848, upload-time = "2025-11-11T21:06:09.832Z" }, + { url = "https://files.pythonhosted.org/packages/b8/94/d6ddb78334996ccfc1179444bfcfc0f37ffd07ee79bb98940466da6f68f8/wandb-0.23.0-py3-none-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:6e5847f98cbb3175caf5291932374410141f5bb3b7c25f9c5e562c1988ce0bf5", size = 20231493, upload-time = "2025-11-11T21:06:12.323Z" }, + { url = "https://files.pythonhosted.org/packages/52/4d/0ad6df0e750c19dabd24d2cecad0938964f69a072f05fbdab7281bec2b64/wandb-0.23.0-py3-none-musllinux_1_2_aarch64.whl", hash = "sha256:6151355fd922539926e870be811474238c9614b96541773b990f1ce53368aef6", size = 18793473, upload-time = "2025-11-11T21:06:14.967Z" }, + { url = "https://files.pythonhosted.org/packages/f8/da/c2ba49c5573dff93dafc0acce691bb1c3d57361bf834b2f2c58e6193439b/wandb-0.23.0-py3-none-musllinux_1_2_x86_64.whl", hash = "sha256:df62e426e448ebc44269140deb7240df474e743b12d4b1f53b753afde4aa06d4", size = 20332882, upload-time = "2025-11-11T21:06:17.865Z" }, + { url = "https://files.pythonhosted.org/packages/40/65/21bfb10ee5cd93fbcaf794958863c7e05bac4bbeb1cc1b652094aa3743a5/wandb-0.23.0-py3-none-win32.whl", hash = "sha256:6c21d3eadda17aef7df6febdffdddfb0b4835c7754435fc4fe27631724269f5c", size = 19433198, upload-time = "2025-11-11T21:06:21.913Z" }, + { url = "https://files.pythonhosted.org/packages/f1/33/cbe79e66c171204e32cf940c7fdfb8b5f7d2af7a00f301c632f3a38aa84b/wandb-0.23.0-py3-none-win_amd64.whl", hash = "sha256:b50635fa0e16e528bde25715bf446e9153368428634ca7a5dbd7a22c8ae4e915", size = 19433201, upload-time = "2025-11-11T21:06:24.607Z" }, + { url = "https://files.pythonhosted.org/packages/1c/a0/5ecfae12d78ea036a746c071e4c13b54b28d641efbba61d2947c73b3e6f9/wandb-0.23.0-py3-none-win_arm64.whl", hash = "sha256:fa0181b02ce4d1993588f4a728d8b73ae487eb3cb341e6ce01c156be7a98ec72", size = 17678649, upload-time = "2025-11-11T21:06:27.289Z" }, +] + +[[package]] +name = "wcwidth" +version = "0.2.14" +source = { registry = "https://pypi.org/simple/" } +sdist = { url = "https://files.pythonhosted.org/packages/24/30/6b0809f4510673dc723187aeaf24c7f5459922d01e2f794277a3dfb90345/wcwidth-0.2.14.tar.gz", hash = "sha256:4d478375d31bc5395a3c55c40ccdf3354688364cd61c4f6adacaa9215d0b3605", size = 102293, upload-time = "2025-09-22T16:29:53.023Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/af/b5/123f13c975e9f27ab9c0770f514345bd406d0e8d3b7a0723af9d43f710af/wcwidth-0.2.14-py2.py3-none-any.whl", hash = "sha256:a7bb560c8aee30f9957e5f9895805edd20602f2d7f720186dfd906e82b4982e1", size = 37286, upload-time = "2025-09-22T16:29:51.641Z" }, +] + +[[package]] +name = "webdataset" +version = "1.0.2" +source = { registry = "https://pypi.org/simple/" } +dependencies = [ + { name = "braceexpand", marker = "platform_machine != 'x86_64' or sys_platform != 'darwin'" }, + { name = "numpy", marker = "platform_machine != 'x86_64' or sys_platform != 'darwin'" }, + { name = "pyyaml", marker = "platform_machine != 'x86_64' or sys_platform != 'darwin'" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/5a/3a/68800d92e065cf4750ebecf973b13979c0c929b439e1293012938862038d/webdataset-1.0.2.tar.gz", hash = "sha256:7f0498be827cfa46cc5430a58768a24e2c6a410676a61be1838f53d61afdaab4", size = 80090, upload-time = "2025-06-19T23:26:21.945Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/d9/00/aca6beb3658dab4ed3dbb41a78e6e7f31342e0b41d28088f205525751601/webdataset-1.0.2-py3-none-any.whl", hash = "sha256:3dbfced32b25c0d199c6b9787937b6f85742bc3c84f652c846893075c1c082d9", size = 74956, upload-time = "2025-06-19T23:26:20.354Z" }, +] + +[[package]] +name = "werkzeug" +version = "3.1.3" +source = { registry = "https://pypi.org/simple/" } +dependencies = [ + { name = "markupsafe", marker = "platform_machine != 'x86_64' or sys_platform != 'darwin'" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/9f/69/83029f1f6300c5fb2471d621ab06f6ec6b3324685a2ce0f9777fd4a8b71e/werkzeug-3.1.3.tar.gz", hash = "sha256:60723ce945c19328679790e3282cc758aa4a6040e4bb330f53d30fa546d44746", size = 806925, upload-time = "2024-11-08T15:52:18.093Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/52/24/ab44c871b0f07f491e5d2ad12c9bd7358e527510618cb1b803a88e986db1/werkzeug-3.1.3-py3-none-any.whl", hash = "sha256:54b78bf3716d19a65be4fceccc0d1d7b89e608834989dfae50ea87564639213e", size = 224498, upload-time = "2024-11-08T15:52:16.132Z" }, +] + +[[package]] +name = "wget" +version = "3.2" +source = { registry = "https://pypi.org/simple/" } +sdist = { url = "https://files.pythonhosted.org/packages/47/6a/62e288da7bcda82b935ff0c6cfe542970f04e29c756b0e147251b2fb251f/wget-3.2.zip", hash = "sha256:35e630eca2aa50ce998b9b1a127bb26b30dfee573702782aa982f875e3f16061", size = 10857, upload-time = "2015-10-22T15:26:37.51Z" } + +[[package]] +name = "whisper-normalizer" +version = "0.1.12" +source = { registry = "https://pypi.org/simple/" } +dependencies = [ + { name = "indic-numtowords", marker = "platform_machine != 'x86_64' or sys_platform != 'darwin'" }, + { name = "more-itertools", marker = "platform_machine != 'x86_64' or sys_platform != 'darwin'" }, + { name = "regex", marker = "platform_machine != 'x86_64' or sys_platform != 'darwin'" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/77/81/d4a23d67e9356f1c2d6fe9aa7e99f42078b5e3845b181412a5582f168af4/whisper_normalizer-0.1.12.tar.gz", hash = "sha256:484dcedbfeba2ee94cf9412d57ab1e66b847e91f80c15ffc4c6ab82ad5484b8c", size = 39630, upload-time = "2025-06-06T19:03:50.75Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/07/d7/2bf42cb3f19da0aec48052a6e3bc3a592afc182fe98c011a0e0ae5fbe1f5/whisper_normalizer-0.1.12-py3-none-any.whl", hash = "sha256:2cd7276d2599c05147a50cf86d240e6cd27623f5ccfe8b20ccea6a518274989a", size = 36748, upload-time = "2025-06-06T19:03:49.182Z" }, +] + +[[package]] +name = "win32-setctime" +version = "1.2.0" +source = { registry = "https://pypi.org/simple/" } +sdist = { url = "https://files.pythonhosted.org/packages/b3/8f/705086c9d734d3b663af0e9bb3d4de6578d08f46b1b101c2442fd9aecaa2/win32_setctime-1.2.0.tar.gz", hash = "sha256:ae1fdf948f5640aae05c511ade119313fb6a30d7eabe25fef9764dca5873c4c0", size = 4867, upload-time = "2024-12-07T15:28:28.314Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/e1/07/c6fe3ad3e685340704d314d765b7912993bcb8dc198f0e7a89382d37974b/win32_setctime-1.2.0-py3-none-any.whl", hash = "sha256:95d644c4e708aba81dc3704a116d8cbc974d70b3bdb8be1d150e36be6e9d1390", size = 4083, upload-time = "2024-12-07T15:28:26.465Z" }, +] + [[package]] name = "wrapt" version = "1.17.3" @@ -2623,6 +4458,59 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/1f/f6/a933bd70f98e9cf3e08167fc5cd7aaaca49147e48411c0bd5ae701bb2194/wrapt-1.17.3-py3-none-any.whl", hash = "sha256:7171ae35d2c33d326ac19dd8facb1e82e5fd04ef8c6c0e394d7af55a55051c22", size = 23591, upload-time = "2025-08-12T05:53:20.674Z" }, ] +[[package]] +name = "xxhash" +version = "3.6.0" +source = { registry = "https://pypi.org/simple/" } +sdist = { url = "https://files.pythonhosted.org/packages/02/84/30869e01909fb37a6cc7e18688ee8bf1e42d57e7e0777636bd47524c43c7/xxhash-3.6.0.tar.gz", hash = "sha256:f0162a78b13a0d7617b2845b90c763339d1f1d82bb04a4b07f4ab535cc5e05d6", size = 85160, upload-time = "2025-10-02T14:37:08.097Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/9a/07/d9412f3d7d462347e4511181dea65e47e0d0e16e26fbee2ea86a2aefb657/xxhash-3.6.0-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:01362c4331775398e7bb34e3ab403bc9ee9f7c497bc7dee6272114055277dd3c", size = 32744, upload-time = "2025-10-02T14:34:34.622Z" }, + { url = "https://files.pythonhosted.org/packages/79/35/0429ee11d035fc33abe32dca1b2b69e8c18d236547b9a9b72c1929189b9a/xxhash-3.6.0-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:b7b2df81a23f8cb99656378e72501b2cb41b1827c0f5a86f87d6b06b69f9f204", size = 30816, upload-time = "2025-10-02T14:34:36.043Z" }, + { url = "https://files.pythonhosted.org/packages/b7/f2/57eb99aa0f7d98624c0932c5b9a170e1806406cdbcdb510546634a1359e0/xxhash-3.6.0-cp312-cp312-manylinux1_i686.manylinux_2_28_i686.manylinux_2_5_i686.whl", hash = "sha256:dc94790144e66b14f67b10ac8ed75b39ca47536bf8800eb7c24b50271ea0c490", size = 194035, upload-time = "2025-10-02T14:34:37.354Z" }, + { url = "https://files.pythonhosted.org/packages/4c/ed/6224ba353690d73af7a3f1c7cdb1fc1b002e38f783cb991ae338e1eb3d79/xxhash-3.6.0-cp312-cp312-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:93f107c673bccf0d592cdba077dedaf52fe7f42dcd7676eba1f6d6f0c3efffd2", size = 212914, upload-time = "2025-10-02T14:34:38.6Z" }, + { url = "https://files.pythonhosted.org/packages/38/86/fb6b6130d8dd6b8942cc17ab4d90e223653a89aa32ad2776f8af7064ed13/xxhash-3.6.0-cp312-cp312-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:2aa5ee3444c25b69813663c9f8067dcfaa2e126dc55e8dddf40f4d1c25d7effa", size = 212163, upload-time = "2025-10-02T14:34:39.872Z" }, + { url = "https://files.pythonhosted.org/packages/ee/dc/e84875682b0593e884ad73b2d40767b5790d417bde603cceb6878901d647/xxhash-3.6.0-cp312-cp312-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:f7f99123f0e1194fa59cc69ad46dbae2e07becec5df50a0509a808f90a0f03f0", size = 445411, upload-time = "2025-10-02T14:34:41.569Z" }, + { url = "https://files.pythonhosted.org/packages/11/4f/426f91b96701ec2f37bb2b8cec664eff4f658a11f3fa9d94f0a887ea6d2b/xxhash-3.6.0-cp312-cp312-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:49e03e6fe2cac4a1bc64952dd250cf0dbc5ef4ebb7b8d96bce82e2de163c82a2", size = 193883, upload-time = "2025-10-02T14:34:43.249Z" }, + { url = "https://files.pythonhosted.org/packages/53/5a/ddbb83eee8e28b778eacfc5a85c969673e4023cdeedcfcef61f36731610b/xxhash-3.6.0-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:bd17fede52a17a4f9a7bc4472a5867cb0b160deeb431795c0e4abe158bc784e9", size = 210392, upload-time = "2025-10-02T14:34:45.042Z" }, + { url = "https://files.pythonhosted.org/packages/1e/c2/ff69efd07c8c074ccdf0a4f36fcdd3d27363665bcdf4ba399abebe643465/xxhash-3.6.0-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:6fb5f5476bef678f69db04f2bd1efbed3030d2aba305b0fc1773645f187d6a4e", size = 197898, upload-time = "2025-10-02T14:34:46.302Z" }, + { url = "https://files.pythonhosted.org/packages/58/ca/faa05ac19b3b622c7c9317ac3e23954187516298a091eb02c976d0d3dd45/xxhash-3.6.0-cp312-cp312-musllinux_1_2_ppc64le.whl", hash = "sha256:843b52f6d88071f87eba1631b684fcb4b2068cd2180a0224122fe4ef011a9374", size = 210655, upload-time = "2025-10-02T14:34:47.571Z" }, + { url = "https://files.pythonhosted.org/packages/d4/7a/06aa7482345480cc0cb597f5c875b11a82c3953f534394f620b0be2f700c/xxhash-3.6.0-cp312-cp312-musllinux_1_2_s390x.whl", hash = "sha256:7d14a6cfaf03b1b6f5f9790f76880601ccc7896aff7ab9cd8978a939c1eb7e0d", size = 414001, upload-time = "2025-10-02T14:34:49.273Z" }, + { url = "https://files.pythonhosted.org/packages/23/07/63ffb386cd47029aa2916b3d2f454e6cc5b9f5c5ada3790377d5430084e7/xxhash-3.6.0-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:418daf3db71e1413cfe211c2f9a528456936645c17f46b5204705581a45390ae", size = 191431, upload-time = "2025-10-02T14:34:50.798Z" }, + { url = "https://files.pythonhosted.org/packages/0f/93/14fde614cadb4ddf5e7cebf8918b7e8fac5ae7861c1875964f17e678205c/xxhash-3.6.0-cp312-cp312-win32.whl", hash = "sha256:50fc255f39428a27299c20e280d6193d8b63b8ef8028995323bf834a026b4fbb", size = 30617, upload-time = "2025-10-02T14:34:51.954Z" }, + { url = "https://files.pythonhosted.org/packages/13/5d/0d125536cbe7565a83d06e43783389ecae0c0f2ed037b48ede185de477c0/xxhash-3.6.0-cp312-cp312-win_amd64.whl", hash = "sha256:c0f2ab8c715630565ab8991b536ecded9416d615538be8ecddce43ccf26cbc7c", size = 31534, upload-time = "2025-10-02T14:34:53.276Z" }, + { url = "https://files.pythonhosted.org/packages/54/85/6ec269b0952ec7e36ba019125982cf11d91256a778c7c3f98a4c5043d283/xxhash-3.6.0-cp312-cp312-win_arm64.whl", hash = "sha256:eae5c13f3bc455a3bbb68bdc513912dc7356de7e2280363ea235f71f54064829", size = 27876, upload-time = "2025-10-02T14:34:54.371Z" }, +] + +[[package]] +name = "yarl" +version = "1.22.0" +source = { registry = "https://pypi.org/simple/" } +dependencies = [ + { name = "idna", marker = "platform_machine != 'x86_64' or sys_platform != 'darwin'" }, + { name = "multidict", marker = "platform_machine != 'x86_64' or sys_platform != 'darwin'" }, + { name = "propcache", marker = "platform_machine != 'x86_64' or sys_platform != 'darwin'" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/57/63/0c6ebca57330cd313f6102b16dd57ffaf3ec4c83403dcb45dbd15c6f3ea1/yarl-1.22.0.tar.gz", hash = "sha256:bebf8557577d4401ba8bd9ff33906f1376c877aa78d1fe216ad01b4d6745af71", size = 187169, upload-time = "2025-10-06T14:12:55.963Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/75/ff/46736024fee3429b80a165a732e38e5d5a238721e634ab41b040d49f8738/yarl-1.22.0-cp312-cp312-macosx_10_13_universal2.whl", hash = "sha256:e340382d1afa5d32b892b3ff062436d592ec3d692aeea3bef3a5cfe11bbf8c6f", size = 142000, upload-time = "2025-10-06T14:09:44.631Z" }, + { url = "https://files.pythonhosted.org/packages/5a/9a/b312ed670df903145598914770eb12de1bac44599549b3360acc96878df8/yarl-1.22.0-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:f1e09112a2c31ffe8d80be1b0988fa6a18c5d5cad92a9ffbb1c04c91bfe52ad2", size = 94338, upload-time = "2025-10-06T14:09:46.372Z" }, + { url = "https://files.pythonhosted.org/packages/ba/f5/0601483296f09c3c65e303d60c070a5c19fcdbc72daa061e96170785bc7d/yarl-1.22.0-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:939fe60db294c786f6b7c2d2e121576628468f65453d86b0fe36cb52f987bd74", size = 94909, upload-time = "2025-10-06T14:09:48.648Z" }, + { url = "https://files.pythonhosted.org/packages/60/41/9a1fe0b73dbcefce72e46cf149b0e0a67612d60bfc90fb59c2b2efdfbd86/yarl-1.22.0-cp312-cp312-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:e1651bf8e0398574646744c1885a41198eba53dc8a9312b954073f845c90a8df", size = 372940, upload-time = "2025-10-06T14:09:50.089Z" }, + { url = "https://files.pythonhosted.org/packages/17/7a/795cb6dfee561961c30b800f0ed616b923a2ec6258b5def2a00bf8231334/yarl-1.22.0-cp312-cp312-manylinux2014_armv7l.manylinux_2_17_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:b8a0588521a26bf92a57a1705b77b8b59044cdceccac7151bd8d229e66b8dedb", size = 345825, upload-time = "2025-10-06T14:09:52.142Z" }, + { url = "https://files.pythonhosted.org/packages/d7/93/a58f4d596d2be2ae7bab1a5846c4d270b894958845753b2c606d666744d3/yarl-1.22.0-cp312-cp312-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:42188e6a615c1a75bcaa6e150c3fe8f3e8680471a6b10150c5f7e83f47cc34d2", size = 386705, upload-time = "2025-10-06T14:09:54.128Z" }, + { url = "https://files.pythonhosted.org/packages/61/92/682279d0e099d0e14d7fd2e176bd04f48de1484f56546a3e1313cd6c8e7c/yarl-1.22.0-cp312-cp312-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:f6d2cb59377d99718913ad9a151030d6f83ef420a2b8f521d94609ecc106ee82", size = 396518, upload-time = "2025-10-06T14:09:55.762Z" }, + { url = "https://files.pythonhosted.org/packages/db/0f/0d52c98b8a885aeda831224b78f3be7ec2e1aa4a62091f9f9188c3c65b56/yarl-1.22.0-cp312-cp312-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:50678a3b71c751d58d7908edc96d332af328839eea883bb554a43f539101277a", size = 377267, upload-time = "2025-10-06T14:09:57.958Z" }, + { url = "https://files.pythonhosted.org/packages/22/42/d2685e35908cbeaa6532c1fc73e89e7f2efb5d8a7df3959ea8e37177c5a3/yarl-1.22.0-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:1e8fbaa7cec507aa24ea27a01456e8dd4b6fab829059b69844bd348f2d467124", size = 365797, upload-time = "2025-10-06T14:09:59.527Z" }, + { url = "https://files.pythonhosted.org/packages/a2/83/cf8c7bcc6355631762f7d8bdab920ad09b82efa6b722999dfb05afa6cfac/yarl-1.22.0-cp312-cp312-musllinux_1_2_armv7l.whl", hash = "sha256:433885ab5431bc3d3d4f2f9bd15bfa1614c522b0f1405d62c4f926ccd69d04fa", size = 365535, upload-time = "2025-10-06T14:10:01.139Z" }, + { url = "https://files.pythonhosted.org/packages/25/e1/5302ff9b28f0c59cac913b91fe3f16c59a033887e57ce9ca5d41a3a94737/yarl-1.22.0-cp312-cp312-musllinux_1_2_ppc64le.whl", hash = "sha256:b790b39c7e9a4192dc2e201a282109ed2985a1ddbd5ac08dc56d0e121400a8f7", size = 382324, upload-time = "2025-10-06T14:10:02.756Z" }, + { url = "https://files.pythonhosted.org/packages/bf/cd/4617eb60f032f19ae3a688dc990d8f0d89ee0ea378b61cac81ede3e52fae/yarl-1.22.0-cp312-cp312-musllinux_1_2_s390x.whl", hash = "sha256:31f0b53913220599446872d757257be5898019c85e7971599065bc55065dc99d", size = 383803, upload-time = "2025-10-06T14:10:04.552Z" }, + { url = "https://files.pythonhosted.org/packages/59/65/afc6e62bb506a319ea67b694551dab4a7e6fb7bf604e9bd9f3e11d575fec/yarl-1.22.0-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:a49370e8f711daec68d09b821a34e1167792ee2d24d405cbc2387be4f158b520", size = 374220, upload-time = "2025-10-06T14:10:06.489Z" }, + { url = "https://files.pythonhosted.org/packages/e7/3d/68bf18d50dc674b942daec86a9ba922d3113d8399b0e52b9897530442da2/yarl-1.22.0-cp312-cp312-win32.whl", hash = "sha256:70dfd4f241c04bd9239d53b17f11e6ab672b9f1420364af63e8531198e3f5fe8", size = 81589, upload-time = "2025-10-06T14:10:09.254Z" }, + { url = "https://files.pythonhosted.org/packages/c8/9a/6ad1a9b37c2f72874f93e691b2e7ecb6137fb2b899983125db4204e47575/yarl-1.22.0-cp312-cp312-win_amd64.whl", hash = "sha256:8884d8b332a5e9b88e23f60bb166890009429391864c685e17bd73a9eda9105c", size = 87213, upload-time = "2025-10-06T14:10:11.369Z" }, + { url = "https://files.pythonhosted.org/packages/44/c5/c21b562d1680a77634d748e30c653c3ca918beb35555cff24986fff54598/yarl-1.22.0-cp312-cp312-win_arm64.whl", hash = "sha256:ea70f61a47f3cc93bdf8b2f368ed359ef02a01ca6393916bc8ff877427181e74", size = 81330, upload-time = "2025-10-06T14:10:13.112Z" }, + { url = "https://files.pythonhosted.org/packages/73/ae/b48f95715333080afb75a4504487cbe142cae1268afc482d06692d605ae6/yarl-1.22.0-py3-none-any.whl", hash = "sha256:1380560bdba02b6b6c90de54133c81c9f2a453dee9912fe58c1dcced1edb7cff", size = 46814, upload-time = "2025-10-06T14:12:53.872Z" }, +] + [[package]] name = "yt-dlp" version = "2025.10.22" diff --git a/whisper_diarization b/whisper_diarization new file mode 160000 index 00000000..fcbd1930 --- /dev/null +++ b/whisper_diarization @@ -0,0 +1 @@ +Subproject commit fcbd1930d8a2fb2dc4e7cd0b7a0f2bffb786e8d3