diff --git a/.github/ISSUE_TEMPLATE/bug_report.yml b/.github/ISSUE_TEMPLATE/bug_report.yml new file mode 100644 index 000000000..6f024c73b --- /dev/null +++ b/.github/ISSUE_TEMPLATE/bug_report.yml @@ -0,0 +1,56 @@ +name: Bug report +description: Report a bug in pyannote.audio +body: + +- type: markdown + attributes: + value: | + When reporting bugs, please follow the guidelines in this template. This helps identify the problem precisely and thus enables contributors to fix it faster. + - Write a descriptive issue title above. + - The golden rule is to **always open *one* issue for *one* bug**. If you notice several bugs and want to report them, make sure to create one new issue for each of them. + - Search [open](https://github.com/pyannote/pyannote-audio/issues) and [closed](https://github.com/pyannote/pyannote-audio/issues?q=is%3Aissue+is%3Aclosed) issues to ensure it has not already been reported. If you don't find a relevant match or if you're unsure, don't hesitate to **open a new issue**. The bugsquad will handle it from there if it's a duplicate. + - Please always check if your issue is reproducible in the latest version – it may already have been fixed! + - If you use a custom build, please test if your issue is reproducible in official releases too. + +- type: textarea + attributes: + label: Tested versions + description: | + To properly fix a bug, we need to identify if the bug was recently introduced in the engine, or if it was always present. + - Please specify the pyannote.audio version you found the issue in, including the **Git commit hash** if using a development build. + - If you can, **please test earlier pyannote.audio versions** and, if applicable, newer versions (development branch). Mention whether the bug is reproducible or not in the versions you tested. + - The aim is for us to identify whether a bug is a **regression**, i.e. an issue that didn't exist in a previous version, but was introduced later on, breaking existing functionality. For example, if a bug is reproducible in 3.2 but not in 3.0, we would like you to test intermediate 3.1 to find which version is the first one where the issue can be reproduced. + placeholder: | + - Reproducible in: 3.1, 3.2, and later + - Not reproducible in: 3.0 + validations: + required: true + +- type: input + attributes: + label: System information + description: | + - Specify the OS version, and when relevant hardware information. + - For issues that are likely OS-specific and/or GPU-related, please specify the GPU model and architecture. + - **Bug reports not including the required information may be closed at the maintainers' discretion.** If in doubt, always include all the requested information; it's better to include too much information than not enough information. + placeholder: macOS 13.6 - pyannote.audio 3.1.1 - M1 Pro + validations: + required: true + +- type: textarea + attributes: + label: Issue description + description: | + Describe your issue briefly. What doesn't work, and how do you expect it to work instead? + You can include audio, images or videos with drag and drop, and format code blocks or logs with ``` tags. + validations: + required: true + +- type: input + attributes: + label: Minimal reproduction example (MRE) + description: | + Having reproducible issues is a prerequisite for contributors to be able to solve them. + Include a link to minimal reproduction example using [this Google Colab notebook](https://colab.research.google.com/github/pyannote/pyannote-audio/blob/develop/tutorials/MRE_template.ipynb) as a starting point. + validations: + required: true diff --git a/.github/ISSUE_TEMPLATE/config.yml b/.github/ISSUE_TEMPLATE/config.yml new file mode 100644 index 000000000..84f6ea55a --- /dev/null +++ b/.github/ISSUE_TEMPLATE/config.yml @@ -0,0 +1,15 @@ +blank_issues_enabled: false + +contact_links: + + - name: Feature request + url: https://github.com/pyannote/pyannote-audio/discussions + about: Suggest an idea for this project. + + - name: Consulting + url: https://herve.niderb.fr/consulting + about: Using pyannote.audio in production? Make the most of it thanks to our consulting services. + + - name: Premium models + url: https://forms.office.com/e/GdqwVgkZ5C + about: We are considering selling premium models, extensions, or services around pyannote.audio. diff --git a/.github/ISSUE_TEMPLATE/feature_request.md b/.github/ISSUE_TEMPLATE/feature_request.md deleted file mode 100644 index 4ead48053..000000000 --- a/.github/ISSUE_TEMPLATE/feature_request.md +++ /dev/null @@ -1,20 +0,0 @@ ---- -name: Feature request -about: Suggest an idea for this project -title: '' -labels: '' -assignees: '' - ---- - -**Is your feature request related to a problem? Please describe.** -A clear and concise description of what the problem is. Ex. I'm always frustrated when [...] - -**Describe the solution you'd like** -A clear and concise description of what you want to happen. - -**Describe alternatives you've considered** -A clear and concise description of any alternative solutions or features you've considered. - -**Additional context** -Add any other context about the feature request here. diff --git a/.github/workflows/new_issue.yml b/.github/workflows/new_issue.yml deleted file mode 100644 index b8477dc16..000000000 --- a/.github/workflows/new_issue.yml +++ /dev/null @@ -1,29 +0,0 @@ -name: issues -on: - issues: - types: [opened] -jobs: - add-comment: - runs-on: ubuntu-latest - permissions: - issues: write - steps: - - uses: actions/checkout@v3 - with: - ref: develop - - name: Install FAQtory - run: pip install FAQtory - - name: Run Suggest - env: - TITLE: ${{ github.event.issue.title }} - run: faqtory suggest "$TITLE" > suggest.md - - name: Read suggest.md - id: suggest - uses: juliangruber/read-file-action@v1 - with: - path: ./suggest.md - - name: Suggest FAQ - uses: peter-evans/create-or-update-comment@a35cf36e5301d70b76f316e867e7788a55a31dae - with: - issue-number: ${{ github.event.issue.number }} - body: ${{ steps.suggest.outputs.content }} diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index 90a4302c6..e649027ae 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -30,4 +30,4 @@ jobs: pip install -e .[dev,testing] - name: Test with pytest run: | - pytest + pytest -k "not test_cli.py" diff --git a/.github/workflows/test_cli.yml b/.github/workflows/test_cli.yml new file mode 100644 index 000000000..731a4b5b6 --- /dev/null +++ b/.github/workflows/test_cli.yml @@ -0,0 +1,33 @@ +name: CLI tests + +on: + push: + branches: [develop] + pull_request: + branches: [develop] + +jobs: + build: + timeout-minutes: 20 + runs-on: ${{ matrix.os }} + strategy: + matrix: + os: [ubuntu-latest] + python-version: ["3.10"] + steps: + - uses: actions/checkout@v2 + - name: Set up Python ${{ matrix.python-version }} + uses: actions/setup-python@v2 + with: + python-version: ${{ matrix.python-version }} + - name: Install libsndfile + if: matrix.os == 'ubuntu-latest' + run: | + sudo apt-get update + sudo apt-get install libsndfile1 + - name: Install pyannote.audio + run: | + pip install -e .[dev,testing,cli] + - name: Test with pytest + run: | + pytest tests/test_cli.py diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index 549e46ad0..92c952bdc 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -14,7 +14,7 @@ repos: # Sort imports - repo: https://github.com/PyCQA/isort - rev: 5.10.1 + rev: 5.12.0 hooks: - id: isort args: ["--profile", "black"] diff --git a/CHANGELOG.md b/CHANGELOG.md index 777f41f38..ad88762c2 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,40 @@ # Changelog +## Version 3.2.0 (2024-05-08) + +### New features + +- feat(task): add option to cache task training metadata to speed up training (with [@clement-pages](https://github.com/clement-pages/)) +- feat(model): add `receptive_field`, `num_frames` and `dimension` to models (with [@Bilal-Rahou](https://github.com/Bilal-Rahou)) +- feat(model): add `fbank_only` property to `WeSpeaker` models +- feat(util): add `Powerset.permutation_mapping` to help with permutation in powerset space (with [@FrenchKrab](https://github.com/FrenchKrab)) +- feat(sample): add sample file at `pyannote.audio.sample.SAMPLE_FILE` +- feat(metric): add `reduce` option to `diarization_error_rate` metric (with [@Bilal-Rahou](https://github.com/Bilal-Rahou)) +- feat(pipeline): add `Waveform` and `SampleRate` preprocessors + +### Fixes + +- fix(task): fix random generators and their reproducibility (with [@FrenchKrab](https://github.com/FrenchKrab)) +- fix(task): fix estimation of training set size (with [@FrenchKrab](https://github.com/FrenchKrab)) +- fix(hook): fix `torch.Tensor` support in `ArtifactHook` +- fix(doc): fix typo in `Powerset` docstring (with [@lukasstorck](https://github.com/lukasstorck)) + +### Improvements + +- improve(metric): add support for number of speakers mismatch in `diarization_error_rate` metric +- improve(pipeline): track both `Model` and `nn.Module` attributes in `Pipeline.to(device)` +- improve(io): switch to `torchaudio >= 2.2.0` +- improve(doc): update tutorials (with [@clement-pages](https://github.com/clement-pages/)) + +## Breaking changes + +- BREAKING(model): get rid of `Model.example_output` in favor of `num_frames` method, `receptive_field` property, and `dimension` property +- BREAKING(task): custom tasks need to be updated (see "Add your own task" tutorial) + +## Community contributions + +- community: add tutorial for offline use of `pyannote/speaker-diarization-3.1` (by [@simonottenhauskenbun](https://github.com/simonottenhauskenbun)) + ## Version 3.1.1 (2023-12-01) ### TL;DR diff --git a/MANIFEST.in b/MANIFEST.in index 16909925f..45ad7d6af 100644 --- a/MANIFEST.in +++ b/MANIFEST.in @@ -1,4 +1,6 @@ recursive-include pyannote *.py recursive-include pyannote *.yaml +recursive-include pyannote *.wav +recursive-include pyannote *.rttm global-exclude *.pyc global-exclude __pycache__ diff --git a/README.md b/README.md index 49b976a1f..e1326816a 100644 --- a/README.md +++ b/README.md @@ -70,26 +70,30 @@ for turn, _, speaker in diarization.itertracks(yield_label=True): - Videos - [Introduction to speaker diarization](https://umotion.univ-lemans.fr/video/9513-speech-segmentation-and-speaker-diarization/) / JSALT 2023 summer school / 90 min - [Speaker segmentation model](https://www.youtube.com/watch?v=wDH2rvkjymY) / Interspeech 2021 / 3 min - - [First releaase of pyannote.audio](https://www.youtube.com/watch?v=37R_R82lfwA) / ICASSP 2020 / 8 min + - [First release of pyannote.audio](https://www.youtube.com/watch?v=37R_R82lfwA) / ICASSP 2020 / 8 min +- Community contributions (not maintained by the core team) + - 2024-04-05 > [Offline speaker diarization (speaker-diarization-3.1)](tutorials/community/offline_usage_speaker_diarization.ipynb) by [Simon Ottenhaus](https://github.com/simonottenhauskenbun) ## Benchmark Out of the box, `pyannote.audio` speaker diarization [pipeline](https://hf.co/pyannote/speaker-diarization-3.1) v3.1 is expected to be much better (and faster) than v2.x. Those numbers are diarization error rates (in %): -| Benchmark | [v2.1](https://hf.co/pyannote/speaker-diarization-2.1) | [v3.1](https://hf.co/pyannote/speaker-diarization-3.1) | [Premium](https://forms.office.com/e/GdqwVgkZ5C) | -| ---------------------- | ------------------------------------------------------ | ------------------------------------------------------ | ---------------------------------------------- | -| AISHELL-4 | 14.1 | 12.3 | 11.9 | -| AliMeeting (channel 1) | 27.4 | 24.5 | 22.5 | -| AMI (IHM) | 18.9 | 18.8 | 16.6 | -| AMI (SDM) | 27.1 | 22.6 | 20.9 | -| AVA-AVD | 66.3 | 50.0 | 39.8 | -| CALLHOME (part 2) | 31.6 | 28.4 | 22.2 | -| DIHARD 3 (full) | 26.9 | 21.4 | 17.2 | -| Ego4D (dev.) | 61.5 | 51.2 | 43.8 | -| MSDWild | 32.8 | 25.4 | 19.8 | -| REPERE (phase2) | 8.2 | 7.8 | 7.6 | -| VoxConverse (v0.3) | 11.2 | 11.2 | 9.4 | +| Benchmark | [v2.1](https://hf.co/pyannote/speaker-diarization-2.1) | [v3.1](https://hf.co/pyannote/speaker-diarization-3.1) | [Premium](https://forms.office.com/e/GdqwVgkZ5C) | +| --------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------ | ------------------------------------------------------ | ------------------------------------------------ | +| [AISHELL-4](https://arxiv.org/abs/2104.03603) | 14.1 | 12.2 | 11.9 | +| [AliMeeting](https://www.openslr.org/119/) (channel 1) | 27.4 | 24.4 | 22.5 | +| [AMI](https://groups.inf.ed.ac.uk/ami/corpus/) (IHM) | 18.9 | 18.8 | 16.6 | +| [AMI](https://groups.inf.ed.ac.uk/ami/corpus/) (SDM) | 27.1 | 22.4 | 20.9 | +| [AVA-AVD](https://arxiv.org/abs/2111.14448) | 66.3 | 50.0 | 39.8 | +| [CALLHOME](https://catalog.ldc.upenn.edu/LDC2001S97) ([part 2](https://github.com/BUTSpeechFIT/CALLHOME_sublists/issues/1)) | 31.6 | 28.4 | 22.2 | +| [DIHARD 3](https://catalog.ldc.upenn.edu/LDC2022S14) ([full](https://arxiv.org/abs/2012.01477)) | 26.9 | 21.7 | 17.2 | +| [Earnings21](https://github.com/revdotcom/speech-datasets) | 17.0 | 9.4 | 9.0 | +| [Ego4D](https://arxiv.org/abs/2110.07058) (dev.) | 61.5 | 51.2 | 43.8 | +| [MSDWild](https://github.com/X-LANCE/MSDWILD) | 32.8 | 25.3 | 19.8 | +| [RAMC](https://www.openslr.org/123/) | 22.5 | 22.2 | 18.4 | +| [REPERE](https://www.islrn.org/resources/360-758-359-485-0/) (phase2) | 8.2 | 7.8 | 7.6 | +| [VoxConverse](https://github.com/joonson/voxconverse) (v0.3) | 11.2 | 11.3 | 9.4 | [Diarization error rate](http://pyannote.github.io/pyannote-metrics/reference.html#diarization) (in %) diff --git a/pyannote/audio/augmentation/mix.py b/pyannote/audio/augmentation/mix.py index a6fff49c0..c6e811280 100644 --- a/pyannote/audio/augmentation/mix.py +++ b/pyannote/audio/augmentation/mix.py @@ -60,10 +60,10 @@ def __init__( max_snr_in_db: float = 5.0, mode: str = "per_example", p: float = 0.5, - p_mode: str = None, - sample_rate: int = None, - target_rate: int = None, - max_num_speakers: int = None, + p_mode: Optional[str] = None, + sample_rate: Optional[int] = None, + target_rate: Optional[int] = None, + max_num_speakers: Optional[int] = None, output_type: str = "tensor", ): super().__init__( @@ -80,7 +80,7 @@ def __init__( def randomize_parameters( self, - samples: Tensor = None, + samples: Optional[Tensor] = None, sample_rate: Optional[int] = None, targets: Optional[Tensor] = None, target_rate: Optional[int] = None, diff --git a/pyannote/audio/cli/evaluate.py b/pyannote/audio/cli/evaluate.py index a5ab682c5..3eec5e3cc 100644 --- a/pyannote/audio/cli/evaluate.py +++ b/pyannote/audio/cli/evaluate.py @@ -25,7 +25,7 @@ import hydra from omegaconf import DictConfig -from pyannote.database import FileFinder, ProtocolFile, get_protocol +from pyannote.database import FileFinder, ProtocolFile, registry from rich.progress import Progress from pyannote.audio import Inference, Model @@ -41,8 +41,16 @@ def evaluate(cfg: DictConfig) -> Optional[float]: (device,) = get_devices(needs=1) model = Model.from_pretrained(cfg.model, device=device) + # load databases into registry if it was specified + if "registry" in cfg: + for database_yml in cfg.registry.split(","): + registry.load_database(database_yml) + # load evaluation files - protocol = get_protocol(cfg.protocol, preprocessors={"audio": FileFinder()}) + protocol = registry.get_protocol( + cfg.protocol, preprocessors={"audio": FileFinder()} + ) + files = list(getattr(protocol, cfg.subset)()) # load evaluation metric @@ -53,7 +61,7 @@ def evaluate(cfg: DictConfig) -> Optional[float]: main_task = progress.add_task(protocol.name, total=len(files)) file_task = progress.add_task("Processing", total=1.0) - def progress_hook(completed: int = None, total: int = None): + def progress_hook(completed: Optional[int] = None, total: Optional[int] = None): progress.update(file_task, completed=completed / total) inference = Inference(model, device=device) @@ -65,8 +73,6 @@ def hypothesis(file: ProtocolFile): warm_up=(warm_up, warm_up), ) - metric = DiscreteDiarizationErrorRate() - for file in files: progress.update(file_task, description=file["uri"]) reference = file["annotation"] diff --git a/pyannote/audio/cli/evaluate_config/hydra/default.yaml b/pyannote/audio/cli/evaluate_config/hydra/default.yaml index 95979432b..1aaebd1b9 100644 --- a/pyannote/audio/cli/evaluate_config/hydra/default.yaml +++ b/pyannote/audio/cli/evaluate_config/hydra/default.yaml @@ -22,7 +22,8 @@ help: template: |- ${hydra.help.header} - pyannote-audio-eval protocol={protocol_name} + pyannote-audio-eval registry={path_to_database.yml} + protocol={protocol_name} subset={test | development | train} model={path_to_pretrained_model} warm_up={warm_up_duration_in_seconds} diff --git a/pyannote/audio/cli/lr_schedulers/CosineAnnealingWarmRestarts.py b/pyannote/audio/cli/lr_schedulers/CosineAnnealingWarmRestarts.py index d8e5f4b3c..3c270eba1 100644 --- a/pyannote/audio/cli/lr_schedulers/CosineAnnealingWarmRestarts.py +++ b/pyannote/audio/cli/lr_schedulers/CosineAnnealingWarmRestarts.py @@ -20,6 +20,7 @@ # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE # SOFTWARE. +from typing import Optional from torch.optim import Optimizer from torch.optim.lr_scheduler import ( @@ -32,7 +33,7 @@ def CosineAnnealingWarmRestarts( min_lr: float = 1e-8, max_lr: float = 1e-3, patience: int = 1, - num_batches_per_epoch: int = None, + num_batches_per_epoch: Optional[int] = None, **kwargs, ): """Wrapper around CosineAnnealingWarmRestarts diff --git a/pyannote/audio/cli/lr_schedulers/CyclicLR.py b/pyannote/audio/cli/lr_schedulers/CyclicLR.py index cd7a7b730..cca4420b0 100644 --- a/pyannote/audio/cli/lr_schedulers/CyclicLR.py +++ b/pyannote/audio/cli/lr_schedulers/CyclicLR.py @@ -20,6 +20,7 @@ # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE # SOFTWARE. +from typing import Optional from torch.optim import Optimizer from torch.optim.lr_scheduler import CyclicLR as _CyclicLR @@ -31,7 +32,7 @@ def CyclicLR( max_lr: float = 1e-3, mode: str = "triangular2", patience: int = 50, - num_batches_per_epoch: int = None, + num_batches_per_epoch: Optional[int] = None, **kwargs, ): """Wrapper around CyclicLR learning rate scheduler diff --git a/pyannote/audio/cli/train.py b/pyannote/audio/cli/train.py index 74041554b..f052cd5b3 100644 --- a/pyannote/audio/cli/train.py +++ b/pyannote/audio/cli/train.py @@ -51,8 +51,9 @@ def train(cfg: DictConfig) -> Optional[float]: seed_everything(seed=seed) # load databases into registry - for database_yml in cfg.registry.split(","): - registry.load_database(database_yml) + if "registry" in cfg: + for database_yml in cfg.registry.split(","): + registry.load_database(database_yml) # instantiate training protocol with optional preprocessors preprocessors = {"audio": FileFinder(), "torchaudio.info": get_torchaudio_info} @@ -75,9 +76,9 @@ def train(cfg: DictConfig) -> Optional[float]: # instantiate model fine_tuning = cfg.model["_target_"] == "pyannote.audio.cli.pretrained" - model = instantiate(cfg.model) - model.task = task - model.setup(stage="fit") + model = instantiate(cfg.model, task=task) + model.prepare_data() + model.setup() # validation metric to monitor (and its direction: min or max) monitor, direction = task.val_monitor @@ -146,7 +147,6 @@ def configure_optimizers(self): # in case of fine-tuning, validate the initial model to make sure # that we actually improve over the initial performance if fine_tuning: - model.setup(stage="fit") trainer.validate(model) # train the model @@ -157,7 +157,9 @@ def configure_optimizers(self): # return the best validation score # this can be used for hyper-parameter optimization with Hydra sweepers - if monitor is not None: + # this can only be done if the trainer is not in fast dev run mode, as + # checkpointing is disabled in this mode + if monitor is not None and not trainer.fast_dev_run: best_monitor = float(checkpoint.best_model_score) if direction == "min": return best_monitor diff --git a/pyannote/audio/cli/train_config/config.yaml b/pyannote/audio/cli/train_config/config.yaml index d5b761cc9..d7ecd547a 100644 --- a/pyannote/audio/cli/train_config/config.yaml +++ b/pyannote/audio/cli/train_config/config.yaml @@ -1,4 +1,3 @@ -registry: ??? protocol: ??? defaults: diff --git a/pyannote/audio/cli/train_config/trainer/default.yaml b/pyannote/audio/cli/train_config/trainer/default.yaml index ac3a60ff4..f32031af1 100644 --- a/pyannote/audio/cli/train_config/trainer/default.yaml +++ b/pyannote/audio/cli/train_config/trainer/default.yaml @@ -30,6 +30,6 @@ precision: 32 profiler: null reload_dataloaders_every_n_epochs: 0 use_distributed_sampler: True # TODO: check what this does exactly -strategy: null +strategy: auto sync_batchnorm: False val_check_interval: 1.0 diff --git a/pyannote/audio/core/callback.py b/pyannote/audio/core/callback.py index 5ce522d57..0cc46845b 100644 --- a/pyannote/audio/core/callback.py +++ b/pyannote/audio/core/callback.py @@ -20,7 +20,7 @@ # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE # SOFTWARE. -from typing import List, Mapping, Text, Union +from typing import List, Mapping, Optional, Text, Union from pytorch_lightning import Callback, Trainer from pytorch_lightning.utilities.model_summary import ModelSummary @@ -67,7 +67,7 @@ class GraduallyUnfreeze(Callback): def __init__( self, schedule: Union[Mapping[Text, int], List[Union[List[Text], Text]]] = None, - epochs_per_stage: int = None, + epochs_per_stage: Optional[int] = None, ): super().__init__() diff --git a/pyannote/audio/core/inference.py b/pyannote/audio/core/inference.py index dcf21868d..0c3e9b212 100644 --- a/pyannote/audio/core/inference.py +++ b/pyannote/audio/core/inference.py @@ -20,7 +20,6 @@ # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE # SOFTWARE. -import math import warnings from pathlib import Path from typing import Callable, List, Optional, Text, Tuple, Union @@ -37,7 +36,6 @@ from pyannote.audio.core.model import Model, Specifications from pyannote.audio.core.task import Resolution from pyannote.audio.utils.multi_task import map_with_specifications -from pyannote.audio.utils.permutation import mae_cost_func, permutate from pyannote.audio.utils.powerset import Powerset from pyannote.audio.utils.reproducibility import fix_reproducibility @@ -86,12 +84,12 @@ def __init__( self, model: Union[Model, Text, Path], window: Text = "sliding", - duration: float = None, - step: float = None, + duration: Optional[float] = None, + step: Optional[float] = None, pre_aggregation_hook: Callable[[np.ndarray], np.ndarray] = None, skip_aggregation: bool = False, skip_conversion: bool = False, - device: torch.device = None, + device: Optional[torch.device] = None, batch_size: int = 32, use_auth_token: Union[Text, None] = None, ): @@ -263,16 +261,14 @@ def slide( _, num_samples = waveform.shape def __frames( - example_output, specifications: Optional[Specifications] = None + receptive_field, specifications: Optional[Specifications] = None ) -> SlidingWindow: if specifications.resolution == Resolution.CHUNK: return SlidingWindow(start=0.0, duration=self.duration, step=self.step) - return example_output.frames + return receptive_field frames: Union[SlidingWindow, Tuple[SlidingWindow]] = map_with_specifications( - self.model.specifications, - __frames, - self.model.example_output, + self.model.specifications, __frames, self.model.receptive_field ) # prepare complete chunks @@ -373,7 +369,7 @@ def __aggregate( outputs, SlidingWindow(start=0.0, duration=self.duration, step=self.step), ), - frames=frames, + frames, warm_up=self.warm_up, hamming=True, missing=0.0, @@ -526,7 +522,7 @@ def __first_sample(outputs: np.ndarray, **kwargs) -> np.ndarray: @staticmethod def aggregate( scores: SlidingWindowFeature, - frames: SlidingWindow = None, + frames: SlidingWindow, warm_up: Tuple[float, float] = (0.0, 0.0), epsilon: float = 1e-12, hamming: bool = False, @@ -539,10 +535,8 @@ def aggregate( ---------- scores : SlidingWindowFeature Raw (unaggregated) scores. Shape is (num_chunks, num_frames_per_chunk, num_classes). - frames : SlidingWindow, optional - Frames resolution. Defaults to estimate it automatically based on `scores` shape - and chunk size. Providing the exact frame resolution (when known) leads to better - temporal precision. + frames : SlidingWindow + Frames resolution. warm_up : (float, float) tuple, optional Left/right warm up duration (in seconds). missing : float, optional @@ -559,15 +553,11 @@ def aggregate( num_chunks, num_frames_per_chunk, num_classes = scores.data.shape chunks = scores.sliding_window - if frames is None: - duration = step = chunks.duration / num_frames_per_chunk - frames = SlidingWindow(start=chunks.start, duration=duration, step=step) - else: - frames = SlidingWindow( - start=chunks.start, - duration=frames.duration, - step=frames.step, - ) + frames = SlidingWindow( + start=chunks.start, + duration=frames.duration, + step=frames.step, + ) masks = 1 - np.isnan(scores) scores.data = np.nan_to_num(scores.data, copy=True, nan=0.0) @@ -602,6 +592,7 @@ def aggregate( scores.sliding_window.start + scores.sliding_window.duration + (num_chunks - 1) * scores.sliding_window.step + + 0.5 * frames.duration ) + 1 ) @@ -627,7 +618,8 @@ def aggregate( # score ~ (num_frames_per_chunk, num_classes)-shaped np.ndarray # mask ~ (num_frames_per_chunk, num_classes)-shaped np.ndarray - start_frame = frames.closest_frame(chunk.start) + start_frame = frames.closest_frame(chunk.start + 0.5 * frames.duration) + aggregated_output[start_frame : start_frame + num_frames_per_chunk] += ( score * mask * hamming_window * warm_up_window ) @@ -698,134 +690,3 @@ def trim( ) return SlidingWindowFeature(new_data, new_chunks) - - @staticmethod - def stitch( - activations: SlidingWindowFeature, - frames: SlidingWindow = None, - lookahead: Optional[Tuple[int, int]] = None, - cost_func: Callable[[torch.Tensor, torch.Tensor], torch.Tensor] = None, - match_func: Callable[[np.ndarray, np.ndarray, float], bool] = None, - ) -> SlidingWindowFeature: - """ - - Parameters - ---------- - activations : SlidingWindowFeature - (num_chunks, num_frames, num_classes)-shaped scores. - frames : SlidingWindow, optional - Frames resolution. Defaults to estimate it automatically based on `activations` - shape and chunk size. Providing the exact frame resolution (when known) leads to better - temporal precision. - lookahead : (int, int) tuple - Number of past and future adjacent chunks to use for stitching. - Defaults to (k, k) with k = chunk_duration / chunk_step - 1 - cost_func : callable - Cost function used to find the optimal mapping between two chunks. - Expects two (num_frames, num_classes) torch.tensor as input - and returns cost as a (num_classes, ) torch.tensor - Defaults to mean absolute error (utils.permutations.mae_cost_func) - match_func : callable - Function used to decide whether two speakers mapped by the optimal - mapping actually are a match. - Expects two (num_frames, ) np.ndarray and the cost (from cost_func) - and returns a boolean. Defaults to always returning True. - """ - - num_chunks, num_frames, num_classes = activations.data.shape - - chunks: SlidingWindow = activations.sliding_window - - if frames is None: - duration = step = chunks.duration / num_frames - frames = SlidingWindow(start=chunks.start, duration=duration, step=step) - else: - frames = SlidingWindow( - start=chunks.start, - duration=frames.duration, - step=frames.step, - ) - - max_lookahead = math.floor(chunks.duration / chunks.step - 1) - if lookahead is None: - lookahead = 2 * (max_lookahead,) - - assert all(L <= max_lookahead for L in lookahead) - - if cost_func is None: - cost_func = mae_cost_func - - if match_func is None: - - def always_match(this: np.ndarray, that: np.ndarray, cost: float): - return True - - match_func = always_match - - stitches = [] - for C, (chunk, activation) in enumerate(activations): - local_stitch = np.NAN * np.zeros( - (sum(lookahead) + 1, num_frames, num_classes) - ) - - for c in range( - max(0, C - lookahead[0]), min(num_chunks, C + lookahead[1] + 1) - ): - # extract common temporal support - shift = round((C - c) * num_frames * chunks.step / chunks.duration) - - if shift < 0: - shift = -shift - this_activations = activation[shift:] - that_activations = activations[c, : num_frames - shift] - else: - this_activations = activation[: num_frames - shift] - that_activations = activations[c, shift:] - - # find the optimal one-to-one mapping - _, (permutation,), (cost,) = permutate( - this_activations[np.newaxis], - that_activations, - cost_func=cost_func, - return_cost=True, - ) - - for this, that in enumerate(permutation): - # only stitch under certain condiditions - matching = (c == C) or ( - match_func( - this_activations[:, this], - that_activations[:, that], - cost[this, that], - ) - ) - - if matching: - local_stitch[c - C + lookahead[0], :, this] = activations[ - c, :, that - ] - - # TODO: do not lookahead further once a mismatch is found - - stitched_chunks = SlidingWindow( - start=chunk.start - lookahead[0] * chunks.step, - duration=chunks.duration, - step=chunks.step, - ) - - local_stitch = Inference.aggregate( - SlidingWindowFeature(local_stitch, stitched_chunks), - frames=frames, - hamming=True, - ) - - stitches.append(local_stitch.data) - - stitches = np.stack(stitches) - stitched_chunks = SlidingWindow( - start=chunks.start - lookahead[0] * chunks.step, - duration=chunks.duration + sum(lookahead) * chunks.step, - step=chunks.step, - ) - - return SlidingWindowFeature(stitches, stitched_chunks) diff --git a/pyannote/audio/core/io.py b/pyannote/audio/core/io.py index 0a44e75ea..8fafe69d3 100644 --- a/pyannote/audio/core/io.py +++ b/pyannote/audio/core/io.py @@ -40,8 +40,6 @@ from pyannote.core import Segment from torch import Tensor -torchaudio.set_audio_backend("soundfile") - AudioFile = Union[Text, Path, IOBase, Mapping] AudioFileDocString = """ @@ -253,7 +251,9 @@ def get_duration(self, file: AudioFile) -> float: return frames / sample_rate - def get_num_samples(self, duration: float, sample_rate: int = None) -> int: + def get_num_samples( + self, duration: float, sample_rate: Optional[int] = None + ) -> int: """Deterministic number of samples from duration and sample rate""" sample_rate = sample_rate or self.sample_rate diff --git a/pyannote/audio/core/model.py b/pyannote/audio/core/model.py index bedb7f6c4..8af802293 100644 --- a/pyannote/audio/core/model.py +++ b/pyannote/audio/core/model.py @@ -46,7 +46,6 @@ from pyannote.audio.core.io import Audio from pyannote.audio.core.task import ( Problem, - Resolution, Specifications, Task, UnknownSpecificationsError, @@ -112,10 +111,6 @@ def task(self) -> Task: def task(self, task: Task): # reset (cached) properties when task changes del self.specifications - try: - del self.example_output - except AttributeError: - pass self._task = task def build(self): @@ -136,15 +131,7 @@ def specifications(self) -> Union[Specifications, Tuple[Specifications]]: ) from e else: - try: - specifications = self.task.specifications - - except AttributeError as e: - raise UnknownSpecificationsError( - "Task specifications are not available. This is most likely because they depend on " - "the content of the training subset. Use `model.task.setup()` to go over the training " - "subset and fix this, or let lightning trainer do that for you in `trainer.fit(model)`." - ) from e + specifications = self.task.specifications return specifications @@ -188,38 +175,35 @@ def example_input_array(self) -> torch.Tensor: return self.__example_input_array() @cached_property - def example_output(self) -> Union[Output, Tuple[Output]]: - """Example output""" - example_input_array = self.__example_input_array() - with torch.inference_mode(): - example_output = self(example_input_array) - - def __example_output( - example_output: torch.Tensor, - specifications: Specifications = None, - ) -> Output: - if specifications.resolution == Resolution.FRAME: - _, num_frames, dimension = example_output.shape - frame_duration = specifications.duration / num_frames - frames = SlidingWindow(step=frame_duration, duration=frame_duration) - else: - _, dimension = example_output.shape - num_frames = None - frames = None - - return Output( - num_frames=num_frames, - dimension=dimension, - frames=frames, - ) + def receptive_field(self) -> SlidingWindow: + """(Internal) frames""" - return map_with_specifications( - self.specifications, __example_output, example_output + receptive_field_size = self.receptive_field_size(num_frames=1) + receptive_field_step = ( + self.receptive_field_size(num_frames=2) - receptive_field_size + ) + receptive_field_start = ( + self.receptive_field_center(frame=0) - (receptive_field_size - 1) / 2 + ) + return SlidingWindow( + start=receptive_field_start / self.hparams.sample_rate, + duration=receptive_field_size / self.hparams.sample_rate, + step=receptive_field_step / self.hparams.sample_rate, ) + def prepare_data(self): + self.task.prepare_data() + def setup(self, stage=None): if stage == "fit": - self.task.setup_metadata() + # let the task know about the trainer (e.g for broadcasting + # cache path between multi-GPU training processes). + self.task.trainer = self.trainer + + # setup the task if defined (only on training and validation stages, + # but not for basic inference) + if self.task: + self.task.setup(stage) # list of layers before adding task-dependent layers before = set((name, id(module)) for name, module in self.named_modules()) @@ -252,7 +236,7 @@ def setup(self, stage=None): module.to(self.device) # add (trainable) loss function (e.g. ArcFace has its own set of trainable weights) - if stage == "fit": + if self.task: # let task know about the model self.task.model = self # setup custom loss function @@ -260,9 +244,6 @@ def setup(self, stage=None): # setup custom validation metrics self.task.setup_validation_metric() - # cache for later (and to avoid later CUDA error with multiprocessing) - _ = self.example_output - # list of layers after adding task-dependent layers after = set((name, id(module)) for name, module in self.named_modules()) @@ -331,7 +312,9 @@ def default_activation(self) -> Union[nn.Module, Tuple[nn.Module]]: Activation. """ - def __default_activation(specifications: Specifications = None) -> nn.Module: + def __default_activation( + specifications: Optional[Specifications] = None, + ) -> nn.Module: if specifications.problem == Problem.BINARY_CLASSIFICATION: return nn.Sigmoid() @@ -468,9 +451,8 @@ def __by_name( if isinstance(modules, str): modules = [modules] - for name, module in ModelSummary(self, max_depth=-1).named_modules: - if name not in modules: - continue + for name in modules: + module = getattr(self, name) for parameter in module.parameters(recurse=True): parameter.requires_grad = requires_grad diff --git a/pyannote/audio/core/pipeline.py b/pyannote/audio/core/pipeline.py index f844d584f..24e266abf 100644 --- a/pyannote/audio/core/pipeline.py +++ b/pyannote/audio/core/pipeline.py @@ -29,6 +29,7 @@ from typing import Callable, Dict, List, Optional, Text, Union import torch +import torch.nn as nn import yaml from huggingface_hub import hf_hub_download from huggingface_hub.utils import RepositoryNotFoundError @@ -232,7 +233,7 @@ def remove_from(*dicts): _models = self.__dict__.get("_models") _inferences = self.__dict__.get("_inferences") - if isinstance(value, Model): + if isinstance(value, nn.Module): if _models is None: msg = "cannot assign models before Pipeline.__init__() call" raise AttributeError(msg) diff --git a/pyannote/audio/core/task.py b/pyannote/audio/core/task.py index 1edfbc35c..0a61e2a6f 100644 --- a/pyannote/audio/core/task.py +++ b/pyannote/audio/core/task.py @@ -23,19 +23,25 @@ from __future__ import annotations +import itertools import multiprocessing import sys import warnings +from collections import defaultdict from dataclasses import dataclass from enum import Enum from functools import cached_property, partial from numbers import Number +from pathlib import Path +from tempfile import mkstemp from typing import Dict, List, Literal, Optional, Sequence, Text, Tuple, Union +import numpy as np import pytorch_lightning as pl import scipy.special import torch from pyannote.database import Protocol +from pyannote.database.protocol.protocol import Scope, Subset from torch.utils.data import DataLoader, Dataset, IterableDataset from torch_audiomentations import Identity from torch_audiomentations.core.transforms_interface import BaseWaveformTransform @@ -44,6 +50,9 @@ from pyannote.audio.utils.loss import binary_cross_entropy, nll_loss from pyannote.audio.utils.protocol import check_protocol +Subsets = list(Subset.__args__) +Scopes = list(Scope.__args__) + # Type of machine learning problem class Problem(Enum): @@ -151,6 +160,31 @@ def __len__(self): return self.task.val__len__() +def get_dtype(value: int) -> str: + """Return the most suitable type for storing the + value passed in parameter in memory. + + Parameters + ---------- + value: int + value whose type is best suited to storage in memory + + Returns + ------- + str: + numpy formatted type + (see https://numpy.org/doc/stable/reference/arrays.dtypes.html) + """ + # signe byte (8 bits), signed short (16 bits), signed int (32 bits): + types_list = [(127, "b"), (32_768, "i2"), (2_147_483_648, "i")] + filtered_list = [ + (max_val, type) for max_val, type in types_list if max_val > abs(value) + ] + if not filtered_list: + return "i8" # signed long (64 bits) + return filtered_list[0][1] + + class Task(pl.LightningDataModule): """Base task class @@ -169,6 +203,13 @@ class Task(pl.LightningDataModule): ---------- protocol : Protocol pyannote.database protocol + cache : str, optional + As (meta-)data preparation might take a very long time for large datasets, + it can be cached to disk for later (and faster!) re-use. + When `cache` does not exist, `Task.prepare_data()` generates training + and validation metadata from `protocol` and save them to disk. + When `cache` exists, `Task.prepare_data()` is skipped and (meta)-data + are loaded from disk. Defaults to a temporary path. duration : float, optional Chunks duration in seconds. Defaults to two seconds (2.). min_duration : float, optional @@ -201,18 +242,20 @@ class Task(pl.LightningDataModule): ---------- specifications : Specifications or tuple of Specifications Task specifications (available after `Task.setup` has been called.) + """ def __init__( self, protocol: Protocol, + cache: Optional[Union[str, None]] = None, duration: float = 2.0, - min_duration: float = None, + min_duration: Optional[float] = None, warm_up: Union[float, Tuple[float, float]] = 0.0, batch_size: int = 32, - num_workers: int = None, + num_workers: Optional[int] = None, pin_memory: bool = False, - augmentation: BaseWaveformTransform = None, + augmentation: Optional[BaseWaveformTransform] = None, metric: Union[Metric, Sequence[Metric], Dict[str, Metric]] = None, ): super().__init__() @@ -221,8 +264,16 @@ def __init__( self.protocol, checks = check_protocol(protocol) self.has_validation = checks["has_validation"] self.has_scope = checks["has_scope"] + if not self.has_scope: + raise ValueError( + "Protocol must provide 'scope' information (e.g. 'file', 'database', or 'global')." + ) + self.has_classes = checks["has_classes"] + # metadata cache + self.cache = Path(cache) if cache else cache + # batching self.duration = duration self.min_duration = duration if min_duration is None else min_duration @@ -255,24 +306,351 @@ def __init__( self._metric = metric def prepare_data(self): - """Use this to download and prepare data - - This is where we might end up downloading datasets - and transform them so that they are ready to be used - with pyannote.database. but for now, the API assume - that we directly provide a pyannote.database.Protocol. + """Use this to prepare data from task protocol Notes ----- - Called only once. + Called only once on the main process (and only on it), for global_rank 0. + + After this method is called, the task should have a `prepared_data` attribute + with the following dictionary structure: + + prepared_data = { + 'protocol': name of the protocol + 'audio-path': array of N paths to audio + 'audio-metadata': array of N audio infos such as audio subset, scope and database + 'audio-info': array of N audio torchaudio.info struct + 'audio-encoding': array of N audio encodings + 'audio-annotated': array of N annotated duration (usually equals file duration but might be shorter if file is not fully annotated) + 'annotations-regions': array of M annotated regions + 'annotations-segments': array of M' annotated segments + 'metadata-values': dict of lists of values for subset, scope and database + 'metadata-`database-name`-labels': array of `database-name` labels. Each database with "database" scope labels has it own array. + 'metadata-labels': array of global scope labels + } + + """ + + if self.cache: + # check if cache exists and is not empty: + if self.cache.exists() and self.cache.stat().st_size > 0: + # data was already created, nothing to do + return + # create parent directory if needed + self.cache.parent.mkdir(parents=True, exist_ok=True) + else: + # if no cache was provided by user, create a temporary file + # in system directory used for temp files + self.cache = Path(mkstemp()[1]) + + # list of possible values for each metadata key + # (will become .prepared_data[""]) + metadata_unique_values = defaultdict(list) + metadata_unique_values["subset"] = Subsets + metadata_unique_values["scope"] = Scopes + + audios = list() # list of path to audio files + audio_infos = list() + audio_encodings = list() + metadata = list() # list of metadata + + annotated_duration = list() # total duration of annotated regions (per file) + annotated_regions = list() # annotated regions + annotations = list() # actual annotations + unique_labels = list() + database_unique_labels = {} + + if self.has_validation: + files_iter = itertools.chain( + self.protocol.train(), self.protocol.development() + ) + else: + files_iter = self.protocol.train() + + for file_id, file in enumerate(files_iter): + # gather metadata and update metadata_unique_values so that each metadatum + # (e.g. source database or label) is represented by an integer. + metadatum = dict() + + # keep track of source database and subset (train, development, or test) + if file["database"] not in metadata_unique_values["database"]: + metadata_unique_values["database"].append(file["database"]) + metadatum["database"] = metadata_unique_values["database"].index( + file["database"] + ) + metadatum["subset"] = Subsets.index(file["subset"]) + + # keep track of label scope (file, database, or global) + metadatum["scope"] = Scopes.index(file["scope"]) + + remaining_metadata_keys = set(file) - set( + [ + "uri", + "database", + "subset", + "audio", + "torchaudio.info", + "scope", + "classes", + "annotation", + "annotated", + ] + ) + + # keep track of any other (integer or string) metadata provided by the protocol + # (e.g. a "domain" key for domain-adversarial training) + for key in remaining_metadata_keys: + value = file[key] + + if isinstance(value, str): + if value not in metadata_unique_values[key]: + metadata_unique_values[key].append(value) + metadatum[key] = metadata_unique_values[key].index(value) + + elif isinstance(value, int): + metadatum[key] = value + + else: + warnings.warn( + f"Ignoring '{key}' metadata because of its type ({type(value)}). Only str and int are supported for now.", + category=UserWarning, + ) + + metadata.append(metadatum) + + # reset list of file-scoped labels + file_unique_labels = list() + + # path to audio file + audios.append(str(file["audio"])) + + # audio info + audio_info = file["torchaudio.info"] + audio_infos.append( + ( + audio_info.sample_rate, # sample rate + audio_info.num_frames, # number of frames + audio_info.num_channels, # number of channels + audio_info.bits_per_sample, # bits per sample + ) + ) + audio_encodings.append(audio_info.encoding) # encoding + + # annotated regions and duration + _annotated_duration = 0.0 + for segment in file["annotated"]: + # skip annotated regions that are shorter than training chunk duration + if segment.duration < self.duration: + continue + + # append annotated region + annotated_region = ( + file_id, + segment.duration, + segment.start, + ) + annotated_regions.append(annotated_region) + + # increment annotated duration + _annotated_duration += segment.duration + + # append annotated duration + annotated_duration.append(_annotated_duration) + + # annotations + for segment, _, label in file["annotation"].itertracks(yield_label=True): + # "scope" is provided by speaker diarization protocols to indicate + # whether speaker labels are local to the file ('file'), consistent across + # all files in a database ('database'), or globally consistent ('global') + + # 0 = 'file' / 1 = 'database' / 2 = 'global' + scope = Scopes.index(file["scope"]) + + # update list of file-scope labels + if label not in file_unique_labels: + file_unique_labels.append(label) + # and convert label to its (file-scope) index + file_label_idx = file_unique_labels.index(label) + + database_label_idx = global_label_idx = -1 + + if scope > 0: # 'database' or 'global' + # update list of database-scope labels + database = file["database"] + if database not in database_unique_labels: + database_unique_labels[database] = [] + if label not in database_unique_labels[database]: + database_unique_labels[database].append(label) + + # and convert label to its (database-scope) index + database_label_idx = database_unique_labels[database].index(label) + + if scope > 1: # 'global' + # update list of global-scope labels + if label not in unique_labels: + unique_labels.append(label) + # and convert label to its (global-scope) index + global_label_idx = unique_labels.index(label) + + annotations.append( + ( + file_id, # index of file + segment.start, # start time + segment.end, # end time + file_label_idx, # file-scope label index + database_label_idx, # database-scope label index + global_label_idx, # global-scope index + ) + ) + + # since not all metadata keys are present in all files, fallback to -1 when a key is missing + metadata = [ + tuple(metadatum.get(key, -1) for key in metadata_unique_values) + for metadatum in metadata + ] + metadata_dtype = [ + (key, get_dtype(max(m[i] for m in metadata))) + for i, key in enumerate(metadata_unique_values) + ] + + # turn list of files metadata into a single numpy array + # TODO: improve using https://github.com/pytorch/pytorch/issues/13246#issuecomment-617140519 + info_dtype = [ + ( + "sample_rate", + get_dtype(max(ai[0] for ai in audio_infos)), + ), + ( + "num_frames", + get_dtype(max(ai[1] for ai in audio_infos)), + ), + ("num_channels", "B"), + ("bits_per_sample", "B"), + ] + + # turn list of annotated regions into a single numpy array + region_dtype = [ + ( + "file_id", + get_dtype(max(ar[0] for ar in annotated_regions)), + ), + ("duration", "f"), + ("start", "f"), + ] + + # turn list of annotations into a single numpy array + segment_dtype = [ + ( + "file_id", + get_dtype(max(a[0] for a in annotations)), + ), + ("start", "f"), + ("end", "f"), + ("file_label_idx", get_dtype(max(a[3] for a in annotations))), + ("database_label_idx", get_dtype(max(a[4] for a in annotations))), + ("global_label_idx", get_dtype(max(a[5] for a in annotations))), + ] + + # save all protocol data in a dict + prepared_data = {} + + # keep track of protocol name + prepared_data["protocol"] = self.protocol.name + + prepared_data["audio-path"] = np.array(audios, dtype=np.str_) + audios.clear() + + prepared_data["audio-metadata"] = np.array(metadata, dtype=metadata_dtype) + metadata.clear() + + prepared_data["audio-info"] = np.array(audio_infos, dtype=info_dtype) + audio_infos.clear() + + prepared_data["audio-encoding"] = np.array(audio_encodings, dtype=np.str_) + audio_encodings.clear() + + prepared_data["audio-annotated"] = np.array(annotated_duration) + annotated_duration.clear() + + prepared_data["annotations-regions"] = np.array( + annotated_regions, dtype=region_dtype + ) + annotated_regions.clear() + + prepared_data["annotations-segments"] = np.array( + annotations, dtype=segment_dtype + ) + annotations.clear() + + prepared_data["metadata-values"] = metadata_unique_values + + for database, labels in database_unique_labels.items(): + prepared_data[f"metadata-{database}-labels"] = np.array( + labels, dtype=np.str_ + ) + database_unique_labels.clear() + + prepared_data["metadata-labels"] = np.array(unique_labels, dtype=np.str_) + unique_labels.clear() + + self.prepare_validation(prepared_data) + self.post_prepare_data(prepared_data) + + # save prepared data on the disk + with open(self.cache, "wb") as cache_file: + np.savez_compressed(cache_file, **prepared_data) + + def post_prepare_data(self, prepared_data: Dict): + """Method for completing `prepared_data` with task-specific data. + For instance, for a classification task, this could be a list of + possible classes. + + Parameters + ---------- + prepared_data: dict + dictionnary containing protocol data prepared by + `prepare_data()` + Note + ---- + This method does not return anything. Thus, user have to directly modify + `prepared_data`, for updates to be taken into account """ pass + def setup(self, stage=None): + """Setup data cached by prepare_data into the task on each device""" + + # send cache path on all processes used for the training, + # allowing them to access the cache generated by prepare_data + if stage == "fit": + self.cache = self.trainer.strategy.broadcast(self.cache) + + try: + with open(self.cache, "rb") as cache_file: + self.prepared_data = dict(np.load(cache_file, allow_pickle=True)) + except FileNotFoundError: + print( + "Cached data for protocol not found. Ensure that prepare_data() was called", + " and executed correctly or/and that the path to the task cache is correct.", + ) + raise + + # checks that the task current protocol matches the cached protocol + if self.protocol.name != self.prepared_data["protocol"]: + raise ValueError( + f"Protocol specified for the task ({self.protocol.name}) " + f"does not correspond to the cached one ({self.prepared_data['protocol']})" + ) + @property def specifications(self) -> Union[Specifications, Tuple[Specifications]]: # setup metadata on-demand the first time specifications are requested and missing if not hasattr(self, "_specifications"): - self.setup_metadata() + raise UnknownSpecificationsError( + "Task specifications are not available. This is most likely because they depend on " + "the content of the training subset. Use `task.prepare_data()` and `task.setup()` " + "to go over the training subset and fix this, or let lightning trainer do that for you in `trainer.fit(model)`." + ) return self._specifications @specifications.setter @@ -281,29 +659,6 @@ def specifications( ): self._specifications = specifications - @property - def has_setup_metadata(self): - return getattr(self, "_has_setup_metadata", False) - - @has_setup_metadata.setter - def has_setup_metadata(self, value: bool): - self._has_setup_metadata = value - - def setup_metadata(self): - """Called at the beginning of training at the very beginning of Model.setup(stage="fit") - - Notes - ----- - This hook is called on every process when using DDP. - - If `specifications` attribute has not been set in `__init__`, - `setup` is your last chance to set it. - """ - - if not self.has_setup_metadata: - self.setup() - self.has_setup_metadata = True - def setup_loss_func(self): pass diff --git a/pyannote/audio/models/blocks/pooling.py b/pyannote/audio/models/blocks/pooling.py index 22d736a03..dc31bea8e 100644 --- a/pyannote/audio/models/blocks/pooling.py +++ b/pyannote/audio/models/blocks/pooling.py @@ -26,53 +26,53 @@ import torch import torch.nn as nn import torch.nn.functional as F -from einops import rearrange -class StatsPool(nn.Module): - """Statistics pooling +def _pool(sequences: torch.Tensor, weights: torch.Tensor) -> torch.Tensor: + """Helper function to compute statistics pooling - Compute temporal mean and (unbiased) standard deviation - and returns their concatenation. + Assumes that weights are already interpolated to match the number of frames + in sequences and that they encode the activation of only one speaker. - Reference - --------- - https://en.wikipedia.org/wiki/Weighted_arithmetic_mean + Parameters + ---------- + sequences : (batch, features, frames) torch.Tensor + Sequences of features. + weights : (batch, frames) torch.Tensor + (Already interpolated) weights. + Returns + ------- + output : (batch, 2 * features) torch.Tensor + Concatenation of mean and (unbiased) standard deviation. """ - def _pool(self, sequences: torch.Tensor, weights: torch.Tensor) -> torch.Tensor: - """Helper function to compute statistics pooling + weights = weights.unsqueeze(dim=1) + # (batch, 1, frames) - Assumes that weights are already interpolated to match the number of frames - in sequences and that they encode the activation of only one speaker. + v1 = weights.sum(dim=2) + 1e-8 + mean = torch.sum(sequences * weights, dim=2) / v1 - Parameters - ---------- - sequences : (batch, features, frames) torch.Tensor - Sequences of features. - weights : (batch, frames) torch.Tensor - (Already interpolated) weights. + dx2 = torch.square(sequences - mean.unsqueeze(2)) + v2 = torch.square(weights).sum(dim=2) - Returns - ------- - output : (batch, 2 * features) torch.Tensor - Concatenation of mean and (unbiased) standard deviation. - """ + var = torch.sum(dx2 * weights, dim=2) / (v1 - v2 / v1 + 1e-8) + std = torch.sqrt(var) - weights = weights.unsqueeze(dim=1) - # (batch, 1, frames) + return torch.cat([mean, std], dim=1) - v1 = weights.sum(dim=2) + 1e-8 - mean = torch.sum(sequences * weights, dim=2) / v1 - dx2 = torch.square(sequences - mean.unsqueeze(2)) - v2 = torch.square(weights).sum(dim=2) +class StatsPool(nn.Module): + """Statistics pooling - var = torch.sum(dx2 * weights, dim=2) / (v1 - v2 / v1 + 1e-8) - std = torch.sqrt(var) + Compute temporal mean and (unbiased) standard deviation + and returns their concatenation. - return torch.cat([mean, std], dim=1) + Reference + --------- + https://en.wikipedia.org/wiki/Weighted_arithmetic_mean + + """ def forward( self, sequences: torch.Tensor, weights: Optional[torch.Tensor] = None @@ -112,17 +112,20 @@ def forward( has_speaker_dimension = True # interpolate weights if needed - _, _, num_frames = sequences.shape - _, _, num_weights = weights.shape + _, _, num_frames = sequences.size() + _, num_speakers, num_weights = weights.size() if num_frames != num_weights: warnings.warn( f"Mismatch between frames ({num_frames}) and weights ({num_weights}) numbers." ) weights = F.interpolate(weights, size=num_frames, mode="nearest") - output = rearrange( - torch.vmap(self._pool, in_dims=(None, 1))(sequences, weights), - "speakers batch features -> batch speakers features", + output = torch.stack( + [ + _pool(sequences, weights[:, speaker, :]) + for speaker in range(num_speakers) + ], + dim=1, ) if not has_speaker_dimension: diff --git a/pyannote/audio/models/blocks/sincnet.py b/pyannote/audio/models/blocks/sincnet.py index 65bd6e57f..2a085201c 100644 --- a/pyannote/audio/models/blocks/sincnet.py +++ b/pyannote/audio/models/blocks/sincnet.py @@ -1,6 +1,6 @@ # The MIT License (MIT) # -# Copyright (c) 2019-2020 CNRS +# Copyright (c) 2019- CNRS # # Permission is hereby granted, free of charge, to any person obtaining a copy # of this software and associated documentation files (the "Software"), to deal @@ -23,22 +23,30 @@ # AUTHOR # Hervé Bredin - http://herve.niderb.fr +from functools import lru_cache import torch import torch.nn as nn import torch.nn.functional as F from asteroid_filterbanks import Encoder, ParamSincFB +from pyannote.audio.utils.receptive_field import ( + multi_conv_num_frames, + multi_conv_receptive_field_center, + multi_conv_receptive_field_size, +) + class SincNet(nn.Module): def __init__(self, sample_rate: int = 16000, stride: int = 1): super().__init__() if sample_rate != 16000: - raise NotImplementedError("PyanNet only supports 16kHz audio for now.") + raise NotImplementedError("SincNet only supports 16kHz audio for now.") # TODO: add support for other sample rate. it should be enough to multiply # kernel_size by (sample_rate / 16000). but this needs to be double-checked. + self.sample_rate = sample_rate self.stride = stride self.wav_norm1d = nn.InstanceNorm1d(1, affine=True) @@ -70,6 +78,88 @@ def __init__(self, sample_rate: int = 16000, stride: int = 1): self.pool1d.append(nn.MaxPool1d(3, stride=3, padding=0, dilation=1)) self.norm1d.append(nn.InstanceNorm1d(60, affine=True)) + @lru_cache + def num_frames(self, num_samples: int) -> int: + """Compute number of output frames + + Parameters + ---------- + num_samples : int + Number of input samples. + + Returns + ------- + num_frames : int + Number of output frames. + """ + + kernel_size = [251, 3, 5, 3, 5, 3] + stride = [self.stride, 3, 1, 3, 1, 3] + padding = [0, 0, 0, 0, 0, 0] + dilation = [1, 1, 1, 1, 1, 1] + + return multi_conv_num_frames( + num_samples, + kernel_size=kernel_size, + stride=stride, + padding=padding, + dilation=dilation, + ) + + def receptive_field_size(self, num_frames: int = 1) -> int: + """Compute size of receptive field + + Parameters + ---------- + num_frames : int, optional + Number of frames in the output signal + + Returns + ------- + receptive_field_size : int + Receptive field size. + """ + + kernel_size = [251, 3, 5, 3, 5, 3] + stride = [self.stride, 3, 1, 3, 1, 3] + padding = [0, 0, 0, 0, 0, 0] + dilation = [1, 1, 1, 1, 1, 1] + + return multi_conv_receptive_field_size( + num_frames, + kernel_size=kernel_size, + stride=stride, + padding=padding, + dilation=dilation, + ) + + def receptive_field_center(self, frame: int = 0) -> int: + """Compute center of receptive field + + Parameters + ---------- + frame : int, optional + Frame index + + Returns + ------- + receptive_field_center : int + Index of receptive field center. + """ + + kernel_size = [251, 3, 5, 3, 5, 3] + stride = [self.stride, 3, 1, 3, 1, 3] + padding = [0, 0, 0, 0, 0, 0] + dilation = [1, 1, 1, 1, 1, 1] + + return multi_conv_receptive_field_center( + frame, + kernel_size=kernel_size, + stride=stride, + padding=padding, + dilation=dilation, + ) + def forward(self, waveforms: torch.Tensor) -> torch.Tensor: """Pass forward @@ -83,7 +173,6 @@ def forward(self, waveforms: torch.Tensor) -> torch.Tensor: for c, (conv1d, pool1d, norm1d) in enumerate( zip(self.conv1d, self.pool1d, self.norm1d) ): - outputs = conv1d(outputs) # https://github.com/mravanelli/SincNet/issues/4 diff --git a/pyannote/audio/models/embedding/debug.py b/pyannote/audio/models/embedding/debug.py index 11b3def30..b09283908 100644 --- a/pyannote/audio/models/embedding/debug.py +++ b/pyannote/audio/models/embedding/debug.py @@ -1,6 +1,6 @@ # MIT License # -# Copyright (c) 2020 CNRS +# Copyright (c) 2020- CNRS # # Permission is hereby granted, free of charge, to any person obtaining a copy # of this software and associated documentation files (the "Software"), to deal @@ -21,6 +21,7 @@ # SOFTWARE. +from functools import lru_cache from typing import Optional import torch @@ -39,7 +40,6 @@ def __init__( num_channels: int = 1, task: Optional[Task] = None, ): - super().__init__(sample_rate=sample_rate, num_channels=num_channels, task=task) self.mfcc = MFCC( @@ -58,6 +58,81 @@ def __init__( bidirectional=True, ) + @lru_cache + def num_frames(self, num_samples: int) -> int: + """Compute number of output frames for a given number of input samples + + Parameters + ---------- + num_samples : int + Number of input samples + + Returns + ------- + num_frames : int + Number of output frames + + Source + ------ + https://pytorch.org/docs/stable/generated/torch.stft.html#torch.stft + + """ + + hop_length = self.mfcc.MelSpectrogram.spectrogram.hop_length + n_fft = self.mfcc.MelSpectrogram.spectrogram.n_fft + center = self.mfcc.MelSpectrogram.spectrogram.center + + if center: + return 1 + num_samples // hop_length + else: + return 1 + (num_samples - n_fft) // hop_length + + def receptive_field_size(self, num_frames: int = 1) -> int: + """Compute size of receptive field + + Parameters + ---------- + num_frames : int, optional + Number of frames in the output signal + + Returns + ------- + receptive_field_size : int + Receptive field size. + """ + + hop_length = self.mfcc.MelSpectrogram.spectrogram.hop_length + n_fft = self.mfcc.MelSpectrogram.spectrogram.n_fft + return n_fft + (num_frames - 1) * hop_length + + def receptive_field_center(self, frame: int = 0) -> int: + """Compute center of receptive field + + Parameters + ---------- + frame : int, optional + Frame index + + Returns + ------- + receptive_field_center : int + Index of receptive field center. + """ + + hop_length = self.mfcc.MelSpectrogram.spectrogram.hop_length + n_fft = self.mfcc.MelSpectrogram.spectrogram.n_fft + center = self.mfcc.MelSpectrogram.spectrogram.center + + if center: + return frame * hop_length + else: + return frame * hop_length + n_fft // 2 + + @property + def dimension(self) -> int: + """Dimension of output""" + return 64 + def forward(self, waveforms: torch.Tensor) -> torch.Tensor: """ diff --git a/pyannote/audio/models/embedding/wespeaker/__init__.py b/pyannote/audio/models/embedding/wespeaker/__init__.py index 603a88c64..be51196c1 100644 --- a/pyannote/audio/models/embedding/wespeaker/__init__.py +++ b/pyannote/audio/models/embedding/wespeaker/__init__.py @@ -21,29 +21,52 @@ # SOFTWARE. -from functools import partial +from functools import lru_cache, partial from typing import Optional import torch +import torch.nn.functional as F import torchaudio.compliance.kaldi as kaldi from pyannote.audio.core.model import Model from pyannote.audio.core.task import Task +from pyannote.audio.utils.receptive_field import ( + conv1d_num_frames, + conv1d_receptive_field_center, + conv1d_receptive_field_size, +) from .resnet import ResNet34, ResNet152, ResNet221, ResNet293 class BaseWeSpeakerResNet(Model): + """Base class for WeSpeaker's ResNet models + + Parameters + ---------- + fbank_centering_span : float, optional + Span of the fbank centering window (in seconds). + Defaults (None) to use whole input. + + See also + -------- + torchaudio.compliance.kaldi.fbank + + """ + def __init__( self, sample_rate: int = 16000, num_channels: int = 1, num_mel_bins: int = 80, - frame_length: int = 25, - frame_shift: int = 10, + frame_length: float = 25.0, # in milliseconds + frame_shift: float = 10.0, # in milliseconds + round_to_power_of_two: bool = True, + snip_edges: bool = True, dither: float = 0.0, window_type: str = "hamming", use_energy: bool = False, + fbank_centering_span: Optional[float] = None, task: Optional[Task] = None, ): super().__init__(sample_rate=sample_rate, num_channels=num_channels, task=task) @@ -55,21 +78,38 @@ def __init__( "frame_length", "frame_shift", "dither", + "round_to_power_of_two", + "snip_edges", "window_type", "use_energy", + "fbank_centering_span", ) self._fbank = partial( kaldi.fbank, num_mel_bins=self.hparams.num_mel_bins, frame_length=self.hparams.frame_length, + round_to_power_of_two=self.hparams.round_to_power_of_two, frame_shift=self.hparams.frame_shift, + snip_edges=self.hparams.snip_edges, dither=self.hparams.dither, sample_frequency=self.hparams.sample_rate, window_type=self.hparams.window_type, use_energy=self.hparams.use_energy, ) + @property + def fbank_only(self) -> bool: + """Whether to only extract fbank features""" + return getattr(self, "_fbank_only", False) + + @fbank_only.setter + def fbank_only(self, value: bool): + if hasattr(self, "receptive_field"): + del self.receptive_field + + self._fbank_only = value + def compute_fbank(self, waveforms: torch.Tensor) -> torch.Tensor: """Extract fbank features @@ -80,6 +120,7 @@ def compute_fbank(self, waveforms: torch.Tensor) -> torch.Tensor: Returns ------- fbank : (batch_size, num_frames, num_mel_bins) + fbank features Source: https://github.com/wenet-e2e/wespeaker/blob/45941e7cba2c3ea99e232d02bedf617fc71b0dad/wespeaker/bin/infer_onnx.py#L30C1-L50 """ @@ -93,19 +134,209 @@ def compute_fbank(self, waveforms: torch.Tensor) -> torch.Tensor: features = torch.vmap(self._fbank)(waveforms.to(fft_device)).to(device) - return features - torch.mean(features, dim=1, keepdim=True) + # center features with global average + if self.hparams.fbank_centering_span is None: + return features - torch.mean(features, dim=1, keepdim=True) + + # center features with running average + window_size = int(self.hparams.sample_rate * self.hparams.frame_length * 0.001) + step_size = int(self.hparams.sample_rate * self.hparams.frame_shift * 0.001) + kernel_size = conv1d_num_frames( + num_samples=int( + self.hparams.fbank_centering_span * self.hparams.sample_rate + ), + kernel_size=window_size, + stride=step_size, + padding=0, + dilation=1, + ) + return features - F.avg_pool1d( + features.transpose(1, 2), + kernel_size=2 * (kernel_size // 2) + 1, + stride=1, + padding=kernel_size // 2, + count_include_pad=False, + ).transpose(1, 2) + + @property + def dimension(self) -> int: + """Dimension of output""" + + if self.fbank_only: + return self.hparams.num_mel_bins + + return self.resnet.embed_dim + + @lru_cache + def num_frames(self, num_samples: int) -> int: + """Compute number of output frames + + Parameters + ---------- + num_samples : int + Number of input samples. + + Returns + ------- + num_frames : int + Number of output frames. + """ + window_size = int(self.hparams.sample_rate * self.hparams.frame_length * 0.001) + step_size = int(self.hparams.sample_rate * self.hparams.frame_shift * 0.001) + + # TODO: take round_to_power_of_two and snip_edges into account + + num_frames = conv1d_num_frames( + num_samples=num_samples, + kernel_size=window_size, + stride=step_size, + padding=0, + dilation=1, + ) + + if self.fbank_only: + return num_frames + + return self.resnet.num_frames(num_frames) + + def receptive_field_size(self, num_frames: int = 1) -> int: + """Compute size of receptive field + + Parameters + ---------- + num_frames : int, optional + Number of frames in the output signal + + Returns + ------- + receptive_field_size : int + Receptive field size. + """ + + receptive_field_size = num_frames + + if not self.fbank_only: + receptive_field_size = self.resnet.receptive_field_size( + receptive_field_size + ) + + window_size = int(self.hparams.sample_rate * self.hparams.frame_length * 0.001) + step_size = int(self.hparams.sample_rate * self.hparams.frame_shift * 0.001) + + return conv1d_receptive_field_size( + num_frames=receptive_field_size, + kernel_size=window_size, + stride=step_size, + padding=0, + dilation=1, + ) + + def receptive_field_center(self, frame: int = 0) -> int: + """Compute center of receptive field + + Parameters + ---------- + frame : int, optional + Frame index + + Returns + ------- + receptive_field_center : int + Index of receptive field center. + """ + receptive_field_center = frame + + if not self.fbank_only: + receptive_field_center = self.resnet.receptive_field_center( + frame=receptive_field_center + ) + + window_size = int(self.hparams.sample_rate * self.hparams.frame_length * 0.001) + step_size = int(self.hparams.sample_rate * self.hparams.frame_shift * 0.001) + return conv1d_receptive_field_center( + frame=receptive_field_center, + kernel_size=window_size, + stride=step_size, + padding=0, + dilation=1, + ) def forward( - self, waveforms: torch.Tensor, weights: torch.Tensor = None + self, waveforms: torch.Tensor, weights: Optional[torch.Tensor] = None ) -> torch.Tensor: + """Extract speaker embeddings + + Parameters + ---------- + waveforms : torch.Tensor + Batch of waveforms with shape (batch, channel, sample) + weights : (batch, frames) or (batch, speakers, frames) torch.Tensor, optional + Batch of weights passed to statistics pooling layer. + + Returns + ------- + embeddings : (batch, dimension) or (batch, speakers, dimension) torch.Tensor + Batch of embeddings. """ + fbank = self.compute_fbank(waveforms) + if self.fbank_only: + return fbank + + return self.resnet(fbank, weights=weights)[1] + + def forward_frames(self, waveforms: torch.Tensor) -> torch.Tensor: + """Extract frame-wise embeddings + Parameters ---------- waveforms : torch.Tensor Batch of waveforms with shape (batch, channel, sample) - weights : torch.Tensor, optional - Batch of weights with shape (batch, frame). + + Returns + ------- + embeddings : (batch, ..., embedding_frames) torch.Tensor + Batch of frame-wise embeddings. + """ + fbank = self.compute_fbank(waveforms) + return self.resnet.forward_frames(fbank) + + def forward_embedding( + self, frames: torch.Tensor, weights: torch.Tensor = None + ) -> torch.Tensor: + """Extract speaker embeddings from frame-wise embeddings + + Parameters + ---------- + frames : torch.Tensor + Batch of frames with shape (batch, ..., embedding_frames). + weights : (batch, frames) or (batch, speakers, frames) torch.Tensor, optional + Batch of weights passed to statistics pooling layer. + + Returns + ------- + embeddings : (batch, dimension) or (batch, speakers, dimension) torch.Tensor + Batch of embeddings. + + """ + return self.resnet.forward_embedding(frames, weights=weights)[1] + + def forward( + self, waveforms: torch.Tensor, weights: Optional[torch.Tensor] = None + ) -> torch.Tensor: + """Extract speaker embeddings + + Parameters + ---------- + waveforms : torch.Tensor + Batch of waveforms with shape (batch, channel, sample) + weights : (batch, frames) or (batch, speakers, frames) torch.Tensor, optional + Batch of weights passed to statistics pooling layer. + + Returns + ------- + embeddings : (batch, dimension) or (batch, speakers, dimension) torch.Tensor + Batch of embeddings. """ fbank = self.compute_fbank(waveforms) diff --git a/pyannote/audio/models/embedding/wespeaker/resnet.py b/pyannote/audio/models/embedding/wespeaker/resnet.py index 54f95fa8b..4c9d5a5f0 100644 --- a/pyannote/audio/models/embedding/wespeaker/resnet.py +++ b/pyannote/audio/models/embedding/wespeaker/resnet.py @@ -15,12 +15,23 @@ # See the License for the specific language governing permissions and # limitations under the License. +from functools import lru_cache +from typing import Optional + import torch import torch.nn as nn import torch.nn.functional as F from einops import rearrange from pyannote.audio.models.blocks.pooling import StatsPool +from pyannote.audio.utils.receptive_field import ( + conv1d_num_frames, + conv1d_receptive_field_center, + conv1d_receptive_field_size, + multi_conv_num_frames, + multi_conv_receptive_field_center, + multi_conv_receptive_field_size, +) class TSTP(nn.Module): @@ -35,7 +46,7 @@ def __init__(self, in_dim=0, **kwargs): self.in_dim = in_dim self.stats_pool = StatsPool() - def forward(self, features, weights: torch.Tensor = None): + def forward(self, features, weights: Optional[torch.Tensor] = None): """ Parameters @@ -75,6 +86,7 @@ class BasicBlock(nn.Module): def __init__(self, in_planes, planes, stride=1): super(BasicBlock, self).__init__() + self.stride = stride self.conv1 = nn.Conv2d( in_planes, planes, kernel_size=3, stride=stride, padding=1, bias=False ) @@ -97,6 +109,34 @@ def __init__(self, in_planes, planes, stride=1): nn.BatchNorm2d(self.expansion * planes), ) + @lru_cache + def num_frames(self, num_samples: int) -> int: + return multi_conv_num_frames( + num_samples, + kernel_size=[3, 3], + stride=[self.stride, 1], + padding=[1, 1], + dilation=[1, 1], + ) + + def receptive_field_size(self, num_frames: int = 1) -> int: + return multi_conv_receptive_field_size( + num_frames, + kernel_size=[3, 3], + stride=[self.stride, 1], + padding=[1, 1], + dilation=[1, 1], + ) + + def receptive_field_center(self, frame: int = 0) -> int: + return multi_conv_receptive_field_center( + frame, + kernel_size=[3, 3], + stride=[self.stride, 1], + padding=[1, 1], + dilation=[1, 1], + ) + def forward(self, x): out = F.relu(self.bn1(self.conv1(x))) out = self.bn2(self.conv2(out)) @@ -110,6 +150,7 @@ class Bottleneck(nn.Module): def __init__(self, in_planes, planes, stride=1): super(Bottleneck, self).__init__() + self.stride = stride self.conv1 = nn.Conv2d(in_planes, planes, kernel_size=1, bias=False) self.bn1 = nn.BatchNorm2d(planes) self.conv2 = nn.Conv2d( @@ -134,6 +175,34 @@ def __init__(self, in_planes, planes, stride=1): nn.BatchNorm2d(self.expansion * planes), ) + @lru_cache + def num_frames(self, num_samples: int) -> int: + return multi_conv_num_frames( + num_samples, + kernel_size=[1, 3, 1], + stride=[1, self.stride, 1], + padding=[0, 1, 0], + dilation=[1, 1, 1], + ) + + def receptive_field_size(self, num_frames: int = 1) -> int: + return multi_conv_receptive_field_size( + num_frames, + kernel_size=[1, 3, 1], + stride=[1, self.stride, 1], + padding=[0, 1, 0], + dilation=[1, 1, 1], + ) + + def receptive_field_center(self, frame: int = 0) -> int: + return multi_conv_receptive_field_center( + frame, + kernel_size=[1, 3, 1], + stride=[1, self.stride, 1], + padding=[0, 1, 0], + dilation=[1, 1, 1], + ) + def forward(self, x): out = F.relu(self.bn1(self.conv1(x))) out = F.relu(self.bn2(self.conv2(out))) @@ -190,12 +259,149 @@ def _make_layer(self, block, planes, num_blocks, stride): self.in_planes = planes * block.expansion return nn.Sequential(*layers) - def forward(self, x: torch.Tensor, weights: torch.Tensor = None): + @lru_cache + def num_frames(self, num_samples: int) -> int: + """Compute number of output frames + + Parameters + ---------- + num_samples : int + Number of input samples. + + Returns + ------- + num_frames : int + Number of output frames. + """ + + num_frames = num_samples + num_frames = conv1d_num_frames( + num_frames, kernel_size=3, stride=1, padding=1, dilation=1 + ) + for layers in [self.layer1, self.layer2, self.layer3, self.layer4]: + for layer in layers: + num_frames = layer.num_frames(num_frames) + + return num_frames + + def receptive_field_size(self, num_frames: int = 1) -> int: + """Compute size of receptive field + + Parameters + ---------- + num_frames : int, optional + Number of frames in the output signal + + Returns + ------- + receptive_field_size : int + Receptive field size. """ + receptive_field_size = num_frames + for layers in reversed([self.layer1, self.layer2, self.layer3, self.layer4]): + for layer in reversed(layers): + receptive_field_size = layer.receptive_field_size(receptive_field_size) + + receptive_field_size = conv1d_receptive_field_size( + num_frames=receptive_field_size, + kernel_size=3, + stride=1, + padding=1, + dilation=1, + ) + + return receptive_field_size + + def receptive_field_center(self, frame: int = 0) -> int: + """Compute center of receptive field + Parameters ---------- - x : (batch, frames, features) torch.Tensor + frame : int, optional + Frame index + + Returns + ------- + receptive_field_center : int + Index of receptive field center. + """ + + receptive_field_center = frame + for layers in reversed([self.layer1, self.layer2, self.layer3, self.layer4]): + for layer in reversed(layers): + receptive_field_center = layer.receptive_field_center( + frame=receptive_field_center + ) + + receptive_field_center = conv1d_receptive_field_center( + frame=receptive_field_center, + kernel_size=3, + stride=1, + padding=1, + dilation=1, + ) + + return receptive_field_center + + def forward_frames(self, fbank: torch.Tensor) -> torch.Tensor: + """Extract frame-wise embeddings + + Parameters + ---------- + fbanks : (batch, frames, features) torch.Tensor + Batch of fbank features + + Returns + ------- + embeddings : (batch, ..., embedding_frames) torch.Tensor + Batch of frame-wise embeddings. + + """ + fbank = fbank.permute(0, 2, 1) # (B,T,F) => (B,F,T) + fbank = fbank.unsqueeze_(1) + out = F.relu(self.bn1(self.conv1(fbank))) + out = self.layer1(out) + out = self.layer2(out) + out = self.layer3(out) + out = self.layer4(out) + return out + + def forward_embedding( + self, frames: torch.Tensor, weights: torch.Tensor = None + ) -> torch.Tensor: + """Extract speaker embeddings + + Parameters + ---------- + frames : torch.Tensor + Batch of frames with shape (batch, ..., embedding_frames). + weights : (batch, frames) or (batch, speakers, frames) torch.Tensor, optional + Batch of weights passed to statistics pooling layer. + + Returns + ------- + embeddings : (batch, dimension) or (batch, speakers, dimension) torch.Tensor + Batch of embeddings. + """ + + stats = self.pool(frames, weights=weights) + + embed_a = self.seg_1(stats) + if self.two_emb_layer: + out = F.relu(embed_a) + out = self.seg_bn_1(out) + embed_b = self.seg_2(out) + return embed_a, embed_b + else: + return torch.tensor(0.0), embed_a + + def forward(self, fbank: torch.Tensor, weights: Optional[torch.Tensor] = None): + """Extract speaker embeddings + + Parameters + ---------- + fbank : (batch, frames, features) torch.Tensor Batch of features weights : (batch, frames) torch.Tensor, optional Batch of weights @@ -204,10 +410,9 @@ def forward(self, x: torch.Tensor, weights: torch.Tensor = None): ------- embedding : (batch, embedding_dim) torch.Tensor """ - x = x.permute(0, 2, 1) # (B,T,F) => (B,F,T) - - x = x.unsqueeze_(1) - out = F.relu(self.bn1(self.conv1(x))) + fbank = fbank.permute(0, 2, 1) # (B,T,F) => (B,F,T) + fbank = fbank.unsqueeze_(1) + out = F.relu(self.bn1(self.conv1(fbank))) out = self.layer1(out) out = self.layer2(out) out = self.layer3(out) diff --git a/pyannote/audio/models/embedding/xvector.py b/pyannote/audio/models/embedding/xvector.py index 975f0a991..3161876e3 100644 --- a/pyannote/audio/models/embedding/xvector.py +++ b/pyannote/audio/models/embedding/xvector.py @@ -20,6 +20,7 @@ # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE # SOFTWARE. +from functools import lru_cache from typing import Optional import torch @@ -31,17 +32,21 @@ from pyannote.audio.models.blocks.pooling import StatsPool from pyannote.audio.models.blocks.sincnet import SincNet from pyannote.audio.utils.params import merge_dict +from pyannote.audio.utils.receptive_field import ( + multi_conv_num_frames, + multi_conv_receptive_field_center, + multi_conv_receptive_field_size, +) class XVectorMFCC(Model): - MFCC_DEFAULTS = {"n_mfcc": 40, "dct_type": 2, "norm": "ortho", "log_mels": False} def __init__( self, sample_rate: int = 16000, num_channels: int = 1, - mfcc: dict = None, + mfcc: Optional[dict] = None, dimension: int = 512, task: Optional[Task] = None, ): @@ -57,11 +62,13 @@ def __init__( self.tdnns = nn.ModuleList() in_channel = self.hparams.mfcc["n_mfcc"] out_channels = [512, 512, 512, 512, 1500] - kernel_sizes = [5, 3, 3, 1, 1] - dilations = [1, 2, 3, 1, 1] + self.kernel_size = [5, 3, 3, 1, 1] + self.dilation = [1, 2, 3, 1, 1] + self.padding = [0, 0, 0, 0, 0] + self.stride = [1, 1, 1, 1, 1] for out_channel, kernel_size, dilation in zip( - out_channels, kernel_sizes, dilations + out_channels, self.kernel_size, self.dilation ): self.tdnns.extend( [ @@ -81,8 +88,102 @@ def __init__( self.embedding = nn.Linear(in_channel * 2, self.hparams.dimension) + @property + def dimension(self) -> int: + """Dimension of output""" + return self.hparams.dimension + + @lru_cache + def num_frames(self, num_samples: int) -> int: + """Compute number of output frames + + Parameters + ---------- + num_samples : int + Number of input samples. + + Returns + ------- + num_frames : int + Number of output frames. + """ + + hop_length = self.mfcc.MelSpectrogram.spectrogram.hop_length + n_fft = self.mfcc.MelSpectrogram.spectrogram.n_fft + center = self.mfcc.MelSpectrogram.spectrogram.center + + if center: + num_frames = 1 + num_samples // hop_length + else: + num_frames = 1 + (num_samples - n_fft) // hop_length + + return multi_conv_num_frames( + num_frames, + kernel_size=self.kernel_size, + stride=self.stride, + padding=self.padding, + dilation=self.dilation, + ) + + def receptive_field_size(self, num_frames: int = 1) -> int: + """Compute size of receptive field + + Parameters + ---------- + num_frames : int, optional + Number of frames in the output signal + + Returns + ------- + receptive_field_size : int + Receptive field size. + """ + + receptive_field_size = multi_conv_receptive_field_size( + num_frames, + kernel_size=self.kernel_size, + stride=self.stride, + padding=self.padding, + dilation=self.dilation, + ) + + hop_length = self.mfcc.MelSpectrogram.spectrogram.hop_length + n_fft = self.mfcc.MelSpectrogram.spectrogram.n_fft + return n_fft + (receptive_field_size - 1) * hop_length + + def receptive_field_center(self, frame: int = 0) -> int: + """Compute center of receptive field + + Parameters + ---------- + frame : int, optional + Frame index + + Returns + ------- + receptive_field_center : int + Index of receptive field center. + """ + + receptive_field_center = multi_conv_receptive_field_center( + frame, + kernel_size=self.kernel_size, + stride=self.stride, + padding=self.padding, + dilation=self.dilation, + ) + + hop_length = self.mfcc.MelSpectrogram.spectrogram.hop_length + n_fft = self.mfcc.MelSpectrogram.spectrogram.n_fft + center = self.mfcc.MelSpectrogram.spectrogram.center + + if center: + return receptive_field_center * hop_length + else: + return receptive_field_center * hop_length + n_fft // 2 + def forward( - self, waveforms: torch.Tensor, weights: torch.Tensor = None + self, waveforms: torch.Tensor, weights: Optional[torch.Tensor] = None ) -> torch.Tensor: """ @@ -102,14 +203,13 @@ def forward( class XVectorSincNet(Model): - SINCNET_DEFAULTS = {"stride": 10} def __init__( self, sample_rate: int = 16000, num_channels: int = 1, - sincnet: dict = None, + sincnet: Optional[dict] = None, dimension: int = 512, task: Optional[Task] = None, ): @@ -125,11 +225,13 @@ def __init__( self.tdnns = nn.ModuleList() out_channels = [512, 512, 512, 512, 1500] - kernel_sizes = [5, 3, 3, 1, 1] - dilations = [1, 2, 3, 1, 1] + self.kernel_size = [5, 3, 3, 1, 1] + self.dilation = [1, 2, 3, 1, 1] + self.padding = [0, 0, 0, 0, 0] + self.stride = [1, 1, 1, 1, 1] for out_channel, kernel_size, dilation in zip( - out_channels, kernel_sizes, dilations + out_channels, self.kernel_size, self.dilation ): self.tdnns.extend( [ @@ -149,8 +251,86 @@ def __init__( self.embedding = nn.Linear(in_channel * 2, self.hparams.dimension) + @property + def dimension(self) -> int: + """Dimension of output""" + return self.hparams.dimension + + @lru_cache + def num_frames(self, num_samples: int) -> int: + """Compute number of output frames + + Parameters + ---------- + num_samples : int + Number of input samples. + + Returns + ------- + num_frames : int + Number of output frames. + """ + + num_frames = self.sincnet.num_frames(num_samples) + + return multi_conv_num_frames( + num_frames, + kernel_size=self.kernel_size, + stride=self.stride, + padding=self.padding, + dilation=self.dilation, + ) + + def receptive_field_size(self, num_frames: int = 1) -> int: + """Compute size of receptive field + + Parameters + ---------- + num_frames : int, optional + Number of frames in the output signal + + Returns + ------- + receptive_field_size : int + Receptive field size. + """ + + receptive_field_size = multi_conv_receptive_field_size( + num_frames, + kernel_size=self.kernel_size, + stride=self.stride, + padding=self.padding, + dilation=self.dilation, + ) + + return self.sincnet.receptive_field_size(num_frames=receptive_field_size) + + def receptive_field_center(self, frame: int = 0) -> int: + """Compute center of receptive field + + Parameters + ---------- + frame : int, optional + Frame index + + Returns + ------- + receptive_field_center : int + Index of receptive field center. + """ + + receptive_field_center = multi_conv_receptive_field_center( + frame, + kernel_size=self.kernel_size, + stride=self.stride, + padding=self.padding, + dilation=self.dilation, + ) + + return self.sincnet.receptive_field_center(frame=receptive_field_center) + def forward( - self, waveforms: torch.Tensor, weights: torch.Tensor = None + self, waveforms: torch.Tensor, weights: Optional[torch.Tensor] = None ) -> torch.Tensor: """ diff --git a/pyannote/audio/models/segmentation/PyanNet.py b/pyannote/audio/models/segmentation/PyanNet.py index 5af3734b1..3481b40c6 100644 --- a/pyannote/audio/models/segmentation/PyanNet.py +++ b/pyannote/audio/models/segmentation/PyanNet.py @@ -20,7 +20,7 @@ # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE # SOFTWARE. - +from functools import lru_cache from typing import Optional import torch @@ -73,9 +73,9 @@ class PyanNet(Model): def __init__( self, - sincnet: dict = None, - lstm: dict = None, - linear: dict = None, + sincnet: Optional[dict] = None, + lstm: Optional[dict] = None, + linear: Optional[dict] = None, sample_rate: int = 16000, num_channels: int = 1, task: Optional[Task] = None, @@ -138,6 +138,17 @@ def __init__( ] ) + @property + def dimension(self) -> int: + """Dimension of output""" + if isinstance(self.specifications, tuple): + raise ValueError("PyanNet does not support multi-tasking.") + + if self.specifications.powerset: + return self.specifications.num_powerset_classes + else: + return len(self.specifications.classes) + def build(self): if self.hparams.linear["num_layers"] > 0: in_features = self.hparams.linear["hidden_size"] @@ -146,16 +157,56 @@ def build(self): 2 if self.hparams.lstm["bidirectional"] else 1 ) - if isinstance(self.specifications, tuple): - raise ValueError("PyanNet does not support multi-tasking.") + self.classifier = nn.Linear(in_features, self.dimension) + self.activation = self.default_activation() - if self.specifications.powerset: - out_features = self.specifications.num_powerset_classes - else: - out_features = len(self.specifications.classes) + @lru_cache + def num_frames(self, num_samples: int) -> int: + """Compute number of output frames for a given number of input samples - self.classifier = nn.Linear(in_features, out_features) - self.activation = self.default_activation() + Parameters + ---------- + num_samples : int + Number of input samples + + Returns + ------- + num_frames : int + Number of output frames + """ + + return self.sincnet.num_frames(num_samples) + + def receptive_field_size(self, num_frames: int = 1) -> int: + """Compute size of receptive field + + Parameters + ---------- + num_frames : int, optional + Number of frames in the output signal + + Returns + ------- + receptive_field_size : int + Receptive field size. + """ + return self.sincnet.receptive_field_size(num_frames=num_frames) + + def receptive_field_center(self, frame: int = 0) -> int: + """Compute center of receptive field + + Parameters + ---------- + frame : int, optional + Frame index + + Returns + ------- + receptive_field_center : int + Index of receptive field center. + """ + + return self.sincnet.receptive_field_center(frame=frame) def forward(self, waveforms: torch.Tensor) -> torch.Tensor: """Pass forward diff --git a/pyannote/audio/models/segmentation/SSeRiouSS.py b/pyannote/audio/models/segmentation/SSeRiouSS.py index 7cd545177..b96464ab3 100644 --- a/pyannote/audio/models/segmentation/SSeRiouSS.py +++ b/pyannote/audio/models/segmentation/SSeRiouSS.py @@ -20,7 +20,7 @@ # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE # SOFTWARE. - +from functools import lru_cache from typing import Optional, Union import torch @@ -32,6 +32,11 @@ from pyannote.audio.core.model import Model from pyannote.audio.core.task import Task from pyannote.audio.utils.params import merge_dict +from pyannote.audio.utils.receptive_field import ( + conv1d_num_frames, + conv1d_receptive_field_center, + conv1d_receptive_field_size, +) class SSeRiouSS(Model): @@ -77,8 +82,8 @@ def __init__( self, wav2vec: Union[dict, str] = None, wav2vec_layer: int = -1, - lstm: dict = None, - linear: dict = None, + lstm: Optional[dict] = None, + linear: Optional[dict] = None, sample_rate: int = 16000, num_channels: int = 1, task: Optional[Task] = None, @@ -144,9 +149,12 @@ def __init__( self.lstm = nn.ModuleList( [ nn.LSTM( - wav2vec_dim - if i == 0 - else lstm["hidden_size"] * (2 if lstm["bidirectional"] else 1), + ( + wav2vec_dim + if i == 0 + else lstm["hidden_size"] + * (2 if lstm["bidirectional"] else 1) + ), **one_layer_lstm, ) for i in range(num_layers) @@ -172,6 +180,17 @@ def __init__( ] ) + @property + def dimension(self) -> int: + """Dimension of output""" + if isinstance(self.specifications, tuple): + raise ValueError("SSeRiouSS does not support multi-tasking.") + + if self.specifications.powerset: + return self.specifications.num_powerset_classes + else: + return len(self.specifications.classes) + def build(self): if self.hparams.linear["num_layers"] > 0: in_features = self.hparams.linear["hidden_size"] @@ -180,16 +199,84 @@ def build(self): 2 if self.hparams.lstm["bidirectional"] else 1 ) - if isinstance(self.specifications, tuple): - raise ValueError("SSeRiouSS model does not support multi-tasking.") + self.classifier = nn.Linear(in_features, self.dimension) + self.activation = self.default_activation() - if self.specifications.powerset: - out_features = self.specifications.num_powerset_classes - else: - out_features = len(self.specifications.classes) + @lru_cache + def num_frames(self, num_samples: int) -> int: + """Compute number of output frames - self.classifier = nn.Linear(in_features, out_features) - self.activation = self.default_activation() + Parameters + ---------- + num_samples : int + Number of input samples. + + Returns + ------- + num_frames : int + Number of output frames. + """ + + num_frames = num_samples + for conv_layer in self.wav2vec.feature_extractor.conv_layers: + num_frames = conv1d_num_frames( + num_frames, + kernel_size=conv_layer.kernel_size, + stride=conv_layer.stride, + padding=conv_layer.conv.padding[0], + dilation=conv_layer.conv.dilation[0], + ) + + return num_frames + + def receptive_field_size(self, num_frames: int = 1) -> int: + """Compute size of receptive field + + Parameters + ---------- + num_frames : int, optional + Number of frames in the output signal + + Returns + ------- + receptive_field_size : int + Receptive field size. + """ + + receptive_field_size = num_frames + for conv_layer in reversed(self.wav2vec.feature_extractor.conv_layers): + receptive_field_size = conv1d_receptive_field_size( + num_frames=receptive_field_size, + kernel_size=conv_layer.kernel_size, + stride=conv_layer.stride, + padding=conv_layer.conv.padding[0], + dilation=conv_layer.conv.dilation[0], + ) + return receptive_field_size + + def receptive_field_center(self, frame: int = 0) -> int: + """Compute center of receptive field + + Parameters + ---------- + frame : int, optional + Frame index + + Returns + ------- + receptive_field_center : int + Index of receptive field center. + """ + receptive_field_center = frame + for conv_layer in reversed(self.wav2vec.feature_extractor.conv_layers): + receptive_field_center = conv1d_receptive_field_center( + receptive_field_center, + kernel_size=conv_layer.kernel_size, + stride=conv_layer.stride, + padding=conv_layer.conv.padding[0], + dilation=conv_layer.conv.dilation[0], + ) + return receptive_field_center def forward(self, waveforms: torch.Tensor) -> torch.Tensor: """Pass forward diff --git a/pyannote/audio/models/segmentation/debug.py b/pyannote/audio/models/segmentation/debug.py index 89512320c..ccac612a9 100644 --- a/pyannote/audio/models/segmentation/debug.py +++ b/pyannote/audio/models/segmentation/debug.py @@ -21,6 +21,7 @@ # SOFTWARE. +from functools import lru_cache from typing import Optional import torch @@ -57,18 +58,91 @@ def __init__( bidirectional=True, ) - def build(self): - # define task-dependent layers + @lru_cache + def num_frames(self, num_samples: int) -> int: + """Compute number of output frames for a given number of input samples + + Parameters + ---------- + num_samples : int + Number of input samples + Returns + ------- + num_frames : int + Number of output frames + + Source + ------ + https://pytorch.org/docs/stable/generated/torch.stft.html#torch.stft + + """ + + hop_length = self.mfcc.MelSpectrogram.spectrogram.hop_length + n_fft = self.mfcc.MelSpectrogram.spectrogram.n_fft + center = self.mfcc.MelSpectrogram.spectrogram.center + + if center: + return 1 + num_samples // hop_length + else: + return 1 + (num_samples - n_fft) // hop_length + + def receptive_field_size(self, num_frames: int = 1) -> int: + """Compute size of receptive field + + Parameters + ---------- + num_frames : int, optional + Number of frames in the output signal + + Returns + ------- + receptive_field_size : int + Receptive field size. + """ + + hop_length = self.mfcc.MelSpectrogram.spectrogram.hop_length + n_fft = self.mfcc.MelSpectrogram.spectrogram.n_fft + return n_fft + (num_frames - 1) * hop_length + + def receptive_field_center(self, frame: int = 0) -> int: + """Compute center of receptive field + + Parameters + ---------- + frame : int, optional + Frame index + + Returns + ------- + receptive_field_center : int + Index of receptive field center. + """ + + hop_length = self.mfcc.MelSpectrogram.spectrogram.hop_length + n_fft = self.mfcc.MelSpectrogram.spectrogram.n_fft + center = self.mfcc.MelSpectrogram.spectrogram.center + + if center: + return frame * hop_length + else: + return frame * hop_length + n_fft // 2 + + @property + def dimension(self) -> int: + """Dimension of output""" if isinstance(self.specifications, tuple): raise ValueError("SimpleSegmentationModel does not support multi-tasking.") if self.specifications.powerset: - out_features = self.specifications.num_powerset_classes + return self.specifications.num_powerset_classes else: - out_features = len(self.specifications.classes) + return len(self.specifications.classes) + + def build(self): + # define task-dependent layers - self.classifier = nn.Linear(32 * 2, out_features) + self.classifier = nn.Linear(32 * 2, self.dimension) self.activation = self.default_activation() def forward(self, waveforms: torch.Tensor) -> torch.Tensor: diff --git a/pyannote/audio/pipelines/clustering.py b/pyannote/audio/pipelines/clustering.py index 80098ea24..cd4b38935 100644 --- a/pyannote/audio/pipelines/clustering.py +++ b/pyannote/audio/pipelines/clustering.py @@ -25,7 +25,7 @@ import random from enum import Enum -from typing import Tuple +from typing import Optional, Tuple import numpy as np from einops import rearrange @@ -56,9 +56,9 @@ def __init__( def set_num_clusters( self, num_embeddings: int, - num_clusters: int = None, - min_clusters: int = None, - max_clusters: int = None, + num_clusters: Optional[int] = None, + min_clusters: Optional[int] = None, + max_clusters: Optional[int] = None, ): min_clusters = num_clusters or min_clusters or 1 min_clusters = max(1, min(num_embeddings, min_clusters)) @@ -79,7 +79,7 @@ def set_num_clusters( def filter_embeddings( self, embeddings: np.ndarray, - segmentations: SlidingWindowFeature = None, + segmentations: Optional[SlidingWindowFeature] = None, ) -> Tuple[np.ndarray, np.ndarray, np.ndarray]: """Filter NaN embeddings and downsample embeddings @@ -205,10 +205,10 @@ def assign_embeddings( def __call__( self, embeddings: np.ndarray, - segmentations: SlidingWindowFeature = None, - num_clusters: int = None, - min_clusters: int = None, - max_clusters: int = None, + segmentations: Optional[SlidingWindowFeature] = None, + num_clusters: Optional[int] = None, + min_clusters: Optional[int] = None, + max_clusters: Optional[int] = None, **kwargs, ) -> np.ndarray: """Apply clustering @@ -323,7 +323,7 @@ def cluster( embeddings: np.ndarray, min_clusters: int, max_clusters: int, - num_clusters: int = None, + num_clusters: Optional[int] = None, ): """ @@ -476,10 +476,10 @@ class OracleClustering(BaseClustering): def __call__( self, - embeddings: np.ndarray = None, - segmentations: SlidingWindowFeature = None, - file: AudioFile = None, - frames: SlidingWindow = None, + embeddings: Optional[np.ndarray] = None, + segmentations: Optional[SlidingWindowFeature] = None, + file: Optional[AudioFile] = None, + frames: Optional[SlidingWindow] = None, **kwargs, ) -> np.ndarray: """Apply oracle clustering diff --git a/pyannote/audio/pipelines/multilabel.py b/pyannote/audio/pipelines/multilabel.py index 18693f14c..b35ebee7c 100644 --- a/pyannote/audio/pipelines/multilabel.py +++ b/pyannote/audio/pipelines/multilabel.py @@ -75,7 +75,7 @@ class MultiLabelSegmentation(Pipeline): def __init__( self, - segmentation: PipelineModel = None, + segmentation: Optional[PipelineModel] = None, fscore: bool = False, share_min_duration: bool = False, use_auth_token: Union[Text, None] = None, diff --git a/pyannote/audio/pipelines/overlapped_speech_detection.py b/pyannote/audio/pipelines/overlapped_speech_detection.py index 1c9790feb..1429e4299 100644 --- a/pyannote/audio/pipelines/overlapped_speech_detection.py +++ b/pyannote/audio/pipelines/overlapped_speech_detection.py @@ -128,7 +128,7 @@ def __init__( # load model model = get_model(segmentation, use_auth_token=use_auth_token) - if model.example_output.dimension > 1: + if model.dimension > 1: inference_kwargs["pre_aggregation_hook"] = lambda scores: np.partition( scores, -2, axis=-1 )[:, :, -2, np.newaxis] @@ -255,7 +255,7 @@ def compute_components( _self, reference: Annotation, hypothesis: Annotation, - uem: Timeline = None, + uem: Optional[Timeline] = None, **kwargs, ) -> dict: return super().compute_components( diff --git a/pyannote/audio/pipelines/resegmentation.py b/pyannote/audio/pipelines/resegmentation.py index d01e5d65f..85492f774 100644 --- a/pyannote/audio/pipelines/resegmentation.py +++ b/pyannote/audio/pipelines/resegmentation.py @@ -86,7 +86,7 @@ def __init__( self, segmentation: PipelineModel = "pyannote/segmentation", diarization: Text = "diarization", - der_variant: dict = None, + der_variant: Optional[dict] = None, use_auth_token: Union[Text, None] = None, ): super().__init__() @@ -96,7 +96,6 @@ def __init__( model: Model = get_model(segmentation, use_auth_token=use_auth_token) self._segmentation = Inference(model) - self._frames = self._segmentation.model.example_output.frames self._audio = model.audio @@ -137,7 +136,7 @@ def classes(self): def apply( self, file: AudioFile, - diarization: Annotation = None, + diarization: Optional[Annotation] = None, hook: Optional[Callable] = None, ) -> Annotation: """Apply speaker diarization @@ -193,8 +192,8 @@ def apply( # estimate frame-level number of instantaneous speakers count = self.speaker_count( binarized_segmentations, + self._segmentation.model.receptive_field, warm_up=(self.warm_up, self.warm_up), - frames=self._frames, ) hook("speaker_counting", count) @@ -205,7 +204,7 @@ def apply( support=Segment( 0.0, self._audio.get_duration(file) + self._segmentation.step ), - resolution=self._frames, + resolution=self._segmentation.model.receptive_field, ) hook("@resegmentation/original", diarization) diff --git a/pyannote/audio/pipelines/speaker_diarization.py b/pyannote/audio/pipelines/speaker_diarization.py index 354f6be7e..737cd1cb2 100644 --- a/pyannote/audio/pipelines/speaker_diarization.py +++ b/pyannote/audio/pipelines/speaker_diarization.py @@ -32,7 +32,7 @@ import numpy as np import torch from einops import rearrange -from pyannote.core import Annotation, SlidingWindow, SlidingWindowFeature +from pyannote.core import Annotation, SlidingWindowFeature from pyannote.metrics.diarization import GreedyDiarizationErrorRate from pyannote.pipeline.parameter import ParamDict, Uniform @@ -121,7 +121,7 @@ def __init__( clustering: str = "AgglomerativeClustering", embedding_batch_size: int = 1, segmentation_batch_size: int = 1, - der_variant: dict = None, + der_variant: Optional[dict] = None, use_auth_token: Union[Text, None] = None, ): super().__init__() @@ -147,7 +147,6 @@ def __init__( skip_aggregation=True, batch_size=segmentation_batch_size, ) - self._frames: SlidingWindow = self._segmentation.model.example_output.frames if self._segmentation.model.specifications.powerset: self.segmentation = ParamDict( @@ -428,9 +427,9 @@ def reconstruct( def apply( self, file: AudioFile, - num_speakers: int = None, - min_speakers: int = None, - max_speakers: int = None, + num_speakers: Optional[int] = None, + min_speakers: Optional[int] = None, + max_speakers: Optional[int] = None, return_embeddings: bool = False, hook: Optional[Callable] = None, ) -> Annotation: @@ -493,7 +492,7 @@ def apply( # estimate frame-level number of instantaneous speakers count = self.speaker_count( binarized_segmentations, - frames=self._frames, + self._segmentation.model.receptive_field, warm_up=(0.0, 0.0), ) hook("speaker_counting", count) @@ -527,7 +526,7 @@ def apply( min_clusters=min_speakers, max_clusters=max_speakers, file=file, # <== for oracle clustering - frames=self._frames, # <== for oracle clustering + frames=self._segmentation.model.receptive_field, # <== for oracle clustering ) # hard_clusters: (num_chunks, num_speakers) # centroids: (num_speakers, dimension) @@ -538,15 +537,20 @@ def apply( # detected number of speakers can still be out of bounds # (specifically, lower than `min_speakers`), since there could be too few embeddings # to make enough clusters with a given minimum cluster size. - if num_different_speakers < min_speakers or num_different_speakers > max_speakers: - warnings.warn(textwrap.dedent( - f""" + if ( + num_different_speakers < min_speakers + or num_different_speakers > max_speakers + ): + warnings.warn( + textwrap.dedent( + f""" The detected number of speakers ({num_different_speakers}) is outside the given bounds [{min_speakers}, {max_speakers}]. This can happen if the given audio file is too short to contain {min_speakers} or more speakers. Try to lower the desired minimal number of speakers. """ - )) + ) + ) # during counting, we could possibly overcount the number of instantaneous # speakers due to segmentation errors, so we cap the maximum instantaneous number @@ -618,7 +622,9 @@ def apply( # of clusters obtained from `clustering`. In this case, we append zero embeddings # for extra speakers if len(diarization.labels()) > centroids.shape[0]: - centroids = np.pad(centroids, ((0, len(diarization.labels()) - centroids.shape[0]), (0, 0))) + centroids = np.pad( + centroids, ((0, len(diarization.labels()) - centroids.shape[0]), (0, 0)) + ) # re-order centroids so that they match # the order given by diarization.labels() diff --git a/pyannote/audio/pipelines/speaker_verification.py b/pyannote/audio/pipelines/speaker_verification.py index c870ea622..8c4139b6f 100644 --- a/pyannote/audio/pipelines/speaker_verification.py +++ b/pyannote/audio/pipelines/speaker_verification.py @@ -23,12 +23,11 @@ import warnings from functools import cached_property from pathlib import Path -from typing import Text, Union +from typing import Optional, Text, Union import numpy as np import torch import torch.nn.functional as F -import torchaudio import torchaudio.compliance.kaldi as kaldi from huggingface_hub import hf_hub_download from huggingface_hub.utils import RepositoryNotFoundError @@ -40,7 +39,6 @@ from pyannote.audio.core.model import CACHE_DIR from pyannote.audio.pipelines.utils import PipelineModel, get_model -backend = torchaudio.get_audio_backend() try: from speechbrain.pretrained import ( EncoderClassifier as SpeechBrain_EncoderClassifier, @@ -49,8 +47,6 @@ SPEECHBRAIN_IS_AVAILABLE = True except ImportError: SPEECHBRAIN_IS_AVAILABLE = False -finally: - torchaudio.set_audio_backend(backend) try: from nemo.collections.asr.models import ( @@ -73,7 +69,7 @@ class NeMoPretrainedSpeakerEmbedding(BaseInference): def __init__( self, embedding: Text = "nvidia/speakerverification_en_titanet_large", - device: torch.device = None, + device: Optional[torch.device] = None, ): if not NEMO_IS_AVAILABLE: raise ImportError( @@ -139,7 +135,7 @@ def min_num_samples(self) -> int: return upper def __call__( - self, waveforms: torch.Tensor, masks: torch.Tensor = None + self, waveforms: torch.Tensor, masks: Optional[torch.Tensor] = None ) -> np.ndarray: """ @@ -238,7 +234,7 @@ class SpeechBrainPretrainedSpeakerEmbedding(BaseInference): def __init__( self, embedding: Text = "speechbrain/spkrec-ecapa-voxceleb", - device: torch.device = None, + device: Optional[torch.device] = None, use_auth_token: Union[Text, None] = None, ): if not SPEECHBRAIN_IS_AVAILABLE: @@ -314,7 +310,7 @@ def min_num_samples(self) -> int: return upper def __call__( - self, waveforms: torch.Tensor, masks: torch.Tensor = None + self, waveforms: torch.Tensor, masks: Optional[torch.Tensor] = None ) -> np.ndarray: """ @@ -414,7 +410,7 @@ class ONNXWeSpeakerPretrainedSpeakerEmbedding(BaseInference): def __init__( self, embedding: Text = "hbredin/wespeaker-voxceleb-resnet34-LM", - device: torch.device = None, + device: Optional[torch.device] = None, ): if not ONNX_IS_AVAILABLE: raise ImportError( @@ -560,7 +556,7 @@ def compute_fbank( return features - torch.mean(features, dim=1, keepdim=True) def __call__( - self, waveforms: torch.Tensor, masks: torch.Tensor = None + self, waveforms: torch.Tensor, masks: Optional[torch.Tensor] = None ) -> np.ndarray: """ @@ -645,7 +641,7 @@ class PyannoteAudioPretrainedSpeakerEmbedding(BaseInference): def __init__( self, embedding: PipelineModel = "pyannote/embedding", - device: torch.device = None, + device: Optional[torch.device] = None, use_auth_token: Union[Text, None] = None, ): super().__init__() @@ -672,7 +668,7 @@ def sample_rate(self) -> int: @cached_property def dimension(self) -> int: - return self.model_.example_output.dimension + return self.model_.dimension @cached_property def metric(self) -> str: @@ -695,7 +691,7 @@ def min_num_samples(self) -> int: return upper def __call__( - self, waveforms: torch.Tensor, masks: torch.Tensor = None + self, waveforms: torch.Tensor, masks: Optional[torch.Tensor] = None ) -> np.ndarray: with torch.inference_mode(): if masks is None: @@ -711,7 +707,7 @@ def __call__( def PretrainedSpeakerEmbedding( embedding: PipelineModel, - device: torch.device = None, + device: Optional[torch.device] = None, use_auth_token: Union[Text, None] = None, ): """Pretrained speaker embedding @@ -801,7 +797,7 @@ class SpeakerEmbedding(Pipeline): def __init__( self, embedding: PipelineModel = "pyannote/embedding", - segmentation: PipelineModel = None, + segmentation: Optional[PipelineModel] = None, use_auth_token: Union[Text, None] = None, ): super().__init__() @@ -848,7 +844,7 @@ def main( protocol: str = "VoxCeleb.SpeakerVerification.VoxCeleb1", subset: str = "test", embedding: str = "pyannote/embedding", - segmentation: str = None, + segmentation: Optional[str] = None, ): import typer from pyannote.database import FileFinder, get_protocol diff --git a/pyannote/audio/pipelines/utils/diarization.py b/pyannote/audio/pipelines/utils/diarization.py index 4a35f7049..5a0f8f675 100644 --- a/pyannote/audio/pipelines/utils/diarization.py +++ b/pyannote/audio/pipelines/utils/diarization.py @@ -20,7 +20,7 @@ # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE # SOFTWARE. -from typing import Dict, Mapping, Tuple, Union +from typing import Dict, Mapping, Optional, Tuple, Union import numpy as np from pyannote.core import Annotation, SlidingWindow, SlidingWindowFeature @@ -28,7 +28,7 @@ from pyannote.metrics.diarization import DiarizationErrorRate from pyannote.audio.core.inference import Inference -from pyannote.audio.utils.signal import Binarize, binarize +from pyannote.audio.utils.signal import Binarize # TODO: move to dedicated module @@ -37,9 +37,9 @@ class SpeakerDiarizationMixin: @staticmethod def set_num_speakers( - num_speakers: int = None, - min_speakers: int = None, - max_speakers: int = None, + num_speakers: Optional[int] = None, + min_speakers: Optional[int] = None, + max_speakers: Optional[int] = None, ): """Validate number of speakers @@ -121,8 +121,8 @@ def optimal_mapping( @staticmethod def speaker_count( binarized_segmentations: SlidingWindowFeature, + frames: SlidingWindow, warm_up: Tuple[float, float] = (0.1, 0.1), - frames: SlidingWindow = None, ) -> SlidingWindowFeature: """Estimate frame-level number of instantaneous speakers @@ -133,7 +133,7 @@ def speaker_count( warm_up : (float, float) tuple, optional Left/right warm up ratio of chunk duration. Defaults to (0.1, 0.1), i.e. 10% on both sides. - frames : SlidingWindow, optional + frames : SlidingWindow Frames resolution. Defaults to estimate it automatically based on `segmentations` shape and chunk size. Providing the exact frame resolution (when known) leads to better temporal precision. @@ -147,7 +147,7 @@ def speaker_count( trimmed = Inference.trim(binarized_segmentations, warm_up=warm_up) count = Inference.aggregate( np.sum(trimmed, axis=-1, keepdims=True), - frames=frames, + frames, hamming=False, missing=0.0, skip_average=False, @@ -212,7 +212,7 @@ def to_diarization( # TODO: investigate alternative aggregation activations = Inference.aggregate( segmentations, - frames=count.sliding_window, + count.sliding_window, hamming=False, missing=0.0, skip_average=True, diff --git a/pyannote/audio/pipelines/utils/getter.py b/pyannote/audio/pipelines/utils/getter.py index 4c589ad05..51040d1c4 100644 --- a/pyannote/audio/pipelines/utils/getter.py +++ b/pyannote/audio/pipelines/utils/getter.py @@ -21,7 +21,7 @@ # SOFTWARE. import itertools -from typing import Mapping, Text, Union +from typing import Mapping, Optional, Text, Union import torch from torch_audiomentations.core.transforms_interface import BaseWaveformTransform @@ -171,7 +171,7 @@ def get_augmentation(augmentation: PipelineAugmentation) -> BaseWaveformTransfor ) -def get_devices(needs: int = None): +def get_devices(needs: Optional[int] = None): """Get devices that can be used by the pipeline Parameters diff --git a/pyannote/audio/pipelines/utils/hook.py b/pyannote/audio/pipelines/utils/hook.py index 2a675d1c9..db6972e2e 100644 --- a/pyannote/audio/pipelines/utils/hook.py +++ b/pyannote/audio/pipelines/utils/hook.py @@ -24,6 +24,7 @@ from copy import deepcopy from typing import Any, Mapping, Optional, Text +import torch from rich.progress import ( BarColumn, Progress, @@ -75,6 +76,9 @@ def __call__( ): return + if isinstance(step_artifact, torch.Tensor): + step_artifact = step_artifact.numpy(force=True) + file.setdefault(self.file_key, dict())[step_name] = deepcopy(step_artifact) diff --git a/pyannote/audio/pipelines/utils/oracle.py b/pyannote/audio/pipelines/utils/oracle.py index 44b4ded61..24401f752 100644 --- a/pyannote/audio/pipelines/utils/oracle.py +++ b/pyannote/audio/pipelines/utils/oracle.py @@ -20,7 +20,7 @@ # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE # SOFTWARE. -from typing import Union +from typing import Optional, Union import numpy as np from pyannote.core import Annotation, Segment, SlidingWindow, SlidingWindowFeature @@ -32,14 +32,14 @@ def oracle_segmentation( file: AudioFile, window: SlidingWindow, frames: Union[SlidingWindow, float], - num_speakers: int = None, + num_speakers: Optional[int] = None, ) -> SlidingWindowFeature: """Oracle speaker segmentation Simulates inference based on an (imaginary) oracle segmentation model: >>> oracle = Model.from_pretrained("oracle") - >>> assert frames == oracle.example_output.frames + >>> assert frames == oracle.receptive_field >>> inference = Inference(oracle, duration=window.duration, step=window.step, skip_aggregation=True) >>> oracle_segmentation = inference(file) diff --git a/pyannote/audio/pipelines/voice_activity_detection.py b/pyannote/audio/pipelines/voice_activity_detection.py index f67489b64..39e529d89 100644 --- a/pyannote/audio/pipelines/voice_activity_detection.py +++ b/pyannote/audio/pipelines/voice_activity_detection.py @@ -284,7 +284,7 @@ class AdaptiveVoiceActivityDetection(Pipeline): def __init__( self, segmentation: PipelineInference = "hbredin/VoiceActivityDetection-PyanNet-DIHARD", - augmentation: PipelineAugmentation = None, + augmentation: Optional[PipelineAugmentation] = None, fscore: bool = False, ): super().__init__() diff --git a/pyannote/audio/sample/__init__.py b/pyannote/audio/sample/__init__.py new file mode 100644 index 000000000..85399af66 --- /dev/null +++ b/pyannote/audio/sample/__init__.py @@ -0,0 +1,56 @@ +# MIT License +# +# Copyright (c) 2024- CNRS +# +# 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. + + +from pathlib import Path + +from pyannote.core import Annotation, Segment, Timeline +from pyannote.database.util import load_rttm + +from pyannote.audio.core.io import Audio, AudioFile + + +def _sample() -> AudioFile: + sample_wav = Path(__file__).parent / "sample.wav" + uri = "sample" + + audio = Audio() + waveform, sample_rate = audio(sample_wav) + + sample_rttm = Path(__file__).parent / "sample.rttm" + + annotation: Annotation = load_rttm(sample_rttm)[uri] + duration = audio.get_duration(sample_wav) + + annotated: Timeline = Timeline([Segment(0.0, duration)], uri=uri) + + return { + "audio": sample_wav, + "uri": "sample", + "waveform": waveform, + "sample_rate": sample_rate, + "annotation": annotation, + "annotated": annotated, + } + + +SAMPLE_FILE = _sample() diff --git a/pyannote/audio/sample/sample.rttm b/pyannote/audio/sample/sample.rttm new file mode 100644 index 000000000..7c6b378fe --- /dev/null +++ b/pyannote/audio/sample/sample.rttm @@ -0,0 +1,10 @@ +SPEAKER sample 1 6.690 0.430 speaker90 +SPEAKER sample 1 7.550 0.800 speaker91 +SPEAKER sample 1 8.320 1.700 speaker90 +SPEAKER sample 1 9.920 1.110 speaker91 +SPEAKER sample 1 10.570 4.130 speaker90 +SPEAKER sample 1 14.490 3.430 speaker91 +SPEAKER sample 1 18.050 3.440 speaker90 +SPEAKER sample 1 18.150 0.440 speaker91 +SPEAKER sample 1 21.780 6.720 speaker91 +SPEAKER sample 1 27.850 2.150 speaker90 diff --git a/pyannote/audio/sample/sample.wav b/pyannote/audio/sample/sample.wav new file mode 100644 index 000000000..150d49a69 Binary files /dev/null and b/pyannote/audio/sample/sample.wav differ diff --git a/pyannote/audio/tasks/embedding/arcface.py b/pyannote/audio/tasks/embedding/arcface.py index bb2cb1f6c..cb6401e2b 100644 --- a/pyannote/audio/tasks/embedding/arcface.py +++ b/pyannote/audio/tasks/embedding/arcface.py @@ -23,7 +23,7 @@ from __future__ import annotations -from typing import Dict, Sequence, Union +from typing import Dict, Optional, Sequence, Union import pytorch_metric_learning.losses from pyannote.database import Protocol @@ -82,15 +82,15 @@ class SupervisedRepresentationLearningWithArcFace( def __init__( self, protocol: Protocol, - min_duration: float = None, + min_duration: Optional[float] = None, duration: float = 2.0, num_classes_per_batch: int = 32, num_chunks_per_class: int = 1, margin: float = 28.6, scale: float = 64.0, - num_workers: int = None, + num_workers: Optional[int] = None, pin_memory: bool = False, - augmentation: BaseWaveformTransform = None, + augmentation: Optional[BaseWaveformTransform] = None, metric: Union[Metric, Sequence[Metric], Dict[str, Metric]] = None, ): diff --git a/pyannote/audio/tasks/embedding/mixins.py b/pyannote/audio/tasks/embedding/mixins.py index da164f04e..9b404f9cf 100644 --- a/pyannote/audio/tasks/embedding/mixins.py +++ b/pyannote/audio/tasks/embedding/mixins.py @@ -75,7 +75,7 @@ def batch_size(self) -> int: def batch_size(self, batch_size: int): self.batch_size_ = batch_size - def setup(self): + def setup(self, stage=None): # loop over the training set, remove annotated regions shorter than # chunk duration, and keep track of the reference annotations, per class. @@ -119,12 +119,6 @@ def setup(self): classes=sorted(self._train), ) - if not self.has_validation: - return - - if isinstance(self.protocol, SpeakerVerificationProtocol): - self._validation = list(self.protocol.development_trial()) - def default_metric( self, ) -> Union[Metric, Sequence[Metric], Dict[str, Metric]]: @@ -145,7 +139,7 @@ def train__iter__(self): """ # create worker-specific random number generator - rng = create_rng_for_worker(self.model.current_epoch) + rng = create_rng_for_worker(self.model) classes = list(self.specifications.classes) @@ -250,9 +244,13 @@ def training_step(self, batch, batch_idx: int): return {"loss": loss} + def prepare_validation(self, prepared_dict: Dict): + if isinstance(self.protocol, SpeakerVerificationProtocol): + prepared_dict["validation"] = list(self.protocol.development_trial()) + def val__getitem__(self, idx): if isinstance(self.protocol, SpeakerVerificationProtocol): - trial = self._validation[idx] + trial = self.prepared_data["validation"][idx] data = dict() for idx in [1, 2]: @@ -281,7 +279,7 @@ def val__getitem__(self, idx): def val__len__(self): if isinstance(self.protocol, SpeakerVerificationProtocol): - return len(self._validation) + return len(self.prepared_data["validation"]) elif isinstance(self.protocol, SpeakerDiarizationProtocol): return 0 diff --git a/pyannote/audio/tasks/segmentation/mixins.py b/pyannote/audio/tasks/segmentation/mixins.py index 018e8db70..be30828f0 100644 --- a/pyannote/audio/tasks/segmentation/mixins.py +++ b/pyannote/audio/tasks/segmentation/mixins.py @@ -23,44 +23,40 @@ import itertools import math import random -import warnings -from collections import defaultdict from typing import Dict, Sequence, Union import matplotlib.pyplot as plt import numpy as np import torch -from pyannote.database.protocol import SegmentationProtocol, SpeakerDiarizationProtocol from pyannote.database.protocol.protocol import Scope, Subset from pytorch_lightning.loggers import MLFlowLogger, TensorBoardLogger from torch.utils.data._utils.collate import default_collate -from torchaudio.backend.common import AudioMetaData +from torchaudio import AudioMetaData from torchmetrics import Metric from torchmetrics.classification import BinaryAUROC, MulticlassAUROC, MultilabelAUROC -from pyannote.audio.core.task import Problem +from pyannote.audio.core.task import Problem, Task, get_dtype from pyannote.audio.utils.random import create_rng_for_worker Subsets = list(Subset.__args__) Scopes = list(Scope.__args__) -class SegmentationTaskMixin: +class SegmentationTask(Task): """Methods common to most segmentation tasks""" def get_file(self, file_id): file = dict() - file["audio"] = str(self.audios[file_id], encoding="utf-8") + file["audio"] = self.prepared_data["audio-path"][file_id] - _audio_info = self.audio_infos[file_id] - _encoding = self.audio_encodings[file_id] + _audio_info = self.prepared_data["audio-info"][file_id] + encoding = self.prepared_data["audio-encoding"][file_id] sample_rate = _audio_info["sample_rate"] num_frames = _audio_info["num_frames"] num_channels = _audio_info["num_channels"] bits_per_sample = _audio_info["bits_per_sample"] - encoding = str(_encoding, encoding="utf-8") file["torchaudio.info"] = AudioMetaData( sample_rate=sample_rate, num_frames=num_frames, @@ -71,319 +67,6 @@ def get_file(self, file_id): return file - def setup(self): - """Setup""" - - # duration of training chunks - # TODO: handle variable duration case - duration = getattr(self, "duration", 0.0) - - # list of possible values for each metadata key - metadata_unique_values = defaultdict(list) - - metadata_unique_values["subset"] = Subsets - - if isinstance(self.protocol, SpeakerDiarizationProtocol): - metadata_unique_values["scope"] = Scopes - - elif isinstance(self.protocol, SegmentationProtocol): - classes = getattr(self, "classes", list()) - - # make sure classes attribute exists (and set to None if it did not exist) - self.classes = getattr(self, "classes", None) - if self.classes is None: - classes = list() - # metadata_unique_values["classes"] = list(classes) - - audios = list() # list of path to audio files - audio_infos = list() - audio_encodings = list() - metadata = list() # list of metadata - - annotated_duration = list() # total duration of annotated regions (per file) - annotated_regions = list() # annotated regions - annotations = list() # actual annotations - annotated_classes = list() # list of annotated classes (per file) - unique_labels = list() - - if self.has_validation: - files_iter = itertools.chain( - self.protocol.train(), self.protocol.development() - ) - else: - files_iter = self.protocol.train() - - for file_id, file in enumerate(files_iter): - # gather metadata and update metadata_unique_values so that each metadatum - # (e.g. source database or label) is represented by an integer. - metadatum = dict() - - # keep track of source database and subset (train, development, or test) - if file["database"] not in metadata_unique_values["database"]: - metadata_unique_values["database"].append(file["database"]) - metadatum["database"] = metadata_unique_values["database"].index( - file["database"] - ) - metadatum["subset"] = Subsets.index(file["subset"]) - - # keep track of speaker label scope (file, database, or global) for speaker diarization protocols - if isinstance(self.protocol, SpeakerDiarizationProtocol): - metadatum["scope"] = Scopes.index(file["scope"]) - - # keep track of list of classes for regular segmentation protocols - # Different files may be annotated using a different set of classes - # (e.g. one database for speech/music/noise, and another one for male/female/child) - if isinstance(self.protocol, SegmentationProtocol): - if "classes" in file: - local_classes = file["classes"] - else: - local_classes = file["annotation"].labels() - - # if task was not initialized with a fixed list of classes, - # we build it as the union of all classes found in files - if self.classes is None: - for klass in local_classes: - if klass not in classes: - classes.append(klass) - annotated_classes.append( - [classes.index(klass) for klass in local_classes] - ) - - # if task was initialized with a fixed list of classes, - # we make sure that all files use a subset of these classes - # if they don't, we issue a warning and ignore the extra classes - else: - extra_classes = set(local_classes) - set(self.classes) - if extra_classes: - warnings.warn( - f"Ignoring extra classes ({', '.join(extra_classes)}) found for file {file['uri']} ({file['database']}). " - ) - annotated_classes.append( - [ - self.classes.index(klass) - for klass in set(local_classes) & set(self.classes) - ] - ) - - remaining_metadata_keys = set(file) - set( - [ - "uri", - "database", - "subset", - "audio", - "torchaudio.info", - "scope", - "classes", - "annotation", - "annotated", - ] - ) - - # keep track of any other (integer or string) metadata provided by the protocol - # (e.g. a "domain" key for domain-adversarial training) - for key in remaining_metadata_keys: - value = file[key] - - if isinstance(value, str): - if value not in metadata_unique_values[key]: - metadata_unique_values[key].append(value) - metadatum[key] = metadata_unique_values[key].index(value) - - elif isinstance(value, int): - metadatum[key] = value - - else: - warnings.warn( - f"Ignoring '{key}' metadata because of its type ({type(value)}). Only str and int are supported for now.", - category=UserWarning, - ) - - metadata.append(metadatum) - - database_unique_labels = list() - - # reset list of file-scoped labels - file_unique_labels = list() - - # path to audio file - audios.append(str(file["audio"])) - - # audio info - audio_info = file["torchaudio.info"] - audio_infos.append( - ( - audio_info.sample_rate, # sample rate - audio_info.num_frames, # number of frames - audio_info.num_channels, # number of channels - audio_info.bits_per_sample, # bits per sample - ) - ) - audio_encodings.append(audio_info.encoding) # encoding - - # annotated regions and duration - _annotated_duration = 0.0 - for segment in file["annotated"]: - # skip annotated regions that are shorter than training chunk duration - if segment.duration < duration: - continue - - # append annotated region - annotated_region = ( - file_id, - segment.duration, - segment.start, - segment.end, - ) - annotated_regions.append(annotated_region) - - # increment annotated duration - _annotated_duration += segment.duration - - # append annotated duration - annotated_duration.append(_annotated_duration) - - # annotations - for segment, _, label in file["annotation"].itertracks(yield_label=True): - # "scope" is provided by speaker diarization protocols to indicate - # whether speaker labels are local to the file ('file'), consistent across - # all files in a database ('database'), or globally consistent ('global') - - if "scope" in file: - # 0 = 'file' - # 1 = 'database' - # 2 = 'global' - scope = Scopes.index(file["scope"]) - - # update list of file-scope labels - if label not in file_unique_labels: - file_unique_labels.append(label) - # and convert label to its (file-scope) index - file_label_idx = file_unique_labels.index(label) - - database_label_idx = global_label_idx = -1 - - if scope > 0: # 'database' or 'global' - # update list of database-scope labels - if label not in database_unique_labels: - database_unique_labels.append(label) - - # and convert label to its (database-scope) index - database_label_idx = database_unique_labels.index(label) - - if scope > 1: # 'global' - # update list of global-scope labels - if label not in unique_labels: - unique_labels.append(label) - # and convert label to its (global-scope) index - global_label_idx = unique_labels.index(label) - - # basic segmentation protocols do not provide "scope" information - # as classes are global by definition - - else: - try: - file_label_idx = ( - database_label_idx - ) = global_label_idx = classes.index(label) - except ValueError: - # skip labels that are not in the list of classes - continue - - annotations.append( - ( - file_id, # index of file - segment.start, # start time - segment.end, # end time - file_label_idx, # file-scope label index - database_label_idx, # database-scope label index - global_label_idx, # global-scope index - ) - ) - - # since not all metadata keys are present in all files, fallback to -1 when a key is missing - metadata = [ - tuple(metadatum.get(key, -1) for key in metadata_unique_values) - for metadatum in metadata - ] - dtype = [(key, "i") for key in metadata_unique_values] - self.metadata = np.array(metadata, dtype=dtype) - - # NOTE: read with str(self.audios[file_id], encoding='utf-8') - self.audios = np.array(audios, dtype=np.string_) - - # turn list of files metadata into a single numpy array - # TODO: improve using https://github.com/pytorch/pytorch/issues/13246#issuecomment-617140519 - - dtype = [ - ("sample_rate", "i"), - ("num_frames", "i"), - ("num_channels", "i"), - ("bits_per_sample", "i"), - ] - self.audio_infos = np.array(audio_infos, dtype=dtype) - self.audio_encodings = np.array(audio_encodings, dtype=np.string_) - - self.annotated_duration = np.array(annotated_duration) - - # turn list of annotated regions into a single numpy array - dtype = [("file_id", "i"), ("duration", "f"), ("start", "f"), ("end", "f")] - self.annotated_regions = np.array(annotated_regions, dtype=dtype) - - # convert annotated_classes (which is a list of list of classes, one list of classes per file) - # into a single (num_files x num_classes) numpy array: - # * True indicates that this particular class was annotated for this particular file (though it may not be active in this file) - # * False indicates that this particular class was not even annotated (i.e. its absence does not imply that it is not active in this file) - if isinstance(self.protocol, SegmentationProtocol) and self.classes is None: - self.classes = classes - self.annotated_classes = np.zeros( - (len(annotated_classes), len(self.classes)), dtype=np.bool_ - ) - for file_id, classes in enumerate(annotated_classes): - self.annotated_classes[file_id, classes] = True - - # turn list of annotations into a single numpy array - dtype = [ - ("file_id", "i"), - ("start", "f"), - ("end", "f"), - ("file_label_idx", "i"), - ("database_label_idx", "i"), - ("global_label_idx", "i"), - ] - self.annotations = np.array(annotations, dtype=dtype) - - self.metadata_unique_values = metadata_unique_values - - if not self.has_validation: - return - - validation_chunks = list() - - # obtain indexes of files in the validation subset - validation_file_ids = np.where( - self.metadata["subset"] == Subsets.index("development") - )[0] - - # iterate over files in the validation subset - for file_id in validation_file_ids: - # get annotated regions in file - annotated_regions = self.annotated_regions[ - self.annotated_regions["file_id"] == file_id - ] - - # iterate over annotated regions - for annotated_region in annotated_regions: - # number of chunks in annotated region - num_chunks = round(annotated_region["duration"] // duration) - - # iterate over chunks - for c in range(num_chunks): - start_time = annotated_region["start"] + c * duration - validation_chunks.append((file_id, start_time, duration)) - - dtype = [("file_id", "i"), ("start", "f"), ("duration", "f")] - self.validation_chunks = np.array(validation_chunks, dtype=dtype) - def default_metric( self, ) -> Union[Metric, Sequence[Metric], Dict[str, Metric]]: @@ -419,14 +102,20 @@ def train__iter__helper(self, rng: random.Random, **filters): """ # indices of training files that matches domain filters - training = self.metadata["subset"] == Subsets.index("train") + training = self.prepared_data["audio-metadata"]["subset"] == Subsets.index( + "train" + ) for key, value in filters.items(): - training &= self.metadata[key] == self.metadata_unique_values[key].index(value) + training &= self.prepared_data["audio-metadata"][key] == self.prepared_data[ + "metadata" + ][key].index(value) file_ids = np.where(training)[0] # turn annotated duration into a probability distribution - annotated_duration = self.annotated_duration[file_ids] - prob_annotated_duration = annotated_duration / np.sum(annotated_duration) + annotated_duration = self.prepared_data["audio-annotated"][file_ids] + cum_prob_annotated_duration = np.cumsum( + annotated_duration / np.sum(annotated_duration) + ) duration = self.duration @@ -434,28 +123,38 @@ def train__iter__helper(self, rng: random.Random, **filters): while True: # select one file at random (with probability proportional to its annotated duration) - file_id = np.random.choice(file_ids, p=prob_annotated_duration) + file_id = file_ids[cum_prob_annotated_duration.searchsorted(rng.random())] # generate `num_chunks_per_file` chunks from this file for _ in range(num_chunks_per_file): # find indices of annotated regions in this file annotated_region_indices = np.where( - self.annotated_regions["file_id"] == file_id + self.prepared_data["annotations-regions"]["file_id"] == file_id )[0] # turn annotated regions duration into a probability distribution - prob_annotated_regions_duration = self.annotated_regions["duration"][ - annotated_region_indices - ] / np.sum(self.annotated_regions["duration"][annotated_region_indices]) - # selected one annotated region at random (with probability proportional to its duration) - annotated_region_index = np.random.choice( - annotated_region_indices, p=prob_annotated_regions_duration + cum_prob_annotated_regions_duration = np.cumsum( + self.prepared_data["annotations-regions"]["duration"][ + annotated_region_indices + ] + / np.sum( + self.prepared_data["annotations-regions"]["duration"][ + annotated_region_indices + ] + ) ) + # selected one annotated region at random (with probability proportional to its duration) + annotated_region_index = annotated_region_indices[ + cum_prob_annotated_regions_duration.searchsorted(rng.random()) + ] + # select one chunk at random in this annotated region - _, _, start, end = self.annotated_regions[annotated_region_index] - start_time = rng.uniform(start, end - duration) + _, region_duration, start = self.prepared_data["annotations-regions"][ + annotated_region_index + ] + start_time = rng.uniform(start, start + region_duration - duration) yield self.prepare_chunk(file_id, start_time, duration) @@ -475,7 +174,7 @@ def train__iter__(self): """ # create worker-specific random number generator - rng = create_rng_for_worker(self.model.current_epoch) + rng = create_rng_for_worker(self.model) balance = getattr(self, "balance", None) if balance is None: @@ -485,7 +184,7 @@ def train__iter__(self): # create a subchunk generator for each combination of "balance" keys subchunks = dict() for product in itertools.product( - *[self.metadata_unique_values[key] for key in balance] + *[self.prepared_data["metadata"][key] for key in balance] ): # we iterate on the cartesian product of the values in metadata_unique_values # eg: for balance=["database", "split"], with 2 databases and 2 splits: @@ -556,12 +255,52 @@ def collate_fn(self, batch, stage="train"): def train__len__(self): # Number of training samples in one epoch + train_file_ids = np.where( + self.prepared_data["audio-metadata"]["subset"] == Subsets.index("train") + )[0] - duration = np.sum(self.annotated_duration) + duration = np.sum(self.prepared_data["audio-annotated"][train_file_ids]) return max(self.batch_size, math.ceil(duration / self.duration)) + def prepare_validation(self, prepared_data: Dict): + validation_chunks = list() + + # obtain indexes of files in the validation subset + validation_file_ids = np.where( + prepared_data["audio-metadata"]["subset"] == Subsets.index("development") + )[0] + + # iterate over files in the validation subset + for file_id in validation_file_ids: + # get annotated regions in file + annotated_regions = prepared_data["annotations-regions"][ + prepared_data["annotations-regions"]["file_id"] == file_id + ] + + # iterate over annotated regions + for annotated_region in annotated_regions: + # number of chunks in annotated region + num_chunks = round(annotated_region["duration"] // self.duration) + + # iterate over chunks + for c in range(num_chunks): + start_time = annotated_region["start"] + c * self.duration + validation_chunks.append((file_id, start_time, self.duration)) + + dtype = [ + ( + "file_id", + get_dtype(max(v[0] for v in validation_chunks)), + ), + ("start", "f"), + ("duration", "f"), + ] + + prepared_data["validation"] = np.array(validation_chunks, dtype=dtype) + validation_chunks.clear() + def val__getitem__(self, idx): - validation_chunk = self.validation_chunks[idx] + validation_chunk = self.prepared_data["validation"][idx] return self.prepare_chunk( validation_chunk["file_id"], validation_chunk["start"], @@ -569,7 +308,7 @@ def val__getitem__(self, idx): ) def val__len__(self): - return len(self.validation_chunks) + return len(self.prepared_data["validation"]) def validation_step(self, batch, batch_idx: int): """Compute validation area under the ROC curve diff --git a/pyannote/audio/tasks/segmentation/multilabel.py b/pyannote/audio/tasks/segmentation/multilabel.py index c1d58431a..9184121c4 100644 --- a/pyannote/audio/tasks/segmentation/multilabel.py +++ b/pyannote/audio/tasks/segmentation/multilabel.py @@ -20,6 +20,8 @@ # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE # SOFTWARE. +import itertools +import textwrap from typing import Dict, List, Optional, Sequence, Text, Tuple, Union import numpy as np @@ -31,11 +33,11 @@ from torch_audiomentations.core.transforms_interface import BaseWaveformTransform from torchmetrics import Metric -from pyannote.audio.core.task import Problem, Resolution, Specifications, Task -from pyannote.audio.tasks.segmentation.mixins import SegmentationTaskMixin +from pyannote.audio.core.task import Problem, Resolution, Specifications +from pyannote.audio.tasks.segmentation.mixins import SegmentationTask -class MultiLabelSegmentation(SegmentationTaskMixin, Task): +class MultiLabelSegmentation(SegmentationTask): """Generic multi-label segmentation Multi-label segmentation is the process of detecting temporal intervals @@ -47,7 +49,13 @@ class MultiLabelSegmentation(SegmentationTaskMixin, Task): Parameters ---------- protocol : Protocol - pyannote.database protocol + cache : str, optional + As (meta-)data preparation might take a very long time for large datasets, + it can be cached to disk for later (and faster!) re-use. + When `cache` does not exist, `Task.prepare_data()` generates training + and validation metadata from `protocol` and save them to disk. + When `cache` exists, `Task.prepare_data()` is skipped and (meta)-data + are loaded from disk. Defaults to a temporary path. classes : List[str], optional List of classes. Defaults to the list of classes available in the training set. duration : float, optional @@ -84,15 +92,16 @@ class MultiLabelSegmentation(SegmentationTaskMixin, Task): def __init__( self, protocol: Protocol, + cache: Optional[Union[str, None]] = None, classes: Optional[List[str]] = None, duration: float = 2.0, warm_up: Union[float, Tuple[float, float]] = 0.0, - balance: Sequence[Text] = None, - weight: Text = None, + balance: Optional[Sequence[Text]] = None, + weight: Optional[Text] = None, batch_size: int = 32, - num_workers: int = None, + num_workers: Optional[int] = None, pin_memory: bool = False, - augmentation: BaseWaveformTransform = None, + augmentation: Optional[BaseWaveformTransform] = None, metric: Union[Metric, Sequence[Metric], Dict[str, Metric]] = None, ): if not isinstance(protocol, SegmentationProtocol): @@ -109,6 +118,7 @@ def __init__( pin_memory=pin_memory, augmentation=augmentation, metric=metric, + cache=cache, ) self.balance = balance @@ -119,11 +129,114 @@ def __init__( # classes should be detected. therefore, we postpone the definition of # specifications to setup() - def setup(self): - super().setup() + def post_prepare_data(self, prepared_data: Dict): + # as different files may be annotated using a different set of classes + # (e.g. one database for speech/music/noise, and another one for + # male/female/child), we keep track of this information. this is used + # to know whether a missing class is considered a negative example (0) or + # simple an unknown example (-1) + + if self.classes is None and not self.has_classes: + msg = textwrap.dedent( + """ + Could not infer list of classes. Either provide a list of classes when + instantiating the task, or make sure that the training protocol provides + a 'classes' entry. See https://github.com/pyannote/pyannote-database#segmentation + for more details. + """ + ) + + if self.has_validation: + files_iter = itertools.chain( + self.protocol.train(), self.protocol.development() + ) + else: + files_iter = self.protocol.train() + + if self.classes is None: + classes = list() # overall list of classes + annotated_classes = list() # list of annotated classes (per file) + + for file in files_iter: + file_classes = file.get("classes", None) + + if not file_classes: + msg = textwrap.dedent( + f""" + File "{file['uri']}" (from {file['database']} database) does not + provide a 'classes' entry. Please make sure the corresponding + training protocol provides a 'classes' entry for all files. See + https://github.com/pyannote/pyannote-database#segmentation for more + details. + """ + ) + raise ValueError(msg) + + for klass in file_classes: + if klass not in classes: + classes.append(klass) + annotated_classes.append( + [classes.index(klass) for klass in file_classes] + ) + + prepared_data["classes-list"] = np.array(classes, dtype=np.str_) + self.classes = classes + + else: + annotated_classes = list() # list of annotated classes (per file) + for file in files_iter: + file_classes = file.get("classes", None) + + if not file_classes: + msg = textwrap.dedent( + f""" + File "{file['uri']}" (from {file['database']} database) does not + provide a 'classes' entry. Please make sure the corresponding + training protocol provides a 'classes' entry for all files. See + https://github.com/pyannote/pyannote-database#segmentation for more + details. + """ + ) + raise ValueError(msg) + + extra_classes = set(file_classes) - set(self.classes) + if extra_classes: + msg = textwrap.dedent( + f""" + File "{file['uri']}" (from {file['database']} database) provides + extra classes ({', '.join(extra_classes)}) that are ignored. + """ + ) + print(msg) + + annotated_classes.append( + [ + self.classes.index(klass) + for klass in set(file_classes) & set(self.classes) + ] + ) + + prepared_data["classes-list"] = np.array(self.classes, dtype=np.str_) + + # convert annotated_classes (which is a list of list of classes, one list of classes per file) + # into a single (num_files x num_classes) numpy array: + # * True indicates that this particular class was annotated for this particular file + # (though it may not be active in this file) + # * False indicates that this particular class was not even annotated (i.e. its absence + # does not imply that it is not active in this file) + annotated_classes_array = np.zeros( + (len(annotated_classes), len(self.classes)), dtype=np.bool_ + ) + for file_id, classes in enumerate(annotated_classes): + annotated_classes_array[file_id, classes] = True + prepared_data["classes-annotated"] = annotated_classes_array + annotated_classes.clear() + + def setup(self, stage=None): + super().setup(stage) self.specifications = Specifications( - classes=self.classes, + classes=self.prepared_data["classes-list"], problem=Problem.MULTI_LABEL_CLASSIFICATION, resolution=Resolution.FRAME, duration=self.duration, @@ -169,7 +282,9 @@ def prepare_chunk(self, file_id: int, start_time: float, duration: float): sample = dict() sample["X"], _ = self.model.audio.crop(file, chunk, duration=duration) # gather all annotations of current file - annotations = self.annotations[self.annotations["file_id"] == file_id] + annotations = self.prepared_data["annotations-segments"][ + self.prepared_data["annotations-segments"]["file_id"] == file_id + ] # gather all annotations with non-empty intersection with current chunk chunk_annotations = annotations[ @@ -177,26 +292,37 @@ def prepare_chunk(self, file_id: int, start_time: float, duration: float): ] # discretize chunk annotations at model output resolution - start = np.maximum(chunk_annotations["start"], chunk.start) - chunk.start - start_idx = np.floor(start / self.model.example_output.frames.step).astype(int) - end = np.minimum(chunk_annotations["end"], chunk.end) - chunk.start - end_idx = np.ceil(end / self.model.example_output.frames.step).astype(int) + step = self.model.receptive_field.step + half = 0.5 * self.model.receptive_field.duration + + start = np.maximum(chunk_annotations["start"], chunk.start) - chunk.start - half + start_idx = np.maximum(0, np.round(start / step)).astype(int) + + end = np.minimum(chunk_annotations["end"], chunk.end) - chunk.start - half + end_idx = np.round(end / step).astype(int) # frame-level targets (-1 for un-annotated classes) + num_frames = self.model.num_frames( + round(duration * self.model.hparams.sample_rate) + ) y = -np.ones( - (self.model.example_output.num_frames, len(self.classes)), dtype=np.int8 + ( + num_frames, + len(self.prepared_data["classes-list"]), + ), + dtype=np.int8, ) - y[:, self.annotated_classes[file_id]] = 0 + y[:, self.prepared_data["classes-annotated"][file_id]] = 0 for start, end, label in zip( start_idx, end_idx, chunk_annotations["global_label_idx"] ): - y[start:end, label] = 1 + y[start : end + 1, label] = 1 sample["y"] = SlidingWindowFeature( - y, self.model.example_output.frames, labels=self.classes + y, self.model.receptive_field, labels=self.classes ) - metadata = self.metadata[file_id] + metadata = self.prepared_data["audio-metadata"][file_id] sample["meta"] = {key: metadata[key] for key in metadata.dtype.names} sample["meta"]["file"] = file_id diff --git a/pyannote/audio/tasks/segmentation/overlapped_speech_detection.py b/pyannote/audio/tasks/segmentation/overlapped_speech_detection.py index 0b7209c5c..89d299a8d 100644 --- a/pyannote/audio/tasks/segmentation/overlapped_speech_detection.py +++ b/pyannote/audio/tasks/segmentation/overlapped_speech_detection.py @@ -21,7 +21,7 @@ # SOFTWARE. -from typing import Dict, Sequence, Text, Tuple, Union +from typing import Dict, Optional, Sequence, Text, Tuple, Union import numpy as np from pyannote.core import Segment, SlidingWindowFeature @@ -29,11 +29,11 @@ from torch_audiomentations.core.transforms_interface import BaseWaveformTransform from torchmetrics import Metric -from pyannote.audio.core.task import Problem, Resolution, Specifications, Task -from pyannote.audio.tasks.segmentation.mixins import SegmentationTaskMixin +from pyannote.audio.core.task import Problem, Resolution, Specifications +from pyannote.audio.tasks.segmentation.mixins import SegmentationTask -class OverlappedSpeechDetection(SegmentationTaskMixin, Task): +class OverlappedSpeechDetection(SegmentationTask): """Overlapped speech detection Overlapped speech detection is the task of detecting regions where at least @@ -51,6 +51,13 @@ class OverlappedSpeechDetection(SegmentationTaskMixin, Task): ---------- protocol : Protocol pyannote.database protocol + cache : str, optional + As (meta-)data preparation might take a very long time for large datasets, + it can be cached to disk for later (and faster!) re-use. + When `cache` does not exist, `Task.prepare_data()` generates training + and validation metadata from `protocol` and save them to disk. + When `cache` exists, `Task.prepare_data()` is skipped and (meta)-data + are loaded from disk. Defaults to a temporary path. duration : float, optional Chunks duration. Defaults to 2s. warm_up : float or (float, float), optional @@ -66,11 +73,12 @@ class OverlappedSpeechDetection(SegmentationTaskMixin, Task): overlap: dict, optional Controls how artificial chunks with overlapping speech are generated: - "probability" key is the probability of artificial overlapping chunks. Setting - "probability" to 0.6 means that, on average, 40% of training chunks are "real" - chunks, while 60% are artifical chunks made out of the (weighted) sum of two - chunks. Defaults to 0.5. + "probability" to 0.6 means that, on average, 40% of training chunks are "real" + chunks, while 60% are artifical chunks made out of the (weighted) sum of two + chunks. Defaults to 0.5. - "snr_min" and "snr_max" keys control the minimum and maximum signal-to-noise - ratio between summed chunks, in dB. Default to 0.0 and 10. + ratio between summed chunks, in dB. Default to 0.0 and 10. + weight: str, optional When provided, use this key to as frame-wise weight in loss function. batch_size : int, optional @@ -98,13 +106,14 @@ def __init__( duration: float = 2.0, warm_up: Union[float, Tuple[float, float]] = 0.0, overlap: dict = OVERLAP_DEFAULTS, - balance: Sequence[Text] = None, - weight: Text = None, + balance: Optional[Sequence[Text]] = None, + weight: Optional[Text] = None, batch_size: int = 32, - num_workers: int = None, + num_workers: Optional[int] = None, pin_memory: bool = False, - augmentation: BaseWaveformTransform = None, + augmentation: Optional[BaseWaveformTransform] = None, metric: Union[Metric, Sequence[Metric], Dict[str, Metric]] = None, + cache: Optional[Union[str, None]] = None, ): super().__init__( protocol, @@ -115,6 +124,7 @@ def __init__( pin_memory=pin_memory, augmentation=augmentation, metric=metric, + cache=cache, ) self.specifications = Specifications( @@ -163,7 +173,9 @@ def prepare_chunk(self, file_id: int, start_time: float, duration: float): sample["X"], _ = self.model.audio.crop(file, chunk, duration=duration) # gather all annotations of current file - annotations = self.annotations[self.annotations["file_id"] == file_id] + annotations = self.prepared_data["annotations-segments"][ + self.prepared_data["annotations-segments"]["file_id"] == file_id + ] # gather all annotations with non-empty intersection with current chunk chunk_annotations = annotations[ @@ -171,22 +183,29 @@ def prepare_chunk(self, file_id: int, start_time: float, duration: float): ] # discretize chunk annotations at model output resolution - start = np.maximum(chunk_annotations["start"], chunk.start) - chunk.start - start_idx = np.floor(start / self.model.example_output.frames.step).astype(int) - end = np.minimum(chunk_annotations["end"], chunk.end) - chunk.start - end_idx = np.ceil(end / self.model.example_output.frames.step).astype(int) + step = self.model.receptive_field.step + half = 0.5 * self.model.receptive_field.duration + + start = np.maximum(chunk_annotations["start"], chunk.start) - chunk.start - half + start_idx = np.maximum(0, np.round(start / step)).astype(int) + + end = np.minimum(chunk_annotations["end"], chunk.end) - chunk.start - half + end_idx = np.round(end / step).astype(int) # frame-level targets - y = np.zeros((self.model.example_output.num_frames, 1), dtype=np.uint8) + num_frames = self.model.num_frames( + round(duration * self.model.hparams.sample_rate) + ) + y = np.zeros((num_frames, 1), dtype=np.uint8) for start, end in zip(start_idx, end_idx): - y[start:end, 0] += 1 + y[start : end + 1, 0] += 1 y = 1 * (y > 1) sample["y"] = SlidingWindowFeature( - y, self.model.example_output.frames, labels=["speech"] + y, self.model.receptive_field, labels=["speech"] ) - metadata = self.metadata[file_id] + metadata = self.prepared_data["audio-metadata"][file_id] sample["meta"] = {key: metadata[key] for key in metadata.dtype.names} sample["meta"]["file"] = file_id diff --git a/pyannote/audio/tasks/segmentation/speaker_diarization.py b/pyannote/audio/tasks/segmentation/speaker_diarization.py index 1094672ed..8a091b1f7 100644 --- a/pyannote/audio/tasks/segmentation/speaker_diarization.py +++ b/pyannote/audio/tasks/segmentation/speaker_diarization.py @@ -23,7 +23,7 @@ import math import warnings from collections import Counter -from typing import Dict, Literal, Sequence, Text, Tuple, Union +from typing import Dict, Literal, Optional, Sequence, Text, Tuple, Union import numpy as np import torch @@ -37,8 +37,8 @@ from torch_audiomentations.core.transforms_interface import BaseWaveformTransform from torchmetrics import Metric -from pyannote.audio.core.task import Problem, Resolution, Specifications, Task -from pyannote.audio.tasks.segmentation.mixins import SegmentationTaskMixin +from pyannote.audio.core.task import Problem, Resolution, Specifications +from pyannote.audio.tasks.segmentation.mixins import SegmentationTask from pyannote.audio.torchmetrics import ( DiarizationErrorRate, FalseAlarmRate, @@ -58,13 +58,20 @@ Scopes = list(Scope.__args__) -class SpeakerDiarization(SegmentationTaskMixin, Task): +class SpeakerDiarization(SegmentationTask): """Speaker diarization Parameters ---------- protocol : SpeakerDiarizationProtocol pyannote.database protocol + cache : str, optional + As (meta-)data preparation might take a very long time for large datasets, + it can be cached to disk for later (and faster!) re-use. + When `cache` does not exist, `Task.prepare_data()` generates training + and validation metadata from `protocol` and save them to disk. + When `cache` exists, `Task.prepare_data()` is skipped and (meta)-data + are loaded from disk. Defaults to a temporary path. duration : float, optional Chunks duration. Defaults to 2s. max_speakers_per_chunk : int, optional @@ -127,20 +134,23 @@ class SpeakerDiarization(SegmentationTaskMixin, Task): def __init__( self, protocol: SpeakerDiarizationProtocol, + cache: Optional[Union[str, None]] = None, duration: float = 2.0, - max_speakers_per_chunk: int = None, - max_speakers_per_frame: int = None, + max_speakers_per_chunk: Optional[int] = None, + max_speakers_per_frame: Optional[int] = None, weigh_by_cardinality: bool = False, warm_up: Union[float, Tuple[float, float]] = 0.0, - balance: Sequence[Text] = None, - weight: Text = None, + balance: Optional[Sequence[Text]] = None, + weight: Optional[Text] = None, batch_size: int = 32, - num_workers: int = None, + num_workers: Optional[int] = None, pin_memory: bool = False, - augmentation: BaseWaveformTransform = None, + augmentation: Optional[BaseWaveformTransform] = None, vad_loss: Literal["bce", "mse"] = None, metric: Union[Metric, Sequence[Metric], Dict[str, Metric]] = None, - max_num_speakers: int = None, # deprecated in favor of `max_speakers_per_chunk`` + max_num_speakers: Optional[ + int + ] = None, # deprecated in favor of `max_speakers_per_chunk`` loss: Literal["bce", "mse"] = None, # deprecated ): super().__init__( @@ -152,6 +162,7 @@ def __init__( pin_memory=pin_memory, augmentation=augmentation, metric=metric, + cache=cache, ) if not isinstance(protocol, SpeakerDiarizationProtocol): @@ -186,28 +197,34 @@ def __init__( self.weight = weight self.vad_loss = vad_loss - def setup(self): - super().setup() + def setup(self, stage=None): + super().setup(stage) # estimate maximum number of speakers per chunk when not provided if self.max_speakers_per_chunk is None: - training = self.metadata["subset"] == Subsets.index("train") + training = self.prepared_data["audio-metadata"]["subset"] == Subsets.index( + "train" + ) num_unique_speakers = [] progress_description = f"Estimating maximum number of speakers per {self.duration:g}s chunk in the training set" for file_id in track( np.where(training)[0], description=progress_description ): - annotations = self.annotations[ - np.where(self.annotations["file_id"] == file_id)[0] + annotations = self.prepared_data["annotations-segments"][ + np.where( + self.prepared_data["annotations-segments"]["file_id"] == file_id + )[0] ] - annotated_regions = self.annotated_regions[ - np.where(self.annotated_regions["file_id"] == file_id)[0] + annotated_regions = self.prepared_data["annotations-regions"][ + np.where( + self.prepared_data["annotations-regions"]["file_id"] == file_id + )[0] ] for region in annotated_regions: # find annotations within current region region_start = region["start"] - region_end = region["end"] + region_end = region["start"] + region["duration"] region_annotations = annotations[ np.where( (annotations["start"] >= region_start) @@ -318,7 +335,7 @@ def prepare_chunk(self, file_id: int, start_time: float, duration: float): file = self.get_file(file_id) # get label scope - label_scope = Scopes[self.metadata[file_id]["scope"]] + label_scope = Scopes[self.prepared_data["audio-metadata"][file_id]["scope"]] label_scope_key = f"{label_scope}_label_idx" # @@ -328,7 +345,9 @@ def prepare_chunk(self, file_id: int, start_time: float, duration: float): sample["X"], _ = self.model.audio.crop(file, chunk, duration=duration) # gather all annotations of current file - annotations = self.annotations[self.annotations["file_id"] == file_id] + annotations = self.prepared_data["annotations-segments"][ + self.prepared_data["annotations-segments"]["file_id"] == file_id + ] # gather all annotations with non-empty intersection with current chunk chunk_annotations = annotations[ @@ -336,10 +355,14 @@ def prepare_chunk(self, file_id: int, start_time: float, duration: float): ] # discretize chunk annotations at model output resolution - start = np.maximum(chunk_annotations["start"], chunk.start) - chunk.start - start_idx = np.floor(start / self.model.example_output.frames.step).astype(int) - end = np.minimum(chunk_annotations["end"], chunk.end) - chunk.start - end_idx = np.ceil(end / self.model.example_output.frames.step).astype(int) + step = self.model.receptive_field.step + half = 0.5 * self.model.receptive_field.duration + + start = np.maximum(chunk_annotations["start"], chunk.start) - chunk.start - half + start_idx = np.maximum(0, np.round(start / step)).astype(int) + + end = np.minimum(chunk_annotations["end"], chunk.end) - chunk.start - half + end_idx = np.round(end / step).astype(int) # get list and number of labels for current scope labels = list(np.unique(chunk_annotations[label_scope_key])) @@ -349,7 +372,10 @@ def prepare_chunk(self, file_id: int, start_time: float, duration: float): pass # initial frame-level targets - y = np.zeros((self.model.example_output.num_frames, num_labels), dtype=np.uint8) + num_frames = self.model.num_frames( + round(duration * self.model.hparams.sample_rate) + ) + y = np.zeros((num_frames, num_labels), dtype=np.uint8) # map labels to indices mapping = {label: idx for idx, label in enumerate(labels)} @@ -358,13 +384,11 @@ def prepare_chunk(self, file_id: int, start_time: float, duration: float): start_idx, end_idx, chunk_annotations[label_scope_key] ): mapped_label = mapping[label] - y[start:end, mapped_label] = 1 + y[start : end + 1, mapped_label] = 1 - sample["y"] = SlidingWindowFeature( - y, self.model.example_output.frames, labels=labels - ) + sample["y"] = SlidingWindowFeature(y, self.model.receptive_field, labels=labels) - metadata = self.metadata[file_id] + metadata = self.prepared_data["audio-metadata"][file_id] sample["meta"] = {key: metadata[key] for key in metadata.dtype.names} sample["meta"]["file"] = file_id @@ -420,7 +444,7 @@ def segmentation_loss( self, permutated_prediction: torch.Tensor, target: torch.Tensor, - weight: torch.Tensor = None, + weight: Optional[torch.Tensor] = None, ) -> torch.Tensor: """Permutation-invariant segmentation loss @@ -463,7 +487,7 @@ def voice_activity_detection_loss( self, permutated_prediction: torch.Tensor, target: torch.Tensor, - weight: torch.Tensor = None, + weight: Optional[torch.Tensor] = None, ) -> torch.Tensor: """Voice activity detection loss @@ -861,7 +885,7 @@ def main(protocol: str, subset: str = "test", model: str = "pyannote/segmentatio main_task = progress.add_task(protocol.name, total=len(files)) file_task = progress.add_task("Processing", total=1.0) - def progress_hook(completed: int = None, total: int = None): + def progress_hook(completed: Optional[int] = None, total: Optional[int] = None): progress.update(file_task, completed=completed / total) inference = Inference(model, device=device) diff --git a/pyannote/audio/tasks/segmentation/voice_activity_detection.py b/pyannote/audio/tasks/segmentation/voice_activity_detection.py index fd9eb8e75..e52613aeb 100644 --- a/pyannote/audio/tasks/segmentation/voice_activity_detection.py +++ b/pyannote/audio/tasks/segmentation/voice_activity_detection.py @@ -20,7 +20,7 @@ # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE # SOFTWARE. -from typing import Dict, Sequence, Text, Tuple, Union +from typing import Dict, Optional, Sequence, Text, Tuple, Union import numpy as np from pyannote.core import Segment, SlidingWindowFeature @@ -28,11 +28,11 @@ from torch_audiomentations.core.transforms_interface import BaseWaveformTransform from torchmetrics import Metric -from pyannote.audio.core.task import Problem, Resolution, Specifications, Task -from pyannote.audio.tasks.segmentation.mixins import SegmentationTaskMixin +from pyannote.audio.core.task import Problem, Resolution, Specifications +from pyannote.audio.tasks.segmentation.mixins import SegmentationTask -class VoiceActivityDetection(SegmentationTaskMixin, Task): +class VoiceActivityDetection(SegmentationTask): """Voice activity detection Voice activity detection (or VAD) is the task of detecting speech regions @@ -45,6 +45,13 @@ class VoiceActivityDetection(SegmentationTaskMixin, Task): ---------- protocol : Protocol pyannote.database protocol + cache : str, optional + As (meta-)data preparation might take a very long time for large datasets, + it can be cached to disk for later (and faster!) re-use. + When `cache` does not exist, `Task.prepare_data()` generates training + and validation metadata from `protocol` and save them to disk. + When `cache` exists, `Task.prepare_data()` is skipped and (meta)-data + are loaded from disk. Defaults to a temporary path. duration : float, optional Chunks duration. Defaults to 2s. warm_up : float or (float, float), optional @@ -79,14 +86,15 @@ class VoiceActivityDetection(SegmentationTaskMixin, Task): def __init__( self, protocol: Protocol, + cache: Optional[Union[str, None]] = None, duration: float = 2.0, warm_up: Union[float, Tuple[float, float]] = 0.0, - balance: Sequence[Text] = None, - weight: Text = None, + balance: Optional[Sequence[Text]] = None, + weight: Optional[Text] = None, batch_size: int = 32, - num_workers: int = None, + num_workers: Optional[int] = None, pin_memory: bool = False, - augmentation: BaseWaveformTransform = None, + augmentation: Optional[BaseWaveformTransform] = None, metric: Union[Metric, Sequence[Metric], Dict[str, Metric]] = None, ): super().__init__( @@ -98,6 +106,7 @@ def __init__( pin_memory=pin_memory, augmentation=augmentation, metric=metric, + cache=cache, ) self.balance = balance @@ -145,7 +154,9 @@ def prepare_chunk(self, file_id: int, start_time: float, duration: float): sample["X"], _ = self.model.audio.crop(file, chunk, duration=duration) # gather all annotations of current file - annotations = self.annotations[self.annotations["file_id"] == file_id] + annotations = self.prepared_data["annotations-segments"][ + self.prepared_data["annotations-segments"]["file_id"] == file_id + ] # gather all annotations with non-empty intersection with current chunk chunk_annotations = annotations[ @@ -153,21 +164,28 @@ def prepare_chunk(self, file_id: int, start_time: float, duration: float): ] # discretize chunk annotations at model output resolution - start = np.maximum(chunk_annotations["start"], chunk.start) - chunk.start - start_idx = np.floor(start / self.model.example_output.frames.step).astype(int) - end = np.minimum(chunk_annotations["end"], chunk.end) - chunk.start - end_idx = np.ceil(end / self.model.example_output.frames.step).astype(int) + step = self.model.receptive_field.step + half = 0.5 * self.model.receptive_field.duration + + start = np.maximum(chunk_annotations["start"], chunk.start) - chunk.start - half + start_idx = np.maximum(0, np.round(start / step)).astype(int) + + end = np.minimum(chunk_annotations["end"], chunk.end) - chunk.start - half + end_idx = np.round(end / step).astype(int) # frame-level targets - y = np.zeros((self.model.example_output.num_frames, 1), dtype=np.uint8) + num_frames = self.model.num_frames( + round(duration * self.model.hparams.sample_rate) + ) + y = np.zeros((num_frames, 1), dtype=np.uint8) for start, end in zip(start_idx, end_idx): - y[start:end, 0] = 1 + y[start : end + 1, 0] = 1 sample["y"] = SlidingWindowFeature( - y, self.model.example_output.frames, labels=["speech"] + y, self.model.receptive_field, labels=["speech"] ) - metadata = self.metadata[file_id] + metadata = self.prepared_data["audio-metadata"][file_id] sample["meta"] = {key: metadata[key] for key in metadata.dtype.names} sample["meta"]["file"] = file_id diff --git a/pyannote/audio/torchmetrics/functional/audio/diarization_error_rate.py b/pyannote/audio/torchmetrics/functional/audio/diarization_error_rate.py index 9502a527e..c401b70dd 100644 --- a/pyannote/audio/torchmetrics/functional/audio/diarization_error_rate.py +++ b/pyannote/audio/torchmetrics/functional/audio/diarization_error_rate.py @@ -25,6 +25,7 @@ from typing import Optional, Tuple, Union import torch +import torch.nn.functional as F from pyannote.audio.utils.permutation import permutate @@ -33,6 +34,7 @@ def _der_update( preds: torch.Tensor, target: torch.Tensor, threshold: Union[torch.Tensor, float] = 0.5, + reduce: str = "batch", ) -> Tuple[torch.Tensor, torch.Tensor, torch.Tensor, torch.Tensor]: """Compute components of diarization error rate @@ -44,16 +46,41 @@ def _der_update( (batch_size, num_speakers, num_frames)-shaped (0 or 1) targets. threshold : float or torch.Tensor, optional Threshold(s) used to binarize predictions. Defaults to 0.5. + reduce : {'batch', 'chunk', 'frame'}, optional + Reduction method. Defaults to 'batch'. Returns ------- - false_alarm : (num_thresholds, )-shaped torch.Tensor - missed_detection : (num_thresholds, )-shaped torch.Tensor - speaker_confusion : (num_thresholds, )-shaped torch.Tensor - speech_total : torch.Tensor - Diarization error rate components accumulated over the whole batch. + false_alarm : torch.Tensor + missed_detection : torch.Tensor + speaker_confusion : torch.Tensor + If `reduce` is 'batch', returns (num_thresholds, )-shaped tensors. + If `reduce` is 'chunk', returns (batch_size, num_thresholds)-shaped tensors. + If `reduce` is 'frame', returns (batch_size, num_frames, num_thresholds)-shaped tensors. + In case `threshold` is a float, the last dimension is removed from the output tensors. + speech_total : (...,)-shaped torch.Tensor torch.Tensor + If `reduce` is 'batch', returns a scalar. + If `reduce` is 'chunk', returns (batch_size,)-shaped tensor. + If `reduce` is 'frame', returns (batch_size, num_frames)-shaped tensor. """ + prd_batch_size, prd_num_speakers, prd_num_frames = preds.shape + tgt_batch_size, tgt_num_speakers, tgt_num_frames = target.shape + + if prd_batch_size != tgt_batch_size: + raise ValueError(f"Batch size mismatch: {prd_batch_size} != {tgt_batch_size}.") + + if prd_num_frames != tgt_num_frames: + raise ValueError( + f"Number of frames mismatch: {prd_num_frames} != {tgt_num_frames}." + ) + + # pad number of speakers if necessary + if prd_num_speakers > tgt_num_speakers: + target = F.pad(target, (0, 0, 0, prd_num_speakers - tgt_num_speakers)) + elif prd_num_speakers < tgt_num_speakers: + preds = F.pad(preds, (0, 0, 0, tgt_num_speakers - prd_num_speakers)) + # make threshold a (num_thresholds,) tensor scalar_threshold = isinstance(threshold, Number) if scalar_threshold: @@ -70,6 +97,9 @@ def _der_update( hypothesis = (permutated_preds.unsqueeze(-1) > threshold).float() # (batch_size, num_speakers, num_frames, num_thresholds) + speech_total = 1.0 * torch.sum(target, 1) + # (batch_size, num_frames) + target = target.unsqueeze(-1) # (batch_size, num_speakers, num_frames, 1) @@ -87,17 +117,47 @@ def _der_update( speaker_confusion = torch.sum((hypothesis != target) * hypothesis, 1) - false_alarm # (batch_size, num_frames, num_thresholds) - false_alarm = torch.sum(torch.sum(false_alarm, 1), 0) - missed_detection = torch.sum(torch.sum(missed_detection, 1), 0) - speaker_confusion = torch.sum(torch.sum(speaker_confusion, 1), 0) + if reduce == "frame": + if scalar_threshold: + return ( + false_alarm[:, :, 0], + missed_detection[:, :, 0], + speaker_confusion[:, :, 0], + speech_total, + ) + return false_alarm, missed_detection, speaker_confusion, torch.sum(target, 1) + + speech_total = torch.sum(speech_total, 1) + # (batch_size, ) + false_alarm = torch.sum(false_alarm, 1) + missed_detection = torch.sum(missed_detection, 1) + speaker_confusion = torch.sum(speaker_confusion, 1) + # (batch_size, num_thresholds) + + if reduce == "chunk": + if scalar_threshold: + return ( + false_alarm[:, 0], + missed_detection[:, 0], + speaker_confusion[:, 0], + speech_total, + ) + return false_alarm, missed_detection, speaker_confusion, speech_total + + speech_total = torch.sum(speech_total, 0) + # scalar + false_alarm = torch.sum(false_alarm, 0) + missed_detection = torch.sum(missed_detection, 0) + speaker_confusion = torch.sum(speaker_confusion, 0) # (num_thresholds, ) - speech_total = 1.0 * torch.sum(target) - if scalar_threshold: - false_alarm = false_alarm[0] - missed_detection = missed_detection[0] - speaker_confusion = speaker_confusion[0] + return ( + false_alarm[0], + missed_detection[0], + speaker_confusion[0], + speech_total, + ) return false_alarm, missed_detection, speaker_confusion, speech_total @@ -131,6 +191,8 @@ def diarization_error_rate( preds: torch.Tensor, target: torch.Tensor, threshold: Union[torch.Tensor, float] = 0.5, + reduce: str = "batch", + return_components: bool = False, ) -> torch.Tensor: """Compute diarization error rate @@ -142,16 +204,32 @@ def diarization_error_rate( (batch_size, num_speakers, num_frames)-shaped (0 or 1) targets. threshold : float or torch.Tensor, optional Threshold(s) used to binarize predictions. Defaults to 0.5. + reduce : {'batch', 'chunk', 'frame'}, optional + Reduction method. Defaults to 'batch'. + return_components : bool, optional + Return diarization error rate components as an additional tuple. + Defaults to False. + Returns ------- - der : (num_thresholds, )-shaped torch.Tensor - Aggregated diarization error rate + der : torch.Tensor + If `reduce` is 'batch', returns (num_thresholds, )-shaped tensors. + If `reduce` is 'chunk', returns (batch_size, num_thresholds)-shaped tensors. + If `reduce` is 'frame', returns (batch_size, num_frames, num_thresholds)-shaped tensors. + In case `threshold` is a float, the last dimension is removed from the output tensors. + components : (false_alarm, missed_detection, speaker_confusion, speech_total) tuple, optional + Same shape as `der`. Only returned when `return_components` is True. + """ false_alarm, missed_detection, speaker_confusion, speech_total = _der_update( - preds, target, threshold=threshold + preds, target, threshold=threshold, reduce=reduce ) - return _der_compute(false_alarm, missed_detection, speaker_confusion, speech_total) + + der = _der_compute(false_alarm, missed_detection, speaker_confusion, speech_total) + if return_components: + return der, (false_alarm, missed_detection, speaker_confusion, speech_total) + return der def optimal_diarization_error_rate( diff --git a/pyannote/audio/utils/loss.py b/pyannote/audio/utils/loss.py index 2c55b26f3..55121a678 100644 --- a/pyannote/audio/utils/loss.py +++ b/pyannote/audio/utils/loss.py @@ -23,11 +23,13 @@ """Frame-weighted versions of common loss functions""" +from typing import Optional + import torch import torch.nn.functional as F -def interpolate(target: torch.Tensor, weight: torch.Tensor = None): +def interpolate(target: torch.Tensor, weight: Optional[torch.Tensor] = None): """Interpolate weight to match target frame resolution Parameters @@ -55,7 +57,9 @@ def interpolate(target: torch.Tensor, weight: torch.Tensor = None): def binary_cross_entropy( - prediction: torch.Tensor, target: torch.Tensor, weight: torch.Tensor = None + prediction: torch.Tensor, + target: torch.Tensor, + weight: Optional[torch.Tensor] = None, ) -> torch.Tensor: """Frame-weighted binary cross entropy @@ -91,7 +95,9 @@ def binary_cross_entropy( def mse_loss( - prediction: torch.Tensor, target: torch.Tensor, weight: torch.Tensor = None + prediction: torch.Tensor, + target: torch.Tensor, + weight: Optional[torch.Tensor] = None, ) -> torch.Tensor: """Frame-weighted mean-squared error loss @@ -131,8 +137,8 @@ def mse_loss( def nll_loss( prediction: torch.Tensor, target: torch.Tensor, - class_weight: torch.Tensor = None, - weight: torch.Tensor = None, + class_weight: Optional[torch.Tensor] = None, + weight: Optional[torch.Tensor] = None, ) -> torch.Tensor: """Frame-weighted negative log-likelihood loss diff --git a/pyannote/audio/utils/params.py b/pyannote/audio/utils/params.py index 685e01653..f4ed42bcc 100644 --- a/pyannote/audio/utils/params.py +++ b/pyannote/audio/utils/params.py @@ -1,8 +1,10 @@ # TODO - make it depth-recursive # TODO - switch to Omegaconf maybe? +from typing import Optional -def merge_dict(defaults: dict, custom: dict = None): + +def merge_dict(defaults: dict, custom: Optional[dict] = None): params = dict(defaults) if custom is not None: params.update(custom) diff --git a/pyannote/audio/utils/powerset.py b/pyannote/audio/utils/powerset.py index b75221e48..23f921569 100644 --- a/pyannote/audio/utils/powerset.py +++ b/pyannote/audio/utils/powerset.py @@ -25,7 +25,8 @@ # Alexis PLAQUET from functools import cached_property -from itertools import combinations +from itertools import combinations, permutations +from typing import Dict, Tuple import scipy.special import torch @@ -65,6 +66,27 @@ def num_powerset_classes(self) -> int: ) def build_mapping(self) -> torch.Tensor: + """Compute powerset to regular mapping + + Returns + ------- + mapping : (num_powerset_classes, num_classes) torch.Tensor + mapping[i, j] == 1 if jth regular class is a member of ith powerset class + mapping[i, j] == 0 otherwise + + Example + ------- + With num_classes == 3 and max_set_size == 2, returns + + [0, 0, 0] # none + [1, 0, 0] # class #1 + [0, 1, 0] # class #2 + [0, 0, 1] # class #3 + [1, 1, 0] # classes #1 and #2 + [1, 0, 1] # classes #1 and #3 + [0, 1, 1] # classes #2 and #3 + + """ mapping = torch.zeros(self.num_powerset_classes, self.num_classes) powerset_k = 0 for set_size in range(0, self.max_set_size + 1): @@ -76,13 +98,7 @@ def build_mapping(self) -> torch.Tensor: def build_cardinality(self) -> torch.Tensor: """Compute size of each powerset class""" - cardinality = torch.zeros(self.num_powerset_classes) - powerset_k = 0 - for set_size in range(0, self.max_set_size + 1): - for _ in combinations(range(self.num_classes), set_size): - cardinality[powerset_k] = set_size - powerset_k += 1 - return cardinality + return torch.sum(self.mapping, dim=1) def to_multilabel(self, powerset: torch.Tensor, soft: bool = False) -> torch.Tensor: """Convert predictions from powerset to multi-label @@ -93,7 +109,7 @@ def to_multilabel(self, powerset: torch.Tensor, soft: bool = False) -> torch.Ten Soft predictions in "powerset" space. soft : bool, optional Return soft multi-label predictions. Defaults to False (i.e. hard predictions) - Assumes that `powerset` are "logits" (not "probabilities"). + Assumes that `powerset` are "log probabilities". Returns ------- @@ -138,3 +154,76 @@ def to_powerset(self, multilabel: torch.Tensor) -> torch.Tensor: torch.argmax(torch.matmul(multilabel, self.mapping.T), dim=-1), num_classes=self.num_powerset_classes, ) + + def _permutation_powerset( + self, multilabel_permutation: Tuple[int, ...] + ) -> Tuple[int, ...]: + """Helper function for `permutation_mapping` property + + Takes a (num_classes,)-shaped permutation in multilabel space and returns + the corresponding (num_powerset_classes,)-shaped permutation in powerset space. + This does not cache anything and only works on one single permutation at a time. + + Parameters + ---------- + multilabel_permutation : tuple of int + Permutation in multilabel space. + + Returns + ------- + powerset_permutation : tuple of int + Permutation in powerset space. + + Example + ------- + >>> powerset = Powerset(3, 2) + >>> powerset._permutation_powerset((1, 0, 2)) + # (0, 2, 1, 3, 4, 6, 5) + + """ + + permutated_mapping: torch.Tensor = self.mapping[:, multilabel_permutation] + + arange = torch.arange( + self.num_classes, device=self.mapping.device, dtype=torch.int + ) + powers_of_two = (2**arange).tile((self.num_powerset_classes, 1)) + + # compute the encoding of the powerset classes in this 2**N space, before and after + # permutation of the columns (mapping cols=labels, mapping rows=powerset classes) + before = torch.sum(self.mapping * powers_of_two, dim=-1) + after = torch.sum(permutated_mapping * powers_of_two, dim=-1) + + # find before-to-after permutation + powerset_permutation = (before[None] == after[:, None]).int().argmax(dim=0) + + # return as tuple of indices + return tuple(powerset_permutation.tolist()) + + @cached_property + def permutation_mapping(self) -> Dict[Tuple[int, ...], Tuple[int, ...]]: + """Mapping between multilabel and powerset permutations + + Example + ------- + With num_classes == 3 and max_set_size == 2, returns + + { + (0, 1, 2): (0, 1, 2, 3, 4, 5, 6), + (0, 2, 1): (0, 1, 3, 2, 5, 4, 6), + (1, 0, 2): (0, 2, 1, 3, 4, 6, 5), + (1, 2, 0): (0, 2, 3, 1, 6, 4, 5), + (2, 0, 1): (0, 3, 1, 2, 5, 6, 4), + (2, 1, 0): (0, 3, 2, 1, 6, 5, 4) + } + """ + permutation_mapping = {} + + for multilabel_permutation in permutations( + range(self.num_classes), self.num_classes + ): + permutation_mapping[ + tuple(multilabel_permutation) + ] = self._permutation_powerset(multilabel_permutation) + + return permutation_mapping diff --git a/pyannote/audio/utils/preprocessors.py b/pyannote/audio/utils/preprocessors.py index ce4685d1f..b26553bf9 100644 --- a/pyannote/audio/utils/preprocessors.py +++ b/pyannote/audio/utils/preprocessors.py @@ -27,12 +27,13 @@ # Hervé BREDIN - http://herve.niderb.fr from functools import reduce -from itertools import chain from typing import Dict, List, Optional, Set from pyannote.core import Annotation, Segment from pyannote.database import ProtocolFile +from pyannote.audio.core.io import Audio, get_torchaudio_info + class LowerTemporalResolution: """Artificially degrade temporal resolution of reference annotation @@ -50,7 +51,6 @@ def __init__(self, resolution: float = 0.1): self.resolution = resolution def __call__(self, current_file: ProtocolFile) -> Annotation: - annotation = current_file["annotation"] new_annotation = annotation.empty() @@ -128,3 +128,17 @@ def __call__(self, current_file: ProtocolFile) -> Annotation: derived[seg] = intersect_label return derived + + +class Waveform: + def __init__(self): + self._audio = Audio() + + def __call__(self, file: ProtocolFile): + waveform, _ = self._audio(file) + return waveform + + +class SampleRate: + def __call__(self, file: ProtocolFile): + return get_torchaudio_info(file).sample_rate diff --git a/pyannote/audio/utils/preview.py b/pyannote/audio/utils/preview.py index fcdf4d124..1a5ace08c 100644 --- a/pyannote/audio/utils/preview.py +++ b/pyannote/audio/utils/preview.py @@ -47,7 +47,7 @@ MOVIEPY_INSTALLED = False -from typing import Mapping +from typing import Mapping, Optional import torch from pyannote.core import ( @@ -64,7 +64,7 @@ from pyannote.audio.utils.signal import Binarize -def listen(audio_file: AudioFile, segment: Segment = None) -> None: +def listen(audio_file: AudioFile, segment: Optional[Segment] = None) -> None: """listen to audio Allows playing of audio files. It will play the whole thing unless @@ -91,7 +91,7 @@ def listen(audio_file: AudioFile, segment: Segment = None) -> None: def preview( audio_file: AudioFile, - segment: Segment = None, + segment: Optional[Segment] = None, zoom: float = 10.0, video_fps: int = 5, video_ext: str = "webm", diff --git a/pyannote/audio/utils/random.py b/pyannote/audio/utils/random.py index 97d50c362..0006ad612 100644 --- a/pyannote/audio/utils/random.py +++ b/pyannote/audio/utils/random.py @@ -22,12 +22,13 @@ import os +import zlib from random import Random import torch -def create_rng_for_worker(epoch: int) -> Random: +def create_rng_for_worker(model) -> Random: """Create worker-specific random number generator This makes sure that @@ -43,19 +44,23 @@ def create_rng_for_worker(epoch: int) -> Random: # create random number generator rng = Random() - #  create seed as a combination of PL_GLOBAL_SEED (set by pl.seed_everything()) - #  and other PL multi-processing variables - global_seed = int(os.environ.get("PL_GLOBAL_SEED", "0")) - local_rank = int(os.environ.get("LOCAL_RANK", "0")) - node_rank = int(os.environ.get("NODE_RANK", "0")) - + global_seed = os.environ.get("PL_GLOBAL_SEED", "unset") worker_info = torch.utils.data.get_worker_info() if worker_info is None: - worker_id = 0 + worker_id = None else: worker_id = worker_info.id - rng.seed(hash((global_seed, worker_id, local_rank, node_rank, epoch))) + seed_tuple = ( + global_seed, + worker_id, + model.local_rank, + model.global_rank, + model.current_epoch, + ) + # use adler32 because python's `hash` is not deterministic. + seed = zlib.adler32(str(seed_tuple).encode()) + rng.seed(seed) return rng diff --git a/pyannote/audio/utils/receptive_field.py b/pyannote/audio/utils/receptive_field.py new file mode 100644 index 000000000..420a62de0 --- /dev/null +++ b/pyannote/audio/utils/receptive_field.py @@ -0,0 +1,165 @@ +# MIT License +# +# Copyright (c) 2023 CNRS +# +# 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. + +from typing import List + + +def conv1d_num_frames( + num_samples, kernel_size=5, stride=1, padding=0, dilation=1 +) -> int: + """Compute expected number of frames after 1D convolution + + Parameters + ---------- + num_samples : int + Number of samples in the input signal + kernel_size : int + Kernel size + stride : int + Stride + padding : int + Padding + dilation : int + Dilation + + Returns + ------- + num_frames : int + Number of frames in the output signal + + Source + ------ + https://pytorch.org/docs/stable/generated/torch.nn.Conv1d.html#torch.nn.Conv1d + """ + return 1 + (num_samples + 2 * padding - dilation * (kernel_size - 1) - 1) // stride + + +def multi_conv_num_frames( + num_samples: int, + kernel_size: List[int] = None, + stride: List[int] = None, + padding: List[int] = None, + dilation: List[int] = None, +) -> int: + num_frames = num_samples + for k, s, p, d in zip(kernel_size, stride, padding, dilation): + num_frames = conv1d_num_frames( + num_frames, kernel_size=k, stride=s, padding=p, dilation=d + ) + + return num_frames + + +def conv1d_receptive_field_size( + num_frames=1, kernel_size=5, stride=1, padding=0, dilation=1 +): + """Compute size of receptive field + + Parameters + ---------- + num_frames : int, optional + Number of frames in the output signal + kernel_size : int + Kernel size + stride : int + Stride + padding : int + Padding + dilation : int + Dilation + + Returns + ------- + size : int + Receptive field size + """ + + effective_kernel_size = 1 + (kernel_size - 1) * dilation + return effective_kernel_size + (num_frames - 1) * stride - 2 * padding + + +def multi_conv_receptive_field_size( + num_frames: int, + kernel_size: List[int] = None, + stride: List[int] = None, + padding: List[int] = None, + dilation: List[int] = None, +) -> int: + receptive_field_size = num_frames + + for k, s, p, d in reversed(list(zip(kernel_size, stride, padding, dilation))): + receptive_field_size = conv1d_receptive_field_size( + num_frames=receptive_field_size, + kernel_size=k, + stride=s, + padding=p, + dilation=d, + ) + return receptive_field_size + + +def conv1d_receptive_field_center( + frame=0, kernel_size=5, stride=1, padding=0, dilation=1 +) -> int: + """Compute center of receptive field + + Parameters + ---------- + frame : int + Frame index + kernel_size : int + Kernel size + stride : int + Stride + padding : int + Padding + dilation : int + Dilation + + Returns + ------- + center : int + Index of receptive field center + """ + + effective_kernel_size = 1 + (kernel_size - 1) * dilation + return frame * stride + (effective_kernel_size - 1) // 2 - padding + + +def multi_conv_receptive_field_center( + frame: int, + kernel_size: List[int] = None, + stride: List[int] = None, + padding: List[int] = None, + dilation: List[int] = None, +) -> int: + receptive_field_center = frame + for k, s, p, d in reversed(list(zip(kernel_size, stride, padding, dilation))): + receptive_field_center = conv1d_receptive_field_center( + frame=receptive_field_center, + kernel_size=k, + stride=s, + padding=p, + dilation=d, + ) + + return receptive_field_center diff --git a/requirements.txt b/requirements.txt index 7e71fe024..3a0aa74dc 100644 --- a/requirements.txt +++ b/requirements.txt @@ -15,5 +15,5 @@ speechbrain >= 0.5.14 tensorboardX >= 2.6 torch >= 2.0.0 torch_audiomentations >= 0.11.0 -torchaudio >= 2.0.0 +torchaudio >= 2.2.0 torchmetrics >= 0.11.0 diff --git a/tests/data/database.yml b/tests/data/database.yml index 608bf40b4..10d3fb084 100644 --- a/tests/data/database.yml +++ b/tests/data/database.yml @@ -2,6 +2,7 @@ Protocols: Debug: SpeakerDiarization: Debug: + scope: database train: uri: debug.train.lst annotation: debug.train.rttm diff --git a/tests/data/debug.train.lst b/tests/data/debug.train.lst index 16be824f4..471bf03d4 100644 --- a/tests/data/debug.train.lst +++ b/tests/data/debug.train.lst @@ -1,4 +1,4 @@ -trn00 +trñ00 trn01 trn02 trn03 diff --git a/tests/data/debug.train.rttm b/tests/data/debug.train.rttm index 004a3f2eb..be89e2a4c 100644 --- a/tests/data/debug.train.rttm +++ b/tests/data/debug.train.rttm @@ -1,26 +1,26 @@ -SPEAKER trn00 1 3.168 0.800 MEO069 -SPEAKER trn00 1 5.463 0.640 MEO069 +SPEAKER trn00 1 3.168 0.800 MÉO069 +SPEAKER trn00 1 5.463 0.640 MÉO069 SPEAKER trn00 1 5.496 0.574 MEE068 -SPEAKER trn00 1 10.454 0.499 MEO069 +SPEAKER trn00 1 10.454 0.499 MÉO069 SPEAKER trn00 1 11.040 4.592 MEE068 -SPEAKER trn00 1 16.736 1.410 MEO069 +SPEAKER trn00 1 16.736 1.410 MÉO069 SPEAKER trn00 1 16.980 2.778 MEE067 SPEAKER trn00 1 18.883 0.490 MEE068 -SPEAKER trn00 1 18.985 1.831 MEO069 +SPEAKER trn00 1 18.985 1.831 MÉO069 SPEAKER trn00 1 20.944 0.447 MEE067 SPEAKER trn00 1 21.392 4.465 MEE068 -SPEAKER trn00 1 22.928 0.384 MEO069 -SPEAKER trn00 1 25.001 2.471 MEO069 +SPEAKER trn00 1 22.928 0.384 MÉO069 +SPEAKER trn00 1 25.001 2.471 MÉO069 SPEAKER trn00 1 28.033 1.967 MEE068 SPEAKER trn01 1 2.977 0.391 FEO066 SPEAKER trn01 1 18.705 0.964 MEE068 SPEAKER trn01 1 22.269 0.457 FEO065 -SPEAKER trn01 1 28.474 1.526 MEO069 +SPEAKER trn01 1 28.474 1.526 MÉO069 SPEAKER trn01 1 28.593 1.407 FEO066 SPEAKER trn01 1 28.993 1.007 FEO065 SPEAKER trn02 1 20.704 0.688 FEO066 SPEAKER trn03 1 0.000 1.184 MEE067 -SPEAKER trn03 1 1.104 28.896 MEO069 +SPEAKER trn03 1 1.104 28.896 MÉO069 SPEAKER trn04 1 14.032 1.744 MEE076 SPEAKER trn04 1 14.345 2.471 MEO074 SPEAKER trn04 1 16.736 7.216 MEE075 diff --git a/tests/data/trn00.wav "b/tests/data/tr\303\26100.wav" similarity index 100% rename from tests/data/trn00.wav rename to "tests/data/tr\303\26100.wav" diff --git a/tests/inference_test.py b/tests/inference_test.py index bd5040394..da28b79d2 100644 --- a/tests/inference_test.py +++ b/tests/inference_test.py @@ -9,7 +9,7 @@ from pyannote.audio.models.segmentation.debug import SimpleSegmentationModel from pyannote.audio.tasks import VoiceActivityDetection -HF_SAMPLE_MODEL_ID = "pyannote/TestModelForContinuousIntegration" +HF_SAMPLE_MODEL_ID = "pyannote/ci-segmentation" def test_hf_download_inference(): diff --git a/tests/tasks/test_reproducibility.py b/tests/tasks/test_reproducibility.py index a7307e0cf..88f2b2d8a 100644 --- a/tests/tasks/test_reproducibility.py +++ b/tests/tasks/test_reproducibility.py @@ -3,7 +3,7 @@ from pyannote.database import FileFinder, get_protocol from pyannote.audio.models.segmentation.debug import SimpleSegmentationModel -from pyannote.audio.tasks import MultiLabelSegmentation, VoiceActivityDetection +from pyannote.audio.tasks import VoiceActivityDetection def setup_tasks(task): @@ -16,7 +16,8 @@ def setup_tasks(task): def create_dl(model, task): m = model(task=task) - m.setup("fit") + m.prepare_data() + m.setup() return task.train_dataloader() @@ -31,35 +32,32 @@ def get_next5(dl): def test_seeding_ensures_data_loaders(): "Setting a global seed for the dataloaders ensures that we get data back in the same order" - for task in [VoiceActivityDetection, MultiLabelSegmentation]: + seed_everything(1) + protocol, vad = setup_tasks(VoiceActivityDetection) + dl = create_dl(SimpleSegmentationModel, vad) + last5a = get_next5(dl) - seed_everything(1) - protocol, vad = setup_tasks(task) - dl = create_dl(SimpleSegmentationModel, vad) - last5a = get_next5(dl) + seed_everything(1) + protocol, vad = setup_tasks(VoiceActivityDetection) + dl = create_dl(SimpleSegmentationModel, vad) + last5b = get_next5(dl) - seed_everything(1) - protocol, vad = setup_tasks(task) - dl = create_dl(SimpleSegmentationModel, vad) - last5b = get_next5(dl) - - for i in range(len(last5b)): - assert torch.equal(last5a[i]["X"], last5b[i]["X"]) + for i in range(len(last5b)): + assert torch.equal(last5a[i]["X"], last5b[i]["X"]) def test_different_seeds(): "Changing the global seed will change the order of the data that loads" - for task in [VoiceActivityDetection, MultiLabelSegmentation]: - protocol, vad = setup_tasks(task) - seed_everything(4) - dl = create_dl(SimpleSegmentationModel, vad) - last5a = get_next5(dl) + protocol, vad = setup_tasks(VoiceActivityDetection) + seed_everything(4) + dl = create_dl(SimpleSegmentationModel, vad) + last5a = get_next5(dl) - protocol, vad = setup_tasks(task) - seed_everything(5) - dl = create_dl(SimpleSegmentationModel, vad) - last5b = get_next5(dl) + protocol, vad = setup_tasks(VoiceActivityDetection) + seed_everything(5) + dl = create_dl(SimpleSegmentationModel, vad) + last5b = get_next5(dl) - for i in range(5): - assert not torch.equal(last5a[i]["X"], last5b[i]["X"]) + for i in range(5): + assert not torch.equal(last5a[i]["X"], last5b[i]["X"]) diff --git a/tests/tasks/test_specifications.py b/tests/tasks/test_specifications.py new file mode 100644 index 000000000..32b816155 --- /dev/null +++ b/tests/tasks/test_specifications.py @@ -0,0 +1,27 @@ +import pytest +from pyannote.database import FileFinder, get_protocol + +from pyannote.audio.core.model import Model +from pyannote.audio.core.task import UnknownSpecificationsError +from pyannote.audio.tasks import SpeakerDiarization + + +@pytest.fixture() +def protocol(): + return get_protocol( + "Debug.SpeakerDiarization.Debug", preprocessors={"audio": FileFinder()} + ) + + +def test_unknown_specifications_error_raised_on_non_setup_task(protocol): + task = SpeakerDiarization(protocol=protocol) + with pytest.raises(UnknownSpecificationsError): + _ = task.specifications + + +def test_unknown_specifications_error_raised_on_non_setup_model_task(protocol): + task = SpeakerDiarization(protocol=protocol) + model = Model.from_pretrained("pyannote/ci-segmentation") + model.task = task + with pytest.raises(UnknownSpecificationsError): + _ = model.specifications diff --git a/tests/test_cli.py b/tests/test_cli.py new file mode 100644 index 000000000..f62cc5260 --- /dev/null +++ b/tests/test_cli.py @@ -0,0 +1,149 @@ +# The MIT License (MIT) +# +# Copyright (c) 2024- CNRS +# +# 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. + +import subprocess + +import pytest +from pyannote.database import FileFinder, get_protocol + + +@pytest.fixture() +def protocol(): + return get_protocol( + "Debug.SpeakerDiarization.Debug", preprocessors={"audio": FileFinder()} + ) + + +@pytest.fixture() +def database(): + return "./tests/data/database.yml" + + +@pytest.fixture() +def model(): + return "pyannote/ci-segmentation" + + +def test_cli_train_vad(database, protocol): + res = subprocess.run( + [ + "pyannote-audio-train", + "model=DebugSegmentation", + "task=VoiceActivityDetection", + f"+registry={database}", + f"protocol={protocol.name}", + "trainer=fast_dev_run", + "hydra.run.dir=.", # run hydra app in current directory + "hydra.output_subdir=null", # disable hydra outputs + "hydra/hydra_logging=disabled", + "hydra/job_logging=disabled", + ] + ) + assert res.returncode == 0 + + +def test_cli_train_segmentation(database, protocol): + res = subprocess.run( + [ + "pyannote-audio-train", + "model=DebugSegmentation", + "task=SpeakerDiarization", + f"+registry={database}", + f"protocol={protocol.name}", + "trainer=fast_dev_run", + "hydra.run.dir=.", # run hydra app in current directory + "hydra.output_subdir=null", # disable hydra outputs + "hydra/hydra_logging=disabled", + "hydra/job_logging=disabled", + ] + ) + assert res.returncode == 0 + + +def test_cli_train_osd(database, protocol): + res = subprocess.run( + [ + "pyannote-audio-train", + "model=DebugSegmentation", + "task=OverlappedSpeechDetection", + f"+registry={database}", + f"protocol={protocol.name}", + "trainer=fast_dev_run", + "hydra.run.dir=.", # run hydra app in current directory + "hydra.output_subdir=null", # disable hydra outputs + "hydra/hydra_logging=disabled", + "hydra/job_logging=disabled", + ] + ) + assert res.returncode == 0 + + +def test_cli_train_supervised_representation_with_arcface(database, protocol): + res = subprocess.run( + [ + "pyannote-audio-train", + "model=DebugEmbedding", + "task=SpeakerEmbedding", + f"+registry={database}", + f"protocol={protocol.name}", + "trainer=fast_dev_run", + "hydra.run.dir=.", # run hydra app in current directory + "hydra.output_subdir=null", # disable hydra outputs + "hydra/hydra_logging=disabled", + "hydra/job_logging=disabled", + ] + ) + assert res.returncode == 0 + + +def test_cli_train_segmentation_with_pyannet(database, protocol): + res = subprocess.run( + [ + "pyannote-audio-train", + "model=PyanNet", + "task=SpeakerDiarization", + f"+registry={database}", + f"protocol={protocol.name}", + "trainer=fast_dev_run", + "hydra.run.dir=.", # run hydra app in current directory + "hydra.output_subdir=null", # disable hydra outputs + "hydra/hydra_logging=disabled", + "hydra/job_logging=disabled", + ] + ) + assert res.returncode == 0 + + +def test_cli_eval_segmentation_model(database, protocol, model): + res = subprocess.run( + [ + "pyannote-audio-eval", + f"model={model}", + f"+registry={database}", + f"protocol={protocol.name}", + "hydra.run.dir=.", # run hydra app in current directory + "hydra.output_subdir=null", # disable hydra outputs + "hydra/hydra_logging=disabled", + "hydra/job_logging=disabled", + ] + ) + assert res.returncode == 0 diff --git a/tests/test_metrics.py b/tests/test_metrics.py new file mode 100644 index 000000000..c366dc091 --- /dev/null +++ b/tests/test_metrics.py @@ -0,0 +1,142 @@ +# MIT License +# +# Copyright (c) 2024- CNRS +# +# 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. + +import pytest +import torch + +from pyannote.audio.torchmetrics.functional.audio.diarization_error_rate import ( + _der_update, + diarization_error_rate, +) + + +@pytest.fixture +def target(): + chunk1 = [[0, 0], [1, 0], [1, 0], [1, 1], [1, 1], [0, 1], [0, 1]] + chunk2 = [[0, 0], [0, 0], [1, 0], [1, 0], [1, 0], [1, 0], [0, 0]] + return torch.tensor([chunk1, chunk2], dtype=torch.float32).transpose(2, 1) + + +@pytest.fixture +def prediction(): + chunk1 = [[0, 0], [1, 0], [0, 0], [1, 1], [0, 1], [1, 1], [1, 0]] + chunk2 = [[0, 0], [0, 0], [0, 1], [0, 1], [0, 1], [1, 1], [1, 0]] + return torch.tensor([chunk1, chunk2], dtype=torch.float32).transpose(2, 1) + + +def test_frame_reduction(target, prediction): + false_alarm, missed_detection, speaker_confusion, speech_total = _der_update( + prediction, target, reduce="frame" + ) + + torch.testing.assert_close( + false_alarm, + torch.Tensor( + [[0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0], [0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 1.0]] + ), + ) + + torch.testing.assert_close( + missed_detection, + torch.Tensor( + [ + [0.0, 0.0, 1.0, 0.0, 1.0, 0.0, 0.0], + [0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], + ] + ), + ) + + torch.testing.assert_close( + speaker_confusion, + torch.Tensor( + [[0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0], [0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0]] + ), + ) + + torch.testing.assert_close( + speech_total, + torch.Tensor( + [[0.0, 1.0, 1.0, 2.0, 2.0, 1.0, 1.0], [0.0, 0.0, 1.0, 1.0, 1.0, 1.0, 0.0]] + ), + ) + + +def test_chunk_reduction(target, prediction): + false_alarm, missed_detection, speaker_confusion, speech_total = _der_update( + prediction, target, reduce="chunk" + ) + + torch.testing.assert_close( + false_alarm, + torch.Tensor([1.0, 2.0]), + ) + + torch.testing.assert_close( + missed_detection, + torch.Tensor([2.0, 0.0]), + ) + + torch.testing.assert_close( + speaker_confusion, + torch.Tensor([1.0, 0.0]), + ) + + torch.testing.assert_close( + speech_total, + torch.Tensor([8.0, 4.0]), + ) + + +def test_batch_reduction(target, prediction): + false_alarm, missed_detection, speaker_confusion, speech_total = _der_update( + prediction, target, reduce="batch" + ) + torch.testing.assert_close(false_alarm.item(), 3.0) + torch.testing.assert_close(missed_detection.item(), 2.0) + torch.testing.assert_close(speaker_confusion.item(), 1.0) + torch.testing.assert_close(speech_total.item(), 12.0) + + +def test_batch_der(target, prediction): + der = diarization_error_rate(prediction, target, reduce="batch") + torch.testing.assert_close(der.item(), (3.0 + 2.0 + 1.0) / 12.0) + + +def test_batch_der_with_components(target, prediction): + der, ( + false_alarm, + missed_detection, + speaker_confusion, + speech_total, + ) = diarization_error_rate( + prediction, target, reduce="batch", return_components=True + ) + torch.testing.assert_close(der.item(), (3.0 + 2.0 + 1.0) / 12.0) + torch.testing.assert_close(false_alarm.item(), 3.0) + torch.testing.assert_close(missed_detection.item(), 2.0) + torch.testing.assert_close(speaker_confusion.item(), 1.0) + torch.testing.assert_close(speech_total.item(), 12.0) + + +def test_chunk_der(target, prediction): + der = diarization_error_rate(prediction, target, reduce="chunk") + torch.testing.assert_close(der, torch.Tensor([4.0 / 8.0, 2.0 / 4.0])) diff --git a/tests/test_sample.py b/tests/test_sample.py new file mode 100644 index 000000000..d47dc9613 --- /dev/null +++ b/tests/test_sample.py @@ -0,0 +1,28 @@ +# The MIT License (MIT) +# +# Copyright (c) 2024- CNRS +# +# 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. + + +def test_sample(): + from pyannote.audio.sample import SAMPLE_FILE + + assert "annotation" in SAMPLE_FILE + assert "annotated" in SAMPLE_FILE diff --git a/tests/test_train.py b/tests/test_train.py index 7a7bfe338..6a7a6c69b 100644 --- a/tests/test_train.py +++ b/tests/test_train.py @@ -1,11 +1,39 @@ +# The MIT License (MIT) +# +# Copyright (c) 2024- CNRS +# +# 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. + + +from tempfile import mkstemp + import pytest from pyannote.database import FileFinder, get_protocol from pytorch_lightning import Trainer +from pyannote.audio.models.embedding.debug import SimpleEmbeddingModel from pyannote.audio.models.segmentation.debug import SimpleSegmentationModel from pyannote.audio.tasks import ( + MultiLabelSegmentation, OverlappedSpeechDetection, SpeakerDiarization, + SupervisedRepresentationLearningWithArcFace, VoiceActivityDetection, ) @@ -17,6 +45,31 @@ def protocol(): ) +@pytest.fixture() +def cache(): + return mkstemp()[1] + + +@pytest.fixture() +def gender_protocol(): + def to_gender(file): + annotation = file["annotation"] + mapping = {label: label[0] for label in annotation.labels()} + return annotation.rename_labels(mapping) + + def classes(file): + return ["M", "F"] + + return get_protocol( + "Debug.SpeakerDiarization.Debug", + preprocessors={ + "audio": FileFinder(), + "annotation": to_gender, + "classes": classes, + }, + ) + + def test_train_segmentation(protocol): segmentation = SpeakerDiarization(protocol) model = SimpleSegmentationModel(task=segmentation) @@ -24,6 +77,48 @@ def test_train_segmentation(protocol): trainer.fit(model) +def test_train_segmentation_with_cached_data_mono_device(protocol, cache): + first_task = SpeakerDiarization(protocol, cache=cache) + first_model = SimpleSegmentationModel(task=first_task) + first_trainer = Trainer(fast_dev_run=True, accelerator="cpu", devices=1) + first_trainer.fit(first_model) + + second_task = SpeakerDiarization(protocol, cache=cache) + second_model = SimpleSegmentationModel(task=second_task) + second_trainer = Trainer(fast_dev_run=True, accelerator="cpu", devices=1) + second_trainer.fit(second_model) + + +def test_train_multilabel_segmentation(gender_protocol): + multilabel_segmentation = MultiLabelSegmentation(gender_protocol) + model = SimpleSegmentationModel(task=multilabel_segmentation) + trainer = Trainer(fast_dev_run=True, accelerator="cpu") + trainer.fit(model) + + +def test_train_multilabel_segmentation_with_cached_data_mono_device( + gender_protocol, cache +): + first_task = MultiLabelSegmentation(gender_protocol, cache=cache) + first_model = SimpleSegmentationModel(task=first_task) + first_trainer = Trainer(fast_dev_run=True, accelerator="cpu", devices=1) + first_trainer.fit(first_model) + + second_task = MultiLabelSegmentation(gender_protocol, cache=cache) + second_model = SimpleSegmentationModel(task=second_task) + second_trainer = Trainer(fast_dev_run=True, accelerator="cpu", devices=1) + second_trainer.fit(second_model) + + +def test_train_supervised_representation_with_arcface(protocol): + supervised_representation_with_arface = SupervisedRepresentationLearningWithArcFace( + protocol + ) + model = SimpleEmbeddingModel(task=supervised_representation_with_arface) + trainer = Trainer(fast_dev_run=True, accelerator="cpu") + trainer.fit(model) + + def test_train_voice_activity_detection(protocol): voice_activity_detection = VoiceActivityDetection(protocol) model = SimpleSegmentationModel(task=voice_activity_detection) @@ -31,6 +126,18 @@ def test_train_voice_activity_detection(protocol): trainer.fit(model) +def test_train_voice_activity_detection_with_cached_data_mono_device(protocol, cache): + first_task = VoiceActivityDetection(protocol, cache=cache) + first_model = SimpleSegmentationModel(task=first_task) + first_trainer = Trainer(fast_dev_run=True, accelerator="cpu", devices=1) + first_trainer.fit(first_model) + + second_task = VoiceActivityDetection(protocol, cache=cache) + second_model = SimpleSegmentationModel(task=second_task) + second_trainer = Trainer(fast_dev_run=True, accelerator="cpu", devices=1) + second_trainer.fit(second_model) + + def test_train_overlapped_speech_detection(protocol): overlapped_speech_detection = OverlappedSpeechDetection(protocol) model = SimpleSegmentationModel(task=overlapped_speech_detection) @@ -38,6 +145,20 @@ def test_train_overlapped_speech_detection(protocol): trainer.fit(model) +def test_train_overlapped_speech_detection_with_cached_data_mono_device( + protocol, cache +): + first_task = OverlappedSpeechDetection(protocol, cache=cache) + first_model = SimpleSegmentationModel(task=first_task) + first_trainer = Trainer(fast_dev_run=True, accelerator="cpu", devices=1) + first_trainer.fit(first_model) + + second_task = OverlappedSpeechDetection(protocol, cache=cache) + second_model = SimpleSegmentationModel(task=second_task) + second_trainer = Trainer(fast_dev_run=True, accelerator="cpu", devices=1) + second_trainer.fit(second_model) + + def test_finetune_with_task_that_does_not_need_setup_for_specs(protocol): voice_activity_detection = VoiceActivityDetection(protocol) model = SimpleSegmentationModel(task=voice_activity_detection) @@ -62,6 +183,18 @@ def test_finetune_with_task_that_needs_setup_for_specs(protocol): trainer.fit(model) +def test_finetune_with_task_that_needs_setup_for_specs_and_with_cache(protocol, cache): + segmentation = SpeakerDiarization(protocol, cache=cache) + model = SimpleSegmentationModel(task=segmentation) + trainer = Trainer(fast_dev_run=True, accelerator="cpu") + trainer.fit(model) + + segmentation = SpeakerDiarization(protocol, cache=cache) + model.task = segmentation + trainer = Trainer(fast_dev_run=True, accelerator="cpu") + trainer.fit(model) + + def test_transfer_with_task_that_does_not_need_setup_for_specs(protocol): segmentation = SpeakerDiarization(protocol) model = SimpleSegmentationModel(task=segmentation) @@ -94,7 +227,22 @@ def test_finetune_freeze_with_task_that_needs_setup_for_specs(protocol): segmentation = SpeakerDiarization(protocol) model.task = segmentation - model.freeze_up_to("mfcc") + model.freeze_by_name("mfcc") + trainer = Trainer(fast_dev_run=True, accelerator="cpu") + trainer.fit(model) + + +def test_finetune_freeze_with_task_that_needs_setup_for_specs_and_with_cache( + protocol, cache +): + segmentation = SpeakerDiarization(protocol, cache=cache) + model = SimpleSegmentationModel(task=segmentation) + trainer = Trainer(fast_dev_run=True, accelerator="cpu") + trainer.fit(model) + + segmentation = SpeakerDiarization(protocol, cache=cache) + model.task = segmentation + model.freeze_by_name("mfcc") trainer = Trainer(fast_dev_run=True, accelerator="cpu") trainer.fit(model) @@ -107,7 +255,23 @@ def test_finetune_freeze_with_task_that_does_not_need_setup_for_specs(protocol): vad = VoiceActivityDetection(protocol) model.task = vad - model.freeze_up_to("mfcc") + model.freeze_by_name("mfcc") + trainer = Trainer(fast_dev_run=True, accelerator="cpu") + trainer.fit(model) + + +def test_finetune_freeze_with_task_that_does_not_need_setup_for_specs_and_with_cache( + protocol, + cache, +): + vad = VoiceActivityDetection(protocol, cache=cache) + model = SimpleSegmentationModel(task=vad) + trainer = Trainer(fast_dev_run=True, accelerator="cpu") + trainer.fit(model) + + vad = VoiceActivityDetection(protocol, cache=cache) + model.task = vad + model.freeze_by_name("mfcc") trainer = Trainer(fast_dev_run=True, accelerator="cpu") trainer.fit(model) @@ -120,7 +284,7 @@ def test_transfer_freeze_with_task_that_does_not_need_setup_for_specs(protocol): voice_activity_detection = VoiceActivityDetection(protocol) model.task = voice_activity_detection - model.freeze_up_to("mfcc") + model.freeze_by_name("mfcc") trainer = Trainer(fast_dev_run=True, accelerator="cpu") trainer.fit(model) @@ -133,6 +297,6 @@ def test_transfer_freeze_with_task_that_needs_setup_for_specs(protocol): segmentation = SpeakerDiarization(protocol) model.task = segmentation - model.freeze_up_to("mfcc") + model.freeze_by_name("mfcc") trainer = Trainer(fast_dev_run=True, accelerator="cpu") trainer.fit(model) diff --git a/tests/utils/test_powerset.py b/tests/utils/test_powerset.py index dd12eed41..e04480753 100644 --- a/tests/utils/test_powerset.py +++ b/tests/utils/test_powerset.py @@ -27,10 +27,8 @@ def test_roundtrip(): - for num_classes in range(2, 5): for max_set_size in range(1, num_classes + 1): - powerset = Powerset(num_classes, max_set_size) # simulate a sequence where each frame is assigned to a different powerset class @@ -51,3 +49,28 @@ def test_roundtrip(): reconstruction = powerset.to_powerset(batch_multilabel) assert torch.equal(batch_powerset, reconstruction) + + +def test_permutate_powerset(): + for num_classes in range(1, 6): + for max_set_size in range(1, num_classes + 1): + powerset = Powerset(num_classes, max_set_size) + + # create (num_powerset_class, num_powerset_class)-shaped tensor, where each frame is assigned to a different powerset class + # and convert it to its multi-label equivalent + t1 = torch.nn.functional.one_hot( + torch.arange(powerset.num_powerset_classes), + powerset.num_powerset_classes, + ) + t1_ml = powerset.to_multilabel(t1) + + # then permutate the powerset class in powerset space AND the multilabel equivalent in its native space + # and check it has the same result. + # perm = torch.randperm(num_classes) + perm = tuple(torch.randperm(num_classes).tolist()) + t1_ml_perm = t1_ml[:, perm] + perm_ps = powerset.permutation_mapping[perm] + t1_ps_perm = t1[..., perm_ps] + t1_ps_perm_ml = powerset.to_multilabel(t1_ps_perm) + + assert t1_ml_perm.equal(t1_ps_perm_ml) diff --git a/tutorials/MRE_template.ipynb b/tutorials/MRE_template.ipynb new file mode 100644 index 000000000..70ffacbc2 --- /dev/null +++ b/tutorials/MRE_template.ipynb @@ -0,0 +1,2220 @@ +{ + "nbformat": 4, + "nbformat_minor": 0, + "metadata": { + "colab": { + "provenance": [], + "gpuType": "T4", + "authorship_tag": "ABX9TyNUZLZoYLpzG6gIYECEOuiV", + "include_colab_link": true + }, + "kernelspec": { + "name": "python3", + "display_name": "Python 3" + }, + "language_info": { + "name": "python" + }, + "accelerator": "GPU", + "widgets": { + "application/vnd.jupyter.widget-state+json": { + "3d0fe95350234ab599497683ae6d4ce6": { + "model_module": "@jupyter-widgets/controls", + "model_name": "HBoxModel", + "model_module_version": "1.5.0", + "state": { + "_dom_classes": [], + "_model_module": "@jupyter-widgets/controls", + "_model_module_version": "1.5.0", + "_model_name": "HBoxModel", + "_view_count": null, + "_view_module": "@jupyter-widgets/controls", + "_view_module_version": "1.5.0", + "_view_name": "HBoxView", + "box_style": "", + "children": [ + "IPY_MODEL_239beda16fde4b1d9e6abfb47f036040", + "IPY_MODEL_2d6f5fe6f9ab4a8b853e7b023aaee35f", + "IPY_MODEL_771629a0fbab4b0e9ad6425b5affe380" + ], + "layout": "IPY_MODEL_8763b8e4c8104b879d4324257a810c0f" + } + }, + "239beda16fde4b1d9e6abfb47f036040": { + "model_module": "@jupyter-widgets/controls", + "model_name": "HTMLModel", + "model_module_version": "1.5.0", + "state": { + "_dom_classes": [], + "_model_module": "@jupyter-widgets/controls", + "_model_module_version": "1.5.0", + "_model_name": "HTMLModel", + "_view_count": null, + "_view_module": "@jupyter-widgets/controls", + "_view_module_version": "1.5.0", + "_view_name": "HTMLView", + "description": "", + "description_tooltip": null, + "layout": "IPY_MODEL_22536aef3997408dbf5ea58241f01e3e", + "placeholder": "​", + "style": "IPY_MODEL_2a6a5f33d7c34b6b996ab7a5b7c2f11d", + "value": "config.yaml: 100%" + } + }, + "2d6f5fe6f9ab4a8b853e7b023aaee35f": { + "model_module": "@jupyter-widgets/controls", + "model_name": "FloatProgressModel", + "model_module_version": "1.5.0", + "state": { + "_dom_classes": [], + "_model_module": "@jupyter-widgets/controls", + "_model_module_version": "1.5.0", + "_model_name": "FloatProgressModel", + "_view_count": null, + "_view_module": "@jupyter-widgets/controls", + "_view_module_version": "1.5.0", + "_view_name": "ProgressView", + "bar_style": "success", + "description": "", + "description_tooltip": null, + "layout": "IPY_MODEL_c348b2f57c6c437fa8a9a2688bf17f4f", + "max": 469, + "min": 0, + "orientation": "horizontal", + "style": "IPY_MODEL_7526127b349a4467a6d3083d92bef5ec", + "value": 469 + } + }, + "771629a0fbab4b0e9ad6425b5affe380": { + "model_module": "@jupyter-widgets/controls", + "model_name": "HTMLModel", + "model_module_version": "1.5.0", + "state": { + "_dom_classes": [], + "_model_module": "@jupyter-widgets/controls", + "_model_module_version": "1.5.0", + "_model_name": "HTMLModel", + "_view_count": null, + "_view_module": "@jupyter-widgets/controls", + "_view_module_version": "1.5.0", + "_view_name": "HTMLView", + "description": "", + "description_tooltip": null, + "layout": "IPY_MODEL_30efc0ed76fb496483d4bb425a930636", + "placeholder": "​", + "style": "IPY_MODEL_e760e231084f4889bb489bc550b7a816", + "value": " 469/469 [00:00<00:00, 21.8kB/s]" + } + }, + "8763b8e4c8104b879d4324257a810c0f": { + "model_module": "@jupyter-widgets/base", + "model_name": "LayoutModel", + "model_module_version": "1.2.0", + "state": { + "_model_module": "@jupyter-widgets/base", + "_model_module_version": "1.2.0", + "_model_name": "LayoutModel", + "_view_count": null, + "_view_module": "@jupyter-widgets/base", + "_view_module_version": "1.2.0", + "_view_name": "LayoutView", + "align_content": null, + "align_items": null, + "align_self": null, + "border": null, + "bottom": null, + "display": null, + "flex": null, + "flex_flow": null, + "grid_area": null, + "grid_auto_columns": null, + "grid_auto_flow": null, + "grid_auto_rows": null, + "grid_column": null, + "grid_gap": null, + "grid_row": null, + "grid_template_areas": null, + "grid_template_columns": null, + "grid_template_rows": null, + "height": null, + "justify_content": null, + "justify_items": null, + "left": null, + "margin": null, + "max_height": null, + "max_width": null, + "min_height": null, + "min_width": null, + "object_fit": null, + "object_position": null, + "order": null, + "overflow": null, + "overflow_x": null, + "overflow_y": null, + "padding": null, + "right": null, + "top": null, + "visibility": null, + "width": null + } + }, + "22536aef3997408dbf5ea58241f01e3e": { + "model_module": "@jupyter-widgets/base", + "model_name": "LayoutModel", + "model_module_version": "1.2.0", + "state": { + "_model_module": "@jupyter-widgets/base", + "_model_module_version": "1.2.0", + "_model_name": "LayoutModel", + "_view_count": null, + "_view_module": "@jupyter-widgets/base", + "_view_module_version": "1.2.0", + "_view_name": "LayoutView", + "align_content": null, + "align_items": null, + "align_self": null, + "border": null, + "bottom": null, + "display": null, + "flex": null, + "flex_flow": null, + "grid_area": null, + "grid_auto_columns": null, + "grid_auto_flow": null, + "grid_auto_rows": null, + "grid_column": null, + "grid_gap": null, + "grid_row": null, + "grid_template_areas": null, + "grid_template_columns": null, + "grid_template_rows": null, + "height": null, + "justify_content": null, + "justify_items": null, + "left": null, + "margin": null, + "max_height": null, + "max_width": null, + "min_height": null, + "min_width": null, + "object_fit": null, + "object_position": null, + "order": null, + "overflow": null, + "overflow_x": null, + "overflow_y": null, + "padding": null, + "right": null, + "top": null, + "visibility": null, + "width": null + } + }, + "2a6a5f33d7c34b6b996ab7a5b7c2f11d": { + "model_module": "@jupyter-widgets/controls", + "model_name": "DescriptionStyleModel", + "model_module_version": "1.5.0", + "state": { + "_model_module": "@jupyter-widgets/controls", + "_model_module_version": "1.5.0", + "_model_name": "DescriptionStyleModel", + "_view_count": null, + "_view_module": "@jupyter-widgets/base", + "_view_module_version": "1.2.0", + "_view_name": "StyleView", + "description_width": "" + } + }, + "c348b2f57c6c437fa8a9a2688bf17f4f": { + "model_module": "@jupyter-widgets/base", + "model_name": "LayoutModel", + "model_module_version": "1.2.0", + "state": { + "_model_module": "@jupyter-widgets/base", + "_model_module_version": "1.2.0", + "_model_name": "LayoutModel", + "_view_count": null, + "_view_module": "@jupyter-widgets/base", + "_view_module_version": "1.2.0", + "_view_name": "LayoutView", + "align_content": null, + "align_items": null, + "align_self": null, + "border": null, + "bottom": null, + "display": null, + "flex": null, + "flex_flow": null, + "grid_area": null, + "grid_auto_columns": null, + "grid_auto_flow": null, + "grid_auto_rows": null, + "grid_column": null, + "grid_gap": null, + "grid_row": null, + "grid_template_areas": null, + "grid_template_columns": null, + "grid_template_rows": null, + "height": null, + "justify_content": null, + "justify_items": null, + "left": null, + "margin": null, + "max_height": null, + "max_width": null, + "min_height": null, + "min_width": null, + "object_fit": null, + "object_position": null, + "order": null, + "overflow": null, + "overflow_x": null, + "overflow_y": null, + "padding": null, + "right": null, + "top": null, + "visibility": null, + "width": null + } + }, + "7526127b349a4467a6d3083d92bef5ec": { + "model_module": "@jupyter-widgets/controls", + "model_name": "ProgressStyleModel", + "model_module_version": "1.5.0", + "state": { + "_model_module": "@jupyter-widgets/controls", + "_model_module_version": "1.5.0", + "_model_name": "ProgressStyleModel", + "_view_count": null, + "_view_module": "@jupyter-widgets/base", + "_view_module_version": "1.2.0", + "_view_name": "StyleView", + "bar_color": null, + "description_width": "" + } + }, + "30efc0ed76fb496483d4bb425a930636": { + "model_module": "@jupyter-widgets/base", + "model_name": "LayoutModel", + "model_module_version": "1.2.0", + "state": { + "_model_module": "@jupyter-widgets/base", + "_model_module_version": "1.2.0", + "_model_name": "LayoutModel", + "_view_count": null, + "_view_module": "@jupyter-widgets/base", + "_view_module_version": "1.2.0", + "_view_name": "LayoutView", + "align_content": null, + "align_items": null, + "align_self": null, + "border": null, + "bottom": null, + "display": null, + "flex": null, + "flex_flow": null, + "grid_area": null, + "grid_auto_columns": null, + "grid_auto_flow": null, + "grid_auto_rows": null, + "grid_column": null, + "grid_gap": null, + "grid_row": null, + "grid_template_areas": null, + "grid_template_columns": null, + "grid_template_rows": null, + "height": null, + "justify_content": null, + "justify_items": null, + "left": null, + "margin": null, + "max_height": null, + "max_width": null, + "min_height": null, + "min_width": null, + "object_fit": null, + "object_position": null, + "order": null, + "overflow": null, + "overflow_x": null, + "overflow_y": null, + "padding": null, + "right": null, + "top": null, + "visibility": null, + "width": null + } + }, + "e760e231084f4889bb489bc550b7a816": { + "model_module": "@jupyter-widgets/controls", + "model_name": "DescriptionStyleModel", + "model_module_version": "1.5.0", + "state": { + "_model_module": "@jupyter-widgets/controls", + "_model_module_version": "1.5.0", + "_model_name": "DescriptionStyleModel", + "_view_count": null, + "_view_module": "@jupyter-widgets/base", + "_view_module_version": "1.2.0", + "_view_name": "StyleView", + "description_width": "" + } + }, + "9951dce8a6c947dd9a2ed6106cb68f30": { + "model_module": "@jupyter-widgets/controls", + "model_name": "HBoxModel", + "model_module_version": "1.5.0", + "state": { + "_dom_classes": [], + "_model_module": "@jupyter-widgets/controls", + "_model_module_version": "1.5.0", + "_model_name": "HBoxModel", + "_view_count": null, + "_view_module": "@jupyter-widgets/controls", + "_view_module_version": "1.5.0", + "_view_name": "HBoxView", + "box_style": "", + "children": [ + "IPY_MODEL_d68c24e62487484b83bbb06271a6981c", + "IPY_MODEL_467f3c9f15184784aa913cb3ae46700f", + "IPY_MODEL_c87055ce8cef498f999a20ff2b34e1b8" + ], + "layout": "IPY_MODEL_63d957e24276476b9bf1be150675217c" + } + }, + "d68c24e62487484b83bbb06271a6981c": { + "model_module": "@jupyter-widgets/controls", + "model_name": "HTMLModel", + "model_module_version": "1.5.0", + "state": { + "_dom_classes": [], + "_model_module": "@jupyter-widgets/controls", + "_model_module_version": "1.5.0", + "_model_name": "HTMLModel", + "_view_count": null, + "_view_module": "@jupyter-widgets/controls", + "_view_module_version": "1.5.0", + "_view_name": "HTMLView", + "description": "", + "description_tooltip": null, + "layout": "IPY_MODEL_afe35fd2ea654d7b861046e847f82e51", + "placeholder": "​", + "style": "IPY_MODEL_c5f4f5f5fbad4d14973dc21eae2358d4", + "value": "pytorch_model.bin: 100%" + } + }, + "467f3c9f15184784aa913cb3ae46700f": { + "model_module": "@jupyter-widgets/controls", + "model_name": "FloatProgressModel", + "model_module_version": "1.5.0", + "state": { + "_dom_classes": [], + "_model_module": "@jupyter-widgets/controls", + "_model_module_version": "1.5.0", + "_model_name": "FloatProgressModel", + "_view_count": null, + "_view_module": "@jupyter-widgets/controls", + "_view_module_version": "1.5.0", + "_view_name": "ProgressView", + "bar_style": "success", + "description": "", + "description_tooltip": null, + "layout": "IPY_MODEL_b4faa4c7fd01498abe07fef6189de4d4", + "max": 5905440, + "min": 0, + "orientation": "horizontal", + "style": "IPY_MODEL_35ab2642d8a5481780c43eaef7044f3c", + "value": 5905440 + } + }, + "c87055ce8cef498f999a20ff2b34e1b8": { + "model_module": "@jupyter-widgets/controls", + "model_name": "HTMLModel", + "model_module_version": "1.5.0", + "state": { + "_dom_classes": [], + "_model_module": "@jupyter-widgets/controls", + "_model_module_version": "1.5.0", + "_model_name": "HTMLModel", + "_view_count": null, + "_view_module": "@jupyter-widgets/controls", + "_view_module_version": "1.5.0", + "_view_name": "HTMLView", + "description": "", + "description_tooltip": null, + "layout": "IPY_MODEL_37de7e413b25451ca5288ea5f43dd2d5", + "placeholder": "​", + "style": "IPY_MODEL_47012c0ff9394d77b8d857a933b4082e", + "value": " 5.91M/5.91M [00:00<00:00, 66.3MB/s]" + } + }, + "63d957e24276476b9bf1be150675217c": { + "model_module": "@jupyter-widgets/base", + "model_name": "LayoutModel", + "model_module_version": "1.2.0", + "state": { + "_model_module": "@jupyter-widgets/base", + "_model_module_version": "1.2.0", + "_model_name": "LayoutModel", + "_view_count": null, + "_view_module": "@jupyter-widgets/base", + "_view_module_version": "1.2.0", + "_view_name": "LayoutView", + "align_content": null, + "align_items": null, + "align_self": null, + "border": null, + "bottom": null, + "display": null, + "flex": null, + "flex_flow": null, + "grid_area": null, + "grid_auto_columns": null, + "grid_auto_flow": null, + "grid_auto_rows": null, + "grid_column": null, + "grid_gap": null, + "grid_row": null, + "grid_template_areas": null, + "grid_template_columns": null, + "grid_template_rows": null, + "height": null, + "justify_content": null, + "justify_items": null, + "left": null, + "margin": null, + "max_height": null, + "max_width": null, + "min_height": null, + "min_width": null, + "object_fit": null, + "object_position": null, + "order": null, + "overflow": null, + "overflow_x": null, + "overflow_y": null, + "padding": null, + "right": null, + "top": null, + "visibility": null, + "width": null + } + }, + "afe35fd2ea654d7b861046e847f82e51": { + "model_module": "@jupyter-widgets/base", + "model_name": "LayoutModel", + "model_module_version": "1.2.0", + "state": { + "_model_module": "@jupyter-widgets/base", + "_model_module_version": "1.2.0", + "_model_name": "LayoutModel", + "_view_count": null, + "_view_module": "@jupyter-widgets/base", + "_view_module_version": "1.2.0", + "_view_name": "LayoutView", + "align_content": null, + "align_items": null, + "align_self": null, + "border": null, + "bottom": null, + "display": null, + "flex": null, + "flex_flow": null, + "grid_area": null, + "grid_auto_columns": null, + "grid_auto_flow": null, + "grid_auto_rows": null, + "grid_column": null, + "grid_gap": null, + "grid_row": null, + "grid_template_areas": null, + "grid_template_columns": null, + "grid_template_rows": null, + "height": null, + "justify_content": null, + "justify_items": null, + "left": null, + "margin": null, + "max_height": null, + "max_width": null, + "min_height": null, + "min_width": null, + "object_fit": null, + "object_position": null, + "order": null, + "overflow": null, + "overflow_x": null, + "overflow_y": null, + "padding": null, + "right": null, + "top": null, + "visibility": null, + "width": null + } + }, + "c5f4f5f5fbad4d14973dc21eae2358d4": { + "model_module": "@jupyter-widgets/controls", + "model_name": "DescriptionStyleModel", + "model_module_version": "1.5.0", + "state": { + "_model_module": "@jupyter-widgets/controls", + "_model_module_version": "1.5.0", + "_model_name": "DescriptionStyleModel", + "_view_count": null, + "_view_module": "@jupyter-widgets/base", + "_view_module_version": "1.2.0", + "_view_name": "StyleView", + "description_width": "" + } + }, + "b4faa4c7fd01498abe07fef6189de4d4": { + "model_module": "@jupyter-widgets/base", + "model_name": "LayoutModel", + "model_module_version": "1.2.0", + "state": { + "_model_module": "@jupyter-widgets/base", + "_model_module_version": "1.2.0", + "_model_name": "LayoutModel", + "_view_count": null, + "_view_module": "@jupyter-widgets/base", + "_view_module_version": "1.2.0", + "_view_name": "LayoutView", + "align_content": null, + "align_items": null, + "align_self": null, + "border": null, + "bottom": null, + "display": null, + "flex": null, + "flex_flow": null, + "grid_area": null, + "grid_auto_columns": null, + "grid_auto_flow": null, + "grid_auto_rows": null, + "grid_column": null, + "grid_gap": null, + "grid_row": null, + "grid_template_areas": null, + "grid_template_columns": null, + "grid_template_rows": null, + "height": null, + "justify_content": null, + "justify_items": null, + "left": null, + "margin": null, + "max_height": null, + "max_width": null, + "min_height": null, + "min_width": null, + "object_fit": null, + "object_position": null, + "order": null, + "overflow": null, + "overflow_x": null, + "overflow_y": null, + "padding": null, + "right": null, + "top": null, + "visibility": null, + "width": null + } + }, + "35ab2642d8a5481780c43eaef7044f3c": { + "model_module": "@jupyter-widgets/controls", + "model_name": "ProgressStyleModel", + "model_module_version": "1.5.0", + "state": { + "_model_module": "@jupyter-widgets/controls", + "_model_module_version": "1.5.0", + "_model_name": "ProgressStyleModel", + "_view_count": null, + "_view_module": "@jupyter-widgets/base", + "_view_module_version": "1.2.0", + "_view_name": "StyleView", + "bar_color": null, + "description_width": "" + } + }, + "37de7e413b25451ca5288ea5f43dd2d5": { + "model_module": "@jupyter-widgets/base", + "model_name": "LayoutModel", + "model_module_version": "1.2.0", + "state": { + "_model_module": "@jupyter-widgets/base", + "_model_module_version": "1.2.0", + "_model_name": "LayoutModel", + "_view_count": null, + "_view_module": "@jupyter-widgets/base", + "_view_module_version": "1.2.0", + "_view_name": "LayoutView", + "align_content": null, + "align_items": null, + "align_self": null, + "border": null, + "bottom": null, + "display": null, + "flex": null, + "flex_flow": null, + "grid_area": null, + "grid_auto_columns": null, + "grid_auto_flow": null, + "grid_auto_rows": null, + "grid_column": null, + "grid_gap": null, + "grid_row": null, + "grid_template_areas": null, + "grid_template_columns": null, + "grid_template_rows": null, + "height": null, + "justify_content": null, + "justify_items": null, + "left": null, + "margin": null, + "max_height": null, + "max_width": null, + "min_height": null, + "min_width": null, + "object_fit": null, + "object_position": null, + "order": null, + "overflow": null, + "overflow_x": null, + "overflow_y": null, + "padding": null, + "right": null, + "top": null, + "visibility": null, + "width": null + } + }, + "47012c0ff9394d77b8d857a933b4082e": { + "model_module": "@jupyter-widgets/controls", + "model_name": "DescriptionStyleModel", + "model_module_version": "1.5.0", + "state": { + "_model_module": "@jupyter-widgets/controls", + "_model_module_version": "1.5.0", + "_model_name": "DescriptionStyleModel", + "_view_count": null, + "_view_module": "@jupyter-widgets/base", + "_view_module_version": "1.2.0", + "_view_name": "StyleView", + "description_width": "" + } + }, + "d3ca3e02944c49f88d2b232295b19293": { + "model_module": "@jupyter-widgets/controls", + "model_name": "HBoxModel", + "model_module_version": "1.5.0", + "state": { + "_dom_classes": [], + "_model_module": "@jupyter-widgets/controls", + "_model_module_version": "1.5.0", + "_model_name": "HBoxModel", + "_view_count": null, + "_view_module": "@jupyter-widgets/controls", + "_view_module_version": "1.5.0", + "_view_name": "HBoxView", + "box_style": "", + "children": [ + "IPY_MODEL_392a6347341f4dac94cad19e1f0bf02b", + "IPY_MODEL_ba0102afa62c443eb9de89412301bb46", + "IPY_MODEL_b71a286118004001a9a65ece5ba352d2" + ], + "layout": "IPY_MODEL_29b969a7441d41059969962f338d0def" + } + }, + "392a6347341f4dac94cad19e1f0bf02b": { + "model_module": "@jupyter-widgets/controls", + "model_name": "HTMLModel", + "model_module_version": "1.5.0", + "state": { + "_dom_classes": [], + "_model_module": "@jupyter-widgets/controls", + "_model_module_version": "1.5.0", + "_model_name": "HTMLModel", + "_view_count": null, + "_view_module": "@jupyter-widgets/controls", + "_view_module_version": "1.5.0", + "_view_name": "HTMLView", + "description": "", + "description_tooltip": null, + "layout": "IPY_MODEL_3d0be590ca374ef1a768b8d3577d3105", + "placeholder": "​", + "style": "IPY_MODEL_c0ac81654e1c4904a87a2c777b520c09", + "value": "config.yaml: 100%" + } + }, + "ba0102afa62c443eb9de89412301bb46": { + "model_module": "@jupyter-widgets/controls", + "model_name": "FloatProgressModel", + "model_module_version": "1.5.0", + "state": { + "_dom_classes": [], + "_model_module": "@jupyter-widgets/controls", + "_model_module_version": "1.5.0", + "_model_name": "FloatProgressModel", + "_view_count": null, + "_view_module": "@jupyter-widgets/controls", + "_view_module_version": "1.5.0", + "_view_name": "ProgressView", + "bar_style": "success", + "description": "", + "description_tooltip": null, + "layout": "IPY_MODEL_36f8eb5005864f779aa8185acf55e2c5", + "max": 399, + "min": 0, + "orientation": "horizontal", + "style": "IPY_MODEL_5cbb5cf6a37d451c87215851ee8b0b65", + "value": 399 + } + }, + "b71a286118004001a9a65ece5ba352d2": { + "model_module": "@jupyter-widgets/controls", + "model_name": "HTMLModel", + "model_module_version": "1.5.0", + "state": { + "_dom_classes": [], + "_model_module": "@jupyter-widgets/controls", + "_model_module_version": "1.5.0", + "_model_name": "HTMLModel", + "_view_count": null, + "_view_module": "@jupyter-widgets/controls", + "_view_module_version": "1.5.0", + "_view_name": "HTMLView", + "description": "", + "description_tooltip": null, + "layout": "IPY_MODEL_ca3ee9d356bc464e82ee061375cc4ef2", + "placeholder": "​", + "style": "IPY_MODEL_67e4c4a2768b40eca34e8add6265c40c", + "value": " 399/399 [00:00<00:00, 28.2kB/s]" + } + }, + "29b969a7441d41059969962f338d0def": { + "model_module": "@jupyter-widgets/base", + "model_name": "LayoutModel", + "model_module_version": "1.2.0", + "state": { + "_model_module": "@jupyter-widgets/base", + "_model_module_version": "1.2.0", + "_model_name": "LayoutModel", + "_view_count": null, + "_view_module": "@jupyter-widgets/base", + "_view_module_version": "1.2.0", + "_view_name": "LayoutView", + "align_content": null, + "align_items": null, + "align_self": null, + "border": null, + "bottom": null, + "display": null, + "flex": null, + "flex_flow": null, + "grid_area": null, + "grid_auto_columns": null, + "grid_auto_flow": null, + "grid_auto_rows": null, + "grid_column": null, + "grid_gap": null, + "grid_row": null, + "grid_template_areas": null, + "grid_template_columns": null, + "grid_template_rows": null, + "height": null, + "justify_content": null, + "justify_items": null, + "left": null, + "margin": null, + "max_height": null, + "max_width": null, + "min_height": null, + "min_width": null, + "object_fit": null, + "object_position": null, + "order": null, + "overflow": null, + "overflow_x": null, + "overflow_y": null, + "padding": null, + "right": null, + "top": null, + "visibility": null, + "width": null + } + }, + "3d0be590ca374ef1a768b8d3577d3105": { + "model_module": "@jupyter-widgets/base", + "model_name": "LayoutModel", + "model_module_version": "1.2.0", + "state": { + "_model_module": "@jupyter-widgets/base", + "_model_module_version": "1.2.0", + "_model_name": "LayoutModel", + "_view_count": null, + "_view_module": "@jupyter-widgets/base", + "_view_module_version": "1.2.0", + "_view_name": "LayoutView", + "align_content": null, + "align_items": null, + "align_self": null, + "border": null, + "bottom": null, + "display": null, + "flex": null, + "flex_flow": null, + "grid_area": null, + "grid_auto_columns": null, + "grid_auto_flow": null, + "grid_auto_rows": null, + "grid_column": null, + "grid_gap": null, + "grid_row": null, + "grid_template_areas": null, + "grid_template_columns": null, + "grid_template_rows": null, + "height": null, + "justify_content": null, + "justify_items": null, + "left": null, + "margin": null, + "max_height": null, + "max_width": null, + "min_height": null, + "min_width": null, + "object_fit": null, + "object_position": null, + "order": null, + "overflow": null, + "overflow_x": null, + "overflow_y": null, + "padding": null, + "right": null, + "top": null, + "visibility": null, + "width": null + } + }, + "c0ac81654e1c4904a87a2c777b520c09": { + "model_module": "@jupyter-widgets/controls", + "model_name": "DescriptionStyleModel", + "model_module_version": "1.5.0", + "state": { + "_model_module": "@jupyter-widgets/controls", + "_model_module_version": "1.5.0", + "_model_name": "DescriptionStyleModel", + "_view_count": null, + "_view_module": "@jupyter-widgets/base", + "_view_module_version": "1.2.0", + "_view_name": "StyleView", + "description_width": "" + } + }, + "36f8eb5005864f779aa8185acf55e2c5": { + "model_module": "@jupyter-widgets/base", + "model_name": "LayoutModel", + "model_module_version": "1.2.0", + "state": { + "_model_module": "@jupyter-widgets/base", + "_model_module_version": "1.2.0", + "_model_name": "LayoutModel", + "_view_count": null, + "_view_module": "@jupyter-widgets/base", + "_view_module_version": "1.2.0", + "_view_name": "LayoutView", + "align_content": null, + "align_items": null, + "align_self": null, + "border": null, + "bottom": null, + "display": null, + "flex": null, + "flex_flow": null, + "grid_area": null, + "grid_auto_columns": null, + "grid_auto_flow": null, + "grid_auto_rows": null, + "grid_column": null, + "grid_gap": null, + "grid_row": null, + "grid_template_areas": null, + "grid_template_columns": null, + "grid_template_rows": null, + "height": null, + "justify_content": null, + "justify_items": null, + "left": null, + "margin": null, + "max_height": null, + "max_width": null, + "min_height": null, + "min_width": null, + "object_fit": null, + "object_position": null, + "order": null, + "overflow": null, + "overflow_x": null, + "overflow_y": null, + "padding": null, + "right": null, + "top": null, + "visibility": null, + "width": null + } + }, + "5cbb5cf6a37d451c87215851ee8b0b65": { + "model_module": "@jupyter-widgets/controls", + "model_name": "ProgressStyleModel", + "model_module_version": "1.5.0", + "state": { + "_model_module": "@jupyter-widgets/controls", + "_model_module_version": "1.5.0", + "_model_name": "ProgressStyleModel", + "_view_count": null, + "_view_module": "@jupyter-widgets/base", + "_view_module_version": "1.2.0", + "_view_name": "StyleView", + "bar_color": null, + "description_width": "" + } + }, + "ca3ee9d356bc464e82ee061375cc4ef2": { + "model_module": "@jupyter-widgets/base", + "model_name": "LayoutModel", + "model_module_version": "1.2.0", + "state": { + "_model_module": "@jupyter-widgets/base", + "_model_module_version": "1.2.0", + "_model_name": "LayoutModel", + "_view_count": null, + "_view_module": "@jupyter-widgets/base", + "_view_module_version": "1.2.0", + "_view_name": "LayoutView", + "align_content": null, + "align_items": null, + "align_self": null, + "border": null, + "bottom": null, + "display": null, + "flex": null, + "flex_flow": null, + "grid_area": null, + "grid_auto_columns": null, + "grid_auto_flow": null, + "grid_auto_rows": null, + "grid_column": null, + "grid_gap": null, + "grid_row": null, + "grid_template_areas": null, + "grid_template_columns": null, + "grid_template_rows": null, + "height": null, + "justify_content": null, + "justify_items": null, + "left": null, + "margin": null, + "max_height": null, + "max_width": null, + "min_height": null, + "min_width": null, + "object_fit": null, + "object_position": null, + "order": null, + "overflow": null, + "overflow_x": null, + "overflow_y": null, + "padding": null, + "right": null, + "top": null, + "visibility": null, + "width": null + } + }, + "67e4c4a2768b40eca34e8add6265c40c": { + "model_module": "@jupyter-widgets/controls", + "model_name": "DescriptionStyleModel", + "model_module_version": "1.5.0", + "state": { + "_model_module": "@jupyter-widgets/controls", + "_model_module_version": "1.5.0", + "_model_name": "DescriptionStyleModel", + "_view_count": null, + "_view_module": "@jupyter-widgets/base", + "_view_module_version": "1.2.0", + "_view_name": "StyleView", + "description_width": "" + } + }, + "2149e37d14e94f82a77386682ba29195": { + "model_module": "@jupyter-widgets/controls", + "model_name": "HBoxModel", + "model_module_version": "1.5.0", + "state": { + "_dom_classes": [], + "_model_module": "@jupyter-widgets/controls", + "_model_module_version": "1.5.0", + "_model_name": "HBoxModel", + "_view_count": null, + "_view_module": "@jupyter-widgets/controls", + "_view_module_version": "1.5.0", + "_view_name": "HBoxView", + "box_style": "", + "children": [ + "IPY_MODEL_501eb1f4c1a8458a86c917d7dac5eeb5", + "IPY_MODEL_7a115cf3065f4acdb0ae13577447a333", + "IPY_MODEL_532d713a67c94b0d8cf0d61be72c73e7" + ], + "layout": "IPY_MODEL_3f36703cc5bc4fbcbeb97ab722e573cc" + } + }, + "501eb1f4c1a8458a86c917d7dac5eeb5": { + "model_module": "@jupyter-widgets/controls", + "model_name": "HTMLModel", + "model_module_version": "1.5.0", + "state": { + "_dom_classes": [], + "_model_module": "@jupyter-widgets/controls", + "_model_module_version": "1.5.0", + "_model_name": "HTMLModel", + "_view_count": null, + "_view_module": "@jupyter-widgets/controls", + "_view_module_version": "1.5.0", + "_view_name": "HTMLView", + "description": "", + "description_tooltip": null, + "layout": "IPY_MODEL_8088c86a3d394f9e88267196b369dfb9", + "placeholder": "​", + "style": "IPY_MODEL_46c5a63bcc3a472284869bcb11407bed", + "value": "pytorch_model.bin: 100%" + } + }, + "7a115cf3065f4acdb0ae13577447a333": { + "model_module": "@jupyter-widgets/controls", + "model_name": "FloatProgressModel", + "model_module_version": "1.5.0", + "state": { + "_dom_classes": [], + "_model_module": "@jupyter-widgets/controls", + "_model_module_version": "1.5.0", + "_model_name": "FloatProgressModel", + "_view_count": null, + "_view_module": "@jupyter-widgets/controls", + "_view_module_version": "1.5.0", + "_view_name": "ProgressView", + "bar_style": "success", + "description": "", + "description_tooltip": null, + "layout": "IPY_MODEL_754c1729ba074d518557bd53c01e3787", + "max": 26645418, + "min": 0, + "orientation": "horizontal", + "style": "IPY_MODEL_bbe45325b7b74832bf6fe4a9769e0565", + "value": 26645418 + } + }, + "532d713a67c94b0d8cf0d61be72c73e7": { + "model_module": "@jupyter-widgets/controls", + "model_name": "HTMLModel", + "model_module_version": "1.5.0", + "state": { + "_dom_classes": [], + "_model_module": "@jupyter-widgets/controls", + "_model_module_version": "1.5.0", + "_model_name": "HTMLModel", + "_view_count": null, + "_view_module": "@jupyter-widgets/controls", + "_view_module_version": "1.5.0", + "_view_name": "HTMLView", + "description": "", + "description_tooltip": null, + "layout": "IPY_MODEL_9261da2864ce4fd9b0f05f2a2efc54a3", + "placeholder": "​", + "style": "IPY_MODEL_940ed223c43d40e5b85eadf3a5ef0382", + "value": " 26.6M/26.6M [00:00<00:00, 172MB/s]" + } + }, + "3f36703cc5bc4fbcbeb97ab722e573cc": { + "model_module": "@jupyter-widgets/base", + "model_name": "LayoutModel", + "model_module_version": "1.2.0", + "state": { + "_model_module": "@jupyter-widgets/base", + "_model_module_version": "1.2.0", + "_model_name": "LayoutModel", + "_view_count": null, + "_view_module": "@jupyter-widgets/base", + "_view_module_version": "1.2.0", + "_view_name": "LayoutView", + "align_content": null, + "align_items": null, + "align_self": null, + "border": null, + "bottom": null, + "display": null, + "flex": null, + "flex_flow": null, + "grid_area": null, + "grid_auto_columns": null, + "grid_auto_flow": null, + "grid_auto_rows": null, + "grid_column": null, + "grid_gap": null, + "grid_row": null, + "grid_template_areas": null, + "grid_template_columns": null, + "grid_template_rows": null, + "height": null, + "justify_content": null, + "justify_items": null, + "left": null, + "margin": null, + "max_height": null, + "max_width": null, + "min_height": null, + "min_width": null, + "object_fit": null, + "object_position": null, + "order": null, + "overflow": null, + "overflow_x": null, + "overflow_y": null, + "padding": null, + "right": null, + "top": null, + "visibility": null, + "width": null + } + }, + "8088c86a3d394f9e88267196b369dfb9": { + "model_module": "@jupyter-widgets/base", + "model_name": "LayoutModel", + "model_module_version": "1.2.0", + "state": { + "_model_module": "@jupyter-widgets/base", + "_model_module_version": "1.2.0", + "_model_name": "LayoutModel", + "_view_count": null, + "_view_module": "@jupyter-widgets/base", + "_view_module_version": "1.2.0", + "_view_name": "LayoutView", + "align_content": null, + "align_items": null, + "align_self": null, + "border": null, + "bottom": null, + "display": null, + "flex": null, + "flex_flow": null, + "grid_area": null, + "grid_auto_columns": null, + "grid_auto_flow": null, + "grid_auto_rows": null, + "grid_column": null, + "grid_gap": null, + "grid_row": null, + "grid_template_areas": null, + "grid_template_columns": null, + "grid_template_rows": null, + "height": null, + "justify_content": null, + "justify_items": null, + "left": null, + "margin": null, + "max_height": null, + "max_width": null, + "min_height": null, + "min_width": null, + "object_fit": null, + "object_position": null, + "order": null, + "overflow": null, + "overflow_x": null, + "overflow_y": null, + "padding": null, + "right": null, + "top": null, + "visibility": null, + "width": null + } + }, + "46c5a63bcc3a472284869bcb11407bed": { + "model_module": "@jupyter-widgets/controls", + "model_name": "DescriptionStyleModel", + "model_module_version": "1.5.0", + "state": { + "_model_module": "@jupyter-widgets/controls", + "_model_module_version": "1.5.0", + "_model_name": "DescriptionStyleModel", + "_view_count": null, + "_view_module": "@jupyter-widgets/base", + "_view_module_version": "1.2.0", + "_view_name": "StyleView", + "description_width": "" + } + }, + "754c1729ba074d518557bd53c01e3787": { + "model_module": "@jupyter-widgets/base", + "model_name": "LayoutModel", + "model_module_version": "1.2.0", + "state": { + "_model_module": "@jupyter-widgets/base", + "_model_module_version": "1.2.0", + "_model_name": "LayoutModel", + "_view_count": null, + "_view_module": "@jupyter-widgets/base", + "_view_module_version": "1.2.0", + "_view_name": "LayoutView", + "align_content": null, + "align_items": null, + "align_self": null, + "border": null, + "bottom": null, + "display": null, + "flex": null, + "flex_flow": null, + "grid_area": null, + "grid_auto_columns": null, + "grid_auto_flow": null, + "grid_auto_rows": null, + "grid_column": null, + "grid_gap": null, + "grid_row": null, + "grid_template_areas": null, + "grid_template_columns": null, + "grid_template_rows": null, + "height": null, + "justify_content": null, + "justify_items": null, + "left": null, + "margin": null, + "max_height": null, + "max_width": null, + "min_height": null, + "min_width": null, + "object_fit": null, + "object_position": null, + "order": null, + "overflow": null, + "overflow_x": null, + "overflow_y": null, + "padding": null, + "right": null, + "top": null, + "visibility": null, + "width": null + } + }, + "bbe45325b7b74832bf6fe4a9769e0565": { + "model_module": "@jupyter-widgets/controls", + "model_name": "ProgressStyleModel", + "model_module_version": "1.5.0", + "state": { + "_model_module": "@jupyter-widgets/controls", + "_model_module_version": "1.5.0", + "_model_name": "ProgressStyleModel", + "_view_count": null, + "_view_module": "@jupyter-widgets/base", + "_view_module_version": "1.2.0", + "_view_name": "StyleView", + "bar_color": null, + "description_width": "" + } + }, + "9261da2864ce4fd9b0f05f2a2efc54a3": { + "model_module": "@jupyter-widgets/base", + "model_name": "LayoutModel", + "model_module_version": "1.2.0", + "state": { + "_model_module": "@jupyter-widgets/base", + "_model_module_version": "1.2.0", + "_model_name": "LayoutModel", + "_view_count": null, + "_view_module": "@jupyter-widgets/base", + "_view_module_version": "1.2.0", + "_view_name": "LayoutView", + "align_content": null, + "align_items": null, + "align_self": null, + "border": null, + "bottom": null, + "display": null, + "flex": null, + "flex_flow": null, + "grid_area": null, + "grid_auto_columns": null, + "grid_auto_flow": null, + "grid_auto_rows": null, + "grid_column": null, + "grid_gap": null, + "grid_row": null, + "grid_template_areas": null, + "grid_template_columns": null, + "grid_template_rows": null, + "height": null, + "justify_content": null, + "justify_items": null, + "left": null, + "margin": null, + "max_height": null, + "max_width": null, + "min_height": null, + "min_width": null, + "object_fit": null, + "object_position": null, + "order": null, + "overflow": null, + "overflow_x": null, + "overflow_y": null, + "padding": null, + "right": null, + "top": null, + "visibility": null, + "width": null + } + }, + "940ed223c43d40e5b85eadf3a5ef0382": { + "model_module": "@jupyter-widgets/controls", + "model_name": "DescriptionStyleModel", + "model_module_version": "1.5.0", + "state": { + "_model_module": "@jupyter-widgets/controls", + "_model_module_version": "1.5.0", + "_model_name": "DescriptionStyleModel", + "_view_count": null, + "_view_module": "@jupyter-widgets/base", + "_view_module_version": "1.2.0", + "_view_name": "StyleView", + "description_width": "" + } + }, + "ef97ca55c62b40f7bb233120f8efba62": { + "model_module": "@jupyter-widgets/controls", + "model_name": "HBoxModel", + "model_module_version": "1.5.0", + "state": { + "_dom_classes": [], + "_model_module": "@jupyter-widgets/controls", + "_model_module_version": "1.5.0", + "_model_name": "HBoxModel", + "_view_count": null, + "_view_module": "@jupyter-widgets/controls", + "_view_module_version": "1.5.0", + "_view_name": "HBoxView", + "box_style": "", + "children": [ + "IPY_MODEL_2da74c40ebd44b61adaf840b9e7ce343", + "IPY_MODEL_c9517e2631c247b6ba083da05cfd0399", + "IPY_MODEL_29b6d0dc6624409c8c8a8e0565c2bc08" + ], + "layout": "IPY_MODEL_7b6f8f9b2eee485f8defe25d2a9afc4a" + } + }, + "2da74c40ebd44b61adaf840b9e7ce343": { + "model_module": "@jupyter-widgets/controls", + "model_name": "HTMLModel", + "model_module_version": "1.5.0", + "state": { + "_dom_classes": [], + "_model_module": "@jupyter-widgets/controls", + "_model_module_version": "1.5.0", + "_model_name": "HTMLModel", + "_view_count": null, + "_view_module": "@jupyter-widgets/controls", + "_view_module_version": "1.5.0", + "_view_name": "HTMLView", + "description": "", + "description_tooltip": null, + "layout": "IPY_MODEL_fbaa859f9a8d4d5fb15667ede53a2cfb", + "placeholder": "​", + "style": "IPY_MODEL_1840bc4e8cb54d3d89d5b1f199065c77", + "value": "config.yaml: 100%" + } + }, + "c9517e2631c247b6ba083da05cfd0399": { + "model_module": "@jupyter-widgets/controls", + "model_name": "FloatProgressModel", + "model_module_version": "1.5.0", + "state": { + "_dom_classes": [], + "_model_module": "@jupyter-widgets/controls", + "_model_module_version": "1.5.0", + "_model_name": "FloatProgressModel", + "_view_count": null, + "_view_module": "@jupyter-widgets/controls", + "_view_module_version": "1.5.0", + "_view_name": "ProgressView", + "bar_style": "success", + "description": "", + "description_tooltip": null, + "layout": "IPY_MODEL_3f955f5b7421415bb79319058d0d094d", + "max": 221, + "min": 0, + "orientation": "horizontal", + "style": "IPY_MODEL_849cf4fb4ac249368fb8a5c837f8430a", + "value": 221 + } + }, + "29b6d0dc6624409c8c8a8e0565c2bc08": { + "model_module": "@jupyter-widgets/controls", + "model_name": "HTMLModel", + "model_module_version": "1.5.0", + "state": { + "_dom_classes": [], + "_model_module": "@jupyter-widgets/controls", + "_model_module_version": "1.5.0", + "_model_name": "HTMLModel", + "_view_count": null, + "_view_module": "@jupyter-widgets/controls", + "_view_module_version": "1.5.0", + "_view_name": "HTMLView", + "description": "", + "description_tooltip": null, + "layout": "IPY_MODEL_0411eb97e38b4fa081e05f87076ba129", + "placeholder": "​", + "style": "IPY_MODEL_34842bb9a73048caace624929cfc2b03", + "value": " 221/221 [00:00<00:00, 10.8kB/s]" + } + }, + "7b6f8f9b2eee485f8defe25d2a9afc4a": { + "model_module": "@jupyter-widgets/base", + "model_name": "LayoutModel", + "model_module_version": "1.2.0", + "state": { + "_model_module": "@jupyter-widgets/base", + "_model_module_version": "1.2.0", + "_model_name": "LayoutModel", + "_view_count": null, + "_view_module": "@jupyter-widgets/base", + "_view_module_version": "1.2.0", + "_view_name": "LayoutView", + "align_content": null, + "align_items": null, + "align_self": null, + "border": null, + "bottom": null, + "display": null, + "flex": null, + "flex_flow": null, + "grid_area": null, + "grid_auto_columns": null, + "grid_auto_flow": null, + "grid_auto_rows": null, + "grid_column": null, + "grid_gap": null, + "grid_row": null, + "grid_template_areas": null, + "grid_template_columns": null, + "grid_template_rows": null, + "height": null, + "justify_content": null, + "justify_items": null, + "left": null, + "margin": null, + "max_height": null, + "max_width": null, + "min_height": null, + "min_width": null, + "object_fit": null, + "object_position": null, + "order": null, + "overflow": null, + "overflow_x": null, + "overflow_y": null, + "padding": null, + "right": null, + "top": null, + "visibility": null, + "width": null + } + }, + "fbaa859f9a8d4d5fb15667ede53a2cfb": { + "model_module": "@jupyter-widgets/base", + "model_name": "LayoutModel", + "model_module_version": "1.2.0", + "state": { + "_model_module": "@jupyter-widgets/base", + "_model_module_version": "1.2.0", + "_model_name": "LayoutModel", + "_view_count": null, + "_view_module": "@jupyter-widgets/base", + "_view_module_version": "1.2.0", + "_view_name": "LayoutView", + "align_content": null, + "align_items": null, + "align_self": null, + "border": null, + "bottom": null, + "display": null, + "flex": null, + "flex_flow": null, + "grid_area": null, + "grid_auto_columns": null, + "grid_auto_flow": null, + "grid_auto_rows": null, + "grid_column": null, + "grid_gap": null, + "grid_row": null, + "grid_template_areas": null, + "grid_template_columns": null, + "grid_template_rows": null, + "height": null, + "justify_content": null, + "justify_items": null, + "left": null, + "margin": null, + "max_height": null, + "max_width": null, + "min_height": null, + "min_width": null, + "object_fit": null, + "object_position": null, + "order": null, + "overflow": null, + "overflow_x": null, + "overflow_y": null, + "padding": null, + "right": null, + "top": null, + "visibility": null, + "width": null + } + }, + "1840bc4e8cb54d3d89d5b1f199065c77": { + "model_module": "@jupyter-widgets/controls", + "model_name": "DescriptionStyleModel", + "model_module_version": "1.5.0", + "state": { + "_model_module": "@jupyter-widgets/controls", + "_model_module_version": "1.5.0", + "_model_name": "DescriptionStyleModel", + "_view_count": null, + "_view_module": "@jupyter-widgets/base", + "_view_module_version": "1.2.0", + "_view_name": "StyleView", + "description_width": "" + } + }, + "3f955f5b7421415bb79319058d0d094d": { + "model_module": "@jupyter-widgets/base", + "model_name": "LayoutModel", + "model_module_version": "1.2.0", + "state": { + "_model_module": "@jupyter-widgets/base", + "_model_module_version": "1.2.0", + "_model_name": "LayoutModel", + "_view_count": null, + "_view_module": "@jupyter-widgets/base", + "_view_module_version": "1.2.0", + "_view_name": "LayoutView", + "align_content": null, + "align_items": null, + "align_self": null, + "border": null, + "bottom": null, + "display": null, + "flex": null, + "flex_flow": null, + "grid_area": null, + "grid_auto_columns": null, + "grid_auto_flow": null, + "grid_auto_rows": null, + "grid_column": null, + "grid_gap": null, + "grid_row": null, + "grid_template_areas": null, + "grid_template_columns": null, + "grid_template_rows": null, + "height": null, + "justify_content": null, + "justify_items": null, + "left": null, + "margin": null, + "max_height": null, + "max_width": null, + "min_height": null, + "min_width": null, + "object_fit": null, + "object_position": null, + "order": null, + "overflow": null, + "overflow_x": null, + "overflow_y": null, + "padding": null, + "right": null, + "top": null, + "visibility": null, + "width": null + } + }, + "849cf4fb4ac249368fb8a5c837f8430a": { + "model_module": "@jupyter-widgets/controls", + "model_name": "ProgressStyleModel", + "model_module_version": "1.5.0", + "state": { + "_model_module": "@jupyter-widgets/controls", + "_model_module_version": "1.5.0", + "_model_name": "ProgressStyleModel", + "_view_count": null, + "_view_module": "@jupyter-widgets/base", + "_view_module_version": "1.2.0", + "_view_name": "StyleView", + "bar_color": null, + "description_width": "" + } + }, + "0411eb97e38b4fa081e05f87076ba129": { + "model_module": "@jupyter-widgets/base", + "model_name": "LayoutModel", + "model_module_version": "1.2.0", + "state": { + "_model_module": "@jupyter-widgets/base", + "_model_module_version": "1.2.0", + "_model_name": "LayoutModel", + "_view_count": null, + "_view_module": "@jupyter-widgets/base", + "_view_module_version": "1.2.0", + "_view_name": "LayoutView", + "align_content": null, + "align_items": null, + "align_self": null, + "border": null, + "bottom": null, + "display": null, + "flex": null, + "flex_flow": null, + "grid_area": null, + "grid_auto_columns": null, + "grid_auto_flow": null, + "grid_auto_rows": null, + "grid_column": null, + "grid_gap": null, + "grid_row": null, + "grid_template_areas": null, + "grid_template_columns": null, + "grid_template_rows": null, + "height": null, + "justify_content": null, + "justify_items": null, + "left": null, + "margin": null, + "max_height": null, + "max_width": null, + "min_height": null, + "min_width": null, + "object_fit": null, + "object_position": null, + "order": null, + "overflow": null, + "overflow_x": null, + "overflow_y": null, + "padding": null, + "right": null, + "top": null, + "visibility": null, + "width": null + } + }, + "34842bb9a73048caace624929cfc2b03": { + "model_module": "@jupyter-widgets/controls", + "model_name": "DescriptionStyleModel", + "model_module_version": "1.5.0", + "state": { + "_model_module": "@jupyter-widgets/controls", + "_model_module_version": "1.5.0", + "_model_name": "DescriptionStyleModel", + "_view_count": null, + "_view_module": "@jupyter-widgets/base", + "_view_module_version": "1.2.0", + "_view_name": "StyleView", + "description_width": "" + } + } + } + } + }, + "cells": [ + { + "cell_type": "markdown", + "metadata": { + "id": "view-in-github", + "colab_type": "text" + }, + "source": [ + "\"Open" + ] + }, + { + "cell_type": "markdown", + "source": [ + "Sharing a minimal reproduction example (MRE) is a prerequisite for `pyannote.audio` contributors to be able to solve them.\n", + "\n", + "Having an MRE is very important for contributors to be able to reproduce the bug in the same way that you are experiencing it. When testing a potential fix for the issue, contributors will use the MRE to validate that the fix is working as intended.\n", + "\n", + "This notebook provides a template that should help you create such a MRE.\n", + "\n", + "Duplicate it, edit it, and share it as a link within your `pyannote.audio` bug report." + ], + "metadata": { + "id": "SWidE_E7ol-U" + } + }, + { + "cell_type": "markdown", + "source": [ + "# Setup\n", + "\n", + "Before anything, make sure to run this section." + ], + "metadata": { + "id": "k1vex_KZTDFm" + } + }, + { + "cell_type": "markdown", + "source": [ + "Specify the `pyannote.audio` version you found the issue in (including the Git commit hash if using a non-released version)." + ], + "metadata": { + "id": "XRNSJ2omranm" + } + }, + { + "cell_type": "code", + "source": [ + "!pip install -qqq pyannote.audio==3.1.1" + ], + "metadata": { + "colab": { + "base_uri": "https://localhost:8080/" + }, + "id": "THKj6xjdSv9k", + "outputId": "719baaf8-2028-4b8e-8e46-e6a813aaf6f8" + }, + "execution_count": 1, + "outputs": [ + { + "output_type": "stream", + "name": "stdout", + "text": [ + "\u001b[2K \u001b[90m━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\u001b[0m \u001b[32m208.7/208.7 kB\u001b[0m \u001b[31m4.7 MB/s\u001b[0m eta \u001b[36m0:00:00\u001b[0m\n", + "\u001b[2K \u001b[90m━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\u001b[0m \u001b[32m44.6/44.6 kB\u001b[0m \u001b[31m6.4 MB/s\u001b[0m eta \u001b[36m0:00:00\u001b[0m\n", + "\u001b[2K \u001b[90m━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\u001b[0m \u001b[32m2.0/2.0 MB\u001b[0m \u001b[31m15.1 MB/s\u001b[0m eta \u001b[36m0:00:00\u001b[0m\n", + "\u001b[2K \u001b[90m━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\u001b[0m \u001b[32m79.5/79.5 kB\u001b[0m \u001b[31m10.4 MB/s\u001b[0m eta \u001b[36m0:00:00\u001b[0m\n", + "\u001b[2K \u001b[90m━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\u001b[0m \u001b[32m58.5/58.5 kB\u001b[0m \u001b[31m8.5 MB/s\u001b[0m eta \u001b[36m0:00:00\u001b[0m\n", + "\u001b[2K \u001b[90m━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\u001b[0m \u001b[32m48.1/48.1 kB\u001b[0m \u001b[31m7.1 MB/s\u001b[0m eta \u001b[36m0:00:00\u001b[0m\n", + "\u001b[2K \u001b[90m━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\u001b[0m \u001b[32m51.4/51.4 kB\u001b[0m \u001b[31m6.9 MB/s\u001b[0m eta \u001b[36m0:00:00\u001b[0m\n", + "\u001b[2K \u001b[90m━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\u001b[0m \u001b[32m118.6/118.6 kB\u001b[0m \u001b[31m16.3 MB/s\u001b[0m eta \u001b[36m0:00:00\u001b[0m\n", + "\u001b[2K \u001b[90m━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\u001b[0m \u001b[32m630.6/630.6 kB\u001b[0m \u001b[31m21.4 MB/s\u001b[0m eta \u001b[36m0:00:00\u001b[0m\n", + "\u001b[2K \u001b[90m━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\u001b[0m \u001b[32m101.7/101.7 kB\u001b[0m \u001b[31m14.0 MB/s\u001b[0m eta \u001b[36m0:00:00\u001b[0m\n", + "\u001b[2K \u001b[90m━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\u001b[0m \u001b[32m47.9/47.9 kB\u001b[0m \u001b[31m7.2 MB/s\u001b[0m eta \u001b[36m0:00:00\u001b[0m\n", + "\u001b[2K \u001b[90m━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\u001b[0m \u001b[32m806.1/806.1 kB\u001b[0m \u001b[31m25.3 MB/s\u001b[0m eta \u001b[36m0:00:00\u001b[0m\n", + "\u001b[2K \u001b[90m━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\u001b[0m \u001b[32m777.7/777.7 kB\u001b[0m \u001b[31m29.7 MB/s\u001b[0m eta \u001b[36m0:00:00\u001b[0m\n", + "\u001b[2K \u001b[90m━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\u001b[0m \u001b[32m117.0/117.0 kB\u001b[0m \u001b[31m18.7 MB/s\u001b[0m eta \u001b[36m0:00:00\u001b[0m\n", + "\u001b[?25h Preparing metadata (setup.py) ... \u001b[?25l\u001b[?25hdone\n", + " Preparing metadata (setup.py) ... \u001b[?25l\u001b[?25hdone\n", + "\u001b[2K \u001b[90m━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\u001b[0m \u001b[32m413.4/413.4 kB\u001b[0m \u001b[31m29.9 MB/s\u001b[0m eta \u001b[36m0:00:00\u001b[0m\n", + "\u001b[2K \u001b[90m━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\u001b[0m \u001b[32m1.3/1.3 MB\u001b[0m \u001b[31m39.8 MB/s\u001b[0m eta \u001b[36m0:00:00\u001b[0m\n", + "\u001b[2K \u001b[90m━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\u001b[0m \u001b[32m59.6/59.6 kB\u001b[0m \u001b[31m9.3 MB/s\u001b[0m eta \u001b[36m0:00:00\u001b[0m\n", + "\u001b[?25h Preparing metadata (setup.py) ... \u001b[?25l\u001b[?25hdone\n", + "\u001b[2K \u001b[90m━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\u001b[0m \u001b[32m233.4/233.4 kB\u001b[0m \u001b[31m27.2 MB/s\u001b[0m eta \u001b[36m0:00:00\u001b[0m\n", + "\u001b[2K \u001b[90m━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\u001b[0m \u001b[32m116.4/116.4 kB\u001b[0m \u001b[31m14.5 MB/s\u001b[0m eta \u001b[36m0:00:00\u001b[0m\n", + "\u001b[2K \u001b[90m━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\u001b[0m \u001b[32m78.6/78.6 kB\u001b[0m \u001b[31m12.0 MB/s\u001b[0m eta \u001b[36m0:00:00\u001b[0m\n", + "\u001b[2K \u001b[90m━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\u001b[0m \u001b[32m526.7/526.7 kB\u001b[0m \u001b[31m45.2 MB/s\u001b[0m eta \u001b[36m0:00:00\u001b[0m\n", + "\u001b[?25h Building wheel for antlr4-python3-runtime (setup.py) ... \u001b[?25l\u001b[?25hdone\n", + " Building wheel for docopt (setup.py) ... \u001b[?25l\u001b[?25hdone\n", + " Building wheel for julius (setup.py) ... \u001b[?25l\u001b[?25hdone\n" + ] + } + ] + }, + { + "cell_type": "markdown", + "source": [ + "Declare your [Huggingface token](https://huggingface.co/settings/tokens) as `HF_TOKEN` secret by clicking on the 🔑 icon on the left:\n", + "\n", + "* **Name**: `HF_TOKEN` \n", + "* **Value**: your Huggingface token (e.g. `hf_ABCdzRFTkglhlcalBAPGHSQvxLmQs`)" + ], + "metadata": { + "id": "ZLhE8e7iTpTu" + } + }, + { + "cell_type": "markdown", + "source": [ + "Check that you can load the pretrained pipeline." + ], + "metadata": { + "id": "Mogy5_qYUoXs" + } + }, + { + "cell_type": "code", + "source": [ + "# access your HF token\n", + "from google.colab import userdata\n", + "hf_token = userdata.get('HF_TOKEN')\n", + "\n", + "# load the pretrained pipeline\n", + "from pyannote.audio import Pipeline\n", + "pipeline = Pipeline.from_pretrained(\n", + " \"pyannote/speaker-diarization-3.1\",\n", + " use_auth_token=hf_token)" + ], + "metadata": { + "colab": { + "base_uri": "https://localhost:8080/", + "height": 307, + "referenced_widgets": [ + "3d0fe95350234ab599497683ae6d4ce6", + "239beda16fde4b1d9e6abfb47f036040", + "2d6f5fe6f9ab4a8b853e7b023aaee35f", + "771629a0fbab4b0e9ad6425b5affe380", + "8763b8e4c8104b879d4324257a810c0f", + "22536aef3997408dbf5ea58241f01e3e", + "2a6a5f33d7c34b6b996ab7a5b7c2f11d", + "c348b2f57c6c437fa8a9a2688bf17f4f", + "7526127b349a4467a6d3083d92bef5ec", + "30efc0ed76fb496483d4bb425a930636", + "e760e231084f4889bb489bc550b7a816", + "9951dce8a6c947dd9a2ed6106cb68f30", + "d68c24e62487484b83bbb06271a6981c", + "467f3c9f15184784aa913cb3ae46700f", + "c87055ce8cef498f999a20ff2b34e1b8", + "63d957e24276476b9bf1be150675217c", + "afe35fd2ea654d7b861046e847f82e51", + "c5f4f5f5fbad4d14973dc21eae2358d4", + "b4faa4c7fd01498abe07fef6189de4d4", + "35ab2642d8a5481780c43eaef7044f3c", + "37de7e413b25451ca5288ea5f43dd2d5", + "47012c0ff9394d77b8d857a933b4082e", + "d3ca3e02944c49f88d2b232295b19293", + "392a6347341f4dac94cad19e1f0bf02b", + "ba0102afa62c443eb9de89412301bb46", + "b71a286118004001a9a65ece5ba352d2", + "29b969a7441d41059969962f338d0def", + "3d0be590ca374ef1a768b8d3577d3105", + "c0ac81654e1c4904a87a2c777b520c09", + "36f8eb5005864f779aa8185acf55e2c5", + "5cbb5cf6a37d451c87215851ee8b0b65", + "ca3ee9d356bc464e82ee061375cc4ef2", + "67e4c4a2768b40eca34e8add6265c40c", + "2149e37d14e94f82a77386682ba29195", + "501eb1f4c1a8458a86c917d7dac5eeb5", + "7a115cf3065f4acdb0ae13577447a333", + "532d713a67c94b0d8cf0d61be72c73e7", + "3f36703cc5bc4fbcbeb97ab722e573cc", + "8088c86a3d394f9e88267196b369dfb9", + "46c5a63bcc3a472284869bcb11407bed", + "754c1729ba074d518557bd53c01e3787", + "bbe45325b7b74832bf6fe4a9769e0565", + "9261da2864ce4fd9b0f05f2a2efc54a3", + "940ed223c43d40e5b85eadf3a5ef0382", + "ef97ca55c62b40f7bb233120f8efba62", + "2da74c40ebd44b61adaf840b9e7ce343", + "c9517e2631c247b6ba083da05cfd0399", + "29b6d0dc6624409c8c8a8e0565c2bc08", + "7b6f8f9b2eee485f8defe25d2a9afc4a", + "fbaa859f9a8d4d5fb15667ede53a2cfb", + "1840bc4e8cb54d3d89d5b1f199065c77", + "3f955f5b7421415bb79319058d0d094d", + "849cf4fb4ac249368fb8a5c837f8430a", + "0411eb97e38b4fa081e05f87076ba129", + "34842bb9a73048caace624929cfc2b03" + ] + }, + "id": "i8rs3XylTTys", + "outputId": "b1b7445e-6f29-4ce0-c111-f5ffcb488c47" + }, + "execution_count": 3, + "outputs": [ + { + "output_type": "display_data", + "data": { + "text/plain": [ + "config.yaml: 0%| | 0.00/469 [00:00] 937.60K --.-KB/s in 0.04s \n", + "\n", + "2024-01-08 15:31:42 (25.7 MB/s) - ‘sample.wav’ saved [960104/960104]\n", + "\n" + ] + } + ] + }, + { + "cell_type": "markdown", + "source": [ + "Apply the pretrained pipeline and visualize the output." + ], + "metadata": { + "id": "RH6AEClgaAgU" + } + }, + { + "cell_type": "code", + "source": [ + "diarization = pipeline(\"sample.wav\")" + ], + "metadata": { + "colab": { + "base_uri": "https://localhost:8080/" + }, + "id": "AoCal-3UXK0z", + "outputId": "59428f0f-af42-4e78-fc04-abd6324c73db" + }, + "execution_count": 6, + "outputs": [ + { + "output_type": "stream", + "name": "stderr", + "text": [ + "/usr/local/lib/python3.10/dist-packages/pyannote/audio/utils/reproducibility.py:74: ReproducibilityWarning: TensorFloat-32 (TF32) has been disabled as it might lead to reproducibility issues and lower accuracy.\n", + "It can be re-enabled by calling\n", + " >>> import torch\n", + " >>> torch.backends.cuda.matmul.allow_tf32 = True\n", + " >>> torch.backends.cudnn.allow_tf32 = True\n", + "See https://github.com/pyannote/pyannote-audio/issues/1370 for more details.\n", + "\n", + " warnings.warn(\n" + ] + } + ] + }, + { + "cell_type": "code", + "source": [ + "diarization" + ], + "metadata": { + "colab": { + "base_uri": "https://localhost:8080/", + "height": 259 + }, + "id": "iIKvKZoZXN_M", + "outputId": "e7dcd7e1-0512-425c-b46a-6dc18d7a67b1" + }, + "execution_count": 7, + "outputs": [ + { + "output_type": "execute_result", + "data": { + "text/plain": [ + "" + ], + "image/png": "iVBORw0KGgoAAAANSUhEUgAABiIAAADyCAYAAADAzN2uAAAAOXRFWHRTb2Z0d2FyZQBNYXRwbG90bGliIHZlcnNpb24zLjcuMSwgaHR0cHM6Ly9tYXRwbG90bGliLm9yZy/bCgiHAAAACXBIWXMAAA9hAAAPYQGoP6dpAAAe8UlEQVR4nO3de5RV5X038O/hKnEuCjgzoCPiJV4SiMamikmMQQWV5RKlpsalkWhkhYV0qWnkjUWNsZqG9aY2qdrc8NIgxmWjJjG1uViwJqBGG0MxKY0UoykyIMhw0QGEef/wZepkCJyR2XMG5vNZa9Zi9n7Os3/n8Jxn79nfc/Yutba2tgYAAAAAAKAAfSpdAAAAAAAAsPcSRAAAAAAAAIURRAAAAAAAAIURRAAAAAAAAIURRAAAAAAAAIURRAAAAAAAAIURRAAAAAAAAIURRAAAAAAAAIURRAAAAAAAAIURRAAAAAAAAIURRAAAAAAAAIURRAAAAAAAAIURRAAAAAAAAIURRAAAAAAAAIURRAAAAAAAAIURRAAAAAAAAIXZ64OIVatWZerUqTn44IMzcODANDQ0ZPz48fn5z3+eJDnkkENSKpVSKpWy77775v3vf38eeOCBtsd//vOfb1v/9p+jjjqqw7buu+++9O3bN9OmTeuwbv78+SmVSlm7dm3bsuXLl2fUqFE5+eST09zc3NZmRz8rVqzoUE/fvn3T2NiYKVOmZM2aNWW/Ji0tLZk2bVqGDBmSqqqqTJo0KU1NTe3avPTSS5kwYULe9a53pa6uLp/97Gfz5ptvlr2N3sY466iccfYXf/EXOf744zNw4MAce+yxZffdWxlnHe1qnP3qV7/Kxz/+8TQ2NmbQoEE5+uij85WvfKXs/gEAAADYff12t4PmTc1dUUdZagfWdvoxkyZNyubNm3PPPffk0EMPTVNTUx577LGsXr26rc0XvvCFXH755Vm3bl2+/OUv58///M9z4IEH5qSTTkqSvOc978lPf/rTdv3269fxpZs9e3auueaafP3rX8+Xv/zl7LPPPn+0rqVLl+b000/PMccckwceeCCDBg1qW7dkyZLU1NS0a19XV9f27+31bN26Nb/5zW9y6aWXprm5Offff39Zr8lVV12VH/7wh3nggQdSW1ubK664Iuedd17bycytW7dmwoQJaWhoyIIFC/LKK6/kE5/4RPr3759bbrmlrG10pa1v+7/qDn2HDOn0Y4yzjnY1zra79NJL89RTT2XRokVl9Vuk1zZu7rZt7b/vgE4/xjjraFfj7Nlnn01dXV3mzJmTxsbGLFiwIFOmTEnfvn1zxRVXlLUNAAAAAHbPbgcRFz96YVfUUZbvT/xhp9qvXbs2TzzxRObPn5+PfOQjSZIRI0bkT//0T9u1q66uTkNDQxoaGnL77bdnzpw5+cEPftB24q5fv35paGjY6baWLVuWBQsW5Lvf/W7mzZuXBx98MBdeuOPXZtGiRRk/fnzGjh2be+65p8NJwLq6uuy3335/dFtvr+fAAw/M+eefn7vuumun9W3X3Nyc2bNnZ+7cuRk7dmyS5K677srRRx+dJ598MieeeGJ+/OMf59e//nV++tOfpr6+Pscee2xuuummzJgxI5///OczYEDnT6DujhWjj+3W7R34Py93qr1x1lE54yxJvvrVryZ565P+PSGIOHPWvG7b1pM3ju9Ue+Oso3LG2aWXXtruMYceemgWLlyYBx98UBABAAAA0E326kszVVVVpaqqKg8//HA2bdpU1mP69euX/v37Z/Pmzn0y+q677sqECRNSW1ubiy66KLNnz95huwULFuQjH/lIJk2alDlz5uzwk8id8eKLL+ZHP/pR2eHAs88+my1btuS0005rW3bUUUfl4IMPzsKFC5MkCxcuzKhRo1JfX9/WZvz48Vm3bl2ef/753ap3b2ScdVTOOKNzjLOO3uk4a25uzuDBg3erVgAAAADKt1cHEf369cvdd9+de+65J/vtt18++MEP5tprr/2jn7zevHlzvvjFL6a5ubnt07VJ8h//8R9tJwG3/3z6059uW79t27bcfffdueiii5IkF1xwQX72s59l2bJlHbZx7rnn5uyzz85tt92WUqm0wzoOOuigdtt6z3ve02799noGDRqUkSNH5vnnn8+MGTPKek1WrFiRAQMGdPiEcn19fdt121esWNEuhNi+fvs62jPOOipnnNE5xllH72ScLViwIPfff3+mTJlS1jYAAAAA2H27fWmmnm7SpEmZMGFCnnjiiTz55JN59NFHM2vWrHzrW9/K5MmTkyQzZszIzJkz09LSkqqqqvzN3/xNJkyY0NbHkUceme9///vt+n37Nc9/8pOfZOPGjTnrrLOSJEOHDs3pp5+eO++8MzfddFO7x51zzjl56KGH8sQTT+TDH/7wDmt+4oknUl1d3fZ7//79263fXk9LS0vmzJmT5557LtOnT+/8i0OXMc7oDsbZ7lm8eHHOOeec3HDDDRk3blwh2wAAAACgo90OIr595tyuqKNQ++yzT04//fScfvrpue666/KpT30qN9xwQ9uJu89+9rOZPHlyqqqqUl9f3+GTvQMGDMjhhx/+R/ufPXt21qxZ0+4Grdu2bcuiRYty4403pk+f//3iyde//vVcc801OfPMM/PP//zPOfnkkzv0N3LkyJ1eU/3t9Ww/yXjjjTd2OEm4Iw0NDdm8eXPWrl3bbhtNTU1t12lvaGjI008/3e5xTU1Nbeu6W8Oi57p9m++Ecfa/yhlnPdGj13y00iXsknH2vzozzn7961/n1FNPzZQpUzJz5sxd9g0AAABA19ntIKJ2YG1X1NGtjjnmmDz88MNtvw8dOnSnJ+Z2ZvXq1fne976X73znO+0uObJ169Z86EMfyo9//OOcccYZbctLpVK+8Y1vpE+fPjnrrLPywx/+sO3Gs+/UzJkzM3bs2EydOjXDhw/fadvjjz8+/fv3z2OPPZZJkyYlSZYsWZKXXnopY8aMSZKMGTMmN998c1auXJm6urokb31KuqamJsccc8xu1fpO9B0ypNu32RWMs52Ps55o/32790bsXcE42/U4e/755zN27Nhccsklufnmm3erPgAAAAA6b6++NNPq1atz/vnn59JLL83o0aNTXV2dZ555JrNmzco555xTdj9vvvlmh+uNl0ql1NfX59vf/naGDBmSj33sYx0+eXzWWWdl9uzZ7U7cbX/s1772tfTt27ft5N0pp5zStn7lypVpaWlp95ghQ4Z0uKTJdmPGjMno0aNzyy235Lbbbtvpc6mtrc1ll12Wq6++OoMHD05NTU2mT5+eMWPG5MQTT0ySjBs3Lsccc0wuvvjizJo1KytWrMjMmTMzbdq0DBw4cKf990bGWUfljLMkeeGFF7Jhw4asWLEib7zxRp577rkkb51cL/eGxb2FcdZROeNs8eLFGTt2bMaPH5+rr7667bn37ds3BxxwwE77BwAAAKBr7NVBRFVVVU444YTceuutWbp0abZs2ZLGxsZcfvnlufbaa8vu5/nnn8+wYcPaLRs4cGBaWlpy55135txzz93hjVonTZqUiy++OK+++mqHdaVSKbfffnv69OmTCRMm5JFH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SzMBvc6u5syXX345F110URYvXpyNGzemsbEx5557bmbOnJmamppurhZgzyeIAAAAAAAACuMeEQAAAAAAQGEEEQAAAAAAQGEEEQAAAAAAQGEEEQAAAAAAQGEEEQAAAAAAQGEEEQAAAAAAQGEEEQAAAAAAQGEEEQAAAAAAQGEEEQAAQDuTJ0/OxIkTK10GAACwl+hX6QIAAIDuUyqVdrr+hhtuyFe+8pW0trZ2U0UAAMDeThABAAC9yCuvvNL27/vvvz/XX399lixZ0rasqqoqVVVVlSgNAADYS7k0EwAA9CINDQ1tP7W1tSmVSu2WVVVVdbg00ymnnJLp06fnyiuvzP7775/6+vp885vfzMaNG/PJT34y1dXVOfzww/Poo4+229bixYtz5plnpqqqKvX19bn44ovz6quvdvMzBgAAKk0QAQAA7NI999yToUOH5umnn8706dMzderUnH/++TnppJPy7//+7xk3blwuvvjivP7660mStWvXZuzYsTnuuOPyzDPP5F/+5V/S1NSUj33sYxV+JgAAQHcTRAAAALv0vve9LzNnzswRRxyRz33uc9lnn30ydOjQXH755TniiCNy/fXXZ/Xq1Vm0aFGS5Lbbbstxxx2XW265JUcddVSOO+643HnnnZk3b17+67/+q8LPBgAA6E7uEQEAAOzS6NGj2/7dt2/fDBkyJKNGjWpbVl9fnyRZuXJlkuRXv/pV5s2bt8P7TSxdujTvfve7C64YAADoKQQRAADALvXv37/d76VSqd2yUqmUJNm2bVuSZMOGDTn77LPzpS99qUNfw4YNK7BSAACgpxFEAAAAXe79739/vvvd7+aQQw5Jv37+7AAAgN7MPSIAAIAuN23atKxZsyYf//jH84tf/CJLly7Nj370o3zyk5/M1q1bK10eAADQjQQRAABAlxs+fHh+/vOfZ+vWrRk3blxGjRqVK6+8Mvvtt1/69PFnCAAA9Cal1tbW1koXAQAAAAAA7J18FAkAAAAAACiMIAIAAAAAACiMIAIAAAAAACiMIAIAAAAAACiMIAIAAAAAACiMIAIAAAAAACiMIAIAAAAAACiMIAIAAAAAACiMIAIAAAAAACiMIAIAAAAAACiMIAIAAAAAACjM/wM8DotLF49/uQAAAABJRU5ErkJggg==\n" + }, + "metadata": {}, + "execution_count": 7 + } + ] + }, + { + "cell_type": "markdown", + "source": [ + "# MRE\n", + "\n", + "Now that things are setup, edit the following cells with the piece of code allowing to reproduce the bug report.\n" + ], + "metadata": { + "id": "qHxFJZDxr5O1" + } + }, + { + "cell_type": "code", + "source": [ + "from pyannote.audio import Model\n", + "model = Model.from_pretrained(\n", + " \"pyannote/speaker-diarization-3.1\",\n", + " use_auth_token=hf_token)" + ], + "metadata": { + "colab": { + "base_uri": "https://localhost:8080/", + "height": 499 + }, + "id": "gVrDtBcusDbK", + "outputId": "25823c18-bff7-43b5-ef30-f5e8b2e43e2b" + }, + "execution_count": 8, + "outputs": [ + { + "output_type": "error", + "ename": "EntryNotFoundError", + "evalue": "404 Client Error. (Request ID: Root=1-659c1570-229842ad49cdd505022bd7b3;3b3426ec-0f8e-49a4-8783-f5740d92a8ed)\n\nEntry Not Found for url: https://huggingface.co/pyannote/speaker-diarization-3.1/resolve/main/pytorch_model.bin.", + "traceback": [ + "\u001b[0;31m---------------------------------------------------------------------------\u001b[0m", + "\u001b[0;31mHTTPError\u001b[0m Traceback (most recent call last)", + "\u001b[0;32m/usr/local/lib/python3.10/dist-packages/huggingface_hub/utils/_errors.py\u001b[0m in \u001b[0;36mhf_raise_for_status\u001b[0;34m(response, endpoint_name)\u001b[0m\n\u001b[1;32m 285\u001b[0m \u001b[0;32mtry\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0;32m--> 286\u001b[0;31m \u001b[0mresponse\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mraise_for_status\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m\u001b[1;32m 287\u001b[0m \u001b[0;32mexcept\u001b[0m \u001b[0mHTTPError\u001b[0m \u001b[0;32mas\u001b[0m \u001b[0me\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n", + "\u001b[0;32m/usr/local/lib/python3.10/dist-packages/requests/models.py\u001b[0m in \u001b[0;36mraise_for_status\u001b[0;34m(self)\u001b[0m\n\u001b[1;32m 1020\u001b[0m \u001b[0;32mif\u001b[0m \u001b[0mhttp_error_msg\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0;32m-> 1021\u001b[0;31m \u001b[0;32mraise\u001b[0m \u001b[0mHTTPError\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mhttp_error_msg\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mresponse\u001b[0m\u001b[0;34m=\u001b[0m\u001b[0mself\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m\u001b[1;32m 1022\u001b[0m \u001b[0;34m\u001b[0m\u001b[0m\n", + "\u001b[0;31mHTTPError\u001b[0m: 404 Client Error: Not Found for url: https://huggingface.co/pyannote/speaker-diarization-3.1/resolve/main/pytorch_model.bin", + "\nThe above exception was the direct cause of the following exception:\n", + "\u001b[0;31mEntryNotFoundError\u001b[0m Traceback (most recent call last)", + "\u001b[0;32m\u001b[0m in \u001b[0;36m\u001b[0;34m()\u001b[0m\n\u001b[1;32m 1\u001b[0m \u001b[0;32mfrom\u001b[0m \u001b[0mpyannote\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0maudio\u001b[0m \u001b[0;32mimport\u001b[0m \u001b[0mModel\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0;32m----> 2\u001b[0;31m model = Model.from_pretrained(\n\u001b[0m\u001b[1;32m 3\u001b[0m \u001b[0;34m\"pyannote/speaker-diarization-3.1\"\u001b[0m\u001b[0;34m,\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 4\u001b[0m use_auth_token=hf_token)\n", + "\u001b[0;32m/usr/local/lib/python3.10/dist-packages/pyannote/audio/core/model.py\u001b[0m in \u001b[0;36mfrom_pretrained\u001b[0;34m(cls, checkpoint, map_location, hparams_file, strict, use_auth_token, cache_dir, **kwargs)\u001b[0m\n\u001b[1;32m 622\u001b[0m \u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 623\u001b[0m \u001b[0;32mtry\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0;32m--> 624\u001b[0;31m path_for_pl = hf_hub_download(\n\u001b[0m\u001b[1;32m 625\u001b[0m \u001b[0mmodel_id\u001b[0m\u001b[0;34m,\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 626\u001b[0m \u001b[0mHF_PYTORCH_WEIGHTS_NAME\u001b[0m\u001b[0;34m,\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n", + "\u001b[0;32m/usr/local/lib/python3.10/dist-packages/huggingface_hub/utils/_validators.py\u001b[0m in \u001b[0;36m_inner_fn\u001b[0;34m(*args, **kwargs)\u001b[0m\n\u001b[1;32m 116\u001b[0m \u001b[0mkwargs\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0msmoothly_deprecate_use_auth_token\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mfn_name\u001b[0m\u001b[0;34m=\u001b[0m\u001b[0mfn\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0m__name__\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mhas_token\u001b[0m\u001b[0;34m=\u001b[0m\u001b[0mhas_token\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mkwargs\u001b[0m\u001b[0;34m=\u001b[0m\u001b[0mkwargs\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 117\u001b[0m \u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0;32m--> 118\u001b[0;31m \u001b[0;32mreturn\u001b[0m \u001b[0mfn\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;34m*\u001b[0m\u001b[0margs\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0;34m**\u001b[0m\u001b[0mkwargs\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m\u001b[1;32m 119\u001b[0m \u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 120\u001b[0m \u001b[0;32mreturn\u001b[0m \u001b[0m_inner_fn\u001b[0m \u001b[0;31m# type: ignore\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n", + "\u001b[0;32m/usr/local/lib/python3.10/dist-packages/huggingface_hub/file_download.py\u001b[0m in \u001b[0;36mhf_hub_download\u001b[0;34m(repo_id, filename, subfolder, repo_type, revision, library_name, library_version, cache_dir, local_dir, local_dir_use_symlinks, user_agent, force_download, force_filename, proxies, etag_timeout, resume_download, token, local_files_only, legacy_cache_layout, endpoint)\u001b[0m\n\u001b[1;32m 1236\u001b[0m \u001b[0;32mtry\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 1237\u001b[0m \u001b[0;32mtry\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0;32m-> 1238\u001b[0;31m metadata = get_hf_file_metadata(\n\u001b[0m\u001b[1;32m 1239\u001b[0m \u001b[0murl\u001b[0m\u001b[0;34m=\u001b[0m\u001b[0murl\u001b[0m\u001b[0;34m,\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 1240\u001b[0m \u001b[0mtoken\u001b[0m\u001b[0;34m=\u001b[0m\u001b[0mtoken\u001b[0m\u001b[0;34m,\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n", + "\u001b[0;32m/usr/local/lib/python3.10/dist-packages/huggingface_hub/utils/_validators.py\u001b[0m in \u001b[0;36m_inner_fn\u001b[0;34m(*args, **kwargs)\u001b[0m\n\u001b[1;32m 116\u001b[0m \u001b[0mkwargs\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0msmoothly_deprecate_use_auth_token\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mfn_name\u001b[0m\u001b[0;34m=\u001b[0m\u001b[0mfn\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0m__name__\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mhas_token\u001b[0m\u001b[0;34m=\u001b[0m\u001b[0mhas_token\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mkwargs\u001b[0m\u001b[0;34m=\u001b[0m\u001b[0mkwargs\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 117\u001b[0m \u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0;32m--> 118\u001b[0;31m \u001b[0;32mreturn\u001b[0m \u001b[0mfn\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;34m*\u001b[0m\u001b[0margs\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0;34m**\u001b[0m\u001b[0mkwargs\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m\u001b[1;32m 119\u001b[0m \u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 120\u001b[0m \u001b[0;32mreturn\u001b[0m \u001b[0m_inner_fn\u001b[0m \u001b[0;31m# type: ignore\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n", + "\u001b[0;32m/usr/local/lib/python3.10/dist-packages/huggingface_hub/file_download.py\u001b[0m in \u001b[0;36mget_hf_file_metadata\u001b[0;34m(url, token, proxies, timeout, library_name, library_version, user_agent)\u001b[0m\n\u001b[1;32m 1629\u001b[0m \u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 1630\u001b[0m \u001b[0;31m# Retrieve metadata\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0;32m-> 1631\u001b[0;31m r = _request_wrapper(\n\u001b[0m\u001b[1;32m 1632\u001b[0m \u001b[0mmethod\u001b[0m\u001b[0;34m=\u001b[0m\u001b[0;34m\"HEAD\"\u001b[0m\u001b[0;34m,\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 1633\u001b[0m \u001b[0murl\u001b[0m\u001b[0;34m=\u001b[0m\u001b[0murl\u001b[0m\u001b[0;34m,\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n", + "\u001b[0;32m/usr/local/lib/python3.10/dist-packages/huggingface_hub/file_download.py\u001b[0m in \u001b[0;36m_request_wrapper\u001b[0;34m(method, url, follow_relative_redirects, **params)\u001b[0m\n\u001b[1;32m 383\u001b[0m \u001b[0;31m# Recursively follow relative redirects\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 384\u001b[0m \u001b[0;32mif\u001b[0m \u001b[0mfollow_relative_redirects\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0;32m--> 385\u001b[0;31m response = _request_wrapper(\n\u001b[0m\u001b[1;32m 386\u001b[0m \u001b[0mmethod\u001b[0m\u001b[0;34m=\u001b[0m\u001b[0mmethod\u001b[0m\u001b[0;34m,\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 387\u001b[0m \u001b[0murl\u001b[0m\u001b[0;34m=\u001b[0m\u001b[0murl\u001b[0m\u001b[0;34m,\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n", + "\u001b[0;32m/usr/local/lib/python3.10/dist-packages/huggingface_hub/file_download.py\u001b[0m in \u001b[0;36m_request_wrapper\u001b[0;34m(method, url, follow_relative_redirects, **params)\u001b[0m\n\u001b[1;32m 407\u001b[0m \u001b[0;31m# Perform request and return if status_code is not in the retry list.\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 408\u001b[0m \u001b[0mresponse\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0mget_session\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mrequest\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mmethod\u001b[0m\u001b[0;34m=\u001b[0m\u001b[0mmethod\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0murl\u001b[0m\u001b[0;34m=\u001b[0m\u001b[0murl\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0;34m**\u001b[0m\u001b[0mparams\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0;32m--> 409\u001b[0;31m \u001b[0mhf_raise_for_status\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mresponse\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m\u001b[1;32m 410\u001b[0m \u001b[0;32mreturn\u001b[0m \u001b[0mresponse\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 411\u001b[0m \u001b[0;34m\u001b[0m\u001b[0m\n", + "\u001b[0;32m/usr/local/lib/python3.10/dist-packages/huggingface_hub/utils/_errors.py\u001b[0m in \u001b[0;36mhf_raise_for_status\u001b[0;34m(response, endpoint_name)\u001b[0m\n\u001b[1;32m 294\u001b[0m \u001b[0;32melif\u001b[0m \u001b[0merror_code\u001b[0m \u001b[0;34m==\u001b[0m \u001b[0;34m\"EntryNotFound\"\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 295\u001b[0m \u001b[0mmessage\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0;34mf\"{response.status_code} Client Error.\"\u001b[0m \u001b[0;34m+\u001b[0m \u001b[0;34m\"\\n\\n\"\u001b[0m \u001b[0;34m+\u001b[0m \u001b[0;34mf\"Entry Not Found for url: {response.url}.\"\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0;32m--> 296\u001b[0;31m \u001b[0;32mraise\u001b[0m \u001b[0mEntryNotFoundError\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mmessage\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mresponse\u001b[0m\u001b[0;34m)\u001b[0m \u001b[0;32mfrom\u001b[0m \u001b[0me\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m\u001b[1;32m 297\u001b[0m \u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 298\u001b[0m \u001b[0;32melif\u001b[0m \u001b[0merror_code\u001b[0m \u001b[0;34m==\u001b[0m \u001b[0;34m\"GatedRepo\"\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n", + "\u001b[0;31mEntryNotFoundError\u001b[0m: 404 Client Error. (Request ID: Root=1-659c1570-229842ad49cdd505022bd7b3;3b3426ec-0f8e-49a4-8783-f5740d92a8ed)\n\nEntry Not Found for url: https://huggingface.co/pyannote/speaker-diarization-3.1/resolve/main/pytorch_model.bin." + ] + } + ] + }, + { + "cell_type": "code", + "source": [ + "# this does not work because `pyannote/speaker-diarization-3.1` is a not a `Model`, it is a `Pipeline`." + ], + "metadata": { + "id": "e4GWU8Sbsy9u" + }, + "execution_count": 9, + "outputs": [] + } + ] +} diff --git a/tutorials/adapting_pretrained_pipeline.ipynb b/tutorials/adapting_pretrained_pipeline.ipynb index 06d318809..ee749fd80 100644 --- a/tutorials/adapting_pretrained_pipeline.ipynb +++ b/tutorials/adapting_pretrained_pipeline.ipynb @@ -43,9 +43,7 @@ "id": "CZjbjOBBDrdm" }, "source": [ - "## Installation\n", - "\n", - "Let's start by installing `pyannote.audio` 2.1.1 (and `rich` for pretty progress bars)." + "## Installation\n" ] }, { @@ -66,7 +64,7 @@ "id": "ndQ10VIf2W1c" }, "source": [ - "⚠ Restart the runtime (Runtime > Restart runtime). \n", + "⚠ Restart the runtime (Runtime > Restart session). \n", "If you don't, `pyannote.database` will throw an error below." ] }, @@ -154,10 +152,10 @@ }, "outputs": [], "source": [ - "import os\n", - "os.environ[\"PYANNOTE_DATABASE_CONFIG\"] = \"/content/AMI-diarization-setup/pyannote/database.yml\"\n", - "from pyannote.database import get_protocol, FileFinder\n", - "dataset = get_protocol(\"AMI-SDM.SpeakerDiarization.mini\", {\"audio\": FileFinder()})" + "from pyannote.database import registry, FileFinder\n", + "\n", + "registry.load_database(\"AMI-diarization-setup/pyannote/database.yml\")\n", + "dataset = registry.get_protocol(\"AMI-SDM.SpeakerDiarization.mini\", {\"audio\": FileFinder()})" ] }, { @@ -344,7 +342,8 @@ " loss=\"bce\", \n", " vad_loss=\"bce\")\n", "model.task = task\n", - "model.setup(stage=\"fit\")" + "model.prepare_data()\n", + "model.setup()" ] }, { diff --git a/tutorials/add_your_own_model.ipynb b/tutorials/add_your_own_model.ipynb index 30020f8a9..487932588 100644 --- a/tutorials/add_your_own_model.ipynb +++ b/tutorials/add_your_own_model.ipynb @@ -1,284 +1 @@ -{ - "cells": [ - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "# Defining a custom model\n", - "\n", - "A collection of models is readily available in `pyannote.audio.models` but you will eventually want to try your own architecture. \n", - "\n", - "This tutorial explains how to define (and then use) your own model. " - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "from typing import Optional\n", - "import torch\n", - "import torch.nn as nn\n", - "from pyannote.audio import Model\n", - "from pyannote.audio.core.task import Task, Resolution\n", - "from torchaudio.transforms import MFCC\n", - "\n", - "# Your custom model must be a subclass of `pyannote.audio.Model`,\n", - "# which is a subclass of `pytorch_lightning.LightningModule`, \n", - "# which is a subclass of `torch.nn.Module`.\n", - "class MyCustomModel(Model):\n", - " \"\"\"My custom model\"\"\"\n", - "\n", - "\n", - " def __init__(\n", - " self,\n", - " sample_rate: int = 16000, \n", - " num_channels: int = 1, \n", - " task: Optional[Task] = None,\n", - " param1: int = 32,\n", - " param2: int = 16,\n", - " ):\n", - "\n", - " # First three parameters (sample_rate, num_channels, and task)\n", - " # must be there and passed to super().__init__()\n", - " super().__init__(sample_rate=sample_rate, \n", - " num_channels=num_channels, \n", - " task=task)\n", - "\n", - " # Mark param1 and param2 as hyper-parameters.\n", - " self.save_hyperparameters(\"param1\", \"param2\")\n", - "\n", - " # They will be saved automatically into checkpoints.\n", - " # They are now also available in self.hparams:\n", - " # - param1 == self.hparams.param1\n", - " # - param2 == self.hparams.param2\n", - "\n", - " # Layers that do not depend on the addressed task should be defined in '__init__'.\n", - " self.mfcc = MFCC()\n", - " self.linear1 = nn.Linear(self.mfcc.n_mfcc, self.hparams.param1)\n", - " self.linear2 = nn.Linear(self.hparams.param1, self.hparams.param2)\n", - "\n", - " def build(self):\n", - " # Add layers that depend on the specifications of the task addressed \n", - " # by this model.\n", - "\n", - " # For instance, this simple model could be used for \"speech vs. non-speech\"\n", - " # or \"speech vs. music vs. other\" classification and the only difference\n", - " # would lie in the number of classes (2 or 3) in the final classifier.\n", - " \n", - " # Since task specifications are not available at the time '__init__' is called,\n", - " # task-dependent layers can only be added a 'build' time (where task specifications\n", - " # are available in 'specifications' attribute)\n", - " \n", - " num_classes = len(self.specifications.classes)\n", - " self.classifier = nn.Linear(self.hparams.param2, num_classes)\n", - "\n", - " # 'specifications' has several attributes describing what the task is:\n", - " # - classes: the list of classes\n", - " # - problem: the type of machine learning problem (e.g. binary \n", - " # classification or representation learning) \n", - " # - duration: the duration of input audio chunks, in seconds\n", - " # - resolution: the resolution of the output (e.g. frame-wise scores\n", - " # for voice activity detection or chunk-wise vector for speaker \n", - " # embedding)\n", - " # - permutation_invariant : whether classes are permutation-invariant\n", - " # (e.g. in the case of speaker diarization)\n", - "\n", - " # Depending on the type of 'problem', 'default_activation' can be used\n", - " # to automatically guess what the final activation should be (e.g. softmax\n", - " # for multi-class classification or sigmoid for multi-label classification).\n", - " self.activation = self.default_activation()\n", - "\n", - " # You obviously do not _have_ to use 'default_activation' and can choose to\n", - " # use any activation you see fit (or even not use any activation layer). But\n", - " # note that pyannote.audio tasks also define default loss functions that are\n", - " # consistent with `default_activation` (e.g. binary cross entropy with softmax\n", - " # for binary classification tasks)\n", - " \n", - " def forward(self, waveforms: torch.Tensor) -> torch.Tensor:\n", - "\n", - " # Models are expected to work on batches of audio chunks provided as tensors\n", - " # with shape (batch_size, num_channels, num_samples) and using the sample rate \n", - " # passed to __init__. Resampling will be done automatically for you so you do \n", - " # not have to bother about that when preparing the data.\n", - "\n", - " # Extract sequence of MFCCs and passed them through two linear layers\n", - " mfcc = self.mfcc(waveforms).squeeze(dim=1).transpose(1, 2)\n", - " output = self.linear1(mfcc)\n", - " output = self.linear2(output)\n", - "\n", - " # Apply temporal pooling for tasks which need an output at chunk-level. \n", - " if self.specifications.resolution == Resolution.CHUNK:\n", - " output = torch.mean(output, dim=-1)\n", - " # Keep 'mfcc' frame resolution for frame-level tasks.\n", - " elif self.specifications.resolution == Resolution.FRAME:\n", - " pass\n", - " \n", - " # Apply final classifier and activation function\n", - " output = self.classifier(output)\n", - " return self.activation(output) " - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "## Using your model with `pyannote.audio` API \n", - "\n", - "Your model can now be used like any other builtin model." - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "# initialize your experimental protocol\n", - "from pyannote.database import get_protocol\n", - "protocol = get_protocol('Debug.SpeakerDiarization.Debug')\n", - "\n", - "# initialize the task you want to address\n", - "from pyannote.audio.tasks import VoiceActivityDetection\n", - "task = VoiceActivityDetection(protocol)\n", - "\n", - "# initialize the model\n", - "model = MyCustomModel(task=task)\n", - "\n", - "# train the model\n", - "from pytorch_lightning import Trainer\n", - "trainer = Trainer(max_epochs=1)\n", - "trainer.fit(model)" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "## Using your model with `pyannote-audio-train` CLI\n", - "\n", - "1. Define your model in a proper Python package:\n", - "\n", - "```\n", - "/your/favorite/directory/\n", - " your_package_name/\n", - " __init__.py # needs to be here but can be empty\n", - " custom_model.py # contains the above definition of your model \n", - "```\n", - "\n", - "2. Add the package to your `PYTHONPATH`:\n", - "\n", - "```bash\n", - "$ export PYTHONPATH=/your/favorite/directory\n", - "```\n", - "\n", - "3. Check that you can import it from Python:\n", - "\n", - "```python\n", - ">>> from your_package_name.custom_model import MyCustomModel\n", - "```\n", - "\n", - "4. Tell `Hydra` (on which `pyannote-audio-train` is based) about this new model:\n", - "\n", - "```\n", - "/your/favorite/directory/\n", - " custom_config/\n", - " model/\n", - " MyCustomModel.yaml\n", - "```\n", - "\n", - "where the content of `MyCustomModel.yaml` is as follows:\n", - "\n", - "```yaml\n", - "# @package _group_\n", - "_target_: your_package_name.custom_model.MyCustomModel\n", - "param1: 32\n", - "param2: 16\n", - "```\n", - "\n", - "5. Enjoy\n", - "\n", - "```bash\n", - "$ pyannote-audio-train --config-dir=/your/favorite/directory/custom_config \\\n", - " protocol=Debug.SpeakerDiarization.Debug \\\n", - " task=VoiceActivityDetection \\\n", - " model=MyCustomModel \\\n", - " model.param2=12 \n", - "```" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "## Contributing your model to `pyannote-audio` \n", - "\n", - "1. Add your model in `pyannote.audio.models`.\n", - "\n", - "```\n", - "pyannote/\n", - " audio/\n", - " models/\n", - " custom_model.py \n", - "```\n", - "\n", - "2. Check that you can import it from Python:\n", - "\n", - "```python\n", - ">>> from pyannote.audio.models.custom_model import MyCustomModel\n", - "```\n", - "\n", - "3. Add the corresponding `Hydra` configuration file:\n", - "\n", - "```\n", - "pyannote/\n", - " audio/\n", - " cli/\n", - " train_config/\n", - " model/\n", - " MyCustomModel.yaml\n", - "```\n", - "\n", - "where the content of `MyCustomModel.yaml` is as follows:\n", - "\n", - "```yaml\n", - "# @package _group_\n", - "_target_: pyannote.audio.models.custom_model.MyCustomModel\n", - "param1: 32\n", - "param2: 16\n", - "```\n", - "\n", - "4. Enjoy\n", - "\n", - "```bash\n", - "$ pyannote-audio-train protocol=Debug.SpeakerDiarization.Debug \\\n", - " task=VoiceActivityDetection \\\n", - " model=MyCustomModel \\\n", - " model.param2=12 \n", - "```" - ] - } - ], - "metadata": { - "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.5" - } - }, - "nbformat": 4, - "nbformat_minor": 2 -} +{"cells":[{"cell_type":"markdown","metadata":{"id":"kY1p-wCLHw92"},"source":["# Add your own model"]},{"cell_type":"markdown","metadata":{"id":"iD_DNGmmHs9v"},"source":["\"Open"]},{"cell_type":"markdown","metadata":{"id":"hhBTSvk6H_JC"},"source":["## Tutorial setup"]},{"cell_type":"markdown","metadata":{"id":"r-ocA5Z8PqNl"},"source":["### `Google Colab` setup"]},{"cell_type":"markdown","metadata":{"id":"I7lc6ctfIBv-"},"source":["If you are running this tutorial on `Colab`, execute the following commands in order to setup `Colab` environment. These commands will install `pyannote.audio` and download a mini version of the `AMI` corpus."]},{"cell_type":"code","execution_count":null,"metadata":{"id":"l07Xq_UAIUFE"},"outputs":[],"source":["!pip install -qq pyannote.audio==3.1.1\n","!pip install -qq ipython==7.34.0\n","!git clone https://github.com/pyannote/AMI-diarization-setup.git\n","%cd ./AMI-diarization-setup/pyannote/\n","!bash ./download_ami_mini.sh\n","%cd /content"]},{"cell_type":"markdown","metadata":{"id":"3rjw5hATOv_c"},"source":["⚠ Restart the runtime (Runtime > Restart session)."]},{"cell_type":"markdown","metadata":{},"source":["### Non `Google Colab` setup"]},{"cell_type":"markdown","metadata":{"id":"VdMVQD-9QAto"},"source":["If you are not using `Colab`, this tutorial assumes that\n","* `pyannote.audio` has been installed\n","* the [AMI corpus](https://groups.inf.ed.ac.uk/ami/corpus/) has already been [setup for use with `pyannote`](https://github.com/pyannote/AMI-diarization-setup/tree/main/pyannote)"]},{"cell_type":"markdown","metadata":{"id":"kuemd4PWHeqh"},"source":["## Defining a custom model\n","\n","A collection of models is readily available in `pyannote.audio.models` but you will eventually want to try your own architecture.\n","\n","This tutorial explains how to define (and then use) your own model. "]},{"cell_type":"code","execution_count":18,"metadata":{"colab":{"base_uri":"https://localhost:8080/"},"executionInfo":{"elapsed":12960,"status":"ok","timestamp":1704802939163,"user":{"displayName":"Clément PAGES","userId":"11757386314069785178"},"user_tz":-60},"id":"kNwQfnTOHeqm","outputId":"5f71bde3-5f13-4431-918f-6e1ca3ddd518"},"outputs":[],"source":["from typing import Optional\n","import torch\n","import torch.nn as nn\n","from pyannote.audio import Model\n","from pyannote.core import SlidingWindow\n","from pyannote.audio.core.task import Task, Resolution\n","from torchaudio.transforms import MFCC\n","\n","# Your custom model must be a subclass of `pyannote.audio.Model`,\n","# which is a subclass of `pytorch_lightning.LightningModule`,\n","# which is a subclass of `torch.nn.Module`.\n","class MyCustomModel(Model):\n"," \"\"\"My custom model\"\"\"\n","\n","\n"," def __init__(\n"," self,\n"," sample_rate: int = 16000,\n"," num_channels: int = 1,\n"," task: Optional[Task] = None,\n"," param1: int = 32,\n"," param2: int = 16,\n"," ):\n","\n"," # First three parameters (sample_rate, num_channels, and task)\n"," # must be there and passed to super().__init__()\n"," super().__init__(sample_rate=sample_rate,\n"," num_channels=num_channels,\n"," task=task)\n","\n"," # Mark param1 and param2 as hyper-parameters.\n"," self.save_hyperparameters(\"param1\", \"param2\")\n","\n"," # They will be saved automatically into checkpoints.\n"," # They are now also available in self.hparams:\n"," # - param1 == self.hparams.param1\n"," # - param2 == self.hparams.param2\n","\n"," # Layers that do not depend on the addressed task should be defined in '__init__'.\n"," self.mfcc = MFCC()\n"," self.linear1 = nn.Linear(self.mfcc.n_mfcc, self.hparams.param1)\n"," self.linear2 = nn.Linear(self.hparams.param1, self.hparams.param2)\n","\n"," def num_frames(self, num_samples: int) -> int:\n"," # Compute number of output frames for a given number of input samples\n"," hop_length = self.mfcc.MelSpectrogram.spectrogram.hop_length\n"," n_fft = self.mfcc.MelSpectrogram.spectrogram.n_fft\n"," center = self.mfcc.MelSpectrogram.spectrogram.center\n"," return (\n"," 1 + num_samples // hop_length\n"," if center\n"," else 1 + (num_samples - n_fft) // hop_length\n"," )\n","\n"," def receptive_field_size(self, num_frames: int = 1) -> int:\n"," # Compute receptive field size\n"," hop_length = self.mfcc.MelSpectrogram.spectrogram.hop_length\n"," n_fft = self.mfcc.MelSpectrogram.spectrogram.n_fft\n"," center = self.mfcc.MelSpectrogram.spectrogram.center\n","\n"," if center:\n"," return (num_frames - 1) * hop_length\n"," else:\n"," return (num_frames - 1) * hop_length + n_fft\n","\n"," def receptive_field(self) -> SlidingWindow:\n"," # Compute receptive field\n","\n"," # duration of the receptive field of each output frame\n"," duration = (\n"," self.mfcc.MelSpectrogram.spectrogram.win_length / self.hparams.sample_rate\n"," )\n","\n"," # step between the receptive field region of two consecutive output frames\n"," step = (\n"," self.mfcc.MelSpectrogram.spectrogram.hop_length / self.hparams.sample_rate\n"," )\n","\n"," return SlidingWindow(start=0.0, duration=duration, step=step)\n","\n"," def build(self):\n"," # Add layers that depend on the specifications of the task addressed\n"," # by this model.\n","\n"," # For instance, this simple model could be used for \"speech vs. non-speech\"\n"," # or \"speech vs. music vs. other\" classification and the only difference\n"," # would lie in the number of classes (2 or 3) in the final classifier.\n","\n"," # Since task specifications are not available at the time '__init__' is called,\n"," # task-dependent layers can only be added a 'build' time (where task specifications\n"," # are available in 'specifications' attribute)\n","\n"," num_classes = len(self.specifications.classes)\n"," self.classifier = nn.Linear(self.hparams.param2, num_classes)\n","\n"," # 'specifications' has several attributes describing what the task is:\n"," # - classes: the list of classes\n"," # - problem: the type of machine learning problem (e.g. binary\n"," # classification or representation learning)\n"," # - duration: the duration of input audio chunks, in seconds\n"," # - resolution: the resolution of the output (e.g. frame-wise scores\n"," # for voice activity detection or chunk-wise vector for speaker\n"," # embedding)\n"," # - permutation_invariant : whether classes are permutation-invariant\n"," # (e.g. in the case of speaker diarization)\n","\n"," # Depending on the type of 'problem', 'default_activation' can be used\n"," # to automatically guess what the final activation should be (e.g. softmax\n"," # for multi-class classification or sigmoid for multi-label classification).\n"," self.activation = self.default_activation()\n","\n"," # You obviously do not _have_ to use 'default_activation' and can choose to\n"," # use any activation you see fit (or even not use any activation layer). But\n"," # note that pyannote.audio tasks also define default loss functions that are\n"," # consistent with `default_activation` (e.g. binary cross entropy with softmax\n"," # for binary classification tasks)\n","\n"," def forward(self, waveforms: torch.Tensor) -> torch.Tensor:\n","\n"," # Models are expected to work on batches of audio chunks provided as tensors\n"," # with shape (batch_size, num_channels, num_samples) and using the sample rate\n"," # passed to __init__. Resampling will be done automatically for you so you do\n"," # not have to bother about that when preparing the data.\n","\n"," # Extract sequence of MFCCs and passed them through two linear layers\n"," mfcc = self.mfcc(waveforms).squeeze(dim=1).transpose(1, 2)\n"," output = self.linear1(mfcc)\n"," output = self.linear2(output)\n","\n"," # Apply temporal pooling for tasks which need an output at chunk-level.\n"," if self.specifications.resolution == Resolution.CHUNK:\n"," output = torch.mean(output, dim=-1)\n"," # Keep 'mfcc' frame resolution for frame-level tasks.\n"," elif self.specifications.resolution == Resolution.FRAME:\n"," pass\n","\n"," # Apply final classifier and activation function\n"," output = self.classifier(output)\n"," return self.activation(output)"]},{"cell_type":"markdown","metadata":{"id":"BuieqViJHeqp"},"source":["## Using your model with `pyannote.audio` API\n","\n","Your model can now be used like any other builtin model."]},{"cell_type":"code","execution_count":null,"metadata":{"id":"qwTjuGuvHeqr"},"outputs":[],"source":["# initialize your experimental protocol\n","from pyannote.database import registry, FileFinder\n","\n","registry.load_database(\"./AMI-diarization-setup/pyannote/database.yml\")\n","protocol = registry.get_protocol('AMI.SpeakerDiarization.mini', preprocessors={\"audio\": FileFinder()})\n","\n","# initialize the task you want to address\n","from pyannote.audio.tasks import VoiceActivityDetection\n","task = VoiceActivityDetection(protocol)\n","\n","# initialize the model\n","model = MyCustomModel(task=task)\n","\n","# train the model\n","from pytorch_lightning import Trainer\n","trainer = Trainer(max_epochs=1)\n","trainer.fit(model)"]},{"cell_type":"markdown","metadata":{"id":"4qidmGQyHeqt"},"source":["## Using your model with `pyannote-audio-train` CLI\n","\n","1. Define your model in a proper Python package:\n","\n","```\n","/your/favorite/directory/\n"," your_package_name/\n"," __init__.py # needs to be here but can be empty\n"," custom_model.py # contains the above definition of your model\n","```\n","\n","2. Add the package to your `PYTHONPATH`:\n","\n","```bash\n","$ export PYTHONPATH=/your/favorite/directory\n","```\n","\n","3. Check that you can import it from Python:\n","\n","```python\n",">>> from your_package_name.custom_model import MyCustomModel\n","```\n","\n","4. Tell `Hydra` (on which `pyannote-audio-train` is based) about this new model:\n","\n","```\n","/your/favorite/directory/\n"," custom_config/\n"," model/\n"," MyCustomModel.yaml\n","```\n","\n","where the content of `MyCustomModel.yaml` is as follows:\n","\n","```yaml\n","# @package _group_\n","_target_: your_package_name.custom_model.MyCustomModel\n","param1: 32\n","param2: 16\n","```\n","\n","5. Enjoy\n","\n","```bash\n","$ pyannote-audio-train --config-dir=/your/favorite/directory/custom_config \\\n"," protocol=Debug.SpeakerDiarization.Debug \\\n"," task=VoiceActivityDetection \\\n"," model=MyCustomModel \\\n"," model.param2=12\n","```"]},{"cell_type":"markdown","metadata":{"id":"8W2UT1IpHequ"},"source":["## Contributing your model to `pyannote-audio`\n","\n","1. Add your model in `pyannote.audio.models`.\n","\n","```\n","pyannote/\n"," audio/\n"," models/\n"," custom_model.py \n","```\n","\n","2. Check that you can import it from Python:\n","\n","```python\n",">>> from pyannote.audio.models.custom_model import MyCustomModel\n","```\n","\n","3. Add the corresponding `Hydra` configuration file:\n","\n","```\n","pyannote/\n"," audio/\n"," cli/\n"," train_config/\n"," model/\n"," MyCustomModel.yaml\n","```\n","\n","where the content of `MyCustomModel.yaml` is as follows:\n","\n","```yaml\n","# @package _group_\n","_target_: pyannote.audio.models.custom_model.MyCustomModel\n","param1: 32\n","param2: 16\n","```\n","\n","4. Enjoy\n","\n","```bash\n","$ pyannote-audio-train protocol=Debug.SpeakerDiarization.Debug \\\n"," task=VoiceActivityDetection \\\n"," model=MyCustomModel \\\n"," model.param2=12\n","```"]}],"metadata":{"accelerator":"GPU","colab":{"gpuType":"T4","provenance":[]},"kernelspec":{"display_name":"Python 3","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.10.13"}},"nbformat":4,"nbformat_minor":0} diff --git a/tutorials/add_your_own_task.ipynb b/tutorials/add_your_own_task.ipynb index 251846957..b572e3d28 100644 --- a/tutorials/add_your_own_task.ipynb +++ b/tutorials/add_your_own_task.ipynb @@ -1,350 +1 @@ -{ - "cells": [ - { - "attachments": {}, - "cell_type": "markdown", - "metadata": {}, - "source": [ - "# Defining a custom task\n", - "\n", - "In `pyannote.audio`, a *task* is a combination of a **_problem_** that needs to be addressed and an **experimental protocol**.\n", - "\n", - "For example, one can address **_voice activity detection_** following the **AMI only_words** experimental protocol, by instantiating the following *task*:\n" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "# this assumes that the AMI corpus has been setup for diarization\n", - "# according to https://github.com/pyannote/AMI-diarization-setup\n", - "import os\n", - "os.environ['PYANNOTE_DATABASE_CONFIG'] = '/Users/bredin/Development/pyannote/pyannote-db/AMI-diarization-setup/pyannote/database.yml'\n", - "\n", - "from pyannote.database import get_protocol, FileFinder\n", - "ami = get_protocol('AMI.SpeakerDiarization.only_words', \n", - " preprocessors={'audio': FileFinder()})\n", - "\n", - "# address voice activity detection\n", - "from pyannote.audio.tasks import VoiceActivityDetection\n", - "task = VoiceActivityDetection(ami)" - ] - }, - { - "attachments": {}, - "cell_type": "markdown", - "metadata": {}, - "source": [ - "A growing collection of tasks is readily available in `pyannote.audio.tasks`..." - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "from pyannote.audio.tasks import __all__ as TASKS; print('\\n'.join(TASKS))" - ] - }, - { - "attachments": {}, - "cell_type": "markdown", - "metadata": {}, - "source": [ - "... but you will eventually want to use `pyannote.audio` to address a different task. \n", - "In this example, we will add a new task addressing the **sound event detection** problem.\n", - "\n" - ] - }, - { - "attachments": {}, - "cell_type": "markdown", - "metadata": {}, - "source": [ - "## Problem specification\n", - "\n", - "A problem is expected to be solved by a model $f$ that takes an audio chunk $X$ as input and returns its predicted solution $\\hat{y} = f(X)$. \n", - "\n", - "### Resolution\n", - "\n", - "Depending on the addressed problem, you might expect the model to output just one prediction for the whole audio chunk (`Resolution.CHUNK`) or a temporal sequence of predictions (`Resolution.FRAME`).\n", - "\n", - "In our particular case, we would like the model to provide one decision for the whole chunk:" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "from pyannote.audio.core.task import Resolution\n", - "resolution = Resolution.CHUNK" - ] - }, - { - "attachments": {}, - "cell_type": "markdown", - "metadata": {}, - "source": [ - "### Type of problem\n", - "\n", - "Similarly, the type of your problem may fall into one of these generic machine learning categories:\n", - "* `Problem.BINARY_CLASSIFICATION` for binary classification\n", - "* `Problem.MONO_LABEL_CLASSIFICATION` for multi-class classification \n", - "* `Problem.MULTI_LABEL_CLASSIFICATION` for multi-label classification\n", - "* `Problem.REGRESSION` for regression\n", - "* `Problem.REPRESENTATION` for representation learning\n", - "\n", - "In our particular case, we would like the model to do multi-label classification because one audio chunk may contain multiple sound events:" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "from pyannote.audio.core.task import Problem\n", - "problem = Problem.MULTI_LABEL_CLASSIFICATION" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "from pyannote.audio.core.task import Specifications\n", - "specifications = Specifications(\n", - " problem=problem,\n", - " resolution=resolution,\n", - " duration=5.0,\n", - " classes=[\"Speech\", \"Dog\", \"Cat\", \"Alarm_bell_ringing\", \"Dishes\", \n", - " \"Frying\", \"Blender\", \"Running_water\", \"Vacuum_cleaner\", \n", - " \"Electric_shaver_toothbrush\"],\n", - ")" - ] - }, - { - "attachments": {}, - "cell_type": "markdown", - "metadata": {}, - "source": [ - "A task is expected to be solved by a model $f$ that (usually) takes an audio chunk $X$ as input and returns its predicted solution $\\hat{y} = f(X)$. \n", - "\n", - "To help training the model $f$, the task $\\mathcal{T}$ is in charge of \n", - "- generating $(X, y)$ training samples using the **dataset**\n", - "- defining the loss function $\\mathcal{L}(y, \\hat{y})$\n" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "from typing import Optional\n", - "import torch\n", - "import torch.nn as nn\n", - "import numpy as np\n", - "from pyannote.core import Annotation\n", - "from pyannote.audio import Model\n", - "from pyannote.audio.core.task import Task, Resolution\n", - "\n", - "# Your custom task must be a subclass of `pyannote.audio.core.task.Task`\n", - "class SoundEventDetection(Task):\n", - " \"\"\"Sound event detection\"\"\"\n", - "\n", - " def __init__(\n", - " self,\n", - " protocol: Protocol,\n", - " duration: float = 5.0,\n", - " warm_up: Union[float, Tuple[float, float]] = 0.0,\n", - " batch_size: int = 32,\n", - " num_workers: int = None,\n", - " pin_memory: bool = False,\n", - " augmentation: BaseWaveformTransform = None,\n", - " **other_params,\n", - " ):\n", - "\n", - " super().__init__(\n", - " protocol,\n", - " duration=duration,\n", - " min_duration=min_duration,\n", - " warm_up=warm_up,\n", - " batch_size=batch_size,\n", - " num_workers=num_workers,\n", - " pin_memory=pin_memory,\n", - " augmentation=augmentation,\n", - " )\n", - "\n", - " def setup(self):\n", - "\n", - " # load metadata for training subset\n", - " self.train_metadata_ = list()\n", - " for training_file in self.protocol.train():\n", - " self.training_metadata_.append({\n", - " # path to audio file (str)\n", - " \"audio\": training_file[\"audio\"],\n", - " # duration of audio file (float)\n", - " \"duration\": training_file[\"duration\"],\n", - " # reference annotation (pyannote.core.Annotation)\n", - " \"annotation\": training_file[\"annotation\"],\n", - " })\n", - "\n", - " # gather the list of classes\n", - " classes = set()\n", - " for training_file in self.train_metadata_:\n", - " classes.update(training_file[\"reference\"].labels())\n", - " classes = sorted(classes)\n", - "\n", - " # specify the addressed problem\n", - " self.specifications = Specifications(\n", - " # it is a multi-label classification problem\n", - " problem=Problem.MULTI_LABEL_CLASSIFICATION,\n", - " # we expect the model to output one prediction \n", - " # for the whole chunk\n", - " resolution=Resolution.CHUNK,\n", - " # the model will ingest chunks with that duration (in seconds)\n", - " duration=self.duration,\n", - " # human-readable names of classes\n", - " classes=classes)\n", - "\n", - " # `has_validation` is True iff protocol defines a development set\n", - " if not self.has_validation:\n", - " return\n", - "\n", - " # load metadata for validation subset\n", - " self.validation_metadata_ = list()\n", - " for validation_file in self.protocol.development():\n", - " self.validation_metadata_.append({\n", - " \"audio\": validation_file[\"audio\"],\n", - " \"num_samples\": math.floor(validation_file[\"duration\"] / self.duration),\n", - " \"annotation\": validation_file[\"annotation\"],\n", - " })\n", - " \n", - " \n", - "\n", - " def train__iter__(self):\n", - " # this method generates training samples, one at a time, \"ad infinitum\". each worker \n", - " # of the dataloader will run it, independently from other workers. pyannote.audio and\n", - " # pytorch-lightning will take care of making batches out of it.\n", - "\n", - " # create worker-specific random number generator (RNG) to avoid this common bug:\n", - " # tanelp.github.io/posts/a-bug-that-plagues-thousands-of-open-source-ml-projects/\n", - " rng = create_rng_for_worker(self.model.current_epoch)\n", - "\n", - " # load list and number of classes\n", - " classes = self.specifications.classes\n", - " num_classes = len(classes)\n", - "\n", - " # yield training samples \"ad infinitum\"\n", - " while True:\n", - "\n", - " # select training file at random\n", - " random_training_file, *_ = rng.choices(self.train_metadata_, k=1)\n", - "\n", - " # select one chunk at random \n", - " random_start_time = rng.uniform(0, random_training_file[\"duration\"] - self.duration)\n", - " random_chunk = Segment(random_start_time, random_start_time + self.duration)\n", - "\n", - " # load audio excerpt corresponding to random chunk\n", - " X = self.model.audio.crop(random_training_file[\"audio\"], \n", - " random_chunk, \n", - " fixed=self.duration)\n", - " \n", - " # load labels corresponding to random chunk as {0|1} numpy array\n", - " # y[k] = 1 means that kth class is active\n", - " y = np.zeros((num_classes,))\n", - " active_classes = random_training_file[\"annotation\"].crop(random_chunk).labels()\n", - " for active_class in active_classes:\n", - " y[classes.index(active_class)] = 1\n", - " \n", - " # yield training samples as a dict (use 'X' for input and 'y' for target)\n", - " yield {'X': X, 'y': y}\n", - "\n", - " def train__len__(self):\n", - " # since train__iter__ runs \"ad infinitum\", we need a way to define what an epoch is.\n", - " # this is the purpose of this method. it outputs the number of training samples that\n", - " # make an epoch.\n", - "\n", - " # we compute this number as the total duration of the training set divided by \n", - " # duration of training chunks. we make sure that an epoch is at least one batch long,\n", - " # or pytorch-lightning will complain\n", - " train_duration = sum(training_file[\"duration\"] for training_file in self.train_metadata_)\n", - " return max(self.batch_size, math.ceil(train_duration / self.duration))\n", - "\n", - " def val__getitem__(self, sample_idx):\n", - "\n", - " # load list and number of classes\n", - " classes = self.specifications.classes\n", - " num_classes = len(classes)\n", - "\n", - "\n", - " # find which part of the validation set corresponds to sample_idx\n", - " num_samples = np.cumsum([\n", - " validation_file[\"num_samples\"] for validation_file in self.validation_metadata_])\n", - " file_idx = np.where(num_samples < sample_idx)[0][0]\n", - " validation_file = self.validation_metadata_[file_idx]\n", - " idx = sample_idx - (num_samples[file_idx] - validation_file[\"num_samples\"]) \n", - " chunk = SlidingWindow(start=0., duration=self.duration, step=self.duration)[idx]\n", - "\n", - " # load audio excerpt corresponding to current chunk\n", - " X = self.model.audio.crop(validation_file[\"audio\"], chunk, fixed=self.duration)\n", - "\n", - " # load labels corresponding to random chunk as {0|1} numpy array\n", - " # y[k] = 1 means that kth class is active\n", - " y = np.zeros((num_classes,))\n", - " active_classes = validaiton_file[\"annotation\"].crop(chunk).labels()\n", - " for active_class in active_classes:\n", - " y[classes.index(active_class)] = 1\n", - "\n", - " return {'X': X, 'y': y}\n", - "\n", - " def val__len__(self):\n", - " return sum(validation_file[\"num_samples\"] \n", - " for validation_file in self.validation_metadata_)\n", - "\n", - " # `pyannote.audio.core.task.Task` base class provides a `LightningModule.training_step` and \n", - " # `LightningModule.validation_step` methods that rely on self.specifications to guess which \n", - " # loss and metrics should be used. you can obviously choose to customize them. \n", - " # More details can be found in pytorch-lightning documentation and in \n", - " # pyannote.audio.core.task.Task source code. \n", - "\n", - " # def training_step(self, batch, batch_idx: int):\n", - " # return loss\n", - "\n", - " # def validation_step(self, batch, batch_idx: int):\n", - " # return metric\n", - "\n", - " # pyannote.audio.tasks.segmentation.mixin also provides a convenient mixin\n", - " # for \"segmentation\" tasks (ie. with Resolution.FRAME) that already defines\n", - " # a bunch of useful methods. \n" - ] - } - ], - "metadata": { - "kernelspec": { - "display_name": "Python 3.8.5 64-bit ('pyannote-audio-v2': conda)", - "name": "python385jvsc74a57bd0af55542e943232842f746a64555e4e006c72c98a3a863e85e6cbaf12772fa219" - }, - "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.5" - } - }, - "nbformat": 4, - "nbformat_minor": 2 -} +{"cells":[{"cell_type":"markdown","metadata":{"id":"W7BMj2EZlWqU"},"source":["\"Open"]},{"cell_type":"markdown","metadata":{"id":"HG6OvaE4lWqZ"},"source":["# Defining a custom task"]},{"cell_type":"markdown","metadata":{"id":"c6LwrLYVlWqZ"},"source":["## Tutorial setup"]},{"cell_type":"markdown","metadata":{"id":"6lR9bgJBlWqb"},"source":["### `Google Colab` setup"]},{"cell_type":"markdown","metadata":{},"source":["If you are running this tutorial on `Colab`, execute the following commands in order to setup `Colab` environment. These commands will install `pyannote.audio` and download a mini version of the `AMI` corpus."]},{"cell_type":"code","execution_count":null,"metadata":{"colab":{"base_uri":"https://localhost:8080/"},"executionInfo":{"elapsed":127254,"status":"ok","timestamp":1704809957597,"user":{"displayName":"Clément PAGES","userId":"11757386314069785178"},"user_tz":-60},"id":"6LoOS-PjlWqd","outputId":"cd92e2d4-83cc-4bb0-ad5c-824cb2ca11ac"},"outputs":[],"source":["!pip install -qq pyannote.audio==3.1.1\n","!pip install -qq ipython==7.34.0\n","!git clone https://github.com/pyannote/AMI-diarization-setup.git\n","%cd ./AMI-diarization-setup/pyannote/\n","!bash ./download_ami_mini.sh\n","%cd /content"]},{"cell_type":"markdown","metadata":{"id":"LsZTSX-ulWqf"},"source":["⚠ Restart the runtime (Runtime > Restart session)."]},{"cell_type":"markdown","metadata":{"id":"904hVjv8lWqg"},"source":["### Non `Google Colab` setup"]},{"cell_type":"markdown","metadata":{"id":"serWAfFxlWqh"},"source":["If you are not using `Colab`, this tutorial assumes that\n","* `pyannote.audio` has been installed\n","* the [AMI corpus](https://groups.inf.ed.ac.uk/ami/corpus/) has already been [setup for use with `pyannote`](https://github.com/pyannote/AMI-diarization-setup/tree/main/pyannote)"]},{"cell_type":"markdown","metadata":{"id":"uWyNce9FlkA3"},"source":["## Task in `pyannote.audio`"]},{"cell_type":"markdown","metadata":{"id":"BK4hbdq6lWqj"},"source":["\n","In `pyannote.audio`, a *task* is a combination of a **_problem_** that needs to be addressed and an **experimental protocol**.\n","\n","For example, one can address **_voice activity detection_** following the **AMI only_words** experimental protocol, by instantiating the following *task*:\n"]},{"cell_type":"code","execution_count":null,"metadata":{"id":"-4B8nLDmlWql"},"outputs":[],"source":["# this assumes that the AMI corpus has been setup for diarization\n","# according to https://github.com/pyannote/AMI-diarization-setup\n","\n","from pyannote.database import registry, FileFinder\n","registry.load_database(\"AMI-diarization-setup/pyannote/database.yml\")\n","ami = registry.get_protocol('AMI.SpeakerDiarization.mini',\n"," preprocessors={'audio': FileFinder()})\n","\n","# address voice activity detection\n","from pyannote.audio.tasks import VoiceActivityDetection\n","task = VoiceActivityDetection(ami)"]},{"cell_type":"markdown","metadata":{"id":"A9nxwDQGlWqn"},"source":["A growing collection of tasks is readily available in `pyannote.audio.tasks`..."]},{"cell_type":"code","execution_count":2,"metadata":{"colab":{"base_uri":"https://localhost:8080/"},"executionInfo":{"elapsed":232,"status":"ok","timestamp":1704810010556,"user":{"displayName":"Clément PAGES","userId":"11757386314069785178"},"user_tz":-60},"id":"qbbDA2P5lWqp","outputId":"bf1988fb-9140-4d6a-8a2c-970578331f35"},"outputs":[{"name":"stdout","output_type":"stream","text":["SpeakerDiarization\n","VoiceActivityDetection\n","OverlappedSpeechDetection\n","MultiLabelSegmentation\n","SpeakerEmbedding\n","Segmentation\n"]}],"source":["from pyannote.audio.tasks import __all__ as TASKS; print('\\n'.join(TASKS))"]},{"cell_type":"markdown","metadata":{"id":"hihPu4iElWqr"},"source":["... but you will eventually want to use `pyannote.audio` to address a different task. \n","In this example, we will add a new task addressing the **sound event detection** problem.\n","\n"]},{"cell_type":"markdown","metadata":{"id":"RZOs3C4HlWqr"},"source":["## Problem specification\n","\n","A problem is expected to be solved by a model $f$ that takes an audio chunk $X$ as input and returns its predicted solution $\\hat{y} = f(X)$.\n","\n","### Resolution\n","\n","Depending on the addressed problem, you might expect the model to output just one prediction for the whole audio chunk (`Resolution.CHUNK`) or a temporal sequence of predictions (`Resolution.FRAME`).\n","\n","In our particular case, we would like the model to provide one decision for the whole chunk:"]},{"cell_type":"code","execution_count":3,"metadata":{"executionInfo":{"elapsed":234,"status":"ok","timestamp":1704810016464,"user":{"displayName":"Clément PAGES","userId":"11757386314069785178"},"user_tz":-60},"id":"G96Mz8vPlWqs"},"outputs":[],"source":["from pyannote.audio.core.task import Resolution\n","resolution = Resolution.CHUNK"]},{"cell_type":"markdown","metadata":{"id":"_Efd28eclWqt"},"source":["### Type of problem\n","\n","Similarly, the type of your problem may fall into one of these generic machine learning categories:\n","* `Problem.BINARY_CLASSIFICATION` for binary classification\n","* `Problem.MONO_LABEL_CLASSIFICATION` for multi-class classification\n","* `Problem.MULTI_LABEL_CLASSIFICATION` for multi-label classification\n","* `Problem.REGRESSION` for regression\n","* `Problem.REPRESENTATION` for representation learning\n","\n","In our particular case, we would like the model to do multi-label classification because one audio chunk may contain multiple sound events:"]},{"cell_type":"code","execution_count":4,"metadata":{"executionInfo":{"elapsed":315,"status":"ok","timestamp":1704810020230,"user":{"displayName":"Clément PAGES","userId":"11757386314069785178"},"user_tz":-60},"id":"Cl0VqB5jlWqu"},"outputs":[],"source":["from pyannote.audio.core.task import Problem\n","problem = Problem.MULTI_LABEL_CLASSIFICATION"]},{"cell_type":"code","execution_count":5,"metadata":{"executionInfo":{"elapsed":251,"status":"ok","timestamp":1704810021646,"user":{"displayName":"Clément PAGES","userId":"11757386314069785178"},"user_tz":-60},"id":"Hz_B7FCplWqv"},"outputs":[],"source":["from pyannote.audio.core.task import Specifications\n","specifications = Specifications(\n"," problem=problem,\n"," resolution=resolution,\n"," duration=5.0,\n"," classes=[\"Speech\", \"Dog\", \"Cat\", \"Alarm_bell_ringing\", \"Dishes\",\n"," \"Frying\", \"Blender\", \"Running_water\", \"Vacuum_cleaner\",\n"," \"Electric_shaver_toothbrush\"],\n",")"]},{"cell_type":"markdown","metadata":{"id":"5N72ksU7lWqv"},"source":["A task is expected to be solved by a model $f$ that (usually) takes an audio chunk $X$ as input and returns its predicted solution $\\hat{y} = f(X)$.\n","\n","To help training the model $f$, the task $\\mathcal{T}$ is in charge of\n","- generating $(X, y)$ training samples using the **dataset**\n","- defining the loss function $\\mathcal{L}(y, \\hat{y})$\n"]},{"cell_type":"code","execution_count":null,"metadata":{"id":"lrTD1RwUlWqw"},"outputs":[],"source":["from math import ceil\n","from typing import Dict, Optional,Tuple, Union\n","import numpy as np\n","from pyannote.core import Segment, SlidingWindow\n","from pyannote.audio.utils.random import create_rng_for_worker\n","from pyannote.audio.core.task import Task, Resolution\n","from pyannote.database import Protocol\n","from torchmetrics.classification import MultilabelAUROC\n","\n","# Your custom task must be a subclass of `pyannote.audio.core.task.Task`\n","class SoundEventDetection(Task):\n"," \"\"\"Sound event detection\"\"\"\n","\n"," def __init__(\n"," self,\n"," protocol: Protocol,\n"," duration: float = 5.0,\n"," min_duration: float = 5.0,\n"," warm_up: Union[float, Tuple[float, float]] = 0.0,\n"," batch_size: int = 32,\n"," num_workers: int = None,\n"," pin_memory: bool = False,\n"," augmentation = None,\n"," cache: Optional[Union[str, None]] = None,\n"," **other_params,\n"," ):\n","\n"," super().__init__(\n"," protocol,\n"," duration=duration,\n"," min_duration=min_duration,\n"," warm_up=warm_up,\n"," batch_size=batch_size,\n"," num_workers=num_workers,\n"," pin_memory=pin_memory,\n"," augmentation=augmentation,\n"," cache=cache,\n"," )\n"," \n"," def prepare_data(self):\n"," # this method is called to prepare data from the specified protocol. \n"," # For most tasks, calling Task.prepare_data() is sufficient. If you \n"," # need to prepare task-specific data, define a post_prepare_data method for your task.\n"," super().prepare_data()\n","\n"," def post_prepare_data(self, prepared_data: Dict):\n"," # this method is called at the end of Task.prepare_data() \n"," # to complete data preparation with task-specific data, here \n"," # the list of classes and some training metadata\n","\n"," # load metadata for training subset\n"," prepared_data[\"train_metadata\"] = list()\n"," for training_file in self.protocol.train():\n"," prepared_data[\"train_metadata\"].append({\n"," # path to audio file (str)\n"," \"audio\": training_file[\"audio\"],\n"," # duration of audio file (float)\n"," \"duration\": training_file[\"torchaudio.info\"].num_frames / training_file[\"torchaudio.info\"].sample_rate,\n"," # reference annotation (pyannote.core.Annotation)\n"," \"annotation\": training_file[\"annotation\"],\n"," })\n","\n"," # gather the list of classes\n"," classes = set()\n"," for training_file in prepared_data[\"train_metadata\"]:\n"," classes.update(training_file[\"annotation\"].labels())\n"," prepared_data[\"classes\"] = sorted(classes)\n","\n"," # `has_validation` is True if protocol defines a development set\n"," if not self.has_validation:\n"," return\n"," \n"," def prepare_validation(self, prepared_data : Dict):\n"," # this method is called at the end of Task.prepare_data(), to complete data preparation\n"," # with task validation elements\n"," \n"," # load metadata for validation subset\n"," prepared_data[\"validation\"] = list()\n"," for validation_file in self.protocol.development():\n"," prepared_data[\"validation\"].append({\n"," \"audio\": validation_file[\"audio\"],\n"," \"num_samples\": validation_file[\"torchaudio.info\"].num_frames,\n"," \"annotation\": validation_file[\"annotation\"],\n"," })\n"," \n"," \n"," def setup(self, stage: Optional[Union[str, None]] = None):\n"," # this method assigns prepared data from task.prepare_data() to the task\n"," # and declares the task specifications\n","\n"," super().setup(stage)\n"," \n"," # specify the addressed problem\n"," self.specifications = Specifications(\n"," # it is a multi-label classification problem\n"," problem=Problem.MULTI_LABEL_CLASSIFICATION,\n"," # we expect the model to output one prediction \n"," # for the whole chunk\n"," resolution=Resolution.CHUNK,\n"," # the model will ingest chunks with that duration (in seconds)\n"," duration=self.duration,\n"," # human-readable names of classes\n"," classes=self.prepared_data[\"classes\"])\n"," \n"," def default_metric(self):\n"," # this method defines the default metrics used to evaluate the model during\n"," # a training\n"," num_classes = len(self.specifications.classes)\n"," return MultilabelAUROC(num_classes, average=\"macro\", compute_on_cpu=True)\n","\n"," def train__iter__(self):\n"," # this method generates training samples, one at a time, \"ad infinitum\". each worker \n"," # of the dataloader will run it, independently from other workers. pyannote.audio and\n"," # pytorch-lightning will take care of making batches out of it.\n","\n"," # create worker-specific random number generator (RNG) to avoid this common bug:\n"," # tanelp.github.io/posts/a-bug-that-plagues-thousands-of-open-source-ml-projects/\n"," rng = create_rng_for_worker(self.model)\n","\n"," # load list and number of classes\n"," classes = self.specifications.classes\n"," num_classes = len(classes)\n","\n"," # yield training samples \"ad infinitum\"\n"," while True:\n","\n"," # select training file at random\n"," random_training_file, *_ = rng.choices(self.prepared_data[\"train_metadata\"], k=1)\n","\n"," # select one chunk at random \n"," random_start_time = rng.uniform(0, random_training_file[\"duration\"] - self.duration)\n"," random_chunk = Segment(random_start_time, random_start_time + self.duration)\n","\n"," # load audio excerpt corresponding to random chunk\n"," X = self.model.audio.crop(random_training_file[\"audio\"], \n"," random_chunk, \n"," fixed=self.duration)\n"," \n"," # load labels corresponding to random chunk as {0|1} numpy array\n"," # y[k] = 1 means that kth class is active\n"," y = np.zeros((num_classes,))\n"," active_classes = random_training_file[\"annotation\"].crop(random_chunk).labels()\n"," for active_class in active_classes:\n"," y[classes.index(active_class)] = 1\n"," \n"," # yield training samples as a dict (use 'X' for input and 'y' for target)\n"," yield {'X': X, 'y': y}\n","\n"," def train__len__(self):\n"," # since train__iter__ runs \"ad infinitum\", we need a way to define what an epoch is.\n"," # this is the purpose of this method. it outputs the number of training samples that\n"," # make an epoch.\n","\n"," # we compute this number as the total duration of the training set divided by \n"," # duration of training chunks. we make sure that an epoch is at least one batch long,\n"," # or pytorch-lightning will complain\n"," train_duration = sum(training_file[\"duration\"] for training_file in self.prepared_data[\"train_metadata\"])\n"," return max(self.batch_size, ceil(train_duration / self.duration))\n","\n"," def val__getitem__(self, sample_idx):\n","\n"," # load list and number of classes\n"," classes = self.specifications.classes\n"," num_classes = len(classes)\n","\n","\n"," # find which part of the validation set corresponds to sample_idx\n"," num_samples = np.cumsum([\n"," validation_file[\"num_samples\"] for validation_file in self.prepared_data[\"validation\"]])\n"," file_idx = np.where(num_samples < sample_idx)[0][0]\n"," validation_file = self.prepared_data[\"validation\"][file_idx]\n"," idx = sample_idx - (num_samples[file_idx] - validation_file[\"num_samples\"]) \n"," chunk = SlidingWindow(start=0., duration=self.duration, step=self.duration)[idx]\n","\n"," # load audio excerpt corresponding to current chunk\n"," X = self.model.audio.crop(validation_file[\"audio\"], chunk, fixed=self.duration)\n","\n"," # load labels corresponding to random chunk as {0|1} numpy array\n"," # y[k] = 1 means that kth class is active\n"," y = np.zeros((num_classes,))\n"," active_classes = validation_file[\"annotation\"].crop(chunk).labels()\n"," for active_class in active_classes:\n"," y[classes.index(active_class)] = 1\n","\n"," return {'X': X, 'y': y}\n","\n"," def val__len__(self):\n"," return sum(validation_file[\"num_samples\"] \n"," for validation_file in self.prepared_data[\"validation\"])\n","\n"," # `pyannote.audio.core.task.Task` base class provides a `LightningModule.training_step` and \n"," # `LightningModule.validation_step` methods that rely on self.specifications to guess which \n"," # loss and metrics should be used. you can obviously choose to customize them. \n"," # More details can be found in pytorch-lightning documentation and in \n"," # pyannote.audio.core.task.Task source code. \n","\n"," # def training_step(self, batch, batch_idx: int):\n"," # return loss\n","\n"," # def validation_step(self, batch, batch_idx: int):\n"," # return metric\n","\n"," # pyannote.audio.tasks.segmentation.mixin also provides a convenient mixin\n"," # for \"segmentation\" tasks (ie. with Resolution.FRAME) that already defines\n"," # a bunch of useful methods. You can use it by inheriting your task from the \n"," # pyannote.audio.tasks.segmentation.mixinSegmentationTask"]}],"metadata":{"colab":{"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.10.13"}},"nbformat":4,"nbformat_minor":0} diff --git a/tutorials/applying_a_model.ipynb b/tutorials/applying_a_model.ipynb index e035d0654..68524eb57 100644 --- a/tutorials/applying_a_model.ipynb +++ b/tutorials/applying_a_model.ipynb @@ -1,437 +1 @@ -{ - "cells": [ - { - "cell_type": "code", - "execution_count": 1, - "metadata": {}, - "outputs": [], - "source": [ - "# preparing notebook for visualization purposes\n", - "# (only show outputs between t=0s and t=30s)\n", - "from pyannote.core import notebook, Segment\n", - "notebook.crop = Segment(0, 30)" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "# Applying a pretrained model\n", - "\n", - "In this tutorial, you will learn how to apply `pyannote.audio` models on an audio file, whose manual annotation is depicted below" - ] - }, - { - "cell_type": "code", - "execution_count": 2, - "metadata": {}, - "outputs": [], - "source": [ - "# clone pyannote-audio Github repository and update ROOT_DIR accordingly\n", - "ROOT_DIR = \"/Users/hbredin/Development/pyannote/pyannote-audio\"\n", - "AUDIO_FILE = f\"{ROOT_DIR}/tutorials/assets/sample.wav\"" - ] - }, - { - "cell_type": "code", - "execution_count": 3, - "metadata": {}, - "outputs": [ - { - "data": { - "image/png": "iVBORw0KGgoAAAANSUhEUgAABi8AAADyCAYAAAA1MlYeAAAAOXRFWHRTb2Z0d2FyZQBNYXRwbG90bGliIHZlcnNpb24zLjYuMCwgaHR0cHM6Ly9tYXRwbG90bGliLm9yZy89olMNAAAACXBIWXMAAA9hAAAPYQGoP6dpAAAdwUlEQVR4nO3dfZBV9X0/8PeCgDzsrjwtC/JQqsgQJSrSUTQViBFlTEY0aRFTfxDSGIqmohPNRNOI0UDVStpqS2xSk2qTAE0UMw1GmSCgZWTUhmqTjA1GBAO4SoVdCS7K3t8fjtsQTAxwl3t29/Wa2Zm95977PZ9777nf/dx933NOValUKgUAAAAAAKAgulS6AAAAAAAAgF8nvAAAAAAAAApFeAEAAAAAABSK8AIAAAAAACgU4QUAAAAAAFAowgsAAAAAAKBQhBcAAAAAAEChCC8AAAAAAIBCEV4AAAAAAACFIrwAAAAAAAAKRXgBAAAAAAAUivACAAAAAAAoFOEFAAAAAABQKMILAAAAAACgUIQXAAAAAABAoQgvKmDWrFmZNm1apcugHbCtAAAAAACdkfCiA2lqasq8efMyYsSI9OzZM2eeeWaefPLJ/W5TKpUyf/78DBkyJD179sykSZPyk5/8pEIVUym/z7Zy//3357zzzsuAAQNSVVWVDRs2VKZYAAAAAKDTOarcA+7bsaPcQ/5OXfv3P6LrK6I333wz3bp1y5//+Z/nv//7v3PfffdlyJAh+dd//dd86EMfyk9/+tMce+yxSZLbbrstixYtyje/+c2ccMIJueWWW3LuuefmueeeS3V19RGv/bXde4/o+vr27n5E11c0B7Ot7N69O2eddVb+5E/+JJ/61KcqXDkAAAAA0JlUlUqlUjkH/OWxw8o53Hs69pdbDvo+3/3ud3PTTTdl48aN6dWrV0499dQ8+OCDueKKK7Jz586ceuqp+Yd/+Ie88cYbmTFjRu6888507/72P71LpVJuv/32fPWrX822bdtywgkn5K/+6q/ysY99LEmyb9++XH755Vm1alW2b9+e4cOHZ+7cubnqqqta1z9r1qzs3Lkzy5cvT5I8/fTTmTp1aq666qrccMMN2bVrV6699tosX748b7zxRsaPH5+vfOUrOfnkk5Mk8+fPz/Lly/OXf/mXueWWW7Jp06bs3r071dXVefDBB3PBBRe0ruuUU07Jhz/84dxyyy0plUoZMmRI5s2bl8997nNJkubm5gwaNCi33nprPv3pTx/Sa3A4zrjx4SO6viduOu+gbt9Zt5Vft2nTpowcOTI//vGPc8oppxzsUw4AAAAAcNDKvudF0W3bti0zZszIbbfdlosuuihNTU157LHH8k6G86Mf/ShHH310Hn300WzatCmf+MQnMmDAgHz5y19OknzhC1/I/fffn8WLF2fUqFFZu3Zt/uzP/iwDBw7MxIkT09LSkqFDh2bZsmUZMGBA1q1bl8svvzyDBw/On/7pnx5Qz+rVqzNt2rQsXLgwf/EXf5FSqZQLLrgg/fr1y4oVK1JbW5u7774755xzTv7nf/4n/fr1S5Js3Lgxy5Yty/e+97107do1b731Vvbt25ejjz56v/F79uyZxx9/PEnywgsvZPv27ZkyZUrr9T169MjEiROzbt26ioQXRdaZtxUAAAAAgErqlOHFW2+9lYsvvjgjRoxIkowdO7b1+u7du+eee+5Jr169cuKJJ+ZLX/pSrr322tx8883Zs2dPFi1alFWrVmXChAlJkj/8wz/M448/nrvvvjsTJ05Mt27dctNNN7WON3LkyKxbty7Lli074B/SDz74YC677LLcfffdmTFjRpLk0UcfzbPPPpuGhob06NEjSfI3f/M3Wb58eb773e/m8ssvT5Ls3bs39913XwYOHNg63oQJE3LzzTdnzJgxGTRoUL7zne9k/fr1GTVqVJJk+/btSZJBgwbtV8egQYPy4osvHv6T28F05m0FAAAAAKCSOl14cfLJJ+ecc87J2LFjc95552XKlCn52Mc+lr59+7Ze36tXr9bbT5gwIa+//nq2bNmShoaGvPHGGzn33HP3G3Pv3r059dRTWy9/9atfzde//vW8+OKL2bNnT/bu3XvA4XbWr1+ff//3f8+//du/5aKLLmpd/vTTT+f1119P/984l8eePXvy/PPPt14eMWLEfv+MTpL77rsvs2fPzrHHHpuuXbtm3LhxufTSS/Of//mf+92uqqpqv8ulUumAZdhWAAAAAAAqpezhRf0zG8o9ZFl17do1K1euzLp16/LII4/kzjvvzA033JD169f/zvtVVVWlpaUlSfKDH/yg9aTG73jnm+/Lli3L1VdfnTvuuCMTJkxIdXV1br/99gPGP+6449K/f//cc889ueCCC1rPk9DS0pLBgwdn9erV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", - "text/plain": [ - "" - ] - }, - "execution_count": 3, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "from pyannote.database.util import load_rttm\n", - "REFERENCE = f\"{ROOT_DIR}/tutorials/assets/sample.rttm\"\n", - "reference = load_rttm(REFERENCE)[\"sample\"]\n", - "reference" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "## Loading models from 🤗 hub\n", - "\n", - "A bunch of pretrained models are available on [🤗 Huggingface model hub](https://hf.co/models?other=pyannote-audio-model) and can be listed by looking for the [`pyannote-audio-model`](https://hf.co/models?other=pyannote-audio-model) tag." - ] - }, - { - "cell_type": "code", - "execution_count": 16, - "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": [ - "['pyannote/Segmentation-PyanNet-DIHARD',\n", - " 'pyannote/TestModelForContinuousIntegration',\n", - " 'pyannote/embedding',\n", - " 'pyannote/segmentation',\n", - " 'pyannote/brouhaha']" - ] - }, - "execution_count": 16, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "from huggingface_hub import HfApi\n", - "available_models = [m.modelId for m in HfApi().list_models(filter=\"pyannote-audio-model\")]\n", - "list(filter(lambda p: p.startswith(\"pyannote/\"), available_models))" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "Official [pyannote.audio](https://github.com/pyannote/pyannote-audio) models (i.e. those under the [`pyannote` organization](https://hf.co/pyannote) umbrella) are open-source, but gated. It means that you have to first accept users conditions on their respective Huggingface page to access the pretrained weights and hyper-parameters. Despite this initial process, those models can perfectly be downloaded for later offline use: keep reading this tutorial until the end to learn how to do that.\n", - "\n", - "For instance, to load the speaker segmentation model used in this tutorial, you have to visit [hf.co/pyannote/segmentation](https://hf.co/pyannote/segmentation), accept the terms, and log in using `notebook_login` below:" - ] - }, - { - "cell_type": "code", - "execution_count": 5, - "metadata": {}, - "outputs": [ - { - "data": { - "application/vnd.jupyter.widget-view+json": { - "model_id": "1b7ac613e9e841c8903dc4932e183006", - "version_major": 2, - "version_minor": 0 - }, - "text/plain": [ - "VBox(children=(HTML(value='
, resolution=, duration=5.0, warm_up=(0.0, 0.0), classes=['speaker#1', 'speaker#2', 'speaker#3'], permutation_invariant=True)" - ] - }, - "execution_count": 8, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "specs = model.specifications\n", - "specs" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "... which can be understood like that:\n", - "\n", - "* `duration = 5.0`: the model ingests 5s-long audio chunks\n", - "* `Resolution.FRAME` and `len(classes) == 3`: the model output a sequence of frame-wise 3-dimensoinal scores\n", - "* `Problem.MULTI_LABEL_CLASSIFICATION` for each frame, more than one speaker can be active at once" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "To apply the model on the audio file, we wrap it into an `Inference` instance:" - ] - }, - { - "cell_type": "code", - "execution_count": 9, - "metadata": {}, - "outputs": [ - { - "data": { - "image/png": "iVBORw0KGgoAAAANSUhEUgAABi4AAAGZCAYAAAAetMkNAAAAOXRFWHRTb2Z0d2FyZQBNYXRwbG90bGliIHZlcnNpb24zLjYuMCwgaHR0cHM6Ly9tYXRwbG90bGliLm9yZy89olMNAAAACXBIWXMAAA9hAAAPYQGoP6dpAADTZ0lEQVR4nOzdd2AcZ53/8ffMNvVuybbk3lsc2+m9EtIJgUCAEHo7erkf9TjuDg6OO2roJUDoSSgJ6QnpzUkc995lVavXrTO/P55dFVu2VXa1K/nzgs3Mzs7OPJLWszPzfb7P13Jd10VERERERERERERERCQD2OlugIiIiIiIiIiIiIiISIICFyIiIiIiIiIiIiIikjEUuBARERERERERERERkYyhwIWIiIiIiIiIiIiIiGQMBS5ERERERERERERERCRjKHAhIiIiIiIiIiIiIiIZQ4ELERERERERERERERHJGN7RvtFxHGpra8nPz8eyrGS2SUREREREREREREREJhjXdens7GT69OnY9ujzJkYduKitrWXGjBmj3rGIiIiIiIiIiIiIiEw+1dXVVFVVjfr9ow5c5Ofn9zWgoKBg1A0QEREREREREREREZGJr6OjgxkzZvTFD0Zr1IGLxPBQBQUFClyIiIiIiIiIiIiIiAjAmMtLqDi3iIiIiIiIiIiIiIhkDAUuREREREREREREREQkYyhwISIiIiIiIiIiIiIiGUOBCxERERERERERERERyRgKXIiIiIiIiIiIiIiISMZQ4EJERERERERERERERDKGAhciIiIiIiIiIiIiIpIxFLgQEREREREREREREZGMocCFiIiIiIiIiIiIiIhkDAUuREREREREREREREQkY3jT3QAREZHxFozECEUdYo5L1IlPY278udu3nmX1v8fqW2YNsWzgetZRy47c3mi2YR0xYzFgG9YR6wzYx+BlR7w3PrEtyPZ58HpOrv4MruviuBBzXLy2hW0P8UcTkZFzXXCi4MTAdcwDt3/edeMP5zivD5jniHUHvo7bvz2z8/73JNqCO0QjE474d3/Uwfs4B/NjbmOM+xjqC2TM28iUfRz5lgHreLMgf9rw3ncCkZhDTzhGbzhGOOoQcRwiMYdI1MVxXWzLwrLMrmzLij+ILxvwHLOebZtvzv71rAHvja9nc/T7jlwvCT+bSCZr6grhOOb8ysU1h2fMOZc74LB81GskDuNm+aD3D5gf+P6RsoY6nh9r3RT+Ux3JtlPV5lS1YaAj/0buyP9kx952krY1ms/RkNtJ4s+WTJYFXtvGE/9+8to2tk3f1GNZZPk85AZ0a1gylz6dIiKSeuFuiIUhFgUnYpbZXvPw5YA3kNorBOCZXU18+9Gd7GropCMYTem+Jiqfx5y8Zvs8ZPs9lOcHqCrO4fTZJbx+dSVZPo9ZMRaBnQ9BVz2EeyDSA6FOCHUAVv/f1ImadWMhM42G4p+D+CMan7oxsGywPPGpHb97FJ+3PeY12wtev7m55fEd/QPkVUDRTLOfcBeEugZPYxEc28ef2hfzbwdOIRIb/Ha/1ybgtYcMAJn5+PRYrw9aPnDLR2/DHnCzLHFTy2MffSMsEnMIRR1C0RjBiDPohltiPfPcGrDN+I03++h9HHf9YbQp8V6/16KqOIfrVk5neWXhCT5ZMunVb4ZfXB4PVkTjAQWRUSiaBW/5E5QvGdbqwUiMP79czVM7mzjQ3M3hrhA98WBFpjrymOqxBzwGPLctC6/HLLNtywTY48v8HrvvO8vvtYk5EIrG4t8XDqGI+R0kvj+ijumckbihHHPNfKI9Fhbx//cHXIgHaGDAa+Y7we+xyQt4ycvysrAin5tOm8EZc0rS90uVjPHa7zxNU1co3c0QkRHI9XuoKMxiaoF5VBRmUZEfYGphFhUFWUwtzGJKXuCk6+QmmcFy3dHFBjs6OigsLKS9vZ2CgoJkt0tERCa6ug3w0BegYTP0th5/XdsL/lzw50MgD/x5/dPEfE4ZlMyBkrnmkVM6+O6w68LhHXBorZlWLIMVbwSPj4PNPVz6rSeIxIb+yvN5zE0Cr20P6hGZ+Ioc9C6Xo5YNtV5fr7ABS90h3stx1hu47sCva3eI9VJtZkkO3795FSsr/PD7m2D/0+O38xT4VPgD3O1ckO5mTHge2+L37zmTM+eWprspkk4NW+BH54zyzdbRwUrLHrDcjt8xPXK5dfTzxN3Vvu1aA6bxZYMccRA96qA6xEH2ROsc9ZYR7mPIA/tYt5GOfZxg+0NtI9xppsVz4EMvgC9riHb2i8Qc3vWrl3h6V9Mx1/HYFgGvjde28Hvtvu95F3DiWXemR7c74Hmix3d/r/Ghlstgn7tyMe+/cF66myFpdubXHuVwZ6gv6DVUYGxQRhIcFRgbGDSz4iv0ZUQxeJ3hGO4tr+H+sx7u+fdwe/MPf3vDXG/Yx6fkti+xxWN35IGjv4dHZiz93May57H2rxtt1spY9t3/fWVGFIjFXGLxeeeIUQaG244peQHml+exorKQ162qZMk03QuWY0tW3ECBCxERSb7DO+Bnl5he7key48l+zhizHvz5kFsK2cXgy4XmXdDVMHid5W+AG3/Or57bz7/fu5WZJTn89O1rmF6UTZbXMymHBxoU4BhmkCXmuIQiDr2RGL2RGD3hKD3hGA0dQXY3dvHHtdXUdwTxeSzuPuUlTtn2LRNQmnuRCTj5csw0q8hsMNID0aD5W3v8JvvC4wNPfOoNmOWJh+05YhiYAcPBODGTkeHE+jM4okGTxTHwIsB1oKMG2mvMzS5/Pk0RH+vqo2xpitEaCxDBy5X2Wi7wbKI3eyrd734GT3Yhtm0yGxJDiB35+xv4WxwqqHT08mMEoQYEqRJDHzhH3CxzBixz3f4skIDXQ8Br47GtvvXNOgPe49D3viO3G3OOvY9jbs8l3jv36NdDkRj3bKhl3cE2qoqzeeBj55OfNUQWjJwcomHorO3PpLO9/ZlSA4MRRwUoJtfxV8aoswF+fC50H4a33wNzLzzu6j9/ei//dd82snw2H7lkASsqC5lWmEVOwEuu30OO34vfm7reoUMFOAY9P1YgJD4sTiyRBRE/Rsccc1PJZEZA1HHir3HE686AbArz8MYDNInvioCvf97vtfF5rL6MOk/83Cdx+jPSoXxc1yUUdegORWnrjfDQlnr+sq4GgB++dTVXrZiWst+5iIgkj+O49ETMNV9De5CGziD17SEaOoLUx583tAdp7AwdFeiwLPjOm07l+lMr09R6yXTJihtoqCgREUm+Bz9nghYzzoKr/9cM/eDLNjezBt6oikUh0n3EkD6d/c8HDvPT1QAt+8yjo8asF+6E1v392/NmQeVpUFgJG/8Mm++CZa/jmd1TAbj5jJksnjq5g+1DDW10xBpHLfF5IMvnoZChbzy/67w5/OudG3l0yyHKt/7KbOLKb8CqtyWlzcnW3hPh03dt4JGt/YGsLJ9NaW6AmrzLOa/1VrJ768n+0VI4/T1w8echOz+NLZ6YblxTxZXffZpDrb385z+28j9vWJnuJkm6eP1QPDvdrZCJLr8CZp4N2+4xWZvHCVw4jstvnj8AwBevXsrbzpo1Xq3s01fnYow9iCe6K5ZNpSDLx6+e288n/rSeqYVZrJ5ZnO5miYjICdi2ZYb9m5LHvCl5x1zPcVyaukPUtQXZUd/JvRtreXpXE1/822bOmltKRcHxMyRFxkKBCxERSa76zbDnMbB9cMOPzLBOx+LxgqcQskY4Rn4kCO3V0NNihqGKdEPeVKg6zfTmB8idAs/fhrP5rzy/5yYAzl9QNsof6uRWkOXj+29ZxRu++AxTrRacrCLsFW9Md7OGFIzEeNsvXmRTTTte2+K6U6dz69mzWVFZ2J9ds+Un8M//gubd8MIPoXotvPth00Nchi0/y8e3bjqVN/30ee7ZUMtHL11AVXFOupslIhPZtFNM4KJ+43FXe35vMwdbeijM9nHj6qpxapwcy5euWUp1Sw+ba9vxawx0EZFJxbYtyvOzKM/PYuWMIl6/upLX/+g5Nh5q549rq/nYZQvS3USZxBS4EBGR5ErUPph74fGDFmPhy4KyE5wgLb0enr8Na/cjhMPXA14WVBy7J4kcn89jMy0QBiCSO41AIkCUYb5y71Y21bRTkuvnN+86Y+jC0ctugKWvg92PwZ23Qs3LsO7XcNq7xr29E90Zc0r4j+uXc/bcUgUtRGTspsYzt+qOH7h4eX8rAJcsLifbr6Bzunlsi+/dvIqOYIRphdnpbo6IiKSQ12PzrnPn8PE/reeuddV85JL5k274Zckc6g4hIiLJdeBZM511bnrbUXka5JZjhTo4zd4BoF6AY1SRFQEg5MlNc0uG9tL+Fv6w9iAAt928auigRYJlwYLL4KLPmufr/zAOLZycbjlrFvPLFRQUkSSYdoqZNu+CSO8xV9tU0wbAKVUjzNiUlMkNeBW0EBE5SVyxbCp5AS/VLb28Wt2a7ubIJKY7OCIikjyuCweeM/PpDlzYtikeDZxlb8XnsQbVf5CRq/CbwEXQysye9YnioDeuruKc+cMcFiz+GaFp55HVuEVEZLzlVYA/D1wH2g8dc7WNh9oBWHG8ALWIiIikRLbfw8WLywF4dFtjmlsjk5kCFyIikjz1m6CnGXw5MH1VulsDs03w5Cx7Gz5lW4xZqc8MFdVjZWYBtr2HuwA4d37p8N9UMs9Mg23msysiIuljWVBQaeY7aoZcpaEjSGNnCNuCpdMLxrFxIiIiknDZEhO4+KcCF5JCuosjIiLJs+cxM51zAXj96W0LwOzzATjV2k2eHUlzYya+El8IgE43M4eC2N/cDcCcshEMZeXPgcKZZr5pVwpaJSIiI1IYD1y0Dx242HvYHOtnleaS41fJRhERkXS4cOEUPLbFjoZOqlt60t0cmaQUuBARkeTZHQ9czLs0ve1IKJlLzF9AwIoyy9OU7tZMeEUeE7jocDIv46I7FKWhw7RvRIELgLL5ZtqswIWISNoVTDfTY2RcNHWZY/2U/MB4tUhERESOUJTjZ82sYgAe29aQ5tbIZKXAhYiIJEfX4f76FvMzJHBhWTheU48h146muTETX74VBKA1mnk3ixLZFsU5PopyRpjtU7rATJt2JrlVIiIyYgVVZnqMGheHO+OBi7zM+y4SERE5mSSGi3psu4aLktRQ4EJERJJj813gxqByDZTOS3dr+jgecxM7x6PAxVjlWb0AtGRi4KLJpCfPHmm2BUDJXDNtO5jEFomIyKgUHr/GhTIuREREMsMliysAeHFvC8FILM2tkclIgQsREUmODX8w05U3p7cdR4jZ5sZGtjIuxizHNYGLw2FfmltytEOtJnAxsyRn5G8umGamHbVJbJGIiIxKwfFrXCQCF2V5GVBLS0RE5CQ2b0ouZXl+wjGHzTXt6W6OTEIKXIiIyNg1bIW6DWD7YNnr092aQRzb3GTPttUDZKxy4xkXB7s99IYz6/fZ0hMGoDR3FD1wEzfJOuqS2CIRERmVwvhQUcfIuOgbKkoZFyIiImllWVZfnYuXD7SmuTUyGSlwISIiY5fItlh4BeSWprctR0hkXORYkTS3ZOLzx0xWQ4eTxda6jjS3ZrC2bvP3Lc4ZRTZIfjzjoqseHCeJrRIRkRFLBJNDHRA8+rumqcsEqstU40JERCTtEoGLVxS4kBRQ4EJERMYm1Anrfm3mT31retsyhGg84yJLQ0WNmRXqBKDbzWLjobb0NuYIrfGMi6LcUQwdklcBlg1OFLoPJ7llIiIyIoE8yCo080MM4acaFyIiIpljzawSANYdaMV13TS3RiYbBS5ERGT09jwOt18JwXYoXQALX5vuFh2lr8aFpcDFmIW6AOgim02HMmsM07aeMWRceLyQW27mO1XnQkQk7QoSw0UdGrTYdd0BNS4UuBAREUm35ZUF+L02zd1h9jf3pLs5MskocCEiIqN38AWo32R6q1/272Bn3tdK1DI3sgPKuBi7cH/gYldjV5obM1gi46I4Z5TFWlWgW0QkcxQOXaC7vTdCJGZ6c5YOpzh3pNd0sogEk91CERERAQJeD6dUmkzJl/e3pLk1Mtlk3h0mERGZONbcCud8BD7yCiy5Jt2tGVLUMjc2slGNizFxnL7ARbebRV17b5obNFjfUFGjybiAAQW6FbgQEUm7gulmekSB7rp2E4AoyfUT8HpOvJ273g13vA5uOx1a9ye3jSIiIgKozoWkjgIXIiIyegXT4TX/BSVz092SY4rEAxcBFecem3B/hkUX2TR1hQlGYmlsUD/XdfuGiioZTY0LgNL5ZvrE16Fpd5JaJiIio5IYKuqIjIvaNhM0n16UdeJt7HoUdtwX385B+NF5sOsRcF3oaoSYzgtERESS4Yw5ps7FUzsPq86FJJUCFyIiMqlFEkNFoaGixiTYBoDr8WP7zA2j+vbMGHqjMxQl6pgT5FEPFXXOR2HqKdDTBH95L8T0eRERSZvEUFFH1LiojX/vTCvMPvE2tt9rprPPB9sL4U743Rvg67PgfxfA/y6E7fcls9UiIiInpXPnl5Ht81DbHmRLbUe6myOTiAIXIiIyqSnjIkk66gCwCqYzrcjcMKrNkOGi2rrN3zbLZ5PlG8bQIUPJLYWb/wiBQqhdB/ueSF4DRURkZIpmmukRGXB1iYyLwmFkXDRsMdPT3gnXfg/mXGgCGKF2s7y3Be5+LxzemaxWi4iInJSyfB7OX1AGwMNb6tPcGplMFLgQEZFJLYIXAL9qXIxNYpzxgkoqE4GLtszIuBhzYe6EwkpY+BozX/PqGFslIiKjNu1UsDwm46Ktum9x/1BRJ8i4cBxo2GrmK5bDqrfCrfeYmlyXfBHe/HuTiRHphoe/kKIfQkRE5ORx1YppANz5yiGiMSfNrZHJQoELERGZ1MLEMy4Ip7klE1yiaHXBdKbFe7omer6mW39h7jEGLsDcLAOoWz/2bYmIyOgE8mDaKWa++sW+xX1DRZ0ocNG23wQlPAEomde/vHg2XPAZWHw1XPtdExzZ9TAcfPFYWxIREZFheO3yqZTk+qlrD/LY9sZ0N0cmCQUuRERkUgvHa1z4VONibAYELqZn2lBR8cLcxTm+sW9s+qlmWrdh7NsSEZHRm3m2mR54tm9RXfswh4pKDBM1ZRF4vEOvUzoPTr3ZzL/447G0VERE5KSX5fNw02kzAHhy5+E0t0YmCwUuRERkUgu55ma231XGxZgMGCpqeuEkHSoKYOoKM22vhu7msW9PRERGZ+5FZrr5bgh18ueXq6luMYGLmSU5x3/v4e1mWr7k+Oud8X4z3XYPdDaMvq0iIiLCO86ZzV0fOJuvvm55upsik4QCFyIiMqmF4zUufKpxMTZDZVxkzFBR5m9blIyMi6zC/mFF6lTnQkQkbeZfDqULINgO637Dj57YA8D7LphLecEJMi4SRb3LFhx/vWmnQOUacKImeCEiIiKjNrUwi9Nml2BZVrqbIpOEAhciIjKpBeMZFz5lXIzNwBoXReaGUW1bL67rprFRRls846IkNwkZF9A/XFTt+uRsT0RERs624awPmPlNd9LUFQLgTafPOPF7m+OBi9ITBC4All5vptvvG0UjRURERCRVFLgQEZFJLdQXuFDGxag5MeisM/P50/uGiuoOx+gIpr92SEt3Eotzw4AC3apzISKSVkuuB8uG2lcpDJnvocLsE2TXuS407zLzJ8q4AFh8jZnufxp6WsbQWBERERFJJgUuRERkUgtibnB4FbgYva5GcGNgeSCvnGy/p68Qdl0GFOhOanFugGkrzbRufXK2JyIio5M3BWadC8BNnseBYQQuupvM8FJYUDL3xPsonQdTTzHDRa37zRgbLCIiIiLJosCFiIhMaiHXA4DPDaW5JRNYYpio/Glgm99nJtW5SGpxbogHLixoO2iCNiIikj5nvBeA93ruZ7a/HZ/nBJewTTvNtHAG+LKHt48z40W61/4MYunPJBQRERERBS5ERGSS63VMz0yPo4yLUeuoMdOC6X2LpsWHi6ppC6ajRYO0JbM4N0B2EVQsM/P7n0nONkVEZHSWXEdP6TKyrTCX+LedeP1Da8106orh72P5GyCnFDoOwQ7VuhARERHJBApciIjIpNYbr3HhdVSce9SGCFxUFZvAxaGWnnS0aJCkZ1wAzD7PTA88m7xtiojIyFkWXXlzAKjwDeM758BzZjr73OHvw5cFa95p5l/48QgbKCIiIiKpoMCFiIhMar2OFwDbVeBi1PoCF5V9ixZU5AGwvb4zHS3qE4rG6AnHgBQFLpRxISKSdt2eAgCmeLqPv6ITg4MvmPlZIwhcAJz+brC9cPA5qNswilaKiIiISDIpcCEiIpNaInDhUcbF6CVqXAzIuFg81dxE2l7fkY4W9UkME2VbkJ/lTd6GEze8Dm+HrsPJ266IiIxYh5UPQKl9gsDFwRcg1AGBgpENFQXmO27p9Wb+xZ+MopUiIiIikkwKXIiIyKTW65hi0gpcjMEQgYtFU81NpIaOEC3d6fvdJoaJKsrxY9tW8jacUwLl8ToXGi5KRCSt2jHfOUV0HX/Fdb8x06XXg+0Z+Y7O/KCZbrpTQWsRERGRNFPgQkREJrXueHFuOxZKc0smsLaDZlpY1bcoL+BlVmkOkN6si4YO83edkhdI/sY1XJSISEZocc3whAUc5/umtxW2/s3Mr3nH6HY043SoXAOxMLzyq9FtQ0RERESSQoELERGZ1BIZF3YsBK6b5tZMQL1t/TUupiwa9NLSaWa4qHUHWse5Uf3q2noBmF6UlfyNJwIXe59I/rZFRGTYmqImUJ7nHFFXqbMenvg69LTAxj9DNGiy5SrXjH5nZ37ATNf92tTMEBEREZG0UOBCREQmte54jQsLF5xomlszATVuNdPCGZBVOOil8xaUAfDEjvQNp1HbF7jITv7G514Ilgead0HLvuRvX0REhqUxmgtATrR98At33ABP/Dc88m/wyq/NsjW3gjWGoQOXXGu+79qrFbgWERERSSMFLkREZFLrjPr6n4Q6j72iDK1hi5mWLz3qpYsWlQOw7mAr7fEi2eOttj0IpChwkVUIM88287seTv72RUTkhLpDUV6sNxmTgeiAoaIOPNcfXH/1DmjcAt4sOOWmse3Qlw0r4tvY8MexbUtERERERk2BCxERmTQOd4bYXNPOzoZOfvnMPh7YVEdn1KbLjQ8j1Ju+IY0mrETgomLZUS9VFmWzsCIPx4V/bKod54YZtakcKgpg4WvMVIELEZFx5zguX39gO/t6TB0jb7QHovGaVbseOfoNS6+H7OKx73jFG810xwMQCY59eyIiIiIyYt50N0BERCQZttZ28LofPks46hz1WlsgjzyCZgzs0nlpaN0EVr3WTKcuH/LlN58+k//4x1Zuf3Y/bzljJtZYhucYhUTgYlphCjIuABZcYYYg2fc0hLvBn5ua/YiIyFHuWneIO144gEU2LjYWjvkuL5gGTTuPWNuC09+bnB1XnQ4FlabG057HYPHVydmuiIiIiAybMi5ERGTCc12XL/xt06CgxZyyXLy2uYnuZpeYhb0t6WjexNW8xwy9YXth7sVDrvLG06rIC3jZ3djF83ubx7V5ruv2DRVVmYqhosAUJC+aCbEQ7HsqNfsQEZEhvbjXfG+/+7x5WDnxTIrEd3nTLjN9y53w3sfhwy/BjNOTs2PbNrUuwGRdiIiIiMi4U8aFiIhMeOur23j1YBs5fg+Pf/oi8rO85Pi9bDrUzqaadip3VMLenaaXpgzftnvMdPb5kFMy5Cr5WT6uXTmdP6w9yJ0vH+KceWXj1ryGjhDhqINtQUVBioaKsixY8Bp46efm5tWiK1OzHxEROcquRlOb6rTZxXCwAnqaof0QHHoJmnaYlcqXQNGM5O984RXw4o/NkFSuO7aC3yIiIiIyYsq4EBGRCe/BzfUAXLqkgoqCLHL8Ji6/oqqQt5w5EztHGRcj5rr9RUmXve64q950WhUA92+q41BrT4ob1u+VA6ZmyZJpBfi9KTylSQwRsuN+cGKp24+IiPRxHJfdjV0AzC/P76+19OJP4N6P9a9YUJmaBsw6F3y50FUPdRtSsw8REREROSYFLkREZEJzXZcH4oGLK5dPHXqlxFBRyrg4sUgQHvky/PEtcHg7+HJg2euP+5ZTZxRxxpwSQlGHL/99C67rjktTX9pv/p6nzx46GyRpZp8PWYXQfRiqX0ztvkREBICatl56wjF8HotZpTkw9RTzwp7H+lfKKTXDOqWCNwBzzjfzB55NzT5ERERE5JgUuBARkQltW10nB1t6CHhtLlw4ZeiVlHExfM/fBs9+x2QXACy/EbIKjvsWy7L46uuW4/NYPLa9kYe21Ke+ncDafebvedrs4tTuyOODRVeZ+Q1/SO2+REQEoC/bYm5ZHj6PDdNOOXqla7+X2kbMONNMD76Q2v2IiIiIyFEUuBARkQntwc11AFy4cAq5gWOUbsopNdOe8S0ePeEEO+DZ7/Y/P//TcOX/DOutCyryef8F8wD47we2E3NSm3VR3x5kW30HAGekOuMCYNUtZrrpbgi2p35/IiInuRfjweml0+PB86lHBC4+tQOWXJPaRsw8y0yrXzRDKIqIiIjIuFHgQkREJrS+YaJWHGOYKNBQUcO162EIdUDJPPi3Vrj0S+DPGfbbP3TxPIpyfBxo7uHhFGdd/GNjLa4Lp80qpjxVhbkHmnUOlC2CSDesuyP1+xMROUnVtfdyqLWHx7c3AnDRong2ZU4JrL4VimfD+Z+C/ON87yfL9FVg+6CrAZr3pH5/IiIiItJHgQsREZmwdjd2sauxC5/H4pLFFcdeMSc+lFBv6/g0bKLa8YCZLrl2VGOG5/i93HLWLAC+/ehOojEnma3rE3Nc/vxyNQDXnzo9Jfs4imXB2R8y88//wNQCERGRpApFY1zzvWc47xuPs6OhE9ti8DCQ130PPrYBLv238WmQL7u/zsXGP47PPkVEREQEUOBCREQmsEQthXPmlVGY7Tv2iomMi+6mcWjVBBUNw65HzPziq0e9mXefN4eiHB87G7r41XP7R/Te7fUdfOrPG3jlwLEzY8JRh289soOdDV0UZHm5duU4BS4AVt4M+dOgsxYe+tz47VdE5CTQ2Bnkx0/spbk73LfsgoVTKMrxp7FVwKq3men630Msmt62iIiIiJxEFLgQEZEJyXFc7l53CIDXLj/BcBElc8HyQFc9tOwbh9ZNQPufglA75FVA5ZpRb6Yox89nrlgEwDcf2sHW2o5hve/BzfW8/ofPcfe6Q3zwt+voDEaOWueeDbWs/s9H+MHjZriOz1yxaHxvaHkDcN1tgAUv/xI2qPetiEgyuK7LO29/iW8/urNv2fdvXsWP3zb676OkWXyNqZXVUQNb/5bu1oiIiIicNBS4EBGRCenxHY3sPdxNfmAYve6zi2Dm2WZ+18Mpb9uEtPXvZrr4GrA9Y9rUzafP5PwFZYSiDm/5+Qv89Kk9PLu7icgQQ0f1hKN88W+b+MBvX6EnHMO2oLEzxHcf3TVovbtfOcTH//gqXaEoJbl+/v3apbwtPizVuFpwGVz4/8z8vR+Hhi3j3wYRkUnmqV1NbBkQ6P7P65dx7crpZPnG9n2UFN4AnPkBM//Md1SkW0RERGSceNPdABERkZHqCUf56n3bALj5zJnkBYbxdbbwNXDgGRO4OPP9KW7hBBOLwrZ/mPml1415c7ZtcdvNq7n19rWsr27ja/dvB2BqQRa3njObJdPymZIfoLEjxH/8Yyv7mroBM8zUufNLedevXub25/YzZ0ouAa+HXz6zj6115obWm06bwddevwKPbY25naN24b/CobWw559w5zvh/U+BbxwKhIuITFK/f/FA37zXtrhgYF2LTHD6e0zQomET7H7MBLFFREREJKUUuBARkQnna/dvY29TNxUFAT500bzhvWl2vLhm7aumt6SVxhvfmebAs9DbYmqBzDovKZsszPHxx/edxXce3cWL+5o50NxDfUeQbzy4/ah1pxVm8c03rOS8BWUAXL1iGvdtquMLf93ct47PY3HLWbP54tVLsNMZtACTkfL6n8MPz4KmHfDMt+Fi1bwQERmNcNThmV2mBtXP3n4alUXZzCrNTXOrjpBTAqe9E56/zRzzFbgQERERSTkFLkREZEJ5fHsjv33hIAD/98ZTh1/jYMpisGzoaYauRsivSGErJ5i+YaKuBk/yTg2yfB4+e+ViAELRGH97tYY/vVRNTzhGY2eIYCTGG9ZU8anXLBpUXP1/37iSqpJsHtvWSEGWl/Pml/Gu8+akv0DrQLmlcOU34K53wgs/hLM/BFmF6W6ViMiE88qBVrrDMcry/Fy6uDz9weljOetD8OJPTPZm9VqYcUa6WyQiIiIyqSlwISIiE0ZzV4jP3LURgHeeO7uvh/6w+HNMke7m3dCwWYGLhFAnbLrLzC97Xcp2E/B6eNPpM3nT6TP7lrmuizVE5ku238PnrlzC565ckrL2JMXS18GUb8Dh7fD8D+Diz6e7RSIiE87DW+sBOH/BlMwNWgAUVsLKN8Grv4XHvwa3/FXZmyIiIiIppOLcIiIyIbiuy+f+sommrhALyvP4f69dPPKNlC8108atyW3cRPbqbyHUDqXzYe4l47rroYIWE4ptwwWfMfNPfRP2PZ3e9oiITDA94Sh3v3IIgOtWTk9za4bh/E+BJwB7H+8P+ouIiIhISihwISIiE8KfX67m4a0N+DwW33nzqWT5PCPfSMUyM61dn9S2TVi9beaGO8DZ/2JuxMvILL8RVt4MrgN3vQvaa9LdIhGRCeMXT++jIxhlZkkOF2ZaQe6hlMw1wQuAez8G9ZvS2x4RERGRSUx3KEREZNQ6ghG+9LfNNHYGU7qfA83dfOVekyXxycsXsWz6KGsJzLnQTLf/A7qbktS6CeyJr5uaH2WLYNUt6W7NxGRZcPW3oHwZdDfCHTfosyUiMgx/fqmabz+6E4CPXrogs4eJGuj8T8GcCyDSDb+5Huo3p7tFIiIiIpOSAhciIjJq33lkF3e8cIDzvvE4Z3z1UZZ/+SHO/u/HeMOPnqO6pScp+4jGHD7xp/X0hGOcMaeE910wd/Qbm3kWTDsVokF45ttJad+E1bAF1v7UzF/5dfD4jr++HJs/B97yRyiogqYd8JvXQcvedLdKZNwc7gzx5b9v5usPbE93U2QCcF2X/35gG/9690YcF24+YyY3rq5Md7OGz+OFm34D01eZ4P+vr1XmhYiIiEgKKHAhIiKjdt2p01lZVUg46tDYGaIrFKWuPcjLB1p5809foDMYGfM+vvPoLtYdbCM/4OVbN63EM5YemZYFF33OzD9/G2y7d8ztm5DC3XD3e8CNweJrYN741raYlIpmwtv/BrlToGET/OAsePKb4LrpbplIym2t6+DXzx/gl8/so6atN93NkQz386f38ZMnTXD3Y5cu4Gs3LJ94NY+yi+GWv8H01dDbYoIXdRvT3SoRERGRScVy3dFdUXd0dFBYWEh7ezsFBQXJbpeIiEwQjuOyrb6DnnCMnnCM/U3d/PCJ3TR0hAB445oqPn/VEopz/biuS3tvBNu2KMjyEYrG2F7XyYv7mtnX1M2+pm4ONPcQiTmcPrsEgAc21wPwrZtW8vrVVclp9P2fMdkGngC84Zew5JrkbHciCHbAn94K+54yN9k/8CzkV6S7VZNH20H4+4dh35Pm+Wnvgqv+T/VDZFJzXZc3//QFXtzXwjWnTOP7N6+aeDeiZVzsbOjkqu8+TdRx+dI1S3n3eXPS3aSxCbbDHa+HmpfBnw+XfBFOfQtk6fpYRERETl7JihsocCEiIkn33J4m3v6LtUQd8xWTF/BSVZxNTWsvnaEoADl+Dz3h2LC296+vXcSHLpqfvAbGonDnrabWBcDyN8Dl/wGFE2ioitFo2Qd/eDMc3g7+PLjlrzDjjHS3avJxXXj5l3DfpwAXVrwRXvcjDcclk9qrB1u58UfPxYf+mcHnrlpCQZY+89IvGInxpp88z4ZD7Vy2pIKfvX3N5AhwBdvhj2+F/U+b575cOOuDcMFnwJeV3raJiIiIpIECFyIiktEaO4Nsrmnn6w9sZ2dD1zHXy/V7OHd+GYun5jO7LJfZZbl0h6Lct7GO3ICXG1ZVsrxylMW4jycWhUe+BC/8CHDBmwVnfQjOfD/kT03+/tIpFoW1P4HHvwbhLsibCjf/ASpXp7tlk9vmu+Ev7wMnCrPPN2Oi55Sku1UiKfO7Fw/whb+aQsV5AS9nzS3htNklnFJVyIrKQvIVyDhpNXYE+dgf1/P83mYKs33c/7HzqSzKTnezkseJmYD12p9Ckyk4zrRT4fofwNTlaW2aiIjIuGreA6Xz0t0KSTMFLkQyQEcwwiNbGni1upWdDV2Eog4+28LnsckNeFk1s4gz55SwoqqQgNeT7uaKpEUk5rChuo2uUJSq4myqinNwXJeGjhAFWV5Kcv3p7XFZux4e/BwcfK5/2ZQlMO9imHsRzDoHAvnpat3YHXwR7vskNJibicw4C954OxRMT2+7Tha7HoE732ECRkUz4bVfhwVXmOKuIpPQM7ua+Mq9W9jVODhgbVkwtyyXFZWFFOX4yfJ5KM31s2hqPgsq8phWOIluYgtgMizaeiK8sLeZ//zHVpq7w2T7PNz+ztM5a25pupuXGq5r6mfd+zFT+wJM4Hr1rbDkWmVgiIjI5Lb2Z+ba+trvwKq3pbs1kkYKXEjadIeibK/vZH9TN229EaYWZOG4Loc7QzR2hghFY8wsyWF2WS4rq4ooyfWnu8lJ19Id5idP7uF3Lx6kKz7szfEEvHY8iFHKmXNKWDWzmGy/AhkiGcN1YccD8PT/Qc0rwICvRtsLVWfAgstgwWugfNnEqFfQ0wKPfhnW/cY8zy6Gy74Cq26ZGO2fTBq3mSG6Wveb5wWVcP4nzd/CG0hr00RSwXFcNta089K+Fl6tbmVDdfsJi3YX5fg4d14Z166czkWLppDl03nSRNXYGeSXz+znty8cGHSevHhqPre9ZTXzy/PS2Lpx0lZtsjq3/h1cxyzLKTVDSJ35QQicBL8DOTntfhRsH8y9MN0tEZFkiYZNMD7SC8E2OPiCqZfYfRgWXwNTV4BlQ/1GePQr4Mbg0i+b6x05aSlwIePCcVw6Q1EONvdw78Zattd3sv5gKx3BE9+sB/B5LN5+9mw+d+VivJ6Jf6PMdV3u31TPl+/ZTFNXGIB5U3K5dEkFS6blkx/wEXUcIjETyHlpfwtr97XQ3B0etB2vbTG/PI8VlYWsqCpkeWUhS6YWTLhgxu7GTvICPqYWqveYTCI9Laaw8p7HYe8T0HZg8OvZxSaQMeMMmHkWTF8N/py0NHVIjgPrfweP/Ft/b89VbzNBi9yy9LbtZBZsh6e/ZQJJib9LoAAWXG4yMAqmmedZBVA4I7PrYbTXwN7HTbAvFoYrvwElc9PdKslwTV0hNtW0s62ug+5QlGDE4VBrD/uautnd2IUz4IokP8vLkqkFzJ2Sax5leayaWURpngJ96eDGOyjlBLzkBbwEIzE6eiOUF2SZa4VglLbeMHsPd/Pnl6t5ZGtDX40rgMqibG5cU8WHLpp38gWk2g/Bq78zx/6OQ2ZZThnMuwSmnWJu9kw9ZXIMIxgNQfVamHN+ulsi6RLuhttOh44aWHaDqR9XNDPdrRKR4XBdE4zoqDHn9+010LIHGrZC8y4z9O1wrbzZ1PebDHWsZNQyJnBR09jM9CmT4ERLBukJR/nuo7v408vVtPVEjnq9NNfPvCl5lBcEqG7tJeCxmVIQYEpeAL/X5mBzD7sPd7E7PkzAyqpCPn/VEs6YUzIhi/Ad7gyxobqN37xwgKd2HgZgYUUen71yMRcvKj/uz+S6LnsOd7N2Xwsv7mvmxb0t1HcEj1rPtmDulDwqi7KZWpBFRUGA8oIspuQHKMszv9vygkBaL/hijsvBlh6e2d3E/RvreH5vM+8+bw5fumZp2tokknIt+2DPY2bIn71PQvSIXsO219x0qFhmbt6WzIXiWSbAkVVobkbb4/DvtqvR9Oxc9xvT2wWgfClc/S2YdXbq9y/DEwmav9Gz3zEXBkPJmwqnv9sEx8oWmUyNxi0mc8ObZT5vYMZRb90HsYjp0RuLmM+n5QFfNnj8JqPDn2cKzxfOgMIq88ifPrzhqhwHOmvh0Mtw4FkTzEuM357gzYaz/wXO+4R6EcuotPdG2N3YxT3ra3hkawO17UefJ1kWrKwyQ3Dm+L0srMhjRkkOS6cVYNsT79wy07X3RtjX1E1Nay9ff3Ab1S3muy8/y0s46hCKOuT6PfREYgx1Nbl6ZhEfvGg+ly4u198HTK2pLX+Fx79qjttHKqgytTByp0Dp/HhQ45SjOxzEIua8pKve9Gr3+E2gu7AqfcGPYDs88x145XbobYWPbYDi2elpi6RXsAP++Z/w0s/NeYllw8LXwqKroOp089nWUJkimaetGv7yXjj4/HFWssz1hS/HfEfNucBc526601yHevzmOmDFTeY6ZjyufyWjZUzgYu6n7mTRjAqmF2WT5bMJeD2Dplk+DwHv4Gni9Wy/h7yAl/ws03snN+Al4LUn5I3tySAYifHy/lae3NnI39fX0tgZ6nst4LW5cOEULllczvSibM6dX4ZnGBch922s41/v2kB3OAbA1IIs1swuZm5ZLrNLcynM9uHz2vhsC6/Hxucx9SG8HrPtmOPiOBB1HBzXJZaYdyDmujiOS9RxzXpu/9R16XsejDoEwzF6I/FHvC0AtmXhuC6haIyesHmtN2LmO4MR2nsjdPRG6Y30v8fvsfngRfP44Ch7jbmuS117kE017Wyuae+bJjI4TiQ/y0tFQRYluX7yA17yssy/HZ9tYVkWlgUWFrYFHtvCts384DaAE/8dRWPmdxZ1HGIOhKMOPeEoPeFY37Q3HKM7HKW1O0I45gz4/cHrV1fxv29cOeLfg8iEFA1DwyZTN6I6/uisO8GbLDM8RMF0M0RQwXTTu76g0vS6DOSZG8u+HDP2tS/H3Jz2Zh09pJPrmt5soU7oqIWWvXB4G+z5J9S+2r+eLxcu/hyc+YHM7rl/MnMcqF1nxkI/+Dz0tpmbPz1NI+vRNFqWDfnTIK+i/8aX7Y1PfSbFu/WAucEWDR793umrYfoqOPQS1K03gbqProfsotS3XSa1aMxhW10new53sfdwF3uautnV0MnOhq4h15+SH+DiRVNYMq2AZdMLmV+eR3GOT9cTI9DeG2Hv4S72Hu5mX1M3z+9t5pUDrSPaRo7fQ0mun8uWVPDmM2aweKoy8ocUi5iMzroNppNB/aahAxkJ+dMhv8K8L9IDbQeP/R2RP910opi6HEoXmONxoMDU6Qrk9897A2PrBeu6ZqiQmnUmoL3hj/2B+PxpcMOPTY0wOXnVb4KHvmAymAfyZpnP6JwLTeeMknkmyOWdfENLi0wInfXwwg9NXYpIj+mMNOMME6DIn2b+fZYvhYql5tpV51YyAhkTuJjx8T9jB5I7RIbfY+P3mpvYfm9i3sZOwz+SXL+Hgmwfhdk+8rN8ZPv6AzKJ+UB83u+18doWngEPr23jscFjm9dsy8LriU8Hrdc/D+amsuu6g6eYqeOYG/N9z10Xt+9mvXmeuHnvDnyO2VYk5tLWE6GlO0xrT5h9Td3sqO9kR0Mn4Wj/TenphVl8+bplXLigjCwranpxRgY8elvMTTyv39z0CHWZk9hgmzm5jvf0bLPyuWNzhN9vi1Afy8Nl4g0ZlSgoee78Mt557hzmFPuhu8mM6dfbYm4khrvNzRxvIH7TccDUE4hP/QNuDHnMzSHbi2t7OdwVZnt9J/XtQRo6gjR0BqlvD9HUZR6HO0OEBvx90iXgtVleWchlSyq45pRpzCjJoCFyRMab60J7tRkaoXm3CSS07DVDQwTbzQngWCQCGN4sc9wNdTCo/saRpq+CU94EK96oYaEmqmgIXv0t7H/G1FtpO2AuFMqXQvli813bssd89krmQtlC8/2S+E7xZYMTg0h3PAMjZD437TXms9p+qD8FfLgsD0xZDLPPNb2rZp9nAhVg2rH9HxDugZVvSs3vRASobw/y+I5GNtW00xuOsb+5m531nX2dYwbKz/IysySHquJsyvICFGT7yM/yUpDloyDbR0GWl4JsH8U5fkrzTEeQyRTocByX7nCUrlCU3nCMvYe7eXZPE71h0zmnINtkTexv6mFvU9cxO8+U5QXoDEaYXZrLHe85gxy/l7q2XkJRh6ribA53hijMMddJAa96Vo5asB0atphHTws0bjU3flv2DL2+L8dkWLiOOZZHQ9DVMPz92V4TwPDnn/iGsRMzgZJYxEydiDneO0dk5BfPgdf8p+lZr162knB4hwlsVb9oOtgMdV5s2ebzXDIPimbEs5ULzdCZ/tx4D+/c/p7evuwj5nPMtfUkOoZPOI5jsq0iPfF7RT2m00s0aK5hfDnmb+nP7Z/XcWJ8RMPm/L/t4NCPztr+dWecCa//mRk5QCQJMiZw8X/fPwOP3+7v5Y6FCziuhQO4fdP+ZY47+BHruzHfz2XwF495rX9Zf6ut477vyGVD/bDD/YqzjnezKAnvHbodR79veN/JQ7xvGO/y2Rb5AZsCT5QcerFCnUf3tBwjx/Lg4CGKTQybGJ4jpjZRbJx4gCPR7sTPbWH1/yxW4rlrfseWWd/q+8SYMIkVX25bYFuJ34350Fm4fa+bddy+bdgD3meBuUCIBs0XcrJZljlxszzxqW16W1sesPp+Qlys/n8/iWUOuPF1gEFTN/5L6Zvv+81Y8V+qNeCXm8jasLBx8Vj9vxM7Pk0sM78/h3kVq7j06h8m//chE8Lztc/zRPUT2JbJlrP6Ph39xyDXdeOBVgfHdUh87STWT0xty+5bbjNge33/zq1B+xhqG8dzoteHc5Ac8T6cmDlmhLtMlkSowxxXg2aeSI+56RALm2EkYhEs9+ibcEc107JMlkZ2CeQUm/GDS+ebGxGT0ChPVTKaO9xzCieW/Iu7ROZOsN0EOJyY+SJxHJNpkSgkm1XYP+TZCdoQ8AS4ddmtyW2nTBhNvU38ftvvx32/Mceltj1IdUsPbT1hGjtCdIVHnrHksS2TLe7t7zxF4jx0iMO+Ff+PNcSyxFJr4PLE/IBz2YFvGmod6L/e6TtzjS84cjlAJNafMRsccvim439/5QY8FOf4Kc7xU5LrZ0FFHrkBLzHHnCcPtwPZCb9rk2S89jN+uxliR9EwdDea8wjLYwIOWYXmu/7Iv0c0ZDpUdTWYITuCbRAJmffGwhALQSyc3B8nUGjOP4pnmeC6xwRBblhwA+U55cnck0wgv936W3qiQwQoXNfc3G4/BC37sLobTaDuOB0phv15tSyw/WYYKo8/fi2duM61Bxy07SOuge3+GwUMfE9iHRu3771W/zqDrqGP3t6Q19nmlzBgMvgg3X+uO/juVv/Twa8PPjceMD/Udo7axsBtD7Gd+HL3mNtzTfAyGurvWOXEjtrDcdle8/eyvLh2/P7HoKlnwL0Qz6DfsTvo72QP+B0f+fvuv8dhfpojvpkHfGf3v2XgOsf4aY65eOTXK0O+5zibcV3H/O6d6OBHLNofXHZiZhqLgRsd8h7pIAXToPJ0KJnT/+sY4Y/i4tId6aYl2NL3uHXZrbxx4RtHtiGZVJIVuBjzAIM/93biCShaOmkFsoDxKrzsxB+ZLhB/jLehTmbS78rWLVya7kZI2mxt3srvt4//zapJwxd/4I0/Rnq8bTc3n+v3Q/1TSW6cyPAV+AsUuDiJNfc287NNP0t3M6Bg9GdoMaA7/kiZI0/hknlK5wGyzWM0g65EgcPA4TAQhhdGNlKUZKLEqQUeICf+SLJwNTRUQ8MzfYvOrTxXgYuT2C82/4Km3qYTr+gDClPxuXQxR/RRvnXgVI7PE39kJaO+2THuBbno73EiFkfc2U38YYarG+qeMI8kqus60XDKIsMz5sDF9SWnEMgN0BeR7OsCNLBXuzt4Ouj1xDoD5o8yVAT5iNeGiFoftd7xXh4yCJmsPilHRnGHXicx/BPQl65+3BYMq+fTKH4GyzY9FfrGWg+YiLjtNa+NViJbwXUG9O6MT93Y0fMj+oZK5Esw+PdiHRlVH2q9gRH6I9cd4r2e+FAcnjGMD+s65rPsOvGera7p6Ypz9Guuc8Tne8C/s7HMH9l7YtBzl8G9ThK/hwHz8ddWlC0f3e9AJoWVU1by3hXv7cuocN1E5lPiGGamtmX3PQZmZQx6H5j5xP8Sw+ANeJ54H/RnciSmYzGcHv0n2sdw2jDWzIHh7mMyDXky3satF+8kk+Udr04OkomKAkW8dclbx3WfycrEijouwUiMcNTpKzodS2QdHZnxEL+eOGrP7uDjs9u3bIh2D/WeITIoBr3DSpyF9fcS7T9SmfpmXtvqqyWY5fPg99jDqkc39B4n/12idGTypeP3mo59FmcVj/s+JXNcPedquiJD1yQ6llF9Tl0X13WwnGj/kGaJaeL6uu8+lNlLYpkVf//AZQxcdtSUI9Yd4rUjtjd4HwNZR8wOOpoPXm/QIfzoexxH3TEa8vx/8OvWkcuP9Z5BbTuyzZjhST1+M9ycP98M/9TXruN89ySyARJD0MXvd1h99z1i8QzgI+ZJ3B8xv1MziIYzxN8obohMEWvg86HuHw75nhF+j474GmyEe4hnpFgeH1jxrJXEvTrbM2De2z9EuTdrVNc3I72ezPHmUJJVQnFWMSVZJcwsmDnifYoMZcxDRY015UNERERERERERERERCa+ZMUNJl6VZBERERERERERERERmbQUuBARERERERERERERkYyhwIWIiIiIiIiIiIiIiGQMBS5ERERERERERERERCRjKHAhIiIiIiIiIiIiIiIZQ4ELERERERERERERERHJGApciIiIiIiIiIiIiIhIxlDgQkREREREREREREREMoYCFyIiIiIiIiIiIiIikjEUuBARERERERERERERkYyhwIWIiIiIiIiIiIiIiGQM72jf6LouAB0dHUlrjIiIiIiIiIiIiIiITEyJeEEifjBaow5cNDc3AzBjxowxNUBERERERERERERERCaPzs5OCgsLR/3+UQcuSkpKADh48OCYGiAiE1dHRwczZsygurqagoKCdDdHRNJAxwER0XFAREDHAhHRcUBE+o8DW7duZfr06WPa1qgDF7ZtymMUFhbqYCRykisoKNBxQOQkp+OAiOg4ICKgY4GI6DggIlBZWdkXPxgtFecWEREREREREREREZGMocCFiIiIiIiIiIiIiIhkjFEHLgKBAF/+8pcJBALJbI+ITCA6DoiIjgMiouOAiICOBSKi44CIJPc4YLmu6yahTSIiIiIiIiIiIiIiImOmoaJERERERERERERERCRjKHAhIiIiIiIiIiIiIiIZQ4ELERERERERERERERHJGApciIiIiIiIiIiIiIhIxlDgQkREREREREREREREMoYCFyIiIiIiIiIiIiIikjEUuBARERERERERERERkYyhwIWIiIiIiIiIiIiIiGQMBS5ERERERERERERERCRjKHAhIiIiIiIiIiIiIiIZQ4ELERERERERERERERHJGApciIiIiIiIiIiIiIhIxlDgQkREREREREREREREMoZ3tG90HIfa2lry8/OxLCuZ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", - "text/plain": [ - "" - ] - }, - "execution_count": 9, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "from pyannote.audio import Inference\n", - "inference = Inference(model, step=2.5)\n", - "output = inference(AUDIO_FILE)\n", - "output" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "For each of the 11 positions of the 5s window, the model outputs a 3-dimensional vector every 16ms (293 frames for 5 seconds), corresponding to the probabilities that each of (up to) 3 speakers is active. " - ] - }, - { - "cell_type": "code", - "execution_count": 10, - "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": [ - "(11, 293, 3)" - ] - }, - "execution_count": 10, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "output.data.shape" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "## Processing a file from memory\n", - "\n", - "In case the audio file is not stored on disk, pipelines can also process audio provided as a `{\"waveform\": ..., \"sample_rate\": ...}` dictionary. " - ] - }, - { - "cell_type": "code", - "execution_count": 11, - "metadata": {}, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "type(waveform)=\n", - "waveform.shape=torch.Size([1, 480000])\n", - "waveform.dtype=torch.float32\n" - ] - } - ], - "source": [ - "import torchaudio\n", - "waveform, sample_rate = torchaudio.load(AUDIO_FILE)\n", - "\n", - "print(f\"{type(waveform)=}\")\n", - "print(f\"{waveform.shape=}\")\n", - "print(f\"{waveform.dtype=}\")\n", - "\n", - "audio_in_memory = {\"waveform\": waveform, \"sample_rate\": sample_rate}" - ] - }, - { - "cell_type": "code", - "execution_count": 12, - "metadata": {}, - "outputs": [ - { - "data": { - "image/png": "iVBORw0KGgoAAAANSUhEUgAABi4AAAGZCAYAAAAetMkNAAAAOXRFWHRTb2Z0d2FyZQBNYXRwbG90bGliIHZlcnNpb24zLjYuMCwgaHR0cHM6Ly9tYXRwbG90bGliLm9yZy89olMNAAAACXBIWXMAAA9hAAAPYQGoP6dpAADTZ0lEQVR4nOzdd2AcZ53/8ffMNvVuybbk3lsc2+m9EtIJgUCAEHo7erkf9TjuDg6OO2roJUDoSSgJ6QnpzUkc995lVavXrTO/P55dFVu2VXa1K/nzgs3Mzs7OPJLWszPzfb7P13Jd10VERERERERERERERCQD2OlugIiIiIiIiIiIiIiISIICFyIiIiIiIiIiIiIikjEUuBARERERERERERERkYyhwIWIiIiIiIiIiIiIiGQMBS5ERERERERERERERCRjKHAhIiIiIiIiIiIiIiIZQ4ELERERERERERERERHJGN7RvtFxHGpra8nPz8eyrGS2SUREREREREREREREJhjXdens7GT69OnY9ujzJkYduKitrWXGjBmj3rGIiIiIiIiIiIiIiEw+1dXVVFVVjfr9ow5c5Ofn9zWgoKBg1A0QEREREREREREREZGJr6OjgxkzZvTFD0Zr1IGLxPBQBQUFClyIiIiIiIiIiIiIiAjAmMtLqDi3iIiIiIiIiIiIiIhkDAUuREREREREREREREQkYyhwISIiIiIiIiIiIiIiGUOBCxERERERERERERERyRgKXIiIiIiIiIiIiIiISMZQ4EJERERERERERERERDKGAhciIiIiIiIiIiIiIpIxFLgQEREREREREREREZGMocCFiIiIiIiIiIiIiIhkDAUuREREREREREREREQkY3jT3QAREZHxFozECEUdYo5L1IlPY278udu3nmX1v8fqW2YNsWzgetZRy47c3mi2YR0xYzFgG9YR6wzYx+BlR7w3PrEtyPZ58HpOrv4MruviuBBzXLy2hW0P8UcTkZFzXXCi4MTAdcwDt3/edeMP5zivD5jniHUHvo7bvz2z8/73JNqCO0QjE474d3/Uwfs4B/NjbmOM+xjqC2TM28iUfRz5lgHreLMgf9rw3ncCkZhDTzhGbzhGOOoQcRwiMYdI1MVxXWzLwrLMrmzLij+ILxvwHLOebZtvzv71rAHvja9nc/T7jlwvCT+bSCZr6grhOOb8ysU1h2fM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JXNcPedquiJD1yQ6llF9Tl0X13WwnGj/kGaJaeL6uu8+lNlLYpkVf//AZQxcdtSUI9Yd4rUjtjd4HwNZR8wOOpoPXm/QIfzoexxH3TEa8vx/8OvWkcuP9Z5BbTuyzZjhST1+M9ycP98M/9TXruN89ySyARJD0MXvd1h99z1i8QzgI+ZJ3B8xv1MziIYzxN8obohMEWvg86HuHw75nhF+j474GmyEe4hnpFgeH1jxrJXEvTrbM2De2z9EuTdrVNc3I72ezPHmUJJVQnFWMSVZJcwsmDnifYoMZcxDRY015UNERERERERERERERCa+ZMUNJl6VZBERERERERERERERmbQUuBARERERERERERERkYyhwIWIiIiIiIiIiIiIiGQMBS5ERERERERERERERCRjKHAhIiIiIiIiIiIiIiIZQ4ELERERERERERERERHJGApciIiIiIiIiIiIiIhIxlDgQkREREREREREREREMoYCFyIiIiIiIiIiIiIikjEUuBARERERERERERERkYyhwIWIiIiIiIiIiIiIiGQM72jf6LouAB0dHUlrjIiIiIiIiIiIiIiITEyJeEEifjBaow5cNDc3AzBjxowxNUBERERERERERERERCaPzs5OCgsLR/3+UQcuSkpKADh48OCYGiAiE1dHRwczZsygurqagoKCdDdHRNJAxwER0XFAREDHAhHRcUBE+o8DW7duZfr06WPa1qgDF7ZtymMUFhbqYCRykisoKNBxQOQkp+OAiOg4ICKgY4GI6DggIlBZWdkXPxgtFecWEREREREREREREZGMocCFiIiIiIiIiIiIiIhkjFEHLgKBAF/+8pcJBALJbI+ITCA6DoiIjgMiouOAiICOBSKi44CIJPc4YLmu6yahTSIiIiIiIiIiIiIiImOmoaJERERERERERERERCRjKHAhIiIiIiIiIiIiIiIZQ4ELERERERERERERERHJGApciIiIiIiIiIiIiIhIxlDgQkREREREREREREREMoYCFyIiIiIiIiIiIiIikjEUuBARERERERERERERkYyhwIWIiIiIiIiIiIiIiGQMBS5ERERERERERERERCRjKHAhIiIiIiIiIiIiIiIZQ4ELERERERERERERERHJGApciIiIiIiIiIiIiIhIxlDgQkREREREREREREREMoZ3tG90HIfa2lry8/OxLCuZ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", - "text/plain": [ - "" - ] - }, - "execution_count": 12, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "output = inference(audio_in_memory)\n", - "output" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "## Processing part of a file\n", - "\n", - "If needed, `Inference` can be used to process only part of a file:" - ] - }, - { - "cell_type": "code", - "execution_count": 13, - "metadata": {}, - "outputs": [ - { - "data": { - "image/png": "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vnx53vrWt+bd7353TjvttJx22ml597vfnWnTpuXVr351E6sGGumJrgNz5szJNddck1/8xV/MokWL8vDDD+cd73hH5s2bl5e97GVNrBpopDe/+c35j//4j3zuc5/LzJkzRz9N2d3dnalTp6YoCq8J4Bh3qOvAjh07vCaAY9w73vGOXHnllVm2bFl6e3vziU98It/+9rfzla98paGvBcYUXLziFa/I5s2b82d/9mdZu3Ztzj333HzpS1/KiSeeOJbugElm1apVedWrXpVNmzblhBNOyJOf/OT88Ic/dA2AY9jNN9+cZz/72aPPR+azee1rX5uPfvSj+YM/+IPs3r07b3rTm7J169Zcfvnl+drXvpaZM2c2q2SgwZ7oOvDBD34wd9xxRz72sY9l27ZtWbRoUZ797Gfn2muvdR2AY8gHP/jBJMmznvWs/dZ/5CMfyete97ok8ZoAjnGHug5Uq1WvCeAYt379+rzmNa/J2rVr093dnfPPPz9f+cpX8vznPz9J414LFGVZlhPxBQAAAAAAABypI57jAgAAAAAAYKIILgAAAAAAgJYhuAAAAAAAAFqG4AIAAAAAAGgZggsAAAAAAKBlCC4AAAAAAICWIbgAAAAAAABahuACAAAAAABoGYILAADgkK655ppceOGFzS4DAAA4DhRlWZbNLgIAAGieoiiecPtrX/vavP/9709fX1/mzp17lKoCAACOV4ILAAA4zq1bt250+dprr82f/umf5p577hldN3Xq1HR3dzejNAAA4DjkVlEAAHCcW7hw4eiju7s7RVE8Zt2Bt4p63etel6uuuirvfve7s2DBgsyaNSvvete7Mjg4mN///d/PnDlzsnTp0vzLv/zLfudavXp1XvGKV2T27NmZO3duXvrSl+bhhx8+ul8wAADQ0gQXAADAmHzzm9/MmjVr8p3vfCd/8zd/k2uuuSYvfvGLM3v27PzoRz/K1VdfnauvvjorV65MkuzatSvPfvazM2PGjHznO9/Jd7/73cyYMSMvfOEL09/f3+SvBgAAaBWCCwAAYEzmzJmTv/u7v8sZZ5yR17/+9TnjjDOya9euvOMd78hpp52W//E//kc6Ojryve99L0nyiU98IpVKJf/8z/+c8847L2eddVY+8pGP5NFHH823v/3t5n4xAABAy2hrdgEAAMDkdM4556RS2ftZqAULFuTcc88dfV6tVjN37txs2LAhSXLLLbfk/vvvz8yZM/frZ8+ePXnggQeOTtEAAEDLE1wAAABj0t7evt/zoigOuq5WqyVJarVaLrnkknz84x9/TF8nnHDCxBUKAABMKoILAADgqLj44otz7bXXZv78+enq6mp2OQAAQIsyxwUAAHBU/Mqv/ErmzZuXl770pbnhhhvy0EMP5frrr8/v/d7vZdWqVc0uDwAAaBGCCwAA4KiYNm1avvOd72T58uV5+ctfnrPOOiuvf/3rs3v3biMwAACAUUVZlmWziwAAAAAAAEiMuAAAAAAAAFqI4AIAAAAAAGgZggsAAAAAAKBlCC4AAAAAAICWIbgAAAAAAABahuACAAAAAABoGYILAAAAAACgZQguAAAAAACAliG4AAAAAAAAWobgAgAAAAAAaBmCCwAAAAAAoGX8/wFqlZQ/bA3JugAAAABJRU5ErkJggg==", - "text/plain": [ - "" - ] - }, - "execution_count": 13, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "from pyannote.core import Segment\n", - "output = inference.crop(AUDIO_FILE, Segment(10, 20))\n", - "output" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "## Offline use\n", - "\n", - "Gating models allows [me](https://herve.niderb.fr) to know a bit more about `pyannote.audio` user base and eventually help me write grant proposals to make `pyannote.audio` even better. Please fill this form as precisely as possible. \n", - "\n", - "For instance, before gating `pyannote/segmentation`, I had no idea that so many people were relying on it in production. Hint: sponsors are more than welcome! maintaining open source libraries is time consuming.\n", - "\n", - "That being said: this whole authentication process does not prevent you from using official `pyannote.audio` models offline (i.e. without going through the authentication process in every `docker run ...` or whatever you are using in production).\n", - "\n", - "* Step 1: download the `pytorch_model.bin` model\n", - "\n", - "![](assets/download-model.png)\n", - "\n", - "* Step 2: load the model" - ] - }, - { - "cell_type": "code", - "execution_count": 14, - "metadata": {}, - "outputs": [], - "source": [ - "# look ma: no hands! \n", - "offline_model = Model.from_pretrained(\"pytorch_model.bin\")" - ] - }, - { - "cell_type": "code", - "execution_count": 15, - "metadata": {}, - "outputs": [], - "source": [ - "# just checking weights are the same...\n", - "import torch\n", - "for weights, offline_weights in zip(model.parameters(), offline_model.parameters()):\n", - " assert torch.equal(weights, offline_weights)" - ] - } - ], - "metadata": { - "kernelspec": { - "display_name": "Python 3.9.13 ('pyannote-mps')", - "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.9.13" - }, - "vscode": { - "interpreter": { - "hash": "36a3a48a52702f18671693adf589423ec3f7db45d50f6ee539f1b0696bb58d43" - } - } - }, - "nbformat": 4, - "nbformat_minor": 2 -} +{"cells":[{"cell_type":"markdown","metadata":{"id":"rkz0m90MTNdU"},"source":["**\"Open**"]},{"cell_type":"markdown","metadata":{"id":"vDBFFNeGWF0v"},"source":["# Applying a pretrained model\n","\n","In this tutorial, you will learn how to apply `pyannote.audio` models on an audio file, whose manual annotation is depicted below"]},{"cell_type":"markdown","metadata":{"id":"DcXUj3lVTkWz"},"source":["## Tutorial setup"]},{"cell_type":"code","execution_count":3,"metadata":{"executionInfo":{"elapsed":221,"status":"ok","timestamp":1704806538788,"user":{"displayName":"Clément PAGES","userId":"11757386314069785178"},"user_tz":-60},"id":"p7uwJtF1W0Od"},"outputs":[],"source":["# preparing notebook for visualization purposes\n","# (only show outputs between t=0s and t=30s)\n","from pyannote.core import notebook, Segment\n","notebook.crop = Segment(0, 30)"]},{"cell_type":"markdown","metadata":{"id":"yr4ONuV9Tlgj"},"source":["### `Google Colab` setup"]},{"cell_type":"markdown","metadata":{"id":"OaXXRLf5Tp2D"},"source":["If you are running this tutorial on `Colab`, execute the following commands in order to setup `Colab` environment. These commands will install `pyannote.audio`, and download resources used in this tutorial."]},{"cell_type":"code","execution_count":null,"metadata":{"id":"wQub0z0VTzpU"},"outputs":[],"source":["!pip install -qq pyannote.audio==3.1.1\n","!pip install -qq ipython==7.34.0\n","!wget -q \"https://github.com/pyannote/pyannote-audio/raw/develop/tutorials/assets/sample.wav\"\n","!wget -q \"https://github.com/pyannote/pyannote-audio/raw/develop/tutorials/assets/sample.rttm\"\n","!wget -q -P ./assets/ \"https://github.com/pyannote/pyannote-audio/blob/develop/tutorials/assets/download-model.png\""]},{"cell_type":"markdown","metadata":{"id":"4Qy1iMvGVaHF"},"source":["⚠ Restart the runtime (Runtime > Restart session)."]},{"cell_type":"code","execution_count":18,"metadata":{"executionInfo":{"elapsed":203,"status":"ok","timestamp":1704807063824,"user":{"displayName":"Clément PAGES","userId":"11757386314069785178"},"user_tz":-60},"id":"vHwJOO-sUdF2"},"outputs":[],"source":["AUDIO_FILE = \"sample.wav\"\n","REFERENCE = \"sample.rttm\""]},{"cell_type":"markdown","metadata":{"id":"CUmGkiY-V-wI"},"source":["### Non `Google Colab` setup"]},{"cell_type":"markdown","metadata":{"id":"_E4buYUQWXE5"},"source":["If you are not using Colab, clone `pyannote.audio` [GitHub repository](https://github.com/pyannote/pyannote-audio) and update ROOT_DIR accordingly"]},{"cell_type":"code","execution_count":2,"metadata":{"executionInfo":{"elapsed":232,"status":"ok","timestamp":1704806051725,"user":{"displayName":"Clément PAGES","userId":"11757386314069785178"},"user_tz":-60},"id":"Wii7pyvSTIa1"},"outputs":[],"source":["# clone pyannote-audio Github repository and update ROOT_DIR accordingly\n","ROOT_DIR = \"/pyannote-audio\"\n","AUDIO_FILE = f\"{ROOT_DIR}/tutorials/assets/sample.wav\"\n","REFERENCE = f\"{ROOT_DIR}/tutorials/assets/sample.rttm\""]},{"cell_type":"markdown","metadata":{"id":"o01jf1VTXC8u"},"source":["## References\n","\n","First, let's take a look at the audio reference used in this tutorial. It can be accessed as follows:"]},{"cell_type":"code","execution_count":4,"metadata":{"colab":{"base_uri":"https://localhost:8080/","height":259},"executionInfo":{"elapsed":542,"status":"ok","timestamp":1704807074571,"user":{"displayName":"Clément PAGES","userId":"11757386314069785178"},"user_tz":-60},"id":"Q4hYAMEiTIa3","outputId":"9fecf73e-2448-4a4e-93e4-f35d2ec4da8b"},"outputs":[{"data":{"image/png":"iVBORw0KGgoAAAANSUhEUgAABi8AAADyCAYAAAA1MlYeAAAAOXRFWHRTb2Z0d2FyZQBNYXRwbG90bGliIHZlcnNpb24zLjguMiwgaHR0cHM6Ly9tYXRwbG90bGliLm9yZy8g+/7EAAAACXBIWXMAAA9hAAAPYQGoP6dpAAAfHUlEQVR4nO3dfZRU9X0/8PeCgAi7i4AsrCKigpgEEB9KVq2aSED02KIxCnlQqNXWIKeoJNZWRKvGBmsejCYmaa3RVI0xgm2soSkIVkPwISHG2hjhaLA/npSE5UEFszu/PzxuQzAmwOzO3d3X65w9Z/feme/9zNzvfPc78557b1WpVCoFAAAAAACgILpUugAAAAAAAIDfJLwAAAAAAAAKRXgBAAAAAAAUivACAAAAAAAoFOEFAAAAAABQKMILAAAAAACgUIQXAAAAAABAoQgvAAAAAACAQhFeAAAAAAAAhSK8AAAAAAAACkV4AQAAAAAAFIrwAgAAAAAAKBThBQAAAAAAUCjCCwAAAAAAoFCEFwAAAAAAQKEILypg6tSpmTRpUqXLoB3QVwAAAACAzkh40YFs3rw5M2fOzJAhQ9KzZ88ce+yxefLJJ3e4TalUylVXXZVBgwalZ8+eGTduXF544YUKVUyl/CF95YEHHsj48ePTr1+/VFVVZfny5ZUpFgAAAADodPYqd4NNGzaUu8l31bVfvzbdXhFt37493bt3z5//+Z/n2WefzV133ZX6+vp885vfzLhx4/Lcc89l//33T5LMnTs3N998c77xjW9k6NChmT17diZMmJDnnnsue++9d5vW/aut29t0e/v26t6m2yuiXekrW7duzfHHH5+zzz47F1xwQYUrBwAAAAA6k6pSqVQqZ4P/b//B5Wzu99r//728y/e5//77c80112TFihXZZ599MmbMmDz44IOZPn16Nm7cmDFjxuSWW27Jtm3b8tGPfjQ333xzund/64Pv5ubmfPazn83Xvva1rF27NsOHD8/s2bNz1llnJUmamppy4YUXZtGiRVm7dm0OPPDAfPKTn8xf/dVftWx/6tSp2bhxY+bPn58kefLJJ3Pqqadm1qxZufzyy7Nx48bMmjUrDz74YLZt25ajjz46n//85zN69OgkydVXX5358+fn4osvzvXXX59f/OIX2bp1a6qrq/Pggw/mtNNOa9nWUUcdlYkTJ+a6665LqVRKfX19LrvsssyaNStJ0tjYmLq6utxxxx2ZPHnybu2D3fX+OQvadHs/vGbCLt+ns/aV3/TSSy9l6NCh+fGPf5wjjjhil59DAAAAAIBdVfYjL4puzZo1mTJlSubOnZszzjgjmzdvzn/913/l7Qxn4cKF2XvvvbN48eK89NJLmTZtWvr165frr78+SXLDDTfkm9/8Zm677bYMGzYsjz76aD7+8Y9nv/32y4knnpjm5uYccMAB+fa3v51+/frlBz/4QS688MIMGjQoZ5999k71LFq0KGeeeWbmzp2bCy+8MEnykY98JD179szDDz+c2trafPWrX83JJ5+cn//85+nbt2+SZMWKFfnOd76TBx54IF27ds2vf/3rNDU17XT0RM+ePfPYY48lSV588cWsXbs248aNa1lfW1ubsWPHZunSpW0eXhRdZ+4rAAAAAACV1CnDi1//+tc588wzM2TIkCTJyJEjW9Z37949t99+e/bZZ5+8973vzd/93d/lU5/6VK699tq8+eab+cxnPpP//M//TENDQ5Lk4IMPzmOPPZavfvWrOfHEE9OtW7dcc801Le0NHTo0S5cuzX333bfTB9Lz5s3Lueeem3/8x3/MOeeckyR57LHH8sQTT2T9+vXp0aNHkuQf/uEfMn/+/Nx///0tH1pv3749d955Z/bbb7+W9hoaGnLttdfm8MMPT11dXe65554sXbo0hx56aJJk7dq1SZK6urod6qirq2tZx//pzH0FAAAAAKCSOl14MXr06Jx88skZOXJkJkyYkPHjx+ess87Kvvvu27J+n332abl9Q0NDtmzZkpdffjlbtmzJa6+9lg996EM7tLl9+/aMGTOm5e9bb701t99+e1atWpXXX38927dv3+l0O8uWLct3v/vd3H///Zk0aVLL8p/85CfZsmVL+v3WtTxef/31rFy5suXvIUOG7PBhdJLcdddd+bM/+7Psv//+6dq1a4488shMmTIlTz/99G49V52dvgIAAAAAUBllDy8GPrO83E2WVdeuXfP9738/P/jBD/If//Ef+dKXvpS//du/zbJly37vfbds2ZIkeeihh1ouavy2t7/5fu+992bWrFm56aab0tDQkOrq6tx44407tX/IIYekX79+uf3223PaaaelW7duLdsYNGhQFi9evNP2+/Tp0/J7r169dlp/yCGHZMmSJdm6dWs2bdqU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","text/plain":[""]},"execution_count":4,"metadata":{},"output_type":"execute_result"}],"source":["from pyannote.database.util import load_rttm\n","\n","reference = load_rttm(REFERENCE)[\"sample\"]\n","reference"]},{"cell_type":"markdown","metadata":{"id":"3cpR2brxTIa6"},"source":["## Loading models from 🤗 hub\n","\n","A bunch of pretrained models are available on [🤗 Huggingface model hub](https://hf.co/models?other=pyannote-audio-model) and can be listed by looking for the [`pyannote-audio-model`](https://hf.co/models?other=pyannote-audio-model) tag."]},{"cell_type":"code","execution_count":5,"metadata":{"colab":{"base_uri":"https://localhost:8080/"},"executionInfo":{"elapsed":1201,"status":"ok","timestamp":1704807077972,"user":{"displayName":"Clément PAGES","userId":"11757386314069785178"},"user_tz":-60},"id":"OXNju-sFTIa7","outputId":"6c587fd6-f14f-4162-81ba-0609153aa7f2"},"outputs":[{"data":{"text/plain":["['pyannote/TestModelForContinuousIntegration',\n"," 'pyannote/embedding',\n"," 'pyannote/segmentation',\n"," 'pyannote/brouhaha',\n"," 'pyannote/segmentation-3.0',\n"," 'pyannote/wespeaker-voxceleb-resnet34-LM']"]},"execution_count":5,"metadata":{},"output_type":"execute_result"}],"source":["from huggingface_hub import HfApi\n","available_models = [m.modelId for m in HfApi().list_models(filter=\"pyannote-audio-model\")]\n","list(filter(lambda p: p.startswith(\"pyannote/\"), available_models))"]},{"cell_type":"markdown","metadata":{"id":"LrQ2ykU4TIa-"},"source":["Official [pyannote.audio](https://github.com/pyannote/pyannote-audio) models (i.e. those under the [`pyannote` organization](https://hf.co/pyannote) umbrella) are open-source, but gated. It means that you have to first accept users conditions on their respective Huggingface page to access the pretrained weights and hyper-parameters. Despite this initial process, those models can perfectly be downloaded for later offline use: keep reading this tutorial until the end to learn how to do that.\n","\n","For instance, to load the speaker segmentation model used in this tutorial, you have to visit [hf.co/pyannote/segmentation](https://hf.co/pyannote/segmentation), accept the terms, and log in using `notebook_login` below:"]},{"cell_type":"code","execution_count":null,"metadata":{"colab":{"base_uri":"https://localhost:8080/","height":145,"referenced_widgets":["a73cecb8608f491e8f996c5114df4d0f","bc10c6804346449b8e349728a1acb8d2","73915caf6d1042ca9a27853986217ae2","2d1965df902b4b7eb6e4e28e44d6e32b","b2e03b10050d46548932f429bcc18d81","0c537fef94bd4a3d8c42d981a70ea35b","79d55946b3764666a0b57a72722f6c19","988c83c85f7d44d0be949de6eedcf977","53919e13e42441d9b8cf5eb4f2effe96","47da80658de14604a7cc5268b951c172","c7fbfffbbc304f0ba025e03beb8f638a","416ffb7703b1404ab1c19c6b1ecafb4c","5be7421c575d41128d0675dc9abbc196","8b3353af24074ce5b5d2d9b162c61062","cd40e31c191044b7a0f8fa4694ad6380","ecbb880cf0044404ab9bfc5995656807","79287ffea49a4e4a80191b1157de15cc","0e04a45510f346b8ab3c465b10ccdfd2","bf5c88fe90f0462b95aa8a81467c1e9d","09ee64808a5c431b928066a4cb287a78","52a4a1aab39741f2a0499428f07a4c25","f23cc133109c4ecb9b383f118bcc71aa","2b91f4b11d5848c0b6795b649bc2d7bc","b437981acb894f97ad45daaebe2734c7","01a79756e1104be0bcbe1d233677d605","990375a830eb4cd79c69ad78b9ac685b","49cb317b141a43b7b8ce342e2d62ab03","abc23089f4ef4d2a9f8a104fb1dba14a","57cf64e9c70e4057a76c2f3fb1e9b191","5e90e4818f1f43f2aa4714e0e40dc15d","fb027db34fd740c2a4758d650ae3f73c","1a30ac8b519948bbad72886049b53d55"]},"executionInfo":{"elapsed":215,"status":"ok","timestamp":1704807086866,"user":{"displayName":"Clément PAGES","userId":"11757386314069785178"},"user_tz":-60},"id":"x9iQwHjfTIa_","outputId":"b5b3c597-4c2e-4306-e6a5-9ccc9ed19d08"},"outputs":[],"source":["from huggingface_hub import notebook_login\n","notebook_login()"]},{"cell_type":"markdown","metadata":{"id":"fUvB3kwwTIbA"},"source":["Once authenticated, you can load the model..."]},{"cell_type":"code","execution_count":null,"metadata":{"executionInfo":{"elapsed":3254,"status":"ok","timestamp":1704807117456,"user":{"displayName":"Clément PAGES","userId":"11757386314069785178"},"user_tz":-60},"id":"IzYUeS99TIbE"},"outputs":[],"source":["from pyannote.audio import Model\n","model = Model.from_pretrained(\"pyannote/segmentation-3.0\", use_auth_token=True)"]},{"cell_type":"markdown","metadata":{"id":"UxuGtfPoTIbF"},"source":["... which consists in SincNet feature extraction (`sincnet`) , LSTM sequence modeling (`lstm`), a few feed-forward layers (`linear`), and a final multi-label `classifier`:"]},{"cell_type":"code","execution_count":8,"metadata":{"colab":{"base_uri":"https://localhost:8080/"},"executionInfo":{"elapsed":223,"status":"ok","timestamp":1704807124564,"user":{"displayName":"Clément PAGES","userId":"11757386314069785178"},"user_tz":-60},"id":"BQ2RDdqUTIbH","outputId":"6caf82ff-7a19-401d-ad79-8350315ec9de"},"outputs":[{"data":{"text/plain":[" | Name | Type | Params | In sizes | Out sizes \n","---------------------------------------------------------------------------------------------------------\n","0 | sincnet | SincNet | 42.6 K | [1, 1, 160000] | [1, 60, 589] \n","1 | lstm | LSTM | 1.4 M | [1, 589, 60] | [[1, 589, 256], [[8, 1, 128], [8, 1, 128]]]\n","2 | linear | ModuleList | 49.4 K | ? | ? \n","3 | classifier | Linear | 903 | [1, 589, 128] | [1, 589, 7] \n","4 | activation | LogSoftmax | 0 | [1, 589, 7] | [1, 589, 7] \n","---------------------------------------------------------------------------------------------------------\n","1.5 M Trainable params\n","0 Non-trainable params\n","1.5 M Total params\n","5.893 Total estimated model params size (MB)"]},"execution_count":8,"metadata":{},"output_type":"execute_result"}],"source":["from pytorch_lightning.utilities.model_summary import summarize\n","\n","summarize(model)"]},{"cell_type":"markdown","metadata":{"id":"ahfL4saFTIbI"},"source":["More details about the model are provided by its specifications..."]},{"cell_type":"code","execution_count":9,"metadata":{"colab":{"base_uri":"https://localhost:8080/"},"executionInfo":{"elapsed":195,"status":"ok","timestamp":1704807127275,"user":{"displayName":"Clément PAGES","userId":"11757386314069785178"},"user_tz":-60},"id":"B0OFti5ITIbJ","outputId":"c2d74d99-7727-4f36-9a0f-4ec2aa76bd25"},"outputs":[{"data":{"text/plain":["Specifications(problem=, resolution=, duration=10.0, min_duration=None, warm_up=(0.0, 0.0), classes=['speaker#1', 'speaker#2', 'speaker#3'], powerset_max_classes=2, permutation_invariant=True)"]},"execution_count":9,"metadata":{},"output_type":"execute_result"}],"source":["specs = model.specifications\n","specs"]},{"cell_type":"markdown","metadata":{"id":"kP5sRrrdTIbK"},"source":["... which can be understood like that:\n","\n","* `duration = 10.0`: the model ingests 10s-long audio chunks\n","* `Resolution.FRAME`: the model output a sequence of frame-wise scores\n","* `len(classes) = 3`: model handle chunks with up to 3 speakers\n","* `powerset_max_classes = 2`: at most 2 speakers can talk at the same time (overlapped speech)\n","The previous two specifications give the classes that the model can predict: {no speech}, {spk1}, {spk2}, {spk3}, {spk1, spk2}, {spk1, spk3}, {spk2, spk3}, so a total of 7 classes.\n","More details about powerset can be found in the article `A. Plaquet and H. Bredin, “Powerset multi-class cross entropy loss for neural speaker diarization,” 2023.`, available [here](https://arxiv.org/abs/2310.13025).\n","* `Problem.MONO_LABEL_CLASSIFICATION`: the model prediction associates one class to each time frame"]},{"cell_type":"markdown","metadata":{"id":"wTY4-nT2TIbM"},"source":["To apply the model on the audio file, we wrap it into an `Inference` instance:"]},{"cell_type":"code","execution_count":10,"metadata":{"colab":{"base_uri":"https://localhost:8080/","height":657},"executionInfo":{"elapsed":1614,"status":"ok","timestamp":1704807131091,"user":{"displayName":"Clément PAGES","userId":"11757386314069785178"},"user_tz":-60},"id":"vKcaevu8TIbN","outputId":"e020fdb9-3c92-4f76-fcec-5053c1842d19"},"outputs":[{"data":{"image/png":"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JspDAQAAAAAAWRC0AAAAAAAAsiBoAQAAAAAAZEHQAgAAAAAAyMJUQYtf/uVfjvve975xySWXxOMf//j467/+66bHBWTqx3/8x6MoinX/99CHPrTtYQEJveMd74jnPOc5ceDAgSiKIt70pjet+/2yLOPVr3513Ote94rdu3fH05/+9PjEJz7RzmCBJC50H3jRi1503vzgWc96VjuDBZL46Z/+6fjKr/zK2Lt3b1xzzTXx3Oc+Nz72sY+t+5577rknXvayl8WVV14Ze/bsiW/91m+Nz3/+8y2NGGjaxdwHnvrUp543J/in//SftjRioGmvfe1r48Ybb4yVlZVYWVmJJz7xifHmN7+5/v2m5gITBy1+93d/N37gB34gbrrppnjve98bj3rUo+KZz3xmfOELX5j45MBievjDHx633XZb/X/vfOc72x4SkNDx48fjUY96VPzyL//yhr//Mz/zM/GLv/iL8Su/8ivxV3/1V3HZZZfFM5/5zLjnnnvmPFIglQvdByIinvWsZ62bH7zhDW+Y4wiB1N7+9rfHy172svjLv/zL+NM//dM4c+ZMPOMZz4jjx4/X3/P93//98Yd/+IfxX//rf423v/3tcfjw4fiWb/mWFkcNNOli7gMRES95yUvWzQl+5md+pqURA0274YYb4t/8m38T73nPe+Ld7353PO1pT4tv+qZvig9/+MMR0dxcoCjLspzkBx7/+MfHV37lV8Yv/dIvRUTEcDiMgwcPxstf/vL44R/+4YkHACyWH//xH483velN8f73v7/toQAtKIoi3vjGN8Zzn/vciFjLsjhw4EC88pWvjB/8wR+MiIgjR47EtddeG6973evi+c9/foujBVI49z4QsZZpcffdd5+XgQEsry9+8YtxzTXXxNvf/vZ4ylOeEkeOHImrr746Xv/618fznve8iIj46Ec/Gg972MPiXe96VzzhCU9oecRA0869D0SsZVo8+tGPjp//+Z9vd3DA3Ozfvz9+9md/Np73vOc1NheYKNPi9OnT8Z73vCee/vSnnz1ApxNPf/rT413vetckhwIW2Cc+8Yk4cOBA3P/+949/+A//Ydx6661tDwloyac//em4/fbb180N9u3bF49//OPNDWCbedvb3hbXXHNNPOQhD4mXvvSlceedd7Y9JCChI0eORMTaQkVExHve8544c+bMujnBQx/60Lj3ve9t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","text/plain":[""]},"execution_count":10,"metadata":{},"output_type":"execute_result"}],"source":["from pyannote.audio import Inference\n","inference = Inference(model, step=2.5)\n","output = inference(AUDIO_FILE)\n","output"]},{"cell_type":"markdown","metadata":{"id":"MoqfhoX_TIbO"},"source":["For each of the 9 positions of the 10s window, the model outputs a 3-dimensional vector every 17ms (589 frames for 10 seconds), corresponding to the probabilities that each of (up to) 3 speakers is active. "]},{"cell_type":"code","execution_count":11,"metadata":{"colab":{"base_uri":"https://localhost:8080/"},"executionInfo":{"elapsed":196,"status":"ok","timestamp":1704807141814,"user":{"displayName":"Clément PAGES","userId":"11757386314069785178"},"user_tz":-60},"id":"JObvduJMTIbO","outputId":"af45591c-c30d-401a-8906-db029140cea2"},"outputs":[{"data":{"text/plain":["(9, 589, 3)"]},"execution_count":11,"metadata":{},"output_type":"execute_result"}],"source":["output.data.shape"]},{"cell_type":"markdown","metadata":{"id":"Zdk-iqOaTIbQ"},"source":["## Processing a file from memory\n","\n","In case the audio file is not stored on disk, pipelines can also process audio provided as a `{\"waveform\": ..., \"sample_rate\": ...}` dictionary."]},{"cell_type":"code","execution_count":12,"metadata":{"executionInfo":{"elapsed":229,"status":"ok","timestamp":1704807145587,"user":{"displayName":"Clément PAGES","userId":"11757386314069785178"},"user_tz":-60},"id":"oFQrkl01TIbQ"},"outputs":[{"name":"stdout","output_type":"stream","text":["type(waveform)=\n","waveform.shape=torch.Size([1, 480000])\n","waveform.dtype=torch.float32\n"]}],"source":["import torchaudio\n","waveform, sample_rate = torchaudio.load(AUDIO_FILE)\n","\n","print(f\"{type(waveform)=}\")\n","print(f\"{waveform.shape=}\")\n","print(f\"{waveform.dtype=}\")\n","\n","audio_in_memory = {\"waveform\": waveform, \"sample_rate\": sample_rate}"]},{"cell_type":"code","execution_count":13,"metadata":{"colab":{"base_uri":"https://localhost:8080/","height":657},"executionInfo":{"elapsed":1904,"status":"ok","timestamp":1704807149946,"user":{"displayName":"Clément PAGES","userId":"11757386314069785178"},"user_tz":-60},"id":"j2zi1CzHTIbR","outputId":"fb8ac3d0-c9f0-4b0a-c01f-a10612bdf254"},"outputs":[{"data":{"image/png":"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JspDAQAAAAAAWRC0AAAAAAAAsiBoAQAAAAAAZEHQAgAAAAAAyMJUQYtf/uVfjvve975xySWXxOMf//j467/+66bHBWTqx3/8x6MoinX/99CHPrTtYQEJveMd74jnPOc5ceDAgSiKIt70pjet+/2yLOPVr3513Ote94rdu3fH05/+9PjEJz7RzmCBJC50H3jRi1503vzgWc96VjuDBZL46Z/+6fjKr/zK2Lt3b1xzzTXx3Oc+Nz72sY+t+5577rknXvayl8WVV14Ze/bsiW/91m+Nz3/+8y2NGGjaxdwHnvrUp543J/in//SftjRioGmvfe1r48Ybb4yVlZVYWVmJJz7xifHmN7+5/v2m5gITBy1+93d/N37gB34gbrrppnjve98bj3rUo+KZz3xmfOELX5j45MBievjDHx633XZb/X/vfOc72x4SkNDx48fjUY96VPzyL//yhr//Mz/zM/GLv/iL8Su/8ivxV3/1V3HZZZfFM5/5zLjnnnvmPFIglQvdByIinvWsZ62bH7zhDW+Y4wiB1N7+9rfHy172svjLv/zL+NM//dM4c+ZMPOMZz4jjx4/X3/P93//98Yd/+IfxX//rf423v/3tcfjw4fiWb/mWFkcNNOli7gMRES95yUvWzQl+5md+pqURA0274YYb4t/8m38T73nPe+Ld7353PO1pT4tv+qZvig9/+MMR0dxcoCjLspzkBx7/+MfHV37lV8Yv/dIvRUTEcDiMgwcPxstf/vL44R/+4YkHACyWH//xH483velN8f73v7/toQAtKIoi3vjGN8Zzn/vciFjLsjhw4EC88pWvjB/8wR+MiIgjR47EtddeG6973evi+c9/foujBVI49z4QsZZpcffdd5+XgQEsry9+8YtxzTXXxNvf/vZ4ylOeEkeOHImrr746Xv/618fznve8iIj46Ec/Gg972MPiXe96VzzhCU9oecRA0869D0SsZVo8+tGPjp//+Z9vd3DA3Ozfvz9+9md/Np73vOc1NheYKNPi9OnT8Z73vCee/vSnnz1ApxNPf/rT413vetckhwIW2Cc+8Yk4cOBA3P/+949/+A//Ydx6661tDwloyac//em4/fbb180N9u3bF49//OPNDWCbedvb3hbXXHNNPOQhD4mXvvSlceedd7Y9JCChI0eORMTaQkVExHve8544c+bMujnBQx/60Lj3ve9t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","text/plain":[""]},"execution_count":13,"metadata":{},"output_type":"execute_result"}],"source":["output = inference(audio_in_memory)\n","output"]},{"cell_type":"markdown","metadata":{"id":"aB5QNx7lTIbS"},"source":["## Processing part of a file\n","\n","If needed, `Inference` can be used to process only part of a file:"]},{"cell_type":"code","execution_count":19,"metadata":{"id":"E0Pydt0VTIbT"},"outputs":[{"data":{"image/png":"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IQ95SFx11VUtrhpo0itf+cp4xzveEX/8x38ce/bsGfWmXl5ejl27dsXy8nK8/OUvj9e85jWxd+/eWFpaile96lVx5ZVXxpOf/OSWVw804Uz3gVtuuSXe8Y53xLd8y7fEeeedF5/85CfjB3/wB+NpT3taXH755S2vHmjC6173urj66qvj/ve/fxw+fDje8Y53xPXXXx/vec97Gv0sUFRVVW12cdddd138zM/8TNx+++3xmMc8Jt761reOyr2A+faCF7wgPvCBD8TBgwfjggsuiKc+9anxkz/5k3pTwhy7/vrr41/9q391r99/yUteEm9/+9ujqqq49tpr41d+5Vfirrvuiqc+9anxtre9LS677LIWVgukcLr7wC/90i/FNddcEx//+Mfjrrvuin379sWzn/3s+PEf//G48MILW1gtkEJRFKf8/V//9V+Pl770pRERcezYsXjta18bv/3bvx3Hjx+Pq666Kt72trdpDwVz4kz3gf3798eLXvSiuOmmm+LIkSOxsrIS/+7f/bt4/etfH0tLS1NeLZDCy1/+8njve98bt912WywvL8fll18eP/IjPxLf/M3fHBHNfRaYKLQAAAAAAABo2qZmWgAAAAAAAKQitAAAAAAAALIgtAAAAAAAALIgtAAAAAAAALIgtAAAAAAAALIgtAAAAAAAALIgtAAAAAAAALIgtAAAAAAAALIgtAAAAE7rpS99aVxzzTVtLwMAAFgAvbYXAAAAtKcoitP+82uvvTZ+4Rd+IaqqmtKKAACARSa0AACABXbbbbeNfv27v/u78YY3vCE+85nPjH5v9+7dsXv37jaWBgAALCDtoQAAYIFddNFFo/8tLy9HURQbfm/37t33ag/19Kc/PV71qlfFq1/96jj33HPjwgsvjF/91V+NI0eOxMte9rLYs2dPPOQhD4k/+7M/23Cum266Ka6++urYvXt3XHjhhfHiF7847rzzzin/iQEAgJwJLQAAgE37jd/4jTj//PPj7/7u7+JVr3pVfN/3fV98+7d/ezzlKU+Jj33sY/HsZz87XvziF8c999wTERF33XVXPOMZz4jHPvax8ZGPfCT+/M//PL74xS/Gd3zHd7T8JwEAAHIitAAAADbt0Y9+dLz+9a+Phz70ofG6170udu7cGeeff3684hWviIc+9KHxhje8IQ4ePBif/OQnIyLiuuuui8c+9rHxUz/1U/Hwhz88HvvYx8av/dqvxfve9774x3/8x5b/NAAAQC7MtAAAADbt8ssvH/262+3GeeedF4961KNGv3fhhRdGRMSXvvSliIj4xCc+Ee973/tOOR/jlltuicsuuyzxigEAgFkgtAAAADZt27ZtG/7/oig2/F5RFBERUZZlRETcfffd8dznPjf+03/6T/c61sUXX5xwpQAAwCwRWgAAAMk97nGPiz/8wz+MBz7wgdHr+c8QAADg1My0AAAAknvlK18ZX/7yl+OFL3xhfPjDH45bbrkl3vOe98TLXvayGAwGbS8PAADIhNACAABIbt++ffHBD34wBoNBPPvZz45HPepR8epXvzrOOeec6HT8ZwkAALCmqKqqansRAAAAAAAAHmkCAAAAAACyILQAAAAAAACyILQAAAAAAACyILQAAAAAAACyILQAAAAAAACyILQAAAAAAACyILQAAAAAAACyILQAAAAAAACyILQAAAAAAACyILQAAAAAAACyILQAAAAAAACy8P8DwJDOCD5+uAYAAAAASUVORK5CYII=","text/plain":[""]},"execution_count":19,"metadata":{},"output_type":"execute_result"}],"source":["from pyannote.core import Segment\n","output = inference.crop(audio_in_memory, Segment(0, 20))\n","output"]},{"cell_type":"markdown","metadata":{"id":"K_Z-ciLaTIbU"},"source":["## Offline use\n","\n","Gating models allows [me](https://herve.niderb.fr) to know a bit more about `pyannote.audio` user base and eventually help me write grant proposals to make `pyannote.audio` even better. Please fill this form as precisely as possible.\n","\n","For instance, before gating `pyannote/segmentation`, I had no idea that so many people were relying on it in production. Hint: sponsors are more than welcome! maintaining open source libraries is time consuming.\n","\n","That being said: this whole authentication process does not prevent you from using official `pyannote.audio` models offline (i.e. without going through the authentication process in every `docker run ...` or whatever you are using in production).\n","\n","* Step 1: download the `pytorch_model.bin` model\n","\n","![](assets/download-model.png)\n","\n","* Step 2: load the model"]},{"cell_type":"code","execution_count":null,"metadata":{"id":"t_kZgFSSTIbV"},"outputs":[],"source":["# look ma: no hands!\n","offline_model = Model.from_pretrained(\"pytorch_model.bin\")"]},{"cell_type":"code","execution_count":null,"metadata":{"id":"wBkIFwR-TIbV"},"outputs":[],"source":["# just checking weights are the same...\n","import torch\n","for weights, offline_weights in zip(model.parameters(), offline_model.parameters()):\n"," assert torch.equal(weights, offline_weights)"]}],"metadata":{"accelerator":"GPU","colab":{"gpuType":"T4","provenance":[]},"kernelspec":{"display_name":"Python 3","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.10.13"},"vscode":{"interpreter":{"hash":"36a3a48a52702f18671693adf589423ec3f7db45d50f6ee539f1b0696bb58d43"}},"widgets":{"application/vnd.jupyter.widget-state+json":{"01a79756e1104be0bcbe1d233677d605":{"model_module":"@jupyter-widgets/base","model_module_version":"1.2.0","model_name":"LayoutModel","state":{"_model_module":"@jupyter-widgets/base","_model_module_version":"1.2.0","_model_name":"LayoutModel","_view_count":null,"_view_module":"@jupyter-widgets/base","_view_module_version":"1.2.0","_view_name":"LayoutView","align_content":null,"align_items":null,"align_self":null,"border":null,"bottom":null,"display":null,"flex":null,"flex_flow":null,"grid_area":null,"grid_auto_columns":null,"grid_auto_flow":null,"grid_auto_rows":null,"grid_column":null,"grid_gap":null,"grid_row":null,"grid_template_areas":null,"grid_template_columns":null,"grid_template_rows":null,"height":null,"justify_content":null,"justify_items":null,"left":null,"margin":null,"max_height":null,"max_width":null,"min_height":null,"min_width":null,"object_fit":null,"object_position":null,"order":null,"overflow":null,"overflow_x":null,"overflow_y":null,"padding":null,"right":null,"top":null,"visibility":null,"width":null}},"09ee64808a5c431b928066a4cb287a78":{"model_module":"@jupyter-widgets/controls","model_module_version":"1.5.0","model_name":"DescriptionStyleModel","state":{"_model_module":"@jupyter-widgets/controls","_model_module_version":"1.5.0","_model_name":"DescriptionStyleModel","_view_count":null,"_view_module":"@jupyter-widgets/base","_view_module_version":"1.2.0","_view_name":"StyleView","description_width":""}},"0c537fef94bd4a3d8c42d981a70ea35b":{"model_module":"@jupyter-widgets/controls","model_module_version":"1.5.0","model_name":"HTMLModel","state":{"_dom_classes":[],"_model_module":"@jupyter-widgets/controls","_model_module_version":"1.5.0","_model_name":"HTMLModel","_view_count":null,"_view_module":"@jupyter-widgets/controls","_view_module_version":"1.5.0","_view_name":"HTMLView","description":"","description_tooltip":null,"layout":"IPY_MODEL_ecbb880cf0044404ab9bfc5995656807","placeholder":"​","style":"IPY_MODEL_79287ffea49a4e4a80191b1157de15cc","value":"\nPro Tip: If you don't already have one, you can create a dedicated\n'notebooks' token with 'write' access, that you can then easily reuse for all\nnotebooks.
"}},"0e04a45510f346b8ab3c465b10ccdfd2":{"model_module":"@jupyter-widgets/controls","model_module_version":"1.5.0","model_name":"LabelModel","state":{"_dom_classes":[],"_model_module":"@jupyter-widgets/controls","_model_module_version":"1.5.0","_model_name":"LabelModel","_view_count":null,"_view_module":"@jupyter-widgets/controls","_view_module_version":"1.5.0","_view_name":"LabelView","description":"","description_tooltip":null,"layout":"IPY_MODEL_bf5c88fe90f0462b95aa8a81467c1e9d","placeholder":"​","style":"IPY_MODEL_09ee64808a5c431b928066a4cb287a78","value":"Connecting..."}},"1a30ac8b519948bbad72886049b53d55":{"model_module":"@jupyter-widgets/controls","model_module_version":"1.5.0","model_name":"DescriptionStyleModel","state":{"_model_module":"@jupyter-widgets/controls","_model_module_version":"1.5.0","_model_name":"DescriptionStyleModel","_view_count":null,"_view_module":"@jupyter-widgets/base","_view_module_version":"1.2.0","_view_name":"StyleView","description_width":""}},"2b91f4b11d5848c0b6795b649bc2d7bc":{"model_module":"@jupyter-widgets/controls","model_module_version":"1.5.0","model_name":"LabelModel","state":{"_dom_classes":[],"_model_module":"@jupyter-widgets/controls","_model_module_version":"1.5.0","_model_name":"LabelModel","_view_count":null,"_view_module":"@jupyter-widgets/controls","_view_module_version":"1.5.0","_view_name":"LabelView","description":"","description_tooltip":null,"layout":"IPY_MODEL_57cf64e9c70e4057a76c2f3fb1e9b191","placeholder":"​","style":"IPY_MODEL_5e90e4818f1f43f2aa4714e0e40dc15d","value":"Your token has been saved to /root/.cache/huggingface/token"}},"2d1965df902b4b7eb6e4e28e44d6e32b":{"model_module":"@jupyter-widgets/controls","model_module_version":"1.5.0","model_name":"CheckboxModel","state":{"_dom_classes":[],"_model_module":"@jupyter-widgets/controls","_model_module_version":"1.5.0","_model_name":"CheckboxModel","_view_count":null,"_view_module":"@jupyter-widgets/controls","_view_module_version":"1.5.0","_view_name":"CheckboxView","description":"Add token as git credential?","description_tooltip":null,"disabled":false,"indent":true,"layout":"IPY_MODEL_416ffb7703b1404ab1c19c6b1ecafb4c","style":"IPY_MODEL_5be7421c575d41128d0675dc9abbc196","value":true}},"416ffb7703b1404ab1c19c6b1ecafb4c":{"model_module":"@jupyter-widgets/base","model_module_version":"1.2.0","model_name":"LayoutModel","state":{"_model_module":"@jupyter-widgets/base","_model_module_version":"1.2.0","_model_name":"LayoutModel","_view_count":null,"_view_module":"@jupyter-widgets/base","_view_module_version":"1.2.0","_view_name":"LayoutView","align_content":null,"align_items":null,"align_self":null,"border":null,"bottom":null,"display":null,"flex":null,"flex_flow":null,"grid_area":null,"grid_auto_columns":null,"grid_auto_flow":null,"grid_auto_rows":null,"grid_column":null,"grid_gap":null,"grid_row":null,"grid_template_areas":null,"grid_template_columns":null,"grid_template_rows":null,"height":null,"justify_content":null,"justify_items":null,"left":null,"margin":null,"max_height":null,"max_width":null,"min_height":null,"min_width":null,"object_fit":null,"object_position":null,"order":null,"overflow":null,"overflow_x":null,"overflow_y":null,"padding":null,"right":null,"top":null,"visibility":null,"width":null}},"47da80658de14604a7cc5268b951c172":{"model_module":"@jupyter-widgets/base","model_module_version":"1.2.0","model_name":"LayoutModel","state":{"_model_module":"@jupyter-widgets/base","_model_module_version":"1.2.0","_model_name":"LayoutModel","_view_count":null,"_view_module":"@jupyter-widgets/base","_view_module_version":"1.2.0","_view_name":"LayoutView","align_content":null,"align_items":null,"align_self":null,"border":null,"bottom":null,"display":null,"flex":null,"flex_flow":null,"grid_area":null,"grid_auto_columns":null,"grid_auto_flow":null,"grid_auto_rows":null,"grid_column":null,"grid_gap":null,"grid_row":null,"grid_template_areas":null,"grid_template_columns":null,"grid_template_rows":null,"height":null,"justify_content":null,"justify_items":null,"left":null,"margin":null,"max_height":null,"max_width":null,"min_height":null,"min_width":null,"object_fit":null,"object_position":null,"order":null,"overflow":null,"overflow_x":null,"overflow_y":null,"padding":null,"right":null,"top":null,"visibility":null,"width":null}},"49cb317b141a43b7b8ce342e2d62ab03":{"model_module":"@jupyter-widgets/base","model_module_version":"1.2.0","model_name":"LayoutModel","state":{"_model_module":"@jupyter-widgets/base","_model_module_version":"1.2.0","_model_name":"LayoutModel","_view_count":null,"_view_module":"@jupyter-widgets/base","_view_module_version":"1.2.0","_view_name":"LayoutView","align_content":null,"align_items":null,"align_self":null,"border":null,"bottom":null,"display":null,"flex":null,"flex_flow":null,"grid_area":null,"grid_auto_columns":null,"grid_auto_flow":null,"grid_auto_rows":null,"grid_column":null,"grid_gap":null,"grid_row":null,"grid_template_areas":null,"grid_template_columns":null,"grid_template_rows":null,"height":null,"justify_content":null,"justify_items":null,"left":null,"margin":null,"max_height":null,"max_width":null,"min_height":null,"min_width":null,"object_fit":null,"object_position":null,"order":null,"overflow":null,"overflow_x":null,"overflow_y":null,"padding":null,"right":null,"top":null,"visibility":null,"width":null}},"52a4a1aab39741f2a0499428f07a4c25":{"model_module":"@jupyter-widgets/controls","model_module_version":"1.5.0","model_name":"LabelModel","state":{"_dom_classes":[],"_model_module":"@jupyter-widgets/controls","_model_module_version":"1.5.0","_model_name":"LabelModel","_view_count":null,"_view_module":"@jupyter-widgets/controls","_view_module_version":"1.5.0","_view_name":"LabelView","description":"","description_tooltip":null,"layout":"IPY_MODEL_01a79756e1104be0bcbe1d233677d605","placeholder":"​","style":"IPY_MODEL_990375a830eb4cd79c69ad78b9ac685b","value":"Token is valid (permission: write)."}},"53919e13e42441d9b8cf5eb4f2effe96":{"model_module":"@jupyter-widgets/controls","model_module_version":"1.5.0","model_name":"DescriptionStyleModel","state":{"_model_module":"@jupyter-widgets/controls","_model_module_version":"1.5.0","_model_name":"DescriptionStyleModel","_view_count":null,"_view_module":"@jupyter-widgets/base","_view_module_version":"1.2.0","_view_name":"StyleView","description_width":""}},"57cf64e9c70e4057a76c2f3fb1e9b191":{"model_module":"@jupyter-widgets/base","model_module_version":"1.2.0","model_name":"LayoutModel","state":{"_model_module":"@jupyter-widgets/base","_model_module_version":"1.2.0","_model_name":"LayoutModel","_view_count":null,"_view_module":"@jupyter-widgets/base","_view_module_version":"1.2.0","_view_name":"LayoutView","align_content":null,"align_items":null,"align_self":null,"border":null,"bottom":null,"display":null,"flex":null,"flex_flow":null,"grid_area":null,"grid_auto_columns":null,"grid_auto_flow":null,"grid_auto_rows":null,"grid_column":null,"grid_gap":null,"grid_row":null,"grid_template_areas":null,"grid_template_columns":null,"grid_template_rows":null,"height":null,"justify_content":null,"justify_items":null,"left":null,"margin":null,"max_height":null,"max_width":null,"min_height":null,"min_width":null,"object_fit":null,"object_position":null,"order":null,"overflow":null,"overflow_x":null,"overflow_y":null,"padding":null,"right":null,"top":null,"visibility":null,"width":null}},"5be7421c575d41128d0675dc9abbc196":{"model_module":"@jupyter-widgets/controls","model_module_version":"1.5.0","model_name":"DescriptionStyleModel","state":{"_model_module":"@jupyter-widgets/controls","_model_module_version":"1.5.0","_model_name":"DescriptionStyleModel","_view_count":null,"_view_module":"@jupyter-widgets/base","_view_module_version":"1.2.0","_view_name":"StyleView","description_width":""}},"5e90e4818f1f43f2aa4714e0e40dc15d":{"model_module":"@jupyter-widgets/controls","model_module_version":"1.5.0","model_name":"DescriptionStyleModel","state":{"_model_module":"@jupyter-widgets/controls","_model_module_version":"1.5.0","_model_name":"DescriptionStyleModel","_view_count":null,"_view_module":"@jupyter-widgets/base","_view_module_version":"1.2.0","_view_name":"StyleView","description_width":""}},"73915caf6d1042ca9a27853986217ae2":{"model_module":"@jupyter-widgets/controls","model_module_version":"1.5.0","model_name":"PasswordModel","state":{"_dom_classes":[],"_model_module":"@jupyter-widgets/controls","_model_module_version":"1.5.0","_model_name":"PasswordModel","_view_count":null,"_view_module":"@jupyter-widgets/controls","_view_module_version":"1.5.0","_view_name":"PasswordView","continuous_update":true,"description":"Token:","description_tooltip":null,"disabled":false,"layout":"IPY_MODEL_47da80658de14604a7cc5268b951c172","placeholder":"​","style":"IPY_MODEL_c7fbfffbbc304f0ba025e03beb8f638a","value":""}},"79287ffea49a4e4a80191b1157de15cc":{"model_module":"@jupyter-widgets/controls","model_module_version":"1.5.0","model_name":"DescriptionStyleModel","state":{"_model_module":"@jupyter-widgets/controls","_model_module_version":"1.5.0","_model_name":"DescriptionStyleModel","_view_count":null,"_view_module":"@jupyter-widgets/base","_view_module_version":"1.2.0","_view_name":"StyleView","description_width":""}},"79d55946b3764666a0b57a72722f6c19":{"model_module":"@jupyter-widgets/base","model_module_version":"1.2.0","model_name":"LayoutModel","state":{"_model_module":"@jupyter-widgets/base","_model_module_version":"1.2.0","_model_name":"LayoutModel","_view_count":null,"_view_module":"@jupyter-widgets/base","_view_module_version":"1.2.0","_view_name":"LayoutView","align_content":null,"align_items":"center","align_self":null,"border":null,"bottom":null,"display":"flex","flex":null,"flex_flow":"column","grid_area":null,"grid_auto_columns":null,"grid_auto_flow":null,"grid_auto_rows":null,"grid_column":null,"grid_gap":null,"grid_row":null,"grid_template_areas":null,"grid_template_columns":null,"grid_template_rows":null,"height":null,"justify_content":null,"justify_items":null,"left":null,"margin":null,"max_height":null,"max_width":null,"min_height":null,"min_width":null,"object_fit":null,"object_position":null,"order":null,"overflow":null,"overflow_x":null,"overflow_y":null,"padding":null,"right":null,"top":null,"visibility":null,"width":"50%"}},"8b3353af24074ce5b5d2d9b162c61062":{"model_module":"@jupyter-widgets/base","model_module_version":"1.2.0","model_name":"LayoutModel","state":{"_model_module":"@jupyter-widgets/base","_model_module_version":"1.2.0","_model_name":"LayoutModel","_view_count":null,"_view_module":"@jupyter-widgets/base","_view_module_version":"1.2.0","_view_name":"LayoutView","align_content":null,"align_items":null,"align_self":null,"border":null,"bottom":null,"display":null,"flex":null,"flex_flow":null,"grid_area":null,"grid_auto_columns":null,"grid_auto_flow":null,"grid_auto_rows":null,"grid_column":null,"grid_gap":null,"grid_row":null,"grid_template_areas":null,"grid_template_columns":null,"grid_template_rows":null,"height":null,"justify_content":null,"justify_items":null,"left":null,"margin":null,"max_height":null,"max_width":null,"min_height":null,"min_width":null,"object_fit":null,"object_position":null,"order":null,"overflow":null,"overflow_x":null,"overflow_y":null,"padding":null,"right":null,"top":null,"visibility":null,"width":null}},"988c83c85f7d44d0be949de6eedcf977":{"model_module":"@jupyter-widgets/base","model_module_version":"1.2.0","model_name":"LayoutModel","state":{"_model_module":"@jupyter-widgets/base","_model_module_version":"1.2.0","_model_name":"LayoutModel","_view_count":null,"_view_module":"@jupyter-widgets/base","_view_module_version":"1.2.0","_view_name":"LayoutView","align_content":null,"align_items":null,"align_self":null,"border":null,"bottom":null,"display":null,"flex":null,"flex_flow":null,"grid_area":null,"grid_auto_columns":null,"grid_auto_flow":null,"grid_auto_rows":null,"grid_column":null,"grid_gap":null,"grid_row":null,"grid_template_areas":null,"grid_template_columns":null,"grid_template_rows":null,"height":null,"justify_content":null,"justify_items":null,"left":null,"margin":null,"max_height":null,"max_width":null,"min_height":null,"min_width":null,"object_fit":null,"object_position":null,"order":null,"overflow":null,"overflow_x":null,"overflow_y":null,"padding":null,"right":null,"top":null,"visibility":null,"width":null}},"990375a830eb4cd79c69ad78b9ac685b":{"model_module":"@jupyter-widgets/controls","model_module_version":"1.5.0","model_name":"DescriptionStyleModel","state":{"_model_module":"@jupyter-widgets/controls","_model_module_version":"1.5.0","_model_name":"DescriptionStyleModel","_view_count":null,"_view_module":"@jupyter-widgets/base","_view_module_version":"1.2.0","_view_name":"StyleView","description_width":""}},"a73cecb8608f491e8f996c5114df4d0f":{"model_module":"@jupyter-widgets/controls","model_module_version":"1.5.0","model_name":"VBoxModel","state":{"_dom_classes":[],"_model_module":"@jupyter-widgets/controls","_model_module_version":"1.5.0","_model_name":"VBoxModel","_view_count":null,"_view_module":"@jupyter-widgets/controls","_view_module_version":"1.5.0","_view_name":"VBoxView","box_style":"","children":["IPY_MODEL_52a4a1aab39741f2a0499428f07a4c25","IPY_MODEL_f23cc133109c4ecb9b383f118bcc71aa","IPY_MODEL_2b91f4b11d5848c0b6795b649bc2d7bc","IPY_MODEL_b437981acb894f97ad45daaebe2734c7"],"layout":"IPY_MODEL_79d55946b3764666a0b57a72722f6c19"}},"abc23089f4ef4d2a9f8a104fb1dba14a":{"model_module":"@jupyter-widgets/controls","model_module_version":"1.5.0","model_name":"DescriptionStyleModel","state":{"_model_module":"@jupyter-widgets/controls","_model_module_version":"1.5.0","_model_name":"DescriptionStyleModel","_view_count":null,"_view_module":"@jupyter-widgets/base","_view_module_version":"1.2.0","_view_name":"StyleView","description_width":""}},"b2e03b10050d46548932f429bcc18d81":{"model_module":"@jupyter-widgets/controls","model_module_version":"1.5.0","model_name":"ButtonModel","state":{"_dom_classes":[],"_model_module":"@jupyter-widgets/controls","_model_module_version":"1.5.0","_model_name":"ButtonModel","_view_count":null,"_view_module":"@jupyter-widgets/controls","_view_module_version":"1.5.0","_view_name":"ButtonView","button_style":"","description":"Login","disabled":false,"icon":"","layout":"IPY_MODEL_8b3353af24074ce5b5d2d9b162c61062","style":"IPY_MODEL_cd40e31c191044b7a0f8fa4694ad6380","tooltip":""}},"b437981acb894f97ad45daaebe2734c7":{"model_module":"@jupyter-widgets/controls","model_module_version":"1.5.0","model_name":"LabelModel","state":{"_dom_classes":[],"_model_module":"@jupyter-widgets/controls","_model_module_version":"1.5.0","_model_name":"LabelModel","_view_count":null,"_view_module":"@jupyter-widgets/controls","_view_module_version":"1.5.0","_view_name":"LabelView","description":"","description_tooltip":null,"layout":"IPY_MODEL_fb027db34fd740c2a4758d650ae3f73c","placeholder":"​","style":"IPY_MODEL_1a30ac8b519948bbad72886049b53d55","value":"Login successful"}},"bc10c6804346449b8e349728a1acb8d2":{"model_module":"@jupyter-widgets/controls","model_module_version":"1.5.0","model_name":"HTMLModel","state":{"_dom_classes":[],"_model_module":"@jupyter-widgets/controls","_model_module_version":"1.5.0","_model_name":"HTMLModel","_view_count":null,"_view_module":"@jupyter-widgets/controls","_view_module_version":"1.5.0","_view_name":"HTMLView","description":"","description_tooltip":null,"layout":"IPY_MODEL_988c83c85f7d44d0be949de6eedcf977","placeholder":"​","style":"IPY_MODEL_53919e13e42441d9b8cf5eb4f2effe96","value":"

Copy a token from your Hugging Face\ntokens page and paste it below.
Immediately click login after copying\nyour token or it might be stored in plain text in this notebook file.
"}},"bf5c88fe90f0462b95aa8a81467c1e9d":{"model_module":"@jupyter-widgets/base","model_module_version":"1.2.0","model_name":"LayoutModel","state":{"_model_module":"@jupyter-widgets/base","_model_module_version":"1.2.0","_model_name":"LayoutModel","_view_count":null,"_view_module":"@jupyter-widgets/base","_view_module_version":"1.2.0","_view_name":"LayoutView","align_content":null,"align_items":null,"align_self":null,"border":null,"bottom":null,"display":null,"flex":null,"flex_flow":null,"grid_area":null,"grid_auto_columns":null,"grid_auto_flow":null,"grid_auto_rows":null,"grid_column":null,"grid_gap":null,"grid_row":null,"grid_template_areas":null,"grid_template_columns":null,"grid_template_rows":null,"height":null,"justify_content":null,"justify_items":null,"left":null,"margin":null,"max_height":null,"max_width":null,"min_height":null,"min_width":null,"object_fit":null,"object_position":null,"order":null,"overflow":null,"overflow_x":null,"overflow_y":null,"padding":null,"right":null,"top":null,"visibility":null,"width":null}},"c7fbfffbbc304f0ba025e03beb8f638a":{"model_module":"@jupyter-widgets/controls","model_module_version":"1.5.0","model_name":"DescriptionStyleModel","state":{"_model_module":"@jupyter-widgets/controls","_model_module_version":"1.5.0","_model_name":"DescriptionStyleModel","_view_count":null,"_view_module":"@jupyter-widgets/base","_view_module_version":"1.2.0","_view_name":"StyleView","description_width":""}},"cd40e31c191044b7a0f8fa4694ad6380":{"model_module":"@jupyter-widgets/controls","model_module_version":"1.5.0","model_name":"ButtonStyleModel","state":{"_model_module":"@jupyter-widgets/controls","_model_module_version":"1.5.0","_model_name":"ButtonStyleModel","_view_count":null,"_view_module":"@jupyter-widgets/base","_view_module_version":"1.2.0","_view_name":"StyleView","button_color":null,"font_weight":""}},"ecbb880cf0044404ab9bfc5995656807":{"model_module":"@jupyter-widgets/base","model_module_version":"1.2.0","model_name":"LayoutModel","state":{"_model_module":"@jupyter-widgets/base","_model_module_version":"1.2.0","_model_name":"LayoutModel","_view_count":null,"_view_module":"@jupyter-widgets/base","_view_module_version":"1.2.0","_view_name":"LayoutView","align_content":null,"align_items":null,"align_self":null,"border":null,"bottom":null,"display":null,"flex":null,"flex_flow":null,"grid_area":null,"grid_auto_columns":null,"grid_auto_flow":null,"grid_auto_rows":null,"grid_column":null,"grid_gap":null,"grid_row":null,"grid_template_areas":null,"grid_template_columns":null,"grid_template_rows":null,"height":null,"justify_content":null,"justify_items":null,"left":null,"margin":null,"max_height":null,"max_width":null,"min_height":null,"min_width":null,"object_fit":null,"object_position":null,"order":null,"overflow":null,"overflow_x":null,"overflow_y":null,"padding":null,"right":null,"top":null,"visibility":null,"width":null}},"f23cc133109c4ecb9b383f118bcc71aa":{"model_module":"@jupyter-widgets/controls","model_module_version":"1.5.0","model_name":"LabelModel","state":{"_dom_classes":[],"_model_module":"@jupyter-widgets/controls","_model_module_version":"1.5.0","_model_name":"LabelModel","_view_count":null,"_view_module":"@jupyter-widgets/controls","_view_module_version":"1.5.0","_view_name":"LabelView","description":"","description_tooltip":null,"layout":"IPY_MODEL_49cb317b141a43b7b8ce342e2d62ab03","placeholder":"​","style":"IPY_MODEL_abc23089f4ef4d2a9f8a104fb1dba14a","value":"Your token has been saved in your configured git credential helpers (store)."}},"fb027db34fd740c2a4758d650ae3f73c":{"model_module":"@jupyter-widgets/base","model_module_version":"1.2.0","model_name":"LayoutModel","state":{"_model_module":"@jupyter-widgets/base","_model_module_version":"1.2.0","_model_name":"LayoutModel","_view_count":null,"_view_module":"@jupyter-widgets/base","_view_module_version":"1.2.0","_view_name":"LayoutView","align_content":null,"align_items":null,"align_self":null,"border":null,"bottom":null,"display":null,"flex":null,"flex_flow":null,"grid_area":null,"grid_auto_columns":null,"grid_auto_flow":null,"grid_auto_rows":null,"grid_column":null,"grid_gap":null,"grid_row":null,"grid_template_areas":null,"grid_template_columns":null,"grid_template_rows":null,"height":null,"justify_content":null,"justify_items":null,"left":null,"margin":null,"max_height":null,"max_width":null,"min_height":null,"min_width":null,"object_fit":null,"object_position":null,"order":null,"overflow":null,"overflow_x":null,"overflow_y":null,"padding":null,"right":null,"top":null,"visibility":null,"width":null}}}}},"nbformat":4,"nbformat_minor":0} diff --git a/tutorials/applying_a_pipeline.ipynb b/tutorials/applying_a_pipeline.ipynb index c1080071d..945caab4e 100644 --- a/tutorials/applying_a_pipeline.ipynb +++ b/tutorials/applying_a_pipeline.ipynb @@ -1,400 +1 @@ -{ - "cells": [ - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "# Applying a pretrained pipeline\n", - "\n", - "In this tutorial, you will learn how to apply `pyannote.audio` pipelines on an audio file.\n", - "\n", - "A pipeline takes an audio file as input and returns a labeled temporal segmentation of the audio file. \n", - "\n", - "More precisely, it usually applies a pretrained model (= neural network) on the audio file, post-processes the output of the model, and returns its output as a [`pyannote.core.Annotation`](http://pyannote.github.io/pyannote-core/structure.html#annotation) instance. It should become clearer as you keep reading..." - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "## Loading pipeline from 🤗 hub\n", - "\n", - "A bunch of pretrained pipelines are available on [🤗 Huggingface model hub](https://hf.co/models?other=pyannote-audio-pipeline) and can be listed by looking for the [`pyannote-audio-pipeline`](https://hf.co/models?other=pyannote-audio-pipeline) tag." - ] - }, - { - "cell_type": "code", - "execution_count": 4, - "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": [ - "['pyannote/overlapped-speech-detection',\n", - " 'pyannote/speaker-diarization',\n", - " 'pyannote/speaker-segmentation',\n", - " 'pyannote/voice-activity-detection']" - ] - }, - "execution_count": 4, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "from huggingface_hub import HfApi\n", - "available_pipelines = [p.modelId for p in HfApi().list_models(filter=\"pyannote-audio-pipeline\")]\n", - "list(filter(lambda p: p.startswith(\"pyannote/\"), available_pipelines))" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "Official [pyannote.audio](https://github.com/pyannote/pyannote-audio) pipelines (i.e. those under the [`pyannote` organization](https://hf.co/pyannote) umbrella) are open-source, but gated. It means that you have to first accept users conditions on their respective Huggingface page to access the pretrained weights and hyper-parameters. Despite this initial process, those pipelines can perfectly be downloaded for later offline use: keep reading this tutorial until the end to learn how to do that.\n", - "\n", - "For instance, to load the speaker diarization pipeline used in this tutorial, you have to visit [hf.co/pyannote/speaker-diarization](https://hf.co/pyannote/speaker-diarization), accept the terms, visit [hf.co/pyannote/segmentation](https://hf.co/pyannote/segmentation) (used internally by the speaker diarization pipeline), accept the terms, and log in using `notebook_login` below:" - ] - }, - { - "cell_type": "code", - "execution_count": 2, - "metadata": {}, - "outputs": [ - { - "data": { - "application/vnd.jupyter.widget-view+json": { - "model_id": "9466934e67254fe6a7ff67b727a3f3ab", - "version_major": 2, - "version_minor": 0 - }, - "text/plain": [ - "VBox(children=(HTML(value='
" - ] - }, - "execution_count": 9, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "# we visualize [0, 30] time range\n", - "from pyannote.core import notebook, Segment\n", - "notebook.crop = Segment(0, 30)\n", - "dia" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "When available, the reference annotation can be visualized too, for comparison:" - ] - }, - { - "cell_type": "code", - "execution_count": 10, - "metadata": {}, - "outputs": [ - { - "data": { - "image/png": "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lltuiSlTpkRExA033BBTpkyJjh07Rq9eveq8sdqmTZs444wzjtj+Aw88EAcPHozTTjutZluWZdG2bdvYuXNndO3atWb77NmzY+jQoXH11VdHlmU1P9T833r27HnU/iIiBgwYEF26dImzzjor3n333bjsssviL3/5yxE/Yf/h9j/8yffKysqaT8h37949ioqKjnpMU+v58vqC9NtQxlrd9o93HF1//fWxbNmyWLVqVfTp0+eYbQMAAAAALUPev3nRtVO7Jr3ky+DBg2Pfvn0117t37x5nnHFG9O7du8HfLDh48GAsXLgw7r777lqfXv/zn/8c/fv3j4cffrjObb73ve/FbbfdFldffXVePmF+7bXXxuHDh+P+++8/ruNHjRoVy5cvr7Xtt7/9bZx//vkREdGuXbsYPnx4nWOWL19ec0xTKyovb9JLvhhrRx9rEe+HLzNmzIhHH300nn766RgwYMBJ1wkAAAAANB95/+ZF6qqqquKLX/xiTJ06NYYOHRolJSWxdu3auOuuu2LChAnH3U6WZfWeo7+ioiJ+9atfxc6dO+OrX/1qlJWV1dr/hS98IR544IGYMWNGndveeOONUVRUVPNm8NVXX12zb9euXXX6KykpiU6dOtVbX5s2bWLmzJlx++23x3XXXRcdO3Y86v355je/GRdeeGHceeedMWHChHj88cfjd7/7XaxZs6bmmFmzZsW1114bI0aMiFGjRsVPf/rT2Lx5c0ybNu2obbdWxlr9jmesTZ8+PX7xi1/E448/HiUlJTX1lJWVRYcOHY7aPgAAAADQAmStzLvvvpvdeOON2bBhw7KysrKsY8eO2cCBA7Pvfe972dtvv51lWZb1798/u/fee4/Yxvz587OIqPfy1ltvZZ///Oezz372s/Xedt26dVlEZOvWrctee+21LCKyl156qdYxd999d1ZUVJQtXLgwy7LsiH3NnTs3y7Ise+aZZ7KIyHbu3Fmrnb1792Zdu3bN7rzzzuN6bH75y19mAwcOzNq2bZudffbZ2ZIlS+oc8+Mf/zjr379/1q5du2zYsGHZypUrj6vt1shYO7JjjbUj1TF//vzjah8AAAAAaN5yWZZljRuPAAAAAAAAHL+8/+YFAAAAAADAyRBetBKdO3c+4mX16tWFLo8WxFgDAAAAAE6W00a1Eps2bTrivtNOO82PIJM3xhoAAAAAcLKEFwAAAAAAQFKcNgoAAAAAAEiK8AIAAAAAAEjKKSd6w8OHD8ebb74ZJSUlkcvl8lkTAAAAAADQzGRZFtXV1dG7d+9o0+bkvjtxwuHFm2++GX379j2pzgEAAAAAgJZly5Yt0adPn5Nq44TDi5KSkpoiSktLT6oIAAAAAACgeduzZ0/07du3Jj84GSccXnxwqqjS0lLhBQAAAAAAEBGRl5+a8IPdAAAAAABAUoQXAAAAAABAUoQXAAAAAABAUoQXAAAAAABAUoQXAAAAAABAUoQXAAAAAABAUoQXAAAAAABAUoQXAAAAAABAUoQXAAAAAABAUoQXAAAAAABAUoQXAAAAAABAUoQXAAAAAABAUoQXAAAAAABAUoQXAAAAAABAUoQXAAAAAABAUoQXAAAAAABAUoQXAAAAAABAUoQXAAAAAABAUoQXAAAAAABAUoQXAAAAAABAUoQXAAAAAABAUoQXAAAAAABAUoQXAAAAAABAUoQXAAAAAABAUoQXAAAAAABAUoQXAAAAAABAUoQXAAAAAABAUoQXAAAAAABAUoQXAAAAAABAUoQXAAAAAABAUoQXAAAAAABAUoQXAAAAAABAUoQXAAAAAABAUoQXAAAAAABAUoQXAAAAAABAUoQXAAAAAABAUoQXAAAAAABAUoQXAAAAAABAUoQXAAAAAABAUoQXAAAAAABAUoQXAIk6tG1b7Ln7nji0bVuzaHdH9f742TObYkf1/ry2m0/NocbUtZbHsLXcT1o+Y5nm7khjuLHWM9CUTmYcm98BGp+5tvCEFwCJOlRZGdX33BuHKiubRbs7qvfHAyv+mfR/6s2hxtS1lsewtdxPWj5jmebuSGO4sdYz0JROZhyb3wEan7m28IQXAAAAAABAUoQXAAAAAABAUoQXAAAAAABAUk4pdAEAHN3hXbvjUFVVXttrTNXvvBc79x1o1D5OVPU77xW6hBYj5ec5H4wVWpqW/pql5TrWfJzvdRI0pXysy83vAI3H34WFJ7wASFzVlVcVuoQGuX7h2kKXQBPwPEPz4jVLS9Xc1kmQb+Z3AFoyp40CAAAAAACSIrwAAAAAAACSIrwAAAAAAACS4jcvABJXvuiRaDt4UN7ae++VvzXq+aH/7ysj4oyeJY3W/snYtLXaeYHzJOXnOR+MFVqalv6apeU61nyc73USNKV8rMvN7wCNx9+FhSe8AEhcmy5lUVRenrf2DnUpy1tb9Snp0Da6dmrXqH2cqJIObQtdQouR8vOcD8YKLU1Lf83Sch1rPs73OgmaUj7W5eZ3gMbj78LCc9ooAAAAAAAgKcILAAAAAAAgKcILAAAAAAAgKcILAAAAAAAgKcILgEQVVVREyaz/iaKKimbRbveS4vjqRadH95LivLabT82hxtS1lsewtdxPWj5jmebuSGO4sdYz0JROZhyb3wEan7m28HJZlmUncsM9e/ZEWVlZ7N69O0pLS/NdFwAAAAAA0IzkMzfwzQsAAAAAACApwgsAAAAAACApwgsAAAAAACApwgsAAAAAACApwgsAAAAAACApwgsAAAAAACApwgsAAAAAACApwgsAAAAAACApwgsAAAAAACApwgsAAAAAACApwgsAAAAAACApwgsAAAAAACApwgsAAAAAACApwgsAAAAAACApwgsAAAAAACApwgsAAAAAACApwgsAAAAAACApwgsAAAAAACApwgsAAAAAACApwgsAAAAAACApwgsAAAAAACApwgsAAAAAACApwgsAAAAAACApwgsAAAAAACApwgsAAAAAACApwgsAAAAAACApwgsAAAAAACApwgsAAAAAACApwgsAAAAAACApwgsAAAAAACApwgsAAAAAACApwgsAAAAAACApwgsAAAAAACApwgsAAAAAACApwgsAWoVD27bFnrvviUPbthW6lBapqR9fzyfkl9cULcWO6v3xs2c2xY7q/c2iXQCgftanzdehysq8tSW8AKBVOFRZGdX33JvX/0T5j6Z+fD2fkF9eU7QUO6r3xwMr/tko4UVjtAsA1M/6tPk6tH173toSXgAAAAAAAEkRXgAAAAAAAEk5pdAFAEBTOrxrdxyqqip0GS3O4V27C9av5xNOXqFew9BYqt95L3buO5DX9gCApudvvubn8O49eWtLeAFAq1J15VWFLoE88nwCUJ/rF64tdAkAQB74m6/5qT58OG9tOW0UAAAAAACQFOEFAAAAAACQFOEFAAAAAACQFL95AUCrUr7okWg7eFChy2hx3nvlbwU5F6nnE/KjUK9haCz/95URcUbPkry1t2lrtd/RAIAC8Ddf89P2xbUR48flpS3hBQCtSpsuZVFUXl7oMlqcQ13KCtKv5xPyo1CvYWgsJR3aRtdO7fLaHgDQ9PzN1/y0KSvNX1t5awkAAAAAACAP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", - "text/plain": [ - "" - ] - }, - "execution_count": 10, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "from pyannote.database.util import load_rttm\n", - "REFERENCE = f\"{ROOT_DIR}/tutorials/assets/sample.rttm\"\n", - "reference = load_rttm(REFERENCE)[\"sample\"]\n", - "\n", - "# map hypothesized and reference speakers for visualization purposes\n", - "pipeline.optimal_mapping(dia, reference)" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "## Processing a file from memory\n", - "\n", - "In case the audio file is not stored on disk, pipelines can also process audio provided as a `{\"waveform\": ..., \"sample_rate\": ...}` dictionary. " - ] - }, - { - "cell_type": "code", - "execution_count": 11, - "metadata": {}, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "type(waveform)=\n", - "waveform.shape=torch.Size([1, 480000])\n", - "waveform.dtype=torch.float32\n" - ] - } - ], - "source": [ - "import torchaudio\n", - "waveform, sample_rate = torchaudio.load(AUDIO_FILE)\n", - "\n", - "print(f\"{type(waveform)=}\")\n", - "print(f\"{waveform.shape=}\")\n", - "print(f\"{waveform.dtype=}\")\n", - "\n", - "audio_in_memory = {\"waveform\": waveform, \"sample_rate\": sample_rate}" - ] - }, - { - "cell_type": "code", - "execution_count": 12, - "metadata": {}, - "outputs": [ - { - "data": { - "image/png": "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bPHixalUKu2+mpqaunpZQCdat25dzjzzzIwcOTKVSiWrVq1qd321Ws3ixYszcuTIDBw4MKeddlr+8pe/dM1igU7zVnvB3Llz95kRTj755K5ZLFBzS5Ysyfvf//7U1dVl2LBhmTlzZh566KF2tzETQM/3dvYCMwH0bMuWLctxxx2X+vr61NfXZ9KkSfntb3/bdn2t5oEOx4uVK1dm4cKF+epXv5r7778/H/7whzN9+vRs3ry5w3cOdF/HHHNMtm7d2va1adOmrl4S0In27NmT448/Ptdcc80bXr906dJcffXVueaaa3LvvfemqakpU6ZMybPPPvsOrxToTG+1FyTJtGnT2s0It9566zu4QqAzrV27NhdccEHuueee3H777XnppZcyderU7Nmzp+02ZgLo+d7OXpCYCaAnGzVqVL71rW9lw4YN2bBhQ04//fTMmDGjLVDUah6oVKvVakd+YOLEiTnhhBOybNmytmPjx4/PzJkzs2TJkg7dOdA9LV68OKtWrcrGjRu7eilAF6hUKrn55pszc+bMJK/+RcXIkSOzcOHCXHrppUmS1tbWDB8+PN/+9rdz/vnnd+Fqgc7y+r0gefWvLHft2rXPKzKAnumf//xnhg0blrVr1+YjH/mImQB6qdfvBYmZAHqjxsbGfOc738m8efNqNg906JUXL7zwQu67775MnTq13fGpU6fmrrvu6sipgG7u4YcfzsiRIzN27Nh8+tOfzt///veuXhLQRR577LFs27at3XzQv3//nHrqqeYD6IXWrFmTYcOG5aijjsr8+fOzffv2rl4S0El2796d5NVfViRmAuitXr8XvMZMAL3Dyy+/nBUrVmTPnj2ZNGlSTeeBDsWLHTt25OWXX87w4cPbHR8+fHi2bdvWoTsGuq+JEyfmhhtuyG233Zaf/OQn2bZtW0455ZTs3Lmzq5cGdIHXZgDzATB9+vTceOONueOOO/Ld73439957b04//fS0trZ29dKAGqtWq7nooovyoQ99KBMmTEhiJoDe6I32gsRMAL3Bpk2bMnjw4PTv3z8LFizIzTffnKOPPrqm80Df/VlYpVJpd7lare5zDOi5pk+f3vb9sccem0mTJuXwww/P9ddfn4suuqgLVwZ0JfMBMHv27LbvJ0yYkJNOOiljxozJb37zm5x11llduDKg1i688MI88MADufPOO/e5zkwAvcd/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", - "text/plain": [ - "" - ] - }, - "execution_count": 12, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "vad = Pipeline.from_pretrained(\"pyannote/voice-activity-detection\", use_auth_token=True)\n", - "vad(audio_in_memory)" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "## Offline use\n", - "\n", - "Gating models and pipelines allows [me](https://herve.niderb.fr) to know a bit more about `pyannote.audio` user base and eventually help me write grant proposals to make `pyannote.audio` even better. Please fill this form as precisely as possible. \n", - "\n", - "For instance, before gating `pyannote/speaker-diarization`, I had no idea that so many people were relying on it in production. Hint: sponsors are more than welcome! maintaining open source libraries is time consuming.\n", - "\n", - "That being said: this whole authentication process does not prevent you from using official `pyannote.audio` models and pipelines offline (i.e. without going through the authentication process in every `docker run ...` or whatever you are using in production).\n", - "\n", - "* Step 1: download `config.yaml` of [`pyannote/voice-activity-detection`](https://hf.co/pyannote/voice-activity-detection) pipeline\n", - "\n", - "![](assets/download-pipeline.png)\n", - "\n", - "* Step 2: download the `pytorch_model.bin` model\n", - "\n", - "![](assets/download-model.png)\n", - "\n", - "* Step 3: edit `config.yaml` to point to the local model\n", - "\n", - "```diff\n", - "pipeline:\n", - " name: pyannote.audio.pipelines.VoiceActivityDetection\n", - " params:\n", - "- segmentation: pyannote/segmentation@Interspeech2021\n", - "+ segmentation: pytorch_model.bin\n", - "\n", - "params:\n", - " min_duration_off: 0.09791355693027545\n", - " min_duration_on: 0.05537587440407595\n", - " offset: 0.4806866463041527\n", - " onset: 0.8104268538848918\n", - "```\n", - "\n", - "* Step 4: load the pipeline" - ] - }, - { - "cell_type": "code", - "execution_count": 21, - "metadata": {}, - "outputs": [ - { - "data": { - "image/png": "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bPHixalUKu2+mpqaunpZQCdat25dzjzzzIwcOTKVSiWrVq1qd321Ws3ixYszcuTIDBw4MKeddlr+8pe/dM1igU7zVnvB3Llz95kRTj755K5ZLFBzS5Ysyfvf//7U1dVl2LBhmTlzZh566KF2tzETQM/3dvYCMwH0bMuWLctxxx2X+vr61NfXZ9KkSfntb3/bdn2t5oEOx4uVK1dm4cKF+epXv5r7778/H/7whzN9+vRs3ry5w3cOdF/HHHNMtm7d2va1adOmrl4S0In27NmT448/Ptdcc80bXr906dJcffXVueaaa3LvvfemqakpU6ZMybPPPvsOrxToTG+1FyTJtGnT2s0It9566zu4QqAzrV27NhdccEHuueee3H777XnppZcyderU7Nmzp+02ZgLo+d7OXpCYCaAnGzVqVL71rW9lw4YN2bBhQ04//fTMmDGjLVDUah6oVKvVakd+YOLEiTnhhBOybNmytmPjx4/PzJkzs2TJkg7dOdA9LV68OKtWrcrGjRu7eilAF6hUKrn55pszc+bMJK/+RcXIkSOzcOHCXHrppUmS1tbWDB8+PN/+9rdz/vnnd+Fqgc7y+r0gefWvLHft2rXPKzKAnumf//xnhg0blrVr1+YjH/mImQB6qdfvBYmZAHqjxsbGfOc738m8efNqNg906JUXL7zwQu67775MnTq13fGpU6fmrrvu6sipgG7u4YcfzsiRIzN27Nh8+tOfzt///veuXhLQRR577LFs27at3XzQv3//nHrqqeYD6IXWrFmTYcOG5aijjsr8+fOzffv2rl4S0El2796d5NVfViRmAuitXr8XvMZMAL3Dyy+/nBUrVmTPnj2ZNGlSTeeBDsWLHTt25OWXX87w4cPbHR8+fHi2bdvWoTsGuq+JEyfmhhtuyG233Zaf/OQn2bZtW0455ZTs3Lmzq5cGdIHXZgDzATB9+vTceOONueOOO/Ld73439957b04//fS0trZ29dKAGqtWq7nooovyoQ99KBMmTEhiJoDe6I32gsRMAL3Bpk2bMnjw4PTv3z8LFizIzTffnKOPPrqm80Df/VlYpVJpd7lare5zDOi5pk+f3vb9sccem0mTJuXwww/P9ddfn4suuqgLVwZ0JfMBMHv27LbvJ0yYkJNOOiljxozJb37zm5x11llduDKg1i688MI88MADufPOO/e5zkwAvcd/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", - "text/plain": [ - "" - ] - }, - "execution_count": 21, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "# look ma: no hands!\n", - "offline_vad = Pipeline.from_pretrained(\"config.yaml\")\n", - "offline_vad(audio_in_memory)" - ] - }, - { - "cell_type": "code", - "execution_count": 22, - "metadata": {}, - "outputs": [], - "source": [ - "# just checking output is the same\n", - "assert (vad(audio_in_memory) == offline_vad(audio_in_memory))" - ] - } - ], - "metadata": { - "kernelspec": { - "display_name": "Python 3.9.13 ('pyannote-mps')", - "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.9.13" - }, - "vscode": { - "interpreter": { - "hash": "36a3a48a52702f18671693adf589423ec3f7db45d50f6ee539f1b0696bb58d43" - } - } - }, - "nbformat": 4, - "nbformat_minor": 2 -} +{"cells":[{"cell_type":"markdown","metadata":{},"source":["**\"Open**"]},{"cell_type":"markdown","metadata":{"id":"uiNbotxCeq4b"},"source":["# Applying a pretrained pipeline\n","\n","In this tutorial, you will learn how to apply `pyannote.audio` pipelines on an audio file.\n","\n","A pipeline takes an audio file as input and returns a labeled temporal segmentation of the audio file.\n","\n","More precisely, it usually applies a pretrained model (= neural network) on the audio file, post-processes the output of the model, and returns its output as a [`pyannote.core.Annotation`](http://pyannote.github.io/pyannote-core/structure.html#annotation) instance. It should become clearer as you keep reading..."]},{"cell_type":"markdown","metadata":{"id":"z_4VUpZxesS2"},"source":["## Tutorial setup"]},{"cell_type":"markdown","metadata":{"id":"gbonpHYte3FC"},"source":["### `Google Colab` setup\n"]},{"cell_type":"markdown","metadata":{"id":"hxhhcj8Fe7v7"},"source":["If you are running this tutorial on `Colab`, execute the following commands in order to setup `Colab` environment. These commands will install `pyannote.audio`, and download resources used in this tutorial."]},{"cell_type":"code","execution_count":4,"metadata":{"executionInfo":{"elapsed":17283,"status":"ok","timestamp":1704808539241,"user":{"displayName":"Clément PAGES","userId":"11757386314069785178"},"user_tz":-60},"id":"NFdANMKsfD1p"},"outputs":[],"source":["!pip install -qq pyannote.audio==3.1.1\n","!pip install -qq ipython==7.34.0\n","!wget -q \"https://github.com/pyannote/pyannote-audio/raw/develop/tutorials/assets/sample.wav\"\n","!wget -q \"https://github.com/pyannote/pyannote-audio/raw/develop/tutorials/assets/sample.rttm\"\n","!wget -q -P ./assets/ \"https://github.com/pyannote/pyannote-audio/blob/develop/tutorials/assets/download-model.png\"\n","!wget -q -P ./assets/ \"https://github.com/pyannote/pyannote-audio/blob/develop/tutorials/assets/download-pipeline.png\""]},{"cell_type":"markdown","metadata":{"id":"PScZ6o_9gkfo"},"source":["⚠ Restart the runtime (Runtime > Restart session)."]},{"cell_type":"code","execution_count":13,"metadata":{"executionInfo":{"elapsed":458,"status":"ok","timestamp":1704809048938,"user":{"displayName":"Clément PAGES","userId":"11757386314069785178"},"user_tz":-60},"id":"ZU_QIx1UhcV6"},"outputs":[],"source":["AUDIO_FILE = \"sample.wav\"\n","REFERENCE = \"sample.rttm\""]},{"cell_type":"markdown","metadata":{"id":"d-qKbc9shI6o"},"source":["### Non `Google Colab` setup"]},{"cell_type":"markdown","metadata":{"id":"0KEh-IGqho6F"},"source":["If you are not using Colab, clone `pyannote.audio` [GitHub repository](https://github.com/pyannote/pyannote-audio) and update ROOT_DIR accordingly"]},{"cell_type":"code","execution_count":10,"metadata":{"id":"DuoohiL6hOiJ"},"outputs":[],"source":["ROOT_DIR = \"/pyannote-audio\"\n","AUDIO_FILE = f\"{ROOT_DIR}/tutorials/assets/sample.wav\"\n","REFERENCE = f\"{ROOT_DIR}/tutorials/assets/sample.rttm\""]},{"cell_type":"markdown","metadata":{"id":"yA9JsY84eq4e"},"source":["## Loading pipeline from 🤗 hub\n","\n","A bunch of pretrained pipelines are available on [🤗 Huggingface model hub](https://hf.co/models?other=pyannote-audio-pipeline) and can be listed by looking for the [`pyannote-audio-pipeline`](https://hf.co/models?other=pyannote-audio-pipeline) tag."]},{"cell_type":"code","execution_count":2,"metadata":{"colab":{"base_uri":"https://localhost:8080/"},"executionInfo":{"elapsed":2323,"status":"ok","timestamp":1704808592263,"user":{"displayName":"Clément PAGES","userId":"11757386314069785178"},"user_tz":-60},"id":"eAXGgYt8eq4f","outputId":"86772355-3bf0-42e5-c478-2d35a80853e9"},"outputs":[{"data":{"text/plain":["['pyannote/overlapped-speech-detection',\n"," 'pyannote/speaker-diarization',\n"," 'pyannote/speaker-segmentation',\n"," 'pyannote/voice-activity-detection',\n"," 'pyannote/speaker-diarization-3.0',\n"," 'pyannote/speaker-diarization-3.1']"]},"execution_count":2,"metadata":{},"output_type":"execute_result"}],"source":["from huggingface_hub import HfApi\n","available_pipelines = [p.modelId for p in HfApi().list_models(filter=\"pyannote-audio-pipeline\")]\n","list(filter(lambda p: p.startswith(\"pyannote/\"), available_pipelines))"]},{"cell_type":"markdown","metadata":{"id":"fry3qMrJeq4h"},"source":["Official [pyannote.audio](https://github.com/pyannote/pyannote-audio) pipelines (i.e. those under the [`pyannote` organization](https://hf.co/pyannote) umbrella) are open-source, but gated. It means that you have to first accept users conditions on their respective Huggingface page to access the pretrained weights and hyper-parameters. Despite this initial process, those pipelines can perfectly be downloaded for later offline use: keep reading this tutorial until the end to learn how to do that.\n","\n","For instance, to load the speaker diarization pipeline used in this tutorial, you have to visit [hf.co/pyannote/speaker-diarization](https://hf.co/pyannote/speaker-diarization), accept the terms, visit [hf.co/pyannote/segmentation](https://hf.co/pyannote/segmentation) (used internally by the speaker diarization pipeline), accept the terms, and log in using `notebook_login` below:"]},{"cell_type":"code","execution_count":null,"metadata":{"colab":{"base_uri":"https://localhost:8080/","height":145,"referenced_widgets":["6fe26270a8794dea85b9ac8dedde6353","f9969c7acd834359bd67e83c31b82c0b","ef6be001daaa465598bdf20c304bae0b","a8e61b300a324911b1d3babf6b1ebac1","45c2352ba41b46288c8ba74c661e1f85","78f428e1d8ac4c78bd84d208a78b1fe5","9d7b5e47af9448c98a2a434f02b54633","253408a6cab947c7b9ae40a14e255328","a435c85128f148cb80152d03825710e2","90533da4fc1341a28bc247bc9fbbbe9e","6556790d1997431a8476447297e3f595","5253489738b249f69b30f1c84884a95a","3f500b1182a945c3b8b546b1bd04f98e","c3b3069a93994e55b993cab04c066f17","f77186e2976d4a7daa798fd9f0f7b4cb","7ffa4930e0a7421e9464abff87bbde7f","1dd6bfb824ba4919ba392e0d4cd5ac82","7c23cd10c573438c840148ba1afaa5f3","bc4d3f45eaf04cccb7a655ef87d7a927","36f60aa99ea84b739f066c6ee216f159","5033834cc66f49efaa16b240245ec1d3","0b127e22a6de4339aecc1e76a6719d7f","8a7afaf126ac49dcaf24d64c2d918086","1b5f49211db54348924a05482ca7379d","1f3be36a57074214a5f92e08165e41be","275642719b694328ad3b0fb06b53e42a","ae378b480ed747438bcbe147a7e8d277","b22a1d21940e4995b72642b003ae1301","58e423b86bf349aa89fc81a2b0d0f697","a3ebe0f0e6e44522a2545db0ed47af62","dc9c065286e544df921e5bc4a51faf64","16244ab1dc76493d9fafad80a9b65700"]},"executionInfo":{"elapsed":418,"status":"ok","timestamp":1704808601143,"user":{"displayName":"Clément PAGES","userId":"11757386314069785178"},"user_tz":-60},"id":"IdXJumYveq4i","outputId":"cb87e106-b30f-4ec8-e726-d797ca98698b"},"outputs":[],"source":["from huggingface_hub import notebook_login\n","notebook_login()"]},{"cell_type":"markdown","metadata":{"id":"ym2671Fweq4j"},"source":["Once authenticated, you can load the pipeline (and the internal models)..."]},{"cell_type":"code","execution_count":null,"metadata":{"colab":{"base_uri":"https://localhost:8080/","height":266,"referenced_widgets":["5a2a95f41f014663b5d131635844e3c8","f8df65e5ad6444648681230f415b8d08","17e14569a3f74cbf991b582c27fdf280","4e0ca7f084804d30a89cb9dc439b6cdc","d304f698c6f34f3692548267ca0aba47","3f69734124f7449da0efffbbfd1153fe","686b58e0ccee468f938ea5659f3a9623","e98b1f7ec5e04e748069340fa2fcec2d","616f35eccdd34bcdb5c9f700103ff538","185457147fe44751a1c6e7ae6ad23570","b02b253086e34249ae1d896a75a08960","0b191fb0d6db4f1a98a641dc50445f1e","4a589ea883de4409b7a8275127747fa7","b5f4829158cf4a5c8350966d8eacbf60","7cab72ad0ace45d58d6954021082ace7","5440ac4cffa0438c99c0daeca27a4087","0d0dfc2576784812b6abf673752fa812","84e416e01cfa4a79b0294a44cfd77f32","b33021db4313476ab8bcb85bb1b190d7","6d5431955c09424a96e825aa9bba1b62","54eacc5604f64f658617cde596a728dd","1749a0e7fc6847849ab40ac7f764b699","ff048516fdba44a48a69c51a82aa7aaa","775611277f1948a5ab95641c4e92ff2e","c955f8144b46451493474e02726b5deb","c9eeb26bd5e049f89205e494d54e3818","d4d428f0b0c44756a128adae747716d2","70d672feec1c452aa49a40a3b8c1a4f0","e8b3188ee4934ab4becbc431fc4ccb0b","754a843fd634446b8d246998eaded1fa","1e53e26668aa4f8dabdd6973b79b5b9f","cf5ae82d36384a728d8ca893cc27392b","5cc77ca8ba304ad88342ed6ced6c6a4a","6412ef268e11484f8bbcdb510f66ee21","a987408c2f994329a9a80208b22e3c52","9446f61936c4421d9610464984890353","a80c0fb6a1254bb9a00741c1346b9d9a","b55e95f31216480fa6c81bd1b57ad729","517a1b1faec045f7847ca84f0538f4e1","008a47e4d1174b188e75232fed325398","30864d7b4d074994ba643c73875a67b8","b852998433e24f7fad1fe27e249085f9","46ac2d0bfedc47c8836e8dde0fc91662","58b140d0453a4a219bc64e0152cc5c5e","3bb60a8db7c0406f8debdc8dd88bcdb4","bf644ae3e2894787bb416740749200cd","0fccc53081a34d58a46912d1ceae0533","39cd6fe37b6f4476b6032c29f026d570","87a0e712c0b045449b98ee368c62fff2","2be7c1f5fe32462f8d1cd7ea57cfbf3a","d6135ce9cfaa4f8496a70cee4f1e89a7","00ac431507a54c0d9a41244013b1c0f3","6f318bc3e900434a9134a79e4057f666","7580595b498a4c50b748af9df67132e2","3f1d750804a54d78a6abff2623441360"]},"executionInfo":{"elapsed":30028,"status":"ok","timestamp":1704808674003,"user":{"displayName":"Clément PAGES","userId":"11757386314069785178"},"user_tz":-60},"id":"1NihzPUPeq4k","outputId":"04275648-23ef-4453-9bf4-8d8dfadd99e0"},"outputs":[],"source":["from pyannote.audio import Pipeline\n","pipeline = Pipeline.from_pretrained(\"pyannote/speaker-diarization-3.1\", use_auth_token=True)"]},{"cell_type":"markdown","metadata":{"id":"cZhtRXAHeq4l"},"source":["## Processing a file from disk"]},{"cell_type":"markdown","metadata":{"id":"X7hQRbzeeq4m"},"source":["... and apply it to an audio file. \n","\n","The pipeline will automatically use GPUs when available.\n","On CPU it might take a long while (up to 10x RT)."]},{"cell_type":"code","execution_count":9,"metadata":{"executionInfo":{"elapsed":82100,"status":"ok","timestamp":1704808982782,"user":{"displayName":"Clément PAGES","userId":"11757386314069785178"},"user_tz":-60},"id":"digxFLaueq4n"},"outputs":[],"source":["dia = pipeline(AUDIO_FILE)"]},{"cell_type":"markdown","metadata":{"id":"9WTsQVjjeq4o"},"source":["## Visualizing the output\n","\n","Most pipelines return a [`pyannote.core.Annotation`](http://pyannote.github.io/pyannote-core/structure.html#annotation) instance..."]},{"cell_type":"code","execution_count":10,"metadata":{"executionInfo":{"elapsed":1079,"status":"ok","timestamp":1704809008347,"user":{"displayName":"Clément PAGES","userId":"11757386314069785178"},"user_tz":-60},"id":"Ch7SaA4-eq4p"},"outputs":[],"source":["from pyannote.core import Annotation\n","assert isinstance(dia, Annotation)"]},{"cell_type":"markdown","metadata":{"id":"T4BsOhmXeq4p"},"source":["... whose [API](https://pyannote.github.io/pyannote-core/structure.html#annotation) you can use to print the result:"]},{"cell_type":"code","execution_count":11,"metadata":{"colab":{"base_uri":"https://localhost:8080/"},"executionInfo":{"elapsed":610,"status":"ok","timestamp":1704809011691,"user":{"displayName":"Clément PAGES","userId":"11757386314069785178"},"user_tz":-60},"id":"OzEPn1hqeq4p","outputId":"e61015ad-c0df-4890-acc6-f65c87d7c30d"},"outputs":[{"name":"stdout","output_type":"stream","text":[" 6.7 7.2 SPEAKER_01\n"," 7.2 7.2 SPEAKER_02\n"," 7.6 8.3 SPEAKER_01\n"," 8.3 9.9 SPEAKER_02\n"," 9.9 10.9 SPEAKER_01\n","10.5 14.7 SPEAKER_02\n","10.9 11.0 SPEAKER_00\n","14.3 17.9 SPEAKER_00\n","18.0 21.5 SPEAKER_02\n","18.2 18.4 SPEAKER_00\n","21.8 28.5 SPEAKER_00\n","27.9 30.0 SPEAKER_02\n"]}],"source":["for speech_turn, track, speaker in dia.itertracks(yield_label=True):\n"," print(f\"{speech_turn.start:4.1f} {speech_turn.end:4.1f} {speaker}\")"]},{"cell_type":"markdown","metadata":{"id":"PqiV2D2geq4q"},"source":["If you happen to be running this example in a _Jupyter notebook_, `dia` can be [visualized directly](http://pyannote.github.io/pyannote-core/visualization.html):"]},{"cell_type":"code","execution_count":12,"metadata":{"colab":{"base_uri":"https://localhost:8080/","height":220},"executionInfo":{"elapsed":841,"status":"ok","timestamp":1704809016036,"user":{"displayName":"Clément PAGES","userId":"11757386314069785178"},"user_tz":-60},"id":"80D-4Yhreq4r","outputId":"ee02c234-ebc6-40f3-94b1-0838fac05f81"},"outputs":[{"data":{"image/png":"iVBORw0KGgoAAAANSUhEUgAABi8AAADyCAYAAAA1MlYeAAAAOXRFWHRTb2Z0d2FyZQBNYXRwbG90bGliIHZlcnNpb24zLjcuMSwgaHR0cHM6Ly9tYXRwbG90bGliLm9yZy/bCgiHAAAACXBIWXMAAA9hAAAPYQGoP6dpAAAheUlEQVR4nO3df5TVdZ0/8Ocw/FznhwIyIzogpqIYqFkhZeaigsjx+INstdVETU8eZI9ayeqSaKa29G1LV+0n/tgQdS21snWtXDAL1NWWCCs2WVp1lUEHGX7UgMJ8//AwOUHAwB3uZ+DxOOeeM3M/n8/787oz73nf99znve9PRWtra2sAAAAAAAAKolu5CwAAAAAAAHgn4QUAAAAAAFAowgsAAAAAAKBQhBcAAAAAAEChCC8AAAAAAIBCEV4AAAAAAACFIrwAAAAAAAAKRXgBAAAAAAAUivACAAAAAAAoFOEFAAAAAABQKMILAAAAAACgUIQXAAAAAABAoQgvAAAAAACAQhFeAAAAAAAAhSK8AAAAAAAACkV4AQAAAAAAFMpuGV689tprueSSSzJo0KD06tUr9fX1GTt2bH7+858nSfbff/9UVFSkoqIie+yxR97znvfkgQceaDv+2muvbdv+ztshhxyyybnuvffeVFZWZtKkSZtsmzNnTioqKrJixYq2+1555ZUMHz48xx57bJqbm9v22dxt6dKlm9RTWVmZhoaGXHzxxVm+fPk2/0xaWloyadKk9OvXL1VVVZkwYUIaGxvb7fPiiy9m/Pjx+au/+qsMGDAgn/nMZ/LWW29t8zl2N/rZpraln/3d3/1djjrqqPTq1StHHHHENre9u9LPNrW1fvbLX/4yZ599dhoaGtKnT58ceuihufnmm7e5fQAAAAA6X/dSN9i8trnUTW5Rba/aDh8zYcKErFu3LnfffXcOOOCANDY25vHHH09TU1PbPp/73Ody0UUXZeXKlfnSl76Uv/mbv8m+++6bD3zgA0mSww47LD/5yU/atdu9+6Y/zhkzZuTKK6/M17/+9XzpS19K7969/2Jdixcvzoknnphhw4blgQceSJ8+fdq2LVq0KDU1Ne32HzBgQNvXG+tZv359fvOb3+SCCy5Ic3Nz7r///m36mVx++eX54Q9/mAceeCC1tbW59NJLc8YZZ7S9ALp+/fqMHz8+9fX1mTt3bl599dV8/OMfT48ePXLjjTdu0zlKaf07flc7Q2W/fh0+Rj/b1Nb62UYXXHBBnn766SxYsGCb2u0sb6xZt1PPt9cePTt8jH62qa31s+eeey4DBgzIzJkz09DQkLlz5+biiy9OZWVlLr300m06BwAAAACdq+ThxbmPfqzUTW7R90/7YYf2X7FiRZ588snMmTMnH/7wh5MkgwcPzvvf//52+1VXV6e+vj719fW57bbbMnPmzPzgBz9oe7Gve/fuqa+v3+K5lixZkrlz5+a73/1uZs+enQcffDAf+9jmfz4LFizI2LFjM3r06Nx9992bvHA4YMCA7Lnnnn/xXO+sZ999982ZZ56ZO++8c4v1bdTc3JwZM2Zk1qxZGT16dJLkzjvvzKGHHpqnnnoqRx99dH70ox/l17/+dX7yk5+krq4uRxxxRK6//vpMmTIl1157bXr27PiLrjti6Ygjdur59v2/lzq0v362qW3pZ0lyyy23JHn7EwXlDi/GTZ+9U8/31HVjO7S/frapbelnF1xwQbtjDjjggMybNy8PPvig8AIAAACgIHa7ZaOqqqpSVVWVhx9+OGvXrt2mY7p3754ePXpk3bqOvQv7zjvvzPjx41NbW5tzzjknM2bM2Ox+c+fOzYc//OFMmDAhM2fO3Ow7njvi97//fR577LFtDhSee+65vPnmmznhhBPa7jvkkEMyaNCgzJs3L0kyb968DB8+PHV1dW37jB07NitXrszzzz+/Q/XuivSzTW1LP6Nj9LNNbW8/a25uTt++fXeoVgAAAABKZ7cLL7p375677rord999d/bcc8988IMfzNVXX/0X3+G9bt263HTTTWlubm57F2+S/OpXv2p74XDj7ZOf/GTb9g0bNuSuu+7KOeeckyQ566yz8rOf/SxLlizZ5Bynn356TjnllNx6662pqKjYbB377bdfu3Mddthh7bZvrKdPnz4ZMmRInn/++UyZMmWbfiZLly5Nz549N3kndF1dXds69EuXLm0XXGzcvnEb7elnm9qWfkbH6Geb2p5+Nnfu3Nx///25+OKLt+kcAAAAAHS+ki8b1RVMmDAh48ePz5NPPpmnnnoqjz76aKZPn55vfetbmThxYpJkypQpmTp1alpaWlJVVZUvfOELGT9+fFsbQ4cOzfe///127b5zDfcf//jHWbNmTU4++eQkSf/+/XPiiSfmjjvuyPXXX9/uuFNP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H8+oUaM6dGJg17B69eosXrw4++yzT7lLAcpkyJAhqa+vbzc/WLlyZZ5++mnzA9iNvfzyy2lqajJHgF1Ia2trLr300jz00EP5j//4jwwZMqTd9qOOOio9evRoNydYtGhRXnzxRXMC2EVsbRzYnPnz5yeJOQHs4jZs2JC1a9eWdD7Q4WWjrrjiipx33nl573vfm/e///35yle+kjVr1uT888/vaFNAF/TpT386p5xySgYPHpxXXnkl06ZNS2VlZc4+++xylwZ0otWrV7d7p9SSJUsyf/789O3bN4MGDcpll12Wz3/+8znooIMyZMiQfPazn83AgQNz2mmnla9ooKS2NA707ds31113XSZMmJD6+vosXrw4V155ZQ488MCMHTu2jFUDpTRp0qTMmjUr3/ve91JdXd22bnVtbW369OmT2traXHjhhbniiivSt2/f1NTUZPLkyRk1alSOPvroMlcPlMLWxoHFixdn1qxZOfnkk9OvX78sWLAgl19+eY499tiMGDGizNUDpXLVVVdl3LhxGTRoUFatWpVZs2Zlzpw5eeyxx0o6H6hobW1t7Whxt956a774xS9m6dKlOeKII3LLLbe0fQQM2LWdddZZ+elPf5qmpqbsvffeOeaYY3LDDTdYtxJ2cXPmzMlf//Vfb3L/eeedl7vuuiutra2ZNm1avvGNb2TFihU55phjcvvtt+fggw8uQ7VAZ9jSOPDVr341p512Wv7rv/4rK1asyMCBAzNmzJhcf/31qaurK0O1QGeoqKjY7P133nlnJk6cmCRpaWnJpz71qdx7771Zu3Ztxo4dm9tvv92yUbCL2No48NJLL+Wcc87JwoULs2bNmjQ0NOT000/P1KlTU1NTs5OrBTrLhRdemMcffzyvvvpqamtrM2LEiEyZMiUnnnhiktLNB7YrvAAAAAAAAOgsHbrmBQAAAAAAQGcTXgAAAAAAAIUivAAAAAAAAApFeAEAAAAAABSK8AIAAAAAACgU4QUAAAAAAFAowgsAAAAAAKBQhBcAAAAAAEChCC8AAIAtmjhxYk477bRylwEAAOxGupe7AAAAoHwqKiq2uH3atGm5+eab09raupMqAgAAEF4AAMBu7dVXX237+v77788111yTRYsWtd1XVVWVqqqqcpQGAADsxiwbBQAAu7H6+vq2W21tbSoqKtrdV1VVtcmyUccdd1wmT56cyy67LHvttVfq6uryzW9+M2vWrMn555+f6urqHHjggXn00UfbnWvhwoUZN25cqqqqUldXl3PPPTevv/76Tn7EAABAVyC8AAAAOuzuu+9O//7988wzz2Ty5Mm55JJLcuaZZ+YDH/hAfvGLX2TMmDE599xz84c//CFJsmLFiowePTpHHnlknn322fz7v/97Ghsb89GPfrTMjwQAACgi4QUAANBhhx9+eKZOnZqDDjooV111VXr37p3+/fvnoosuykEHHZRrrrkmTU1NWbBgQZLk1ltvzZFHHpkbb7wxhxxySI488sjccccdmT17dv77v/+7zI8GAAAoGte8AAAAOmzEiBFtX1dWVqZfv34ZPnx42311dXVJkmXLliVJfvnLX2b27NmbvX7G4sWLc/DBB3dyxQAAQFcivAAAADqsR48e7b6vqKhod19FRUWSZMOGDUmS1atX55RTTsk//uM/btLWPvvs04mVAgAAXZHwAgAA6HTvec978t3vfjf7779/unf3bwgAALBlrnkBAAB0ukmTJmX58uU5++yz85//+Z9ZvHhxHnvssZx//vlZv359ucsDAAAKRngBAAB0uoEDB+bnP/951q9fnzFjxmT48OG57LLLsueee6ZbN/+WAAAA7VW0tra2lrsIAAAAAACAjbzFCQAAAAAAKBThBQAAAAAAUCjCCwAAAAAAoFCEFwAAAAAAQKEILwAAAAAAgEIRXgAAAAAAAIUivAAAAAAAAApFeAEAAAAAABSK8AIAAAAAACgU4QUAAAAAAFAowgsAAAAAAKBQ/j9ABajFKnR58QAAAABJRU5ErkJggg==","text/plain":[""]},"execution_count":12,"metadata":{},"output_type":"execute_result"}],"source":["# we visualize [0, 30] time range\n","from pyannote.core import notebook, Segment\n","notebook.crop = Segment(0, 30)\n","dia"]},{"cell_type":"markdown","metadata":{"id":"TC_ZiDYoeq4s"},"source":["When available, the reference annotation can be visualized too, for comparison:"]},{"cell_type":"code","execution_count":14,"metadata":{"colab":{"base_uri":"https://localhost:8080/","height":220},"executionInfo":{"elapsed":1085,"status":"ok","timestamp":1704809060416,"user":{"displayName":"Clément PAGES","userId":"11757386314069785178"},"user_tz":-60},"id":"xlcEFiHUeq4s","outputId":"d30ad6ba-a0c6-416d-eb8c-5c8e93f309da"},"outputs":[{"data":{"image/png":"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TTflH//xHzNz5szmD5U/85nPZPLkyamsrExtbe0u31Tv0aNHjjjiiL/Z/pw5c7J+/foWF0PesWNHli9fnltvvTVduvzlRy9f//rXc/3112fcuHH5j//4j5x22mm7tDdkyJA9Xovg7fXs/AD81ltv3eUD7N2pq6vLtm3bsmHDhhbHWLt2bfP1Derq6vLcc8+12G/t2rXN6/a3J6//6H4/5ruhn/3F3vSznX7961/njDPOyFVXXZUZM2a8Y9sAAAAAQMdS8vCipmdNqZvcL4499tg8/vjjzf/u37//Hj803pN169blu9/9bh566KEWp93Zvn17Tj311Pzwhz/MWWed1by8oqIi3/jGN9KlS5ecffbZ+cEPftB8ked3a8aMGRk1alSmTJmSgQMH7nHbk046Kd27d8+CBQsyceLEJMnKlSvz8ssvZ+TIkUmSkSNH5vbbb89rr72WAQMGJPnzt/6rq6tz7LHH7lOt78aBB+zfC4SXin62536WJC+88EJGjRqVSZMm5fbbb9+n+gAAAACA9qnTnTZq3bp1ueCCC3L55Zdn+PDhqaqqyvPPP59Zs2bl3HPP3et23nrrrV3O019RUZHa2tp861vfSr9+/fLxj398l2/Sn3322ZkzZ06LD5V37vu1r30tXbt2bf5g+fTTT29e/9prr6WxsbHFPv369dvltD47jRw5MsOHD88dd9yR2bNn7/G+1NTU5Iorrsh1112Xvn37prq6OtOmTcvIkSNz8sknJ0nGjBmTY489NpdeemlmzZqVNWvWZMaMGZk6dWp69uy5x/Y7I/1sV3vTz1asWJFRo0Zl7Nixue6665rve9euXXPQQQftsX0AAAAAoOPodOFFZWVlRowYkS996UtZtWpV3nzzzdTX1+fKK6/MjTfeuNftvPDCCzn44INbLOvZs2caGxtz77335rzzztvtRZEnTpyYSy+9NG+88cYu6yoqKnL33XenS5cuGT9+fJ544onmNoYOHbrL9kuWLGn+0Hd3rr322kyePDnTp09PfX39Hu/Pl770pXTp0iUTJ07M1q1bM3bs2Nxzzz3N67t27ZonnngiU6ZMyciRI3PAAQdk0qRJ+exnP7vHdjsr/Wz33qmfffvb387rr7+eefPmZd68ec3LBw8enJdeemmPbQMAAAAAHUdFU1NTU7mLAAAAAAAA2KnLO28CAAAAAACw/wgv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6EMfynvf+94kf54T9OjRI3369GmxrTkBdEy7GweS5OKLL87gwYMzcODALF++PNOnT8/KlSvz6KOPlrFaoNR+9atfZeTIkWlsbExlZWUee+yxHHvssVm2bFnJ5gOtCi8Axo0b1/z38OHDM2LEiAwePDj//u//niuuuKKMlQEA5fT2U8QNGzYsw4cPz+GHH55FixbljDPOKGNlQFuYOnVqVqxY4fp30In9rXHgqquuav572LBhOfjgg3PGGWdk1apVOfzww/d3mUAbGTp0aJYtW5aGhoZ8+9vfzqRJk/L000+X9BitOm1U//7907Vr112uDL527drU1dWVtDCgfejTp0+OOuqo/P73vy93KUCZ7JwDmB8Ab3fYYYelf//+5gjQAV199dV54oknsnDhwhxyyCHNy+vq6rJt27Zs2LChxfbmBNDx/K1xYHdGjBiRJOYE0MH06NEjRxxxRE466aTceeedOf7443PXXXeVdD7QqvCiR48eOemkk7JgwYLmZTt27MiCBQsycuTIVh0Y6Bg2b96cVatW5eCDDy53KUCZDBkyJHV1dS3mBxs3bszPf/5z8wPoxP7v//4v69atM0eADqSpqSlXX311HnvssfzXf/1XhgwZ0mL9SSedlO7du7eYE6xcuTIvv/yyOQF0EO80DuzOsmXLksScADq4HTt2ZOvWrSWdD7T6tFHXXXddJk2alPe///354Ac/mC9/+cvZsmVLLrvsstY2BbRDn/70p3POOedk8ODBWb16dWbOnJmuXbvmoosuKndpQBvavHlzi29Kvfjii1m2bFn69u2bQYMG5Zprrsk///M/58gjj8yQIUNy0003ZeDAgZkwYUL5igZKak/jQN++fXPrrbdm4sSJqaury6pVq3L99dfniCOOyNixY8tYNVBKU6dOzfz58/Pd7343VVVVzeetrqmpSe/evVNTU5Mrrrgi1113Xfr27Zvq6upMmzYtI0eOzMknn1zm6oFSeKdxYNWqVZk/f37OPvvs9OvXL8uXL8+1116b0047LcOHDy9z9UCp3HDDDRk3blwGDRqUTZs2Zf78+Vm0aFGeeuqpks4HKpqamppaW9zs2bPzhS98IWvWrMkJJ5yQr3zlK80/AQM6tgsvvDA/+clPsm7duhx00EE59dRTc/vttztvJXRwixYtykc/+tFdlk+aNClz585NU1NTZs6cmW984xvZsGFDTj311Nxzzz056qijylAt0Bb2NA589atfzYQJE/I///M/2bBhQwYOHJgxY8bktttuS21tbRmqBdpCRUXFbpffd999mTx5cpKksbExn/rUp/Lggw9m69atGTt2bO655x6njYIO4p3GgVdeeSWXXHJJVqxYkS1btqS+vj7nnXdeZsyYkerq6v1cLdBWrrjiiixYsCCvvvpqampqMnz48EyfPj2jR49OUrr5wLsKLwAAAAAAANpKq655AQAAAAAA0NaEFwAAAAAAQKEILwAAAAAAgEIRXgAAAAAAAIUivAAAAAAAAApFeAEAAAAAABSK8AIAAAAAACgU4QUAAAAAAFAowgsAAGCPJk+enAkTJpS7DAAAoBPpVu4CAACA8qmoqNjj+pkzZ+auu+5KU1PTfqoIAABAeAEAAJ3aq6++2vz3ww8/nJtvvjkrV65sXlZZWZnKyspylAYAAHRiThsFAACdWF1dXfOtpqYmFRUVLZZVVlbuctqo008/PdOmTcs111yTAw88MLW1tfnmN7+ZLVu25LLLLktVVVWOOOKIPPnkky2OtWLFiowbNy6VlZWpra3NpZdemjfeeGM/32MAAKA9EF4AAACtdv/996d///557rnnMm3atEyZMiUXXHBBTjnllPziF7/ImDFjcumll+aPf/xjkmTDhg0ZNWpUTjzxxDz//PP5z//8z6xduzYf//jHy3xPAACAIhJeAAAArXb88cdnxowZOfLII3PDDTekV69e6d+/f6688soceeSRufnmm7Nu3bosX748STJ79uyceOKJueOOO3L00UfnxBNPzL333puFCxfmf//3f8t8bwAAgKJxzQsAAKDVhg8f3vx3165d069fvwwbNqx5WW1tbZLktddeS5L88pe/zMKFC3d7/YxVq1blqKOOauOKAQCA9kR4AQAAtFr37t1b/LuioqLFsoqKiiTJjh07kiSbN2/OOeeck89//vO7tHXwwQe3YaUAAEB7JLwAAADa3Pve97585zvfyaGHHppu3bwNAQAA9sw1LwAAgDY3derUrF+/PhdddFH++7//O6tWrcpTTz2Vyy67LNu3by93eQAAQMEILwAAgDY3cODA/OxnP8v27dszZsyYDBs2LNdcc0369OmTLl28LQEAAFqqaGpqaip3EQAAAAAAADv5ihMAAAAAAFAowgsAAAAAAKBQhBcAAAAAAEChCC8AAAAAAIBCEV4AAAAAAACFIrwAAAAAAAAKRXgBAAAAAAAUivACAAAAAAAoFOEFAAAAAABQKMILAAAAAACgUIQXAAAAAABAofx/KOKnS3lbHocAAAAASUVORK5CYII=","text/plain":[""]},"execution_count":14,"metadata":{},"output_type":"execute_result"}],"source":["from pyannote.database.util import load_rttm\n","\n","reference = load_rttm(REFERENCE)[\"sample\"]\n","\n","# map hypothesized and reference speakers for visualization purposes\n","pipeline.optimal_mapping(dia, reference)"]},{"cell_type":"markdown","metadata":{"id":"rfTV3nSSeq4t"},"source":["## Processing a file from memory\n","\n","In case the audio file is not stored on disk, pipelines can also process audio provided as a `{\"waveform\": ..., \"sample_rate\": ...}` dictionary."]},{"cell_type":"code","execution_count":11,"metadata":{"colab":{"base_uri":"https://localhost:8080/"},"executionInfo":{"elapsed":410,"status":"ok","timestamp":1704809066383,"user":{"displayName":"Clément PAGES","userId":"11757386314069785178"},"user_tz":-60},"id":"Nha4sg76eq4u","outputId":"69192d82-c240-47d1-fe01-d373c2b4e500"},"outputs":[{"name":"stdout","output_type":"stream","text":["type(waveform)=\n","waveform.shape=torch.Size([1, 480000])\n","waveform.dtype=torch.float32\n"]}],"source":["import torchaudio\n","waveform, sample_rate = torchaudio.load(AUDIO_FILE)\n","\n","print(f\"{type(waveform)=}\")\n","print(f\"{waveform.shape=}\")\n","print(f\"{waveform.dtype=}\")\n","\n","audio_in_memory = {\"waveform\": waveform, \"sample_rate\": sample_rate}"]},{"cell_type":"code","execution_count":null,"metadata":{"colab":{"base_uri":"https://localhost:8080/","height":388,"referenced_widgets":["514552137d7442368b39aaddce056bb8","f744ac29ccdd4d9d91050fabaed13e16","f18c80869ccc4ce1b2a215293d493e19","2c0b1ed212544e14b4934e036e8736d7","9988b4433d6e4c58a819a2e1b54f57b2","b8861f8cb72c4e65afac6519b7004170","668a49e70c2b4c8a9dcb534cb30714d6","9025d2b6c7b14162a692b98c3e86ec8a","6c361855da5e4eb78e311defb2ca2f2b","3be13f7f05da47b1ae3795ead9f2546a","07bb94f0dcda45a9a5e2d553fd239106","57ef34701b594a60a9fd269943b49888","1d051eb2d87e4671aa08039761c7899a","9537f195677745cba18618764b2290ab","4f0d63f098b0491097c6b72f3baee04f","f7be373f08c64c8bb5b6e070a7373cca","be8b64ce7f8247499c8bbcb62c5dd902","491c3dcba4474a52b860080fa7a627e7","4abbe0d8e0fa4e1b9d712743013b2d4e","661c7494ef2d47c794e6236e5f2c8978","6358920ecd46403a87cca46509465076","4f25b89365b24056b803119d415ac056","1d97d11a99454cc990cc5e374d0f8197","425146d4e0fb453486629d9d6af0a999","8fad50e0475341d9801e9f86e04e15c7","ea03f9526a7440a0a9a281ee877892fd","d1863b2c9ebc4efa9cac2dad7dfaf53a","8bda58a4c0c6430ca1470282ddbe8222","5d38b6ceec1844068f48da7bedf471fa","2a72c7660c2f498089c63c78eaa69fc8","05283cf0054d412c9a1ebfcc44bf41cb","b9d9acd287c345debdff1e72a85641af","91ca95844e084619b9ae01fe8176f875"]},"executionInfo":{"elapsed":12810,"status":"ok","timestamp":1704809082573,"user":{"displayName":"Clément PAGES","userId":"11757386314069785178"},"user_tz":-60},"id":"LvboMeeYeq4u","outputId":"225dd352-6367-4793-ae11-f8125d930c2b"},"outputs":[],"source":["vad = Pipeline.from_pretrained(\"pyannote/voice-activity-detection\", use_auth_token=True)"]},{"cell_type":"code","execution_count":12,"metadata":{},"outputs":[{"data":{"image/png":"iVBORw0KGgoAAAANSUhEUgAABiIAAADyCAYAAADAzN2uAAAAOXRFWHRTb2Z0d2FyZQBNYXRwbG90bGliIHZlcnNpb24zLjguMCwgaHR0cHM6Ly9tYXRwbG90bGliLm9yZy81sbWrAAAACXBIWXMAAA9hAAAPYQGoP6dpAAAWJUlEQVR4nO3dfZCVdf3/8dfhRrzZG2SRXTZWF2/QTDDtV941Rt4Aak4o2r2JFY2KOqilaSplTRYTYk3ajU2pk/ptHNOyGW3KwMxRy8rIvt/IdpwRQ9FodhcxhOD8/nBc20BYZD+cZXk8ZnaGvc6153ofZs41n+XJua5KtVqtBgAAAAAAoIAhtR4AAAAAAAAYvIQIAAAAAACgGCECAAAAAAAoRogAAAAAAACKESIAAAAAAIBihAgAAAAAAKAYIQIAAAAAAChGiAAAAAAAAIoRIgAAAAAAgGKECAAAAAAAoBghAgAAAAAAKEaIAAAAAAAAihEiAAAAAACAYoQIAAAAAACgGCECAAAAAAAoRogAAAAAAACKGfQh4oUXXsg555yTPffcMyNGjEhLS0umTp2ahx56KEnS3t6eSqWSSqWS3XbbLYceemjuuOOOnp//3Oc+1/P4f34dcMABPftMnjx5o/ucffbZvWZZuHBhTjzxxDQ1NWXXXXfNgQcemIsvvjh///vfkySLFi1KpVJJZ2fnBq+jvb091113Xf//BQEAAAAAQEHDtvYJ1q1Y0R9z9MnQpqYt/pkZM2ZkzZo1ufnmm7P33ntn+fLluf/++7PiP+a++uqrM2vWrHR3d2f+/Pl5//vfnze96U058sgjkyRvectb8otf/KLX8w4b1vuvbtasWbn66qt7bdt11117/vztb3875557bs4888zceeedaW9vz9NPP51bbrkl8+fPz7XXXrvFrw0AAAAAAAa6rQ4Rz016az+M0Tdv+vvSLdq/s7MzDz74YBYtWpR3vetdSZK99tor73jHO3rtV19fn5aWlrS0tOT666/PD37wg9xzzz09IWLYsGFpaWnZ5LF23XXX193nmWeeyQUXXJALLrggCxYs6Nne3t6eo48+eqOfgAAAAAAAgMFgUF+aqa6uLnV1dbn77rvz8ssv9+lnhg0bluHDh2fNmjX9Nscdd9yRNWvW5JJLLtno4yNHjuy3YwEAAAAAwEAyqEPEsGHDctNNN+Xmm2/OyJEjc9RRR+Xyyy/P4sWLN7r/mjVrcs0116SrqyvHHHNMz/Y//elPPVHj1a//vv/DDTfcsME+t956a5LkySefTENDQ8aOHdunuceNG7fBcz399NNv8G8BAAAAAABqZ6svzTTQzZgxIyeddFIefPDBPPLII7n33nszb968fPe7383MmTOTJJdeemmuuOKKrF69OnV1dfnyl7+ck046qec59t9///zkJz/p9bwNDQ29vv/whz+cz372s722NTc3J0mq1WoqlUqfZ37wwQdTX1/fa9vkyZP7/PMAAAAAADBQbHWIaFn8eD+MUdbOO++c448/Pscff3yuvPLKfOITn8jcuXN7QsSnP/3pzJw5M3V1dWlubt4gGuy0007Zd999N3mMxsbG191nwoQJ6erqyrPPPtunT0WMHz9+g8s1/ffNsQEAAAAAYHuw1f+6PbSpqT/m2KYOPPDA3H333T3fjx49erOhYWucdtpp+cxnPpN58+b1uln1qzo7O90nAgAAAACAQWlQ/zf7FStW5PTTT8/HPvaxTJo0KfX19Xnssccyb968vPe97+3z8/z73//Oc88912tbpVLpufRSkrz00ksb7DNixIjsvvvuaWtry4IFC3Leeeelu7s7H/3oR9Pe3p5nnnkmt9xyS+rq6jJ//vyte7EAAAAAADAADeoQUVdXl8MOOywLFixIR0dH1q5dm7a2tsyaNSuXX355n5/nz3/+8waXVBoxYkRWr17d8/2NN96YG2+8sdc+U6dOzX333ZckOffcczNhwoR89atfzSmnnJJ//etfaW9vz3ve855cdNFFW/EqAQAAAABg4KpUq9VqrYcAAAAAAAAGpyG1HgAAAAAAABi8hAgAAAAAAKAYIQIAAAAAAChGiAAAAAAAAIoRIgAAAAAAgGKECAAAAAAAoJhhfdlp/fr1WbZsWerr61OpVErPBAAAAAAADGDVajUrV65Ma2trhgzZ9Gce+hQili1blra2tn4ZDgAAAAAAGByWLl2acePGbXKfPoWI+vr6nidsaGjY+skAAAAAAIDtVnd3d9ra2nr6wab0KUS8ejmmhoYGIQIAAAAAAEiSPt3Owc2qAQAAAACAYoQIAAAAAACgGCECAAAAAAAoRogAAAAAAACKESIAAAAAAIBihAgAAAAAAKAYIQIAAAAAAChGiAAAAAAAAIoRIgAAAAAAgGKECAAA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gGKECAAAAAAAoBghAgAAAAAAKEaIAAAAAAAAihEiYBv71a9+lZNPPjmtra2pVCq5++67ez1erVZz1VVXZezYsdlll11y3HHH5cknn6zNsAA1trlz5syZM1OpVHp9TZs2rTbDAtTQNddck7e//e2pr6/PmDFjMn369CxZsqTXPqtXr87s2bPT1NSUurq6zJgxI8uXL6/RxAC11Zfz5uTJkzdYa5599tk1mhhg+yZEwDa2atWqHHzwwbn++us3+vi8efPy9a9/Pd/61rfy6KOPZrfddsvUqVOzevXqbTwpQO1t7pyZJNOmTcuzzz7b83X77bdvwwkBBoYHHnggs2fPziOPPJKf//znWbt2baZMmZJVq1b17HPhhRfmnnvuyR133JEHHnggy5Yty6mnnlrDqQFqpy/nzSSZNWtWr7XmvHnzajQxwPatUq1Wq7UeAnZUlUold911V6ZPn57klU9DtLa25uKLL86nPvWpJElXV1eam5tz00035QMf+EANpwWorf8+ZyavfCKis7Nzg09KAOzoXnjhhYwZMyYPPPBAjj766HR1dWWPPfbIbbfdltNOOy1J8pe//CVvfvOb8/DDD+fwww+v8cQAtfXf583klU9EvPWtb811111X2+EABgGfiIAB5Kmnnspzzz2X4447rmdbY2NjDjvssDz88MM1nAxg4Fq0aFHGjBmT/fffP+ecc05WrFhR65EAaq6rqytJMmrUqCTJ7373u6xdu7bXOvOAAw7InnvuaZ0JkA3Pm6+69dZbM3r06Bx00EG57LLL8tJLL9ViPIDt3rBaDwC85rnnnkuSNDc399re3Nzc8xgAr5k2bVpOPfXUjB8/Ph0dHbn88stzwgkn5OGHH87QoUNrPR5ATaxfvz5z5szJUUcdlYMOOijJK+vMnXbaKSNHjuy1r3UmwMbPm0nyoQ99KHvttVdaW1uzePHiXHrppVmyZEl+9KMf1XBagO2TEAEAbLf+85J1EydOzKRJk7LPPvtk0aJFOfbYY2s4GUDtzJ49O0888UR+/etf13oUgO3C6503P/nJT/b8eeLEiRk7dmyOPfbYdHR0ZJ999tnWYwJs11yaCQaQlpaWJMny5ct7bV++fHnPYwC8vr333jujR4/O3/72t1qPAlAT5513Xn76059m4cKFGTduXM/2lpaWrFmzJp2dnb32t84EdnSvd97cmMMOOyxJrDUB3gAhAgaQ8ePHp6WlJffff3/Ptu7u7jz66KM54ogjajgZwPbhmWeeyYoVKzJ27NhajwKwTVWr1Zx33nm566678stf/jLjx4/v9fjb3va2DB8+vNc6c8mSJXn66aetM4Ed0ubOmxvz+OOPJ4m1JsAb4NJMsI29+OKLvf73xFNPPZXHH388o0aNyp577pk5c+bki1/8Yvbbb7+MHz8+V155ZVpbWzN9+vTaDQ1QI5s6Z44aNSqf//znM2PGjLS0tKSjoyOXXHJJ9t1330ydOrWGUwNse7Nnz85tt92WH//4x6mvr++570NjY2N22WWXNDY25uMf/3guuuiijBo1Kg0NDTn//PNzxBFH5PDDD6/x9ADb3ubOmx0dHbntttty4oknpqmpKYsXL86FF16Yo48+OpMmTarx9ADbn0q1Wq3WegjYkSxatCjvfve7N9h+5pln5qabbkq1Ws3cuXPzne98J52dnXnnO9+ZG264IRMmTKjBtAC1talz5je/+c1Mnz49f/jDH9LZ2ZnW1tZMmTIlX/jCF9Lc3FyDaQFqp1KpbHT797///cycOTNJsnr16lx88cW5/fbb8/LLL2fq1Km54YYbXJoJ2CFt7ry5dOnSfOQjH8kTTzyRVatWpa2tLaecckquuOKKNDQ0bONpAbZ/QgQAAAAAAFCMe0QAAAAAAADFCBEAAAAAAEAxQgQAAAAAAFCMEAEAAAAAABQjRAAAAAAAAMUIEQAAAAAAQDFCBAAAAAAAUIwQAQAA9DJz5sxMnz691mMAAACDxLBaDwAAAGw7lUplk4/PnTs3X/va11KtVrfRRAAAwGAnRAAAwA7k2Wef7fnzD3/4w1x11VVZsmRJz7a6urrU1dXVYjQAAGCQcmkmAADYgbS0tPR8NTY2plKp9NpWV1e3waWZJk+enPPPPz9z5szJ7rvvnubm5tx4441ZtWpVzjrrrNTX12fffffNvffe2+tYTzzxRE444YTU1dWlubk5Z5xxRv7xj39s41cMAADUmhABAABs1s0335zRo0fnN7/5Tc4///ycc845Of3003PkkUfm97//faZMmZIzzjgjL730UpKks7MzxxxzTA455JA89thjue+++7J8+fK8733vq/ErAQAAtjUhAgAA2KyDDz44V1xxRfbbb79cdtll2XnnnTN69OjMmjUr++23X6666qqsWLEiixcvTpJ84xvfyCGHHJIvfelLOeCAA3LIIYfke9/7XhYuXJi//vWvNX41AADAtuQeEQAAwGZNmjSp589Dhw5NU1NTJk6c2LOtubk5SfL8888nSf74xz9m4cKFG73fREdHRyZMmFB4YgAAYKAQIgAAgM0aPnx4r+8rlUqvbZVKJUmyfv36JMmLL76Yk08+OV/5ylc2eK6xY8cWnBQAABhohAgAAKDfHXroobnzzjvT3t6eYcP82gEAADsy94gAAAD63ezZs/PPf/4zH/zgB/Pb3/42HR0d+dnPfpazzjor69atq/V4AADANiREAAAA/a61tTUPPfRQ1q1blylTpmTixImZM2dORo4cmSFD/BoCAAA7kkq1Wq3WeggAAAAAAGBw8l+RAAAAAACAYoQIAAAAAACgGCECAAAAAAAoRogAAAAAAACKESIAAAAAAIBihAgAAAAAAKAYIQIAAAAAAChGiAAAAAAAAIoRIgAAAAAAgGKECAAAAAAAoBghAgAAAAAAKEaIAAAAAAAAivn/OkPb8btR7hwAAAAASUVORK5CYII=","text/plain":[""]},"execution_count":12,"metadata":{},"output_type":"execute_result"}],"source":["vad(audio_in_memory)"]},{"cell_type":"markdown","metadata":{"id":"LllNe0s3eq4u"},"source":["## Offline use\n","\n","Gating models and pipelines allows [me](https://herve.niderb.fr) to know a bit more about `pyannote.audio` user base and eventually help me write grant proposals to make `pyannote.audio` even better. Please fill this form as precisely as possible.\n","\n","For instance, before gating `pyannote/speaker-diarization`, I had no idea that so many people were relying on it in production. Hint: sponsors are more than welcome! maintaining open source libraries is time consuming.\n","\n","That being said: this whole authentication process does not prevent you from using official `pyannote.audio` models and pipelines offline (i.e. without going through the authentication process in every `docker run ...` or whatever you are using in production).\n","\n","* Step 1: download `config.yaml` of [`pyannote/voice-activity-detection`](https://hf.co/pyannote/voice-activity-detection) pipeline\n","\n","![](https://github.com/pyannote/pyannote-audio/blob/develop/tutorials/assets/download-pipeline.png?raw=1)\n","\n","* Step 2: download the `pytorch_model.bin` model\n","\n","![](https://github.com/pyannote/pyannote-audio/blob/develop/tutorials/assets/download-model.png?raw=1)\n","\n","* Step 3: edit `config.yaml` to point to the local model\n","\n","```diff\n","pipeline:\n"," name: pyannote.audio.pipelines.VoiceActivityDetection\n"," params:\n","- segmentation: pyannote/segmentation@Interspeech2021\n","+ segmentation: pytorch_model.bin\n","\n","params:\n"," min_duration_off: 0.09791355693027545\n"," min_duration_on: 0.05537587440407595\n"," offset: 0.4806866463041527\n"," onset: 0.8104268538848918\n","```\n","\n","* Step 4: load the pipeline"]},{"cell_type":"code","execution_count":null,"metadata":{"id":"a1bZGOoEeq4v","outputId":"a8851164-100c-4cc1-afd2-d387a5fc4fd5"},"outputs":[{"data":{"image/png":"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bPHixalUKu2+mpqaunpZQCdat25dzjzzzIwcOTKVSiWrVq1qd321Ws3ixYszcuTIDBw4MKeddlr+8pe/dM1igU7zVnvB3Llz95kRTj755K5ZLFBzS5Ysyfvf//7U1dVl2LBhmTlzZh566KF2tzETQM/3dvYCMwH0bMuWLctxxx2X+vr61NfXZ9KkSfntb3/bdn2t5oEOx4uVK1dm4cKF+epXv5r7778/H/7whzN9+vRs3ry5w3cOdF/HHHNMtm7d2va1adOmrl4S0In27NmT448/Ptdcc80bXr906dJcffXVueaaa3LvvfemqakpU6ZMybPPPvsOrxToTG+1FyTJtGnT2s0It9566zu4QqAzrV27NhdccEHuueee3H777XnppZcyderU7Nmzp+02ZgLo+d7OXpCYCaAnGzVqVL71rW9lw4YN2bBhQ04//fTMmDGjLVDUah6oVKvVakd+YOLEiTnhhBOybNmytmPjx4/PzJkzs2TJkg7dOdA9LV68OKtWrcrGjRu7eilAF6hUKrn55pszc+bMJK/+RcXIkSOzcOHCXHrppUmS1tbWDB8+PN/+9rdz/vnnd+Fqgc7y+r0gefWvLHft2rXPKzKAnumf//xnhg0blrVr1+YjH/mImQB6qdfvBYmZAHqjxsbGfOc738m8efNqNg906JUXL7zwQu67775MnTq13fGpU6fmrrvu6sipgG7u4YcfzsiRIzN27Nh8+tOfzt///veuXhLQRR577LFs27at3XzQv3//nHrqqeYD6IXWrFmTYcOG5aijjsr8+fOzffv2rl4S0El2796d5NVfViRmAuitXr8XvMZMAL3Dyy+/nBUrVmTPnj2ZNGlSTeeBDsWLHTt25OWXX87w4cPbHR8+fHi2bdvWoTsGuq+JEyfmhhtuyG233Zaf/OQn2bZtW0455ZTs3Lmzq5cGdIHXZgDzATB9+vTceOONueOOO/Ld73439957b04//fS0trZ29dKAGqtWq7nooovyoQ99KBMmTEhiJoDe6I32gsRMAL3Bpk2bMnjw4PTv3z8LFizIzTffnKOPPrqm80Df/VlYpVJpd7lare5zDOi5pk+f3vb9sccem0mTJuXwww/P9ddfn4suuqgLVwZ0JfMBMHv27LbvJ0yYkJNOOiljxozJb37zm5x11llduDKg1i688MI88MADufPOO/e5zkwAvcd/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","text/plain":[""]},"execution_count":21,"metadata":{},"output_type":"execute_result"}],"source":["# look ma: no hands!\n","offline_vad = Pipeline.from_pretrained(\"config.yaml\")\n","offline_vad(audio_in_memory)"]},{"cell_type":"code","execution_count":null,"metadata":{"id":"eepjEec8eq4w"},"outputs":[],"source":["# just checking output is the same\n","assert (vad(audio_in_memory) == offline_vad(audio_in_memory))"]}],"metadata":{"accelerator":"GPU","colab":{"gpuType":"T4","provenance":[{"file_id":"https://github.com/pyannote/pyannote-audio/blob/develop/tutorials/applying_a_pipeline.ipynb","timestamp":1704808199718}]},"kernelspec":{"display_name":"Python 3","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.10.13"},"vscode":{"interpreter":{"hash":"36a3a48a52702f18671693adf589423ec3f7db45d50f6ee539f1b0696bb58d43"}},"widgets":{"application/vnd.jupyter.widget-state+json":{"008a47e4d1174b188e75232fed325398":{"model_module":"@jupyter-widgets/controls","model_module_version":"1.5.0","model_name":"DescriptionStyleModel","state":{"_model_module":"@jupyter-widgets/controls","_model_module_version":"1.5.0","_model_name":"DescriptionStyleModel","_view_count":null,"_view_module":"@jupyter-widgets/base","_view_module_version":"1.2.0","_view_name":"StyleView","description_width":""}},"00ac431507a54c0d9a41244013b1c0f3":{"model_module":"@jupyter-widgets/base","model_module_version":"1.2.0","model_name":"LayoutModel","state":{"_model_module":"@jupyter-widgets/base","_model_module_version":"1.2.0","_model_name":"LayoutModel","_view_count":null,"_view_module":"@jupyter-widgets/base","_view_module_version":"1.2.0","_view_name":"LayoutView","align_content":null,"align_items":null,"align_self":null,"border":null,"bottom":null,"display":null,"flex":null,"flex_flow":null,"grid_area":null,"grid_auto_columns":null,"grid_auto_flow":null,"grid_auto_rows":null,"grid_column":null,"grid_gap":null,"grid_row":null,"grid_template_areas":null,"grid_template_columns":null,"grid_template_rows":null,"height":null,"justify_content":null,"justify_items":null,"left":null,"margin":null,"max_height":null,"max_width":null,"min_height":null,"min_width":null,"object_fit":null,"object_position":null,"order":null,"overflow":null,"overflow_x":null,"overflow_y":null,"padding":null,"right":null,"top":null,"visibility":null,"width":null}},"05283cf0054d412c9a1ebfcc44bf41cb":{"model_module":"@jupyter-widgets/controls","model_module_version":"1.5.0","model_name":"ProgressStyleModel","state":{"_model_module":"@jupyter-widgets/controls","_model_module_version":"1.5.0","_model_name":"ProgressStyleModel","_view_count":null,"_view_module":"@jupyter-widgets/base","_view_module_version":"1.2.0","_view_name":"StyleView","bar_color":null,"description_width":""}},"07bb94f0dcda45a9a5e2d553fd239106":{"model_module":"@jupyter-widgets/controls","model_module_version":"1.5.0","model_name":"DescriptionStyleModel","state":{"_model_module":"@jupyter-widgets/controls","_model_module_version":"1.5.0","_model_name":"DescriptionStyleModel","_view_count":null,"_view_module":"@jupyter-widgets/base","_view_module_version":"1.2.0","_view_name":"StyleView","description_width":""}},"0b127e22a6de4339aecc1e76a6719d7f":{"model_module":"@jupyter-widgets/controls","model_module_version":"1.5.0","model_name":"LabelModel","state":{"_dom_classes":[],"_model_module":"@jupyter-widgets/controls","_model_module_version":"1.5.0","_model_name":"LabelModel","_view_count":null,"_view_module":"@jupyter-widgets/controls","_view_module_version":"1.5.0","_view_name":"LabelView","description":"","description_tooltip":null,"layout":"IPY_MODEL_ae378b480ed747438bcbe147a7e8d277","placeholder":"​","style":"IPY_MODEL_b22a1d21940e4995b72642b003ae1301","value":"Your token has been saved in your configured git credential helpers (store)."}},"0b191fb0d6db4f1a98a641dc50445f1e":{"model_module":"@jupyter-widgets/controls","model_module_version":"1.5.0","model_name":"HBoxModel","state":{"_dom_classes":[],"_model_module":"@jupyter-widgets/controls","_model_module_version":"1.5.0","_model_name":"HBoxModel","_view_count":null,"_view_module":"@jupyter-widgets/controls","_view_module_version":"1.5.0","_view_name":"HBoxView","box_style":"","children":["IPY_MODEL_4a589ea883de4409b7a8275127747fa7","IPY_MODEL_b5f4829158cf4a5c8350966d8eacbf60","IPY_MODEL_7cab72ad0ace45d58d6954021082ace7"],"layout":"IPY_MODEL_5440ac4cffa0438c99c0daeca27a4087"}},"0d0dfc2576784812b6abf673752fa812":{"model_module":"@jupyter-widgets/base","model_module_version":"1.2.0","model_name":"LayoutModel","state":{"_model_module":"@jupyter-widgets/base","_model_module_version":"1.2.0","_model_name":"LayoutModel","_view_count":null,"_view_module":"@jupyter-widgets/base","_view_module_version":"1.2.0","_view_name":"LayoutView","align_content":null,"align_items":null,"align_self":null,"border":null,"bottom":null,"display":null,"flex":null,"flex_flow":null,"grid_area":null,"grid_auto_columns":null,"grid_auto_flow":null,"grid_auto_rows":null,"grid_column":null,"grid_gap":null,"grid_row":null,"grid_template_areas":null,"grid_template_columns":null,"grid_template_rows":null,"height":null,"justify_content":null,"justify_items":null,"left":null,"margin":null,"max_height":null,"max_width":null,"min_height":null,"min_width":null,"object_fit":null,"object_position":null,"order":null,"overflow":null,"overflow_x":null,"overflow_y":null,"padding":null,"right":null,"top":null,"visibility":null,"width":null}},"0fccc53081a34d58a46912d1ceae0533":{"model_module":"@jupyter-widgets/controls","model_module_version":"1.5.0","model_name":"FloatProgressModel","state":{"_dom_classes":[],"_model_module":"@jupyter-widgets/controls","_model_module_version":"1.5.0","_model_name":"FloatProgressModel","_view_count":null,"_view_module":"@jupyter-widgets/controls","_view_module_version":"1.5.0","_view_name":"ProgressView","bar_style":"success","description":"","description_tooltip":null,"layout":"IPY_MODEL_00ac431507a54c0d9a41244013b1c0f3","max":221,"min":0,"orientation":"horizontal","style":"IPY_MODEL_6f318bc3e900434a9134a79e4057f666","value":221}},"16244ab1dc76493d9fafad80a9b65700":{"model_module":"@jupyter-widgets/controls","model_module_version":"1.5.0","model_name":"DescriptionStyleModel","state":{"_model_module":"@jupyter-widgets/controls","_model_module_version":"1.5.0","_model_name":"DescriptionStyleModel","_view_count":null,"_view_module":"@jupyter-widgets/base","_view_module_version":"1.2.0","_view_name":"StyleView","description_width":""}},"1749a0e7fc6847849ab40ac7f764b699":{"model_module":"@jupyter-widgets/controls","model_module_version":"1.5.0","model_name":"DescriptionStyleModel","state":{"_model_module":"@jupyter-widgets/controls","_model_module_version":"1.5.0","_model_name":"DescriptionStyleModel","_view_count":null,"_view_module":"@jupyter-widgets/base","_view_module_version":"1.2.0","_view_name":"StyleView","description_width":""}},"17e14569a3f74cbf991b582c27fdf280":{"model_module":"@jupyter-widgets/controls","model_module_version":"1.5.0","model_name":"FloatProgressModel","state":{"_dom_classes":[],"_model_module":"@jupyter-widgets/controls","_model_module_version":"1.5.0","_model_name":"FloatProgressModel","_view_count":null,"_view_module":"@jupyter-widgets/controls","_view_module_version":"1.5.0","_view_name":"ProgressView","bar_style":"success","description":"","description_tooltip":null,"layout":"IPY_MODEL_e98b1f7ec5e04e748069340fa2fcec2d","max":469,"min":0,"orientation":"horizontal","style":"IPY_MODEL_616f35eccdd34bcdb5c9f700103ff538","value":469}},"185457147fe44751a1c6e7ae6ad23570":{"model_module":"@jupyter-widgets/base","model_module_version":"1.2.0","model_name":"LayoutModel","state":{"_model_module":"@jupyter-widgets/base","_model_module_version":"1.2.0","_model_name":"LayoutModel","_view_count":null,"_view_module":"@jupyter-widgets/base","_view_module_version":"1.2.0","_view_name":"LayoutView","align_content":null,"align_items":null,"align_self":null,"border":null,"bottom":null,"display":null,"flex":null,"flex_flow":null,"grid_area":null,"grid_auto_columns":null,"grid_auto_flow":null,"grid_auto_rows":null,"grid_column":null,"grid_gap":null,"grid_row":null,"grid_template_areas":null,"grid_template_columns":null,"grid_template_rows":null,"height":null,"justify_content":null,"justify_items":null,"left":null,"margin":null,"max_height":null,"max_width":null,"min_height":null,"min_width":null,"object_fit":null,"object_position":null,"order":null,"overflow":null,"overflow_x":null,"overflow_y":null,"padding":null,"right":null,"top":null,"visibility":null,"width":null}},"1b5f49211db54348924a05482ca7379d":{"model_module":"@jupyter-widgets/controls","model_module_version":"1.5.0","model_name":"LabelModel","state":{"_dom_classes":[],"_model_module":"@jupyter-widgets/controls","_model_module_version":"1.5.0","_model_name":"LabelModel","_view_count":null,"_view_module":"@jupyter-widgets/controls","_view_module_version":"1.5.0","_view_name":"LabelView","description":"","description_tooltip":null,"layout":"IPY_MODEL_dc9c065286e544df921e5bc4a51faf64","placeholder":"​","style":"IPY_MODEL_16244ab1dc76493d9fafad80a9b65700","value":"Login successful"}},"1d051eb2d87e4671aa08039761c7899a":{"model_module":"@jupyter-widgets/controls","model_module_version":"1.5.0","model_name":"HTMLModel","state":{"_dom_classes":[],"_model_module":"@jupyter-widgets/controls","_model_module_version":"1.5.0","_model_name":"HTMLModel","_view_count":null,"_view_module":"@jupyter-widgets/controls","_view_module_version":"1.5.0","_view_name":"HTMLView","description":"","description_tooltip":null,"layout":"IPY_MODEL_be8b64ce7f8247499c8bbcb62c5dd902","placeholder":"​","style":"IPY_MODEL_491c3dcba4474a52b860080fa7a627e7","value":"pytorch_model.bin: 100%"}},"1d97d11a99454cc990cc5e374d0f8197":{"model_module":"@jupyter-widgets/controls","model_module_version":"1.5.0","model_name":"HBoxModel","state":{"_dom_classes":[],"_model_module":"@jupyter-widgets/controls","_model_module_version":"1.5.0","_model_name":"HBoxModel","_view_count":null,"_view_module":"@jupyter-widgets/controls","_view_module_version":"1.5.0","_view_name":"HBoxView","box_style":"","children":["IPY_MODEL_425146d4e0fb453486629d9d6af0a999","IPY_MODEL_8fad50e0475341d9801e9f86e04e15c7","IPY_MODEL_ea03f9526a7440a0a9a281ee877892fd"],"layout":"IPY_MODEL_d1863b2c9ebc4efa9cac2dad7dfaf53a"}},"1dd6bfb824ba4919ba392e0d4cd5ac82":{"model_module":"@jupyter-widgets/controls","model_module_version":"1.5.0","model_name":"DescriptionStyleModel","state":{"_model_module":"@jupyter-widgets/controls","_model_module_version":"1.5.0","_model_name":"DescriptionStyleModel","_view_count":null,"_view_module":"@jupyter-widgets/base","_view_module_version":"1.2.0","_view_name":"StyleView","description_width":""}},"1e53e26668aa4f8dabdd6973b79b5b9f":{"model_module":"@jupyter-widgets/controls","model_module_version":"1.5.0","model_name":"ProgressStyleModel","state":{"_model_module":"@jupyter-widgets/controls","_model_module_version":"1.5.0","_model_name":"ProgressStyleModel","_view_count":null,"_view_module":"@jupyter-widgets/base","_view_module_version":"1.2.0","_view_name":"StyleView","bar_color":null,"description_width":""}},"1f3be36a57074214a5f92e08165e41be":{"model_module":"@jupyter-widgets/base","model_module_version":"1.2.0","model_name":"LayoutModel","state":{"_model_module":"@jupyter-widgets/base","_model_module_version":"1.2.0","_model_name":"LayoutModel","_view_count":null,"_view_module":"@jupyter-widgets/base","_view_module_version":"1.2.0","_view_name":"LayoutView","align_content":null,"align_items":null,"align_self":null,"border":null,"bottom":null,"display":null,"flex":null,"flex_flow":null,"grid_area":null,"grid_auto_columns":null,"grid_auto_flow":null,"grid_auto_rows":null,"grid_column":null,"grid_gap":null,"grid_row":null,"grid_template_areas":null,"grid_template_columns":null,"grid_template_rows":null,"height":null,"justify_content":null,"justify_items":null,"left":null,"margin":null,"max_height":null,"max_width":null,"min_height":null,"min_width":null,"object_fit":null,"object_position":null,"order":null,"overflow":null,"overflow_x":null,"overflow_y":null,"padding":null,"right":null,"top":null,"visibility":null,"width":null}},"253408a6cab947c7b9ae40a14e255328":{"model_module":"@jupyter-widgets/base","model_module_version":"1.2.0","model_name":"LayoutModel","state":{"_model_module":"@jupyter-widgets/base","_model_module_version":"1.2.0","_model_name":"LayoutModel","_view_count":null,"_view_module":"@jupyter-widgets/base","_view_module_version":"1.2.0","_view_name":"LayoutView","align_content":null,"align_items":null,"align_self":null,"border":null,"bottom":null,"display":null,"flex":null,"flex_flow":null,"grid_area":null,"grid_auto_columns":null,"grid_auto_flow":null,"grid_auto_rows":null,"grid_column":null,"grid_gap":null,"grid_row":null,"grid_template_areas":null,"grid_template_columns":null,"grid_template_rows":null,"height":null,"justify_content":null,"justify_items":null,"left":null,"margin":null,"max_height":null,"max_width":null,"min_height":null,"min_width":null,"object_fit":null,"object_position":null,"order":null,"overflow":null,"overflow_x":null,"overflow_y":null,"padding":null,"right":null,"top":null,"visibility":null,"width":null}},"275642719b694328ad3b0fb06b53e42a":{"model_module":"@jupyter-widgets/controls","model_module_version":"1.5.0","model_name":"DescriptionStyleModel","state":{"_model_module":"@jupyter-widgets/controls","_model_module_version":"1.5.0","_model_name":"DescriptionStyleModel","_view_count":null,"_view_module":"@jupyter-widgets/base","_view_module_version":"1.2.0","_view_name":"StyleView","description_width":""}},"2a72c7660c2f498089c63c78eaa69fc8":{"model_module":"@jupyter-widgets/base","model_module_version":"1.2.0","model_name":"LayoutModel","state":{"_model_module":"@jupyter-widgets/base","_model_module_version":"1.2.0","_model_name":"LayoutModel","_view_count":null,"_view_module":"@jupyter-widgets/base","_view_module_version":"1.2.0","_view_name":"LayoutView","align_content":null,"align_items":null,"align_self":null,"border":null,"bottom":null,"display":null,"flex":null,"flex_flow":null,"grid_area":null,"grid_auto_columns":null,"grid_auto_flow":null,"grid_auto_rows":null,"grid_column":null,"grid_gap":null,"grid_row":null,"grid_template_areas":null,"grid_template_columns":null,"grid_template_rows":null,"height":null,"justify_content":null,"justify_items":null,"left":null,"margin":null,"max_height":null,"max_width":null,"min_height":null,"min_width":null,"object_fit":null,"object_position":null,"order":null,"overflow":null,"overflow_x":null,"overflow_y":null,"padding":null,"right":null,"top":null,"visibility":null,"width":null}},"2be7c1f5fe32462f8d1cd7ea57cfbf3a":{"model_module":"@jupyter-widgets/base","model_module_version":"1.2.0","model_name":"LayoutModel","state":{"_model_module":"@jupyter-widgets/base","_model_module_version":"1.2.0","_model_name":"LayoutModel","_view_count":null,"_view_module":"@jupyter-widgets/base","_view_module_version":"1.2.0","_view_name":"LayoutView","align_content":null,"align_items":null,"align_self":null,"border":null,"bottom":null,"display":null,"flex":null,"flex_flow":null,"grid_area":null,"grid_auto_columns":null,"grid_auto_flow":null,"grid_auto_rows":null,"grid_column":null,"grid_gap":null,"grid_row":null,"grid_template_areas":null,"grid_template_columns":null,"grid_template_rows":null,"height":null,"justify_content":null,"justify_items":null,"left":null,"margin":null,"max_height":null,"max_width":null,"min_height":null,"min_width":null,"object_fit":null,"object_position":null,"order":null,"overflow":null,"overflow_x":null,"overflow_y":null,"padding":null,"right":null,"top":null,"visibility":null,"width":null}},"2c0b1ed212544e14b4934e036e8736d7":{"model_module":"@jupyter-widgets/controls","model_module_version":"1.5.0","model_name":"HTMLModel","state":{"_dom_classes":[],"_model_module":"@jupyter-widgets/controls","_model_module_version":"1.5.0","_model_name":"HTMLModel","_view_count":null,"_view_module":"@jupyter-widgets/controls","_view_module_version":"1.5.0","_view_name":"HTMLView","description":"","description_tooltip":null,"layout":"IPY_MODEL_3be13f7f05da47b1ae3795ead9f2546a","placeholder":"​","style":"IPY_MODEL_07bb94f0dcda45a9a5e2d553fd239106","value":" 277/277 [00:00<00:00, 14.5kB/s]"}},"30864d7b4d074994ba643c73875a67b8":{"model_module":"@jupyter-widgets/base","model_module_version":"1.2.0","model_name":"LayoutModel","state":{"_model_module":"@jupyter-widgets/base","_model_module_version":"1.2.0","_model_name":"LayoutModel","_view_count":null,"_view_module":"@jupyter-widgets/base","_view_module_version":"1.2.0","_view_name":"LayoutView","align_content":null,"align_items":null,"align_self":null,"border":null,"bottom":null,"display":null,"flex":null,"flex_flow":null,"grid_area":null,"grid_auto_columns":null,"grid_auto_flow":null,"grid_auto_rows":null,"grid_column":null,"grid_gap":null,"grid_row":null,"grid_template_areas":null,"grid_template_columns":null,"grid_template_rows":null,"height":null,"justify_content":null,"justify_items":null,"left":null,"margin":null,"max_height":null,"max_width":null,"min_height":null,"min_width":null,"object_fit":null,"object_position":null,"order":null,"overflow":null,"overflow_x":null,"overflow_y":null,"padding":null,"right":null,"top":null,"visibility":null,"width":null}},"36f60aa99ea84b739f066c6ee216f159":{"model_module":"@jupyter-widgets/controls","model_module_version":"1.5.0","model_name":"DescriptionStyleModel","state":{"_model_module":"@jupyter-widgets/controls","_model_module_version":"1.5.0","_model_name":"DescriptionStyleModel","_view_count":null,"_view_module":"@jupyter-widgets/base","_view_module_version":"1.2.0","_view_name":"StyleView","description_width":""}},"39cd6fe37b6f4476b6032c29f026d570":{"model_module":"@jupyter-widgets/controls","model_module_version":"1.5.0","model_name":"HTMLModel","state":{"_dom_classes":[],"_model_module":"@jupyter-widgets/controls","_model_module_version":"1.5.0","_model_name":"HTMLModel","_view_count":null,"_view_module":"@jupyter-widgets/controls","_view_module_version":"1.5.0","_view_name":"HTMLView","description":"","description_tooltip":null,"layout":"IPY_MODEL_7580595b498a4c50b748af9df67132e2","placeholder":"​","style":"IPY_MODEL_3f1d750804a54d78a6abff2623441360","value":" 221/221 [00:00<00:00, 14.0kB/s]"}},"3bb60a8db7c0406f8debdc8dd88bcdb4":{"model_module":"@jupyter-widgets/controls","model_module_version":"1.5.0","model_name":"HBoxModel","state":{"_dom_classes":[],"_model_module":"@jupyter-widgets/controls","_model_module_version":"1.5.0","_model_name":"HBoxModel","_view_count":null,"_view_module":"@jupyter-widgets/controls","_view_module_version":"1.5.0","_view_name":"HBoxView","box_style":"","children":["IPY_MODEL_bf644ae3e2894787bb416740749200cd","IPY_MODEL_0fccc53081a34d58a46912d1ceae0533","IPY_MODEL_39cd6fe37b6f4476b6032c29f026d570"],"layout":"IPY_MODEL_87a0e712c0b045449b98ee368c62fff2"}},"3be13f7f05da47b1ae3795ead9f2546a":{"model_module":"@jupyter-widgets/base","model_module_version":"1.2.0","model_name":"LayoutModel","state":{"_model_module":"@jupyter-widgets/base","_model_module_version":"1.2.0","_model_name":"LayoutModel","_view_count":null,"_view_module":"@jupyter-widgets/base","_view_module_version":"1.2.0","_view_name":"LayoutView","align_content":null,"align_items":null,"align_self":null,"border":null,"bottom":null,"display":null,"flex":null,"flex_flow":null,"grid_area":null,"grid_auto_columns":null,"grid_auto_flow":null,"grid_auto_rows":null,"grid_column":null,"grid_gap":null,"grid_row":null,"grid_template_areas":null,"grid_template_columns":null,"grid_template_rows":null,"height":null,"justify_content":null,"justify_items":null,"left":null,"margin":null,"max_height":null,"max_width":null,"min_height":null,"min_width":null,"object_fit":null,"object_position":null,"order":null,"overflow":null,"overflow_x":null,"overflow_y":null,"padding":null,"right":null,"top":null,"visibility":null,"width":null}},"3f1d750804a54d78a6abff2623441360":{"model_module":"@jupyter-widgets/controls","model_module_version":"1.5.0","model_name":"DescriptionStyleModel","state":{"_model_module":"@jupyter-widgets/controls","_model_module_version":"1.5.0","_model_name":"DescriptionStyleModel","_view_count":null,"_view_module":"@jupyter-widgets/base","_view_module_version":"1.2.0","_view_name":"StyleView","description_width":""}},"3f500b1182a945c3b8b546b1bd04f98e":{"model_module":"@jupyter-widgets/controls","model_module_version":"1.5.0","model_name":"DescriptionStyleModel","state":{"_model_module":"@jupyter-widgets/controls","_model_module_version":"1.5.0","_model_name":"DescriptionStyleModel","_view_count":null,"_view_module":"@jupyter-widgets/base","_view_module_version":"1.2.0","_view_name":"StyleView","description_width":""}},"3f69734124f7449da0efffbbfd1153fe":{"model_module":"@jupyter-widgets/base","model_module_version":"1.2.0","model_name":"LayoutModel","state":{"_model_module":"@jupyter-widgets/base","_model_module_version":"1.2.0","_model_name":"LayoutModel","_view_count":null,"_view_module":"@jupyter-widgets/base","_view_module_version":"1.2.0","_view_name":"LayoutView","align_content":null,"align_items":null,"align_self":null,"border":null,"bottom":null,"display":null,"flex":null,"flex_flow":null,"grid_area":null,"grid_auto_columns":null,"grid_auto_flow":null,"grid_auto_rows":null,"grid_column":null,"grid_gap":null,"grid_row":null,"grid_template_areas":null,"grid_template_columns":null,"grid_template_rows":null,"height":null,"justify_content":null,"justify_items":null,"left":null,"margin":null,"max_height":null,"max_width":null,"min_height":null,"min_width":null,"object_fit":null,"object_position":null,"order":null,"overflow":null,"overflow_x":null,"overflow_y":null,"padding":null,"right":null,"top":null,"visibility":null,"width":null}},"425146d4e0fb453486629d9d6af0a999":{"model_module":"@jupyter-widgets/controls","model_module_version":"1.5.0","model_name":"HTMLModel","state":{"_dom_classes":[],"_model_module":"@jupyter-widgets/controls","_model_module_version":"1.5.0","_model_name":"HTMLModel","_view_count":null,"_view_module":"@jupyter-widgets/controls","_view_module_version":"1.5.0","_view_name":"HTMLView","description":"","description_tooltip":null,"layout":"IPY_MODEL_8bda58a4c0c6430ca1470282ddbe8222","placeholder":"​","style":"IPY_MODEL_5d38b6ceec1844068f48da7bedf471fa","value":"config.yaml: 100%"}},"45c2352ba41b46288c8ba74c661e1f85":{"model_module":"@jupyter-widgets/controls","model_module_version":"1.5.0","model_name":"ButtonModel","state":{"_dom_classes":[],"_model_module":"@jupyter-widgets/controls","_model_module_version":"1.5.0","_model_name":"ButtonModel","_view_count":null,"_view_module":"@jupyter-widgets/controls","_view_module_version":"1.5.0","_view_name":"ButtonView","button_style":"","description":"Login","disabled":false,"icon":"","layout":"IPY_MODEL_c3b3069a93994e55b993cab04c066f17","style":"IPY_MODEL_f77186e2976d4a7daa798fd9f0f7b4cb","tooltip":""}},"46ac2d0bfedc47c8836e8dde0fc91662":{"model_module":"@jupyter-widgets/base","model_module_version":"1.2.0","model_name":"LayoutModel","state":{"_model_module":"@jupyter-widgets/base","_model_module_version":"1.2.0","_model_name":"LayoutModel","_view_count":null,"_view_module":"@jupyter-widgets/base","_view_module_version":"1.2.0","_view_name":"LayoutView","align_content":null,"align_items":null,"align_self":null,"border":null,"bottom":null,"display":null,"flex":null,"flex_flow":null,"grid_area":null,"grid_auto_columns":null,"grid_auto_flow":null,"grid_auto_rows":null,"grid_column":null,"grid_gap":null,"grid_row":null,"grid_template_areas":null,"grid_template_columns":null,"grid_template_rows":null,"height":null,"justify_content":null,"justify_items":null,"left":null,"margin":null,"max_height":null,"max_width":null,"min_height":null,"min_width":null,"object_fit":null,"object_position":null,"order":null,"overflow":null,"overflow_x":null,"overflow_y":null,"padding":null,"right":null,"top":null,"visibility":null,"width":null}},"491c3dcba4474a52b860080fa7a627e7":{"model_module":"@jupyter-widgets/controls","model_module_version":"1.5.0","model_name":"DescriptionStyleModel","state":{"_model_module":"@jupyter-widgets/controls","_model_module_version":"1.5.0","_model_name":"DescriptionStyleModel","_view_count":null,"_view_module":"@jupyter-widgets/base","_view_module_version":"1.2.0","_view_name":"StyleView","description_width":""}},"4a589ea883de4409b7a8275127747fa7":{"model_module":"@jupyter-widgets/controls","model_module_version":"1.5.0","model_name":"HTMLModel","state":{"_dom_classes":[],"_model_module":"@jupyter-widgets/controls","_model_module_version":"1.5.0","_model_name":"HTMLModel","_view_count":null,"_view_module":"@jupyter-widgets/controls","_view_module_version":"1.5.0","_view_name":"HTMLView","description":"","description_tooltip":null,"layout":"IPY_MODEL_0d0dfc2576784812b6abf673752fa812","placeholder":"​","style":"IPY_MODEL_84e416e01cfa4a79b0294a44cfd77f32","value":"pytorch_model.bin: 100%"}},"4abbe0d8e0fa4e1b9d712743013b2d4e":{"model_module":"@jupyter-widgets/base","model_module_version":"1.2.0","model_name":"LayoutModel","state":{"_model_module":"@jupyter-widgets/base","_model_module_version":"1.2.0","_model_name":"LayoutModel","_view_count":null,"_view_module":"@jupyter-widgets/base","_view_module_version":"1.2.0","_view_name":"LayoutView","align_content":null,"align_items":null,"align_self":null,"border":null,"bottom":null,"display":null,"flex":null,"flex_flow":null,"grid_area":null,"grid_auto_columns":null,"grid_auto_flow":null,"grid_auto_rows":null,"grid_column":null,"grid_gap":null,"grid_row":null,"grid_template_areas":null,"grid_template_columns":null,"grid_template_rows":null,"height":null,"justify_content":null,"justify_items":null,"left":null,"margin":null,"max_height":null,"max_width":null,"min_height":null,"min_width":null,"object_fit":null,"object_position":null,"order":null,"overflow":null,"overflow_x":null,"overflow_y":null,"padding":null,"right":null,"top":null,"visibility":null,"width":null}},"4e0ca7f084804d30a89cb9dc439b6cdc":{"model_module":"@jupyter-widgets/controls","model_module_version":"1.5.0","model_name":"HTMLModel","state":{"_dom_classes":[],"_model_module":"@jupyter-widgets/controls","_model_module_version":"1.5.0","_model_name":"HTMLModel","_view_count":null,"_view_module":"@jupyter-widgets/controls","_view_module_version":"1.5.0","_view_name":"HTMLView","description":"","description_tooltip":null,"layout":"IPY_MODEL_185457147fe44751a1c6e7ae6ad23570","placeholder":"​","style":"IPY_MODEL_b02b253086e34249ae1d896a75a08960","value":" 469/469 [00:00<00:00, 34.3kB/s]"}},"4f0d63f098b0491097c6b72f3baee04f":{"model_module":"@jupyter-widgets/controls","model_module_version":"1.5.0","model_name":"HTMLModel","state":{"_dom_classes":[],"_model_module":"@jupyter-widgets/controls","_model_module_version":"1.5.0","_model_name":"HTMLModel","_view_count":null,"_view_module":"@jupyter-widgets/controls","_view_module_version":"1.5.0","_view_name":"HTMLView","description":"","description_tooltip":null,"layout":"IPY_MODEL_6358920ecd46403a87cca46509465076","placeholder":"​","style":"IPY_MODEL_4f25b89365b24056b803119d415ac056","value":" 17.7M/17.7M [00:00<00:00, 66.5MB/s]"}},"4f25b89365b24056b803119d415ac056":{"model_module":"@jupyter-widgets/controls","model_module_version":"1.5.0","model_name":"DescriptionStyleModel","state":{"_model_module":"@jupyter-widgets/controls","_model_module_version":"1.5.0","_model_name":"DescriptionStyleModel","_view_count":null,"_view_module":"@jupyter-widgets/base","_view_module_version":"1.2.0","_view_name":"StyleView","description_width":""}},"5033834cc66f49efaa16b240245ec1d3":{"model_module":"@jupyter-widgets/controls","model_module_version":"1.5.0","model_name":"LabelModel","state":{"_dom_classes":[],"_model_module":"@jupyter-widgets/controls","_model_module_version":"1.5.0","_model_name":"LabelModel","_view_count":null,"_view_module":"@jupyter-widgets/controls","_view_module_version":"1.5.0","_view_name":"LabelView","description":"","description_tooltip":null,"layout":"IPY_MODEL_1f3be36a57074214a5f92e08165e41be","placeholder":"​","style":"IPY_MODEL_275642719b694328ad3b0fb06b53e42a","value":"Token is valid (permission: write)."}},"514552137d7442368b39aaddce056bb8":{"model_module":"@jupyter-widgets/controls","model_module_version":"1.5.0","model_name":"HBoxModel","state":{"_dom_classes":[],"_model_module":"@jupyter-widgets/controls","_model_module_version":"1.5.0","_model_name":"HBoxModel","_view_count":null,"_view_module":"@jupyter-widgets/controls","_view_module_version":"1.5.0","_view_name":"HBoxView","box_style":"","children":["IPY_MODEL_f744ac29ccdd4d9d91050fabaed13e16","IPY_MODEL_f18c80869ccc4ce1b2a215293d493e19","IPY_MODEL_2c0b1ed212544e14b4934e036e8736d7"],"layout":"IPY_MODEL_9988b4433d6e4c58a819a2e1b54f57b2"}},"517a1b1faec045f7847ca84f0538f4e1":{"model_module":"@jupyter-widgets/base","model_module_version":"1.2.0","model_name":"LayoutModel","state":{"_model_module":"@jupyter-widgets/base","_model_module_version":"1.2.0","_model_name":"LayoutModel","_view_count":null,"_view_module":"@jupyter-widgets/base","_view_module_version":"1.2.0","_view_name":"LayoutView","align_content":null,"align_items":null,"align_self":null,"border":null,"bottom":null,"display":null,"flex":null,"flex_flow":null,"grid_area":null,"grid_auto_columns":null,"grid_auto_flow":null,"grid_auto_rows":null,"grid_column":null,"grid_gap":null,"grid_row":null,"grid_template_areas":null,"grid_template_columns":null,"grid_template_rows":null,"height":null,"justify_content":null,"justify_items":null,"left":null,"margin":null,"max_height":null,"max_width":null,"min_height":null,"min_width":null,"object_fit":null,"object_position":null,"order":null,"overflow":null,"overflow_x":null,"overflow_y":null,"padding":null,"right":null,"top":null,"visibility":null,"width":null}},"5253489738b249f69b30f1c84884a95a":{"model_module":"@jupyter-widgets/base","model_module_version":"1.2.0","model_name":"LayoutModel","state":{"_model_module":"@jupyter-widgets/base","_model_module_version":"1.2.0","_model_name":"LayoutModel","_view_count":null,"_view_module":"@jupyter-widgets/base","_view_module_version":"1.2.0","_view_name":"LayoutView","align_content":null,"align_items":null,"align_self":null,"border":null,"bottom":null,"display":null,"flex":null,"flex_flow":null,"grid_area":null,"grid_auto_columns":null,"grid_auto_flow":null,"grid_auto_rows":null,"grid_column":null,"grid_gap":null,"grid_row":null,"grid_template_areas":null,"grid_template_columns":null,"grid_template_rows":null,"height":null,"justify_content":null,"justify_items":null,"left":null,"margin":null,"max_height":null,"max_width":null,"min_height":null,"min_width":null,"object_fit":null,"object_position":null,"order":null,"overflow":null,"overflow_x":null,"overflow_y":null,"padding":null,"right":null,"top":null,"visibility":null,"width":null}},"5440ac4cffa0438c99c0daeca27a4087":{"model_module":"@jupyter-widgets/base","model_module_version":"1.2.0","model_name":"LayoutModel","state":{"_model_module":"@jupyter-widgets/base","_model_module_version":"1.2.0","_model_name":"LayoutModel","_view_count":null,"_view_module":"@jupyter-widgets/base","_view_module_version":"1.2.0","_view_name":"LayoutView","align_content":null,"align_items":null,"align_self":null,"border":null,"bottom":null,"display":null,"flex":null,"flex_flow":null,"grid_area":null,"grid_auto_columns":null,"grid_auto_flow":null,"grid_auto_rows":null,"grid_column":null,"grid_gap":null,"grid_row":null,"grid_template_areas":null,"grid_template_columns":null,"grid_template_rows":null,"height":null,"justify_content":null,"justify_items":null,"left":null,"margin":null,"max_height":null,"max_width":null,"min_height":null,"min_width":null,"object_fit":null,"object_position":null,"order":null,"overflow":null,"overflow_x":null,"overflow_y":null,"padding":null,"right":null,"top":null,"visibility":null,"width":null}},"54eacc5604f64f658617cde596a728dd":{"model_module":"@jupyter-widgets/base","model_module_version":"1.2.0","model_name":"LayoutModel","state":{"_model_module":"@jupyter-widgets/base","_model_module_version":"1.2.0","_model_name":"LayoutModel","_view_count":null,"_view_module":"@jupyter-widgets/base","_view_module_version":"1.2.0","_view_name":"LayoutView","align_content":null,"align_items":null,"align_self":null,"border":null,"bottom":null,"display":null,"flex":null,"flex_flow":null,"grid_area":null,"grid_auto_columns":null,"grid_auto_flow":null,"grid_auto_rows":null,"grid_column":null,"grid_gap":null,"grid_row":null,"grid_template_areas":null,"grid_template_columns":null,"grid_template_rows":null,"height":null,"justify_content":null,"justify_items":null,"left":null,"margin":null,"max_height":null,"max_width":null,"min_height":null,"min_width":null,"object_fit":null,"object_position":null,"order":null,"overflow":null,"overflow_x":null,"overflow_y":null,"padding":null,"right":null,"top":null,"visibility":null,"width":null}},"57ef34701b594a60a9fd269943b49888":{"model_module":"@jupyter-widgets/controls","model_module_version":"1.5.0","model_name":"HBoxModel","state":{"_dom_classes":[],"_model_module":"@jupyter-widgets/controls","_model_module_version":"1.5.0","_model_name":"HBoxModel","_view_count":null,"_view_module":"@jupyter-widgets/controls","_view_module_version":"1.5.0","_view_name":"HBoxView","box_style":"","children":["IPY_MODEL_1d051eb2d87e4671aa08039761c7899a","IPY_MODEL_9537f195677745cba18618764b2290ab","IPY_MODEL_4f0d63f098b0491097c6b72f3baee04f"],"layout":"IPY_MODEL_f7be373f08c64c8bb5b6e070a7373cca"}},"58b140d0453a4a219bc64e0152cc5c5e":{"model_module":"@jupyter-widgets/controls","model_module_version":"1.5.0","model_name":"DescriptionStyleModel","state":{"_model_module":"@jupyter-widgets/controls","_model_module_version":"1.5.0","_model_name":"DescriptionStyleModel","_view_count":null,"_view_module":"@jupyter-widgets/base","_view_module_version":"1.2.0","_view_name":"StyleView","description_width":""}},"58e423b86bf349aa89fc81a2b0d0f697":{"model_module":"@jupyter-widgets/base","model_module_version":"1.2.0","model_name":"LayoutModel","state":{"_model_module":"@jupyter-widgets/base","_model_module_version":"1.2.0","_model_name":"LayoutModel","_view_count":null,"_view_module":"@jupyter-widgets/base","_view_module_version":"1.2.0","_view_name":"LayoutView","align_content":null,"align_items":null,"align_self":null,"border":null,"bottom":null,"display":null,"flex":null,"flex_flow":null,"grid_area":null,"grid_auto_columns":null,"grid_auto_flow":null,"grid_auto_rows":null,"grid_column":null,"grid_gap":null,"grid_row":null,"grid_template_areas":null,"grid_template_columns":null,"grid_template_rows":null,"height":null,"justify_content":null,"justify_items":null,"left":null,"margin":null,"max_height":null,"max_width":null,"min_height":null,"min_width":null,"object_fit":null,"object_position":null,"order":null,"overflow":null,"overflow_x":null,"overflow_y":null,"padding":null,"right":null,"top":null,"visibility":null,"width":null}},"5a2a95f41f014663b5d131635844e3c8":{"model_module":"@jupyter-widgets/controls","model_module_version":"1.5.0","model_name":"HBoxModel","state":{"_dom_classes":[],"_model_module":"@jupyter-widgets/controls","_model_module_version":"1.5.0","_model_name":"HBoxModel","_view_count":null,"_view_module":"@jupyter-widgets/controls","_view_module_version":"1.5.0","_view_name":"HBoxView","box_style":"","children":["IPY_MODEL_f8df65e5ad6444648681230f415b8d08","IPY_MODEL_17e14569a3f74cbf991b582c27fdf280","IPY_MODEL_4e0ca7f084804d30a89cb9dc439b6cdc"],"layout":"IPY_MODEL_d304f698c6f34f3692548267ca0aba47"}},"5cc77ca8ba304ad88342ed6ced6c6a4a":{"model_module":"@jupyter-widgets/controls","model_module_version":"1.5.0","model_name":"DescriptionStyleModel","state":{"_model_module":"@jupyter-widgets/controls","_model_module_version":"1.5.0","_model_name":"DescriptionStyleModel","_view_count":null,"_view_module":"@jupyter-widgets/base","_view_module_version":"1.2.0","_view_name":"StyleView","description_width":""}},"5d38b6ceec1844068f48da7bedf471fa":{"model_module":"@jupyter-widgets/controls","model_module_version":"1.5.0","model_name":"DescriptionStyleModel","state":{"_model_module":"@jupyter-widgets/controls","_model_module_version":"1.5.0","_model_name":"DescriptionStyleModel","_view_count":null,"_view_module":"@jupyter-widgets/base","_view_module_version":"1.2.0","_view_name":"StyleView","description_width":""}},"616f35eccdd34bcdb5c9f700103ff538":{"model_module":"@jupyter-widgets/controls","model_module_version":"1.5.0","model_name":"ProgressStyleModel","state":{"_model_module":"@jupyter-widgets/controls","_model_module_version":"1.5.0","_model_name":"ProgressStyleModel","_view_count":null,"_view_module":"@jupyter-widgets/base","_view_module_version":"1.2.0","_view_name":"StyleView","bar_color":null,"description_width":""}},"6358920ecd46403a87cca46509465076":{"model_module":"@jupyter-widgets/base","model_module_version":"1.2.0","model_name":"LayoutModel","state":{"_model_module":"@jupyter-widgets/base","_model_module_version":"1.2.0","_model_name":"LayoutModel","_view_count":null,"_view_module":"@jupyter-widgets/base","_view_module_version":"1.2.0","_view_name":"LayoutView","align_content":null,"align_items":null,"align_self":null,"border":null,"bottom":null,"display":null,"flex":null,"flex_flow":null,"grid_area":null,"grid_auto_columns":null,"grid_auto_flow":null,"grid_auto_rows":null,"grid_column":null,"grid_gap":null,"grid_row":null,"grid_template_areas":null,"grid_template_columns":null,"grid_template_rows":null,"height":null,"justify_content":null,"justify_items":null,"left":null,"margin":null,"max_height":null,"max_width":null,"min_height":null,"min_width":null,"object_fit":null,"object_position":null,"order":null,"overflow":null,"overflow_x":null,"overflow_y":null,"padding":null,"right":null,"top":null,"visibility":null,"width":null}},"6412ef268e11484f8bbcdb510f66ee21":{"model_module":"@jupyter-widgets/controls","model_module_version":"1.5.0","model_name":"HBoxModel","state":{"_dom_classes":[],"_model_module":"@jupyter-widgets/controls","_model_module_version":"1.5.0","_model_name":"HBoxModel","_view_count":null,"_view_module":"@jupyter-widgets/controls","_view_module_version":"1.5.0","_view_name":"HBoxView","box_style":"","children":["IPY_MODEL_a987408c2f994329a9a80208b22e3c52","IPY_MODEL_9446f61936c4421d9610464984890353","IPY_MODEL_a80c0fb6a1254bb9a00741c1346b9d9a"],"layout":"IPY_MODEL_b55e95f31216480fa6c81bd1b57ad729"}},"6556790d1997431a8476447297e3f595":{"model_module":"@jupyter-widgets/controls","model_module_version":"1.5.0","model_name":"DescriptionStyleModel","state":{"_model_module":"@jupyter-widgets/controls","_model_module_version":"1.5.0","_model_name":"DescriptionStyleModel","_view_count":null,"_view_module":"@jupyter-widgets/base","_view_module_version":"1.2.0","_view_name":"StyleView","description_width":""}},"661c7494ef2d47c794e6236e5f2c8978":{"model_module":"@jupyter-widgets/controls","model_module_version":"1.5.0","model_name":"ProgressStyleModel","state":{"_model_module":"@jupyter-widgets/controls","_model_module_version":"1.5.0","_model_name":"ProgressStyleModel","_view_count":null,"_view_module":"@jupyter-widgets/base","_view_module_version":"1.2.0","_view_name":"StyleView","bar_color":null,"description_width":""}},"668a49e70c2b4c8a9dcb534cb30714d6":{"model_module":"@jupyter-widgets/controls","model_module_version":"1.5.0","model_name":"DescriptionStyleModel","state":{"_model_module":"@jupyter-widgets/controls","_model_module_version":"1.5.0","_model_name":"DescriptionStyleModel","_view_count":null,"_view_module":"@jupyter-widgets/base","_view_module_version":"1.2.0","_view_name":"StyleView","description_width":""}},"686b58e0ccee468f938ea5659f3a9623":{"model_module":"@jupyter-widgets/controls","model_module_version":"1.5.0","model_name":"DescriptionStyleModel","state":{"_model_module":"@jupyter-widgets/controls","_model_module_version":"1.5.0","_model_name":"DescriptionStyleModel","_view_count":null,"_view_module":"@jupyter-widgets/base","_view_module_version":"1.2.0","_view_name":"StyleView","description_width":""}},"6c361855da5e4eb78e311defb2ca2f2b":{"model_module":"@jupyter-widgets/controls","model_module_version":"1.5.0","model_name":"ProgressStyleModel","state":{"_model_module":"@jupyter-widgets/controls","_model_module_version":"1.5.0","_model_name":"ProgressStyleModel","_view_count":null,"_view_module":"@jupyter-widgets/base","_view_module_version":"1.2.0","_view_name":"StyleView","bar_color":null,"description_width":""}},"6d5431955c09424a96e825aa9bba1b62":{"model_module":"@jupyter-widgets/controls","model_module_version":"1.5.0","model_name":"ProgressStyleModel","state":{"_model_module":"@jupyter-widgets/controls","_model_module_version":"1.5.0","_model_name":"ProgressStyleModel","_view_count":null,"_view_module":"@jupyter-widgets/base","_view_module_version":"1.2.0","_view_name":"StyleView","bar_color":null,"description_width":""}},"6f318bc3e900434a9134a79e4057f666":{"model_module":"@jupyter-widgets/controls","model_module_version":"1.5.0","model_name":"ProgressStyleModel","state":{"_model_module":"@jupyter-widgets/controls","_model_module_version":"1.5.0","_model_name":"ProgressStyleModel","_view_count":null,"_view_module":"@jupyter-widgets/base","_view_module_version":"1.2.0","_view_name":"StyleView","bar_color":null,"description_width":""}},"6fe26270a8794dea85b9ac8dedde6353":{"model_module":"@jupyter-widgets/controls","model_module_version":"1.5.0","model_name":"VBoxModel","state":{"_dom_classes":[],"_model_module":"@jupyter-widgets/controls","_model_module_version":"1.5.0","_model_name":"VBoxModel","_view_count":null,"_view_module":"@jupyter-widgets/controls","_view_module_version":"1.5.0","_view_name":"VBoxView","box_style":"","children":["IPY_MODEL_5033834cc66f49efaa16b240245ec1d3","IPY_MODEL_0b127e22a6de4339aecc1e76a6719d7f","IPY_MODEL_8a7afaf126ac49dcaf24d64c2d918086","IPY_MODEL_1b5f49211db54348924a05482ca7379d"],"layout":"IPY_MODEL_9d7b5e47af9448c98a2a434f02b54633"}},"70d672feec1c452aa49a40a3b8c1a4f0":{"model_module":"@jupyter-widgets/base","model_module_version":"1.2.0","model_name":"LayoutModel","state":{"_model_module":"@jupyter-widgets/base","_model_module_version":"1.2.0","_model_name":"LayoutModel","_view_count":null,"_view_module":"@jupyter-widgets/base","_view_module_version":"1.2.0","_view_name":"LayoutView","align_content":null,"align_items":null,"align_self":null,"border":null,"bottom":null,"display":null,"flex":null,"flex_flow":null,"grid_area":null,"grid_auto_columns":null,"grid_auto_flow":null,"grid_auto_rows":null,"grid_column":null,"grid_gap":null,"grid_row":null,"grid_template_areas":null,"grid_template_columns":null,"grid_template_rows":null,"height":null,"justify_content":null,"justify_items":null,"left":null,"margin":null,"max_height":null,"max_width":null,"min_height":null,"min_width":null,"object_fit":null,"object_position":null,"order":null,"overflow":null,"overflow_x":null,"overflow_y":null,"padding":null,"right":null,"top":null,"visibility":null,"width":null}},"754a843fd634446b8d246998eaded1fa":{"model_module":"@jupyter-widgets/base","model_module_version":"1.2.0","model_name":"LayoutModel","state":{"_model_module":"@jupyter-widgets/base","_model_module_version":"1.2.0","_model_name":"LayoutModel","_view_count":null,"_view_module":"@jupyter-widgets/base","_view_module_version":"1.2.0","_view_name":"LayoutView","align_content":null,"align_items":null,"align_self":null,"border":null,"bottom":null,"display":null,"flex":null,"flex_flow":null,"grid_area":null,"grid_auto_columns":null,"grid_auto_flow":null,"grid_auto_rows":null,"grid_column":null,"grid_gap":null,"grid_row":null,"grid_template_areas":null,"grid_template_columns":null,"grid_template_rows":null,"height":null,"justify_content":null,"justify_items":null,"left":null,"margin":null,"max_height":null,"max_width":null,"min_height":null,"min_width":null,"object_fit":null,"object_position":null,"order":null,"overflow":null,"overflow_x":null,"overflow_y":null,"padding":null,"right":null,"top":null,"visibility":null,"width":null}},"7580595b498a4c50b748af9df67132e2":{"model_module":"@jupyter-widgets/base","model_module_version":"1.2.0","model_name":"LayoutModel","state":{"_model_module":"@jupyter-widgets/base","_model_module_version":"1.2.0","_model_name":"LayoutModel","_view_count":null,"_view_module":"@jupyter-widgets/base","_view_module_version":"1.2.0","_view_name":"LayoutView","align_content":null,"align_items":null,"align_self":null,"border":null,"bottom":null,"display":null,"flex":null,"flex_flow":null,"grid_area":null,"grid_auto_columns":null,"grid_auto_flow":null,"grid_auto_rows":null,"grid_column":null,"grid_gap":null,"grid_row":null,"grid_template_areas":null,"grid_template_columns":null,"grid_template_rows":null,"height":null,"justify_content":null,"justify_items":null,"left":null,"margin":null,"max_height":null,"max_width":null,"min_height":null,"min_width":null,"object_fit":null,"object_position":null,"order":null,"overflow":null,"overflow_x":null,"overflow_y":null,"padding":null,"right":null,"top":null,"visibility":null,"width":null}},"775611277f1948a5ab95641c4e92ff2e":{"model_module":"@jupyter-widgets/controls","model_module_version":"1.5.0","model_name":"HTMLModel","state":{"_dom_classes":[],"_model_module":"@jupyter-widgets/controls","_model_module_version":"1.5.0","_model_name":"HTMLModel","_view_count":null,"_view_module":"@jupyter-widgets/controls","_view_module_version":"1.5.0","_view_name":"HTMLView","description":"","description_tooltip":null,"layout":"IPY_MODEL_70d672feec1c452aa49a40a3b8c1a4f0","placeholder":"​","style":"IPY_MODEL_e8b3188ee4934ab4becbc431fc4ccb0b","value":"config.yaml: 100%"}},"78f428e1d8ac4c78bd84d208a78b1fe5":{"model_module":"@jupyter-widgets/controls","model_module_version":"1.5.0","model_name":"HTMLModel","state":{"_dom_classes":[],"_model_module":"@jupyter-widgets/controls","_model_module_version":"1.5.0","_model_name":"HTMLModel","_view_count":null,"_view_module":"@jupyter-widgets/controls","_view_module_version":"1.5.0","_view_name":"HTMLView","description":"","description_tooltip":null,"layout":"IPY_MODEL_7ffa4930e0a7421e9464abff87bbde7f","placeholder":"​","style":"IPY_MODEL_1dd6bfb824ba4919ba392e0d4cd5ac82","value":"\nPro Tip: If you don't already have one, you can create a dedicated\n'notebooks' token with 'write' access, that you can then easily reuse for all\nnotebooks.
"}},"7c23cd10c573438c840148ba1afaa5f3":{"model_module":"@jupyter-widgets/controls","model_module_version":"1.5.0","model_name":"LabelModel","state":{"_dom_classes":[],"_model_module":"@jupyter-widgets/controls","_model_module_version":"1.5.0","_model_name":"LabelModel","_view_count":null,"_view_module":"@jupyter-widgets/controls","_view_module_version":"1.5.0","_view_name":"LabelView","description":"","description_tooltip":null,"layout":"IPY_MODEL_bc4d3f45eaf04cccb7a655ef87d7a927","placeholder":"​","style":"IPY_MODEL_36f60aa99ea84b739f066c6ee216f159","value":"Connecting..."}},"7cab72ad0ace45d58d6954021082ace7":{"model_module":"@jupyter-widgets/controls","model_module_version":"1.5.0","model_name":"HTMLModel","state":{"_dom_classes":[],"_model_module":"@jupyter-widgets/controls","_model_module_version":"1.5.0","_model_name":"HTMLModel","_view_count":null,"_view_module":"@jupyter-widgets/controls","_view_module_version":"1.5.0","_view_name":"HTMLView","description":"","description_tooltip":null,"layout":"IPY_MODEL_54eacc5604f64f658617cde596a728dd","placeholder":"​","style":"IPY_MODEL_1749a0e7fc6847849ab40ac7f764b699","value":" 5.91M/5.91M [00:00<00:00, 88.7MB/s]"}},"7ffa4930e0a7421e9464abff87bbde7f":{"model_module":"@jupyter-widgets/base","model_module_version":"1.2.0","model_name":"LayoutModel","state":{"_model_module":"@jupyter-widgets/base","_model_module_version":"1.2.0","_model_name":"LayoutModel","_view_count":null,"_view_module":"@jupyter-widgets/base","_view_module_version":"1.2.0","_view_name":"LayoutView","align_content":null,"align_items":null,"align_self":null,"border":null,"bottom":null,"display":null,"flex":null,"flex_flow":null,"grid_area":null,"grid_auto_columns":null,"grid_auto_flow":null,"grid_auto_rows":null,"grid_column":null,"grid_gap":null,"grid_row":null,"grid_template_areas":null,"grid_template_columns":null,"grid_template_rows":null,"height":null,"justify_content":null,"justify_items":null,"left":null,"margin":null,"max_height":null,"max_width":null,"min_height":null,"min_width":null,"object_fit":null,"object_position":null,"order":null,"overflow":null,"overflow_x":null,"overflow_y":null,"padding":null,"right":null,"top":null,"visibility":null,"width":null}},"84e416e01cfa4a79b0294a44cfd77f32":{"model_module":"@jupyter-widgets/controls","model_module_version":"1.5.0","model_name":"DescriptionStyleModel","state":{"_model_module":"@jupyter-widgets/controls","_model_module_version":"1.5.0","_model_name":"DescriptionStyleModel","_view_count":null,"_view_module":"@jupyter-widgets/base","_view_module_version":"1.2.0","_view_name":"StyleView","description_width":""}},"87a0e712c0b045449b98ee368c62fff2":{"model_module":"@jupyter-widgets/base","model_module_version":"1.2.0","model_name":"LayoutModel","state":{"_model_module":"@jupyter-widgets/base","_model_module_version":"1.2.0","_model_name":"LayoutModel","_view_count":null,"_view_module":"@jupyter-widgets/base","_view_module_version":"1.2.0","_view_name":"LayoutView","align_content":null,"align_items":null,"align_self":null,"border":null,"bottom":null,"display":null,"flex":null,"flex_flow":null,"grid_area":null,"grid_auto_columns":null,"grid_auto_flow":null,"grid_auto_rows":null,"grid_column":null,"grid_gap":null,"grid_row":null,"grid_template_areas":null,"grid_template_columns":null,"grid_template_rows":null,"height":null,"justify_content":null,"justify_items":null,"left":null,"margin":null,"max_height":null,"max_width":null,"min_height":null,"min_width":null,"object_fit":null,"object_position":null,"order":null,"overflow":null,"overflow_x":null,"overflow_y":null,"padding":null,"right":null,"top":null,"visibility":null,"width":null}},"8a7afaf126ac49dcaf24d64c2d918086":{"model_module":"@jupyter-widgets/controls","model_module_version":"1.5.0","model_name":"LabelModel","state":{"_dom_classes":[],"_model_module":"@jupyter-widgets/controls","_model_module_version":"1.5.0","_model_name":"LabelModel","_view_count":null,"_view_module":"@jupyter-widgets/controls","_view_module_version":"1.5.0","_view_name":"LabelView","description":"","description_tooltip":null,"layout":"IPY_MODEL_58e423b86bf349aa89fc81a2b0d0f697","placeholder":"​","style":"IPY_MODEL_a3ebe0f0e6e44522a2545db0ed47af62","value":"Your token has been saved to /root/.cache/huggingface/token"}},"8bda58a4c0c6430ca1470282ddbe8222":{"model_module":"@jupyter-widgets/base","model_module_version":"1.2.0","model_name":"LayoutModel","state":{"_model_module":"@jupyter-widgets/base","_model_module_version":"1.2.0","_model_name":"LayoutModel","_view_count":null,"_view_module":"@jupyter-widgets/base","_view_module_version":"1.2.0","_view_name":"LayoutView","align_content":null,"align_items":null,"align_self":null,"border":null,"bottom":null,"display":null,"flex":null,"flex_flow":null,"grid_area":null,"grid_auto_columns":null,"grid_auto_flow":null,"grid_auto_rows":null,"grid_column":null,"grid_gap":null,"grid_row":null,"grid_template_areas":null,"grid_template_columns":null,"grid_template_rows":null,"height":null,"justify_content":null,"justify_items":null,"left":null,"margin":null,"max_height":null,"max_width":null,"min_height":null,"min_width":null,"object_fit":null,"object_position":null,"order":null,"overflow":null,"overflow_x":null,"overflow_y":null,"padding":null,"right":null,"top":null,"visibility":null,"width":null}},"8fad50e0475341d9801e9f86e04e15c7":{"model_module":"@jupyter-widgets/controls","model_module_version":"1.5.0","model_name":"FloatProgressModel","state":{"_dom_classes":[],"_model_module":"@jupyter-widgets/controls","_model_module_version":"1.5.0","_model_name":"FloatProgressModel","_view_count":null,"_view_module":"@jupyter-widgets/controls","_view_module_version":"1.5.0","_view_name":"ProgressView","bar_style":"success","description":"","description_tooltip":null,"layout":"IPY_MODEL_2a72c7660c2f498089c63c78eaa69fc8","max":1980,"min":0,"orientation":"horizontal","style":"IPY_MODEL_05283cf0054d412c9a1ebfcc44bf41cb","value":1980}},"9025d2b6c7b14162a692b98c3e86ec8a":{"model_module":"@jupyter-widgets/base","model_module_version":"1.2.0","model_name":"LayoutModel","state":{"_model_module":"@jupyter-widgets/base","_model_module_version":"1.2.0","_model_name":"LayoutModel","_view_count":null,"_view_module":"@jupyter-widgets/base","_view_module_version":"1.2.0","_view_name":"LayoutView","align_content":null,"align_items":null,"align_self":null,"border":null,"bottom":null,"display":null,"flex":null,"flex_flow":null,"grid_area":null,"grid_auto_columns":null,"grid_auto_flow":null,"grid_auto_rows":null,"grid_column":null,"grid_gap":null,"grid_row":null,"grid_template_areas":null,"grid_template_columns":null,"grid_template_rows":null,"height":null,"justify_content":null,"justify_items":null,"left":null,"margin":null,"max_height":null,"max_width":null,"min_height":null,"min_width":null,"object_fit":null,"object_position":null,"order":null,"overflow":null,"overflow_x":null,"overflow_y":null,"padding":null,"right":null,"top":null,"visibility":null,"width":null}},"90533da4fc1341a28bc247bc9fbbbe9e":{"model_module":"@jupyter-widgets/base","model_module_version":"1.2.0","model_name":"LayoutModel","state":{"_model_module":"@jupyter-widgets/base","_model_module_version":"1.2.0","_model_name":"LayoutModel","_view_count":null,"_view_module":"@jupyter-widgets/base","_view_module_version":"1.2.0","_view_name":"LayoutView","align_content":null,"align_items":null,"align_self":null,"border":null,"bottom":null,"display":null,"flex":null,"flex_flow":null,"grid_area":null,"grid_auto_columns":null,"grid_auto_flow":null,"grid_auto_rows":null,"grid_column":null,"grid_gap":null,"grid_row":null,"grid_template_areas":null,"grid_template_columns":null,"grid_template_rows":null,"height":null,"justify_content":null,"justify_items":null,"left":null,"margin":null,"max_height":null,"max_width":null,"min_height":null,"min_width":null,"object_fit":null,"object_position":null,"order":null,"overflow":null,"overflow_x":null,"overflow_y":null,"padding":null,"right":null,"top":null,"visibility":null,"width":null}},"91ca95844e084619b9ae01fe8176f875":{"model_module":"@jupyter-widgets/controls","model_module_version":"1.5.0","model_name":"DescriptionStyleModel","state":{"_model_module":"@jupyter-widgets/controls","_model_module_version":"1.5.0","_model_name":"DescriptionStyleModel","_view_count":null,"_view_module":"@jupyter-widgets/base","_view_module_version":"1.2.0","_view_name":"StyleView","description_width":""}},"9446f61936c4421d9610464984890353":{"model_module":"@jupyter-widgets/controls","model_module_version":"1.5.0","model_name":"FloatProgressModel","state":{"_dom_classes":[],"_model_module":"@jupyter-widgets/controls","_model_module_version":"1.5.0","_model_name":"FloatProgressModel","_view_count":null,"_view_module":"@jupyter-widgets/controls","_view_module_version":"1.5.0","_view_name":"ProgressView","bar_style":"success","description":"","description_tooltip":null,"layout":"IPY_MODEL_30864d7b4d074994ba643c73875a67b8","max":26645418,"min":0,"orientation":"horizontal","style":"IPY_MODEL_b852998433e24f7fad1fe27e249085f9","value":26645418}},"9537f195677745cba18618764b2290ab":{"model_module":"@jupyter-widgets/controls","model_module_version":"1.5.0","model_name":"FloatProgressModel","state":{"_dom_classes":[],"_model_module":"@jupyter-widgets/controls","_model_module_version":"1.5.0","_model_name":"FloatProgressModel","_view_count":null,"_view_module":"@jupyter-widgets/controls","_view_module_version":"1.5.0","_view_name":"ProgressView","bar_style":"success","description":"","description_tooltip":null,"layout":"IPY_MODEL_4abbe0d8e0fa4e1b9d712743013b2d4e","max":17739960,"min":0,"orientation":"horizontal","style":"IPY_MODEL_661c7494ef2d47c794e6236e5f2c8978","value":17739960}},"9988b4433d6e4c58a819a2e1b54f57b2":{"model_module":"@jupyter-widgets/base","model_module_version":"1.2.0","model_name":"LayoutModel","state":{"_model_module":"@jupyter-widgets/base","_model_module_version":"1.2.0","_model_name":"LayoutModel","_view_count":null,"_view_module":"@jupyter-widgets/base","_view_module_version":"1.2.0","_view_name":"LayoutView","align_content":null,"align_items":null,"align_self":null,"border":null,"bottom":null,"display":null,"flex":null,"flex_flow":null,"grid_area":null,"grid_auto_columns":null,"grid_auto_flow":null,"grid_auto_rows":null,"grid_column":null,"grid_gap":null,"grid_row":null,"grid_template_areas":null,"grid_template_columns":null,"grid_template_rows":null,"height":null,"justify_content":null,"justify_items":null,"left":null,"margin":null,"max_height":null,"max_width":null,"min_height":null,"min_width":null,"object_fit":null,"object_position":null,"order":null,"overflow":null,"overflow_x":null,"overflow_y":null,"padding":null,"right":null,"top":null,"visibility":null,"width":null}},"9d7b5e47af9448c98a2a434f02b54633":{"model_module":"@jupyter-widgets/base","model_module_version":"1.2.0","model_name":"LayoutModel","state":{"_model_module":"@jupyter-widgets/base","_model_module_version":"1.2.0","_model_name":"LayoutModel","_view_count":null,"_view_module":"@jupyter-widgets/base","_view_module_version":"1.2.0","_view_name":"LayoutView","align_content":null,"align_items":"center","align_self":null,"border":null,"bottom":null,"display":"flex","flex":null,"flex_flow":"column","grid_area":null,"grid_auto_columns":null,"grid_auto_flow":null,"grid_auto_rows":null,"grid_column":null,"grid_gap":null,"grid_row":null,"grid_template_areas":null,"grid_template_columns":null,"grid_template_rows":null,"height":null,"justify_content":null,"justify_items":null,"left":null,"margin":null,"max_height":null,"max_width":null,"min_height":null,"min_width":null,"object_fit":null,"object_position":null,"order":null,"overflow":null,"overflow_x":null,"overflow_y":null,"padding":null,"right":null,"top":null,"visibility":null,"width":"50%"}},"a3ebe0f0e6e44522a2545db0ed47af62":{"model_module":"@jupyter-widgets/controls","model_module_version":"1.5.0","model_name":"DescriptionStyleModel","state":{"_model_module":"@jupyter-widgets/controls","_model_module_version":"1.5.0","_model_name":"DescriptionStyleModel","_view_count":null,"_view_module":"@jupyter-widgets/base","_view_module_version":"1.2.0","_view_name":"StyleView","description_width":""}},"a435c85128f148cb80152d03825710e2":{"model_module":"@jupyter-widgets/controls","model_module_version":"1.5.0","model_name":"DescriptionStyleModel","state":{"_model_module":"@jupyter-widgets/controls","_model_module_version":"1.5.0","_model_name":"DescriptionStyleModel","_view_count":null,"_view_module":"@jupyter-widgets/base","_view_module_version":"1.2.0","_view_name":"StyleView","description_width":""}},"a80c0fb6a1254bb9a00741c1346b9d9a":{"model_module":"@jupyter-widgets/controls","model_module_version":"1.5.0","model_name":"HTMLModel","state":{"_dom_classes":[],"_model_module":"@jupyter-widgets/controls","_model_module_version":"1.5.0","_model_name":"HTMLModel","_view_count":null,"_view_module":"@jupyter-widgets/controls","_view_module_version":"1.5.0","_view_name":"HTMLView","description":"","description_tooltip":null,"layout":"IPY_MODEL_46ac2d0bfedc47c8836e8dde0fc91662","placeholder":"​","style":"IPY_MODEL_58b140d0453a4a219bc64e0152cc5c5e","value":" 26.6M/26.6M [00:00<00:00, 104MB/s]"}},"a8e61b300a324911b1d3babf6b1ebac1":{"model_module":"@jupyter-widgets/controls","model_module_version":"1.5.0","model_name":"CheckboxModel","state":{"_dom_classes":[],"_model_module":"@jupyter-widgets/controls","_model_module_version":"1.5.0","_model_name":"CheckboxModel","_view_count":null,"_view_module":"@jupyter-widgets/controls","_view_module_version":"1.5.0","_view_name":"CheckboxView","description":"Add token as git credential?","description_tooltip":null,"disabled":false,"indent":true,"layout":"IPY_MODEL_5253489738b249f69b30f1c84884a95a","style":"IPY_MODEL_3f500b1182a945c3b8b546b1bd04f98e","value":true}},"a987408c2f994329a9a80208b22e3c52":{"model_module":"@jupyter-widgets/controls","model_module_version":"1.5.0","model_name":"HTMLModel","state":{"_dom_classes":[],"_model_module":"@jupyter-widgets/controls","_model_module_version":"1.5.0","_model_name":"HTMLModel","_view_count":null,"_view_module":"@jupyter-widgets/controls","_view_module_version":"1.5.0","_view_name":"HTMLView","description":"","description_tooltip":null,"layout":"IPY_MODEL_517a1b1faec045f7847ca84f0538f4e1","placeholder":"​","style":"IPY_MODEL_008a47e4d1174b188e75232fed325398","value":"pytorch_model.bin: 100%"}},"ae378b480ed747438bcbe147a7e8d277":{"model_module":"@jupyter-widgets/base","model_module_version":"1.2.0","model_name":"LayoutModel","state":{"_model_module":"@jupyter-widgets/base","_model_module_version":"1.2.0","_model_name":"LayoutModel","_view_count":null,"_view_module":"@jupyter-widgets/base","_view_module_version":"1.2.0","_view_name":"LayoutView","align_content":null,"align_items":null,"align_self":null,"border":null,"bottom":null,"display":null,"flex":null,"flex_flow":null,"grid_area":null,"grid_auto_columns":null,"grid_auto_flow":null,"grid_auto_rows":null,"grid_column":null,"grid_gap":null,"grid_row":null,"grid_template_areas":null,"grid_template_columns":null,"grid_template_rows":null,"height":null,"justify_content":null,"justify_items":null,"left":null,"margin":null,"max_height":null,"max_width":null,"min_height":null,"min_width":null,"object_fit":null,"object_position":null,"order":null,"overflow":null,"overflow_x":null,"overflow_y":null,"padding":null,"right":null,"top":null,"visibility":null,"width":null}},"b02b253086e34249ae1d896a75a08960":{"model_module":"@jupyter-widgets/controls","model_module_version":"1.5.0","model_name":"DescriptionStyleModel","state":{"_model_module":"@jupyter-widgets/controls","_model_module_version":"1.5.0","_model_name":"DescriptionStyleModel","_view_count":null,"_view_module":"@jupyter-widgets/base","_view_module_version":"1.2.0","_view_name":"StyleView","description_width":""}},"b22a1d21940e4995b72642b003ae1301":{"model_module":"@jupyter-widgets/controls","model_module_version":"1.5.0","model_name":"DescriptionStyleModel","state":{"_model_module":"@jupyter-widgets/controls","_model_module_version":"1.5.0","_model_name":"DescriptionStyleModel","_view_count":null,"_view_module":"@jupyter-widgets/base","_view_module_version":"1.2.0","_view_name":"StyleView","description_width":""}},"b33021db4313476ab8bcb85bb1b190d7":{"model_module":"@jupyter-widgets/base","model_module_version":"1.2.0","model_name":"LayoutModel","state":{"_model_module":"@jupyter-widgets/base","_model_module_version":"1.2.0","_model_name":"LayoutModel","_view_count":null,"_view_module":"@jupyter-widgets/base","_view_module_version":"1.2.0","_view_name":"LayoutView","align_content":null,"align_items":null,"align_self":null,"border":null,"bottom":null,"display":null,"flex":null,"flex_flow":null,"grid_area":null,"grid_auto_columns":null,"grid_auto_flow":null,"grid_auto_rows":null,"grid_column":null,"grid_gap":null,"grid_row":null,"grid_template_areas":null,"grid_template_columns":null,"grid_template_rows":null,"height":null,"justify_content":null,"justify_items":null,"left":null,"margin":null,"max_height":null,"max_width":null,"min_height":null,"min_width":null,"object_fit":null,"object_position":null,"order":null,"overflow":null,"overflow_x":null,"overflow_y":null,"padding":null,"right":null,"top":null,"visibility":null,"width":null}},"b55e95f31216480fa6c81bd1b57ad729":{"model_module":"@jupyter-widgets/base","model_module_version":"1.2.0","model_name":"LayoutModel","state":{"_model_module":"@jupyter-widgets/base","_model_module_version":"1.2.0","_model_name":"LayoutModel","_view_count":null,"_view_module":"@jupyter-widgets/base","_view_module_version":"1.2.0","_view_name":"LayoutView","align_content":null,"align_items":null,"align_self":null,"border":null,"bottom":null,"display":null,"flex":null,"flex_flow":null,"grid_area":null,"grid_auto_columns":null,"grid_auto_flow":null,"grid_auto_rows":null,"grid_column":null,"grid_gap":null,"grid_row":null,"grid_template_areas":null,"grid_template_columns":null,"grid_template_rows":null,"height":null,"justify_content":null,"justify_items":null,"left":null,"margin":null,"max_height":null,"max_width":null,"min_height":null,"min_width":null,"object_fit":null,"object_position":null,"order":null,"overflow":null,"overflow_x":null,"overflow_y":null,"padding":null,"right":null,"top":null,"visibility":null,"width":null}},"b5f4829158cf4a5c8350966d8eacbf60":{"model_module":"@jupyter-widgets/controls","model_module_version":"1.5.0","model_name":"FloatProgressModel","state":{"_dom_classes":[],"_model_module":"@jupyter-widgets/controls","_model_module_version":"1.5.0","_model_name":"FloatProgressModel","_view_count":null,"_view_module":"@jupyter-widgets/controls","_view_module_version":"1.5.0","_view_name":"ProgressView","bar_style":"success","description":"","description_tooltip":null,"layout":"IPY_MODEL_b33021db4313476ab8bcb85bb1b190d7","max":5905440,"min":0,"orientation":"horizontal","style":"IPY_MODEL_6d5431955c09424a96e825aa9bba1b62","value":5905440}},"b852998433e24f7fad1fe27e249085f9":{"model_module":"@jupyter-widgets/controls","model_module_version":"1.5.0","model_name":"ProgressStyleModel","state":{"_model_module":"@jupyter-widgets/controls","_model_module_version":"1.5.0","_model_name":"ProgressStyleModel","_view_count":null,"_view_module":"@jupyter-widgets/base","_view_module_version":"1.2.0","_view_name":"StyleView","bar_color":null,"description_width":""}},"b8861f8cb72c4e65afac6519b7004170":{"model_module":"@jupyter-widgets/base","model_module_version":"1.2.0","model_name":"LayoutModel","state":{"_model_module":"@jupyter-widgets/base","_model_module_version":"1.2.0","_model_name":"LayoutModel","_view_count":null,"_view_module":"@jupyter-widgets/base","_view_module_version":"1.2.0","_view_name":"LayoutView","align_content":null,"align_items":null,"align_self":null,"border":null,"bottom":null,"display":null,"flex":null,"flex_flow":null,"grid_area":null,"grid_auto_columns":null,"grid_auto_flow":null,"grid_auto_rows":null,"grid_column":null,"grid_gap":null,"grid_row":null,"grid_template_areas":null,"grid_template_columns":null,"grid_template_rows":null,"height":null,"justify_content":null,"justify_items":null,"left":null,"margin":null,"max_height":null,"max_width":null,"min_height":null,"min_width":null,"object_fit":null,"object_position":null,"order":null,"overflow":null,"overflow_x":null,"overflow_y":null,"padding":null,"right":null,"top":null,"visibility":null,"width":null}},"b9d9acd287c345debdff1e72a85641af":{"model_module":"@jupyter-widgets/base","model_module_version":"1.2.0","model_name":"LayoutModel","state":{"_model_module":"@jupyter-widgets/base","_model_module_version":"1.2.0","_model_name":"LayoutModel","_view_count":null,"_view_module":"@jupyter-widgets/base","_view_module_version":"1.2.0","_view_name":"LayoutView","align_content":null,"align_items":null,"align_self":null,"border":null,"bottom":null,"display":null,"flex":null,"flex_flow":null,"grid_area":null,"grid_auto_columns":null,"grid_auto_flow":null,"grid_auto_rows":null,"grid_column":null,"grid_gap":null,"grid_row":null,"grid_template_areas":null,"grid_template_columns":null,"grid_template_rows":null,"height":null,"justify_content":null,"justify_items":null,"left":null,"margin":null,"max_height":null,"max_width":null,"min_height":null,"min_width":null,"object_fit":null,"object_position":null,"order":null,"overflow":null,"overflow_x":null,"overflow_y":null,"padding":null,"right":null,"top":null,"visibility":null,"width":null}},"bc4d3f45eaf04cccb7a655ef87d7a927":{"model_module":"@jupyter-widgets/base","model_module_version":"1.2.0","model_name":"LayoutModel","state":{"_model_module":"@jupyter-widgets/base","_model_module_version":"1.2.0","_model_name":"LayoutModel","_view_count":null,"_view_module":"@jupyter-widgets/base","_view_module_version":"1.2.0","_view_name":"LayoutView","align_content":null,"align_items":null,"align_self":null,"border":null,"bottom":null,"display":null,"flex":null,"flex_flow":null,"grid_area":null,"grid_auto_columns":null,"grid_auto_flow":null,"grid_auto_rows":null,"grid_column":null,"grid_gap":null,"grid_row":null,"grid_template_areas":null,"grid_template_columns":null,"grid_template_rows":null,"height":null,"justify_content":null,"justify_items":null,"left":null,"margin":null,"max_height":null,"max_width":null,"min_height":null,"min_width":null,"object_fit":null,"object_position":null,"order":null,"overflow":null,"overflow_x":null,"overflow_y":null,"padding":null,"right":null,"top":null,"visibility":null,"width":null}},"be8b64ce7f8247499c8bbcb62c5dd902":{"model_module":"@jupyter-widgets/base","model_module_version":"1.2.0","model_name":"LayoutModel","state":{"_model_module":"@jupyter-widgets/base","_model_module_version":"1.2.0","_model_name":"LayoutModel","_view_count":null,"_view_module":"@jupyter-widgets/base","_view_module_version":"1.2.0","_view_name":"LayoutView","align_content":null,"align_items":null,"align_self":null,"border":null,"bottom":null,"display":null,"flex":null,"flex_flow":null,"grid_area":null,"grid_auto_columns":null,"grid_auto_flow":null,"grid_auto_rows":null,"grid_column":null,"grid_gap":null,"grid_row":null,"grid_template_areas":null,"grid_template_columns":null,"grid_template_rows":null,"height":null,"justify_content":null,"justify_items":null,"left":null,"margin":null,"max_height":null,"max_width":null,"min_height":null,"min_width":null,"object_fit":null,"object_position":null,"order":null,"overflow":null,"overflow_x":null,"overflow_y":null,"padding":null,"right":null,"top":null,"visibility":null,"width":null}},"bf644ae3e2894787bb416740749200cd":{"model_module":"@jupyter-widgets/controls","model_module_version":"1.5.0","model_name":"HTMLModel","state":{"_dom_classes":[],"_model_module":"@jupyter-widgets/controls","_model_module_version":"1.5.0","_model_name":"HTMLModel","_view_count":null,"_view_module":"@jupyter-widgets/controls","_view_module_version":"1.5.0","_view_name":"HTMLView","description":"","description_tooltip":null,"layout":"IPY_MODEL_2be7c1f5fe32462f8d1cd7ea57cfbf3a","placeholder":"​","style":"IPY_MODEL_d6135ce9cfaa4f8496a70cee4f1e89a7","value":"config.yaml: 100%"}},"c3b3069a93994e55b993cab04c066f17":{"model_module":"@jupyter-widgets/base","model_module_version":"1.2.0","model_name":"LayoutModel","state":{"_model_module":"@jupyter-widgets/base","_model_module_version":"1.2.0","_model_name":"LayoutModel","_view_count":null,"_view_module":"@jupyter-widgets/base","_view_module_version":"1.2.0","_view_name":"LayoutView","align_content":null,"align_items":null,"align_self":null,"border":null,"bottom":null,"display":null,"flex":null,"flex_flow":null,"grid_area":null,"grid_auto_columns":null,"grid_auto_flow":null,"grid_auto_rows":null,"grid_column":null,"grid_gap":null,"grid_row":null,"grid_template_areas":null,"grid_template_columns":null,"grid_template_rows":null,"height":null,"justify_content":null,"justify_items":null,"left":null,"margin":null,"max_height":null,"max_width":null,"min_height":null,"min_width":null,"object_fit":null,"object_position":null,"order":null,"overflow":null,"overflow_x":null,"overflow_y":null,"padding":null,"right":null,"top":null,"visibility":null,"width":null}},"c955f8144b46451493474e02726b5deb":{"model_module":"@jupyter-widgets/controls","model_module_version":"1.5.0","model_name":"FloatProgressModel","state":{"_dom_classes":[],"_model_module":"@jupyter-widgets/controls","_model_module_version":"1.5.0","_model_name":"FloatProgressModel","_view_count":null,"_view_module":"@jupyter-widgets/controls","_view_module_version":"1.5.0","_view_name":"ProgressView","bar_style":"success","description":"","description_tooltip":null,"layout":"IPY_MODEL_754a843fd634446b8d246998eaded1fa","max":399,"min":0,"orientation":"horizontal","style":"IPY_MODEL_1e53e26668aa4f8dabdd6973b79b5b9f","value":399}},"c9eeb26bd5e049f89205e494d54e3818":{"model_module":"@jupyter-widgets/controls","model_module_version":"1.5.0","model_name":"HTMLModel","state":{"_dom_classes":[],"_model_module":"@jupyter-widgets/controls","_model_module_version":"1.5.0","_model_name":"HTMLModel","_view_count":null,"_view_module":"@jupyter-widgets/controls","_view_module_version":"1.5.0","_view_name":"HTMLView","description":"","description_tooltip":null,"layout":"IPY_MODEL_cf5ae82d36384a728d8ca893cc27392b","placeholder":"​","style":"IPY_MODEL_5cc77ca8ba304ad88342ed6ced6c6a4a","value":" 399/399 [00:00<00:00, 24.8kB/s]"}},"cf5ae82d36384a728d8ca893cc27392b":{"model_module":"@jupyter-widgets/base","model_module_version":"1.2.0","model_name":"LayoutModel","state":{"_model_module":"@jupyter-widgets/base","_model_module_version":"1.2.0","_model_name":"LayoutModel","_view_count":null,"_view_module":"@jupyter-widgets/base","_view_module_version":"1.2.0","_view_name":"LayoutView","align_content":null,"align_items":null,"align_self":null,"border":null,"bottom":null,"display":null,"flex":null,"flex_flow":null,"grid_area":null,"grid_auto_columns":null,"grid_auto_flow":null,"grid_auto_rows":null,"grid_column":null,"grid_gap":null,"grid_row":null,"grid_template_areas":null,"grid_template_columns":null,"grid_template_rows":null,"height":null,"justify_content":null,"justify_items":null,"left":null,"margin":null,"max_height":null,"max_width":null,"min_height":null,"min_width":null,"object_fit":null,"object_position":null,"order":null,"overflow":null,"overflow_x":null,"overflow_y":null,"padding":null,"right":null,"top":null,"visibility":null,"width":null}},"d1863b2c9ebc4efa9cac2dad7dfaf53a":{"model_module":"@jupyter-widgets/base","model_module_version":"1.2.0","model_name":"LayoutModel","state":{"_model_module":"@jupyter-widgets/base","_model_module_version":"1.2.0","_model_name":"LayoutModel","_view_count":null,"_view_module":"@jupyter-widgets/base","_view_module_version":"1.2.0","_view_name":"LayoutView","align_content":null,"align_items":null,"align_self":null,"border":null,"bottom":null,"display":null,"flex":null,"flex_flow":null,"grid_area":null,"grid_auto_columns":null,"grid_auto_flow":null,"grid_auto_rows":null,"grid_column":null,"grid_gap":null,"grid_row":null,"grid_template_areas":null,"grid_template_columns":null,"grid_template_rows":null,"height":null,"justify_content":null,"justify_items":null,"left":null,"margin":null,"max_height":null,"max_width":null,"min_height":null,"min_width":null,"object_fit":null,"object_position":null,"order":null,"overflow":null,"overflow_x":null,"overflow_y":null,"padding":null,"right":null,"top":null,"visibility":null,"width":null}},"d304f698c6f34f3692548267ca0aba47":{"model_module":"@jupyter-widgets/base","model_module_version":"1.2.0","model_name":"LayoutModel","state":{"_model_module":"@jupyter-widgets/base","_model_module_version":"1.2.0","_model_name":"LayoutModel","_view_count":null,"_view_module":"@jupyter-widgets/base","_view_module_version":"1.2.0","_view_name":"LayoutView","align_content":null,"align_items":null,"align_self":null,"border":null,"bottom":null,"display":null,"flex":null,"flex_flow":null,"grid_area":null,"grid_auto_columns":null,"grid_auto_flow":null,"grid_auto_rows":null,"grid_column":null,"grid_gap":null,"grid_row":null,"grid_template_areas":null,"grid_template_columns":null,"grid_template_rows":null,"height":null,"justify_content":null,"justify_items":null,"left":null,"margin":null,"max_height":null,"max_width":null,"min_height":null,"min_width":null,"object_fit":null,"object_position":null,"order":null,"overflow":null,"overflow_x":null,"overflow_y":null,"padding":null,"right":null,"top":null,"visibility":null,"width":null}},"d4d428f0b0c44756a128adae747716d2":{"model_module":"@jupyter-widgets/base","model_module_version":"1.2.0","model_name":"LayoutModel","state":{"_model_module":"@jupyter-widgets/base","_model_module_version":"1.2.0","_model_name":"LayoutModel","_view_count":null,"_view_module":"@jupyter-widgets/base","_view_module_version":"1.2.0","_view_name":"LayoutView","align_content":null,"align_items":null,"align_self":null,"border":null,"bottom":null,"display":null,"flex":null,"flex_flow":null,"grid_area":null,"grid_auto_columns":null,"grid_auto_flow":null,"grid_auto_rows":null,"grid_column":null,"grid_gap":null,"grid_row":null,"grid_template_areas":null,"grid_template_columns":null,"grid_template_rows":null,"height":null,"justify_content":null,"justify_items":null,"left":null,"margin":null,"max_height":null,"max_width":null,"min_height":null,"min_width":null,"object_fit":null,"object_position":null,"order":null,"overflow":null,"overflow_x":null,"overflow_y":null,"padding":null,"right":null,"top":null,"visibility":null,"width":null}},"d6135ce9cfaa4f8496a70cee4f1e89a7":{"model_module":"@jupyter-widgets/controls","model_module_version":"1.5.0","model_name":"DescriptionStyleModel","state":{"_model_module":"@jupyter-widgets/controls","_model_module_version":"1.5.0","_model_name":"DescriptionStyleModel","_view_count":null,"_view_module":"@jupyter-widgets/base","_view_module_version":"1.2.0","_view_name":"StyleView","description_width":""}},"dc9c065286e544df921e5bc4a51faf64":{"model_module":"@jupyter-widgets/base","model_module_version":"1.2.0","model_name":"LayoutModel","state":{"_model_module":"@jupyter-widgets/base","_model_module_version":"1.2.0","_model_name":"LayoutModel","_view_count":null,"_view_module":"@jupyter-widgets/base","_view_module_version":"1.2.0","_view_name":"LayoutView","align_content":null,"align_items":null,"align_self":null,"border":null,"bottom":null,"display":null,"flex":null,"flex_flow":null,"grid_area":null,"grid_auto_columns":null,"grid_auto_flow":null,"grid_auto_rows":null,"grid_column":null,"grid_gap":null,"grid_row":null,"grid_template_areas":null,"grid_template_columns":null,"grid_template_rows":null,"height":null,"justify_content":null,"justify_items":null,"left":null,"margin":null,"max_height":null,"max_width":null,"min_height":null,"min_width":null,"object_fit":null,"object_position":null,"order":null,"overflow":null,"overflow_x":null,"overflow_y":null,"padding":null,"right":null,"top":null,"visibility":null,"width":null}},"e8b3188ee4934ab4becbc431fc4ccb0b":{"model_module":"@jupyter-widgets/controls","model_module_version":"1.5.0","model_name":"DescriptionStyleModel","state":{"_model_module":"@jupyter-widgets/controls","_model_module_version":"1.5.0","_model_name":"DescriptionStyleModel","_view_count":null,"_view_module":"@jupyter-widgets/base","_view_module_version":"1.2.0","_view_name":"StyleView","description_width":""}},"e98b1f7ec5e04e748069340fa2fcec2d":{"model_module":"@jupyter-widgets/base","model_module_version":"1.2.0","model_name":"LayoutModel","state":{"_model_module":"@jupyter-widgets/base","_model_module_version":"1.2.0","_model_name":"LayoutModel","_view_count":null,"_view_module":"@jupyter-widgets/base","_view_module_version":"1.2.0","_view_name":"LayoutView","align_content":null,"align_items":null,"align_self":null,"border":null,"bottom":null,"display":null,"flex":null,"flex_flow":null,"grid_area":null,"grid_auto_columns":null,"grid_auto_flow":null,"grid_auto_rows":null,"grid_column":null,"grid_gap":null,"grid_row":null,"grid_template_areas":null,"grid_template_columns":null,"grid_template_rows":null,"height":null,"justify_content":null,"justify_items":null,"left":null,"margin":null,"max_height":null,"max_width":null,"min_height":null,"min_width":null,"object_fit":null,"object_position":null,"order":null,"overflow":null,"overflow_x":null,"overflow_y":null,"padding":null,"right":null,"top":null,"visibility":null,"width":null}},"ea03f9526a7440a0a9a281ee877892fd":{"model_module":"@jupyter-widgets/controls","model_module_version":"1.5.0","model_name":"HTMLModel","state":{"_dom_classes":[],"_model_module":"@jupyter-widgets/controls","_model_module_version":"1.5.0","_model_name":"HTMLModel","_view_count":null,"_view_module":"@jupyter-widgets/controls","_view_module_version":"1.5.0","_view_name":"HTMLView","description":"","description_tooltip":null,"layout":"IPY_MODEL_b9d9acd287c345debdff1e72a85641af","placeholder":"​","style":"IPY_MODEL_91ca95844e084619b9ae01fe8176f875","value":" 1.98k/1.98k [00:00<00:00, 122kB/s]"}},"ef6be001daaa465598bdf20c304bae0b":{"model_module":"@jupyter-widgets/controls","model_module_version":"1.5.0","model_name":"PasswordModel","state":{"_dom_classes":[],"_model_module":"@jupyter-widgets/controls","_model_module_version":"1.5.0","_model_name":"PasswordModel","_view_count":null,"_view_module":"@jupyter-widgets/controls","_view_module_version":"1.5.0","_view_name":"PasswordView","continuous_update":true,"description":"Token:","description_tooltip":null,"disabled":false,"layout":"IPY_MODEL_90533da4fc1341a28bc247bc9fbbbe9e","placeholder":"​","style":"IPY_MODEL_6556790d1997431a8476447297e3f595","value":""}},"f18c80869ccc4ce1b2a215293d493e19":{"model_module":"@jupyter-widgets/controls","model_module_version":"1.5.0","model_name":"FloatProgressModel","state":{"_dom_classes":[],"_model_module":"@jupyter-widgets/controls","_model_module_version":"1.5.0","_model_name":"FloatProgressModel","_view_count":null,"_view_module":"@jupyter-widgets/controls","_view_module_version":"1.5.0","_view_name":"ProgressView","bar_style":"success","description":"","description_tooltip":null,"layout":"IPY_MODEL_9025d2b6c7b14162a692b98c3e86ec8a","max":277,"min":0,"orientation":"horizontal","style":"IPY_MODEL_6c361855da5e4eb78e311defb2ca2f2b","value":277}},"f744ac29ccdd4d9d91050fabaed13e16":{"model_module":"@jupyter-widgets/controls","model_module_version":"1.5.0","model_name":"HTMLModel","state":{"_dom_classes":[],"_model_module":"@jupyter-widgets/controls","_model_module_version":"1.5.0","_model_name":"HTMLModel","_view_count":null,"_view_module":"@jupyter-widgets/controls","_view_module_version":"1.5.0","_view_name":"HTMLView","description":"","description_tooltip":null,"layout":"IPY_MODEL_b8861f8cb72c4e65afac6519b7004170","placeholder":"​","style":"IPY_MODEL_668a49e70c2b4c8a9dcb534cb30714d6","value":"config.yaml: 100%"}},"f77186e2976d4a7daa798fd9f0f7b4cb":{"model_module":"@jupyter-widgets/controls","model_module_version":"1.5.0","model_name":"ButtonStyleModel","state":{"_model_module":"@jupyter-widgets/controls","_model_module_version":"1.5.0","_model_name":"ButtonStyleModel","_view_count":null,"_view_module":"@jupyter-widgets/base","_view_module_version":"1.2.0","_view_name":"StyleView","button_color":null,"font_weight":""}},"f7be373f08c64c8bb5b6e070a7373cca":{"model_module":"@jupyter-widgets/base","model_module_version":"1.2.0","model_name":"LayoutModel","state":{"_model_module":"@jupyter-widgets/base","_model_module_version":"1.2.0","_model_name":"LayoutModel","_view_count":null,"_view_module":"@jupyter-widgets/base","_view_module_version":"1.2.0","_view_name":"LayoutView","align_content":null,"align_items":null,"align_self":null,"border":null,"bottom":null,"display":null,"flex":null,"flex_flow":null,"grid_area":null,"grid_auto_columns":null,"grid_auto_flow":null,"grid_auto_rows":null,"grid_column":null,"grid_gap":null,"grid_row":null,"grid_template_areas":null,"grid_template_columns":null,"grid_template_rows":null,"height":null,"justify_content":null,"justify_items":null,"left":null,"margin":null,"max_height":null,"max_width":null,"min_height":null,"min_width":null,"object_fit":null,"object_position":null,"order":null,"overflow":null,"overflow_x":null,"overflow_y":null,"padding":null,"right":null,"top":null,"visibility":null,"width":null}},"f8df65e5ad6444648681230f415b8d08":{"model_module":"@jupyter-widgets/controls","model_module_version":"1.5.0","model_name":"HTMLModel","state":{"_dom_classes":[],"_model_module":"@jupyter-widgets/controls","_model_module_version":"1.5.0","_model_name":"HTMLModel","_view_count":null,"_view_module":"@jupyter-widgets/controls","_view_module_version":"1.5.0","_view_name":"HTMLView","description":"","description_tooltip":null,"layout":"IPY_MODEL_3f69734124f7449da0efffbbfd1153fe","placeholder":"​","style":"IPY_MODEL_686b58e0ccee468f938ea5659f3a9623","value":"config.yaml: 100%"}},"f9969c7acd834359bd67e83c31b82c0b":{"model_module":"@jupyter-widgets/controls","model_module_version":"1.5.0","model_name":"HTMLModel","state":{"_dom_classes":[],"_model_module":"@jupyter-widgets/controls","_model_module_version":"1.5.0","_model_name":"HTMLModel","_view_count":null,"_view_module":"@jupyter-widgets/controls","_view_module_version":"1.5.0","_view_name":"HTMLView","description":"","description_tooltip":null,"layout":"IPY_MODEL_253408a6cab947c7b9ae40a14e255328","placeholder":"​","style":"IPY_MODEL_a435c85128f148cb80152d03825710e2","value":"

Copy a token from your Hugging Face\ntokens page and paste it below.
Immediately click login after copying\nyour token or it might be stored in plain text in this notebook file.
"}},"ff048516fdba44a48a69c51a82aa7aaa":{"model_module":"@jupyter-widgets/controls","model_module_version":"1.5.0","model_name":"HBoxModel","state":{"_dom_classes":[],"_model_module":"@jupyter-widgets/controls","_model_module_version":"1.5.0","_model_name":"HBoxModel","_view_count":null,"_view_module":"@jupyter-widgets/controls","_view_module_version":"1.5.0","_view_name":"HBoxView","box_style":"","children":["IPY_MODEL_775611277f1948a5ab95641c4e92ff2e","IPY_MODEL_c955f8144b46451493474e02726b5deb","IPY_MODEL_c9eeb26bd5e049f89205e494d54e3818"],"layout":"IPY_MODEL_d4d428f0b0c44756a128adae747716d2"}}}}},"nbformat":4,"nbformat_minor":0} diff --git a/tutorials/assets/download-model.png b/tutorials/assets/download-model.png index 4ca5350f5..810500178 100644 Binary files a/tutorials/assets/download-model.png and b/tutorials/assets/download-model.png differ diff --git a/tutorials/community/offline_usage_speaker_diarization.ipynb b/tutorials/community/offline_usage_speaker_diarization.ipynb new file mode 100644 index 000000000..932742628 --- /dev/null +++ b/tutorials/community/offline_usage_speaker_diarization.ipynb @@ -0,0 +1,172 @@ +{ + "cells": [ + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "# Offline Speaker Diarization (speaker-diarization-3.1)\n", + "\n", + "This notebooks gives a short introduction how to use the [speaker-diarization-3.1](https://huggingface.co/pyannote/speaker-diarization-3.1) pipeline with local models.\n", + "\n", + "In order to use local models, you first need to download them from huggingface and place them in a local folder. \n", + "Then you need to create a local config file, similar to the one in HF, but with local model paths.\n", + "\n", + "❗ **Naming of the model files is REALLY important! See end of notebook for details.** ❗\n", + "\n", + "## Get the models\n", + "\n", + "1. Install the `pyannote-audio` package: `!pip install pyannote.audio`\n", + "2. Create a huggingface account https://huggingface.co/join\n", + "3. Accept [pyannote/segmentation-3.0](https://hf.co/pyannote/segmentation-3.0) user conditions\n", + "4. Create a local folder `models`, place all downloaded files there\n", + " 1. [wespeaker-voxceleb-resnet34-LM](https://huggingface.co/pyannote/wespeaker-voxceleb-resnet34-LM/blob/main/pytorch_model.bin), to be placed in `models/pyannote_model_wespeaker-voxceleb-resnet34-LM.bin`\n", + " 2. [segmentation-3.0](https://huggingface.co/pyannote/segmentation-3.0/blob/main/pytorch_model.bin), to be placed in `models/pyannote_model_segmentation-3.0.bin`\n", + "\n", + "Running `ls models` should show the following files:\n", + "```\n", + "pyannote_model_segmentation-3.0.bin (5.7M)\n", + "pyannote_model_wespeaker-voxceleb-resnet34-LM.bin (26MB)\n", + "```\n", + "\n", + "❗ **make sure the 'wespeaker-voxceleb-resnet34-LM' model is named 'pyannote_model_wespeaker-voxceleb-resnet34-LM.bin'** ❗" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## Config for local models\n", + "\n", + "Create a local config, similar to the one in HF: [speaker-diarization-3.1/blob/main/config.yaml](https://huggingface.co/pyannote/speaker-diarization-3.1/blob/main/config.yaml), but with local model paths\n", + "\n", + "Contents of `models/pyannote_diarization_config.yaml`:\n", + "\n", + "```yaml\n", + "version: 3.1.0\n", + "\n", + "pipeline:\n", + " name: pyannote.audio.pipelines.SpeakerDiarization\n", + " params:\n", + " clustering: AgglomerativeClustering\n", + " # embedding: pyannote/wespeaker-voxceleb-resnet34-LM # if you want to use the HF model\n", + " embedding: models/pyannote_model_wespeaker-voxceleb-resnet34-LM.bin # if you want to use the local model\n", + " embedding_batch_size: 32\n", + " embedding_exclude_overlap: true\n", + " # segmentation: pyannote/segmentation-3.0 # if you want to use the HF model\n", + " segmentation: models/pyannote_model_segmentation-3.0.bin # if you want to use the local model\n", + " segmentation_batch_size: 32\n", + "\n", + "params:\n", + " clustering:\n", + " method: centroid\n", + " min_cluster_size: 12\n", + " threshold: 0.7045654963945799\n", + " segmentation:\n", + " min_duration_off: 0.0\n", + "```" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## Loading the local pipeline\n", + "\n", + "**Hint**: The paths in the config are relative to the current working directory, not relative to the config file.\n", + "If you want to start your notebook/script from a different directory, you can use `os.chdir` temporarily, to 'emulate' config-relative paths.\n" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "from pathlib import Path\n", + "from pyannote.audio import Pipeline\n", + "\n", + "def load_pipeline_from_pretrained(path_to_config: str | Path) -> Pipeline:\n", + " path_to_config = Path(path_to_config)\n", + "\n", + " print(f\"Loading pyannote pipeline from {path_to_config}...\")\n", + " # the paths in the config are relative to the current working directory\n", + " # so we need to change the working directory to the model path\n", + " # and then change it back\n", + "\n", + " cwd = Path.cwd().resolve() # store current working directory\n", + "\n", + " # first .parent is the folder of the config, second .parent is the folder containing the 'models' folder\n", + " cd_to = path_to_config.parent.parent.resolve()\n", + "\n", + " print(f\"Changing working directory to {cd_to}\")\n", + " os.chdir(cd_to)\n", + "\n", + " pipeline = Pipeline.from_pretrained(path_to_config)\n", + "\n", + " print(f\"Changing working directory back to {cwd}\")\n", + " os.chdir(cwd)\n", + "\n", + " return pipeline\n", + "\n", + "PATH_TO_CONFIG = \"path/to/your/pyannote_diarization_config.yaml\"\n", + "pipeline = load_pipeline_from_pretrained(PATH_TO_CONFIG)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## Notes on file naming (pyannote-audio 3.1.1)\n", + "\n", + "Pyannote uses some internal logic to determine the model type.\n", + "\n", + "The funtion `def PretrainedSpeakerEmbedding(...` in (speaker_verification.py)[https://github.com/pyannote/pyannote-audio/blob/develop/pyannote/audio/pipelines/speaker_verification.py#L712] uses the the file path of the model to infer the model type.\n", + "\n", + "```python\n", + "def PretrainedSpeakerEmbedding(\n", + " embedding: PipelineModel,\n", + " device: torch.device = None,\n", + " use_auth_token: Union[Text, None] = None,\n", + "):\n", + " #...\n", + " if isinstance(embedding, str) and \"pyannote\" in embedding:\n", + " return PyannoteAudioPretrainedSpeakerEmbedding(\n", + " embedding, device=device, use_auth_token=use_auth_token\n", + " )\n", + "\n", + " elif isinstance(embedding, str) and \"speechbrain\" in embedding:\n", + " return SpeechBrainPretrainedSpeakerEmbedding(\n", + " embedding, device=device, use_auth_token=use_auth_token\n", + " )\n", + "\n", + " elif isinstance(embedding, str) and \"nvidia\" in embedding:\n", + " return NeMoPretrainedSpeakerEmbedding(embedding, device=device)\n", + "\n", + " elif isinstance(embedding, str) and \"wespeaker\" in embedding:\n", + " return ONNXWeSpeakerPretrainedSpeakerEmbedding(embedding, device=device) # <-- this is called, but the wespeaker-voxceleb-resnet34-LM is not an ONNX model\n", + "\n", + " else:\n", + " # fallback to pyannote in case we are loading a local model\n", + " return PyannoteAudioPretrainedSpeakerEmbedding(\n", + " embedding, device=device, use_auth_token=use_auth_token\n", + " )\n", + "```\n", + "\n", + "The [wespeaker-voxceleb-resnet34-LM](https://huggingface.co/pyannote/wespeaker-voxceleb-resnet34-LM/blob/main/pytorch_model.bin) model is not an ONNX model, but a `PyannoteAudioPretrainedSpeakerEmbedding`. So if `wespeaker` is in the file name, the code will infer the model type incorrectly. If `pyannote` is somewhere in the file name, the model type will be inferred correctly, as the first if statement will be true..." + ] + } + ], + "metadata": { + "kernelspec": { + "display_name": "Python 3", + "language": "python", + "name": "python3" + }, + "language_info": { + "name": "python", + "version": "3.11.7" + } + }, + "nbformat": 4, + "nbformat_minor": 2 +} diff --git a/tutorials/intro.ipynb b/tutorials/intro.ipynb index 572ea2f6d..328ddceaf 100644 --- a/tutorials/intro.ipynb +++ b/tutorials/intro.ipynb @@ -10,15 +10,6 @@ "\"Open" ] }, - { - "cell_type": "markdown", - "metadata": { - "id": "9-KmdPlBYnp6" - }, - "source": [ - "\"Open" - ] - }, { "cell_type": "markdown", "metadata": { @@ -622,7 +613,7 @@ "name": "python", "nbconvert_exporter": "python", "pygments_lexer": "ipython3", - "version": "3.11.5" + "version": "3.10.13" }, "widgets": { "application/vnd.jupyter.widget-state+json": { diff --git a/tutorials/overlapped_speech_detection.ipynb b/tutorials/overlapped_speech_detection.ipynb index 1ad5d4090..9211f0626 100644 --- a/tutorials/overlapped_speech_detection.ipynb +++ b/tutorials/overlapped_speech_detection.ipynb @@ -1,13 +1,41 @@ { "cells": [ { - "cell_type": "code", - "execution_count": null, + "cell_type": "markdown", "metadata": {}, - "outputs": [], "source": [ - "# TODO: switch to AMI\n", - "PROTOCOL = 'Debug.SpeakerDiarization.Debug'" + "\"Open" + ] + }, + { + "attachments": {}, + "cell_type": "markdown", + "metadata": {}, + "source": [ + "# Finetuning a segmentation model on an overlapped speech detection task with `pyannote.audio`\n", + "\n", + "Overlapped speech detection (OSD) is the task of detecting regions where at least two speakers are speaking at the same time. In this notebook, we will finetune a segmentation model on the OSD task, then evaluate an OSD pipeline on AMI database." + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## Tutorial setup" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "### `Google Colab` setup" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "If you are running this tutorial on `Colab`, execute the following commands in order to setup `Colab` environment. These commands will install `pyannote.audio` and download a mini version of the `AMI` corpus." ] }, { @@ -16,17 +44,49 @@ "metadata": {}, "outputs": [], "source": [ - "# TODO: update this tutorial to do fine tuning of a model pretrained on DIHARD" + "!pip install -qq pyannote.audio==3.1.1\n", + "!pip install -qq ipython==7.34.0\n", + "!git clone https://github.com/pyannote/AMI-diarization-setup.git\n", + "%cd ./AMI-diarization-setup/pyannote/\n", + "!bash ./download_ami_mini.sh\n", + "%cd /content" ] }, { - "attachments": {}, "cell_type": "markdown", "metadata": {}, "source": [ - "# Overlapped speech detection with `pyannote.audio`\n", - "\n", - "Overlapped speech detection (OSD) is the task of detecting regions where at least two speakers are speaking at the same time. In this notebook, we will train and evaluate an OSD pipeline on Debug database." + "⚠ Restart the runtime (Runtime > Restart session)." + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "### Non `Google Colab` setup" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "If you are not using `Colab`, this tutorial assumes that\n", + "* `pyannote.audio` has been installed\n", + "* the [AMI corpus](https://groups.inf.ed.ac.uk/ami/corpus/) has already been [setup for use with `pyannote`](https://github.com/pyannote/AMI-diarization-setup/tree/main/pyannote)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## Protocol" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Firstly, we define a protocol, here `AMI.SpeakerDiarization.mini`" ] }, { @@ -35,8 +95,10 @@ "metadata": {}, "outputs": [], "source": [ - "from pyannote.database import get_protocol, FileFinder\n", - "protocol = get_protocol(PROTOCOL, preprocessors={\"audio\": FileFinder()})" + "from pyannote.database import registry, FileFinder\n", + "\n", + "registry.load_database(\"AMI-diarization-setup/pyannote/database.yml\")\n", + "protocol = registry.get_protocol(\"AMI.SpeakerDiarization.mini\", preprocessors={\"audio\": FileFinder()})" ] }, { @@ -60,7 +122,7 @@ }, { "cell_type": "code", - "execution_count": null, + "execution_count": 24, "metadata": {}, "outputs": [], "source": [ @@ -79,9 +141,21 @@ }, { "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], + "execution_count": 26, + "metadata": {}, + "outputs": [ + { + "data": { + "image/png": "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BRdcoF69eikoKEgff/yx3feB6jPr16/XqaeeqsjISKWnp+vpp582O2tAp3HXj5qbm3X//fdrxIgR6tatm3r16qVrrrlGe/bssYuDfoSjnaf5yNYtt9yioKAgPf/883af04/ARgQOeUuWLNHkyZO1fPlyLVy4UM3NzRozZowOHDhgDTNlyhR9+umn+uijj7RkyRLt2bNHl1xyifX7lpYWjRs3Tk1NTfrhhx/0zjvv6O2339bUqVO7IktAl1m5cqVeffVVjRw50u5z+hDgXmVlpU4++WSFhYVp3rx52rx5s/75z38qMTHRGubpp5/Wiy++qFdeeUU//vijunXrprFjx6qhocEa5sorr9SmTZu0cOFCffbZZ/r222910003dUWWgE731FNP6eWXX9ZLL72kLVu26KmnntLTTz+tf/3rX9Yw9CPA3oEDB3Tsscfq3//+t9PvA9FnampqNGbMGGVmZmr16tV65pln9Le//U2vvfaa6fkDOoO7flRXV6effvpJDz30kH766SfNnj1bOTk5uvDCC+3C0Y9wtPM0H1nMmTNHy5cvV69evdp9Rz+CDOAwU1paakgylixZYhiGYVRVVRlhYWHGRx99ZA2zZcsWQ5KxbNkywzAM44svvjCCg4ON4uJia5iXX37ZiIuLMxobGzs3A0AXqa2tNQYOHGgsXLjQOP3004277rrLMAz6EOCN+++/3zjllFNcft/a2mqkpaUZzzzzjPWzqqoqIyIiwpg5c6ZhGIaxefNmQ5KxcuVKa5h58+YZQUFBxu7du81LPHCIGDdunHH99dfbfXbJJZcYV155pWEY9CPAE0nGnDlzrO8D1WemTZtmJCYm2q3p7r//fmPw4MEm5wjofI79yJkVK1YYkoyCggLDMOhHgCNX/WjXrl1G7969jY0bNxqZmZnGc889Z/2OfgTDMAz+IgKHnerqaklS9+7dJUmrV69Wc3OzzjnnHGuYIUOGKCMjQ8uWLZMkLVu2TCNGjFBqaqo1zNixY1VTU6NNmzZ1YuqBrjN58mSNGzfOrq9I9CHAG5988olGjx6tyy67TCkpKRo1apRef/116/c7d+5UcXGxXT+Kj4/XCSecYNePEhISNHr0aGuYc845R8HBwfrxxx87LzNAFznppJP09ddfKzc3V5K0bt06LV26VOeff74k+hHgq0D1mWXLlum0005TeHi4NczY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", + "text/plain": [ + "" + ] + }, + "execution_count": 26, + "metadata": {}, + "output_type": "execute_result" + } + ], "source": [ "first_training_file['annotation']" ] @@ -96,9 +170,21 @@ }, { "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], + "execution_count": 27, + "metadata": {}, + "outputs": [ + { + "data": { + "image/png": "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HtXV1TFs2LD49re/He+99153dwV6xJYtW2LOnDkxfvz4GDhwYHz2s5+Nq666KlJK+TLiCAo98cQTccIJJ0RtbW1UVFTE73//+4L95YqZZcuWxRe+8IXYeeedY8yYMXHDDTdk3TXoNh3F0ebNm+PSSy+NCRMmxC677BK1tbXxjW98I1atWlVQhzhie7et81Fr55xzTlRUVMRPfvKTgu3iCIkIer3HH388Zs6cGU8//XQ0NjbG5s2bY9q0afH+++/ny1x00UXxwAMPxL333huPP/54rFq1Kk4++eT8/i1btsTxxx8fH3/8cfz973+Pu+66K371q1/F3Llze6JL0GMWL14ct99+exx00EEF28UQdOzdd9+Nww47LHbcccd46KGH4qWXXoof/ehHMXz48HyZG264IW655Za47bbbYtGiRbHLLrvEscceGx9++GG+zPTp0+PFF1+MxsbGePDBB+OJJ56Is88+uye6BN3u+uuvj3nz5sWtt94aL7/8clx//fVxww03xE9/+tN8GXEEhd5///04+OCD42c/+1mb+8sRM83NzTFt2rQYO3ZsLFmyJG688ca48sor44477si8f9AdOoqjTZs2xdKlS2POnDmxdOnSuO+++2LFihVx4oknFpQTR2zvtnU+yrn//vvj6aefjtra2q32iSMiQR+zbt26FBHp8ccfTymltH79+rTjjjume++9N1/m5ZdfThGRnnrqqZRSSn/6059SZWVlWrNmTb7MvHnzUnV1dfroo4+6twPQQzZu3Jj22Wef1NjYmI488sh04YUXppTEEJTi0ksvTYcffni7+1taWtLIkSPTjTfemN+2fv36NGDAgPTrX/86pZTSSy+9lCIiLV68OF/moYceShUVFemtt97KrvHQSxx//PHpW9/6VsG2k08+OU2fPj2lJI5gWyIi3X///fnfyxUzP//5z9Pw4cMLrukuvfTStO+++2bcI+h+xXHUlmeeeSZFRHr99ddTSuIIirUXR//+97/TnnvumZYvX57Gjh2bbrrppvw+cURKKflEBH3Ohg0bIiJi1113jYiIJUuWxObNm+OYY47Jl9lvv/1ir732iqeeeioiIp566qmYMGFC1NTU5Msce+yx0dzcHC+++GI3th56zsyZM+P4448viJUIMQSl+OMf/xhTpkyJU089NUaMGBETJ06MO++8M79/5cqVsWbNmoI4Gjp0aNTX1xfE0bBhw2LKlCn5Msccc0xUVlbGokWLuq8z0EMOPfTQePTRR+OVV16JiIjnn38+nnzyyTjuuOMiQhxBZ5UrZp566qk44ogjYqeddsqXOfbYY2PFihXx7rvvdlNvoPfYsGFDVFRUxLBhwyJCHEEpWlpaoqGhIS655JKoq6vbar84IiKiqqcbAJ3R0tISs2bNisMOOywOPPDAiIhYs2ZN7LTTTvmLhJyamppYs2ZNvkzrB6i5/bl90N8tWLAgli5dGosXL95qnxiCbfvnP/8Z8+bNi4svvji+//3vx+LFi+OCCy6InXbaKc4888x8HLQVJ63jaMSIEQX7q6qqYtdddxVHbBcuu+yyaG5ujv322y922GGH2LJlS1x99dUxffr0iAhxBJ1UrphZs2ZNjB8/fqs6cvta/xlC6O8+/PDDuPTSS+P000+P6urqiBBHUIrrr78+qqqq4oILLmhzvzgiQiKCPmbmzJmxfPnyePLJJ3u6KdBnvPnmm3HhhRdGY2Nj7Lzzzj3dHOiTWlpaYsqUKXHNNddERMTEiRNj+fLlcdttt8WZZ57Zw62DvuG3v/1t3H333XHPPfdEXV1dNDU1xaxZs6K2tlYcAdDjNm/eHKeddlqklGLevHk93RzoM5YsWRI333xzLF26NCoqKnq6OfRi/jQTfcZ5550XDz74YCxcuDBGjx6d3z5y5Mj4+OOPY/369QXl165dGyNHjsyXWbt27Vb7c/ugP1uyZEmsW7cuJk2aFFVVVVFVVRWPP/543HLLLVFVVRU1NTViCLZh1KhRccABBxRs23///eONN96IiP/FQVtx0jqO1q1bV7D/k08+iXfeeUccsV245JJL4rLLLouvf/3rMWHChGhoaIiLLroorr322ogQR9BZ5YoZ13nwvyTE66+/Ho2NjflPQ0SII9iWv/71r7Fu3brYa6+98s8cXn/99Zg9e3aMGzcuIsQR/0cigl4vpRTnnXde3H///fHYY49t9TGtyZMnx4477hiPPvpoftuKFSvijTfeiKlTp0ZExNSpU+OFF14oWPRyFxfFD5agvzn66KPjhRdeiKampvy/KVOmxPTp0/M/iyHo2GGHHRYrVqwo2PbKK6/E2LFjIyJi/PjxMXLkyII4am5ujkWLFhXE0fr162PJkiX5Mo899li0tLREfX19N/QCetamTZuisrLw9mOHHXaIlpaWiBBH0FnlipmpU6fGE088EZs3b86XaWxsjH333defwWC7kEtCvPrqq/HnP/85dtttt4L94gg61tDQEMuWLSt45lBbWxuXXHJJPPLIIxEhjvj/evrbsmFbzj333DR06ND0l7/8Ja1evTr/b9OmTfky55xzTtprr73SY489lp599tk0derUNHXq1Pz+Tz75JB144IFp2rRpqampKT388MNpjz32SJdffnlPdAl63JFHHpkuvPDC/O9iCDr2zDPPpKqqqnT11VenV199Nd19991p0KBBaf78+fky1113XRo2bFj6wx/+kJYtW5a+8pWvpPHjx6cPPvggX+bLX/5ymjhxYlq0aFF68skn0z777JNOP/30nugSdLszzzwz7bnnnunBBx9MK1euTPfdd1/afffd0/e+9718GXEEhTZu3Jiee+659Nxzz6WISD/+8Y/Tc889l15//fWUUnliZv369ammpiY1NDSk5cuXpwULFqRBgwal22+/vdv7C1noKI4+/vjjdOKJJ6bRo0enpqamgmcOH330Ub4OccT2blvno2Jjx45NN910U8E2cYREBL1eRLT575e//GW+zAcffJC++93vpuHDh6dBgwalr371q2n16tUF9fzrX/9Kxx13XBo4cGDafffd0+zZs9PmzZu7uTfQOxQnIsQQbNsDDzyQDjzwwDRgwIC03377pTvuuKNgf0tLS5ozZ06qqalJAwYMSEcffXRasWJFQZm33347nX766Wnw4MGpuro6nXXWWWnjxo3d2Q3oMc3NzenCCy9Me+21V9p5553TZz7zmfSDH/yg4EGPOIJCCxcubPNe6Mwzz0wplS9mnn/++XT44YenAQMGpD333DNdd9113dVFyFxHcbRy5cp2nzksXLgwX4c4Ynu3rfNRsbYSEeKIipRS6o5PXgAAAAAAANsf3xEBAAAAAABkRiICAAAAAADIjEQEAAAAAACQGYkIAAAAAAAgMxIRAAAAAABAZiQiAAAAAACAzEhEAAAAAAAAmZGIAAAACnzzm9+Mk046qaebAQAA9BNVPd0AAACg+1RUVHS4/4orroibb745Ukrd1CIAAKC/k4gAAIDtyOrVq/M//+Y3v4m5c+fGihUr8tsGDx4cgwcP7ommAQAA/ZQ/zQQAANuRkSNH5v8NHTo0KioqCrYNHjx4qz/N9MUvfjHOP//8mDVrVgwfPjxqamrizjvvjPfffz/OOuusGDJkSOy9997x0EMPFbzX8uXL47jjjovBgwdHTU1NNDQ0xH//+99u7jEAANDTJCIAAIBtuuuuu2L33XePZ555Js4///w499xz49RTT41DDz00li5dGtOmTYuGhobYtGlTRESsX78+jjrqqJg4cWI8++yz8fDDD8fatWvjtNNO6+GeAAAA3U0iAgAA2KaDDz44fvjDH8Y+++wTl19+eey8886x++67x3e+853YZ599Yu7cufH222/HsmXLIiLi1ltvjYkTJ8Y111wT++23X0ycODF+8YtfxMKFC+OVV17p4d4AAADdyXdEAAAA23TQQQflf95hhx1it912iwkTJuS31dTURETEunXrIiLi+eefj4ULF7b5fROvvfZafO5zn8u4xQAAQG8hEQEAAGzTjjvuWPB7RUVFwbaKioqIiGhpaYmIiPfeey9OOOGEuP7667eqa9SoURm2FAAA6G0kIgAAgLKbNGlS/O53v4tx48ZFVZXbDgAA2J75jggAAKDsZs6cGe+8806cfvrpsXjx4njttdfikUceibPOOiu2bNnS080DAAC6kUQEAABQdrW1tfG3v/0ttmzZEtOmTYsJEybErFmzYtiwYVFZ6TYEAAC2JxUppdTTjQAAAAAAAPon/xUJAAAAAADIjEQEAAAAAACQGYkIAAAAAAAgMxIRAAAAAABAZiQiAAAAAACAzEhEAAAAAAAAmZGIAAAAAAAAMiMRAQAAAAAAZEYiAgAAAAAAyIxEBAAAAAAAkBmJCAAAAAAAIDMSEQAAAAAAQGb+H3i6QsDNwRxqAAAAAElFTkSuQmCC", + "text/plain": [ + ", , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , ])>" + ] + }, + "execution_count": 27, + "metadata": {}, + "output_type": "execute_result" + } + ], "source": [ "from pyannote.audio.pipelines.overlapped_speech_detection import OracleOverlappedSpeechDetection\n", "oracle_osd = OracleOverlappedSpeechDetection()\n", @@ -111,7 +197,9 @@ "cell_type": "markdown", "metadata": {}, "source": [ - "## Training" + "## Finetuning\n", + "\n", + "In this part, we propose to finetune the [hf.co/pyannote/segmentation-3.0](https://hf.co/pyannote/segmentation-3.0) on an OSD *task*" ] }, { @@ -119,7 +207,7 @@ "cell_type": "markdown", "metadata": {}, "source": [ - "We initialize an OSD *task* that describes how the model will be trained:\n", + "Firstly, we initialize an OSD *task* that describes how the model will be trained:\n", "\n", "* `protocol` indicates that we will use files available in `protocol.train()`.\n", "* `duration=2.` and `batch_size=16` indicates that the model will ingest batches of 16 two seconds long audio chunks." @@ -136,11 +224,12 @@ ] }, { - "attachments": {}, "cell_type": "markdown", "metadata": {}, "source": [ - "We initialize the *model*: it needs to know about the task (`task=osd`) for which it is being trained for:" + "The next step is to load the segmentation model. Official [pyannote.audio](https://github.com/pyannote/pyannote-audio) models (i.e. those under the [`pyannote` organization](https://hf.co/pyannote) umbrella) are open-source, but gated. It means that you have to first accept users conditions on their respective Huggingface page to access the pretrained weights and hyper-parameters. Despite this initial process, those models can perfectly be downloaded for later offline use: keep reading this tutorial until the end to learn how to do that.\n", + "\n", + "For instance, to load the speaker segmentation model used in this tutorial, you have to visit [hf.co/pyannote/segmentation-3.0](https://hf.co/pyannote/segmentation-3.0), accept the terms, and log in using `notebook_login` below:" ] }, { @@ -149,8 +238,8 @@ "metadata": {}, "outputs": [], "source": [ - "from pyannote.audio.models.segmentation.debug import SimpleSegmentationModel\n", - "model = SimpleSegmentationModel(task=osd)" + "from huggingface_hub import notebook_login\n", + "notebook_login()" ] }, { @@ -158,18 +247,129 @@ "cell_type": "markdown", "metadata": {}, "source": [ - "Now that everything is ready, let's train with `pytorch-ligthning`!" + "We can then initialize the *pretrained model*: it needs to know about the task (`task=osd`) for which it is being trained for:" ] }, { "cell_type": "code", - "execution_count": null, + "execution_count": 30, "metadata": {}, "outputs": [], + "source": [ + "from pyannote.audio.core.model import Model\n", + "\n", + "pretrained_model = Model.from_pretrained(\"pyannote/segmentation-3.0\", use_auth_token=True)\n", + "# we assign the OSD task to the model\n", + "pretrained_model.task = osd" + ] + }, + { + "attachments": {}, + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Now that everything is ready, let's train with `pytorch-ligthning`!" + ] + }, + { + "cell_type": "code", + "execution_count": 33, + "metadata": {}, + "outputs": [ + { + "name": "stderr", + "output_type": "stream", + "text": [ + "GPU available: False, used: False\n", + "TPU available: False, using: 0 TPU cores\n", + "IPU available: False, using: 0 IPUs\n", + "HPU available: False, using: 0 HPUs\n" + ] + }, + { + "name": "stderr", + "output_type": "stream", + "text": [ + "\n", + " | Name | Type | Params | In sizes | Out sizes \n", + "---------------------------------------------------------------------------------------------------------------------\n", + "0 | sincnet | SincNet | 42.6 K | [1, 1, 32000] | [1, 60, 115] \n", + "1 | lstm | LSTM | 1.4 M | [1, 115, 60] | [[1, 115, 256], [[8, 1, 128], [8, 1, 128]]]\n", + "2 | linear | ModuleList | 49.4 K | ? | ? \n", + "3 | classifier | Linear | 129 | [1, 115, 128] | [1, 115, 1] \n", + "4 | activation | Sigmoid | 0 | [1, 115, 1] | [1, 115, 1] \n", + "5 | validation_metric | MetricCollection | 0 | ? | ? \n", + "---------------------------------------------------------------------------------------------------------------------\n", + "1.5 M Trainable params\n", + "0 Non-trainable params\n", + "1.5 M Total params\n", + "5.890 Total estimated model params size (MB)\n" + ] + }, + { + "data": { + "application/vnd.jupyter.widget-view+json": { + "model_id": "2433ca383e8f4470adae1e34ffa53b2f", + "version_major": 2, + "version_minor": 0 + }, + "text/plain": [ + "Sanity Checking: | | 0/? [00:00, , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , ])>" + ] + }, + "execution_count": 35, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "oracle_osd(test_file).get_timeline()" ] }, { @@ -203,20 +431,32 @@ }, { "cell_type": "code", - "execution_count": null, + "execution_count": 36, "metadata": {}, "outputs": [], "source": [ "from pyannote.audio import Inference\n", - "inference = Inference(model)\n", + "inference = Inference(pretrained_model)\n", "osd_probability = inference(test_file)" ] }, { "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], + "execution_count": 37, + "metadata": {}, + "outputs": [ + { + "data": { + "image/png": "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mqy+vr7yXgAhFaKjo8OaNm2aNX36dOvCCy+0brzxRsuyOIcICcI3vvEN621ve5txfzabtSZOnGjdfvvtzrbW1laroaHBeuSRRyzLsqxVq1ZZAKwFCxY4xzz77LNWIpGwduzYUbrGE1IlXHnlldZ//dd/Sds+/OEPW1dffbVlWZxHhPgBwHryySed73HNmV//+tfW6NGjpd903/jGN6wTTjihxFdESPlR55GO+fPnWwCsrVu3WpbFeUSIimkebd++3Tr88MOtlStXWkceeaR1xx13OPs4j4hlWRY9IsiAo62tDQAwZswYAMCiRYuQSqVw6aWXOseceOKJOOKIIzB37lwAwNy5c3HqqadiwoQJzjGXX3452tvb8cYbb5Sx9YRUjhtuuAFXXnmlNFcAziFCgvCvf/0L55xzDj72sY9h/PjxOPPMM/G73/3O2b9582bs3r1bmkcjR47EeeedJ82jUaNG4ZxzznGOufTSS5FMJjFv3rzyXQwhFeKtb30rXnzxRaxbtw4AsGzZMrz66qu44oorAHAeERKWuObM3Llz8Y53vAP19fXOMZdffjnWrl2LgwcPlulqCKke2trakEgkMGrUKACcR4QEIZvN4pprrsHXvvY1nHzyya79nEcEAGor3QBCwpDNZnHTTTfhggsuwCmnnAIA2L17N+rr650fCTYTJkzA7t27nWNEAaq9395HyGDn0UcfxeLFi7FgwQLXPs4hQvzZtGkT7r33XnzlK1/Bt771LSxYsABf+tKXUF9fj2uvvdaZB7p5Is6j8ePHS/tra2sxZswYziNySHDzzTejvb0dJ554ImpqapDJZPCjH/0IV199NQBwHhESkrjmzO7du3H00Ue7yrD3iWEICRns9Pb24hvf+AauuuoqNDU1AeA8IiQIP/3pT1FbW4svfelL2v2cRwSgIoIMMG644QasXLkSr776aqWbQsiAobm5GTfeeCOmT5+OxsbGSjeHkAFJNpvFOeecgx//+McAgDPPPBMrV67Efffdh2uvvbbCrSNkYPD444/joYcewsMPP4yTTz4ZS5cuxU033YTJkydzHhFCCKk4qVQKH//4x2FZFu69995KN4eQAcOiRYvwy1/+EosXL0Yikah0c0gVw9BMZMDwhS98AU899RRmzpyJKVOmONsnTpyI/v5+tLa2Ssfv2bMHEydOdI7Zs2ePa7+9j5DBzKJFi9DS0oKzzjoLtbW1qK2txSuvvIK77roLtbW1mDBhAucQIT5MmjQJb3rTm6RtJ510ErZt2wagMA9080ScRy0tLdL+dDqNAwcOcB6RQ4Kvfe1ruPnmm/Ef//EfOPXUU3HNNdfgy1/+Mn7yk58A4DwiJCxxzRn+ziOkoITYunUrpk+f7nhDAJxHhPgxe/ZstLS04IgjjnBkDlu3bsVXv/pVHHXUUQA4j0gOKiJI1WNZFr7whS/gySefxEsvveRy0zr77LNRV1eHF1980dm2du1abNu2Deeffz4A4Pzzz8eKFSukRc/+caEKlggZbFxyySVYsWIFli5d6vydc845uPrqq53PnEOEeHPBBRdg7dq10rZ169bhyCOPBAAcffTRmDhxojSP2tvbMW/ePGketba2YtGiRc4xL730ErLZLM4777wyXAUhlaW7uxvJpPz6UVNTg2w2C4DziJCwxDVnzj//fMyaNQupVMo5Zvr06TjhhBMYBoMcEthKiPXr12PGjBkYO3astJ/ziBBvrrnmGixfvlySOUyePBlf+9rX8PzzzwPgPCJ5Kp0tmxA/rr/+emvkyJHWyy+/bO3atcv56+7udo657rrrrCOOOMJ66aWXrIULF1rnn3++df755zv70+m0dcopp1iXXXaZtXTpUuu5556zDjvsMOub3/xmJS6JkIpz4YUXWjfeeKPznXOIEG/mz59v1dbWWj/60Y+s9evXWw899JA1dOhQ68EHH3SOufXWW61Ro0ZZ//znP63ly5dbH/jAB6yjjz7a6unpcY5597vfbZ155pnWvHnzrFdffdWaNm2addVVV1XikggpO9dee611+OGHW0899ZS1efNm64knnrDGjRtnff3rX3eO4TwiRKajo8NasmSJtWTJEguA9Ytf/MJasmSJtXXrVsuy4pkzra2t1oQJE6xrrrnGWrlypfXoo49aQ4cOtX7zm9+U/XoJKQVe86i/v996//vfb02ZMsVaunSpJHPo6+tzyuA8Ioc6fs8jlSOPPNK64447pG2cR4SKCFL1AND+/fGPf3SO6enpsT7/+c9bo0ePtoYOHWp96EMfsnbt2iWVs2XLFuuKK66whgwZYo0bN8766le/aqVSqTJfDSHVgaqI4BwixJ9///vf1imnnGI1NDRYJ554ovXb3/5W2p/NZq3vfve71oQJE6yGhgbrkksusdauXSsds3//fuuqq66yhg8fbjU1NVmf/vSnrY6OjnJeBiEVo7293brxxhutI444wmpsbLSOOeYY69vf/rYk6OE8IkRm5syZ2neha6+91rKs+ObMsmXLrLe97W1WQ0ODdfjhh1u33npruS6RkJLjNY82b95slDnMnDnTKYPziBzq+D2PVHSKCM4jkrAsyyqH5wUhhBBCCCGEEEIIIYQQQg49mCOCEEIIIYQQQgghhBBCCCElg4oIQgghhBBCCCGEEEIIIYSUDCoiCCGEEEIIIYQQQgghhBBSMqiIIIQQQgghhBBCCCGEEEJIyaAighBCCCGEEEIIIYQQQgghJYOKCEIIIYQQQgghhBBCCCGElAwqIgghhBBCCCGEEEIIIYQQUjKoiCCEEEIIIYRIfOpTn8IHP/jBSjeDEEIIIYQQMkiorXQDCCGEEEIIIeUjkUh47v/+97+PX/7yl7Asq0wtIoQQQgghhAx2qIgghBBCCCHkEGLXrl3O58ceewzf+973sHbtWmfb8OHDMXz48Eo0jRBCCCGEEDJIYWgmQgghhBBCDiEmTpzo/I0cORKJRELaNnz4cFdoposuughf/OIXcdNNN2H06NGYMGECfve736Grqwuf/vSnMWLECBx33HF49tlnpbpWrlyJK664AsOHD8eECRNwzTXXYN++fWW+YkIIIYQQQkiloSKCEEIIIYQQ4suf/vQnjBs3DvPnz8cXv/hFXH/99fjYxz6Gt771rVi8eDEuu+wyXHPNNeju7gYAtLa24uKLL8aZZ56JhQsX4rnnnsOePXvw8Y9/vMJXQgghhBBCCCk3VEQQQgghhBBCfDn99NPxne98B9OmTcM3v/lNNDY2Yty4cfjsZz+LadOm4Xvf+x7279+P5cuXAwDuvvtunHnmmfjxj3+ME088EWeeeSb+8Ic/YObMmVi3bl2Fr4YQQgghhBBSTpgjghBCCCGEEOLLaaed5nyuqanB2LFjceqppzrbJkyYAABoaWkBACxbtgwzZ87U5pvYuHEjjj/++BK3mBBCCCGEEFItUBFBCCGEEEII8aWurk76nkgkpG2JRAIAkM1mAQCdnZ143/veh5/+9KeusiZNmlTClhJCCCGEEEKqDSoiCCGEEEIIIbFz1lln4e9//zuOOuoo1NbytYMQQgghhJBDGeaIIIQQQgghhMTODTfcgAMHDuCqq67CggULsHHjRjz//PP49Kc/jUwmU+nmEUIIIYQQQsoIFRGEEEIIIYSQ2Jk8eTLmzJmDTCaDyy67DKeeeipuuukmjBo1CskkX0MIIYQQQgg5lEhYlmVVuhGEEEIIIYQQQgghhBBCCBmc0BSJEEIIIYQQQgghhBBCCCElg4oIQgghhBBCCCGEEEIIIYSUDCoiCCGEEEIIIYQQQgghhBBSMqiIIIQQQgghhBBCCCGEEEJIyaAighBCCCGEEEIIIYQQQgghJYOKCEIIIYQQQgghhBBCCCGElAwqIgghhBBCCCGEEEIIIYQQUjKoiCCEEEIIIYQQQgghhBBCSMmgIoIQQgghhBBCCCGEEEIIISWDighCCCGEEEIIIYQQQgghhJQMKiIIIYQQQgghhBBCCCGEEFIyqIgghBBCCCGEEEIIIYQQQkjJ+P8BVmGsjeyTs2EAAAAASUVORK5CYII=", + "text/plain": [ + "" + ] + }, + "execution_count": 37, + "metadata": {}, + "output_type": "execute_result" + } + ], "source": [ "osd_probability" ] @@ -226,7 +466,7 @@ "cell_type": "markdown", "metadata": {}, "source": [ - "## Pipeline" + "## Pipeline" ] }, { @@ -244,12 +484,12 @@ }, { "cell_type": "code", - "execution_count": null, + "execution_count": 38, "metadata": {}, "outputs": [], "source": [ "from pyannote.audio.pipelines import OverlappedSpeechDetection as OverlappedSpeechDetectionPipeline\n", - "pipeline = OverlappedSpeechDetectionPipeline(scores=inference).instantiate(\n", + "pipeline = OverlappedSpeechDetectionPipeline(pretrained_model).instantiate(\n", " {\"onset\": 0.5, \"offset\": 0.5, \"min_duration_on\": 0.1, \"min_duration_off\": 0.1})" ] }, @@ -263,9 +503,21 @@ }, { "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], + "execution_count": 39, + "metadata": {}, + "outputs": [ + { + "data": { + "image/png": "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r0dNXXrppVFQUBA//elPm23XRwgi6PFWrVoVc+fOjWeeeSYqKytjz549MW3atHj33XdzY6688sp4+OGH44EHHohVq1bF1q1b4/zzz8/t37t3b0yfPj0+/PDD+Oc//xn33ntv/PrXv44lS5bkY0qQN2vXro277rorjj322Gbb9RC07e23345TTjkl+vTpE48++mi89NJL8eMf/ziGDBmSG3PzzTfH7bffHnfeeWesWbMmDjvssDjrrLPi/fffz42ZOXNmvPjii1FZWRmPPPJIPPXUU3HJJZfkY0rQ7ZYtWxbLly+PO+64IzZt2hTLli2Lm2++OX72s5/lxugjaO7dd9+N4447Ln7+85+3uL8reqauri6mTZsWY8eOjaqqqrjlllvi2muvjbvvvjvz+UF3aKuPdu/eHevXr4/FixfH+vXr48EHH4yampo499xzm43TRxzs2ns9avTQQw/FM888E2VlZZ/Yp4+IBAeYHTt2pIhIq1atSimltHPnztSnT5/0wAMP5MZs2rQpRURavXp1Simlv/zlL6mwsDBt27YtN2b58uWppKQkffDBB907AciT+vr6NH78+FRZWZmmTp2a5s2bl1LSQ9ARixYtSqeeemqr+xsaGtKIESPSLbfcktu2c+fO1Ldv3/Tb3/42pZTSSy+9lCIirV27Njfm0UcfTQUFBemNN97IrnjoIaZPn56+/e1vN9t2/vnnp5kzZ6aU9BG0JyLSQw89lLvdVT3zi1/8Ig0ZMqTZ3+kWLVqUjjrqqIxnBN1v3z5qybPPPpsiIm3ZsiWlpI9gX6310X//+990xBFHpI0bN6axY8emW2+9NbdPH5FSSt4RwQFn165dERFx+OGHR0REVVVV7NmzJ84888zcmAkTJsSYMWNi9erVERGxevXqmDRpUpSWlubGnHXWWVFXVxcvvvhiN1YP+TN37tyYPn16s16J0EPQEX/+859jypQpccEFF8Tw4cNj8uTJcc899+T2b968ObZt29asjwYNGhQnnXRSsz4aPHhwTJkyJTfmzDPPjMLCwlizZk33TQby5OSTT44nnngiXn755YiIeP755+Ppp5+Os88+OyL0EeyvruqZ1atXx2mnnRaHHnpobsxZZ50VNTU18fbbb3fTbKDn2LVrVxQUFMTgwYMjQh9BRzQ0NERFRUUsXLgwJk6c+In9+oiIiKJ8FwD7o6GhIebPnx+nnHJKHHPMMRERsW3btjj00ENzf0loVFpaGtu2bcuNafoL1Mb9jfugt7v//vtj/fr1sXbt2k/s00PQvn//+9+xfPnyuOqqq+IHP/hBrF27Nq644oo49NBDY9asWbk+aKlPmvbR8OHDm+0vKiqKww8/XB9xULj66qujrq4uJkyYEIccckjs3bs3rr/++pg5c2ZEhD6C/dRVPbNt27YYN27cJ47RuK/pxxBCb/f+++/HokWLYsaMGVFSUhIR+gg6YtmyZVFUVBRXXHFFi/v1ERGCCA4wc+fOjY0bN8bTTz+d71LggPH666/HvHnzorKyMvr165fvcuCA1NDQEFOmTIkbbrghIiImT54cGzdujDvvvDNmzZqV5+rgwPD73/8+7rvvvvjNb34TEydOjOrq6pg/f36UlZXpIwDybs+ePXHhhRdGSimWL1+e73LggFFVVRW33XZbrF+/PgoKCvJdDj2Yj2bigHHZZZfFI488EitXroxRo0blto8YMSI+/PDD2LlzZ7Px27dvjxEjRuTGbN++/RP7G/dBb1ZVVRU7duyI448/PoqKiqKoqChWrVoVt99+exQVFUVpaakegnaMHDkyvvjFLzbbdvTRR8drr70WER/3QUt90rSPduzY0Wz/Rx99FG+99ZY+4qCwcOHCuPrqq+Mb3/hGTJo0KSoqKuLKK6+MG2+8MSL0EeyvruoZf8+Dj0OILVu2RGVlZe7dEBH6CNrz97//PXbs2BFjxozJ/c5hy5YtsWDBgjjyyCMjQh/xfwQR9HgppbjsssvioYceiieffPITb9M64YQTok+fPvHEE0/kttXU1MRrr70W5eXlERFRXl4eL7zwQrMnvca/XOz7iyXobc4444x44YUXorq6OvdnypQpMXPmzNzPegjadsopp0RNTU2zbS+//HKMHTs2IiLGjRsXI0aMaNZHdXV1sWbNmmZ9tHPnzqiqqsqNefLJJ6OhoSFOOumkbpgF5Nfu3bujsLD5Pz8OOeSQaGhoiAh9BPurq3qmvLw8nnrqqdizZ09uTGVlZRx11FE+BoODQmMI8corr8Rf//rXGDp0aLP9+gjaVlFRERs2bGj2O4eysrJYuHBhPP744xGhj/j/8v1t2dCeOXPmpEGDBqW//e1vqba2Nvdn9+7duTGXXnppGjNmTHryySfTunXrUnl5eSovL8/t/+ijj9IxxxyTpk2blqqrq9Njjz2WPvOZz6RrrrkmH1OCvJs6dWqaN29e7rYegrY9++yzqaioKF1//fXplVdeSffdd18aMGBAWrFiRW7MTTfdlAYPHpz+9Kc/pQ0bNqSvfvWrady4cem9997LjfnKV76SJk+enNasWZOefvrpNH78+DRjxox8TAm63axZs9IRRxyRHnnkkbR58+b04IMPpmHDhqXvf//7uTH6CJqrr69Pzz33XHruuedSRKSf/OQn6bnnnktbtmxJKXVNz+zcuTOVlpamioqKtHHjxnT//fenAQMGpLvuuqvb5wtZaKuPPvzww3TuueemUaNGperq6ma/c/jggw9yx9BHHOzaez3a19ixY9Ott97abJs+QhBBjxcRLf751a9+lRvz3nvvpe9973tpyJAhacCAAelrX/taqq2tbXac//znP+nss89O/fv3T8OGDUsLFixIe/bs6ebZQM+wbxChh6B9Dz/8cDrmmGNS375904QJE9Ldd9/dbH9DQ0NavHhxKi0tTX379k1nnHFGqqmpaTbmzTffTDNmzEjFxcWppKQkXXzxxam+vr47pwF5U1dXl+bNm5fGjBmT+vXrlz772c+mH/7wh81+0aOPoLmVK1e2+G+hWbNmpZS6rmeef/75dOqpp6a+ffumI444It10003dNUXIXFt9tHnz5lZ/57By5crcMfQRB7v2Xo/21VIQoY8oSCml7njnBQAAAAAAcPDxHREAAAAAAEBmBBEAAAAAAEBmBBEAAAAAAEBmBBEAAAAAAEBmBBEAAAAAAEBmBBEAAAAAAEBmBBEAAAAAAEBmBBEAAEAz3/rWt+K8887LdxkAAEAvUZTvAgAAgO5TUFDQ5v6lS5fGbbfdFimlbqoIAADo7QQRAABwEKmtrc39/Lvf/S6WLFkSNTU1uW3FxcVRXFycj9IAAIBeykczAQDAQWTEiBG5P4MGDYqCgoJm24qLiz/x0Uynn356XH755TF//vwYMmRIlJaWxj333BPvvvtuXHzxxTFw4MD4/Oc/H48++mizx9q4cWOcffbZUVxcHKWlpVFRURH/+9//unnGAABAvgkiAACAdt17770xbNiwePbZZ+Pyyy+POXPmxAUXXBAnn3xyrF+/PqZNmxYVFRWxe/fuiIjYuXNnfPnLX47JkyfHunXr4rHHHovt27fHhRdemOeZAAAA3U0QAQAAtOu4446LH/3oRzF+/Pi45pprol+/fjFs2LD47ne/G+PHj48lS5bEm2++GRs2bIiIiDvuuCMmT54cN9xwQ0yYMCEmT54cv/zlL2PlypXx8ssv53k2AABAd/IdEQAAQLuOPfbY3M+HHHJIDB06NCZNmpTbVlpaGhERO3bsiIiI559/PlauXNni9028+uqr8YUvfCHjigEAgJ5CEAEAALSrT58+zW4XFBQ021ZQUBAREQ0NDRER8c4778Q555wTy5Yt+8SxRo4cmWGlAABATyOIAAAAutzxxx8ff/jDH+LII4+MoiL/7AAAgIOZ74gAAAC63Ny5c+Ott96KGTNmxNq1a+PVV1+Nxx9/PC6++OLYu3dvvssDAAC6kSACAADocmVlZfGPf/wj9u7dG9OmTYtJkybF/PnzY/DgwVFY6J8hAABwMClIKaV8FwEAAAAAAPRO/lckAAAAAAAgM4IIAAAAAAAgM4IIAAAAAAAgM4IIAAAAAAAgM4IIAAAAAAAgM4IIAAAAAAAgM4IIAAAAAAAgM4IIAAAAAAAgM4IIAAAAAAAgM4IIAAAAAAAgM4IIAAAAAAAgM4IIAAAAAAAgM/8PKuDJkZRvw6cAAAAASUVORK5CYII=", + "text/plain": [ + ", , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , ])>" + ] + }, + "execution_count": 39, + "metadata": {}, + "output_type": "execute_result" + } + ], "source": [ "pipeline(test_file).get_timeline()" ] @@ -288,25 +540,27 @@ }, { "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "# to make things faster, we run the inference once and for all... \n", - "validation_files = list(protocol.development())\n", - "for file in validation_files:\n", - " file['osd'] = inference(file)\n", - "# ... and tell the pipeline to load OSD scores directly from files\n", - "pipeline = OverlappedSpeechDetectionPipeline(scores=\"osd\")" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], + "execution_count": 40, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "{'loss': 0.7273619100616171,\n", + " 'params': {'onset': 0.4321866835452871,\n", + " 'offset': 0.33656592926710593,\n", + " 'min_duration_on': 0.11171631479481339,\n", + " 'min_duration_off': 0.07311754878841395}}" + ] + }, + "execution_count": 40, + "metadata": {}, + "output_type": "execute_result" + } + ], "source": [ "from pyannote.pipeline import Optimizer\n", + "validation_files = list(protocol.development())\n", "optimizer = Optimizer(pipeline)\n", "optimizer.tune(validation_files, n_iterations=200, show_progress=False)" ] @@ -321,11 +575,23 @@ }, { "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "optimized_pipeline = OverlappedSpeechDetectionPipeline(scores=inference).instantiate(optimizer.best_params)\n", + "execution_count": 41, + "metadata": {}, + "outputs": [ + { + "data": { + "image/png": "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c/HFF6fBgwenv/zlL6muri73b+fOnbkxF110URo3blx6/PHH0zPPPJMqKipSRUVFbv9HH32Ujj766DRjxoxUU1OTHnnkkfSxj30sXXXVVYWYEhTcSSedlObNm5f7XA9B255++ulUXFycrr322vTKK6+ke+65Jw0cODCtWLEiN+aGG25IQ4YMSX/4wx/S+vXr05e//OU0YcKE9N577+XGfOlLX0pTp05Na9asSU8++WSaOHFimjVrViGmBN1uzpw5afTo0emhhx5KGzduTPfff38aPnx4+u53v5sbo4+gpYaGhvTss8+mZ599NkVE+tGPfpSeffbZtGnTppRS1/TM9u3bU1lZWaqsrEwbNmxI9957bxo4cGC64447un2+kIW2+ujDDz9MZ555ZhozZkyqqalp8TuHDz74IHcMfcTBrr3Hoz2NHz8+3XzzzS226SMEEfR4EdHqv1/84he5Me+99176zne+k4YOHZoGDhyYvvKVr6S6uroWx/nXv/6VTj/99DRgwIA0fPjwtGDBgrRr165ung30DHsGEXoI2vfggw+mo48+OvXr1y9NmjQp3XnnnS32NzY2psWLF6eysrLUr1+/dMopp6Ta2toWY9588800a9asVFJSkkpLS9P555+fGhoaunMaUDD19fVp3rx5ady4cal///7p4x//ePr+97/f4hc9+ghaWrlyZas/C82ZMyel1HU989xzz6UTTzwx9evXL40ePTrdcMMN3TVFyFxbfbRx48Z9/s5h5cqVuWPoIw527T0e7am1IEIfUZRSSt3xygsAAAAAAODg4z0iAAAAAACAzAgiAAAAAACAzAgiAAAAAACAzAgiAAAAAACAzAgiAAAAAACAzAgiAAAAAACAzAgiAAAAAACAzAgiAACAFr7xjW/EWWedVegyAACAXqK40AUAAADdp6ioqM39S5cujVtuuSVSSt1UEQAA0NsJIgAA4CBSV1eX+/g3v/lNLFmyJGpra3PbSkpKoqSkpBClAQAAvZQ/zQQAAAeRkSNH5v4NHjw4ioqKWmwrKSnZ608znXzyyXHppZfG/PnzY+jQoVFWVhZ33XVXvPvuu3H++efHoEGD4pOf/GQ8/PDDLb7Xhg0b4vTTT4+SkpIoKyuLysrK+M9//tPNMwYAAApNEAEAALTr7rvvjuHDh8fTTz8dl156aVx88cVxzjnnxPHHHx/r1q2LGTNmRGVlZezcuTMiIrZv3x5f/OIXY+rUqfHMM8/EI488Elu3bo1zzz23wDMBAAC6myACAABo17HHHhs/+MEPYuLEiXHVVVdF//79Y/jw4fHtb387Jk6cGEuWLIk333wz1q9fHxERt912W0ydOjWuu+66mDRpUkydOjV+/vOfx8qVK+Pll18u8GwAAIDu5D0iAACAdh1zzDG5jw855JAYNmxYTJkyJbetrKwsIiK2bdsWERHPPfdcrFy5stX3m3j11VfjU5/6VMYVAwAAPYUgAgAAaFffvn1bfF5UVNRiW1FRUURENDY2RkTEO++8E2eccUYsW7Zsr2ONGjUqw0oBAICeRhABAAB0ueOOOy5+97vfxRFHHBHFxX7sAACAg5n3iAAAALrc3Llz46233opZs2bF2rVr49VXX41HH300zj///Ni9e3ehywMAALqRIAIAAOhy5eXl8be//S12794dM2bMiClTpsT8+fNjyJAh0aePH0MAAOBgUpRSSoUuAgAAAAAA6J38VyQAAAAAACAzgggAAAAAACAzgggAAAAAACAzgggAAAAAACAzgggAAAAAACAzgggAAAAAACAzgggAAAAAACAzgggAAAAAACAzgggAAAAAACAzgggAAAAAACAzgggAAAAAACAzgggAAAAAACAz/wcY2O18OzpOTgAAAABJRU5ErkJggg==", + "text/plain": [ + ", , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , ])>" + ] + }, + "execution_count": 41, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "optimized_pipeline = OverlappedSpeechDetectionPipeline(pretrained_model).instantiate(optimizer.best_params)\n", "optimized_pipeline(test_file).get_timeline()" ] } @@ -346,7 +612,7 @@ "name": "python", "nbconvert_exporter": "python", "pygments_lexer": "ipython3", - "version": "3.8.5" + "version": "3.10.13" } }, "nbformat": 4, diff --git a/tutorials/training_a_model.ipynb b/tutorials/training_a_model.ipynb index f3e019f8b..582d729a5 100644 --- a/tutorials/training_a_model.ipynb +++ b/tutorials/training_a_model.ipynb @@ -1,886 +1 @@ -{ - "cells": [ - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "# preparing notebook for visualization purposes\n", - "# (only show outputs between t=180s and t=240s)\n", - "from pyannote.core import notebook, Segment\n", - "notebook.crop = Segment(210, 240)" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "# Training, fine-tuning, and transfer learning with `pyannote.audio`\n", - "\n", - "In this tutorial, you will learn how to use `pyannote.audio` to \n", - "\n", - "* train a voice activity detection model from scratch, \n", - "* fine-tune a pretrained speaker segmentation model,\n", - "* perform transfer learning (from speaker segmentation to overlapped speech detection)\n", - "\n", - "## Data preparation\n", - "\n", - "This tutorial assumes that \n", - "* the [AMI corpus](https://groups.inf.ed.ac.uk/ami/corpus/) has already been [setup for use with `pyannote`](https://github.com/pyannote/AMI-diarization-setup/tree/main/pyannote)\n", - "* the `PYANNOTE_DATABASE_CONFIG` environment variable is set accordingly. \n", - "\n", - "See [`pyannote.database` documentation](https://github.com/pyannote/pyannote-database#pyannote-database) to learn how to prepare your own dataset for training with `pyannote.audio`." - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "from pyannote.database import get_protocol\n", - "ami = get_protocol('AMI.SpeakerDiarization.only_words')" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "## Training a voice activity detection model from scratch" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "Voice activity detection (VAD) is the task of detecting speech regions in a given audio stream or recording.\n", - "\n", - "We initialize a VAD *task* that describes how the model will be trained:\n", - "\n", - "* `ami` indicates that we will use files available in `ami.train()`.\n", - "* `duration=2.` and `batch_size=128` indicates that the model will ingest batches of 128 two seconds long audio chunks." - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "from pyannote.audio.tasks import VoiceActivityDetection\n", - "vad_task = VoiceActivityDetection(ami, duration=2.0, batch_size=128)" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "We initialize one *model* with the `PyanNet` architecture used [in that paper](https://arxiv.org/abs/2104.04045). \n", - "In particular, we increase the default stride of the initial `sincnet` feature extraction layer to `10`.\n", - "\n", - "The model is also provided with the task (`task=vad_task`) for which it is being trained:" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "from pyannote.audio.models.segmentation import PyanNet\n", - "vad_model = PyanNet(task=vad_task, sincnet={'stride': 10})" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "Now that everything is ready, let's train with `pytorch-ligthning`!" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [ - { - "name": "stderr", - "output_type": "stream", - "text": [ - "GPU available: True, used: True\n", - "TPU available: False, using: 0 TPU cores\n", - "IPU available: False, using: 0 IPUs\n", - "LOCAL_RANK: 0 - CUDA_VISIBLE_DEVICES: [0]\n", - "\n", - " | Name | Type | Params | In sizes | Out sizes \n", - "-----------------------------------------------------------------------------------------------------------------------\n", - "0 | sincnet | SincNet | 42.6 K | [128, 1, 32000] | [128, 60, 115] \n", - "1 | lstm | LSTM | 589 K | [128, 115, 60] | [[128, 115, 256], [[4, 128, 128], [4, 128, 128]]]\n", - "2 | linear | ModuleList | 49.4 K | ? | ? \n", - "3 | classifier | Linear | 129 | [128, 115, 128] | [128, 115, 1] \n", - "4 | activation | Sigmoid | 0 | [128, 115, 1] | [128, 115, 1] \n", - "5 | validation_metric | AUROC | 0 | ? | ? \n", - "-----------------------------------------------------------------------------------------------------------------------\n", - "681 K Trainable params\n", - "0 Non-trainable params\n", - "681 K Total params\n", - "2.728 Total estimated model params size (MB)\n" - ] - }, - { - "data": { - "application/vnd.jupyter.widget-view+json": { - "model_id": "", - "version_major": 2, - "version_minor": 0 - }, - "text/plain": [ - "HBox(children=(HTML(value='Validation sanity check'), FloatProgress(value=1.0, bar_style='info', layout=Layout…" - ] - }, - "metadata": {}, - "output_type": "display_data" - }, - { - "data": { - "application/vnd.jupyter.widget-view+json": { - "model_id": "0a76f04fd4ab4cad9dac09344b932e49", - "version_major": 2, - "version_minor": 0 - }, - "text/plain": [ - "HBox(children=(HTML(value='Training'), FloatProgress(value=1.0, bar_style='info', layout=Layout(flex='2'), max…" - ] - }, - "metadata": {}, - "output_type": "display_data" - }, - { - "data": { - "application/vnd.jupyter.widget-view+json": { - "model_id": "", - "version_major": 2, - "version_minor": 0 - }, - "text/plain": [ - "HBox(children=(HTML(value='Validating'), FloatProgress(value=1.0, bar_style='info', layout=Layout(flex='2'), m…" - ] - }, - "metadata": {}, - "output_type": "display_data" - }, - { - "name": "stdout", - "output_type": "stream", - "text": [ - "\n" - ] - } - ], - "source": [ - "import pytorch_lightning as pl\n", - "trainer = pl.Trainer(devices=1, accelerator=\"gpu\", max_epochs=1)\n", - "trainer.fit(vad_model)" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "For the purpose of this tutorial, the model is trained for only 1 epoch. One can obviously expect better performance by training longer and on more data.\n", - "\n", - "See [`pytorch-lightning`](https://www.pytorchlightning.ai/) documentation to learn more about the [`Trainer` API](https://pytorch-lightning.readthedocs.io/en/latest/common/trainer.html), in particular." - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "Once trained, the model can be applied to a test file:" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "test_file = next(ami.test())\n", - "# here we use a test file provided by the protocol, but it could be any audio file\n", - "# e.g. test_file = \"/path/to/test.wav\"." - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "Because the model was trained on 2s audio chunks and that test files are likely to be much longer than that, we wrap the `model` with an `Inference` instance: it will take care of sliding a 2s window over the whole file and aggregate the output of the model." - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [ - { - "data": { - "image/png": "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", - "text/plain": [ - "" - ] - }, - "execution_count": null, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "from pyannote.audio import Inference\n", - "vad = Inference(vad_model)\n", - "\n", - "vad_probability = vad(test_file)\n", - "vad_probability" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "Perfect voice activity detection output should look like that:" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [ - { - "data": { - "image/png": "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", - "text/plain": [ - ", , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , ])>" - ] - }, - "execution_count": null, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "expected_output = test_file[\"annotation\"].get_timeline().support()\n", - "expected_output" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "## Fine-tuning a pretrained speaker segmentation model\n", - "\n", - "Speaker diarization is the task of partitioning a given audio stream of recording into according to the speaker identity.\n", - "\n", - "[`pyannote/segmentation`](https://hf.co/pyannote/segmentation) is a model that was pretrained to perform speaker diarization, but only locally, on 5s-long audio chunks. \n", - "\n", - "To load the speaker segmentation model, \n", - "\n", - "* accept the user conditions on [hf.co/pyannote/segmentation](https://hf.co/pyannote/segmentation).\n", - "* login using `notebook_login` below" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "from huggingface_hub import notebook_login\n", - "notebook_login()" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "from pyannote.audio import Model\n", - "pretrained = Model.from_pretrained(\"pyannote/segmentation\", use_auth_token=True)" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "Let's visualize how it performs on our test file:" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [ - { - "data": { - "image/png": "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Wf/7gJervGLztfS6/WLla+3ljoD8qfl57NblYGstEej+VehaU26k93NB08v07Z037vBsst/L2K3XebapnWTpdj5nus6H/B2a7fryd6/NYrrV78l/v7at5dT9iT/B69ovGv+YzK9F5eCQO27LvwYYlzK3lJDTrW++UBCCIbxArvWK64Jxtu7DstavuYiTr4mDk0vQuI7/cBz/Ep3N7ftyf3M8m5vH7XahYNu/Zc/h2/Z928xvtjM9/8l0zecY5h52MrJ7FTzhM2/ePLtgwYJBrUNERERERERERLYabMJHNWhFREREREREREYYJXxEREREREREREYYJXxEREREREREREYYJXxEREREREREREYYJXxEREREREREREYYJXxEREREREREREYYJXxEREREREREREYYJXxEREREREREREYYY60d3AqM2Qx0AA1DEpHI8FSLyriMfCrnMhqonMtooHIuo4HKuYx0tUCptbZuoCsYdMIHwBizwFo7b9ArEhmmVMZlNFA5l9FA5VxGA5VzGQ1UzmWkG4oyriZdIiIiIiIiIiIjjBI+IiIiIiIiIiIjzFAlfH49ROsRGa5UxmU0UDmX0UDlXEYDlXMZDVTOZaQbdBkfkj58RERERERERERk+FCTLhERERERERGREWanCR9jzCRjzKPGmNeMMa8aYy7LTX9v7rlnjJm3zTJfNsa8aYxZaow5eVcFLzJU+lvOjTFTjTFxY8yLucd1hYtepG92UM5/YIxZYox52RhztzGmstsy2p9L0ehvGde+XIrRDsr5t3Nl/EVjzAPGmPG56cYY87PcvvxlY8yBhX0HIjs3gHJ+jDGmpdv+/OuFfQciO7e9ct7t9c8bY6wxpjb3vN/785026TLG1AP11trnjTFlwELgTMACHnA98L/W2gW5+fcGbgEOAcYDDwF7WGuz/Xv7IrvPAMr5VOBea+0+hYlYpP92UM4nAo9YazPGmKsBrLVXaH8uxWYAZXwq2pdLkdlBOV9jrW3NzfNZYG9r7cXGmFOBS4FTgfnANdba+YWJXqRvBlDOj8E/Vn9XgUIW6bftlXNr7WvGmEnAb4E9gYOstQ0D2Z/vtIaPtXa9tfb53HgbsBiYYK1dbK1d2ssi7wZutdYmrbXLgTfxTxZEhq0BlHORorODcv6AtTaTm+0Z/JNj0P5ciswAyrhI0dlBOW/tNlsp/kUr8Pflf7S+Z4DK3EmGyLA1gHIuUnS2V85zL/8E+CI9y3i/9+f96sMndyXsAOC/O5htArC62/M13YIWGfb6WM4BphljXjDGPG6MOWrXRyYydHZQzj8G/DM3rv25FK0+lnHQvlyK2Lbl3BjzXWPMauCDQFeTFu3Lpaj1sZwDHGaMeckY809jzJzdH6nIwHUv58aYdwNrrbUvbTNbv/fnfU74GGNiwJ3A5dtkVkVGjH6U8/XAZGvtAcDngD8bY8p3R4wig7W9cm6M+SqQAW4uVGwiQ6EfZVz7cilavZVza+1XrbWT8Mv4ZwoZn8hQ6Ec5fx6YYq3dD7gW+GsBwhUZkO7lHP845Sv0TGYOWJ8SPsaYYC6Am621d+1k9rXApG7PJ+amiQxr/SnnuSYuW3LjC4G3gD12fZQig7O9cm6M+SjwLuCDdmvnbtqfS9HpTxnXvlyKVR+OWW4Gzs6Na18uRak/5dxa22qtbc+N3wcEuzq6FRnOeinnM4BpwEvGmBX4++znjTHjGMD+vC936TLADcBia+2P+xDzPcB5xpiwMWYaMAt4tg/LiRRMf8u5MabOGOPmxqfjl/NluzZKkcHZXjk3xpyC30b4DGttZ7dFtD+XotLfMq59uRSjHZTzWd1mezewJDd+D/Dh3N1dDgVarLXrd1vAIgPQ33JujBmXWwZjzCH457lbdl/EIv3XWzm31i6y1o6x1k611k7Fb7Z1oLV2AwPYnwf6EMcRwIeARcaYF3PTvgKE8avL1QH/MMa8aK092Vr7qjHmduA1/OpIn9YdXaQI9KucA0cD3zLGpPHv4nWxtbZx94ct0i/bK+c/wy/rD+aOlZ6x1l6s/bkUoX6VcbQvl+K0vXL+cWPMbPyyvBK4OPfaffh3dHkT6AQu2K3RigxMf8v5OcAlxpgMEAfO61ZjWWS46rWc52qp9abf+/Od3pZdRERERERERESKS7/u0iUiIiIiIiIiIsOfEj4iIiIiIiIiIiOMEj4iIiIiIiIiIiOMEj4iIiIiIiIiIiOMEj4iIiIiIiIiIiOMEj4iIiJStIwxNcaYF3OPDcaYtbnxdmPMLwsdn4iIiEih6LbsIiIiMiIYY74JtFtrf1joWEREREQKTTV8REREZMQxxhxjjLk3N/5NY8wfjDFPGmNWGmPOMsZ83xizyBjzL2NMMDffQcaYx40xC40x9xtj6gv7LkREREQGTgkfERERGQ1mAMcBZwA3AY9aa/cF4sBpuaTPtcA51tqDgN8B3y1UsCIiIiKDFSh0ACIiIiK7wT+ttWljzCLABf6Vm74ImArMBvYBHjTGkJtnfQHiFBERERkSSviIiIjIaJAEsNZ6xpi03dqJoYd/PGSAV621hxUqQBEREZGhpCZdIiIiIrAUqDPGHAZgjAkaY+YUOCYRERGRAVPCR0REREY9a20KOAe42hjzEvAicHhBgxIREREZBN2WXURERERERERkhFENHxERERERERGREUYJHxERERERERGREUYJHxERERERERGREUYJHxERERERERGREUYJHxERERERERGREUYJHxERERERERGREUYJHxERERERERGREUYJHxERERERERGREeb/A0KZQ28YdpupAAAAAElFTkSuQmCC", - "text/plain": [ - "" - ] - }, - "execution_count": null, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "spk_probability = Inference(pretrained, step=2.5)(test_file)\n", - "spk_probability" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "A perfect output would look like that:" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [ - { - "data": { - "image/png": "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", - "text/plain": [ - "" - ] - }, - "execution_count": null, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "test_file[\"annotation\"].discretize(notebook.crop, resolution=0.010)" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "We are going to fine-tune this pretrained model on the AMI dataset:" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "from pyannote.audio.tasks import SpeakerDiarization\n", - "seg_task = SpeakerDiarization(ami, duration=5.0, max_num_speakers=4)" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "To check that fine-tuning was actually helpful, we need to evaluate the performance of the pretrained model, and compute the average local diarization error rate on a 5s window sliding over the whole test set. To do so, we need to create a helper function:" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "def test(model, protocol, subset=\"test\"):\n", - " from pyannote.audio.utils.signal import binarize\n", - " from pyannote.audio.utils.metric import DiscreteDiarizationErrorRate\n", - " from pyannote.audio.pipelines.utils import get_devices\n", - "\n", - " (device,) = get_devices(needs=1)\n", - " metric = DiscreteDiarizationErrorRate()\n", - " files = list(getattr(protocol, subset)())\n", - "\n", - " inference = Inference(model, device=device)\n", - "\n", - " for file in files:\n", - " reference = file[\"annotation\"]\n", - " hypothesis = binarize(inference(file))\n", - " uem = file[\"annotated\"]\n", - " _ = metric(reference, hypothesis, uem=uem)\n", - " \n", - " return abs(metric)" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "We can then evaluate the model and see its local DER:" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "Local DER (pretrained) = 18.3%\n" - ] - } - ], - "source": [ - "der_pretrained = test(model=pretrained, protocol=ami, subset=\"test\")\n", - "print(f\"Local DER (pretrained) = {der_pretrained * 100:.1f}%\")" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "Next, we prepare the model for fine-tuning, simply by overriding its `task` attribute..." - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "from copy import deepcopy\n", - "finetuned = deepcopy(pretrained)\n", - "finetuned.task = seg_task" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "... and we train it (for just one epoch)" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [ - { - "name": "stderr", - "output_type": "stream", - "text": [ - "GPU available: True, used: True\n", - "TPU available: False, using: 0 TPU cores\n", - "IPU available: False, using: 0 IPUs\n", - "LOCAL_RANK: 0 - CUDA_VISIBLE_DEVICES: [0]\n", - "\n", - " | Name | Type | Params | In sizes | Out sizes \n", - "-------------------------------------------------------------------------------------------------------------------\n", - "0 | sincnet | SincNet | 42.6 K | [32, 1, 80000] | [32, 60, 293] \n", - "1 | lstm | LSTM | 1.4 M | [32, 293, 60] | [[32, 293, 256], [[8, 32, 128], [8, 32, 128]]]\n", - "2 | linear | ModuleList | 49.4 K | ? | ? \n", - "3 | classifier | Linear | 516 | [32, 293, 128] | [32, 293, 4] \n", - "4 | activation | Sigmoid | 0 | [32, 293, 4] | [32, 293, 4] \n", - "5 | validation_metric | AUROC | 0 | ? | ? \n", - "-------------------------------------------------------------------------------------------------------------------\n", - "1.5 M Trainable params\n", - "0 Non-trainable params\n", - "1.5 M Total params\n", - "5.892 Total estimated model params size (MB)\n" - ] - }, - { - "data": { - "application/vnd.jupyter.widget-view+json": { - "model_id": "", - "version_major": 2, - "version_minor": 0 - }, - "text/plain": [ - "HBox(children=(HTML(value='Validation sanity check'), FloatProgress(value=1.0, bar_style='info', layout=Layout…" - ] - }, - "metadata": {}, - "output_type": "display_data" - }, - { - "data": { - "application/vnd.jupyter.widget-view+json": { - "model_id": "634877439d6744d88223cfd1313e5fc1", - "version_major": 2, - "version_minor": 0 - }, - "text/plain": [ - "HBox(children=(HTML(value='Training'), FloatProgress(value=1.0, bar_style='info', layout=Layout(flex='2'), max…" - ] - }, - "metadata": {}, - "output_type": "display_data" - }, - { - "data": { - "application/vnd.jupyter.widget-view+json": { - "model_id": "", - "version_major": 2, - "version_minor": 0 - }, - "text/plain": [ - "HBox(children=(HTML(value='Validating'), FloatProgress(value=1.0, bar_style='info', layout=Layout(flex='2'), m…" - ] - }, - "metadata": {}, - "output_type": "display_data" - }, - { - "name": "stdout", - "output_type": "stream", - "text": [ - "\n" - ] - } - ], - "source": [ - "trainer = pl.Trainer(devices=1, accelerator=\"gpu\", max_epochs=1)\n", - "trainer.fit(finetuned)" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "We now evaluate the performance of the fine-tuned model..." - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "Local DER (finetuned) = 17.5%\n" - ] - } - ], - "source": [ - "der_finetuned = test(model=finetuned, protocol=ami, subset=\"test\")\n", - "print(f\"Local DER (finetuned) = {der_finetuned * 100:.1f}%\")" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "... to confirm that it actually improved its performance on the AMI test set.\n", - "\n", - "\n", - "## Transfer learning\n", - "\n", - "What if you are only interested in detecting overlapped speech regions? \n", - "\n", - "Looking at the output of the `pyannote/segmentation` model, it seems that it would be a good starting point for training such a dedicated model:" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [ - { - "data": { - "image/png": "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Wf/7gJervGLztfS6/WLla+3ljoD8qfl57NblYGstEej+VehaU26k93NB08v07Z037vBsst/L2K3XebapnWTpdj5nus6H/B2a7fryd6/NYrrV78l/v7at5dT9iT/B69ovGv+YzK9F5eCQO27LvwYYlzK3lJDTrW++UBCCIbxArvWK64Jxtu7DstavuYiTr4mDk0vQuI7/cBz/Ep3N7ftyf3M8m5vH7XahYNu/Zc/h2/Z928xvtjM9/8l0zecY5h52MrJ7FTzhM2/ePLtgwYJBrUNERERERERERLYabMJHNWhFREREREREREYYJXxEREREREREREYYJXxEREREREREREYYJXxEREREREREREYYJXxEREREREREREYYJXxEREREREREREYYJXxEREREREREREYYJXxEREREREREREYYY60d3AqM2Qx0AA1DEpHI8FSLyriMfCrnMhqonMtooHIuo4HKuYx0tUCptbZuoCsYdMIHwBizwFo7b9ArEhmmVMZlNFA5l9FA5VxGA5VzGQ1UzmWkG4oyriZdIiIiIiIiIiIjjBI+IiIiIiIiIiIjzFAlfH49ROsRGa5UxmU0UDmX0UDlXEYDlXMZDVTOZaQbdBkfkj58RERERERERERk+FCTLhERERERERGREWanCR9jzCRjzKPGmNeMMa8aYy7LTX9v7rlnjJm3zTJfNsa8aYxZaow5eVcFLzJU+lvOjTFTjTFxY8yLucd1hYtepG92UM5/YIxZYox52RhztzGmstsy2p9L0ehvGde+XIrRDsr5t3Nl/EVjzAPGmPG56cYY87PcvvxlY8yBhX0HIjs3gHJ+jDGmpdv+/OuFfQciO7e9ct7t9c8bY6wxpjb3vN/785026TLG1AP11trnjTFlwELgTMACHnA98L/W2gW5+fcGbgEOAcYDDwF7WGuz/Xv7IrvPAMr5VOBea+0+hYlYpP92UM4nAo9YazPGmKsBrLVXaH8uxWYAZXwq2pdLkdlBOV9jrW3NzfNZYG9r7cXGmFOBS4FTgfnANdba+YWJXqRvBlDOj8E/Vn9XgUIW6bftlXNr7WvGmEnAb4E9gYOstQ0D2Z/vtIaPtXa9tfb53HgbsBiYYK1dbK1d2ssi7wZutdYmrbXLgTfxTxZEhq0BlHORorODcv6AtTaTm+0Z/JNj0P5ciswAyrhI0dlBOW/tNlsp/kUr8Pflf7S+Z4DK3EmGyLA1gHIuUnS2V85zL/8E+CI9y3i/9+f96sMndyXsAOC/O5htArC62/M13YIWGfb6WM4BphljXjDGPG6MOWrXRyYydHZQzj8G/DM3rv25FK0+lnHQvlyK2Lbl3BjzXWPMauCDQFeTFu3Lpaj1sZwDHGaMeckY809jzJzdH6nIwHUv58aYdwNrrbUvbTNbv/fnfU74GGNiwJ3A5dtkVkVGjH6U8/XAZGvtAcDngD8bY8p3R4wig7W9cm6M+SqQAW4uVGwiQ6EfZVz7cilavZVza+1XrbWT8Mv4ZwoZn8hQ6Ec5fx6YYq3dD7gW+GsBwhUZkO7lHP845Sv0TGYOWJ8SPsaYYC6Am621d+1k9rXApG7PJ+amiQxr/SnnuSYuW3LjC4G3gD12fZQig7O9cm6M+SjwLuCDdmvnbtqfS9HpTxnXvlyKVR+OWW4Gzs6Na18uRak/5dxa22qtbc+N3wcEuzq6FRnOeinnM4BpwEvGmBX4++znjTHjGMD+vC936TLADcBia+2P+xDzPcB5xpiwMWYaMAt4tg/LiRRMf8u5MabOGOPmxqfjl/NluzZKkcHZXjk3xpyC30b4DGttZ7dFtD+XotLfMq59uRSjHZTzWd1mezewJDd+D/Dh3N1dDgVarLXrd1vAIgPQ33JujBmXWwZjzCH457lbdl/EIv3XWzm31i6y1o6x1k611k7Fb7Z1oLV2AwPYnwf6EMcRwIeARcaYF3PTvgKE8avL1QH/MMa8aK092Vr7qjHmduA1/OpIn9YdXaQI9KucA0cD3zLGpPHv4nWxtbZx94ct0i/bK+c/wy/rD+aOlZ6x1l6s/bkUoX6VcbQvl+K0vXL+cWPMbPyyvBK4OPfaffh3dHkT6AQu2K3RigxMf8v5OcAlxpgMEAfO61ZjWWS46rWc52qp9abf+/Od3pZdRERERERERESKS7/u0iUiIiIiIiIiIsOfEj4iIiIiIiIiIiOMEj4iIiIiIiIiIiOMEj4iIiIiIiIiIiOMEj4iIiIiIiIiIiOMEj4iIiJStIwxNcaYF3OPDcaYtbnxdmPMLwsdn4iIiEih6LbsIiIiMiIYY74JtFtrf1joWEREREQKTTV8REREZMQxxhxjjLk3N/5NY8wfjDFPGmNWGmPOMsZ83xizyBjzL2NMMDffQcaYx40xC40x9xtj6gv7LkREREQGTgkfERERGQ1mAMcBZwA3AY9aa/cF4sBpuaTPtcA51tqDgN8B3y1UsCIiIiKDFSh0ACIiIiK7wT+ttWljzCLABf6Vm74ImArMBvYBHjTGkJtnfQHiFBERERkSSviIiIjIaJAEsNZ6xpi03dqJoYd/PGSAV621hxUqQBEREZGhpCZdIiIiIrAUqDPGHAZgjAkaY+YUOCYRERGRAVPCR0REREY9a20KOAe42hjzEvAicHhBgxIREREZBN2WXURERERERERkhFENHxERERERERGREUYJHxERERERERGREUYJHxERERERERGREUYJHxERERERERGREUYJHxERERERERGREUYJHxERERERERGREUYJHxERERERERGREUYJHxERERERERGREeb/A0KZQ28YdpupAAAAAElFTkSuQmCC", - "text/plain": [ - "" - ] - }, - "execution_count": null, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "\n", - "Inference('pyannote/segmentation', use_auth_token=True, step=2.5)(test_file)" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [ - { - "data": { - "image/png": "iVBORw0KGgoAAAANSUhEUgAABH0AAACsCAYAAADmO9AtAAAAOXRFWHRTb2Z0d2FyZQBNYXRwbG90bGliIHZlcnNpb24zLjMuMywgaHR0cHM6Ly9tYXRwbG90bGliLm9yZy/Il7ecAAAACXBIWXMAAAsTAAALEwEAmpwYAAAQvklEQVR4nO3de5Ald1k38O8jiVeCqIkxLquLKQSDQiArF68RL6HEIpQikNL3BUypUfECoihWmY2IgkIoxLK8YYmKCgoqoiREBcTyzau7uMmaxGi4GdaAQCwDEjUhj3+cTjFZ9zJn5syeOb/5fKpObXef7t5npp/67cx3+9enujsAAAAAjOXjll0AAAAAAIsn9AEAAAAYkNAHAAAAYEBCHwAAAIABCX0AAAAABiT0AQAAABiQ0AcAAABgQEIfAAAAgAEJfQAAAAAGJPQBAAAAGNBQoU9VPaGquqoeNK3vmdZ/cs0+p1fVHVX189P6vqp69jHO99GqOrjmtaeqzq+q10/vP62q3n/EPudM7z21qv5pej11zTkvqqpDVXVtVV1RVadP28+tqqunc+yvqkds3Xfq5DvZ12bN33ltVd0wfc+fsOa9T6+qq6brc1VVfdq0/VOr6o+r6pqquq6qnr7mmBdW1d9Prycv/JsEAAAACzRU6JPkoiR/Nf15t3cmedya9W9Oct06z3d7d5+75vWuo+zzqiP2ub6qPj3JpUkemeQRSS6tqk+rqlOSvDTJV3X3Q5Jcm+QZ03l+Jsll3X1ukh+f1kdyUq9NVT00yYuSXNjdX5Dk8UleVFUPmXb5kSR/3t0PSPLn03qSfE+S67v7oUnOT/Liqvr4qnpckocnOTez6/rsqrrPOmsFAACAk26Y0Keq7p3ky5JcnOQpa976SJIbqmrvtP7kJK/e4nIuSHJVd9/a3f+W5Kokj01S0+tTqqqS3CfJv0zH9LSeJJ+6ZvvKW9K1eXaSn+rudybJ9OdPJ/mh6f0Lk7xiWn5FkidMy53ktOn63DvJrUnuTHJOkr/s7ju7+z8yC+weu6BaAQAAYOGGCX0y+yX+iu7+xyQfrKrz1rz3u0meUlW7k3w06w9UPmnN9KE/OMY+Tz5imtEnJdmV5OY1+7wnya7uviPJdyU5NNVwTpKXT/v8QJKfraqbM7tD5UfXWeMqWMa1eXCSA0ds2z9tT5Izu/uWafm9Sc6cln8+yRdMdRxK8v3dfVeSa5I8tqo+eZqS91VJdq+zVgAAADjpTtmKkx7etXtfZtObFuWyXYdv3neCfS7KbOpUMgsSLsrsF/gkuSLJ85K8L8mr5vh7b5+mWx3Pq7r7GWs3zG4S+d+q6tTMQp+HJXlHkpdlFu785LT9md39mqp6UmZh0NfMUeu6POrSK/dlwdfm6ssu2HeCfZZ1bdalu7uqelq9IMnBJI9JcnaSq6rqrd39xqr64iR/neT9Sf5fZiEVAAAAbEtD3OkzPUPnMUl+tareldkUnidlNpUq3f3fmd318YNJfv8Y59i95s6RSzZZ0uHc8y6Q+03bzp3qeXt3d2ZTmb5k2uepSV47Lf9eZs8CWnlLvDbXJznviG3n5WPPDHpfVZ01nf+sJP86bX96ktf2zE2ZPXfoQVOtz5+eH/S1U/3/uM5aAAAA4KTbkjt9luCJSX6zu7/z7g1V9ZbcM3h5cZK3dPetR7sTp7tvzhTKLMCVSX7q7k+ESvJ1md3R84lJzqmqM7r7/Um+NskN0z7/kuQrk7w5s5DknxZUy7It69q8KMnvVdVfdPe7qmpPkudO9STJ6zIL2l4w/flH0/Z/TvLVSd5aVWcmeWCSd1TVvZLct7s/OD0M+iFJ3jhnTQAAAHDSbEnoM03F2rcV5z6Gi5K88Ihtr8ma5+J093VZ/ydDzePJVfVla9a/u7v/uqqel+Rvp20/0d23JklVXZbkL6vqjiTvTvK0aZ9vT/LS6RO+/jPJd2xBrZmmYu3binMfw1KuTXcfrKrnJPnjaVrdHUl+uLsPTru8IMmrq+rizK7Dk6btz0vy61V1KLO7eZ7T3R+oqk/MLAhKktuSfGt337nImgEAAGCRajbLCAAAAICRDPFMHwAAAADuSegDAAAAMCChDwAAAMCAhD4AAAAAAxL6AAAAAAxoIR/Zfvrpp/eePXsWcSoAAAAAkhw4cOAD3X3GRo9fSOizZ8+e7N+/fxGnAgAAACBJVb17M8eb3gUAAAAwIKEPAAAAwICEPgAAAAADEvoAAAAADEjoAwAAADAgoQ8AAADAgIQ+AAAAAAMS+gAAAAAMSOgDAAAAMCChDwAAAMCAhD4AAAAAAxL6AAAAAAxI6AMAAAAwIKEPAAAAwICEPgAAAAADEvoAAAAADEjoAwAAADAgoQ8AAADAgIQ+AAAAAAMS+gAAAAAMSOgDAAAAMCChDwAAAMCAhD4AAAAAAxL6AAAAAAxI6AMAAAAwIKEPAAAAwICEPgAAAAADEvoAAAAADEjoAwAAADCghYQ+H33f+xZxGoCluO3Fly+7hA1Z1bpHtZXX41fedNOWnZtx6BOA7cfYvFi+n/NbSOhzl9AHWGEfuvwlyy5hQ1a17lFt5fV4+ZvfvmXnZhz6BGD7MTYvlu/n/EzvAgAAABiQ0AcAAABgQKcs6kSHd+1e1KkAWCdj787xqEuvXHYJAMAG+DecZXKnDwAAAMCAhD4AAAAAA1rY9K5dh29e1KkATqpVniJl7N0+trqPrr7sgi09P6vP9AGA7cm/4Yvj37r5udMHAAAAYEBCHwAAAIABCX0AAAAABrSQ0OfjzjxzEacBWIrTnvXMZZewIata96i28npcfP7ZW3ZuxqFPALYfY/Ni+X7Or7p70yfZu3dv79+/fwHlAAAAAJAkVXWgu/du9HjTuwAAAAAGJPQBAAAAGJDQBwAAAGBAQh8AAACAAQl9AAAAAAYk9AEAAAAYkNAHAAAAYEBCHwAAAIABCX0AAAAABiT0AQAAABiQ0AcAAABgQEIfAAAAgAEJfQAAAAAGJPQBAAAAGJDQBwAAAGBAQh8AAACAAQl9AAAAAAYk9AEAAAAYkNAHAAAAYEBCHwAAAIABCX0AAAAABiT0AQAAABiQ0AcAAABgQEIfABbqV95007JLOKrtWhfc9uLLl13Cpqx6/QAwMqEPAAv18je/fdklHNV2rQs+dPlLll3Cpqx6/QAwMqEPAAAAwICEPgAAAAADEvoAAAAADOiUZRcAwHgedemVyy4BVsrhXbuXXQIAMCB3+gAAAAAMSOgDAAAAMCDTuwBYuKsvu2DZJfwvppyxne06fPOyS9gwU9MAYPtypw8AAADAgIQ+AAAAAAMS+gCwUBeff/aySziq7VoXnPasZy67hE1Z9foBYGTV3Zs+yd69e3v//v0LKAcAAACAJKmqA929d6PHu9MHAAAAYEBCHwAAAIABCX0AAAAABiT0AQAAABiQ0AcAAABgQEIfAAAAgAEJfQAAAAAGJPQBAAAAGJDQBwAAAGBAQh8AAACAAQl9AAAAAAYk9AEAAAAYkNAHAAAAYEBCHwAAAIABCX0AAAAABiT0AQAAABiQ0AcAAABgQEIfAAAAgAEJfQAAAAAGJPQBAAAAGJDQBwAAAGBAQh8AAACAAQl9AAAAAAYk9AEAAAAYkNAHAAAAYEBCHwAAAIABCX0AAAAABiT0AQAAABiQ0AcAAABgQNXdmz9J1YeS3Lj5cmBbOz3JB5ZdBGwxfc5OoM/ZCfQ5O4E+Zyd4YHefttGDT1lQETd2994FnQu2parar88ZnT5nJ9Dn7AT6nJ1An7MTVNX+zRxvehcAAADAgIQ+AAAAAANaVOjzyws6D2xn+pydQJ+zE+hzdgJ9zk6gz9kJNtXnC3mQMwAAAADbi+ldAAAAAAM6YehTVbur6k1VdX1VXVdV3z9t/+Zp/a6q2nvEMT9aVTdV1Y1VdcFWFQ+LMm+fV9Weqrq9qg5Or19cXvWwPsfp85+tqn+oqmur6g+q6r5rjjGes1Lm7XPjOavoOH3+vKnHD1bVG6vqs6ftVVU/N43n11bVw5f7FcCJbaDPz6+qf18znv/4cr8COLFj9fma93+wqrqqTp/W5x7PTzi9q6rOSnJWd7+tqk5LciDJE5J0kruS/FKSZ3f3/mn/c5L8TpJHJPnsJH+W5PO7+6Pzfflw8mygz/ckeX13f+FyKob5HafP75fkL7r7zqp6YZJ093OM56yiDfT5nhjPWTHH6fP3dPdt0z7fl+Sc7r6kqr4+yfcm+fokj0zy0u5+5HKqh/XZQJ+fn9nP69+wpJJhbsfq8+6+vqp2J/nVJA9Kcl53f2Aj4/kJ7/Tp7lu6+23T8oeS3JBkV3ff0N03HuWQC5P8bnf/V3e/M8lNmf3CANvWBvocVs5x+vyN3X3ntNvVmf1ynBjPWUEb6HNYOcfp89vW7PYpmf3nVTIbz3+jZ65Oct/pFw3YtjbQ57ByjtXn09svSfLDuWePzz2ez/VMn+l/wx6W5P8fZ7ddSW5es/6eNUXDtrfOPk+S+1fV31XVW6rqy7e+Mlic4/T5tyV5w7RsPGelrbPPE+M5K+zIPq+q51fVzUm+Jcnd01uM56y0dfZ5kjy6qq6pqjdU1YNPfqWwcWv7vKouTHK4u685Yre5x/N1hz5Vde8kr0nyA0ekqzCMOfr8liSf090PS/KsJL9dVfc5GTXCZh2rz6vqx5LcmeSVy6oNFmWOPjees7KO1ufd/WPdvTuzHn/GMuuDRZijz9+W5HO7+6FJXpbkD5dQLmzI2j7P7OeU5+aegeaGrSv0qapTpwJe2d2vPcHuh5PsXrN+v2kbbGvz9Pk03eWD0/KBJG9P8vlbXyVszrH6vKqeluQbknxLf+xhb8ZzVtI8fW48Z1Wt4+eWVyb5pmnZeM5KmqfPu/u27v7wtPynSU69++G3sJ0dpc/PTnL/JNdU1bsyG7PfVlWflQ2M5+v59K5K8vIkN3T35euo+XVJnlJVn1BV90/ygCR/s47jYGnm7fOqOqOq7jUtf15mff6Ora0SNudYfV5Vj81svvDju/sjaw4xnrNy5u1z4zmr6Dh9/oA1u12Y5B+m5dcl+b/Tp748Ksm/d/ctJ61g2IB5+7yqPms6JlX1iMx+1/3gyasY5ne0Pu/uQ939md29p7v3ZDaF6+Hd/d5sYDw/ZR11fGmS/5PkUFUdnLY9N8knZHbb3BlJ/qSqDnb3Bd19XVW9Osn1md2W9D0+6YUVMFefJ/mKJD9RVXdk9ulel3T3rSe/bJjLsfr85zLr9aumn5Wu7u5LjOesqLn6PMZzVtOx+vziqnpgZr387iSXTO/9aWaf9HJTko8kefpJrRY2Zt4+f2KS76qqO5PcnuQpa+5ehu3qqH0+3a12NHOP5yf8yHYAAAAAVs9cn94FAAAAwGoQ+gAAAAAMSOgDAAAAMCChDwAAAMCAhD4AAAAAAxL6AAArq6o+o6oOTq/3VtXhafnDVfULy64PAGCZfGQ7ADCEqtqX5MPd/aJl1wIAsB240wcAGE5VnV9Vr5+W91XVK6rqrVX17qr6xqr6mao6VFVXVNWp037nVdVbqupAVV1ZVWct96sAANgcoQ8AsBOcneQxSR6f5LeSvKm7vyjJ7UkeNwU/L0vyxO4+L8mvJXn+sooFAFiEU5ZdAADASfCG7r6jqg4luVeSK6bth5LsSfLAJF+Y5KqqyrTPLUuoEwBgYYQ+AMBO8F9J0t13VdUd/bGHGt6V2c9DleS67n70sgoEAFg007sAAJIbk5xRVY9Okqo6taoevOSaAAA2RegDAOx43f3fSZ6Y5IVVdU2Sg0m+ZKlFAQBsko9sBwAAABiQO30AAAAABiT0AQAAABiQ0AcAAABgQEIfAAAAgAEJfQAAAAAGJPQBAAAAGJDQBwAAAGBAQh8AAACAAf0PoCynY/nhXP8AAAAASUVORK5CYII=", - "text/plain": [ - "" - ] - }, - "execution_count": null, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "test_file[\"annotation\"]" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "Let's update the model so that it specifically addresses overlapped speech detection. \n", - "This is achieved very simply by updating the `task` attribute..." - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "from pyannote.audio.tasks import OverlappedSpeechDetection\n", - "osd_task = OverlappedSpeechDetection(ami, duration=2.0)\n", - "\n", - "osd_model = Model.from_pretrained(\"pyannote/segmentation\", use_auth_token=True)\n", - "osd_model.task = osd_task" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "... optionally freeezing a bunch of layers..." - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": [ - "['sincnet',\n", - " 'sincnet.wav_norm1d',\n", - " 'sincnet.conv1d',\n", - " 'sincnet.conv1d.0',\n", - " 'sincnet.conv1d.0.filterbank',\n", - " 'sincnet.conv1d.1',\n", - " 'sincnet.conv1d.2',\n", - " 'sincnet.pool1d',\n", - " 'sincnet.pool1d.0',\n", - " 'sincnet.pool1d.1',\n", - " 'sincnet.pool1d.2',\n", - " 'sincnet.norm1d',\n", - " 'sincnet.norm1d.0',\n", - " 'sincnet.norm1d.1',\n", - " 'sincnet.norm1d.2',\n", - " 'lstm']" - ] - }, - "execution_count": null, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "osd_model.freeze_up_to('lstm')" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "... and training it:" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [ - { - "name": "stderr", - "output_type": "stream", - "text": [ - "GPU available: True, used: True\n", - "TPU available: False, using: 0 TPU cores\n", - "IPU available: False, using: 0 IPUs\n", - "LOCAL_RANK: 0 - CUDA_VISIBLE_DEVICES: [0]\n", - "\n", - " | Name | Type | Params | In sizes | Out sizes \n", - "-------------------------------------------------------------------------------------------------------------------\n", - "0 | sincnet | SincNet | 42.6 K | [32, 1, 32000] | [32, 60, 115] \n", - "1 | lstm | LSTM | 1.4 M | [32, 115, 60] | [[32, 115, 256], [[8, 32, 128], [8, 32, 128]]]\n", - "2 | linear | ModuleList | 49.4 K | ? | ? \n", - "3 | classifier | Linear | 129 | [32, 115, 128] | [32, 115, 1] \n", - "4 | activation | Sigmoid | 0 | [32, 115, 1] | [32, 115, 1] \n", - "5 | validation_metric | AUROC | 0 | ? | ? \n", - "-------------------------------------------------------------------------------------------------------------------\n", - "49.5 K Trainable params\n", - "1.4 M Non-trainable params\n", - "1.5 M Total params\n", - "5.890 Total estimated model params size (MB)\n" - ] - }, - { - "data": { - "application/vnd.jupyter.widget-view+json": { - "model_id": "", - "version_major": 2, - "version_minor": 0 - }, - "text/plain": [ - "HBox(children=(HTML(value='Validation sanity check'), FloatProgress(value=1.0, bar_style='info', layout=Layout…" - ] - }, - "metadata": {}, - "output_type": "display_data" - }, - { - "data": { - "application/vnd.jupyter.widget-view+json": { - "model_id": "17ca908b800f4d34841bc2c7d5ccdff3", - "version_major": 2, - "version_minor": 0 - }, - "text/plain": [ - "HBox(children=(HTML(value='Training'), FloatProgress(value=1.0, bar_style='info', layout=Layout(flex='2'), max…" - ] - }, - "metadata": {}, - "output_type": "display_data" - }, - { - "data": { - "application/vnd.jupyter.widget-view+json": { - "model_id": "", - "version_major": 2, - "version_minor": 0 - }, - "text/plain": [ - "HBox(children=(HTML(value='Validating'), FloatProgress(value=1.0, bar_style='info', layout=Layout(flex='2'), m…" - ] - }, - "metadata": {}, - "output_type": "display_data" - }, - { - "name": "stdout", - "output_type": "stream", - "text": [ - "\n" - ] - } - ], - "source": [ - "trainer = pl.Trainer(devices=1, accelerator=\"gpu\", max_epochs=1)\n", - "trainer.fit(osd_model)" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "Et voilà! A brand new overlapped speech detection model!" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [ - { - "data": { - "image/png": "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", - "text/plain": [ - "" - ] - }, - "execution_count": null, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "from pyannote.audio.utils.signal import binarize\n", - "binarize(Inference(osd_model)(test_file))" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [ - { - "data": { - "image/png": "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", - "text/plain": [ - "" - ] - }, - "execution_count": null, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "test_file[\"annotation\"]" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "## Going further\n", - "\n", - "This tutorial only scratched the surface of the training API.\n", - "\n", - "Every task supports an `augmentation` parameter for training with data augmentation via [`torch-audiomentations`](https://github.com/asteroid-team/torch-audiomentations) library:\n", - "\n", - "```python\n", - "from torch_audiomentations import AddBackgroundNoise\n", - "augmentation = AddBackgroundNoise(\"/path/to/background/noise/directory\")\n", - "vad_task = VoiceActivityDetection(ami, augmentation=augmentation)\n", - "```\n", - "\n", - "We also benefit from all the nice things [`pytorch-lightning`](ttps://pytorch-lightning.readthedocs.io) has to offer (like multi-gpu training, for instance).\n", - "\n", - "```python\n", - "trainer = Trainer(devices=4, accelerator=\"gpu\", strategy='ddp')\n", - "trainer.fit(model)\n", - "```\n", - "\n", - "Default optimizer (`Adam` with default parameters) is automatically set up for you. \n", - "Customizing optimizer (and scheduler) requires overriding [`model.configure_optimizers`](https://pytorch-lightning.readthedocs.io/en/stable/api/pytorch_lightning.core.lightning.html#pytorch_lightning.core.lightning.LightningModule.configure_optimizers) method:\n", - "\n", - "```python\n", - "from types import MethodType\n", - "from torch.optim import SGD\n", - "from torch.optim.lr_scheduler import ExponentialLR\n", - "def configure_optimizers(self):\n", - " return {\"optimizer\": SGD(self.parameters()),\n", - " \"lr_scheduler\": ExponentialLR(optimizer, 0.9)}\n", - "model.configure_optimizers = MethodType(configure_optimizers, model)\n", - "trainer.fit(model)\n", - "```" - ] - } - ], - "metadata": { - "kernelspec": { - "display_name": "Python 3 (ipykernel)", - "language": "python", - "name": "python3" - } - }, - "nbformat": 4, - "nbformat_minor": 4 -} +{"cells":[{"cell_type":"markdown","metadata":{},"source":["\"Open"]},{"cell_type":"markdown","metadata":{},"source":["\n","# Training, fine-tuning, and transfer learning with pyannote.audio\n","\n","In this tutorial, you will learn how to use pyannote.audio to\n","\n","- train a voice activity detection model from scratch,\n","- fine-tune a pretrained speaker segmentation model,\n","- perform transfer learning (from speaker segmentation to overlapped speech detection)\n"]},{"cell_type":"markdown","metadata":{},"source":["## Tutorial setup"]},{"cell_type":"markdown","metadata":{"id":"72ECjKLknm8D"},"source":["### `Google Colab` setup"]},{"cell_type":"markdown","metadata":{"id":"mBBNyENbofJ4"},"source":["If you are running this tutorial on `Colab`, execute the following commands in order to setup `Colab` environment. These commands will install `pyannote.audio` and download a mini version of the `AMI` corpus."]},{"cell_type":"code","execution_count":null,"metadata":{"colab":{"base_uri":"https://localhost:8080/"},"executionInfo":{"elapsed":68165,"status":"ok","timestamp":1704810976973,"user":{"displayName":"Clément PAGES","userId":"11757386314069785178"},"user_tz":-60},"id":"Luhkk8D4oiir","outputId":"7f43b6e3-8dba-40c1-a9e9-5b3ae4ddc891"},"outputs":[],"source":["!pip install -qq pyannote.audio==3.1.1\n","!pip install -qq ipython==7.34.0\n","!git clone https://github.com/pyannote/AMI-diarization-setup.git\n","%cd ./AMI-diarization-setup/pyannote/\n","!bash ./download_ami_mini.sh\n","%cd /content"]},{"cell_type":"markdown","metadata":{"id":"VWo84u4ypEMc"},"source":["⚠ Restart the runtime (Runtime > Restart session)."]},{"cell_type":"markdown","metadata":{"id":"zmnD8CUUnt1N"},"source":["### Non `Google Colab` setup"]},{"cell_type":"markdown","metadata":{"id":"HS7SxeZkoth1"},"source":["If you are not using `Colab`, this tutorial assumes that\n","* `pyannote.audio` has been installed\n","* the [AMI corpus](https://groups.inf.ed.ac.uk/ami/corpus/) has already been [setup for use with `pyannote`](https://github.com/pyannote/AMI-diarization-setup/tree/main/pyannote)\n"]},{"cell_type":"code","execution_count":1,"metadata":{"executionInfo":{"elapsed":810,"status":"ok","timestamp":1704811019354,"user":{"displayName":"Clément PAGES","userId":"11757386314069785178"},"user_tz":-60},"id":"67whHDb3pOIe"},"outputs":[],"source":["# preparing notebook for visualization purposes\n","# (only show outputs between t=180s and t=240s)\n","from pyannote.core import notebook, Segment\n","notebook.crop = Segment(210, 240)"]},{"cell_type":"markdown","metadata":{"id":"z4-LIYSEnj5i"},"source":["## Data preparation\n","\n","See [`pyannote.database` documentation](https://github.com/pyannote/pyannote-database#pyannote-database) to learn how to prepare your own dataset for training with `pyannote.audio`."]},{"cell_type":"code","execution_count":null,"metadata":{"id":"8vw0KmndnX8L"},"outputs":[],"source":["from pyannote.database import registry, FileFinder\n","\n","registry.load_database(\"AMI-diarization-setup/pyannote/database.yml\")\n","ami = registry.get_protocol('AMI.SpeakerDiarization.mini')"]},{"cell_type":"markdown","metadata":{"id":"69qydyg6nX8M"},"source":["## Training a voice activity detection model from scratch"]},{"cell_type":"markdown","metadata":{"id":"l0-I4_ApnX8N"},"source":["Voice activity detection (VAD) is the task of detecting speech regions in a given audio stream or recording.\n","\n","We initialize a VAD *task* that describes how the model will be trained:\n","\n","* `ami` indicates that we will use files available in `ami.train()`.\n","* `duration=2.` and `batch_size=128` indicates that the model will ingest batches of 128 two seconds long audio chunks."]},{"cell_type":"code","execution_count":null,"metadata":{"id":"lFDktlSDnX8O"},"outputs":[],"source":["from pyannote.audio.tasks import VoiceActivityDetection\n","vad_task = VoiceActivityDetection(ami, duration=2.0, batch_size=128)"]},{"cell_type":"markdown","metadata":{"id":"EZ0Kje3RnX8Q"},"source":["We initialize one *model* with the `PyanNet` architecture used [in that paper](https://arxiv.org/abs/2104.04045). \n","In particular, we increase the default stride of the initial `sincnet` feature extraction layer to `10`.\n","\n","The model is also provided with the task (`task=vad_task`) for which it is being trained:"]},{"cell_type":"code","execution_count":4,"metadata":{"executionInfo":{"elapsed":226,"status":"ok","timestamp":1704811118255,"user":{"displayName":"Clément PAGES","userId":"11757386314069785178"},"user_tz":-60},"id":"kSfY8Y3fnX8R"},"outputs":[],"source":["from pyannote.audio.models.segmentation import PyanNet\n","vad_model = PyanNet(task=vad_task, sincnet={'stride': 10})"]},{"cell_type":"markdown","metadata":{"id":"WCNd35YInX8T"},"source":["Now that everything is ready, let's train with `pytorch-ligthning`!"]},{"cell_type":"code","execution_count":5,"metadata":{"id":"ExlUZ6DonX8U"},"outputs":[{"name":"stderr","output_type":"stream","text":["GPU available: False, used: False\n","TPU available: False, using: 0 TPU cores\n","IPU available: False, using: 0 IPUs\n","HPU available: False, using: 0 HPUs\n","\n"," | Name | Type | Params | In sizes | Out sizes \n","---------------------------------------------------------------------------------------------------------------------\n","0 | sincnet | SincNet | 42.6 K | [1, 1, 32000] | [1, 60, 115] \n","1 | lstm | LSTM | 589 K | [1, 115, 60] | [[1, 115, 256], [[4, 1, 128], [4, 1, 128]]]\n","2 | linear | ModuleList | 49.4 K | ? | ? \n","3 | classifier | Linear | 129 | [1, 115, 128] | [1, 115, 1] \n","4 | activation | Sigmoid | 0 | [1, 115, 1] | [1, 115, 1] \n","5 | validation_metric | MetricCollection | 0 | ? | ? \n","---------------------------------------------------------------------------------------------------------------------\n","681 K Trainable params\n","0 Non-trainable params\n","681 K Total params\n","2.728 Total estimated model params size (MB)\n"]},{"data":{"application/vnd.jupyter.widget-view+json":{"model_id":"766125242dd74f4bbd958c0488de0aeb","version_major":2,"version_minor":0},"text/plain":["Sanity Checking: | | 0/? [00:00"]},"execution_count":7,"metadata":{},"output_type":"execute_result"}],"source":["from pyannote.audio import Inference\n","vad = Inference(vad_model)\n","\n","vad_probability = vad(test_file)\n","vad_probability"]},{"cell_type":"markdown","metadata":{"id":"vYf27Tg9nX8Z"},"source":["Perfect voice activity detection output should look like that:"]},{"cell_type":"code","execution_count":8,"metadata":{"id":"DRX0bew-nX8Z","outputId":"77b43b35-ba67-4189-c588-43396ee49366"},"outputs":[{"data":{"image/png":"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","text/plain":[", , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , ])>"]},"execution_count":8,"metadata":{},"output_type":"execute_result"}],"source":["expected_output = test_file[\"annotation\"].get_timeline().support()\n","expected_output"]},{"cell_type":"markdown","metadata":{"id":"dzNs5vrUnX8a"},"source":["## Fine-tuning a pretrained speaker segmentation model\n","\n","Speaker diarization is the task of partitioning a given audio stream of recording into according to the speaker identity.\n","\n","[`pyannote/segmentation`](https://huggingface.co/pyannote/segmentation-3.0) is a model that was pretrained to perform speaker diarization, but only locally, on 10s-long audio chunks.\n","\n","To load the speaker segmentation model,\n","\n","* accept the user conditions on [hf.co/pyannote/segmentation](https://hf.co/pyannote/segmentation-3.0).\n","* login using `notebook_login` below"]},{"cell_type":"code","execution_count":null,"metadata":{"colab":{"base_uri":"https://localhost:8080/","height":145,"referenced_widgets":["0c403a6fbba048a9a5388b71a0d83259","b906b2359fa84291b3b78bcced4f3028","8f7afdee0292401181bd477a89ee3069","05b307b893b84133a376088787ababac","c258b47039a243cabadd48de545542f2","15ab3c58a6014beb9c7ba5e3f5bc0b77","df65aff406cc4288806b278cf83fb7df","31f30fd568f84363b8dea2d40f54885c","f383e9d323c64c64b528266858d6595c","772e6eb169d84fcb808957fd886a59d1","dcf595ee01a248f895635ad054c8ce28","385eecea5fca4494be7a0e2dc34110ca","c742508bbe1e4f0f9ad385896afea5eb","e7aa7e431546419792ff998e10c4bbe9","0e04e5e88aae4f14838356c422ba7ed5","20ba5327eef34c7fa20f9f247b9042b1","cc9cc24a3aea416a99897cf0c617f225","98b09e7bb5d14a9d8c85e52f54c9c6cf","50ed1cf2997e4929853964103bb7552c","4bf2285d01ca4f6c86a117f73972c7e7","d1063e27f20648ff9a43fede902a08a4","3b133fae87364dcc89a34ed147995807","e50f15a31e4543219ed038b88132d905","6b641f7304e943d7b53466fc5aa376a2","8865c7d7d01040329de63b6a13e0fdff","3e816698f9f54bc28712b7e0a1f1dba5","bd36d10136344d4b9965557a8783c5f1","d1f2777676bf4237947a0e42ff7da6de","245a4232482547579a72d10243664849","d072771073ed479b8e16cd9e5b9262c7","bf24ab0141ce423393972b66c6d09f94","bd2757c3b84f4ec283b083d64ea52d7a"]},"executionInfo":{"elapsed":362,"status":"ok","timestamp":1704811300494,"user":{"displayName":"Clément PAGES","userId":"11757386314069785178"},"user_tz":-60},"id":"peG_1xclnX8b","outputId":"3befc3a8-d54c-4a4b-9b40-2ce1229eeaa5"},"outputs":[],"source":["from huggingface_hub import notebook_login\n","notebook_login()"]},{"cell_type":"code","execution_count":10,"metadata":{"colab":{"base_uri":"https://localhost:8080/","height":81,"referenced_widgets":["84262babb03c4f7dab14b35637e29c31","35f0b383bafc4425a27f36bc95874430","f3d067b1a56849c19c933fb3380386b6","5fb8f440470f4492a5a7a009760a0926","c8348fafe0de405da831284cb39af5cc","b3a67d2e0c14492788806bb221761174","2f70dbe63df14dd18224e2bcb35b6e38","0f59d4fccfc045b89337b4b4254de7c3","c3204d520d604179923e93e0a9bfd395","1cc4aeb271f4441d83c3227a0fef607e","dd4a788ac0cb44ce93b6c001449d5d45","bcccc0031f7245a394abc3aee4a6e1c2","69c5b722ba3746aa80d87b3ee9fea08e","ef96f5501bbb4a55b3aedac70d1261b5","2d26c7ece1fe40178ab85f3d14408532","693fc1fa7fd746ce8a089f3fd6683b51","fd5fe3ad4e43456c896ca45ff6a6f155","b92e36c0853f40738b51b8ef39f0377d","8336d24b72414718b82c3195897ee896","469ce1b8998a4d998d42fbea5f431781","e7045e323ec947b3b354ffc61365f4cd","b86e1bdb52414bfab9798b661e3e096d"]},"executionInfo":{"elapsed":3764,"status":"ok","timestamp":1704811326591,"user":{"displayName":"Clément PAGES","userId":"11757386314069785178"},"user_tz":-60},"id":"wO1fXdA9nX8c","outputId":"5933da6e-d984-4ab1-9041-62b3d9c5a909"},"outputs":[],"source":["from pyannote.audio import Model\n","pretrained = Model.from_pretrained(\"pyannote/segmentation-3.0\", use_auth_token=True)"]},{"cell_type":"markdown","metadata":{"id":"zm1-d-IsnX8d"},"source":["Let's visualize how it performs on our test file:"]},{"cell_type":"code","execution_count":11,"metadata":{"id":"beFpRrN-nX8d"},"outputs":[{"data":{"image/png":"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zem7AGZxrnng7rvvjle+8pVx5ZVXxq5du+LBD35wvOpVr4r77rtv3eN8/vOfj+c+97mxe/fueOADHxg/8AM/EMPhcN7fDjClquaCU9cDWZbF7/zO78z72wGmsJm9wcte9rJ4+MMfHrt27YqLL744nv/858cnPvGJdX/HmgDaq6p5wHoA2msz80Ahz/O45pprIsuy+MM//MN1/62K9cCWgh3vfOc749prr42/+Zu/iRtvvDFOnjwZV199dRw+fLj8O0eOHInnPOc58SM/8iNnfJwXvehF8bGPfSxuvPHG+NM//dP4y7/8y/hX/+pfbWngQDOqmgciIv7zf/7Pcdttt5X/e+UrX1n38IEKnGseOHjwYBw8eDB+5md+Jj760Y/GDTfcEG9961vje77ne8rHWFlZiec+97lx4sSJePe73x2/9mu/FjfccEO85jWvaerbAraoirmgcP31169bE7zgBS+Y83cDTGMze4MnPvGJcf3118fHP/7xeNvb3hZ5nsfVV18dKysrEWFNAG1XxTxQsB6AdtrMPFD4+Z//+ciy7LR/X9l6IJ/BnXfemUdE/s53vvO0/3bTTTflEZHfc8896/79zTffnEdE/r73va/8d295y1vyLMvyW2+9dZbhAA2YZh7I8zx/yEMekv/cz/1c/QMEane2eaDwu7/7u/n27dvzkydP5nme53/2Z3+WDwaD/Pbbby//zutf//p8aWkpP378eO1jBqo3zVyQ53keEfmb3/zmOYwQqNtm5oEPf/jDeUTkn/zkJ/M8tyaArplmHshz6wHokjPNAx/84Afzyy+/PL/ttttOe89XtR6YqWdHkYJ+4YUXbvpr3vOe98T5558fT3rSk8p/9w3f8A0xGAzive997yzDARowzTxQeN3rXhcXXXRRPP7xj4+f/umflqoOLbWZeeC+++6LpaWlWFxcjIjV9cCjH/3ouOSSS8q/843f+I2xvLwcH/vYx+odMFCLaeaCwrXXXhsPeMAD4slPfnK88Y1vjDzPax0rUI9zzQOHDx+O66+/Ph72sIfF/v37I8KaALpmmnmgYD0A3bDRPHDkyJH4zu/8zvjv//2/x6WXXnra11S1Hlg891/Z2Gg0ile/+tXx9Kc/PR71qEdt+utuv/32eOADH7h+EIuLceGFF8btt98+7XCABkw7D0REvOpVr4onPOEJceGFF8a73/3u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","text/plain":[""]},"execution_count":11,"metadata":{},"output_type":"execute_result"}],"source":["spk_probability = Inference(pretrained, step=2.5)(test_file)\n","spk_probability"]},{"cell_type":"markdown","metadata":{"id":"hrJ9pDbTnX8e"},"source":["A perfect output would look like that:"]},{"cell_type":"code","execution_count":12,"metadata":{"id":"bLcE98G4nX8f","outputId":"7bb6ed3d-8076-4ebf-fa89-95a8c5943d27"},"outputs":[{"data":{"image/png":"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fd7zk4oHVFwAreGWD0ceeeQh/9tLL700jjrqqNi4cWN8+MMfVg4OhRqnH3jooYdibm4uli9fHhER1157bZx22mmxbt269mt+4Rd+Iebn5+O73/3udBsMTNyT6QeGzjvvvDj66KPjZ37mZ+JTn/pUNE0z1bYC03OwvmD79u1x2WWXxYknnhgbNmyICDEB1ObJ9ANDYgKow/76gR07dsSb3vSm+OM//uM47rjj9vk3k4oHlh/8S4A+WFhYiAsvvDBe/vKXxwte8IJD+rcXXHBBvPjFL44jjzwyvva1r8V73vOeuPvuu+MP//APp9RaYBrG6Qfuu++++IM/+IN461vf2v7d1q1bFwUkEdH+99atW6fXYGDinmw/ELF728hXvvKVcfjhh8eXv/zl+K3f+q14+OGH44ILLuii6cAELdUXfOITn4jf/d3fje3bt8cpp5wSV111VRx22GERISaAmjzZfiBCTAC1OFA/8I53vCPOOOOMeN3rXrfffzepeEDiAoiI3ashbrrppvjqV796yP/2ne98Z/vnF77whXHYYYfF2972tvjABz4QK1eunGQzgSk6WD8wPz8fZ599dpx66qnx/ve/v9vGAZ14Kv3A7/3e77V/3rhxY2zfvj0+/OEPm6SAAi3VF/zKr/xKvOpVr4q77747PvKRj8Qb3/jGuOaaa2LVqlUJWgpMy1PpB8QEUIf99QOf/exn4+qrr45vf/vbU7++raKAePvb3x6f+9znYvPmzbF+/fqn/P1OP/30ePzxx+P2229/6o0DOnGwfmDbtm3x6le/OmZnZ+PKK6+MFStWtP/vuOOOi3vuuWfR1w//e39lo0Cenko/sD+nn3563HXXXbFz585pNRmYgoP1BWvXro2TTz45fu7nfi7+9m//Nm6++ea48sorI0JMALV4Kv3A/ogJoDwH6geuvvrquO222+LpT396LF++vN069vWvf32ceeaZETG5eEDiAnqsaZp4+9vfHldeeWVcffXVceKJJ07k+15//fUxMzMTxx577ES+HzA94/QD8/PzsWnTpjjssMPis5/97D4rKl/2spfFd77znbj33nvbv7vqqqtibm4uTj311KnfA/DUTKIf2J/rr78+jjjiCNWXUIgnMzZomiaapmknI8UEULZJ9AP7IyaAchysH3j3u98dN954Y1x//fXtr4iIj370o3HZZZdFxOTiAVtFQY+dd9558ZnPfCb+4R/+IWZnZ9t95tauXRurV6+OiN17z23dujW+//3vR0TEd77znZidnY3jjz8+jjzyyLj22mvj61//erziFa+I2dnZuPbaa+Md73hH/Oqv/mocccQRye4NGM/B+oHhZOWOHTviL//yL2N+fj7m5+cjIuKYY46JZcuWxaZNm+LUU0+Nc889Nz70oQ/F1q1b433ve1+cd955BidQgEn0A//4j/8Y99xzT/zsz/5srFq1Kq666qq45JJL4nd+53dS3hpwCA7WF/zgBz+IK664IjZt2hTHHHNM3HXXXXHppZfG6tWr4zWveU1EhJgACjeJfkBMAGU7WD9w3HHH7bdq4vjjj2+THBOLBxqgtyJiv78uu+yy9msuvvjiJb/mm9/8ZnP66ac3a9eubVatWtU8//nPby655JLmkUceSXNTwCE5WD+wefPmA37ND3/4w/b73H777c1ZZ53VrF69ujn66KOb3/7t324ee+yxNDcFHJJJ9ANf+MIXmp/+6Z9u1qxZ0zztaU9rXvSiFzWf/OQnm127dqW7MeCQHKwv+NGPftScddZZzbHHHtusWLGiWb9+ffOmN72pufnmmxd9HzEBlGsS/YCYAMo2zlzh/v7NlVdeuejvJhEPDPZ8cwAAAAAAgOSccQEAAAAAAGRD4gIAAAAAAMiGxAUAAAAAAJANiQsAAAAAACAbEhcAAAAAAEA2JC4AAAAAAIBsSFwAAAAAAADZkLgAAAAW+bVf+7U455xzUjcDAADoqeWpGwAAAHRnMBgs+f8vvvji+NjHPhZN03TUIgAAgMUkLgAAoEfuvvvu9s9XXHFFXHTRRXHLLbe0f7dmzZpYs2ZNiqYBAABEhK2iAACgV4477rj219q1a2MwGCz6uzVr1uyzVdSZZ54Z559/flx44YVxxBFHxLp16+LP/uzPYvv27fHmN785Zmdn47nPfW584QtfWHStm266Kc4666xYs2ZNrFu3Ls4999y47777Or5jAACgNBIXAADAQX3605+Oo48+Ov7lX/4lzj///PjN3/zNeMMb3hBnnHFGfOtb34pNmzbFueeeGzt27IiIiAcffDBe+cpXxsaNG+O6666LL37xi3HPPffEG9/4xsR3AgAA5E7iAgAAOKgXvehF8b73vS9OPvnkeM973hOrVq2Ko48+Ot7ylrfEySefHBdddFHcf//9ceONN0ZExMc//vHYuHFjXHLJJfG85z0vNm7cGJ/61Kdi8+bNceuttya+GwAAIGfOuAAAAA7qhS98YfvnZcuWxVFHHRWnnXZa+3fr1q2LiIh77703IiJuuOGG2Lx5837Py7jtttvip37qp6bcYgAAoFQSFwAAwEGtWLFi0X8PBoNFfzcYDCIiYmFhISIiHn744Xjta18bH/zgB/f5Xs94xjOm2FIAAKB0EhcAAMDEvfjFL46/+7u/ixNOOCGWLzfsAAAAxueMCwAAYOLOO++8eOCBB+KXf/mX4xvf+Ebcdttt8aUvfSne/OY3x65du1I3DwAAyJjEBQAAMHHPfOYz45prroldu3bFpk2b4rTTTosLL7wwnv70p8fMjGEIAABwYIOmaZrUjQAAAAAAAIhQcQEAAAAAAGRE4gIAAAAAAMiGxAUAAAAAAJANiQsAAAAAACAbEhcAAAAAAEA2JC4AAAAAAIBsSFwAAAAAAADZkLgAAAAAAACyIXEBAAAAAABkQ+ICAAAAAADIhsQFAAAAAACQDYkLAAAAAAAgG/8fDti5GILmY0wAAAAASUVORK5CYII=","text/plain":[""]},"execution_count":12,"metadata":{},"output_type":"execute_result"}],"source":["test_file[\"annotation\"].discretize(notebook.crop, resolution=0.010)"]},{"cell_type":"markdown","metadata":{"id":"9DY3NIY5nX8f"},"source":["We are going to fine-tune this pretrained model on the AMI dataset:"]},{"cell_type":"code","execution_count":13,"metadata":{"executionInfo":{"elapsed":1183,"status":"ok","timestamp":1704811457994,"user":{"displayName":"Clément PAGES","userId":"11757386314069785178"},"user_tz":-60},"id":"GJ2BWqqknX8g"},"outputs":[],"source":["from pyannote.audio.tasks import SpeakerDiarization\n","seg_task = SpeakerDiarization(ami, duration=10.0, max_speakers_per_chunk=3, max_speakers_per_frame=2)"]},{"cell_type":"markdown","metadata":{"id":"y6e77EJ-nX8g"},"source":["To check that fine-tuning was actually helpful, we need to evaluate the performance of the pretrained model, and compute the average local diarization error rate on a 10s window sliding over the whole test set. To do so, we need to create a helper function:"]},{"cell_type":"code","execution_count":14,"metadata":{"id":"XxJs0DtCnX8h"},"outputs":[],"source":["def test(model, protocol, subset=\"test\"):\n"," from pyannote.audio.utils.signal import binarize\n"," from pyannote.audio.utils.metric import DiscreteDiarizationErrorRate\n"," from pyannote.audio.pipelines.utils import get_devices\n","\n"," (device,) = get_devices(needs=1)\n"," metric = DiscreteDiarizationErrorRate()\n"," files = list(getattr(protocol, subset)())\n","\n"," inference = Inference(model, device=device)\n","\n"," for file in files:\n"," reference = file[\"annotation\"]\n"," hypothesis = binarize(inference(file))\n"," uem = file[\"annotated\"]\n"," _ = metric(reference, hypothesis, uem=uem)\n","\n"," return abs(metric)"]},{"cell_type":"markdown","metadata":{"id":"Nkdm0dR0nX8h"},"source":["We can then evaluate the model and see its local DER:"]},{"cell_type":"code","execution_count":15,"metadata":{"id":"LH0CGdmnnX8i","outputId":"b07ba927-6f23-403a-d70b-74cf8685df06"},"outputs":[{"name":"stdout","output_type":"stream","text":["Local DER (pretrained) = 19.7%\n"]}],"source":["der_pretrained = test(model=pretrained, protocol=ami, subset=\"test\")\n","print(f\"Local DER (pretrained) = {der_pretrained * 100:.1f}%\")"]},{"cell_type":"markdown","metadata":{"id":"qUCdup8QnX8i"},"source":["Next, we prepare the model for fine-tuning, simply by overriding its `task` attribute..."]},{"cell_type":"code","execution_count":16,"metadata":{"id":"5i5Bv-7enX8j"},"outputs":[],"source":["from copy import deepcopy\n","finetuned = deepcopy(pretrained)\n","finetuned.task = seg_task"]},{"cell_type":"markdown","metadata":{"id":"nDPEYDZKnX8j"},"source":["... and we train it (for just one epoch)"]},{"cell_type":"code","execution_count":17,"metadata":{"colab":{"referenced_widgets":["","634877439d6744d88223cfd1313e5fc1"]},"id":"AIUsJ3MqnX8k","outputId":"6078a5dd-5cb2-4780-db4e-e3516d1cce8e"},"outputs":[{"name":"stderr","output_type":"stream","text":["GPU available: False, used: False\n","TPU available: False, using: 0 TPU cores\n","IPU available: False, using: 0 IPUs\n","HPU available: False, using: 0 HPUs\n"]},{"name":"stderr","output_type":"stream","text":["\n"," | Name | Type | Params | In sizes | Out sizes \n","----------------------------------------------------------------------------------------------------------------------\n","0 | sincnet | SincNet | 42.6 K | [1, 1, 160000] | [1, 60, 589] \n","1 | lstm | LSTM | 1.4 M | [1, 589, 60] | [[1, 589, 256], [[8, 1, 128], [8, 1, 128]]]\n","2 | linear | ModuleList | 49.4 K | ? | ? \n","3 | classifier | Linear | 903 | [1, 589, 128] | [1, 589, 7] \n","4 | activation | LogSoftmax | 0 | [1, 589, 7] | [1, 589, 7] \n","5 | powerset | Powerset | 0 | ? | ? \n","6 | validation_metric | MetricCollection | 0 | ? | ? \n","----------------------------------------------------------------------------------------------------------------------\n","1.5 M Trainable params\n","0 Non-trainable params\n","1.5 M Total params\n","5.893 Total estimated model params size (MB)\n"]},{"data":{"application/vnd.jupyter.widget-view+json":{"model_id":"fc1c93f0b95649b1ae7a7135c9c04d62","version_major":2,"version_minor":0},"text/plain":["Sanity Checking: | | 0/? [00:00"]},"execution_count":19,"metadata":{},"output_type":"execute_result"}],"source":["Inference('pyannote/segmentation-3.0', use_auth_token=True, step=2.5)(test_file)"]},{"cell_type":"code","execution_count":20,"metadata":{"id":"DvpRY7H1nX82","outputId":"ce284d08-e0f1-4a58-da1e-0b7c62fa2f31"},"outputs":[{"data":{"image/png":"iVBORw0KGgoAAAANSUhEUgAABjwAAADyCAYAAAD5q2z1AAAAOXRFWHRTb2Z0d2FyZQBNYXRwbG90bGliIHZlcnNpb24zLjguMCwgaHR0cHM6Ly9tYXRwbG90bGliLm9yZy81sbWrAAAACXBIWXMAAA9hAAAPYQGoP6dpAAAfgElEQVR4nO3de5RV5X038O8M14nMDHdGFNSoUVxRg5cqJmYpRUAxS1oTl8ZqJC7NBbFiLo2uVPuaxlhNtbWJsc0yaGo1pmm9tkCoEK1KCBLxFm8YXV5gIIAwgIow7PcPX+ftFJQB5nDY4+ez1llr5pzn7P17zp75zTPznbN3TVEURQAAAAAAAEqsttoFAAAAAAAA7CiBBwAAAAAAUHoCDwAAAAAAoPQEHgAAAAAAQOkJPAAAAAAAgNITeAAAAAAAAKUn8AAAAAAAAEpP4AEAAAAAAJSewAMAAAAAACg9gQcAAAAAAFB6Ag8AAAAAAKD0BB4AAAAAAEDpCTwAAAAAAIDSE3gAAAAAAAClJ/AAAAAAAABKT+ABAAAAAACUnsBjC84555zU1NRsdlu0aFHOOeecTJw4catjx48f3zbm7bffzuTJkzNgwID06dMnp556apYuXdpun/Pnz88f//Efp2/fvunXr1/GjRuXxx9/vN2YmTNn5uijj059fX0GDRqUU089NS+//HIlX4pS25bjmCSvvvpqvvjFL2bo0KHp2bNn9tprr/z5n/95VqxY0W5cURS57LLLsvvuu6euri5jxozJCy+80G7M888/n1NOOSUDBw5MQ0NDPvWpT2XOnDntxtx///055phjUl9fn6ampvzFX/xFNm7cWJHXAgAAAACgq6tK4NG6YsVOvW2P8ePHZ8mSJe1u++yzT4fH3n777W2PT506Nffee2/+9V//NQ888EAWL16cP/3TP217fO3atRk/fnyGDx+eefPm5aGHHkp9fX3GjRuXDRs2JEleeumlnHLKKRk9enQWLlyYmTNnZvny5e22s7O9se6dnXbbXh09jr///e9zxBFH5IUXXsjtt9+eRYsW5cYbb8z999+fUaNGZeXKlW1jr7766lx//fW58cYbM2/evOy2224ZN25c3n777bYxJ598cjZu3JjZs2dnwYIFOfTQQ3PyySenubk5SfL444/npJNOyvjx4/PYY4/ljjvuyD333JNvfetb2z1XAAAAAIAPs5qiKIqdvdPX9xi2U/e3x+uvbtP4c845J6tWrcpdd9211cc+aGySrF69OoMGDcptt92Wz372s0mSZ599NiNGjMjcuXNz9NFH59FHH82RRx6ZV155JcOGvfvaPPnkkznkkEPywgsvZL/99ssvfvGLnHHGGVm/fn1qa9/Nqe69996ccsopWb9+fXr06LFNc+wMR18+c6ft69f/Z9w2P2dbjuOJJ56Yp556Ks8//3zq6uraxjU3N2fffffN2WefnR/96EcpiiJDhw7N1772tXz9619P8u4xHjJkSG6++eacfvrpWb58eQYNGpQHH3wwxx57bJJkzZo1aWhoyKxZszJmzJhceumlmTVrVubPn9+2r3vvvTennXZali1blvr6+m2eLwAAAADAh5lTWlXYggULsmHDhowZM6btvgMPPDDDhw/P3LlzkyQHHHBABgwYkJtuuinvvPNO3nrrrdx0000ZMWJE9t577yTJ4Ycfntra2kybNi2tra1ZvXp1/vmf/zljxoypStjRlaxcuTIzZ87MV7/61XZhR5I0NTXlzDPPzB133JGiKPLSSy+lubm53fFsbGzMUUcd1XY8BwwYkAMOOCA//elPs27dumzcuDH/+I//mMGDB+fwww9Pkqxfvz69e/dut6+6urq8/fbbWbBgQYVnDAAAAADQ9Qg83sd9992XPn36tN0+97nPdXhsnz59cuWVVyZ59x0CPXv2TN++fds9Z8iQIW2nN6qvr8+vfvWr3Hrrramrq0ufPn0yY8aMTJ8+Pd27d0+S7LPPPvnlL3+ZSy+9NL169Urfvn3z2muv5ec//3llXoAuoiPH8YUXXkhRFBkxYsQWtzFixIi88cYb+cMf/tB2zIYMGdJuzP88njU1Nfmv//qvPPbYY6mvr0/v3r1z7bXXZsaMGenXr1+SZNy4cXnkkUdy++23p7W1Na+//nquuOKKJMmSJUs6bf4AAAAAAB8WAo/3cfzxx2fhwoVtt+uvv77DYxcuXJgvf/nLHd7XW2+9lXPPPTef/OQn8+tf/zoPP/xwPv7xj2fChAl56623krwbnJx33nn5whe+kPnz5+eBBx5Iz54989nPfjZVOCtZaWzLceys17EoikyePDmDBw/Of//3f+c3v/lNJk6cmM985jNtYcbYsWNzzTXX5Mtf/nJ69eqVj33sYznppJOSpO2UZQAAAAAAdFz3auy06YmF1djtNtltt92y33777fDYpqamvPPOO1m1alW7d3ksXbo0TU1NSZLbbrstL7/8cubOndv2x+7bbrst/fr1y913353TTz89P/zhD9PY2Jirr766bRu33nprhg0blnnz5uXoo4/ezpluv+nfPH6n73NbdeQ47rfffqmpqckzzzyTP/mTP9ns8WeeeSb9+vXLoEGDsnbt2iTvHr/dd9+9bczSpUvziU98Ikkye/bs3HfffXnjjTfS0NCQJLnhhhsya9as3HLLLW0XJr/44oszderULFmyJP369cvLL7+cSy65JB/96Ec7Y+oAAAAAAB8qVQk8ug0YUI3dVsXhhx+eHj165P7778+pp56aJHnuuefyyiuvZNSoUUmSN998M7W1tampqWl73nufb9q0qd2Y/6lbt25J0jZmZ+u3W8+q7LezDRgwICeccEJuuOGGTJ06dbOLlv/Lv/xLzj777NTU1GSfffZJU1NT7r///raAo6WlJfPmzctXvvKVJO8eq2Tzd2rU1tZudqxqamoydOjQJMntt9+eYcOG5bDDDqvUVAEAAAAAuiznzukE69evT3Nzc7vb8uXLk7x7Qetzzz03F198cebMmZMFCxZk0qRJGTVqVNu7Mk444YS88cYbmTx5cp555pk8/fTTmTRpUrp3757jj3/3XRQTJkzI/Pnzc8UVV+SFF17Ib3/720yaNCl77bVXRo4cWbW5dxU/+MEPsn79+owbNy4PPvhgXn311cyYMSMnnHBC9thjj3z3u99N8m5AcdFFF+Wv//qvc8899+TJJ5/M2WefnaFDh2bixIlJklGjRqVfv375whe+kMcffzzPP/98vvGNb+Sll17KhAkT2vZ5zTXX5Mknn8zTTz+d73znO7nqqqty/fXXtwVZAAAAAAB0nMCjE8yYMSO77757u9unPvWptsevu+66nHzyyTn11FPz6U9/Ok1NTfn3f//3tscPPPDA3HvvvXniiScyatSoHHvssVm8eHHbdpNk9OjRue2223LXXXdl5MiRGT9+fHr16pUZM2a0e0cC22f//ffPo48+mo9+9KM57bTTsu++++b888/P8ccfn7lz56Z///5tY7/5zW9mypQpOf/883PkkUdm7dq1mTFjRnr37p0kGThwYGbMmJG1a9dm9OjROeKII/LQQw/l7rvvzqGHHtq2nenTp+fYY4/N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qafy0EMPbe8mgJLbkT5w8cUXt318yCGHpGfPnvnSl76U733ve+nVq1dnlglU2NZ6QUtLSyZMmJCDDjoof/VXf7VziwN2ih3pA3/5l3/Z9vHIkSOzbt26XHPNNf64ASXzQX3gzDPPzAknnJAlS5bk+9//fk477bQ8/PDD6d27dxUqBSppR3qBNQF0DVvqA/fcc09mz56dxx57rOL7365TWl1wwQW57777MmfOnOy5557b9NympqYsW7as3X0bN27MypUrt/hWFmDXtCN9YEuOOuqobNy4MS+//PKOFwfsNFvrBWvWrMn48eNTX1+fO++8Mz169Gh7rKmpKUuXLm03/r3PrQmgPHakD2zJUUcdlddeey3r16+vVMlAJ9taH2hsbMz++++fT3/60/nFL36RZ599NnfeeWcS6wHoSnakF2yJNQGUz/v1gdmzZ+fFF19M3759071797ZT3J566qk57rjjknTemmCbAo+iKHLBBRfkzjvvzOzZs7PPPvtsy9OTJKNGjcqqVauyYMGCtvtmz56dTZs25aijjtrm7QE7V2f0gS1ZuHBhamtrNzvlHbBr6kgvaGlpydixY9OzZ8/cc889m/0X56hRo/Lkk0+2+0eIWbNmpaGhIQcddFDF5wDsmM7oA1uycOHC9OvXzzs+oQS253eDoihSFEXbHzCtB6D8OqMXbIk1AZTH1vrAt771rTzxxBNZuHBh2y1JrrvuukybNi1J560JtumUVpMnT85tt92Wu+++O/X19W3nzmpsbExdXV2Sd8+n1dzcnEWLFiVJnnzyydTX12f48OHp379/RowYkfHjx+e8887LjTfemA0bNuSCCy7I6aefnqFDh25LOUAVdEYfmDt3bubNm5fjjz8+9fX1mTt3bqZOnZo/+7M/S79+/ao2N6DjttYL3vsj55tvvplbb701LS0taWlpSZIMGjQo3bp1y9ixY3PQQQflrLPOytVXX53m5uZ8+9vfzuTJk/1SAyXQGX3g3nvvzdKlS3P00Uend+/emTVrVq688sp8/etfr+bUgA7aWh/4/e9/nzvuuCNjx47NoEGD8tprr+Wqq65KXV1dTjrppCSxHoAuoDN6gTUBlNvW+kBTU9MW36UxfPjwtnCk09YExTZIssXbtGnT2sZcfvnlWx2zYsWK4owzzij69OlTNDQ0FJMmTSrWrFmzLaUAVdIZfWDBggXFUUcdVTQ2Nha9e/cuRowYUVx55ZXF22+/XZ1JAdtsa71gzpw57zvmpZdeatvOyy+/XJx44olFXV1dMXDgwOJrX/tasWHDhupMCtgmndEHpk+fXnziE58o+vTpU+y2227FoYceWtx4441Fa2tr9SYGdNjW+sDrr79enHjiicXgwYOLHj16FHvuuWfx+c9/vnj22Wfbbcd6AMqtM3qBNQGUW0f+Xril59x5553t7uuMNUHN/9s4AAAAAABAaW3XRcsBAAAAAAB2JQIPAAAAAACg9AQeAAAAAABA6Qk8AAAAAACA0hN4AAAAAAAApSfwAAAAAAAASk/gAQAAAAAAlJ7AAwAA2GHnnHNOJk6cWO0yAACAD7Hu1S4AAADYtdXU1Hzg45dffnn+/u//PkVR7KSKAAAANifwAAAAPtCSJUvaPr7jjjty2WWX5bnnnmu7r0+fPunTp081SgMAAGjjlFYAAMAHampqars1Njampqam3X19+vTZ7JRWxx13XKZMmZKLLroo/fr1y5AhQ/LjH/8469aty6RJk1JfX5/99tsv06dPb7evp556KieeeGL69OmTIUOG5Kyzzsry5ct38owBAIAyEngAAAAVccstt2TgwIH5zW9+kylTpuQrX/lKPve5z+WYY47Jb3/724wdOzZnnXVW3nzzzSTJqlWrMnr06IwcOTKPPvpoZsyYkaVLl+a0006r8kwAAIAyEHgAAAAVceihh+bb3/529t9//1xyySXp3bt3Bg4cmPPOOy/7779/LrvssqxYsSJPPPFEkuQHP/hBRo4cmSuvvDIHHnhgRo4cmZ/85CeZM2dOnn/++SrPBgAA2NW5hgcAAFARhxxySNvH3bp1y4ABA3LwwQe33TdkyJAkybJly5Ikjz/+eObMmbPF64G8+OKL+djHPlbhigEAgDITeAAAABXRo0ePdp/X1NS0u6+mpiZJsmnTpiTJ2rVr85nPfCZ/8zd/s9m2dt999wpWCgAAdAUCDwAAYJdw2GGH5d/+7d+y9957p3t3v6oAAADbxjU8AACAXcLkyZOzcuXKnHHGGZk/f35efPHFzJw5M5MmTUpra2u1ywMAAHZxAg8AAGCXMHTo0Dz88MNpbW3N2LFjc/DBB+eiiy5K3759U1vrVxcAAOCD1RRFUVS7CAAAAAAAgB3h36QAAAAAAIDSE3gAAAAAAAClJ/AAAAAAAABKT+ABAAAAAACUnsADAAAAAAAoPYEHAAAAAABQegIPAAAAAACg9AQeAAAAAABA6Qk8AAAAAACA0hN4AAAAAAAApSfwAAAAAAAASk/gAQAAAAAAlN7/Bcs45RiRI+F2AAAAAElFTkSuQmCC","text/plain":[""]},"execution_count":20,"metadata":{},"output_type":"execute_result"}],"source":["test_file[\"annotation\"]"]},{"cell_type":"markdown","metadata":{"id":"hjw4nIE7nX83"},"source":["Let's update the model so that it specifically addresses overlapped speech detection. \n","This is achieved very simply by updating the `task` attribute..."]},{"cell_type":"code","execution_count":21,"metadata":{"id":"xhmDk1qJnX83"},"outputs":[],"source":["from pyannote.audio.tasks import OverlappedSpeechDetection\n","osd_task = OverlappedSpeechDetection(ami, duration=2.0)\n","\n","osd_model = Model.from_pretrained(\"pyannote/segmentation-3.0\", use_auth_token=True)\n","osd_model.task = osd_task"]},{"cell_type":"markdown","metadata":{"id":"wbb0MeQanX84"},"source":["... optionally freeezing a bunch of layers..."]},{"cell_type":"code","execution_count":22,"metadata":{"id":"tuE1xNjunX84","outputId":"2211d836-8bda-4550-a5e2-7646c764c0af"},"outputs":[{"data":{"text/plain":["['sincnet',\n"," 'sincnet.wav_norm1d',\n"," 'sincnet.conv1d',\n"," 'sincnet.conv1d.0',\n"," 'sincnet.conv1d.0.filterbank',\n"," 'sincnet.conv1d.1',\n"," 'sincnet.conv1d.2',\n"," 'sincnet.pool1d',\n"," 'sincnet.pool1d.0',\n"," 'sincnet.pool1d.1',\n"," 'sincnet.pool1d.2',\n"," 'sincnet.norm1d',\n"," 'sincnet.norm1d.0',\n"," 'sincnet.norm1d.1',\n"," 'sincnet.norm1d.2',\n"," 'lstm']"]},"execution_count":22,"metadata":{},"output_type":"execute_result"}],"source":["osd_model.freeze_up_to('lstm')"]},{"cell_type":"markdown","metadata":{"id":"DrKqQyXonX85"},"source":["... and training it:"]},{"cell_type":"code","execution_count":23,"metadata":{"colab":{"referenced_widgets":["","17ca908b800f4d34841bc2c7d5ccdff3"]},"id":"z9PIQ4oUnX85","outputId":"ed98a898-d9a2-4895-d523-9660abf79f1e"},"outputs":[{"name":"stderr","output_type":"stream","text":["GPU available: False, used: False\n","TPU available: False, using: 0 TPU cores\n","IPU available: False, using: 0 IPUs\n","HPU available: False, using: 0 HPUs\n"]},{"name":"stderr","output_type":"stream","text":["\n"," | Name | Type | Params | In sizes | Out sizes \n","---------------------------------------------------------------------------------------------------------------------\n","0 | sincnet | SincNet | 42.6 K | [1, 1, 32000] | [1, 60, 115] \n","1 | lstm | LSTM | 1.4 M | [1, 115, 60] | [[1, 115, 256], [[8, 1, 128], [8, 1, 128]]]\n","2 | linear | ModuleList | 49.4 K | ? | ? \n","3 | classifier | Linear | 129 | [1, 115, 128] | [1, 115, 1] \n","4 | activation | Sigmoid | 0 | [1, 115, 1] | [1, 115, 1] \n","5 | validation_metric | MetricCollection | 0 | ? | ? \n","---------------------------------------------------------------------------------------------------------------------\n","49.5 K Trainable params\n","1.4 M Non-trainable params\n","1.5 M Total params\n","5.890 Total estimated model params size (MB)\n"]},{"data":{"application/vnd.jupyter.widget-view+json":{"model_id":"7a9dfccd597f477bb2990e2746433375","version_major":2,"version_minor":0},"text/plain":["Sanity Checking: | | 0/? [00:00"]},"execution_count":24,"metadata":{},"output_type":"execute_result"}],"source":["from pyannote.audio.utils.signal import binarize\n","binarize(Inference(osd_model)(test_file))"]},{"cell_type":"code","execution_count":25,"metadata":{"id":"P_7CB2wgnX87","outputId":"a5e3a05f-8695-4880-9380-fbde264ca06f"},"outputs":[{"data":{"image/png":"iVBORw0KGgoAAAANSUhEUgAABjwAAADyCAYAAAD5q2z1AAAAOXRFWHRTb2Z0d2FyZQBNYXRwbG90bGliIHZlcnNpb24zLjguMCwgaHR0cHM6Ly9tYXRwbG90bGliLm9yZy81sbWrAAAACXBIWXMAAA9hAAAPYQGoP6dpAAAfgElEQVR4nO3de5RV5X038O8M14nMDHdGFNSoUVxRg5cqJmYpRUAxS1oTl8ZqJC7NBbFiLo2uVPuaxlhNtbWJsc0yaGo1pmm9tkCoEK1KCBLxFm8YXV5gIIAwgIow7PcPX+ftFJQB5nDY4+ez1llr5pzn7P17zp75zTPznbN3TVEURQAAAAAAAEqsttoFAAAAAAAA7CiBBwAAAAAAUHoCDwAAAAAAoPQEHgAAAAAAQOkJPAAAAAAAgNITeAAAAAAAAKUn8AAAAAAAAEpP4AEAAAAAAJSewAMAAAAAACg9gQcAAAAAAFB6Ag8AAAAAAKD0BB4AAAAAAEDpCTwAAAAAAIDSE3gAAAAAAAClJ/AAAAAAAABKT+ABAAAAAACUnsBjC84555zU1NRsdlu0aFHOOeecTJw4catjx48f3zbm7bffzuTJkzNgwID06dMnp556apYuXdpun/Pnz88f//Efp2/fvunXr1/GjRuXxx9/vN2YmTNn5uijj059fX0GDRqUU089NS+//HIlX4pS25bjmCSvvvpqvvjFL2bo0KHp2bNn9tprr/z5n/95VqxY0W5cURS57LLLsvvuu6euri5jxozJCy+80G7M888/n1NOOSUDBw5MQ0NDPvWpT2XOnDntxtx///055phjUl9fn6ampvzFX/xFNm7cWJHXAgAAAACgq6tK4NG6YsVOvW2P8ePHZ8mSJe1u++yzT4fH3n777W2PT506Nffee2/+9V//NQ888EAWL16cP/3TP217fO3atRk/fnyGDx+eefPm5aGHHkp9fX3GjRuXDRs2JEleeumlnHLKKRk9enQWLlyYmTNnZvny5e22s7O9se6dnXbbXh09jr///e9zxBFH5IUXXsjtt9+eRYsW5cYbb8z999+fUaNGZeXKlW1jr7766lx//fW58cYbM2/evOy2224ZN25c3n777bYxJ598cjZu3JjZs2dnwYIFOfTQQ3PyySenubk5SfL444/npJNOyvjx4/PYY4/ljjvuyD333JNvfetb2z1XAAAAAIAPs5qiKIqdvdPX9xi2U/e3x+uvbtP4c845J6tWrcpdd9211cc+aGySrF69OoMGDcptt92Wz372s0mSZ599NiNGjMjcuXNz9NFH59FHH82RRx6ZV155JcOGvfvaPPnkkznkkEPywgsvZL/99ssvfvGLnHHGGVm/fn1qa9/Nqe69996ccsopWb9+fXr06LFNc+wMR18+c6ft69f/Z9w2P2dbjuOJJ56Yp556Ks8//3zq6uraxjU3N2fffffN2WefnR/96EcpiiJDhw7N1772tXz9619P8u4xHjJkSG6++eacfvrpWb58eQYNGpQHH3wwxx57bJJkzZo1aWhoyKxZszJmzJhceumlmTVrVubPn9+2r3vvvTennXZali1blvr6+m2eLwAAAADAh5lTWlXYggULsmHDhowZM6btvgMPPDDDhw/P3LlzkyQHHHBABgwYkJtuuinvvPNO3nrrrdx0000ZMWJE9t577yTJ4Ycfntra2kybNi2tra1ZvXp1/vmf/zljxoypStjRlaxcuTIzZ87MV7/61XZhR5I0NTXlzDPPzB133JGiKPLSSy+lubm53fFsbGzMUUcd1XY8BwwYkAMOOCA//elPs27dumzcuDH/+I//mMGDB+fwww9Pkqxfvz69e/dut6+6urq8/fbbWbBgQYVnDAAAAADQ9Qg83sd9992XPn36tN0+97nPdXhsnz59cuWVVyZ59x0CPXv2TN++fds9Z8iQIW2nN6qvr8+vfvWr3Hrrramrq0ufPn0yY8aMTJ8+Pd27d0+S7LPPPvnlL3+ZSy+9NL169Urfvn3z2muv5ec//3llXoAuoiPH8YUXXkhRFBkxYsQWtzFixIi88cYb+cMf/tB2zIYMGdJuzP88njU1Nfmv//qvPPbYY6mvr0/v3r1z7bXXZsaMGenXr1+SZNy4cXnkkUdy++23p7W1Na+//nquuOKKJMmSJUs6bf4AAAAAAB8WAo/3cfzxx2fhwoVtt+uvv77DYxcuXJgvf/nLHd7XW2+9lXPPPTef/OQn8+tf/zoPP/xwPv7xj2fChAl56623krwbnJx33nn5whe+kPnz5+eBBx5Iz54989nPfjZVOCtZaWzLceys17EoikyePDmDBw/Of//3f+c3v/lNJk6cmM985jNtYcbYsWNzzTXX5Mtf/nJ69eqVj33sYznppJOSpO2UZQAAAAAAdFz3auy06YmF1djtNtltt92y33777fDYpqamvPPOO1m1alW7d3ksXbo0TU1NSZLbbrstL7/8cubOndv2x+7bbrst/fr1y913353TTz89P/zhD9PY2Jirr766bRu33nprhg0blnnz5uXoo4/ezpluv+nfPH6n73NbdeQ47rfffqmpqckzzzyTP/mTP9ns8WeeeSb9+vXLoEGDsnbt2iTvHr/dd9+9bczSpUvziU98Ikkye/bs3HfffXnjjTfS0NCQJLnhhhsya9as3HLLLW0XJr/44oszderULFmyJP369cvLL7+cSy65JB/96Ec7Y+oAAAAAAB8qVQk8ug0YUI3dVsXhhx+eHj165P7778+pp56aJHnuuefyyiuvZNSoUUmSN998M7W1tampqWl73nufb9q0qd2Y/6lbt25J0jZmZ+u3W8+q7LezDRgwICeccEJuuOGGTJ06dbOLlv/Lv/xLzj777NTU1GSfffZJU1NT7r///raAo6WlJfPmzctXvvKVJO8eq2Tzd2rU1tZudqxqamoydOjQJMntt9+eYcOG5bDDDqvUVAEAAAAAuiznzukE69evT3Nzc7vb8uXLk7x7Qetzzz03F198cebMmZMFCxZk0qRJGTVqVNu7Mk444YS88cYbmTx5cp555pk8/fTTmTRpUrp3757jj3/3XRQTJkzI/Pnzc8UVV+SFF17Ib3/720yaNCl77bVXRo4cWbW5dxU/+MEPsn79+owbNy4PPvhgXn311cyYMSMnnHBC9thjj3z3u99N8m5AcdFFF+Wv//qvc8899+TJJ5/M2WefnaFDh2bixIlJklGjRqVfv375whe+kMcffzzPP/98vvGNb+Sll17KhAkT2vZ5zTXX5Mknn8zTTz+d73znO7nqqqty/fXXtwVZAAAAAAB0nMCjE8yYMSO77757u9unPvWptsevu+66nHzyyTn11FPz6U9/Ok1NTfn3f//3tscPPPDA3HvvvXniiScyatSoHHvssVm8eHHbdpNk9OjRue2223LXXXdl5MiRGT9+fHr16pUZM2a0e0cC22f//ffPo48+mo9+9KM57bTTsu++++b888/P8ccfn7lz56Z///5tY7/5zW9mypQpOf/883PkkUdm7dq1mTFjRnr37p0kGThwYGbMmJG1a9dm9OjROeKII/LQQw/l7rvvzqGHHtq2nenTp+fYY4/N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qafy0EMPbe8mgJLbkT5w8cUXt318yCGHpGfPnvnSl76U733ve+nVq1dnlglU2NZ6QUtLSyZMmJCDDjoof/VXf7VziwN2ih3pA3/5l3/Z9vHIkSOzbt26XHPNNf64ASXzQX3gzDPPzAknnJAlS5bk+9//fk477bQ8/PDD6d27dxUqBSppR3qBNQF0DVvqA/fcc09mz56dxx57rOL7365TWl1wwQW57777MmfOnOy5557b9NympqYsW7as3X0bN27MypUrt/hWFmDXtCN9YEuOOuqobNy4MS+//PKOFwfsNFvrBWvWrMn48eNTX1+fO++8Mz169Gh7rKmpKUuXLm03/r3PrQmgPHakD2zJUUcdlddeey3r16+vVMlAJ9taH2hsbMz++++fT3/60/nFL36RZ599NnfeeWcS6wHoSnakF2yJNQGUz/v1gdmzZ+fFF19M3759071797ZT3J566qk57rjjknTemmCbAo+iKHLBBRfkzjvvzOzZs7PPPvtsy9OTJKNGjcqqVauyYMGCtvtmz56dTZs25aijjtrm7QE7V2f0gS1ZuHBhamtrNzvlHbBr6kgvaGlpydixY9OzZ8/cc889m/0X56hRo/Lkk0+2+0eIWbNmpaGhIQcddFDF5wDsmM7oA1uycOHC9OvXzzs+oQS253eDoihSFEXbHzCtB6D8OqMXbIk1AZTH1vrAt771rTzxxBNZuHBh2y1JrrvuukybNi1J560JtumUVpMnT85tt92Wu+++O/X19W3nzmpsbExdXV2Sd8+n1dzcnEWLFiVJnnzyydTX12f48OHp379/RowYkfHjx+e8887LjTfemA0bNuSCCy7I6aefnqFDh25LOUAVdEYfmDt3bubNm5fjjz8+9fX1mTt3bqZOnZo/+7M/S79+/ao2N6DjttYL3vsj55tvvplbb701LS0taWlpSZIMGjQo3bp1y9ixY3PQQQflrLPOytVXX53m5uZ8+9vfzuTJk/1SAyXQGX3g3nvvzdKlS3P00Uend+/emTVrVq688sp8/etfr+bUgA7aWh/4/e9/nzvuuCNjx47NoEGD8tprr+Wqq65KXV1dTjrppCSxHoAuoDN6gTUBlNvW+kBTU9MW36UxfPjwtnCk09YExTZIssXbtGnT2sZcfvnlWx2zYsWK4owzzij69OlTNDQ0FJMmTSrWrFmzLaUAVdIZfWDBggXFUUcdVTQ2Nha9e/cuRowYUVx55ZXF22+/XZ1JAdtsa71gzpw57zvmpZdeatvOyy+/XJx44olFXV1dMXDgwOJrX/tasWHDhupMCtgmndEHpk+fXnziE58o+vTpU+y2227FoYceWtx4441Fa2tr9SYGdNjW+sDrr79enHjiicXgwYOLHj16FHvuuWfx+c9/vnj22Wfbbcd6AMqtM3qBNQGUW0f+Xril59x5553t7uuMNUHN/9s4AAAAAABAaW3XRcsBAAAAAAB2JQIPAAAAAACg9AQeAAAAAABA6Qk8AAAAAACA0hN4AAAAAAAApSfwAAAAAAAASk/gAQAAAAAAlJ7AAwAA2GHnnHNOJk6cWO0yAACAD7Hu1S4AAADYtdXU1Hzg45dffnn+/u//PkVR7KSKAAAANifwAAAAPtCSJUvaPr7jjjty2WWX5bnnnmu7r0+fPunTp081SgMAAGjjlFYAAMAHampqars1Njampqam3X19+vTZ7JRWxx13XKZMmZKLLroo/fr1y5AhQ/LjH/8469aty6RJk1JfX5/99tsv06dPb7evp556KieeeGL69OmTIUOG5Kyzzsry5ct38owBAIAyEngAAAAVccstt2TgwIH5zW9+kylTpuQrX/lKPve5z+WYY47Jb3/724wdOzZnnXVW3nzzzSTJqlWrMnr06IwcOTKPPvpoZsyYkaVLl+a0006r8kwAAIAyEHgAAAAVceihh+bb3/529t9//1xyySXp3bt3Bg4cmPPOOy/7779/LrvssqxYsSJPPPFEkuQHP/hBRo4cmSuvvDIHHnhgRo4cmZ/85CeZM2dOnn/++SrPBgAA2NW5hgcAAFARhxxySNvH3bp1y4ABA3LwwQe33TdkyJAkybJly5Ikjz/+eObMmbPF64G8+OKL+djHPlbhigEAgDITeAAAABXRo0ePdp/X1NS0u6+mpiZJsmnTpiTJ2rVr85nPfCZ/8zd/s9m2dt999wpWCgAAdAUCDwAAYJdw2GGH5d/+7d+y9957p3t3v6oAAADbxjU8AACAXcLkyZOzcuXKnHHGGZk/f35efPHFzJw5M5MmTUpra2u1ywMAAHZxAg8AAGCXMHTo0Dz88MNpbW3N2LFjc/DBB+eiiy5K3759U1vrVxcAAOCD1RRFUVS7CAAAAAAAgB3h36QAAAAAAIDSE3gAAAAAAAClJ/AAAAAAAABKT+ABAAAAAACUnsADAAAAAAAoPYEHAAAAAABQegIPAAAAAACg9AQeAAAAAABA6Qk8AAAAAACA0hN4AAAAAAAApSfwAAAAAAAASk/gAQAAAAAAlN7/Bcs45RiRI+F2AAAAAElFTkSuQmCC","text/plain":[""]},"execution_count":25,"metadata":{},"output_type":"execute_result"}],"source":["test_file[\"annotation\"]"]},{"cell_type":"markdown","metadata":{"id":"A4OM7DzwnX88"},"source":["## Going further\n","\n","This tutorial only scratched the surface of the training API.\n","\n","Every task supports an `augmentation` parameter for training with data augmentation via [`torch-audiomentations`](https://github.com/asteroid-team/torch-audiomentations) library:\n","\n","```python\n","from torch_audiomentations import AddBackgroundNoise\n","augmentation = AddBackgroundNoise(\"/path/to/background/noise/directory\")\n","vad_task = VoiceActivityDetection(ami, augmentation=augmentation)\n","```\n","\n","We also benefit from all the nice things [`pytorch-lightning`](https://lightning.ai/docs/pytorch/stable/) has to offer (like multi-gpu training, for instance).\n","\n","```python\n","trainer = Trainer(devices=4, accelerator=\"gpu\", strategy='ddp')\n","trainer.fit(model)\n","```\n","\n","Default optimizer (`Adam` with default parameters) is automatically set up for you. \n","Customizing optimizer (and scheduler) requires overriding [`model.configure_optimizers`](https://lightning.ai/docs/pytorch/stable/common/lightning_module.html#configure-optimizers) method:\n","\n","```python\n","from types import MethodType\n","from torch.optim import SGD\n","from torch.optim.lr_scheduler import ExponentialLR\n","def configure_optimizers(self):\n"," return {\"optimizer\": SGD(self.parameters()),\n"," \"lr_scheduler\": ExponentialLR(optimizer, 0.9)}\n","model.configure_optimizers = MethodType(configure_optimizers, model)\n","trainer.fit(model)\n","```"]}],"metadata":{"accelerator":"GPU","colab":{"gpuType":"T4","provenance":[]},"kernelspec":{"display_name":"Python 3","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.10.13"},"widgets":{"application/vnd.jupyter.widget-state+json":{"05b307b893b84133a376088787ababac":{"model_module":"@jupyter-widgets/controls","model_module_version":"1.5.0","model_name":"CheckboxModel","state":{"_dom_classes":[],"_model_module":"@jupyter-widgets/controls","_model_module_version":"1.5.0","_model_name":"CheckboxModel","_view_count":null,"_view_module":"@jupyter-widgets/controls","_view_module_version":"1.5.0","_view_name":"CheckboxView","description":"Add token as git credential?","description_tooltip":null,"disabled":false,"indent":true,"layout":"IPY_MODEL_385eecea5fca4494be7a0e2dc34110ca","style":"IPY_MODEL_c742508bbe1e4f0f9ad385896afea5eb","value":true}},"0c403a6fbba048a9a5388b71a0d83259":{"model_module":"@jupyter-widgets/controls","model_module_version":"1.5.0","model_name":"VBoxModel","state":{"_dom_classes":[],"_model_module":"@jupyter-widgets/controls","_model_module_version":"1.5.0","_model_name":"VBoxModel","_view_count":null,"_view_module":"@jupyter-widgets/controls","_view_module_version":"1.5.0","_view_name":"VBoxView","box_style":"","children":["IPY_MODEL_d1063e27f20648ff9a43fede902a08a4","IPY_MODEL_3b133fae87364dcc89a34ed147995807","IPY_MODEL_e50f15a31e4543219ed038b88132d905","IPY_MODEL_6b641f7304e943d7b53466fc5aa376a2"],"layout":"IPY_MODEL_df65aff406cc4288806b278cf83fb7df"}},"0e04e5e88aae4f14838356c422ba7ed5":{"model_module":"@jupyter-widgets/controls","model_module_version":"1.5.0","model_name":"ButtonStyleModel","state":{"_model_module":"@jupyter-widgets/controls","_model_module_version":"1.5.0","_model_name":"ButtonStyleModel","_view_count":null,"_view_module":"@jupyter-widgets/base","_view_module_version":"1.2.0","_view_name":"StyleView","button_color":null,"font_weight":""}},"0f59d4fccfc045b89337b4b4254de7c3":{"model_module":"@jupyter-widgets/base","model_module_version":"1.2.0","model_name":"LayoutModel","state":{"_model_module":"@jupyter-widgets/base","_model_module_version":"1.2.0","_model_name":"LayoutModel","_view_count":null,"_view_module":"@jupyter-widgets/base","_view_module_version":"1.2.0","_view_name":"LayoutView","align_content":null,"align_items":null,"align_self":null,"border":null,"bottom":null,"display":null,"flex":null,"flex_flow":null,"grid_area":null,"grid_auto_columns":null,"grid_auto_flow":null,"grid_auto_rows":null,"grid_column":null,"grid_gap":null,"grid_row":null,"grid_template_areas":null,"grid_template_columns":null,"grid_template_rows":null,"height":null,"justify_content":null,"justify_items":null,"left":null,"margin":null,"max_height":null,"max_width":null,"min_height":null,"min_width":null,"object_fit":null,"object_position":null,"order":null,"overflow":null,"overflow_x":null,"overflow_y":null,"padding":null,"right":null,"top":null,"visibility":null,"width":null}},"15ab3c58a6014beb9c7ba5e3f5bc0b77":{"model_module":"@jupyter-widgets/controls","model_module_version":"1.5.0","model_name":"HTMLModel","state":{"_dom_classes":[],"_model_module":"@jupyter-widgets/controls","_model_module_version":"1.5.0","_model_name":"HTMLModel","_view_count":null,"_view_module":"@jupyter-widgets/controls","_view_module_version":"1.5.0","_view_name":"HTMLView","description":"","description_tooltip":null,"layout":"IPY_MODEL_20ba5327eef34c7fa20f9f247b9042b1","placeholder":"​","style":"IPY_MODEL_cc9cc24a3aea416a99897cf0c617f225","value":"\nPro Tip: If you don't already have one, you can create a dedicated\n'notebooks' token with 'write' access, that you can then easily reuse for all\nnotebooks. "}},"1cc4aeb271f4441d83c3227a0fef607e":{"model_module":"@jupyter-widgets/base","model_module_version":"1.2.0","model_name":"LayoutModel","state":{"_model_module":"@jupyter-widgets/base","_model_module_version":"1.2.0","_model_name":"LayoutModel","_view_count":null,"_view_module":"@jupyter-widgets/base","_view_module_version":"1.2.0","_view_name":"LayoutView","align_content":null,"align_items":null,"align_self":null,"border":null,"bottom":null,"display":null,"flex":null,"flex_flow":null,"grid_area":null,"grid_auto_columns":null,"grid_auto_flow":null,"grid_auto_rows":null,"grid_column":null,"grid_gap":null,"grid_row":null,"grid_template_areas":null,"grid_template_columns":null,"grid_template_rows":null,"height":null,"justify_content":null,"justify_items":null,"left":null,"margin":null,"max_height":null,"max_width":null,"min_height":null,"min_width":null,"object_fit":null,"object_position":null,"order":null,"overflow":null,"overflow_x":null,"overflow_y":null,"padding":null,"right":null,"top":null,"visibility":null,"width":null}},"20ba5327eef34c7fa20f9f247b9042b1":{"model_module":"@jupyter-widgets/base","model_module_version":"1.2.0","model_name":"LayoutModel","state":{"_model_module":"@jupyter-widgets/base","_model_module_version":"1.2.0","_model_name":"LayoutModel","_view_count":null,"_view_module":"@jupyter-widgets/base","_view_module_version":"1.2.0","_view_name":"LayoutView","align_content":null,"align_items":null,"align_self":null,"border":null,"bottom":null,"display":null,"flex":null,"flex_flow":null,"grid_area":null,"grid_auto_columns":null,"grid_auto_flow":null,"grid_auto_rows":null,"grid_column":null,"grid_gap":null,"grid_row":null,"grid_template_areas":null,"grid_template_columns":null,"grid_template_rows":null,"height":null,"justify_content":null,"justify_items":null,"left":null,"margin":null,"max_height":null,"max_width":null,"min_height":null,"min_width":null,"object_fit":null,"object_position":null,"order":null,"overflow":null,"overflow_x":null,"overflow_y":null,"padding":null,"right":null,"top":null,"visibility":null,"width":null}},"245a4232482547579a72d10243664849":{"model_module":"@jupyter-widgets/base","model_module_version":"1.2.0","model_name":"LayoutModel","state":{"_model_module":"@jupyter-widgets/base","_model_module_version":"1.2.0","_model_name":"LayoutModel","_view_count":null,"_view_module":"@jupyter-widgets/base","_view_module_version":"1.2.0","_view_name":"LayoutView","align_content":null,"align_items":null,"align_self":null,"border":null,"bottom":null,"display":null,"flex":null,"flex_flow":null,"grid_area":null,"grid_auto_columns":null,"grid_auto_flow":null,"grid_auto_rows":null,"grid_column":null,"grid_gap":null,"grid_row":null,"grid_template_areas":null,"grid_template_columns":null,"grid_template_rows":null,"height":null,"justify_content":null,"justify_items":null,"left":null,"margin":null,"max_height":null,"max_width":null,"min_height":null,"min_width":null,"object_fit":null,"object_position":null,"order":null,"overflow":null,"overflow_x":null,"overflow_y":null,"padding":null,"right":null,"top":null,"visibility":null,"width":null}},"2d26c7ece1fe40178ab85f3d14408532":{"model_module":"@jupyter-widgets/controls","model_module_version":"1.5.0","model_name":"HTMLModel","state":{"_dom_classes":[],"_model_module":"@jupyter-widgets/controls","_model_module_version":"1.5.0","_model_name":"HTMLModel","_view_count":null,"_view_module":"@jupyter-widgets/controls","_view_module_version":"1.5.0","_view_name":"HTMLView","description":"","description_tooltip":null,"layout":"IPY_MODEL_e7045e323ec947b3b354ffc61365f4cd","placeholder":"​","style":"IPY_MODEL_b86e1bdb52414bfab9798b661e3e096d","value":" 399/399 [00:00<00:00, 22.1kB/s]"}},"2f70dbe63df14dd18224e2bcb35b6e38":{"model_module":"@jupyter-widgets/controls","model_module_version":"1.5.0","model_name":"DescriptionStyleModel","state":{"_model_module":"@jupyter-widgets/controls","_model_module_version":"1.5.0","_model_name":"DescriptionStyleModel","_view_count":null,"_view_module":"@jupyter-widgets/base","_view_module_version":"1.2.0","_view_name":"StyleView","description_width":""}},"31f30fd568f84363b8dea2d40f54885c":{"model_module":"@jupyter-widgets/base","model_module_version":"1.2.0","model_name":"LayoutModel","state":{"_model_module":"@jupyter-widgets/base","_model_module_version":"1.2.0","_model_name":"LayoutModel","_view_count":null,"_view_module":"@jupyter-widgets/base","_view_module_version":"1.2.0","_view_name":"LayoutView","align_content":null,"align_items":null,"align_self":null,"border":null,"bottom":null,"display":null,"flex":null,"flex_flow":null,"grid_area":null,"grid_auto_columns":null,"grid_auto_flow":null,"grid_auto_rows":null,"grid_column":null,"grid_gap":null,"grid_row":null,"grid_template_areas":null,"grid_template_columns":null,"grid_template_rows":null,"height":null,"justify_content":null,"justify_items":null,"left":null,"margin":null,"max_height":null,"max_width":null,"min_height":null,"min_width":null,"object_fit":null,"object_position":null,"order":null,"overflow":null,"overflow_x":null,"overflow_y":null,"padding":null,"right":null,"top":null,"visibility":null,"width":null}},"35f0b383bafc4425a27f36bc95874430":{"model_module":"@jupyter-widgets/controls","model_module_version":"1.5.0","model_name":"HTMLModel","state":{"_dom_classes":[],"_model_module":"@jupyter-widgets/controls","_model_module_version":"1.5.0","_model_name":"HTMLModel","_view_count":null,"_view_module":"@jupyter-widgets/controls","_view_module_version":"1.5.0","_view_name":"HTMLView","description":"","description_tooltip":null,"layout":"IPY_MODEL_b3a67d2e0c14492788806bb221761174","placeholder":"​","style":"IPY_MODEL_2f70dbe63df14dd18224e2bcb35b6e38","value":"pytorch_model.bin: 100%"}},"385eecea5fca4494be7a0e2dc34110ca":{"model_module":"@jupyter-widgets/base","model_module_version":"1.2.0","model_name":"LayoutModel","state":{"_model_module":"@jupyter-widgets/base","_model_module_version":"1.2.0","_model_name":"LayoutModel","_view_count":null,"_view_module":"@jupyter-widgets/base","_view_module_version":"1.2.0","_view_name":"LayoutView","align_content":null,"align_items":null,"align_self":null,"border":null,"bottom":null,"display":null,"flex":null,"flex_flow":null,"grid_area":null,"grid_auto_columns":null,"grid_auto_flow":null,"grid_auto_rows":null,"grid_column":null,"grid_gap":null,"grid_row":null,"grid_template_areas":null,"grid_template_columns":null,"grid_template_rows":null,"height":null,"justify_content":null,"justify_items":null,"left":null,"margin":null,"max_height":null,"max_width":null,"min_height":null,"min_width":null,"object_fit":null,"object_position":null,"order":null,"overflow":null,"overflow_x":null,"overflow_y":null,"padding":null,"right":null,"top":null,"visibility":null,"width":null}},"3b133fae87364dcc89a34ed147995807":{"model_module":"@jupyter-widgets/controls","model_module_version":"1.5.0","model_name":"LabelModel","state":{"_dom_classes":[],"_model_module":"@jupyter-widgets/controls","_model_module_version":"1.5.0","_model_name":"LabelModel","_view_count":null,"_view_module":"@jupyter-widgets/controls","_view_module_version":"1.5.0","_view_name":"LabelView","description":"","description_tooltip":null,"layout":"IPY_MODEL_bd36d10136344d4b9965557a8783c5f1","placeholder":"​","style":"IPY_MODEL_d1f2777676bf4237947a0e42ff7da6de","value":"Your token has been saved in your configured git credential helpers (store)."}},"3e816698f9f54bc28712b7e0a1f1dba5":{"model_module":"@jupyter-widgets/controls","model_module_version":"1.5.0","model_name":"DescriptionStyleModel","state":{"_model_module":"@jupyter-widgets/controls","_model_module_version":"1.5.0","_model_name":"DescriptionStyleModel","_view_count":null,"_view_module":"@jupyter-widgets/base","_view_module_version":"1.2.0","_view_name":"StyleView","description_width":""}},"469ce1b8998a4d998d42fbea5f431781":{"model_module":"@jupyter-widgets/controls","model_module_version":"1.5.0","model_name":"ProgressStyleModel","state":{"_model_module":"@jupyter-widgets/controls","_model_module_version":"1.5.0","_model_name":"ProgressStyleModel","_view_count":null,"_view_module":"@jupyter-widgets/base","_view_module_version":"1.2.0","_view_name":"StyleView","bar_color":null,"description_width":""}},"4bf2285d01ca4f6c86a117f73972c7e7":{"model_module":"@jupyter-widgets/controls","model_module_version":"1.5.0","model_name":"DescriptionStyleModel","state":{"_model_module":"@jupyter-widgets/controls","_model_module_version":"1.5.0","_model_name":"DescriptionStyleModel","_view_count":null,"_view_module":"@jupyter-widgets/base","_view_module_version":"1.2.0","_view_name":"StyleView","description_width":""}},"50ed1cf2997e4929853964103bb7552c":{"model_module":"@jupyter-widgets/base","model_module_version":"1.2.0","model_name":"LayoutModel","state":{"_model_module":"@jupyter-widgets/base","_model_module_version":"1.2.0","_model_name":"LayoutModel","_view_count":null,"_view_module":"@jupyter-widgets/base","_view_module_version":"1.2.0","_view_name":"LayoutView","align_content":null,"align_items":null,"align_self":null,"border":null,"bottom":null,"display":null,"flex":null,"flex_flow":null,"grid_area":null,"grid_auto_columns":null,"grid_auto_flow":null,"grid_auto_rows":null,"grid_column":null,"grid_gap":null,"grid_row":null,"grid_template_areas":null,"grid_template_columns":null,"grid_template_rows":null,"height":null,"justify_content":null,"justify_items":null,"left":null,"margin":null,"max_height":null,"max_width":null,"min_height":null,"min_width":null,"object_fit":null,"object_position":null,"order":null,"overflow":null,"overflow_x":null,"overflow_y":null,"padding":null,"right":null,"top":null,"visibility":null,"width":null}},"5fb8f440470f4492a5a7a009760a0926":{"model_module":"@jupyter-widgets/controls","model_module_version":"1.5.0","model_name":"HTMLModel","state":{"_dom_classes":[],"_model_module":"@jupyter-widgets/controls","_model_module_version":"1.5.0","_model_name":"HTMLModel","_view_count":null,"_view_module":"@jupyter-widgets/controls","_view_module_version":"1.5.0","_view_name":"HTMLView","description":"","description_tooltip":null,"layout":"IPY_MODEL_1cc4aeb271f4441d83c3227a0fef607e","placeholder":"​","style":"IPY_MODEL_dd4a788ac0cb44ce93b6c001449d5d45","value":" 5.91M/5.91M [00:00<00:00, 45.4MB/s]"}},"693fc1fa7fd746ce8a089f3fd6683b51":{"model_module":"@jupyter-widgets/base","model_module_version":"1.2.0","model_name":"LayoutModel","state":{"_model_module":"@jupyter-widgets/base","_model_module_version":"1.2.0","_model_name":"LayoutModel","_view_count":null,"_view_module":"@jupyter-widgets/base","_view_module_version":"1.2.0","_view_name":"LayoutView","align_content":null,"align_items":null,"align_self":null,"border":null,"bottom":null,"display":null,"flex":null,"flex_flow":null,"grid_area":null,"grid_auto_columns":null,"grid_auto_flow":null,"grid_auto_rows":null,"grid_column":null,"grid_gap":null,"grid_row":null,"grid_template_areas":null,"grid_template_columns":null,"grid_template_rows":null,"height":null,"justify_content":null,"justify_items":null,"left":null,"margin":null,"max_height":null,"max_width":null,"min_height":null,"min_width":null,"object_fit":null,"object_position":null,"order":null,"overflow":null,"overflow_x":null,"overflow_y":null,"padding":null,"right":null,"top":null,"visibility":null,"width":null}},"69c5b722ba3746aa80d87b3ee9fea08e":{"model_module":"@jupyter-widgets/controls","model_module_version":"1.5.0","model_name":"HTMLModel","state":{"_dom_classes":[],"_model_module":"@jupyter-widgets/controls","_model_module_version":"1.5.0","_model_name":"HTMLModel","_view_count":null,"_view_module":"@jupyter-widgets/controls","_view_module_version":"1.5.0","_view_name":"HTMLView","description":"","description_tooltip":null,"layout":"IPY_MODEL_fd5fe3ad4e43456c896ca45ff6a6f155","placeholder":"​","style":"IPY_MODEL_b92e36c0853f40738b51b8ef39f0377d","value":"config.yaml: 100%"}},"6b641f7304e943d7b53466fc5aa376a2":{"model_module":"@jupyter-widgets/controls","model_module_version":"1.5.0","model_name":"LabelModel","state":{"_dom_classes":[],"_model_module":"@jupyter-widgets/controls","_model_module_version":"1.5.0","_model_name":"LabelModel","_view_count":null,"_view_module":"@jupyter-widgets/controls","_view_module_version":"1.5.0","_view_name":"LabelView","description":"","description_tooltip":null,"layout":"IPY_MODEL_bf24ab0141ce423393972b66c6d09f94","placeholder":"​","style":"IPY_MODEL_bd2757c3b84f4ec283b083d64ea52d7a","value":"Login successful"}},"772e6eb169d84fcb808957fd886a59d1":{"model_module":"@jupyter-widgets/base","model_module_version":"1.2.0","model_name":"LayoutModel","state":{"_model_module":"@jupyter-widgets/base","_model_module_version":"1.2.0","_model_name":"LayoutModel","_view_count":null,"_view_module":"@jupyter-widgets/base","_view_module_version":"1.2.0","_view_name":"LayoutView","align_content":null,"align_items":null,"align_self":null,"border":null,"bottom":null,"display":null,"flex":null,"flex_flow":null,"grid_area":null,"grid_auto_columns":null,"grid_auto_flow":null,"grid_auto_rows":null,"grid_column":null,"grid_gap":null,"grid_row":null,"grid_template_areas":null,"grid_template_columns":null,"grid_template_rows":null,"height":null,"justify_content":null,"justify_items":null,"left":null,"margin":null,"max_height":null,"max_width":null,"min_height":null,"min_width":null,"object_fit":null,"object_position":null,"order":null,"overflow":null,"overflow_x":null,"overflow_y":null,"padding":null,"right":null,"top":null,"visibility":null,"width":null}},"8336d24b72414718b82c3195897ee896":{"model_module":"@jupyter-widgets/base","model_module_version":"1.2.0","model_name":"LayoutModel","state":{"_model_module":"@jupyter-widgets/base","_model_module_version":"1.2.0","_model_name":"LayoutModel","_view_count":null,"_view_module":"@jupyter-widgets/base","_view_module_version":"1.2.0","_view_name":"LayoutView","align_content":null,"align_items":null,"align_self":null,"border":null,"bottom":null,"display":null,"flex":null,"flex_flow":null,"grid_area":null,"grid_auto_columns":null,"grid_auto_flow":null,"grid_auto_rows":null,"grid_column":null,"grid_gap":null,"grid_row":null,"grid_template_areas":null,"grid_template_columns":null,"grid_template_rows":null,"height":null,"justify_content":null,"justify_items":null,"left":null,"margin":null,"max_height":null,"max_width":null,"min_height":null,"min_width":null,"object_fit":null,"object_position":null,"order":null,"overflow":null,"overflow_x":null,"overflow_y":null,"padding":null,"right":null,"top":null,"visibility":null,"width":null}},"84262babb03c4f7dab14b35637e29c31":{"model_module":"@jupyter-widgets/controls","model_module_version":"1.5.0","model_name":"HBoxModel","state":{"_dom_classes":[],"_model_module":"@jupyter-widgets/controls","_model_module_version":"1.5.0","_model_name":"HBoxModel","_view_count":null,"_view_module":"@jupyter-widgets/controls","_view_module_version":"1.5.0","_view_name":"HBoxView","box_style":"","children":["IPY_MODEL_35f0b383bafc4425a27f36bc95874430","IPY_MODEL_f3d067b1a56849c19c933fb3380386b6","IPY_MODEL_5fb8f440470f4492a5a7a009760a0926"],"layout":"IPY_MODEL_c8348fafe0de405da831284cb39af5cc"}},"8865c7d7d01040329de63b6a13e0fdff":{"model_module":"@jupyter-widgets/base","model_module_version":"1.2.0","model_name":"LayoutModel","state":{"_model_module":"@jupyter-widgets/base","_model_module_version":"1.2.0","_model_name":"LayoutModel","_view_count":null,"_view_module":"@jupyter-widgets/base","_view_module_version":"1.2.0","_view_name":"LayoutView","align_content":null,"align_items":null,"align_self":null,"border":null,"bottom":null,"display":null,"flex":null,"flex_flow":null,"grid_area":null,"grid_auto_columns":null,"grid_auto_flow":null,"grid_auto_rows":null,"grid_column":null,"grid_gap":null,"grid_row":null,"grid_template_areas":null,"grid_template_columns":null,"grid_template_rows":null,"height":null,"justify_content":null,"justify_items":null,"left":null,"margin":null,"max_height":null,"max_width":null,"min_height":null,"min_width":null,"object_fit":null,"object_position":null,"order":null,"overflow":null,"overflow_x":null,"overflow_y":null,"padding":null,"right":null,"top":null,"visibility":null,"width":null}},"8f7afdee0292401181bd477a89ee3069":{"model_module":"@jupyter-widgets/controls","model_module_version":"1.5.0","model_name":"PasswordModel","state":{"_dom_classes":[],"_model_module":"@jupyter-widgets/controls","_model_module_version":"1.5.0","_model_name":"PasswordModel","_view_count":null,"_view_module":"@jupyter-widgets/controls","_view_module_version":"1.5.0","_view_name":"PasswordView","continuous_update":true,"description":"Token:","description_tooltip":null,"disabled":false,"layout":"IPY_MODEL_772e6eb169d84fcb808957fd886a59d1","placeholder":"​","style":"IPY_MODEL_dcf595ee01a248f895635ad054c8ce28","value":""}},"98b09e7bb5d14a9d8c85e52f54c9c6cf":{"model_module":"@jupyter-widgets/controls","model_module_version":"1.5.0","model_name":"LabelModel","state":{"_dom_classes":[],"_model_module":"@jupyter-widgets/controls","_model_module_version":"1.5.0","_model_name":"LabelModel","_view_count":null,"_view_module":"@jupyter-widgets/controls","_view_module_version":"1.5.0","_view_name":"LabelView","description":"","description_tooltip":null,"layout":"IPY_MODEL_50ed1cf2997e4929853964103bb7552c","placeholder":"​","style":"IPY_MODEL_4bf2285d01ca4f6c86a117f73972c7e7","value":"Connecting..."}},"b3a67d2e0c14492788806bb221761174":{"model_module":"@jupyter-widgets/base","model_module_version":"1.2.0","model_name":"LayoutModel","state":{"_model_module":"@jupyter-widgets/base","_model_module_version":"1.2.0","_model_name":"LayoutModel","_view_count":null,"_view_module":"@jupyter-widgets/base","_view_module_version":"1.2.0","_view_name":"LayoutView","align_content":null,"align_items":null,"align_self":null,"border":null,"bottom":null,"display":null,"flex":null,"flex_flow":null,"grid_area":null,"grid_auto_columns":null,"grid_auto_flow":null,"grid_auto_rows":null,"grid_column":null,"grid_gap":null,"grid_row":null,"grid_template_areas":null,"grid_template_columns":null,"grid_template_rows":null,"height":null,"justify_content":null,"justify_items":null,"left":null,"margin":null,"max_height":null,"max_width":null,"min_height":null,"min_width":null,"object_fit":null,"object_position":null,"order":null,"overflow":null,"overflow_x":null,"overflow_y":null,"padding":null,"right":null,"top":null,"visibility":null,"width":null}},"b86e1bdb52414bfab9798b661e3e096d":{"model_module":"@jupyter-widgets/controls","model_module_version":"1.5.0","model_name":"DescriptionStyleModel","state":{"_model_module":"@jupyter-widgets/controls","_model_module_version":"1.5.0","_model_name":"DescriptionStyleModel","_view_count":null,"_view_module":"@jupyter-widgets/base","_view_module_version":"1.2.0","_view_name":"StyleView","description_width":""}},"b906b2359fa84291b3b78bcced4f3028":{"model_module":"@jupyter-widgets/controls","model_module_version":"1.5.0","model_name":"HTMLModel","state":{"_dom_classes":[],"_model_module":"@jupyter-widgets/controls","_model_module_version":"1.5.0","_model_name":"HTMLModel","_view_count":null,"_view_module":"@jupyter-widgets/controls","_view_module_version":"1.5.0","_view_name":"HTMLView","description":"","description_tooltip":null,"layout":"IPY_MODEL_31f30fd568f84363b8dea2d40f54885c","placeholder":"​","style":"IPY_MODEL_f383e9d323c64c64b528266858d6595c","value":"

Copy a token from your Hugging Face\ntokens page and paste it below.
Immediately click login after copying\nyour token or it might be stored in plain text in this notebook file.
"}},"b92e36c0853f40738b51b8ef39f0377d":{"model_module":"@jupyter-widgets/controls","model_module_version":"1.5.0","model_name":"DescriptionStyleModel","state":{"_model_module":"@jupyter-widgets/controls","_model_module_version":"1.5.0","_model_name":"DescriptionStyleModel","_view_count":null,"_view_module":"@jupyter-widgets/base","_view_module_version":"1.2.0","_view_name":"StyleView","description_width":""}},"bcccc0031f7245a394abc3aee4a6e1c2":{"model_module":"@jupyter-widgets/controls","model_module_version":"1.5.0","model_name":"HBoxModel","state":{"_dom_classes":[],"_model_module":"@jupyter-widgets/controls","_model_module_version":"1.5.0","_model_name":"HBoxModel","_view_count":null,"_view_module":"@jupyter-widgets/controls","_view_module_version":"1.5.0","_view_name":"HBoxView","box_style":"","children":["IPY_MODEL_69c5b722ba3746aa80d87b3ee9fea08e","IPY_MODEL_ef96f5501bbb4a55b3aedac70d1261b5","IPY_MODEL_2d26c7ece1fe40178ab85f3d14408532"],"layout":"IPY_MODEL_693fc1fa7fd746ce8a089f3fd6683b51"}},"bd2757c3b84f4ec283b083d64ea52d7a":{"model_module":"@jupyter-widgets/controls","model_module_version":"1.5.0","model_name":"DescriptionStyleModel","state":{"_model_module":"@jupyter-widgets/controls","_model_module_version":"1.5.0","_model_name":"DescriptionStyleModel","_view_count":null,"_view_module":"@jupyter-widgets/base","_view_module_version":"1.2.0","_view_name":"StyleView","description_width":""}},"bd36d10136344d4b9965557a8783c5f1":{"model_module":"@jupyter-widgets/base","model_module_version":"1.2.0","model_name":"LayoutModel","state":{"_model_module":"@jupyter-widgets/base","_model_module_version":"1.2.0","_model_name":"LayoutModel","_view_count":null,"_view_module":"@jupyter-widgets/base","_view_module_version":"1.2.0","_view_name":"LayoutView","align_content":null,"align_items":null,"align_self":null,"border":null,"bottom":null,"display":null,"flex":null,"flex_flow":null,"grid_area":null,"grid_auto_columns":null,"grid_auto_flow":null,"grid_auto_rows":null,"grid_column":null,"grid_gap":null,"grid_row":null,"grid_template_areas":null,"grid_template_columns":null,"grid_template_rows":null,"height":null,"justify_content":null,"justify_items":null,"left":null,"margin":null,"max_height":null,"max_width":null,"min_height":null,"min_width":null,"object_fit":null,"object_position":null,"order":null,"overflow":null,"overflow_x":null,"overflow_y":null,"padding":null,"right":null,"top":null,"visibility":null,"width":null}},"bf24ab0141ce423393972b66c6d09f94":{"model_module":"@jupyter-widgets/base","model_module_version":"1.2.0","model_name":"LayoutModel","state":{"_model_module":"@jupyter-widgets/base","_model_module_version":"1.2.0","_model_name":"LayoutModel","_view_count":null,"_view_module":"@jupyter-widgets/base","_view_module_version":"1.2.0","_view_name":"LayoutView","align_content":null,"align_items":null,"align_self":null,"border":null,"bottom":null,"display":null,"flex":null,"flex_flow":null,"grid_area":null,"grid_auto_columns":null,"grid_auto_flow":null,"grid_auto_rows":null,"grid_column":null,"grid_gap":null,"grid_row":null,"grid_template_areas":null,"grid_template_columns":null,"grid_template_rows":null,"height":null,"justify_content":null,"justify_items":null,"left":null,"margin":null,"max_height":null,"max_width":null,"min_height":null,"min_width":null,"object_fit":null,"object_position":null,"order":null,"overflow":null,"overflow_x":null,"overflow_y":null,"padding":null,"right":null,"top":null,"visibility":null,"width":null}},"c258b47039a243cabadd48de545542f2":{"model_module":"@jupyter-widgets/controls","model_module_version":"1.5.0","model_name":"ButtonModel","state":{"_dom_classes":[],"_model_module":"@jupyter-widgets/controls","_model_module_version":"1.5.0","_model_name":"ButtonModel","_view_count":null,"_view_module":"@jupyter-widgets/controls","_view_module_version":"1.5.0","_view_name":"ButtonView","button_style":"","description":"Login","disabled":false,"icon":"","layout":"IPY_MODEL_e7aa7e431546419792ff998e10c4bbe9","style":"IPY_MODEL_0e04e5e88aae4f14838356c422ba7ed5","tooltip":""}},"c3204d520d604179923e93e0a9bfd395":{"model_module":"@jupyter-widgets/controls","model_module_version":"1.5.0","model_name":"ProgressStyleModel","state":{"_model_module":"@jupyter-widgets/controls","_model_module_version":"1.5.0","_model_name":"ProgressStyleModel","_view_count":null,"_view_module":"@jupyter-widgets/base","_view_module_version":"1.2.0","_view_name":"StyleView","bar_color":null,"description_width":""}},"c742508bbe1e4f0f9ad385896afea5eb":{"model_module":"@jupyter-widgets/controls","model_module_version":"1.5.0","model_name":"DescriptionStyleModel","state":{"_model_module":"@jupyter-widgets/controls","_model_module_version":"1.5.0","_model_name":"DescriptionStyleModel","_view_count":null,"_view_module":"@jupyter-widgets/base","_view_module_version":"1.2.0","_view_name":"StyleView","description_width":""}},"c8348fafe0de405da831284cb39af5cc":{"model_module":"@jupyter-widgets/base","model_module_version":"1.2.0","model_name":"LayoutModel","state":{"_model_module":"@jupyter-widgets/base","_model_module_version":"1.2.0","_model_name":"LayoutModel","_view_count":null,"_view_module":"@jupyter-widgets/base","_view_module_version":"1.2.0","_view_name":"LayoutView","align_content":null,"align_items":null,"align_self":null,"border":null,"bottom":null,"display":null,"flex":null,"flex_flow":null,"grid_area":null,"grid_auto_columns":null,"grid_auto_flow":null,"grid_auto_rows":null,"grid_column":null,"grid_gap":null,"grid_row":null,"grid_template_areas":null,"grid_template_columns":null,"grid_template_rows":null,"height":null,"justify_content":null,"justify_items":null,"left":null,"margin":null,"max_height":null,"max_width":null,"min_height":null,"min_width":null,"object_fit":null,"object_position":null,"order":null,"overflow":null,"overflow_x":null,"overflow_y":null,"padding":null,"right":null,"top":null,"visibility":null,"width":null}},"cc9cc24a3aea416a99897cf0c617f225":{"model_module":"@jupyter-widgets/controls","model_module_version":"1.5.0","model_name":"DescriptionStyleModel","state":{"_model_module":"@jupyter-widgets/controls","_model_module_version":"1.5.0","_model_name":"DescriptionStyleModel","_view_count":null,"_view_module":"@jupyter-widgets/base","_view_module_version":"1.2.0","_view_name":"StyleView","description_width":""}},"d072771073ed479b8e16cd9e5b9262c7":{"model_module":"@jupyter-widgets/controls","model_module_version":"1.5.0","model_name":"DescriptionStyleModel","state":{"_model_module":"@jupyter-widgets/controls","_model_module_version":"1.5.0","_model_name":"DescriptionStyleModel","_view_count":null,"_view_module":"@jupyter-widgets/base","_view_module_version":"1.2.0","_view_name":"StyleView","description_width":""}},"d1063e27f20648ff9a43fede902a08a4":{"model_module":"@jupyter-widgets/controls","model_module_version":"1.5.0","model_name":"LabelModel","state":{"_dom_classes":[],"_model_module":"@jupyter-widgets/controls","_model_module_version":"1.5.0","_model_name":"LabelModel","_view_count":null,"_view_module":"@jupyter-widgets/controls","_view_module_version":"1.5.0","_view_name":"LabelView","description":"","description_tooltip":null,"layout":"IPY_MODEL_8865c7d7d01040329de63b6a13e0fdff","placeholder":"​","style":"IPY_MODEL_3e816698f9f54bc28712b7e0a1f1dba5","value":"Token is valid (permission: write)."}},"d1f2777676bf4237947a0e42ff7da6de":{"model_module":"@jupyter-widgets/controls","model_module_version":"1.5.0","model_name":"DescriptionStyleModel","state":{"_model_module":"@jupyter-widgets/controls","_model_module_version":"1.5.0","_model_name":"DescriptionStyleModel","_view_count":null,"_view_module":"@jupyter-widgets/base","_view_module_version":"1.2.0","_view_name":"StyleView","description_width":""}},"dcf595ee01a248f895635ad054c8ce28":{"model_module":"@jupyter-widgets/controls","model_module_version":"1.5.0","model_name":"DescriptionStyleModel","state":{"_model_module":"@jupyter-widgets/controls","_model_module_version":"1.5.0","_model_name":"DescriptionStyleModel","_view_count":null,"_view_module":"@jupyter-widgets/base","_view_module_version":"1.2.0","_view_name":"StyleView","description_width":""}},"dd4a788ac0cb44ce93b6c001449d5d45":{"model_module":"@jupyter-widgets/controls","model_module_version":"1.5.0","model_name":"DescriptionStyleModel","state":{"_model_module":"@jupyter-widgets/controls","_model_module_version":"1.5.0","_model_name":"DescriptionStyleModel","_view_count":null,"_view_module":"@jupyter-widgets/base","_view_module_version":"1.2.0","_view_name":"StyleView","description_width":""}},"df65aff406cc4288806b278cf83fb7df":{"model_module":"@jupyter-widgets/base","model_module_version":"1.2.0","model_name":"LayoutModel","state":{"_model_module":"@jupyter-widgets/base","_model_module_version":"1.2.0","_model_name":"LayoutModel","_view_count":null,"_view_module":"@jupyter-widgets/base","_view_module_version":"1.2.0","_view_name":"LayoutView","align_content":null,"align_items":"center","align_self":null,"border":null,"bottom":null,"display":"flex","flex":null,"flex_flow":"column","grid_area":null,"grid_auto_columns":null,"grid_auto_flow":null,"grid_auto_rows":null,"grid_column":null,"grid_gap":null,"grid_row":null,"grid_template_areas":null,"grid_template_columns":null,"grid_template_rows":null,"height":null,"justify_content":null,"justify_items":null,"left":null,"margin":null,"max_height":null,"max_width":null,"min_height":null,"min_width":null,"object_fit":null,"object_position":null,"order":null,"overflow":null,"overflow_x":null,"overflow_y":null,"padding":null,"right":null,"top":null,"visibility":null,"width":"50%"}},"e50f15a31e4543219ed038b88132d905":{"model_module":"@jupyter-widgets/controls","model_module_version":"1.5.0","model_name":"LabelModel","state":{"_dom_classes":[],"_model_module":"@jupyter-widgets/controls","_model_module_version":"1.5.0","_model_name":"LabelModel","_view_count":null,"_view_module":"@jupyter-widgets/controls","_view_module_version":"1.5.0","_view_name":"LabelView","description":"","description_tooltip":null,"layout":"IPY_MODEL_245a4232482547579a72d10243664849","placeholder":"​","style":"IPY_MODEL_d072771073ed479b8e16cd9e5b9262c7","value":"Your token has been saved to /root/.cache/huggingface/token"}},"e7045e323ec947b3b354ffc61365f4cd":{"model_module":"@jupyter-widgets/base","model_module_version":"1.2.0","model_name":"LayoutModel","state":{"_model_module":"@jupyter-widgets/base","_model_module_version":"1.2.0","_model_name":"LayoutModel","_view_count":null,"_view_module":"@jupyter-widgets/base","_view_module_version":"1.2.0","_view_name":"LayoutView","align_content":null,"align_items":null,"align_self":null,"border":null,"bottom":null,"display":null,"flex":null,"flex_flow":null,"grid_area":null,"grid_auto_columns":null,"grid_auto_flow":null,"grid_auto_rows":null,"grid_column":null,"grid_gap":null,"grid_row":null,"grid_template_areas":null,"grid_template_columns":null,"grid_template_rows":null,"height":null,"justify_content":null,"justify_items":null,"left":null,"margin":null,"max_height":null,"max_width":null,"min_height":null,"min_width":null,"object_fit":null,"object_position":null,"order":null,"overflow":null,"overflow_x":null,"overflow_y":null,"padding":null,"right":null,"top":null,"visibility":null,"width":null}},"e7aa7e431546419792ff998e10c4bbe9":{"model_module":"@jupyter-widgets/base","model_module_version":"1.2.0","model_name":"LayoutModel","state":{"_model_module":"@jupyter-widgets/base","_model_module_version":"1.2.0","_model_name":"LayoutModel","_view_count":null,"_view_module":"@jupyter-widgets/base","_view_module_version":"1.2.0","_view_name":"LayoutView","align_content":null,"align_items":null,"align_self":null,"border":null,"bottom":null,"display":null,"flex":null,"flex_flow":null,"grid_area":null,"grid_auto_columns":null,"grid_auto_flow":null,"grid_auto_rows":null,"grid_column":null,"grid_gap":null,"grid_row":null,"grid_template_areas":null,"grid_template_columns":null,"grid_template_rows":null,"height":null,"justify_content":null,"justify_items":null,"left":null,"margin":null,"max_height":null,"max_width":null,"min_height":null,"min_width":null,"object_fit":null,"object_position":null,"order":null,"overflow":null,"overflow_x":null,"overflow_y":null,"padding":null,"right":null,"top":null,"visibility":null,"width":null}},"ef96f5501bbb4a55b3aedac70d1261b5":{"model_module":"@jupyter-widgets/controls","model_module_version":"1.5.0","model_name":"FloatProgressModel","state":{"_dom_classes":[],"_model_module":"@jupyter-widgets/controls","_model_module_version":"1.5.0","_model_name":"FloatProgressModel","_view_count":null,"_view_module":"@jupyter-widgets/controls","_view_module_version":"1.5.0","_view_name":"ProgressView","bar_style":"success","description":"","description_tooltip":null,"layout":"IPY_MODEL_8336d24b72414718b82c3195897ee896","max":399,"min":0,"orientation":"horizontal","style":"IPY_MODEL_469ce1b8998a4d998d42fbea5f431781","value":399}},"f383e9d323c64c64b528266858d6595c":{"model_module":"@jupyter-widgets/controls","model_module_version":"1.5.0","model_name":"DescriptionStyleModel","state":{"_model_module":"@jupyter-widgets/controls","_model_module_version":"1.5.0","_model_name":"DescriptionStyleModel","_view_count":null,"_view_module":"@jupyter-widgets/base","_view_module_version":"1.2.0","_view_name":"StyleView","description_width":""}},"f3d067b1a56849c19c933fb3380386b6":{"model_module":"@jupyter-widgets/controls","model_module_version":"1.5.0","model_name":"FloatProgressModel","state":{"_dom_classes":[],"_model_module":"@jupyter-widgets/controls","_model_module_version":"1.5.0","_model_name":"FloatProgressModel","_view_count":null,"_view_module":"@jupyter-widgets/controls","_view_module_version":"1.5.0","_view_name":"ProgressView","bar_style":"success","description":"","description_tooltip":null,"layout":"IPY_MODEL_0f59d4fccfc045b89337b4b4254de7c3","max":5905440,"min":0,"orientation":"horizontal","style":"IPY_MODEL_c3204d520d604179923e93e0a9bfd395","value":5905440}},"fd5fe3ad4e43456c896ca45ff6a6f155":{"model_module":"@jupyter-widgets/base","model_module_version":"1.2.0","model_name":"LayoutModel","state":{"_model_module":"@jupyter-widgets/base","_model_module_version":"1.2.0","_model_name":"LayoutModel","_view_count":null,"_view_module":"@jupyter-widgets/base","_view_module_version":"1.2.0","_view_name":"LayoutView","align_content":null,"align_items":null,"align_self":null,"border":null,"bottom":null,"display":null,"flex":null,"flex_flow":null,"grid_area":null,"grid_auto_columns":null,"grid_auto_flow":null,"grid_auto_rows":null,"grid_column":null,"grid_gap":null,"grid_row":null,"grid_template_areas":null,"grid_template_columns":null,"grid_template_rows":null,"height":null,"justify_content":null,"justify_items":null,"left":null,"margin":null,"max_height":null,"max_width":null,"min_height":null,"min_width":null,"object_fit":null,"object_position":null,"order":null,"overflow":null,"overflow_x":null,"overflow_y":null,"padding":null,"right":null,"top":null,"visibility":null,"width":null}}}}},"nbformat":4,"nbformat_minor":0} diff --git a/tutorials/training_with_cli.md b/tutorials/training_with_cli.md index bc34bd573..984465938 100644 --- a/tutorials/training_with_cli.md +++ b/tutorials/training_with_cli.md @@ -2,7 +2,7 @@ *This tutorial is a very preliminary draft. Expect hiccups and missing details.* -`pyannote.audio` provides a command line tool called `pyannote-audio-train` +`pyannote.audio` provides a command line tool called `pyannote-audio-train` that allows to train models directly from your terminal. It relies on extra dependencies installed using th `[cli]` suffix: @@ -20,6 +20,7 @@ detection on the AMI corpus... pyannote-audio-train \ model=PyanNet \ task=VoiceActivityDetection \ + +registry="AMI-diarization-setup/pyannote/database.yml" \ protocol=AMI.SpeakerDiarization.only_words ``` @@ -28,20 +29,64 @@ pyannote-audio-train \ ```python from pyannote.audio.tasks import VoiceActivityDetection from pyannote.audio.models.segmentation import PyanNet -from pyannote.database import get_protocol +from pyannote.database import registry, FileFinder() from pytorch_lightning import Trainer -protocol = get_protocol("AMI.SpeakerDiarization.only_words") +registry.load_database("AMI-diarization-setup/pyannote/database.yml") +protocol = registry.get_protocol("AMI.SpeakerDiarization.only_words", preprocessors={"audio": FileFinder()}) task = VoiceActivityDetection(protocol) model = PyanNet(task=task) trainer = Trainer() trainer.fit(model) ``` +You can also evaluate a model from it checkpoint on the AMI corpus by calling the following commad... + +```bash +pyannote-audio-eval \ + model=path_to_model_checkpoint.ckpt \ + +registry="AMI-diarization-setup/pyannote/database.yml" \ + protocol="Debug.SpeakerDiarization.Debug" \ + subset=test \ +``` +... which is more or less equivalent to running the following Python script: + +```python +from pyannote.database import FileFinder, ProtocolFile, registry + +from pyannote.audio import Inference, Model +from pyannote.audio.utils.metric import DiscreteDiarizationErrorRate +from pyannote.audio.utils.signal import binarize + +model = Model.from_pretrained("path_to_checkpoint.ckpt") + +# load evaluation files +registry.load_database("AMI-diarization-setup/pyannote/database.yml") +protocol = registry.get_protocol("AMI.SpeakerDiarization.only_words", preprocessors={"audio": FileFinder()}) +files = list(getattr(protocol, "test")()) + +# load evaluation metric +metric = DiscreteDiarizationErrorRate() + +inference = Inference(model) + +def hypothesis(file: ProtocolFile): + return Inference.trim( + binarize(inference(file, hook=progress_hook)), + ) + +for file in files: + reference = file["annotation"] + uem = file["annotated"] + _ = metric(reference, hypothesis(file), uem=uem) + +report = metric.report(display=False) +``` + ## Hydra-based configuration -`pyannote-audio-train` relies on [`Hydra`](https://hydra.cc) to configure the -training process. Adding `--cfg job` option to the previous command will let +`pyannote-audio-train` relies on [`Hydra`](https://hydra.cc) to configure the +training process. Adding `--cfg job` option to the previous command will let you know about the actual configuration used for training: @@ -49,6 +94,7 @@ you know about the actual configuration used for training: pyannote-audio-train --cfg job \ model=PyanNet \ task=VoiceActivityDetection \ + registry="AMI-diarization-setup/pyannote/database.yml" \ protocol=AMI.SpeakerDiarization.only_words ``` @@ -71,6 +117,7 @@ To change the duration of audio chunks used for training to 2 seconds, you would pyannote-audio-train \ model=PyanNet \ task=VoiceActivityDetection task.duration=2.0 \ + registry="AMI-diarization-setup/pyannote/database.yml" \ protocol=AMI.SpeakerDiarization.only_words ``` @@ -104,6 +151,7 @@ pyannote-audio-train \ --config-dir /path/to/custom_config \ model=PyanNet \ task=VoiceActivityDetection task.duration=2.0 \ + registry="AMI-diarization-setup/pyannote/database.yml" \ protocol=AMI.SpeakerDiarization.only_words \ +augmentation=background_noise ``` @@ -123,10 +171,11 @@ Here, we launch a grid of (3 x 2 =) six different jobs: * mono-directional or bidirectional LSTMs ```bash -pyannote-audio-train +pyannote-audio-train --multirun hydra/launcher=submitit_slurm \ model=PyanNet +model.lstm.num_layers=2,3,4 +model.lstm.bidirectional=true,false \ task=VoiceActivityDetection \ + registry="AMI-diarization-setup/pyannote/database.yml" \ protocol=AMI.SpeakerDiarization.only_words ``` diff --git a/tutorials/voice_activity_detection.ipynb b/tutorials/voice_activity_detection.ipynb index df2cadd15..470ee53df 100644 --- a/tutorials/voice_activity_detection.ipynb +++ b/tutorials/voice_activity_detection.ipynb @@ -1,649 +1 @@ -{ - "cells": [ - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "# Training a voice activity detection pipeline from scratch with `pyannote.audio`\n", - "\n", - "Voice activity detection (VAD) is the task of detecting speech regions in a given audio stream or recording. \n", - "In this tutorial, you will learn how to train and evaluate a VAD pipeline from scratch." - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "## Data preparation\n", - "\n", - "This tutorial assumes that \n", - "* the [AMI corpus](https://groups.inf.ed.ac.uk/ami/corpus/) has already been [setup for use with `pyannote`](https://github.com/pyannote/AMI-diarization-setup/tree/main/pyannote)\n", - "* the `PYANNOTE_DATABASE_CONFIG` environment variable is set accordingly. \n", - "\n", - "See [`pyannote.database` documentation](https://github.com/pyannote/pyannote-database#pyannote-database) to learn how to prepare your own dataset for training with `pyannote.audio`." - ] - }, - { - "cell_type": "code", - "execution_count": 2, - "metadata": {}, - "outputs": [], - "source": [ - "from pyannote.database import get_protocol, FileFinder\n", - "preprocessors = {\"audio\": FileFinder()}\n", - "ami = get_protocol('AMI.SpeakerDiarization.only_words', \n", - " preprocessors=preprocessors)" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "`pyannote.database` *protocols* usually define \n", - "* a training set: `for training_file in protocol.train(): ...`, \n", - "* a validation set: `for validation_file in protocol.development(): ...` \n", - "* an evaluation set `for evaluation_file in protocol.test(): ...`" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "Let's listen to one minute of the first training file..." - ] - }, - { - "cell_type": "code", - "execution_count": 40, - "metadata": {}, - "outputs": [], - "source": [ - "first_training_file = next(ami.train())\n", - "reference = first_training_file[\"annotation\"]" - ] - }, - { - "cell_type": "code", - "execution_count": 72, - "metadata": {}, - "outputs": [ - { - "data": { - "text/html": [ - "\n", - " \n", - " " - ], - "text/plain": [ - "" - ] - }, - "execution_count": 72, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "from pyannote.audio.utils.preview import listen\n", - "from pyannote.core import Segment\n", - "one_minute = Segment(240, 300)\n", - "listen(first_training_file, one_minute)" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "... and visualize the manual annotation:" - ] - }, - { - "cell_type": "code", - "execution_count": 73, - "metadata": {}, - "outputs": [ - { - "data": { - "image/png": "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", - "text/plain": [ - "" - ] - }, - "execution_count": 73, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "from pyannote.core import notebook\n", - "notebook.crop = one_minute\n", - "reference" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "## Training" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "We initialize a VAD *task* that describes how the model will be trained:\n", - "\n", - "* `ami` indicates that we will use files available in `ami.train()`.\n", - "* `duration=2.` and `batch_size=128` indicates that the model will ingest batches of 128 two seconds long audio chunks." - ] - }, - { - "cell_type": "code", - "execution_count": 17, - "metadata": {}, - "outputs": [], - "source": [ - "from pyannote.audio.tasks import VoiceActivityDetection\n", - "vad = VoiceActivityDetection(ami, duration=2., batch_size=128)" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "We initialize one *model* with the `PyanNet` architecture used [in that paper](https://arxiv.org/abs/2104.04045). \n", - "In particular, we increase the default stride of the initial `sincnet` feature extraction layer to `10`.\n", - "\n", - "The model is also provided with the task (`task=vad`) for which it is being trained:" - ] - }, - { - "cell_type": "code", - "execution_count": 20, - "metadata": {}, - "outputs": [], - "source": [ - "from pyannote.audio.models.segmentation import PyanNet\n", - "model = PyanNet(sincnet={'stride': 10}, task=vad)" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "Now that everything is ready, let's train with `pytorch-ligthning`!" - ] - }, - { - "cell_type": "code", - "execution_count": 21, - "metadata": {}, - "outputs": [ - { - "name": "stderr", - "output_type": "stream", - "text": [ - "GPU available: True, used: True\n", - "TPU available: False, using: 0 TPU cores\n", - "IPU available: False, using: 0 IPUs\n", - "LOCAL_RANK: 0 - CUDA_VISIBLE_DEVICES: [0]\n", - "\n", - " | Name | Type | Params | In sizes | Out sizes \n", - "-----------------------------------------------------------------------------------------------------------------------\n", - "0 | sincnet | SincNet | 42.6 K | [128, 1, 32000] | [128, 60, 115] \n", - "1 | lstm | LSTM | 589 K | [128, 115, 60] | [[128, 115, 256], [[4, 128, 128], [4, 128, 128]]]\n", - "2 | linear | ModuleList | 49.4 K | ? | ? \n", - "3 | classifier | Linear | 129 | [128, 115, 128] | [128, 115, 1] \n", - "4 | activation | Sigmoid | 0 | [128, 115, 1] | [128, 115, 1] \n", - "5 | validation_metric | AUROC | 0 | ? | ? \n", - "-----------------------------------------------------------------------------------------------------------------------\n", - "681 K Trainable params\n", - "0 Non-trainable params\n", - "681 K Total params\n", - "2.728 Total estimated model params size (MB)\n" - ] - }, - { - "data": { - "application/vnd.jupyter.widget-view+json": { - "model_id": "", - "version_major": 2, - "version_minor": 0 - }, - "text/plain": [ - "HBox(children=(HTML(value='Validation sanity check'), FloatProgress(value=1.0, bar_style='info', layout=Layout…" - ] - }, - "metadata": {}, - "output_type": "display_data" - }, - { - "data": { - "application/vnd.jupyter.widget-view+json": { - "model_id": "5bee6d4900844312aac04eb9b176f023", - "version_major": 2, - "version_minor": 0 - }, - "text/plain": [ - "HBox(children=(HTML(value='Training'), FloatProgress(value=1.0, bar_style='info', layout=Layout(flex='2'), max…" - ] - }, - "metadata": {}, - "output_type": "display_data" - }, - { - "data": { - "application/vnd.jupyter.widget-view+json": { - "model_id": "", - "version_major": 2, - "version_minor": 0 - }, - "text/plain": [ - "HBox(children=(HTML(value='Validating'), FloatProgress(value=1.0, bar_style='info', layout=Layout(flex='2'), m…" - ] - }, - "metadata": {}, - "output_type": "display_data" - }, - { - "data": { - "application/vnd.jupyter.widget-view+json": { - "model_id": "", - "version_major": 2, - "version_minor": 0 - }, - "text/plain": [ - "HBox(children=(HTML(value='Validating'), FloatProgress(value=1.0, bar_style='info', layout=Layout(flex='2'), m…" - ] - }, - "metadata": {}, - "output_type": "display_data" - }, - { - "name": "stdout", - "output_type": "stream", - "text": [ - "\n", - "\n" - ] - } - ], - "source": [ - "import pytorch_lightning as pl\n", - "trainer = pl.Trainer(devices=1, accelerator=\"gpu\", max_epochs=2)\n", - "trainer.fit(model)" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "For the purpose of this tutorial, the model is trained for only 2 epochs. One can obviously expect better performance by training longer and on more data.\n", - "\n", - "See [`pytorch-lightning`](https://www.pytorchlightning.ai/) documentation to learn more about the [`Trainer` API](https://pytorch-lightning.readthedocs.io/en/latest/common/trainer.html), in particular." - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "## Inference\n", - "\n", - "Once trained, the model can be applied to a test file:" - ] - }, - { - "cell_type": "code", - "execution_count": 23, - "metadata": {}, - "outputs": [], - "source": [ - "test_file = next(ami.test())\n", - "# here we use a test file provided by the protocol, but it could be any audio file\n", - "# e.g. test_file = \"/path/to/test.wav\"." - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "Because the model was trained on 2s audio chunks and that test files are likely to be much longer than that, we wrap the `model` with an `Inference` instance: it will take care of sliding a 2s window over the whole file and aggregate the output of the model." - ] - }, - { - "cell_type": "code", - "execution_count": 29, - "metadata": {}, - "outputs": [], - "source": [ - "from pyannote.audio import Inference\n", - "inference = Inference(model)\n", - "vad_probability = inference(test_file)" - ] - }, - { - "cell_type": "code", - "execution_count": 30, - "metadata": {}, - "outputs": [ - { - "data": { - "image/png": "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", - "text/plain": [ - "" - ] - }, - "execution_count": 30, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "vad_probability" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "Perfect voice activity detection output should look like that:" - ] - }, - { - "cell_type": "code", - "execution_count": 34, - "metadata": {}, - "outputs": [ - { - "data": { - "image/png": "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", - "text/plain": [ - ", , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , ])>" - ] - }, - "execution_count": 34, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "expected_output = test_file[\"annotation\"].get_timeline().support()\n", - "expected_output" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "## Pipeline" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "Almost there! To obtain the final speech regions, we need to apply a detection threshold. \n", - "For that, we rely on the voice activity detection pipeline whose hyper-parameters are set manually:\n", - "- `onset=0.6`: mark region as `active` when probability goes above 0.6\n", - "- `offset=0.4`: switch back to `inactive` when probability goes below 0.4\n", - "- `min_duration_on=0.0`: remove `active` regions shorter than that many seconds\n", - "- `min_duration_off=0.0`: fill `inactive` regions shorter than that many seconds\n", - "\n", - "\n", - "More details about those hyper-parameters are provided in Figure 2 of [that paper](https://arxiv.org/abs/2104.04045)." - ] - }, - { - "cell_type": "code", - "execution_count": 56, - "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": [ - "" - ] - }, - "execution_count": 56, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "from pyannote.audio.pipelines import VoiceActivityDetection as VoiceActivityDetectionPipeline\n", - "pipeline = VoiceActivityDetectionPipeline(segmentation=model)\n", - "initial_params = {\"onset\": 0.6, \"offset\": 0.4, \n", - " \"min_duration_on\": 0.0, \"min_duration_off\": 0.0}\n", - "pipeline.instantiate(initial_params)" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "Here we go:" - ] - }, - { - "cell_type": "code", - "execution_count": 76, - "metadata": {}, - "outputs": [ - { - "data": { - "image/png": "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", - "text/plain": [ - ", , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , ])>" - ] - }, - "execution_count": 76, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "pipeline(test_file).get_timeline()" - ] - }, - { - "cell_type": "code", - "execution_count": 77, - "metadata": {}, - "outputs": [ - { - "data": { - "image/png": "iVBORw0KGgoAAAANSUhEUgAABH0AAABjCAYAAAAGhXxMAAAAOXRFWHRTb2Z0d2FyZQBNYXRwbG90bGliIHZlcnNpb24zLjMuMywgaHR0cHM6Ly9tYXRwbG90bGliLm9yZy/Il7ecAAAACXBIWXMAAAsTAAALEwEAmpwYAAALQElEQVR4nO3df6xkZ1kH8O9Dt6iJFZQtWrHJbZBiREOlK1INEatiwMQqVil/aCNEDaJRRE0gapdEE6lFoiZKVGrqj9hWabQSiqmxqZoIzW5tXVraWGIRlgKpSqVRF0of/5hz2cnl3rt3987eO+fM55NM9sz58c5z3vvMu2eeOedMdXcAAAAAmJan7HcAAAAAACyeog8AAADABCn6AAAAAEyQog8AAADABCn6AAAAAEzQgUU0cvDgwV5bW1tEUwAAAAAkOXr06KPdff6Zbr+Qos/a2lqOHDmyiKYAAAAASFJVH9rN9i7vAgAAAJggRR8AAACACVL0AQAAAJggRR8AAACACVL0AQAAAJggRR8AAACACVL0AQAAAJggRR8AAACACVL0AQAAAJggRR8AAACACVL0AQAAAJggRR8AAACACVL0AQAAAJggRR8AAACACVL0AQAAAJggRR8AAACACVL0AQAAAJggRR8AAACACVL0AQAAAJggRR8AAACACVL0AQAAAJggRR8AAACACVL0AQAAAJigpSr6HD58eLKvN+V92ytT2qcz3ZdF9MF6G8vUnzuNZZliPl1jiX0sccKqWvb36NmMb6u2l71P9tLGvtA3y2fsf5Oxxw/zViWfq7t33cihQ4f6yJEjuw+mKouIZxlfb8r7tlemtE9nui+L6IP1NpapP3cayzLFfLrGEvtY4oRVtezv0bMZ31ZtL3uf7KWNfaFvls/Y/yZjjx/mjSWfq+podx860+2X6kwfAAAAABbjwH4HsFFV7XcIZ82U922v6MPF9sEY+3OMMY+NPgZ2Yz/GEOPW1vQNiyanYFyWruiz15dA7aUp79teGcPpdzuxm7/PIi7vWlRbi3I6/bEsMZ+uMb0nx9rHsArGMJaczcu79vo1x2azPtI3y2UM7+FTkVNMxRTejzuxVJd3XXPNNZN9vSnv216Z0j6d6b4sog/W21im/txpLMsU8+kaS+xjiRNW1bK/R89mfFu1vex9spc29oW+WT5j/5uMPX6Ytyr5vFQ3cgYAAABgxo2cAQAAAPg8ij4AAAAAE6ToAwAAADBBij4AAAAAE6ToAwAAADBBij4AAAAAE6ToAwAAADBBij4AAAAAE6ToAwAAADBBij4AAAAAE6ToAwAAADBBij4AAAAAE6ToAwAAADBBij4AAAAAE6ToAwAAADBBij4AAAAAE6ToAwAAADBBij4AAAAAE6ToAwAAADBBij4AAAAAE6ToAwAAADBBij4AAAAAE6ToAwAAADBB1d27b6TqU0ke3H04sNQOJnl0v4OAs0yeswrkOatAnrMK5Dmr4Lndfd6ZbnxgQUE82N2HFtQWLKWqOiLPmTp5ziqQ56wCec4qkOesgqo6spvtXd4FAAAAMEGKPgAAAAATtKiiz+8tqB1YZvKcVSDPWQXynFUgz1kF8pxVsKs8X8iNnAEAAABYLi7vAgAAAJggRR8AAACACTpl0aeqLqyqO6rq/qq6r6p+esPyN1RVV9XB4XlV1W9V1UNV9S9V9YKzFTwsylZ5XlWHq+p4Vd0zPF4+t80bhzx/sKq+a/+ih53Zbjyvqp+qqgeG+dfOzZfnjMo24/lNc2P5w1V1z9w28pxR2SbPL6mq9w55fqSqXjjMd3zO6GyT58+vqn+qqmNV9ddV9SVz2xjPGZWq+sKququq7h3y/M3D/Iuq6n1DPt9UVU8d5n/B8PyhYfnaqV7jwA7ieCLJG7r77qo6L8nRqrq9u++vqguTvDTJv8+t/7Ikzxke35Tkd4d/YZltmufDsrd193XzK1fV1ya5Ksnzknxlkr+tqou7+7N7GjWcnq3y/MuTXJHk+d19oqqemchzRmur45ZXrq9QVW9N8tgwLc8Zo63G82uTvLm7bxu+qLo2yUvi+Jxx2irP/yDJz3X3nVX16iQ/n+SXjOeM1Ikkl3f341V1bpJ/rKrbkvxsZp9Db6yqtyd5TWZj92uS/Fd3f3VVXZXkLUleuVXjyQ7O9OnuR7r77mH6U0k+kORZw+K3JfmFJPN3g74iyR/1zHuTPL2qLtj5PsPeO0Web+aKJDd294nu/rckDyV54dmPFM7cNnn+2iS/1t0nhmWfGDaR54zOqcbzqqokP5jkz4ZZ8pzR2SbPO8n6WQ9PS/LRYdrxOaOzTZ5fnOTvh9VuT/L9w7TxnNEZxuXHh6fnDo9OcnmSvxjm35Dke4fpK4bnGZZ/+3Bss6XTuqfPcOrQNyR5X1VdkeR4d9+7YbVnJfnw3POPZPsPz7BU5vN8mPWTw6nQ11fVlw7z5DmjtiHPL07y4uEU0Tur6huH1eQ5o7bJeJ4kL07y8e7+1+G5PGfUNuT5zyT59ar6cJLrkrxxWE2eM2ob8vy+zD74JskPJLlwmJbnjFJVnTNcdv6JzAqZH0zyye5+YlhlPpc/l+fD8seSPGO79ndc9KmqL07yzsz+M3kiyZuS/PJOt4cxmM/z7v7vzE6he3aSS5I8kuSt+xcdLMYmeX4gyZcleVFmp0jffKpvDGDZbZLn616Vk2f5wKhtkuevTfL67r4wyeuTvGM/44NF2CTPX53kJ6rqaJLzknx6P+OD3eruz3b3JUm+KrOz075mke3vqOgzXFv2ziR/2t23ZPYh+KIk91bVw0Nwd1fVVyQ5npPV1gzLji8yaDgbNsnzdPfHhzfhk0l+PydPEZXnjNJmeZ7Ztwe3DKeX3pXkySQHI88ZqS3yPFV1IMkrktw0t7o8Z5S2yPOrk6xP/3kctzByWxyfP9DdL+3uSzMr4n9wWF2eM2rd/ckkdyS5LLPLcNfvwTyfy5/L82H505L8x3bt7uTXuyqzbwk+0N2/MQRzrLuf2d1r3b2W2QeGF3T3x5LcmuSHh18JeFGSx7r7kdPZWdhrm+X5MH/+evfvS/L+YfrWJFcNd0+/KLMbI961V/HCmdgqz5P8ZZJvG9a5OMlTkzwaec4IbZPnSfIdSR7o7o/MzZPnjM42ef7RJN86TF+eZP0yRsfnjM42x+frPzjxlCS/mOTtwyLjOaNTVedX1dOH6S9K8p2Z3b/qjiRXDqtdneSvhulbh+cZlv9dd8/fY/nz7OTXu74lyQ8lOVYnf970Td397i3Wf3eSl2d246z/SfIjO3gN2G+b5nmSV1XVJZndTOvhJD+eJN19X1XdnOT+zC53fJ1fBmAEtsrz65NcX1Xvz+wU6auH/zzkOWO03XHLVdlwaZfxnJHaajz/0SS/OXz7+39JfmxY5vicMdoqz59TVa8bnt+S5A8T4zmjdUGSG6rqnMxOyrm5u99VVfcnubGqfiXJP+fk5brvSPLHVfVQkv/M7NhmW3WKohAAAAAAI3Rav94FAAAAwDgo+gAAAABMkKIPAAAAwAQp+gAAAABMkKIPAAAAwAQp+gAAo1VVz6iqe4bHx6rq+DD9eFX9zn7HBwCwn/xkOwAwCVV1OMnj3X3dfscCALAMnOkDAExOVb2kqt41TB+uqhuq6h+q6kNV9YqquraqjlXVe6rq3GG9S6vqzqo6WlV/U1UX7O9eAADsjqIPALAKnp3k8iTfk+RPktzR3V+f5H+TfPdQ+PntJFd296VJrk/yq/sVLADAIhzY7wAAAPbAbd39mao6luScJO8Z5h9LspbkuUm+LsntVZVhnUf2IU4AgIVR9AEAVsGJJOnuJ6vqM33ypoZPZnY8VEnu6+7L9itAAIBFc3kXAEDyYJLzq+qyJKmqc6vqefscEwDArij6AAArr7s/neTKJG+pqnuT3JPkm/c1KACAXfKT7QAAAAAT5EwfAAAAgAlS9AEAAACYIEUfAAAAgAlS9AEAAACYIEUfAAAAgAlS9AEAAACYIEUfAAAAgAn6f8GhC80slywjAAAAAElFTkSuQmCC", - "text/plain": [ - ", , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , ])>" - ] - }, - "execution_count": 77, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "expected_output" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "Looks decent! Let's perform a proper evaluation by computing the [detection error rate](https://pyannote.github.io/pyannote-metrics/reference.html#detection) over the whole AMI test set:" - ] - }, - { - "cell_type": "code", - "execution_count": 54, - "metadata": {}, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "Detection error rate = 7.3%\n" - ] - } - ], - "source": [ - "from pyannote.metrics.detection import DetectionErrorRate\n", - "metric = DetectionErrorRate()\n", - "\n", - "for file in ami.test():\n", - " \n", - " # apply the voice activity detection pipeline\n", - " speech = pipeline(file)\n", - "\n", - " # evaluate its output\n", - " _ = metric(\n", - " file['annotation'], # this is the reference annotation\n", - " speech, # this is the hypothesized annotation\n", - " uem=file['annotated']) # this is the part of the file that should be evaluated\n", - " \n", - "# aggregate the performance over the whole test set\n", - "detection_error_rate = abs(metric)\n", - "print(f'Detection error rate = {detection_error_rate * 100:.1f}%')" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "## Optimizing pipeline hyper-parameters" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "While good enough, the hyper-parameters that we chose manually, we can try to optimize `onset` and `offset` on the development (a.k.a. validation) set to get better performance (and freeze the other two hyper-parameters)." - ] - }, - { - "cell_type": "code", - "execution_count": 60, - "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": [ - "" - ] - }, - "execution_count": 60, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "pipeline.freeze({'min_duration_on': 0.0, 'min_duration_off': 0.0})" - ] - }, - { - "cell_type": "code", - "execution_count": 63, - "metadata": {}, - "outputs": [], - "source": [ - "from pyannote.pipeline import Optimizer\n", - "\n", - "optimizer = Optimizer(pipeline)\n", - "optimizer.tune(list(ami.development()), \n", - " warm_start=initial_params, \n", - " n_iterations=20, \n", - " show_progress=False)\n", - "\n", - "optimized_params = optimizer.best_params" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "There you go: better hyper-parameters that (should) lead to better results!" - ] - }, - { - "cell_type": "code", - "execution_count": 78, - "metadata": {}, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "{'onset': 0.8020095763639215, 'offset': 0.5643079355945013, 'min_duration_on': 0.0, 'min_duration_off': 0.0}\n" - ] - } - ], - "source": [ - "print(optimized_params)" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "Let's evaluate the voice activity detection pipeline with this new set of hyper-parameters:" - ] - }, - { - "cell_type": "code", - "execution_count": 79, - "metadata": {}, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "Detection error rate = 6.9%\n" - ] - } - ], - "source": [ - "optimized_pipeline = pipeline.instantiate(optimized_params)\n", - "\n", - "metric = DetectionErrorRate()\n", - "\n", - "for file in ami.test():\n", - " speech = optimized_pipeline(file)\n", - " _ = metric(file['annotation'], speech, uem=file['annotated'])\n", - " \n", - "detection_error_rate = abs(metric)\n", - "print(f'Detection error rate = {detection_error_rate * 100:.1f}%')" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "🎉 Yeay! 5% relativement improvement simply by tuning the thresholds." - ] - } - ], - "metadata": { - "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.7.3" - } - }, - "nbformat": 4, - "nbformat_minor": 4 -} +{"cells":[{"cell_type":"markdown","metadata":{"id":"3M4zoYI4Q-Xi"},"source":["\"Open"]},{"cell_type":"markdown","metadata":{"id":"fEew3B3-Q-Xl"},"source":["# Training a voice activity detection pipeline from scratch with `pyannote.audio`\n","\n","Voice activity detection (VAD) is the task of detecting speech regions in a given audio stream or recording. \n","In this tutorial, you will learn how to train and evaluate a VAD pipeline from scratch."]},{"cell_type":"markdown","metadata":{"id":"1F6PKPftQ-Xm"},"source":["## Tutorial setup"]},{"cell_type":"markdown","metadata":{"id":"ErPKDILdQ-Xn"},"source":["### `Google Colab` setup"]},{"cell_type":"markdown","metadata":{"id":"SYU2JJ9-Q-Xo"},"source":["If you are running this tutorial on `Colab`, execute the following commands in order to setup `Colab` environment. These commands will install `pyannote.audio` and download a mini version of the `AMI` corpus."]},{"cell_type":"code","execution_count":null,"metadata":{"colab":{"base_uri":"https://localhost:8080/"},"executionInfo":{"elapsed":1772401,"status":"ok","timestamp":1704890790335,"user":{"displayName":"Clément PAGES","userId":"11757386314069785178"},"user_tz":-60},"id":"EMspGag4Q-Xp","outputId":"0aaf740d-96c8-4340-a9e7-5c529f12fe9b"},"outputs":[],"source":["!pip install -qq pyannote.audio==3.1.1\n","!pip install -qq ipython==7.34.0\n","!git clone https://github.com/pyannote/AMI-diarization-setup.git\n","%cd ./AMI-diarization-setup/pyannote/\n","!bash ./download_ami_mini.sh\n","%cd /content"]},{"cell_type":"markdown","metadata":{"id":"TFqu_5vyQ-Xq"},"source":["⚠ Restart the runtime (Runtime > Restart session)."]},{"cell_type":"markdown","metadata":{"id":"7_7eodg5Q-Xr"},"source":["### Non `Google Colab` setup"]},{"cell_type":"markdown","metadata":{"id":"WCy8p55QQ-Xr"},"source":["If you are not using `Colab`, this tutorial assumes that\n","* `pyannote.audio` has been installed\n","* the [AMI corpus](https://groups.inf.ed.ac.uk/ami/corpus/) has already been [setup for use with `pyannote`](https://github.com/pyannote/AMI-diarization-setup/tree/main/pyannote)"]},{"cell_type":"markdown","metadata":{"id":"M-oe_8FFQ-Xu"},"source":["## Data preparation\n","\n","See [`pyannote.database` documentation](https://github.com/pyannote/pyannote-database#pyannote-database) to learn how to prepare your own dataset for training with `pyannote.audio`."]},{"cell_type":"code","execution_count":null,"metadata":{"id":"KBstX_2sQ-Xu"},"outputs":[],"source":["from pyannote.database import registry, FileFinder\n","\n","registry.load_database(\"AMI-diarization-setup/pyannote/database.yml\")\n","preprocessors = {\"audio\": FileFinder()}\n","ami = registry.get_protocol('AMI.SpeakerDiarization.mini',\n"," preprocessors=preprocessors)"]},{"cell_type":"markdown","metadata":{"id":"oYIKQ5kwQ-Xv"},"source":["`pyannote.database` *protocols* usually define\n","* a training set: `for training_file in protocol.train(): ...`,\n","* a validation set: `for validation_file in protocol.development(): ...`\n","* an evaluation set `for evaluation_file in protocol.test(): ...`"]},{"cell_type":"markdown","metadata":{"id":"siLd6sE3Q-Xw"},"source":["Let's listen to one minute of the first training file..."]},{"cell_type":"code","execution_count":2,"metadata":{"executionInfo":{"elapsed":212,"status":"ok","timestamp":1704890828290,"user":{"displayName":"Clément PAGES","userId":"11757386314069785178"},"user_tz":-60},"id":"bai4OplyQ-Xw"},"outputs":[],"source":["first_training_file = next(ami.train())\n","reference = first_training_file[\"annotation\"]"]},{"cell_type":"code","execution_count":null,"metadata":{"colab":{"base_uri":"https://localhost:8080/","height":151,"output_embedded_package_id":"1GxUBhwcdeeXdLogFqdzXqSDl6FNpaR2t"},"executionInfo":{"elapsed":7227,"status":"ok","timestamp":1704890839349,"user":{"displayName":"Clément PAGES","userId":"11757386314069785178"},"user_tz":-60},"id":"5t2l6o3NQ-Xx","outputId":"9755f212-b8ca-45ad-e1a2-60f00665d7be"},"outputs":[],"source":["from pyannote.audio.utils.preview import listen\n","from pyannote.core import Segment\n","\n","one_minute = Segment(240, 300)\n","listen(first_training_file, one_minute)"]},{"cell_type":"markdown","metadata":{"id":"Z3-VQas0Q-Xy"},"source":["... and visualize the manual annotation:"]},{"cell_type":"code","execution_count":4,"metadata":{"colab":{"base_uri":"https://localhost:8080/","height":239},"executionInfo":{"elapsed":592,"status":"ok","timestamp":1704890847735,"user":{"displayName":"Clément PAGES","userId":"11757386314069785178"},"user_tz":-60},"id":"8fNi_I0pQ-Xz","outputId":"83cfee16-8a4e-4528-8a60-d5b8c0990fc7"},"outputs":[{"data":{"image/png":"iVBORw0KGgoAAAANSUhEUgAABjwAAADyCAYAAAD5q2z1AAAAOXRFWHRTb2Z0d2FyZQBNYXRwbG90bGliIHZlcnNpb24zLjcuMSwgaHR0cHM6Ly9tYXRwbG90bGliLm9yZy/bCgiHAAAACXBIWXMAAA9hAAAPYQGoP6dpAAAj0klEQVR4nO3deZRcZZ0H/G91dtLpzp4GSSAQDFGIBmYONiqymYRBBeHIyE7CYTOohBkUDkvUdwYYxhHwZXGOBgQBYVBR1EkkkoAsAUOGsBtIWN8xCxDSgQSy3vcPTmpsSSBLd7pv+/mcU+d03fvc5z63btWvbtW3695KURRFAAAAAAAASqymrQcAAAAAAACwtQQeAAAAAABA6Qk8AAAAAACA0hN4AAAAAAAApSfwAAAAAAAASk/gAQAAAAAAlJ7AAwAAAAAAKD2BBwAAAAAAUHoCDwAAAAAAoPQEHgAAAAAAQOkJPAAAAAAAgNITeAAAAAAAAKUn8AAAAAAAAEpP4AEAAAAAAJSewAMAAAAAACg9gQcAAAAAAFB6Ao8NOOmkk1KpVN5zmzdvXk466aQcfvjhH9h27Nix1TbvvPNOJkyYkH79+qW2tjZHHnlkFi1a1Gyds2bNykEHHZTevXunT58+GTNmTB577LFmfZx00knZc88907lz52ZjYMPW75vTTz/9PfMmTJiQSqWSk046qdr2rx/TV155JePHj88OO+yQrl27ZqeddsrXv/71vP76683aFUWRiy66KNtvv3169OiRgw8+OM8991yzNjvvvPN7niOXXnppszaPP/54Pv3pT6d79+4ZPHhwLrvssq1/EDqw9rR/n3322Rx22GHp379/6urq8qlPfSozZsyozn/sscdy9NFHZ/DgwenRo0dGjBiRK6+8smUeCAAAAAAgSdK5LVb6xvJV22xdfXp23aLlxo4dm+uvv77ZtAEDBmxy227dulX/njhxYn7729/m9ttvT319fc4888wcccQReeCBB5Ikb731VsaOHZsvfOELueaaa7JmzZpMmjQpY8aMySuvvJIuXbpk7dq16dGjR772ta/l5z//+RZtU0trWtm0zdZV361+i5YbPHhwbr311lx++eXp0aNHknfDo1tuuSVDhgzZ6HLPP/98Ghsb8+EPfzg//elPM3To0Dz11FM555xzMmXKlDz00EPp27dvkuSyyy7L97///dxwww0ZOnRoLrzwwowZMyZPP/10unfvXu3zO9/5Tk455ZTq/V69elX/XrZsWUaPHp2DDz44P/jBD/LEE09k/Pjx6d27d0499dQt2vatsfavvvRvbZ369dui5drL/v3c5z6X3XbbLdOnT0+PHj1yxRVX5HOf+1zmz5+fhoaGzJ49OwMHDsxNN92UwYMH58EHH8ypp56aTp065cwzz9yibQcAAAAAmmuTwOOQy2Z8cKMW8tC3x2zRct26dUtDQ8NWt21qasrkyZNzyy235MADD0ySXH/99RkxYkQeeuihfOITn8if/vSnLFmyJN/5zncyePDgJMmkSZMycuTIvPTSSxk2bFh69uyZa6+9NknywAMPZOnSpVu0XS3p+CnHbLN13Xn4b7doub322ivz58/PL37xixx77LFJkl/84hcZMmRIhg4dutHlJkyYkK5du+auu+6qfpE+ZMiQjBo1KrvuumvOP//8XHvttSmKIldccUUuuOCCHHbYYUmSG2+8MYMGDcovf/nLfPnLX6722atXr40+T26++easWrUq1113Xbp27ZqPfvSjmTNnTr73ve+1SeCxcOTHt+n6PvS/r2zRcu1h/7722mt57rnnMnny5IwcOTJJcumll+aaa67Jk08+mYaGhowfP77Z+nfZZZfMnDkzv/jFLwQeAAAAANBCnNKqlc2ePTurV6/OwQcfXJ22++67Z8iQIZk5c2aSZPjw4enXr18mT56cVatW5e23387kyZMzYsSI7Lzzzm008o5j/PjxzX6Bc91112XcuHEbbb9kyZL87ne/y1e+8pXql+HrNTQ05Nhjj81tt92WoijywgsvZOHChc32b319ffbZZ5/q/l3v0ksvTb9+/TJq1Kj8+7//e9asWVOdN3PmzOy3337p2vX/fpE0ZsyYzJ07N2+88cYWb/vfgrbev/369cvw4cNz4403Zvny5VmzZk3+8z//MwMHDszee++90XE0NTVVf0UCAAAAAGw9gcdG/OY3v0ltbW319qUvfWmT29bW1ubiiy9OkixcuDBdu3ZN7969my0zaNCgLFy4MMm7//l/zz335KabbkqPHj1SW1ubqVOnZsqUKencuU1+hNOhHHfccbn//vvz0ksv5aWXXsoDDzyQ4447bqPtn3vuuRRFkREjRmxw/ogRI/LGG2/k1Vdfre7DQYMGNWvzl/s3Sb72ta/l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XCQp7r333mbTH3300eJDH/pQsWDBgiJJcccdd1Tn/fd//3dRU1NTLFy4sDrt2muvLerq6oqVK1duzXCANrChOvCZz3ym+PrXv77RZdQB6Hg2VAv22Wef4oILLtjoMk8//XSRpJg1a1Z12pQpU4pKpVL87//+b6uOF2h5G/ts8Jc+/vGPF+PHj6/ed0wAHcuG6kDPnj2LG2+8sVm7vn37Fj/84Q+LonA8AB3RX9eC3/3ud0VNTU3R1NRUbbN06dKiUqkU06ZNK4pCLYCOqE+fPsWPfvSjYunSpUWXLl2K22+/vTrvmWeeKZIUM2fOLIqiZT8XbNU1PJqampIkffv2rU5bsWJFjjnmmFx99dVpaGh4zzIzZ87MnnvumUGDBlWnjRkzJsuWLasmPkB5bKgOJMnNN9+c/v37Z4899sh5552XFStWVOepA9Dx/HUtWLx4cR5++OEMHDgw++67bwYNGpTPfOYzuf/++6vLzJw5M717987f/d3fVacdfPDBqampycMPP7xtNwDYahs7Jlhv9uzZmTNnTk4++eTqNMcE0LFsqA7su+++ue2227JkyZKsW7cut956a955553sv//+SRwPQEf017Vg5cqVqVQq6datW7VN9+7dU1NTU/18oBZAx7F27drceuutWb58eRobGzN79uysXr06Bx98cLXN7rvvniFDhmTmzJlJWvZzwRYHHuvWrctZZ52VT37yk9ljjz2q0ydOnJh99903hx122AaXW7hwYbOBJ6neX7hw4ZYOB2gDG6sDxxxzTG666abMmDEj5513Xn7yk5/kuOOOq85XB6Bj2VAteP7555Mk3/rWt3LKKadk6tSp2WuvvXLQQQflueeeS/Lu633gwIHN+urcuXP69u2rFkDJbOyY4C9Nnjw5I0aMyL777lud5pgAOo6N1YH/+q//yurVq9OvX79069Ytp512Wu64444MGzYsieMB6Gg2VAs+8YlPpGfPnvnmN7+ZFStWZPny5fnnf/7nrF27NgsWLEiiFkBH8MQTT6S2tjbdunXL6aefnjvuuCMf+chHsnDhwnTt2jW9e/du1n7QoEHV13dLfi7ovKUbMGHChDz55JPN/lPzzjvvzPTp05udixPouDZUB5I0O8fmnnvume233z4HHXRQ5s+fn1133XVbDxNoZRuqBevPxXvaaadl3LhxSZJRo0bl7rvvznXXXZdLLrmkTcYKtI6NHROs9/bbb+eWW27JhRdeuI1HBmwrG6sDF154YZYuXZrf//736d+/f375y1/mqKOOyn333Zc999yzjUYLtJYN1YIBAwbk9ttvzxlnnJHvf//7qampydFHH5299tqr2fX9gHIbPnx45syZk6ampvzsZz/LiSeemHvvvXebj2OLAo8zzzyzevGgHXfcsTp9+vTpmT9//nvSmiOPPDKf/vSnc88996ShoSF//OMfm81ff0X2DZ0CC2ifNlYHNmSfffZJksybNy+77rqrOgAdyMZqwfbbb58k+chHPtKs/YgRI/Lyyy8neff1vnjx4mbz16xZkyVLlqgFUCKbckzws5/9LCtWrMgJJ5zQbLpjAugYNlYH5s+fn6uuuipPPvlkPvrRjyZJPvaxj+W+++7L1VdfnR/84AeOB6ADeb9jgtGjR2f+/Pl57bXX0rlz5/Tu3TsNDQ3ZZZddkvhsAB1B165dq7/g3HvvvTNr1qxceeWV+cd//MesWrUqS5cubZYbLFq0qPr6bsnPBZsVoxZFkTPPPDN33HFHpk+fnqFDhzabf+655+bxxx/PnDlzqrckufzyy3P99dcnSRobG/PEE080K2LTpk1LXV3de74UAdqfD6oDG7K+Fqz/AlQdgPL7oFqw8847Z4cddsjcuXObTX/22Wez0047JXm3FixdujSzZ8+uzp8+fXrWrVtXDUqB9mtzjgkmT56cL3zhCxkwYECz6Y4JoNw+qA6sv47fX/8Hd6dOnaq/BnU8AOW3OccE/fv3T+/evTN9+vQsXrw4X/jCF5KoBdARrVu3LitXrszee++dLl265O67767Omzt3bl5++eU0NjYmaeHPBZtzhfMzzjijqK+vL+65555iwYIF1duKFSs2ukyS4o477qjeX7NmTbHHHnsUo0ePLubMmVNMnTq1GDBgQHHeeedt1tXWgbbxQXVg3rx5xXe+853ikUceKV544YXiV7/6VbHLLrsU++23X7UPdQDKb1OOCS6//PKirq6uuP3224vnnnuuuOCCC4ru3bsX8+bNq7YZO3ZsMWrUqOLhhx8u7r///mK33XYrjj766LbYJGAzbepng+eee66oVCrFlClT3tOHYwIotw+qA6tWrSqGDRtWfPrTny4efvjhYt68ecV3v/vdolKpFL/97W+r/TgegHLblGOC6667rpg5c2Yxb9684ic/+UnRt2/f4uyzz27Wj1oA5XXuuecW9957b/HCCy8Ujz/+eHHuuecWlUqluOuuu4qiKIrTTz+9GDJkSDF9+vTikUceKRobG4vGxsbq8i35uWCzAo8kG7xdf/3177vMXwYeRVEUL774YnHIIYcUPXr0KPr371/80z/9U7F69erNHjyw7X1QHXj55ZeL/fbbr+jbt2/RrVu3YtiwYcU555xTNDU1NetHHYBy29RjgksuuaTYcccdi+22265obGws7rvvvmbzX3/99eLoo48uamtri7q6umLcuHHFm2++uQ23BNhSm1oHzjvvvGLw4MHF2rVrN9iPYwIor02pA88++2xxxBFHFAMHDiy22267YuTIkcWNN97YrB/HA1Bum1ILvvnNbxaDBg0qunTpUuy2227Ff/zHfxTr1q1r1o9aAOU1fvz4Yqeddiq6du1aDBgwoDjooIOqYUdRFMXbb79dfOUrXyn69OlTbLfddsUXv/jFYsGCBc36aKnPBZWiKIrN+00IAAAAAABA+7JZ1/AAAAAAAABojwQeAAAAAABA6Qk8AAAAAACA0hN4AAAAAAAApSfwAAAAAAAASk/gAQAAAAAAlJ7AAwAAAAAAKD2BBwAAsNVOOumkHH744W09DAAA4G9Y57YeAAAA0L5VKpX3nT9p0qRceeWVKYpiG40IAADgvQQeAADA+1qwYEH179tuuy0XXXRR5s6dW51WW1ub2trathgaAABAlVNaAQAA76uhoaF6q6+vT6VSaTattrb2Pae02n///fPVr341Z511Vvr06ZNBgwblhz/8YZYvX55x48alV69eGTZsWKZMmdJsXU8++WQOOeSQ1NbWZtCgQTn++OPz2muvbeMtBgAAykjgAQAAtIobbrgh/fv3zx//+Md89atfzRlnnJEvfelL2XffffM///M/GT16dI4//visWLEiSbJ06dIceOCBGTVqVB555JFMnTo1ixYtylFHHdXGWwIAAJSBwAMAAGgVH/vYx3LBBRdkt912y3nnnZfu3bunf//+OeWUU7Lbbrvloosuyuuvv57HH388SXLVVVdl1KhRufjii7P77rtn1KhRue666zJjxow8++yzbbw1AABAe+caHgAAQKsYOXJk9e9OnTqlX79+2XPPPavTBg0alCRZvHhxkuSxxx7LjBkzNng9kPnz5+fDH/5wK48YAAAoM4EHAADQKrp06dLsfqVSaTatUqkkSdatW5ckeeutt/L5z38+//Zv//aevrbffvtWHCkAANARCDwAAIB2Ya+99srPf/7z7Lzzzunc2UcVAABg87iGBwAA0C5MmDAhS5YsydFHH51Zs2Zl/vz5+d3vfpdx48Zl7dq1bT08AACgnRN4AAAA7cIOO+yQBx54IGvXrs3o0aOz55575qyzzkrv3r1TU+OjCwAA8P4qRVEUbT0IAAAAAACAreHfpAAAAAAAgNITeAAAAAAAAKUn8AAAAAAAAEpP4AEAAAAAAJSewAMAAAAAACg9gQcAAAAAAFB6Ag8AAAAAAKD0BB4AAAAAAEDpCTwAAAAAAIDSE3gAAAAAAAClJ/AAAAAAAABKT+ABAAAAAACU3v8P0AeuqsBBxboAAAAASUVORK5CYII=","text/plain":[""]},"execution_count":4,"metadata":{},"output_type":"execute_result"}],"source":["from pyannote.core import notebook\n","notebook.crop = one_minute\n","reference"]},{"cell_type":"markdown","metadata":{"id":"fzbxnisZQ-Xz"},"source":["## Training"]},{"cell_type":"markdown","metadata":{"id":"C_QEjNxjQ-Xz"},"source":["We initialize a VAD *task* that describes how the model will be trained:\n","\n","* `ami` indicates that we will use files available in `ami.train()`.\n","* `duration=2.` and `batch_size=128` indicates that the model will ingest batches of 128 two seconds long audio chunks."]},{"cell_type":"code","execution_count":5,"metadata":{"colab":{"base_uri":"https://localhost:8080/"},"executionInfo":{"elapsed":543,"status":"ok","timestamp":1704890854558,"user":{"displayName":"Clément PAGES","userId":"11757386314069785178"},"user_tz":-60},"id":"oRkU-MboQ-Xz","outputId":"173a3d4b-fdf4-4e13-817d-dc024ac87524"},"outputs":[{"name":"stdout","output_type":"stream","text":["Protocol AMI.SpeakerDiarization.mini does not precompute the output of torchaudio.info(): adding a 'torchaudio.info' preprocessor for you to speed up dataloaders. See pyannote.database documentation on how to do that yourself.\n"]}],"source":["from pyannote.audio.tasks import VoiceActivityDetection\n","\n","vad = VoiceActivityDetection(ami, duration=2., batch_size=128)"]},{"cell_type":"markdown","metadata":{"id":"A7q9pnI4Q-X1"},"source":["We initialize one *model* with the `PyanNet` architecture used [in that paper](https://arxiv.org/abs/2104.04045). \n","In particular, we increase the default stride of the initial `sincnet` feature extraction layer to `10`.\n","\n","The model is also provided with the task (`task=vad`) for which it is being trained:"]},{"cell_type":"code","execution_count":6,"metadata":{"executionInfo":{"elapsed":241,"status":"ok","timestamp":1704890861715,"user":{"displayName":"Clément PAGES","userId":"11757386314069785178"},"user_tz":-60},"id":"dHJMJHB6Q-X1"},"outputs":[],"source":["from pyannote.audio.models.segmentation import PyanNet\n","\n","model = PyanNet(sincnet={'stride': 10}, task=vad)"]},{"cell_type":"markdown","metadata":{"id":"Rwh2ulN2Q-X2"},"source":["Now that everything is ready, let's train with `pytorch-ligthning`!"]},{"cell_type":"code","execution_count":7,"metadata":{"colab":{"base_uri":"https://localhost:8080/","height":414,"referenced_widgets":["de7bbc2d644e4ba79f3b4dcc26da3cb7","b62ef7013afe4da4a00ba0a70a63e938","b20cbf0c630a44f8b108d141e0b14ecc","4946ea8187904c7fa9f7c5de92a563e2","929954f82bc6407aaa6b069da848d1e3","53ac5430d2ef45ecaaecc3da0706825b","ffd1d20386d14e2f945f2d84df7a681f","69c34a612abb4d7a83bd796ef97d1c92","2ea0e51154e54129a6b164fc72588edc","910983c75b5247deb203ab218e05b25a","a1861066848a4efda4cc1f09beacb451","321302a76845477cbfd6b644071048b9","0300ea5285a94c7580c789849ea8b7e7","51dc1507c16e4fd88da6e9681b6f8443","84560e1a1a154cf7a4cc998aaa7db862","dce43bbd970643d99f8abbcb299925ec","f3bb471baf44445d9ea50d0adde041c1","14556644c3104b02850a07f172f1411a","50f8b2a4995242ac9d9961f34f2223ae","622cf364efe34719877311f1a46d24b4","ef09269769d845fb84ba39bd43a4ee0c","b827c08a92434a31b82d0382057ee82b","d5dbc90f387a4c9eb43789707505e617","3b55a90beb874204a44df7f231da55eb","8429d57eec2f4c9c8cda3900c0da5df5","d4f4fff579354b10b3cdb32cb11754fe","b886a9d46c7647f0aa5e04260a5b6e1e","5151fae07f114d4e86ee7ec4e487faae","4d2ea6328f684e6e888bc5710dea4340","290e8084737b4ff7a816f4b67fa8d411","bb89bf63ea124306acf411cbeaca2b90","e17799ed71e04167bd46363cf84cc93f","146c185d279d4583860ba4f9defda025"]},"executionInfo":{"elapsed":1454764,"status":"ok","timestamp":1704892319974,"user":{"displayName":"Clément PAGES","userId":"11757386314069785178"},"user_tz":-60},"id":"KkFsUEV_Q-X2","outputId":"3361c2b5-f341-41e1-e027-8fb9b7404d34"},"outputs":[{"name":"stderr","output_type":"stream","text":["INFO:pytorch_lightning.utilities.rank_zero:GPU available: True (cuda), used: True\n","INFO:pytorch_lightning.utilities.rank_zero:TPU available: False, using: 0 TPU cores\n","INFO:pytorch_lightning.utilities.rank_zero:IPU available: False, using: 0 IPUs\n","INFO:pytorch_lightning.utilities.rank_zero:HPU available: False, using: 0 HPUs\n","WARNING:pytorch_lightning.loggers.tensorboard:Missing logger folder: /content/lightning_logs\n","INFO:pytorch_lightning.accelerators.cuda:LOCAL_RANK: 0 - CUDA_VISIBLE_DEVICES: [0]\n","INFO:pytorch_lightning.callbacks.model_summary:\n"," | Name | Type | Params | In sizes | Out sizes \n","---------------------------------------------------------------------------------------------------------------------\n","0 | sincnet | SincNet | 42.6 K | [1, 1, 32000] | [1, 60, 115] \n","1 | lstm | LSTM | 589 K | [1, 115, 60] | [[1, 115, 256], [[4, 1, 128], [4, 1, 128]]]\n","2 | linear | ModuleList | 49.4 K | ? | ? \n","3 | classifier | Linear | 129 | [1, 115, 128] | [1, 115, 1] \n","4 | activation | Sigmoid | 0 | [1, 115, 1] | [1, 115, 1] \n","5 | validation_metric | MetricCollection | 0 | ? | ? \n","---------------------------------------------------------------------------------------------------------------------\n","681 K Trainable params\n","0 Non-trainable params\n","681 K Total params\n","2.728 Total estimated model params size (MB)\n"]},{"data":{"application/vnd.jupyter.widget-view+json":{"model_id":"de7bbc2d644e4ba79f3b4dcc26da3cb7","version_major":2,"version_minor":0},"text/plain":["Sanity Checking: | | 0/? [00:00"]},"execution_count":10,"metadata":{},"output_type":"execute_result"}],"source":["vad_probability"]},{"cell_type":"markdown","metadata":{"id":"Mscb9fDsQ-X6"},"source":["Perfect voice activity detection output should look like that:"]},{"cell_type":"code","execution_count":11,"metadata":{"colab":{"base_uri":"https://localhost:8080/","height":145},"executionInfo":{"elapsed":689,"status":"ok","timestamp":1704892633130,"user":{"displayName":"Clément PAGES","userId":"11757386314069785178"},"user_tz":-60},"id":"ObtOlbOTQ-X7","outputId":"8dd51edd-e56e-4ae1-e95c-5a592c1a106c"},"outputs":[{"data":{"image/png":"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dovSKgAAAAAAQAcSeAAAAAAAAJlXtMCjR48ecccdd0SPHj2K9RJAiVMHgAi1AFAHAHUA+JBaABS7DuRSSqkoLQMAAAAAAHQQX2kFAAAAAABknsADAAAAAADIPIEHAAAAAACQeQIPAAAAAAAg89oUeNx9993xla98JXr37h2DBg2KSy65JNatW9fssSmlmDhxYuRyuXjmmWea7Nu4cWNccMEF0bNnzxg0aFDcfPPN8cEHHxz2IICO05o6cM4550Qul2vymD59epNj1AHIttauCerq6uLcc8+NXr16RT6fj7POOit2795d2L9169a48sorI5/PR9++fePaa6+N9957ryOHAhymQ9WBN95446D1wIHH3LlzC8dZE0B2tWY9sGnTppgyZUoMHjw4evXqFePGjYunn366yTHWA5BtrakF9fX1cemll8bAgQMjn8/HpEmT4u23325yjFoA2fXAAw/EmDFjIp/PRz6fj+rq6pg/f35h//vvvx8zZsyI/v37R2VlZVx++eUH1YD2ui5oU+CxePHimDFjRvzzn/+MhQsXxr59+6KmpiZ27tx50LH/93//F7lc7qDt+/fvjwsuuCD27t0b//jHP+KRRx6J3/zmN3H77be3ufNAx2ttHZg2bVo0NDQUHj/72c8K+9QByL7W1IK6uro4//zzo6amJpYtWxbLly+PG264ISoqPlp+XHnllfHKK6/EwoUL409/+lP8/e9/j+985zudMSSgjQ5VB4YNG9ZkLdDQ0BB33XVXVFZWxsSJEyPCmgCyrjXrgauvvjrWrVsXzz77bKxZsyYuu+yymDRpUrz88suFY6wHINsOVQt27twZNTU1kcvlora2Nl566aXYu3dvXHjhhdHY2FhoRy2A7Bo6dGj85Cc/iZUrV8aKFSvi3HPPjYsvvjheeeWViIi46aab4o9//GPMnTs3Fi9eHG+99VZcdtllhee363VBOgKbN29OEZEWL17cZPvLL7+cPvvZz6aGhoYUEWnevHmFfX/5y19SRUVF2rRpU2HbAw88kPL5fNqzZ8+RdAfoBM3VgbPPPjt973vfa/E56gCUn+ZqwRlnnJFmz57d4nP+85//pIhIy5cvL2ybP39+yuVy6X//+19R+wu0v5auDT7uS1/6UrrmmmsKP1sTQHlprg706tUrPfroo02O69evX3rwwQdTStYDUI4+WQuee+65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","text/plain":[", , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , ])>"]},"execution_count":11,"metadata":{},"output_type":"execute_result"}],"source":["expected_output = test_file[\"annotation\"].get_timeline().support()\n","expected_output"]},{"cell_type":"markdown","metadata":{"id":"j0f1oMTUQ-X7"},"source":["## Pipeline"]},{"cell_type":"markdown","metadata":{"id":"QcRNQQ_VQ-X7"},"source":["Almost there! To obtain the final speech regions, we need to apply a detection threshold. \n","For that, we rely on the voice activity detection pipeline whose hyper-parameters are set manually:\n","- `onset=0.6`: mark region as `active` when probability goes above 0.6\n","- `offset=0.4`: switch back to `inactive` when probability goes below 0.4\n","- `min_duration_on=0.0`: remove `active` regions shorter than that many seconds\n","- `min_duration_off=0.0`: fill `inactive` regions shorter than that many seconds\n","\n","\n","More details about those hyper-parameters are provided in Figure 2 of [that paper](https://arxiv.org/abs/2104.04045)."]},{"cell_type":"code","execution_count":null,"metadata":{"colab":{"base_uri":"https://localhost:8080/"},"executionInfo":{"elapsed":589,"status":"ok","timestamp":1704892638091,"user":{"displayName":"Clément PAGES","userId":"11757386314069785178"},"user_tz":-60},"id":"TGkXstVpQ-X8","outputId":"d77d4cbe-98e9-4439-9c82-a51d0aeb4e25"},"outputs":[],"source":["from pyannote.audio.pipelines import VoiceActivityDetection as VoiceActivityDetectionPipeline\n","pipeline = VoiceActivityDetectionPipeline(segmentation=model)\n","initial_params = {\"onset\": 0.6, \"offset\": 0.4,\n"," \"min_duration_on\": 0.0, \"min_duration_off\": 0.0}\n","pipeline.instantiate(initial_params)"]},{"cell_type":"markdown","metadata":{"id":"thmmfIyjQ-X8"},"source":["Here we go:"]},{"cell_type":"code","execution_count":13,"metadata":{"colab":{"base_uri":"https://localhost:8080/","height":145},"executionInfo":{"elapsed":44782,"status":"ok","timestamp":1704892685345,"user":{"displayName":"Clément PAGES","userId":"11757386314069785178"},"user_tz":-60},"id":"lq9gPG2hQ-X9","outputId":"928eea8e-737c-4689-cdb7-262a71dd6b3f"},"outputs":[{"data":{"image/png":"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HLlcLp555pkW67Zu3RoXXnhh9OrVKwYNGhS33HJLvP/++x/7IIBjpy05MGHChMjlci1uM2bMaLGNHIBsa+ucoLa2NiZOnBi9e/eOfD4f48ePjz179hTW79y5M6666qrI5/PRr1+/uO666+Ldd989locCfExHyoHXX3/9kPnAwduCBQsK25kTQHa1ZT6wbdu2mDZtWgwePDh69+4dY8eOjaeffrrFNuYDkG1tyYK6urq47LLLYuDAgZHP52PKlCnx1ltvtdhGFkB23X///TF69OjI5/ORz+ejqqoqFi1aVFj/3nvvxaxZs2LAgAFRVlYWV1xxxSEZ0F7nBUdVeCxbtixmzZoVf//732PJkiWxf//+qK6ujt27dx+y7f/93/9FLpc7ZPmBAwfiwgsvjH379sXf/va3eOSRR+JXv/pV3H777Uc9eODYa2sOXH/99VFfX1+4/eQnPymskwOQfW3Jgtra2rjggguiuro6Vq5cGatWrYrZs2dHScl/px9XXXVVvPLKK7FkyZL4wx/+EH/961/jW9/6VmccEnCUjpQDlZWVLeYC9fX1cdddd0VZWVlMnjw5IswJIOvaMh+45pprYuPGjfHss8/G+vXr4/LLL48pU6bEyy+/XNjGfACy7UhZsHv37qiuro5cLhc1NTXx0ksvxb59++Kiiy6K5ubmwn5kAWTX0KFD40c/+lGsWbMmVq9eHRMnToxLLrkkXnnllYiIuPnmm+P3v/99LFiwIJYtWxZvvvlmXH755YX7t+t5QfoEtm/fniIiLVu2rMXyl19+OX36059O9fX1KSLSwoULC+v+9Kc/pZKSkrRt27bCsvvvvz/l8/m0d+/eTzIcoBO0lgPnnXde+s53vnPY+8gB6Hpay4JzzjknzZs377D3+de//pUiIq1ataqwbNGiRSmXy6X//Oc/HTpeoP0d7tzgf33hC19I1157beFncwLoWlrLgd69e6dHH320xXb9+/dPDzzwQErJfAC6og9nwXPPPZdKSkpSY2NjYZuGhoaUy+XSkiVLUkqyALqiE088Mf3yl79MDQ0NqWfPnmnBggWFda+++mqKiFRbW5tSat/zgk90DY/GxsaIiOjfv39hWVNTU1x55ZVx3333xeDBgw+5T21tbYwaNSoqKioKy7761a/Grl27Co0PkB2t5UBExK9//esoLy+PM888M+bOnRtNTU2F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","text/plain":[", , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , ])>"]},"execution_count":13,"metadata":{},"output_type":"execute_result"}],"source":["pipeline(test_file).get_timeline()"]},{"cell_type":"code","execution_count":14,"metadata":{"colab":{"base_uri":"https://localhost:8080/","height":145},"executionInfo":{"elapsed":237,"status":"ok","timestamp":1704892689100,"user":{"displayName":"Clément PAGES","userId":"11757386314069785178"},"user_tz":-60},"id":"EzQZg8VPQ-X9","outputId":"514406de-c097-4904-9b6f-a89cce4cfe89"},"outputs":[{"data":{"image/png":"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dovSKgAAAAAAQAcSeAAAAAAAAJlXtMCjR48ecccdd0SPHj2K9RJAiVMHgAi1AFAHAHUA+JBaABS7DuRSSqkoLQMAAAAAAHQQX2kFAAAAAABknsADAAAAAADIPIEHAAAAAACQeQIPAAAAAAAg89oUeNx9993xla98JXr37h2DBg2KSy65JNatW9fssSmlmDhxYuRyuXjmmWea7Nu4cWNccMEF0bNnzxg0aFDcfPPN8cEHHxz2IICO05o6cM4550Qul2vymD59epNj1AHIttauCerq6uLcc8+NXr16RT6fj7POOit2795d2L9169a48sorI5/PR9++fePaa6+N9957ryOHAhymQ9WBN95446D1wIHH3LlzC8dZE0B2tWY9sGnTppgyZUoMHjw4evXqFePGjYunn366yTHWA5BtrakF9fX1cemll8bAgQMjn8/HpEmT4u23325yjFoA2fXAAw/EmDFjIp/PRz6fj+rq6pg/f35h//vvvx8zZsyI/v37R2VlZVx++eUH1YD2ui5oU+CxePHimDFjRvzzn/+MhQsXxr59+6KmpiZ27tx50LH/93//F7lc7qDt+/fvjwsuuCD27t0b//jHP+KRRx6J3/zmN3H77be3ufNAx2ttHZg2bVo0NDQUHj/72c8K+9QByL7W1IK6uro4//zzo6amJpYtWxbLly+PG264ISoqPlp+XHnllfHKK6/EwoUL409/+lP8/e9/j+985zudMSSgjQ5VB4YNG9ZkLdDQ0BB33XVXVFZWxsSJEyPCmgCyrjXrgauvvjrWrVsXzz77bKxZsyYuu+yymDRpUrz88suFY6wHINsOVQt27twZNTU1kcvlora2Nl566aXYu3dvXHjhhdHY2FhoRy2A7Bo6dGj85Cc/iZUrV8aKFSvi3HPPjYsvvjheeeWViIi46aab4o9//GPMnTs3Fi9eHG+99VZcdtllhee363VBOgKbN29OEZEWL17cZPvLL7+cPvvZz6aGhoYUEWnevHmFfX/5y19SRUVF2rRpU2HbAw88kPL5fNqzZ8+RdAfoBM3VgbPPPjt973vfa/E56gCUn+ZqwRlnnJFmz57d4nP+85//pIhIy5cvL2ybP39+yuVy6X//+19R+wu0v5auDT7uS1/6UrrmmmsKP1sTQHlprg706tUrPfroo02O69evX3rwwQdTStYDUI4+WQuee+65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","text/plain":[", , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , ])>"]},"execution_count":14,"metadata":{},"output_type":"execute_result"}],"source":["expected_output"]},{"cell_type":"markdown","metadata":{"id":"L1FOF3CcQ-X-"},"source":["Looks decent! Let's perform a proper evaluation by computing the [detection error rate](https://pyannote.github.io/pyannote-metrics/reference.html#detection) over the whole AMI test set:"]},{"cell_type":"code","execution_count":15,"metadata":{"colab":{"base_uri":"https://localhost:8080/"},"executionInfo":{"elapsed":153804,"status":"ok","timestamp":1704892850039,"user":{"displayName":"Clément PAGES","userId":"11757386314069785178"},"user_tz":-60},"id":"6v44K7WxQ-X_","outputId":"ce83364e-147c-4d7d-ee07-69fb49d6ca39"},"outputs":[{"name":"stdout","output_type":"stream","text":["Detection error rate = 12.4%\n"]}],"source":["from pyannote.metrics.detection import DetectionErrorRate\n","metric = DetectionErrorRate()\n","\n","for file in ami.test():\n","\n"," # apply the voice activity detection pipeline\n"," speech = pipeline(file)\n","\n"," # evaluate its output\n"," _ = metric(\n"," file['annotation'], # this is the reference annotation\n"," speech, # this is the hypothesized annotation\n"," uem=file['annotated']) # this is the part of the file that should be evaluated\n","\n","# aggregate the performance over the whole test set\n","detection_error_rate = abs(metric)\n","print(f'Detection error rate = {detection_error_rate * 100:.1f}%')"]},{"cell_type":"markdown","metadata":{"id":"CiADYH02Q-X_"},"source":["## Optimizing pipeline hyper-parameters"]},{"cell_type":"markdown","metadata":{"id":"Zik9XIQ1Q-YA"},"source":["While good enough, the hyper-parameters that we chose manually, we can try to optimize `onset` and `offset` on the development (a.k.a. validation) set to get better performance (and freeze the other two hyper-parameters)."]},{"cell_type":"code","execution_count":null,"metadata":{"colab":{"base_uri":"https://localhost:8080/"},"executionInfo":{"elapsed":219,"status":"ok","timestamp":1704893681462,"user":{"displayName":"Clément PAGES","userId":"11757386314069785178"},"user_tz":-60},"id":"pcQ8eJujQ-YA","outputId":"599cb846-c12f-4d6a-e5b6-c623fd9a583c"},"outputs":[],"source":["pipeline.freeze({'min_duration_on': 0.0, 'min_duration_off': 0.0})"]},{"cell_type":"code","execution_count":17,"metadata":{"executionInfo":{"elapsed":192449,"status":"ok","timestamp":1704893876383,"user":{"displayName":"Clément PAGES","userId":"11757386314069785178"},"user_tz":-60},"id":"xdClXgoMQ-YB"},"outputs":[],"source":["from pyannote.pipeline import Optimizer\n","\n","optimizer = Optimizer(pipeline)\n","optimizer.tune(list(ami.development()),\n"," warm_start=initial_params,\n"," n_iterations=20,\n"," show_progress=False)\n","\n","optimized_params = optimizer.best_params"]},{"cell_type":"markdown","metadata":{"id":"wVT0HjowQ-YB"},"source":["There you go: better hyper-parameters that (should) lead to better results!"]},{"cell_type":"code","execution_count":18,"metadata":{"colab":{"base_uri":"https://localhost:8080/"},"executionInfo":{"elapsed":219,"status":"ok","timestamp":1704893925876,"user":{"displayName":"Clément PAGES","userId":"11757386314069785178"},"user_tz":-60},"id":"IuUGrd8CQ-YB","outputId":"393d66bc-b04b-4265-bbdf-19c7ff04098e"},"outputs":[{"name":"stdout","output_type":"stream","text":["{'onset': 0.824238792126195, 'offset': 0.5375254799320842, 'min_duration_on': 0.0, 'min_duration_off': 0.0}\n"]}],"source":["print(optimized_params)"]},{"cell_type":"markdown","metadata":{"id":"3nQUzBigQ-YC"},"source":["Let's evaluate the voice activity detection pipeline with this new set of hyper-parameters:"]},{"cell_type":"code","execution_count":19,"metadata":{"colab":{"base_uri":"https://localhost:8080/"},"executionInfo":{"elapsed":155290,"status":"ok","timestamp":1704894084275,"user":{"displayName":"Clément PAGES","userId":"11757386314069785178"},"user_tz":-60},"id":"7A0sPO_4Q-YD","outputId":"5d28de05-fbbd-4c31-8cc7-62543c82a91d"},"outputs":[{"name":"stdout","output_type":"stream","text":["Detection error rate = 12.0%\n"]}],"source":["optimized_pipeline = pipeline.instantiate(optimized_params)\n","\n","metric = DetectionErrorRate()\n","\n","for file in ami.test():\n"," speech = optimized_pipeline(file)\n"," _ = metric(file['annotation'], speech, uem=file['annotated'])\n","\n","detection_error_rate = abs(metric)\n","print(f'Detection error rate = {detection_error_rate * 100:.1f}%')"]},{"cell_type":"markdown","metadata":{"id":"q6TiP03kQ-YD"},"source":["🎉 Yeay! We can see an improvement simply by adjusting the thresholds."]}],"metadata":{"accelerator":"GPU","colab":{"gpuType":"T4","provenance":[]},"kernelspec":{"display_name":"Python 3","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.10.13"},"widgets":{"application/vnd.jupyter.widget-state+json":{"0300ea5285a94c7580c789849ea8b7e7":{"model_module":"@jupyter-widgets/controls","model_module_version":"1.5.0","model_name":"HTMLModel","state":{"_dom_classes":[],"_model_module":"@jupyter-widgets/controls","_model_module_version":"1.5.0","_model_name":"HTMLModel","_view_count":null,"_view_module":"@jupyter-widgets/controls","_view_module_version":"1.5.0","_view_name":"HTMLView","description":"","description_tooltip":null,"layout":"IPY_MODEL_f3bb471baf44445d9ea50d0adde041c1","placeholder":"​","style":"IPY_MODEL_14556644c3104b02850a07f172f1411a","value":"Epoch 0: 100%"}},"14556644c3104b02850a07f172f1411a":{"model_module":"@jupyter-widgets/controls","model_module_version":"1.5.0","model_name":"DescriptionStyleModel","state":{"_model_module":"@jupyter-widgets/controls","_model_module_version":"1.5.0","_model_name":"DescriptionStyleModel","_view_count":null,"_view_module":"@jupyter-widgets/base","_view_module_version":"1.2.0","_view_name":"StyleView","description_width":""}},"146c185d279d4583860ba4f9defda025":{"model_module":"@jupyter-widgets/controls","model_module_version":"1.5.0","model_name":"DescriptionStyleModel","state":{"_model_module":"@jupyter-widgets/controls","_model_module_version":"1.5.0","_model_name":"DescriptionStyleModel","_view_count":null,"_view_module":"@jupyter-widgets/base","_view_module_version":"1.2.0","_view_name":"StyleView","description_width":""}},"290e8084737b4ff7a816f4b67fa8d411":{"model_module":"@jupyter-widgets/base","model_module_version":"1.2.0","model_name":"LayoutModel","state":{"_model_module":"@jupyter-widgets/base","_model_module_version":"1.2.0","_model_name":"LayoutModel","_view_count":null,"_view_module":"@jupyter-widgets/base","_view_module_version":"1.2.0","_view_name":"LayoutView","align_content":null,"align_items":null,"align_self":null,"border":null,"bottom":null,"display":null,"flex":"2","flex_flow":null,"grid_area":null,"grid_auto_columns":null,"grid_auto_flow":null,"grid_auto_rows":null,"grid_column":null,"grid_gap":null,"grid_row":null,"grid_template_areas":null,"grid_template_columns":null,"grid_template_rows":null,"height":null,"justify_content":null,"justify_items":null,"left":null,"margin":null,"max_height":null,"max_width":null,"min_height":null,"min_width":null,"object_fit":null,"object_position":null,"order":null,"overflow":null,"overflow_x":null,"overflow_y":null,"padding":null,"right":null,"top":null,"visibility":null,"width":null}},"2ea0e51154e54129a6b164fc72588edc":{"model_module":"@jupyter-widgets/controls","model_module_version":"1.5.0","model_name":"ProgressStyleModel","state":{"_model_module":"@jupyter-widgets/controls","_model_module_version":"1.5.0","_model_name":"ProgressStyleModel","_view_count":null,"_view_module":"@jupyter-widgets/base","_view_module_version":"1.2.0","_view_name":"StyleView","bar_color":null,"description_width":""}},"321302a76845477cbfd6b644071048b9":{"model_module":"@jupyter-widgets/controls","model_module_version":"1.5.0","model_name":"HBoxModel","state":{"_dom_classes":[],"_model_module":"@jupyter-widgets/controls","_model_module_version":"1.5.0","_model_name":"HBoxModel","_view_count":null,"_view_module":"@jupyter-widgets/controls","_view_module_version":"1.5.0","_view_name":"HBoxView","box_style":"","children":["IPY_MODEL_0300ea5285a94c7580c789849ea8b7e7","IPY_MODEL_51dc1507c16e4fd88da6e9681b6f8443","IPY_MODEL_84560e1a1a154cf7a4cc998aaa7db862"],"layout":"IPY_MODEL_dce43bbd970643d99f8abbcb299925ec"}},"3b55a90beb874204a44df7f231da55eb":{"model_module":"@jupyter-widgets/controls","model_module_version":"1.5.0","model_name":"HTMLModel","state":{"_dom_classes":[],"_model_module":"@jupyter-widgets/controls","_model_module_version":"1.5.0","_model_name":"HTMLModel","_view_count":null,"_view_module":"@jupyter-widgets/controls","_view_module_version":"1.5.0","_view_name":"HTMLView","description":"","description_tooltip":null,"layout":"IPY_MODEL_5151fae07f114d4e86ee7ec4e487faae","placeholder":"​","style":"IPY_MODEL_4d2ea6328f684e6e888bc5710dea4340","value":"Validation DataLoader 0: 100%"}},"4946ea8187904c7fa9f7c5de92a563e2":{"model_module":"@jupyter-widgets/controls","model_module_version":"1.5.0","model_name":"HTMLModel","state":{"_dom_classes":[],"_model_module":"@jupyter-widgets/controls","_model_module_version":"1.5.0","_model_name":"HTMLModel","_view_count":null,"_view_module":"@jupyter-widgets/controls","_view_module_version":"1.5.0","_view_name":"HTMLView","description":"","description_tooltip":null,"layout":"IPY_MODEL_910983c75b5247deb203ab218e05b25a","placeholder":"​","style":"IPY_MODEL_a1861066848a4efda4cc1f09beacb451","value":" 2/2 [00:08<00:00, 0.24it/s]"}},"4d2ea6328f684e6e888bc5710dea4340":{"model_module":"@jupyter-widgets/controls","model_module_version":"1.5.0","model_name":"DescriptionStyleModel","state":{"_model_module":"@jupyter-widgets/controls","_model_module_version":"1.5.0","_model_name":"DescriptionStyleModel","_view_count":null,"_view_module":"@jupyter-widgets/base","_view_module_version":"1.2.0","_view_name":"StyleView","description_width":""}},"50f8b2a4995242ac9d9961f34f2223ae":{"model_module":"@jupyter-widgets/base","model_module_version":"1.2.0","model_name":"LayoutModel","state":{"_model_module":"@jupyter-widgets/base","_model_module_version":"1.2.0","_model_name":"LayoutModel","_view_count":null,"_view_module":"@jupyter-widgets/base","_view_module_version":"1.2.0","_view_name":"LayoutView","align_content":null,"align_items":null,"align_self":null,"border":null,"bottom":null,"display":null,"flex":"2","flex_flow":null,"grid_area":null,"grid_auto_columns":null,"grid_auto_flow":null,"grid_auto_rows":null,"grid_column":null,"grid_gap":null,"grid_row":null,"grid_template_areas":null,"grid_template_columns":null,"grid_template_rows":null,"height":null,"justify_content":null,"justify_items":null,"left":null,"margin":null,"max_height":null,"max_width":null,"min_height":null,"min_width":null,"object_fit":null,"object_position":null,"order":null,"overflow":null,"overflow_x":null,"overflow_y":null,"padding":null,"right":null,"top":null,"visibility":null,"width":null}},"5151fae07f114d4e86ee7ec4e487faae":{"model_module":"@jupyter-widgets/base","model_module_version":"1.2.0","model_name":"LayoutModel","state":{"_model_module":"@jupyter-widgets/base","_model_module_version":"1.2.0","_model_name":"LayoutModel","_view_count":null,"_view_module":"@jupyter-widgets/base","_view_module_version":"1.2.0","_view_name":"LayoutView","align_content":null,"align_items":null,"align_self":null,"border":null,"bottom":null,"display":null,"flex":null,"flex_flow":null,"grid_area":null,"grid_auto_columns":null,"grid_auto_flow":null,"grid_auto_rows":null,"grid_column":null,"grid_gap":null,"grid_row":null,"grid_template_areas":null,"grid_template_columns":null,"grid_template_rows":null,"height":null,"justify_content":null,"justify_items":null,"left":null,"margin":null,"max_height":null,"max_width":null,"min_height":null,"min_width":null,"object_fit":null,"object_position":null,"order":null,"overflow":null,"overflow_x":null,"overflow_y":null,"padding":null,"right":null,"top":null,"visibility":null,"width":null}},"51dc1507c16e4fd88da6e9681b6f8443":{"model_module":"@jupyter-widgets/controls","model_module_version":"1.5.0","model_name":"FloatProgressModel","state":{"_dom_classes":[],"_model_module":"@jupyter-widgets/controls","_model_module_version":"1.5.0","_model_name":"FloatProgressModel","_view_count":null,"_view_module":"@jupyter-widgets/controls","_view_module_version":"1.5.0","_view_name":"ProgressView","bar_style":"success","description":"","description_tooltip":null,"layout":"IPY_MODEL_50f8b2a4995242ac9d9961f34f2223ae","max":136,"min":0,"orientation":"horizontal","style":"IPY_MODEL_622cf364efe34719877311f1a46d24b4","value":136}},"53ac5430d2ef45ecaaecc3da0706825b":{"model_module":"@jupyter-widgets/base","model_module_version":"1.2.0","model_name":"LayoutModel","state":{"_model_module":"@jupyter-widgets/base","_model_module_version":"1.2.0","_model_name":"LayoutModel","_view_count":null,"_view_module":"@jupyter-widgets/base","_view_module_version":"1.2.0","_view_name":"LayoutView","align_content":null,"align_items":null,"align_self":null,"border":null,"bottom":null,"display":null,"flex":null,"flex_flow":null,"grid_area":null,"grid_auto_columns":null,"grid_auto_flow":null,"grid_auto_rows":null,"grid_column":null,"grid_gap":null,"grid_row":null,"grid_template_areas":null,"grid_template_columns":null,"grid_template_rows":null,"height":null,"justify_content":null,"justify_items":null,"left":null,"margin":null,"max_height":null,"max_width":null,"min_height":null,"min_width":null,"object_fit":null,"object_position":null,"order":null,"overflow":null,"overflow_x":null,"overflow_y":null,"padding":null,"right":null,"top":null,"visibility":null,"width":null}},"622cf364efe34719877311f1a46d24b4":{"model_module":"@jupyter-widgets/controls","model_module_version":"1.5.0","model_name":"ProgressStyleModel","state":{"_model_module":"@jupyter-widgets/controls","_model_module_version":"1.5.0","_model_name":"ProgressStyleModel","_view_count":null,"_view_module":"@jupyter-widgets/base","_view_module_version":"1.2.0","_view_name":"StyleView","bar_color":null,"description_width":""}},"69c34a612abb4d7a83bd796ef97d1c92":{"model_module":"@jupyter-widgets/base","model_module_version":"1.2.0","model_name":"LayoutModel","state":{"_model_module":"@jupyter-widgets/base","_model_module_version":"1.2.0","_model_name":"LayoutModel","_view_count":null,"_view_module":"@jupyter-widgets/base","_view_module_version":"1.2.0","_view_name":"LayoutView","align_content":null,"align_items":null,"align_self":null,"border":null,"bottom":null,"display":null,"flex":"2","flex_flow":null,"grid_area":null,"grid_auto_columns":null,"grid_auto_flow":null,"grid_auto_rows":null,"grid_column":null,"grid_gap":null,"grid_row":null,"grid_template_areas":null,"grid_template_columns":null,"grid_template_rows":null,"height":null,"justify_content":null,"justify_items":null,"left":null,"margin":null,"max_height":null,"max_width":null,"min_height":null,"min_width":null,"object_fit":null,"object_position":null,"order":null,"overflow":null,"overflow_x":null,"overflow_y":null,"padding":null,"right":null,"top":null,"visibility":null,"width":null}},"8429d57eec2f4c9c8cda3900c0da5df5":{"model_module":"@jupyter-widgets/controls","model_module_version":"1.5.0","model_name":"FloatProgressModel","state":{"_dom_classes":[],"_model_module":"@jupyter-widgets/controls","_model_module_version":"1.5.0","_model_name":"FloatProgressModel","_view_count":null,"_view_module":"@jupyter-widgets/controls","_view_module_version":"1.5.0","_view_name":"ProgressView","bar_style":"","description":"","description_tooltip":null,"layout":"IPY_MODEL_290e8084737b4ff7a816f4b67fa8d411","max":14,"min":0,"orientation":"horizontal","style":"IPY_MODEL_bb89bf63ea124306acf411cbeaca2b90","value":14}},"84560e1a1a154cf7a4cc998aaa7db862":{"model_module":"@jupyter-widgets/controls","model_module_version":"1.5.0","model_name":"HTMLModel","state":{"_dom_classes":[],"_model_module":"@jupyter-widgets/controls","_model_module_version":"1.5.0","_model_name":"HTMLModel","_view_count":null,"_view_module":"@jupyter-widgets/controls","_view_module_version":"1.5.0","_view_name":"HTMLView","description":"","description_tooltip":null,"layout":"IPY_MODEL_ef09269769d845fb84ba39bd43a4ee0c","placeholder":"​","style":"IPY_MODEL_b827c08a92434a31b82d0382057ee82b","value":" 136/136 [23:47<00:00, 0.10it/s, v_num=0, BinaryAUROC=0.954]"}},"910983c75b5247deb203ab218e05b25a":{"model_module":"@jupyter-widgets/base","model_module_version":"1.2.0","model_name":"LayoutModel","state":{"_model_module":"@jupyter-widgets/base","_model_module_version":"1.2.0","_model_name":"LayoutModel","_view_count":null,"_view_module":"@jupyter-widgets/base","_view_module_version":"1.2.0","_view_name":"LayoutView","align_content":null,"align_items":null,"align_self":null,"border":null,"bottom":null,"display":null,"flex":null,"flex_flow":null,"grid_area":null,"grid_auto_columns":null,"grid_auto_flow":null,"grid_auto_rows":null,"grid_column":null,"grid_gap":null,"grid_row":null,"grid_template_areas":null,"grid_template_columns":null,"grid_template_rows":null,"height":null,"justify_content":null,"justify_items":null,"left":null,"margin":null,"max_height":null,"max_width":null,"min_height":null,"min_width":null,"object_fit":null,"object_position":null,"order":null,"overflow":null,"overflow_x":null,"overflow_y":null,"padding":null,"right":null,"top":null,"visibility":null,"width":null}},"929954f82bc6407aaa6b069da848d1e3":{"model_module":"@jupyter-widgets/base","model_module_version":"1.2.0","model_name":"LayoutModel","state":{"_model_module":"@jupyter-widgets/base","_model_module_version":"1.2.0","_model_name":"LayoutModel","_view_count":null,"_view_module":"@jupyter-widgets/base","_view_module_version":"1.2.0","_view_name":"LayoutView","align_content":null,"align_items":null,"align_self":null,"border":null,"bottom":null,"display":"inline-flex","flex":null,"flex_flow":"row wrap","grid_area":null,"grid_auto_columns":null,"grid_auto_flow":null,"grid_auto_rows":null,"grid_column":null,"grid_gap":null,"grid_row":null,"grid_template_areas":null,"grid_template_columns":null,"grid_template_rows":null,"height":null,"justify_content":null,"justify_items":null,"left":null,"margin":null,"max_height":null,"max_width":null,"min_height":null,"min_width":null,"object_fit":null,"object_position":null,"order":null,"overflow":null,"overflow_x":null,"overflow_y":null,"padding":null,"right":null,"top":null,"visibility":"hidden","width":"100%"}},"a1861066848a4efda4cc1f09beacb451":{"model_module":"@jupyter-widgets/controls","model_module_version":"1.5.0","model_name":"DescriptionStyleModel","state":{"_model_module":"@jupyter-widgets/controls","_model_module_version":"1.5.0","_model_name":"DescriptionStyleModel","_view_count":null,"_view_module":"@jupyter-widgets/base","_view_module_version":"1.2.0","_view_name":"StyleView","description_width":""}},"b20cbf0c630a44f8b108d141e0b14ecc":{"model_module":"@jupyter-widgets/controls","model_module_version":"1.5.0","model_name":"FloatProgressModel","state":{"_dom_classes":[],"_model_module":"@jupyter-widgets/controls","_model_module_version":"1.5.0","_model_name":"FloatProgressModel","_view_count":null,"_view_module":"@jupyter-widgets/controls","_view_module_version":"1.5.0","_view_name":"ProgressView","bar_style":"","description":"","description_tooltip":null,"layout":"IPY_MODEL_69c34a612abb4d7a83bd796ef97d1c92","max":2,"min":0,"orientation":"horizontal","style":"IPY_MODEL_2ea0e51154e54129a6b164fc72588edc","value":2}},"b62ef7013afe4da4a00ba0a70a63e938":{"model_module":"@jupyter-widgets/controls","model_module_version":"1.5.0","model_name":"HTMLModel","state":{"_dom_classes":[],"_model_module":"@jupyter-widgets/controls","_model_module_version":"1.5.0","_model_name":"HTMLModel","_view_count":null,"_view_module":"@jupyter-widgets/controls","_view_module_version":"1.5.0","_view_name":"HTMLView","description":"","description_tooltip":null,"layout":"IPY_MODEL_53ac5430d2ef45ecaaecc3da0706825b","placeholder":"​","style":"IPY_MODEL_ffd1d20386d14e2f945f2d84df7a681f","value":"Sanity Checking DataLoader 0: 100%"}},"b827c08a92434a31b82d0382057ee82b":{"model_module":"@jupyter-widgets/controls","model_module_version":"1.5.0","model_name":"DescriptionStyleModel","state":{"_model_module":"@jupyter-widgets/controls","_model_module_version":"1.5.0","_model_name":"DescriptionStyleModel","_view_count":null,"_view_module":"@jupyter-widgets/base","_view_module_version":"1.2.0","_view_name":"StyleView","description_width":""}},"b886a9d46c7647f0aa5e04260a5b6e1e":{"model_module":"@jupyter-widgets/base","model_module_version":"1.2.0","model_name":"LayoutModel","state":{"_model_module":"@jupyter-widgets/base","_model_module_version":"1.2.0","_model_name":"LayoutModel","_view_count":null,"_view_module":"@jupyter-widgets/base","_view_module_version":"1.2.0","_view_name":"LayoutView","align_content":null,"align_items":null,"align_self":null,"border":null,"bottom":null,"display":"inline-flex","flex":null,"flex_flow":"row wrap","grid_area":null,"grid_auto_columns":null,"grid_auto_flow":null,"grid_auto_rows":null,"grid_column":null,"grid_gap":null,"grid_row":null,"grid_template_areas":null,"grid_template_columns":null,"grid_template_rows":null,"height":null,"justify_content":null,"justify_items":null,"left":null,"margin":null,"max_height":null,"max_width":null,"min_height":null,"min_width":null,"object_fit":null,"object_position":null,"order":null,"overflow":null,"overflow_x":null,"overflow_y":null,"padding":null,"right":null,"top":null,"visibility":"hidden","width":"100%"}},"bb89bf63ea124306acf411cbeaca2b90":{"model_module":"@jupyter-widgets/controls","model_module_version":"1.5.0","model_name":"ProgressStyleModel","state":{"_model_module":"@jupyter-widgets/controls","_model_module_version":"1.5.0","_model_name":"ProgressStyleModel","_view_count":null,"_view_module":"@jupyter-widgets/base","_view_module_version":"1.2.0","_view_name":"StyleView","bar_color":null,"description_width":""}},"d4f4fff579354b10b3cdb32cb11754fe":{"model_module":"@jupyter-widgets/controls","model_module_version":"1.5.0","model_name":"HTMLModel","state":{"_dom_classes":[],"_model_module":"@jupyter-widgets/controls","_model_module_version":"1.5.0","_model_name":"HTMLModel","_view_count":null,"_view_module":"@jupyter-widgets/controls","_view_module_version":"1.5.0","_view_name":"HTMLView","description":"","description_tooltip":null,"layout":"IPY_MODEL_e17799ed71e04167bd46363cf84cc93f","placeholder":"​","style":"IPY_MODEL_146c185d279d4583860ba4f9defda025","value":" 14/14 [01:58<00:00, 0.12it/s]"}},"d5dbc90f387a4c9eb43789707505e617":{"model_module":"@jupyter-widgets/controls","model_module_version":"1.5.0","model_name":"HBoxModel","state":{"_dom_classes":[],"_model_module":"@jupyter-widgets/controls","_model_module_version":"1.5.0","_model_name":"HBoxModel","_view_count":null,"_view_module":"@jupyter-widgets/controls","_view_module_version":"1.5.0","_view_name":"HBoxView","box_style":"","children":["IPY_MODEL_3b55a90beb874204a44df7f231da55eb","IPY_MODEL_8429d57eec2f4c9c8cda3900c0da5df5","IPY_MODEL_d4f4fff579354b10b3cdb32cb11754fe"],"layout":"IPY_MODEL_b886a9d46c7647f0aa5e04260a5b6e1e"}},"dce43bbd970643d99f8abbcb299925ec":{"model_module":"@jupyter-widgets/base","model_module_version":"1.2.0","model_name":"LayoutModel","state":{"_model_module":"@jupyter-widgets/base","_model_module_version":"1.2.0","_model_name":"LayoutModel","_view_count":null,"_view_module":"@jupyter-widgets/base","_view_module_version":"1.2.0","_view_name":"LayoutView","align_content":null,"align_items":null,"align_self":null,"border":null,"bottom":null,"display":"inline-flex","flex":null,"flex_flow":"row wrap","grid_area":null,"grid_auto_columns":null,"grid_auto_flow":null,"grid_auto_rows":null,"grid_column":null,"grid_gap":null,"grid_row":null,"grid_template_areas":null,"grid_template_columns":null,"grid_template_rows":null,"height":null,"justify_content":null,"justify_items":null,"left":null,"margin":null,"max_height":null,"max_width":null,"min_height":null,"min_width":null,"object_fit":null,"object_position":null,"order":null,"overflow":null,"overflow_x":null,"overflow_y":null,"padding":null,"right":null,"top":null,"visibility":null,"width":"100%"}},"de7bbc2d644e4ba79f3b4dcc26da3cb7":{"model_module":"@jupyter-widgets/controls","model_module_version":"1.5.0","model_name":"HBoxModel","state":{"_dom_classes":[],"_model_module":"@jupyter-widgets/controls","_model_module_version":"1.5.0","_model_name":"HBoxModel","_view_count":null,"_view_module":"@jupyter-widgets/controls","_view_module_version":"1.5.0","_view_name":"HBoxView","box_style":"","children":["IPY_MODEL_b62ef7013afe4da4a00ba0a70a63e938","IPY_MODEL_b20cbf0c630a44f8b108d141e0b14ecc","IPY_MODEL_4946ea8187904c7fa9f7c5de92a563e2"],"layout":"IPY_MODEL_929954f82bc6407aaa6b069da848d1e3"}},"e17799ed71e04167bd46363cf84cc93f":{"model_module":"@jupyter-widgets/base","model_module_version":"1.2.0","model_name":"LayoutModel","state":{"_model_module":"@jupyter-widgets/base","_model_module_version":"1.2.0","_model_name":"LayoutModel","_view_count":null,"_view_module":"@jupyter-widgets/base","_view_module_version":"1.2.0","_view_name":"LayoutView","align_content":null,"align_items":null,"align_self":null,"border":null,"bottom":null,"display":null,"flex":null,"flex_flow":null,"grid_area":null,"grid_auto_columns":null,"grid_auto_flow":null,"grid_auto_rows":null,"grid_column":null,"grid_gap":null,"grid_row":null,"grid_template_areas":null,"grid_template_columns":null,"grid_template_rows":null,"height":null,"justify_content":null,"justify_items":null,"left":null,"margin":null,"max_height":null,"max_width":null,"min_height":null,"min_width":null,"object_fit":null,"object_position":null,"order":null,"overflow":null,"overflow_x":null,"overflow_y":null,"padding":null,"right":null,"top":null,"visibility":null,"width":null}},"ef09269769d845fb84ba39bd43a4ee0c":{"model_module":"@jupyter-widgets/base","model_module_version":"1.2.0","model_name":"LayoutModel","state":{"_model_module":"@jupyter-widgets/base","_model_module_version":"1.2.0","_model_name":"LayoutModel","_view_count":null,"_view_module":"@jupyter-widgets/base","_view_module_version":"1.2.0","_view_name":"LayoutView","align_content":null,"align_items":null,"align_self":null,"border":null,"bottom":null,"display":null,"flex":null,"flex_flow":null,"grid_area":null,"grid_auto_columns":null,"grid_auto_flow":null,"grid_auto_rows":null,"grid_column":null,"grid_gap":null,"grid_row":null,"grid_template_areas":null,"grid_template_columns":null,"grid_template_rows":null,"height":null,"justify_content":null,"justify_items":null,"left":null,"margin":null,"max_height":null,"max_width":null,"min_height":null,"min_width":null,"object_fit":null,"object_position":null,"order":null,"overflow":null,"overflow_x":null,"overflow_y":null,"padding":null,"right":null,"top":null,"visibility":null,"width":null}},"f3bb471baf44445d9ea50d0adde041c1":{"model_module":"@jupyter-widgets/base","model_module_version":"1.2.0","model_name":"LayoutModel","state":{"_model_module":"@jupyter-widgets/base","_model_module_version":"1.2.0","_model_name":"LayoutModel","_view_count":null,"_view_module":"@jupyter-widgets/base","_view_module_version":"1.2.0","_view_name":"LayoutView","align_content":null,"align_items":null,"align_self":null,"border":null,"bottom":null,"display":null,"flex":null,"flex_flow":null,"grid_area":null,"grid_auto_columns":null,"grid_auto_flow":null,"grid_auto_rows":null,"grid_column":null,"grid_gap":null,"grid_row":null,"grid_template_areas":null,"grid_template_columns":null,"grid_template_rows":null,"height":null,"justify_content":null,"justify_items":null,"left":null,"margin":null,"max_height":null,"max_width":null,"min_height":null,"min_width":null,"object_fit":null,"object_position":null,"order":null,"overflow":null,"overflow_x":null,"overflow_y":null,"padding":null,"right":null,"top":null,"visibility":null,"width":null}},"ffd1d20386d14e2f945f2d84df7a681f":{"model_module":"@jupyter-widgets/controls","model_module_version":"1.5.0","model_name":"DescriptionStyleModel","state":{"_model_module":"@jupyter-widgets/controls","_model_module_version":"1.5.0","_model_name":"DescriptionStyleModel","_view_count":null,"_view_module":"@jupyter-widgets/base","_view_module_version":"1.2.0","_view_name":"StyleView","description_width":""}}}}},"nbformat":4,"nbformat_minor":0} diff --git a/version.txt b/version.txt index 94ff29cc4..944880fa1 100644 --- a/version.txt +++ b/version.txt @@ -1 +1 @@ -3.1.1 +3.2.0