lfeats 0.2.1__tar.gz → 0.2.2__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- {lfeats-0.2.1 → lfeats-0.2.2}/PKG-INFO +24 -19
- {lfeats-0.2.1 → lfeats-0.2.2}/README.md +20 -16
- {lfeats-0.2.1 → lfeats-0.2.2}/lfeats/cli.py +14 -1
- {lfeats-0.2.1 → lfeats-0.2.2}/lfeats/interfaces/extractor.py +24 -0
- {lfeats-0.2.1 → lfeats-0.2.2}/lfeats/interfaces/types.py +20 -0
- {lfeats-0.2.1 → lfeats-0.2.2}/lfeats/models/__init__.py +5 -1
- {lfeats-0.2.1 → lfeats-0.2.2}/lfeats/models/base.py +1 -1
- {lfeats-0.2.1 → lfeats-0.2.2}/lfeats/models/higgs_audio.py +14 -2
- {lfeats-0.2.1 → lfeats-0.2.2}/lfeats/models/hubert.py +3 -5
- {lfeats-0.2.1 → lfeats-0.2.2}/lfeats/models/unispeech_sat.py +2 -2
- {lfeats-0.2.1 → lfeats-0.2.2}/lfeats/models/wavlm.py +2 -2
- lfeats-0.2.2/lfeats/models/wavlm_sv.py +120 -0
- {lfeats-0.2.1 → lfeats-0.2.2}/lfeats/models/whisper.py +2 -2
- lfeats-0.2.2/lfeats/models/x_codec.py +128 -0
- {lfeats-0.2.1 → lfeats-0.2.2}/lfeats/third_party/s3prl/util/download.py +10 -3
- {lfeats-0.2.1 → lfeats-0.2.2}/lfeats/utils/io.py +47 -31
- {lfeats-0.2.1 → lfeats-0.2.2}/lfeats/version.py +1 -1
- {lfeats-0.2.1 → lfeats-0.2.2}/pyproject.toml +3 -2
- {lfeats-0.2.1 → lfeats-0.2.2}/.gitignore +0 -0
- {lfeats-0.2.1 → lfeats-0.2.2}/LICENSE +0 -0
- {lfeats-0.2.1 → lfeats-0.2.2}/lfeats/__init__.py +0 -0
- {lfeats-0.2.1 → lfeats-0.2.2}/lfeats/interfaces/__init__.py +0 -0
- {lfeats-0.2.1 → lfeats-0.2.2}/lfeats/interfaces/resampler.py +0 -0
- {lfeats-0.2.1 → lfeats-0.2.2}/lfeats/interfaces/utils.py +0 -0
- {lfeats-0.2.1 → lfeats-0.2.2}/lfeats/models/contentvec.py +0 -0
- {lfeats-0.2.1 → lfeats-0.2.2}/lfeats/models/data2vec.py +0 -0
- {lfeats-0.2.1 → lfeats-0.2.2}/lfeats/models/data2vec2.py +0 -0
- {lfeats-0.2.1 → lfeats-0.2.2}/lfeats/models/ecapa_tdnn.py +0 -0
- {lfeats-0.2.1 → lfeats-0.2.2}/lfeats/models/emotion2vec.py +0 -0
- {lfeats-0.2.1 → lfeats-0.2.2}/lfeats/models/emotion2vec_plus.py +0 -0
- {lfeats-0.2.1 → lfeats-0.2.2}/lfeats/models/manager.py +0 -0
- {lfeats-0.2.1 → lfeats-0.2.2}/lfeats/models/next_tdnn.py +0 -0
- {lfeats-0.2.1 → lfeats-0.2.2}/lfeats/models/r_spin.py +0 -0
- {lfeats-0.2.1 → lfeats-0.2.2}/lfeats/models/r_vector.py +0 -0
- {lfeats-0.2.1 → lfeats-0.2.2}/lfeats/models/redimnet.py +0 -0
- {lfeats-0.2.1 → lfeats-0.2.2}/lfeats/models/spidr.py +0 -0
- {lfeats-0.2.1 → lfeats-0.2.2}/lfeats/models/spin.py +0 -0
- {lfeats-0.2.1 → lfeats-0.2.2}/lfeats/models/sslzip.py +0 -0
- {lfeats-0.2.1 → lfeats-0.2.2}/lfeats/models/wav2vec2.py +0 -0
- {lfeats-0.2.1 → lfeats-0.2.2}/lfeats/models/x_vector.py +0 -0
- {lfeats-0.2.1 → lfeats-0.2.2}/lfeats/resamplers/__init__.py +1 -1
- {lfeats-0.2.1 → lfeats-0.2.2}/lfeats/resamplers/base.py +0 -0
- {lfeats-0.2.1 → lfeats-0.2.2}/lfeats/resamplers/lilfilter.py +0 -0
- {lfeats-0.2.1 → lfeats-0.2.2}/lfeats/resamplers/manager.py +0 -0
- {lfeats-0.2.1 → lfeats-0.2.2}/lfeats/resamplers/scipy.py +0 -0
- {lfeats-0.2.1 → lfeats-0.2.2}/lfeats/resamplers/soxr.py +0 -0
- {lfeats-0.2.1 → lfeats-0.2.2}/lfeats/resamplers/torchaudio.py +0 -0
- {lfeats-0.2.1 → lfeats-0.2.2}/lfeats/third_party/__init__.py +0 -0
- {lfeats-0.2.1 → lfeats-0.2.2}/lfeats/third_party/fairseq/LICENSE +0 -0
- {lfeats-0.2.1 → lfeats-0.2.2}/lfeats/third_party/fairseq/__init__.py +0 -0
- {lfeats-0.2.1 → lfeats-0.2.2}/lfeats/third_party/fairseq/checkpoint_utils.py +0 -0
- {lfeats-0.2.1 → lfeats-0.2.2}/lfeats/third_party/fairseq/config/__init__.py +0 -0
- {lfeats-0.2.1 → lfeats-0.2.2}/lfeats/third_party/fairseq/config/config.yaml +0 -0
- {lfeats-0.2.1 → lfeats-0.2.2}/lfeats/third_party/fairseq/data/__init__.py +0 -0
- {lfeats-0.2.1 → lfeats-0.2.2}/lfeats/third_party/fairseq/data/dictionary.py +0 -0
- {lfeats-0.2.1 → lfeats-0.2.2}/lfeats/third_party/fairseq/data/modality.py +0 -0
- {lfeats-0.2.1 → lfeats-0.2.2}/lfeats/third_party/fairseq/data/text_compressor.py +0 -0
- {lfeats-0.2.1 → lfeats-0.2.2}/lfeats/third_party/fairseq/dataclass/__init__.py +0 -0
- {lfeats-0.2.1 → lfeats-0.2.2}/lfeats/third_party/fairseq/dataclass/configs.py +0 -0
- {lfeats-0.2.1 → lfeats-0.2.2}/lfeats/third_party/fairseq/dataclass/constants.py +0 -0
- {lfeats-0.2.1 → lfeats-0.2.2}/lfeats/third_party/fairseq/dataclass/initialize.py +0 -0
- {lfeats-0.2.1 → lfeats-0.2.2}/lfeats/third_party/fairseq/dataclass/utils.py +0 -0
- {lfeats-0.2.1 → lfeats-0.2.2}/lfeats/third_party/fairseq/file_io.py +0 -0
- {lfeats-0.2.1 → lfeats-0.2.2}/lfeats/third_party/fairseq/incremental_decoding_utils.py +0 -0
- {lfeats-0.2.1 → lfeats-0.2.2}/lfeats/third_party/fairseq/logging/__init__.py +0 -0
- {lfeats-0.2.1 → lfeats-0.2.2}/lfeats/third_party/fairseq/logging/meters.py +0 -0
- {lfeats-0.2.1 → lfeats-0.2.2}/lfeats/third_party/fairseq/models/__init__.py +0 -0
- {lfeats-0.2.1 → lfeats-0.2.2}/lfeats/third_party/fairseq/models/data2vec/__init__.py +0 -0
- {lfeats-0.2.1 → lfeats-0.2.2}/lfeats/third_party/fairseq/models/data2vec/data2vec2.py +0 -0
- {lfeats-0.2.1 → lfeats-0.2.2}/lfeats/third_party/fairseq/models/data2vec/data2vec_audio.py +0 -0
- {lfeats-0.2.1 → lfeats-0.2.2}/lfeats/third_party/fairseq/models/data2vec/modalities/__init__.py +0 -0
- {lfeats-0.2.1 → lfeats-0.2.2}/lfeats/third_party/fairseq/models/data2vec/modalities/audio.py +0 -0
- {lfeats-0.2.1 → lfeats-0.2.2}/lfeats/third_party/fairseq/models/data2vec/modalities/base.py +0 -0
- {lfeats-0.2.1 → lfeats-0.2.2}/lfeats/third_party/fairseq/models/data2vec/modalities/modules.py +0 -0
- {lfeats-0.2.1 → lfeats-0.2.2}/lfeats/third_party/fairseq/models/fairseq_decoder.py +0 -0
- {lfeats-0.2.1 → lfeats-0.2.2}/lfeats/third_party/fairseq/models/fairseq_encoder.py +0 -0
- {lfeats-0.2.1 → lfeats-0.2.2}/lfeats/third_party/fairseq/models/fairseq_incremental_decoder.py +0 -0
- {lfeats-0.2.1 → lfeats-0.2.2}/lfeats/third_party/fairseq/models/fairseq_model.py +0 -0
- {lfeats-0.2.1 → lfeats-0.2.2}/lfeats/third_party/fairseq/models/hubert/__init__.py +0 -0
- {lfeats-0.2.1 → lfeats-0.2.2}/lfeats/third_party/fairseq/models/hubert/hubert.py +0 -0
- {lfeats-0.2.1 → lfeats-0.2.2}/lfeats/third_party/fairseq/models/wav2vec/__init__.py +0 -0
- {lfeats-0.2.1 → lfeats-0.2.2}/lfeats/third_party/fairseq/models/wav2vec/utils.py +0 -0
- {lfeats-0.2.1 → lfeats-0.2.2}/lfeats/third_party/fairseq/models/wav2vec/wav2vec2.py +0 -0
- {lfeats-0.2.1 → lfeats-0.2.2}/lfeats/third_party/fairseq/modules/__init__.py +0 -0
- {lfeats-0.2.1 → lfeats-0.2.2}/lfeats/third_party/fairseq/modules/ema_module.py +0 -0
- {lfeats-0.2.1 → lfeats-0.2.2}/lfeats/third_party/fairseq/modules/fairseq_dropout.py +0 -0
- {lfeats-0.2.1 → lfeats-0.2.2}/lfeats/third_party/fairseq/modules/fp32_group_norm.py +0 -0
- {lfeats-0.2.1 → lfeats-0.2.2}/lfeats/third_party/fairseq/modules/gelu.py +0 -0
- {lfeats-0.2.1 → lfeats-0.2.2}/lfeats/third_party/fairseq/modules/gumbel_vector_quantizer.py +0 -0
- {lfeats-0.2.1 → lfeats-0.2.2}/lfeats/third_party/fairseq/modules/layer_norm.py +0 -0
- {lfeats-0.2.1 → lfeats-0.2.2}/lfeats/third_party/fairseq/modules/multihead_attention.py +0 -0
- {lfeats-0.2.1 → lfeats-0.2.2}/lfeats/third_party/fairseq/modules/quant_noise.py +0 -0
- {lfeats-0.2.1 → lfeats-0.2.2}/lfeats/third_party/fairseq/modules/same_pad.py +0 -0
- {lfeats-0.2.1 → lfeats-0.2.2}/lfeats/third_party/fairseq/modules/transpose_last.py +0 -0
- {lfeats-0.2.1 → lfeats-0.2.2}/lfeats/third_party/fairseq/quantization_utils.py +0 -0
- {lfeats-0.2.1 → lfeats-0.2.2}/lfeats/third_party/fairseq/registry.py +0 -0
- {lfeats-0.2.1 → lfeats-0.2.2}/lfeats/third_party/fairseq/tasks/__init__.py +0 -0
- {lfeats-0.2.1 → lfeats-0.2.2}/lfeats/third_party/fairseq/tasks/audio_pretraining.py +0 -0
- {lfeats-0.2.1 → lfeats-0.2.2}/lfeats/third_party/fairseq/tasks/fairseq_task.py +0 -0
- {lfeats-0.2.1 → lfeats-0.2.2}/lfeats/third_party/fairseq/tasks/hubert_pretraining.py +0 -0
- {lfeats-0.2.1 → lfeats-0.2.2}/lfeats/third_party/fairseq/tokenizer.py +0 -0
- {lfeats-0.2.1 → lfeats-0.2.2}/lfeats/third_party/fairseq/utils.py +0 -0
- {lfeats-0.2.1 → lfeats-0.2.2}/lfeats/third_party/next_tdnn_asv/LICENSE +0 -0
- {lfeats-0.2.1 → lfeats-0.2.2}/lfeats/third_party/next_tdnn_asv/SpeakerNet.py +0 -0
- {lfeats-0.2.1 → lfeats-0.2.2}/lfeats/third_party/next_tdnn_asv/__init__.py +0 -0
- {lfeats-0.2.1 → lfeats-0.2.2}/lfeats/third_party/next_tdnn_asv/aggregation/__init__.py +0 -0
- {lfeats-0.2.1 → lfeats-0.2.2}/lfeats/third_party/next_tdnn_asv/aggregation/vap_bn_tanh_fc_bn.py +0 -0
- {lfeats-0.2.1 → lfeats-0.2.2}/lfeats/third_party/next_tdnn_asv/configs/NeXt_TDNN_C256_B3_K65_7.py +0 -0
- {lfeats-0.2.1 → lfeats-0.2.2}/lfeats/third_party/next_tdnn_asv/configs/NeXt_TDNN_C256_B3_K65_7_cyclical_lr_step.py +0 -0
- {lfeats-0.2.1 → lfeats-0.2.2}/lfeats/third_party/next_tdnn_asv/configs/NeXt_TDNN_light_C256_B3_K65.py +0 -0
- {lfeats-0.2.1 → lfeats-0.2.2}/lfeats/third_party/next_tdnn_asv/configs/__init__.py +0 -0
- {lfeats-0.2.1 → lfeats-0.2.2}/lfeats/third_party/next_tdnn_asv/main.py +0 -0
- {lfeats-0.2.1 → lfeats-0.2.2}/lfeats/third_party/next_tdnn_asv/models/NeXt_TDNN.py +0 -0
- {lfeats-0.2.1 → lfeats-0.2.2}/lfeats/third_party/next_tdnn_asv/models/TSConvNeXt.py +0 -0
- {lfeats-0.2.1 → lfeats-0.2.2}/lfeats/third_party/next_tdnn_asv/models/TSConvNeXt_light.py +0 -0
- {lfeats-0.2.1 → lfeats-0.2.2}/lfeats/third_party/next_tdnn_asv/models/__init__.py +0 -0
- {lfeats-0.2.1 → lfeats-0.2.2}/lfeats/third_party/next_tdnn_asv/models/utils.py +0 -0
- {lfeats-0.2.1 → lfeats-0.2.2}/lfeats/third_party/next_tdnn_asv/preprocessing/__init__.py +0 -0
- {lfeats-0.2.1 → lfeats-0.2.2}/lfeats/third_party/next_tdnn_asv/preprocessing/mel_transform.py +0 -0
- {lfeats-0.2.1 → lfeats-0.2.2}/lfeats/third_party/rspin/LICENSE +0 -0
- {lfeats-0.2.1 → lfeats-0.2.2}/lfeats/third_party/rspin/__init__.py +0 -0
- {lfeats-0.2.1 → lfeats-0.2.2}/lfeats/third_party/rspin/model.py +0 -0
- {lfeats-0.2.1 → lfeats-0.2.2}/lfeats/third_party/rspin/wavlm_config.py +0 -0
- {lfeats-0.2.1 → lfeats-0.2.2}/lfeats/third_party/s3prl/LICENSE +0 -0
- {lfeats-0.2.1 → lfeats-0.2.2}/lfeats/third_party/s3prl/__init__.py +0 -0
- {lfeats-0.2.1 → lfeats-0.2.2}/lfeats/third_party/s3prl/upstream/__init__.py +0 -0
- {lfeats-0.2.1 → lfeats-0.2.2}/lfeats/third_party/s3prl/upstream/hubert/__init__.py +0 -0
- {lfeats-0.2.1 → lfeats-0.2.2}/lfeats/third_party/s3prl/upstream/hubert/convert.py +0 -0
- {lfeats-0.2.1 → lfeats-0.2.2}/lfeats/third_party/s3prl/upstream/hubert/hubert_model.py +0 -0
- {lfeats-0.2.1 → lfeats-0.2.2}/lfeats/third_party/s3prl/upstream/utils.py +0 -0
- {lfeats-0.2.1 → lfeats-0.2.2}/lfeats/third_party/s3prl/upstream/wav2vec2/__init__.py +0 -0
- {lfeats-0.2.1 → lfeats-0.2.2}/lfeats/third_party/s3prl/upstream/wav2vec2/wav2vec2_model.py +0 -0
- {lfeats-0.2.1 → lfeats-0.2.2}/lfeats/third_party/s3prl/upstream/wavlm/WavLM.py +0 -0
- {lfeats-0.2.1 → lfeats-0.2.2}/lfeats/third_party/s3prl/upstream/wavlm/__init__.py +0 -0
- {lfeats-0.2.1 → lfeats-0.2.2}/lfeats/third_party/s3prl/upstream/wavlm/modules.py +0 -0
- {lfeats-0.2.1 → lfeats-0.2.2}/lfeats/third_party/s3prl/util/__init__.py +0 -0
- {lfeats-0.2.1 → lfeats-0.2.2}/lfeats/third_party/speechbrain/LICENSE +0 -0
- {lfeats-0.2.1 → lfeats-0.2.2}/lfeats/third_party/speechbrain/__init__.py +0 -0
- {lfeats-0.2.1 → lfeats-0.2.2}/lfeats/third_party/speechbrain/dataio/__init__.py +0 -0
- {lfeats-0.2.1 → lfeats-0.2.2}/lfeats/third_party/speechbrain/dataio/dataio.py +0 -0
- {lfeats-0.2.1 → lfeats-0.2.2}/lfeats/third_party/speechbrain/dataio/encoder.py +0 -0
- {lfeats-0.2.1 → lfeats-0.2.2}/lfeats/third_party/speechbrain/dataio/preprocess.py +0 -0
- {lfeats-0.2.1 → lfeats-0.2.2}/lfeats/third_party/speechbrain/inference/__init__.py +0 -0
- {lfeats-0.2.1 → lfeats-0.2.2}/lfeats/third_party/speechbrain/inference/classifiers.py +0 -0
- {lfeats-0.2.1 → lfeats-0.2.2}/lfeats/third_party/speechbrain/inference/interfaces.py +0 -0
- {lfeats-0.2.1 → lfeats-0.2.2}/lfeats/third_party/speechbrain/lobes/__init__.py +0 -0
- {lfeats-0.2.1 → lfeats-0.2.2}/lfeats/third_party/speechbrain/lobes/features.py +0 -0
- {lfeats-0.2.1 → lfeats-0.2.2}/lfeats/third_party/speechbrain/lobes/models/ECAPA_TDNN.py +0 -0
- {lfeats-0.2.1 → lfeats-0.2.2}/lfeats/third_party/speechbrain/lobes/models/ResNet.py +0 -0
- {lfeats-0.2.1 → lfeats-0.2.2}/lfeats/third_party/speechbrain/lobes/models/Xvector.py +0 -0
- {lfeats-0.2.1 → lfeats-0.2.2}/lfeats/third_party/speechbrain/lobes/models/__init__.py +0 -0
- {lfeats-0.2.1 → lfeats-0.2.2}/lfeats/third_party/speechbrain/nnet/CNN.py +0 -0
- {lfeats-0.2.1 → lfeats-0.2.2}/lfeats/third_party/speechbrain/nnet/containers.py +0 -0
- {lfeats-0.2.1 → lfeats-0.2.2}/lfeats/third_party/speechbrain/nnet/linear.py +0 -0
- {lfeats-0.2.1 → lfeats-0.2.2}/lfeats/third_party/speechbrain/nnet/normalization.py +0 -0
- {lfeats-0.2.1 → lfeats-0.2.2}/lfeats/third_party/speechbrain/nnet/pooling.py +0 -0
- {lfeats-0.2.1 → lfeats-0.2.2}/lfeats/third_party/speechbrain/processing/__init__.py +0 -0
- {lfeats-0.2.1 → lfeats-0.2.2}/lfeats/third_party/speechbrain/processing/features.py +0 -0
- {lfeats-0.2.1 → lfeats-0.2.2}/lfeats/third_party/speechbrain/utils/__init__.py +0 -0
- {lfeats-0.2.1 → lfeats-0.2.2}/lfeats/third_party/speechbrain/utils/_workarounds.py +0 -0
- {lfeats-0.2.1 → lfeats-0.2.2}/lfeats/third_party/speechbrain/utils/autocast.py +0 -0
- {lfeats-0.2.1 → lfeats-0.2.2}/lfeats/third_party/speechbrain/utils/checkpoints.py +0 -0
- {lfeats-0.2.1 → lfeats-0.2.2}/lfeats/third_party/speechbrain/utils/distributed.py +0 -0
- {lfeats-0.2.1 → lfeats-0.2.2}/lfeats/third_party/speechbrain/utils/fetching.py +0 -0
- {lfeats-0.2.1 → lfeats-0.2.2}/lfeats/third_party/speechbrain/utils/filter_analysis.py +0 -0
- {lfeats-0.2.1 → lfeats-0.2.2}/lfeats/third_party/speechbrain/utils/logger.py +0 -0
- {lfeats-0.2.1 → lfeats-0.2.2}/lfeats/third_party/speechbrain/utils/parameter_transfer.py +0 -0
- {lfeats-0.2.1 → lfeats-0.2.2}/lfeats/third_party/speechbrain/utils/run_opts.py +0 -0
- {lfeats-0.2.1 → lfeats-0.2.2}/lfeats/third_party/spin/LICENSE +0 -0
- {lfeats-0.2.1 → lfeats-0.2.2}/lfeats/third_party/spin/__init__.py +0 -0
- {lfeats-0.2.1 → lfeats-0.2.2}/lfeats/third_party/spin/model/__init__.py +0 -0
- {lfeats-0.2.1 → lfeats-0.2.2}/lfeats/third_party/spin/model/base.py +0 -0
- {lfeats-0.2.1 → lfeats-0.2.2}/lfeats/third_party/spin/model/spin.py +0 -0
- {lfeats-0.2.1 → lfeats-0.2.2}/lfeats/third_party/spin/nn/__init__.py +0 -0
- {lfeats-0.2.1 → lfeats-0.2.2}/lfeats/third_party/spin/nn/dnn.py +0 -0
- {lfeats-0.2.1 → lfeats-0.2.2}/lfeats/third_party/spin/nn/hubert.py +0 -0
- {lfeats-0.2.1 → lfeats-0.2.2}/lfeats/third_party/spin/nn/swav_vq_dis.py +0 -0
- {lfeats-0.2.1 → lfeats-0.2.2}/lfeats/third_party/spin/nn/wavlm.py +0 -0
- {lfeats-0.2.1 → lfeats-0.2.2}/lfeats/third_party/spin/util/__init__.py +0 -0
- {lfeats-0.2.1 → lfeats-0.2.2}/lfeats/third_party/spin/util/model_utils.py +0 -0
- {lfeats-0.2.1 → lfeats-0.2.2}/lfeats/third_party/spin/util/padding.py +0 -0
- {lfeats-0.2.1 → lfeats-0.2.2}/lfeats/third_party/timm/LICENSE +0 -0
- {lfeats-0.2.1 → lfeats-0.2.2}/lfeats/third_party/timm/__init__.py +0 -0
- {lfeats-0.2.1 → lfeats-0.2.2}/lfeats/third_party/timm/layers/__init__.py +0 -0
- {lfeats-0.2.1 → lfeats-0.2.2}/lfeats/third_party/timm/layers/drop.py +0 -0
- {lfeats-0.2.1 → lfeats-0.2.2}/lfeats/third_party/timm/layers/helpers.py +0 -0
- {lfeats-0.2.1 → lfeats-0.2.2}/lfeats/third_party/timm/layers/mlp.py +0 -0
- {lfeats-0.2.1 → lfeats-0.2.2}/lfeats/utils/__init__.py +0 -0
- {lfeats-0.2.1 → lfeats-0.2.2}/lfeats/utils/paths.py +0 -0
- {lfeats-0.2.1 → lfeats-0.2.2}/lfeats/utils/validation.py +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
Metadata-Version: 2.
|
|
1
|
+
Metadata-Version: 2.5
|
|
2
2
|
Name: lfeats
|
|
3
|
-
Version: 0.2.
|
|
3
|
+
Version: 0.2.2
|
|
4
4
|
Summary: A unified interface to extract hidden representations from speech foundation models
|
|
5
5
|
Project-URL: Documentation, https://takenori-y.github.io/lfeats/stable/
|
|
6
6
|
Project-URL: Source, https://github.com/takenori-y/lfeats
|
|
@@ -33,6 +33,7 @@ Requires-Dist: soundfile>=0.10.2
|
|
|
33
33
|
Requires-Dist: soxr>=0.4.0
|
|
34
34
|
Requires-Dist: torch>=2.6.0
|
|
35
35
|
Requires-Dist: torchaudio>=2.6.0
|
|
36
|
+
Requires-Dist: tqdm>=4.63.0
|
|
36
37
|
Requires-Dist: transformers>=5.3.0
|
|
37
38
|
Provides-Extra: dev
|
|
38
39
|
Requires-Dist: build; extra == 'dev'
|
|
@@ -41,7 +42,7 @@ Requires-Dist: mdformat; extra == 'dev'
|
|
|
41
42
|
Requires-Dist: numpydoc; extra == 'dev'
|
|
42
43
|
Requires-Dist: pkginfo; extra == 'dev'
|
|
43
44
|
Requires-Dist: pydata-sphinx-theme; extra == 'dev'
|
|
44
|
-
Requires-Dist: pyright
|
|
45
|
+
Requires-Dist: pyright[nodejs]; extra == 'dev'
|
|
45
46
|
Requires-Dist: pytest; extra == 'dev'
|
|
46
47
|
Requires-Dist: pytest-cov; extra == 'dev'
|
|
47
48
|
Requires-Dist: ruff; extra == 'dev'
|
|
@@ -148,25 +149,29 @@ pip install git+https://github.com/takenori-y/lfeats.git@master
|
|
|
148
149
|
|
|
149
150
|
| Model Name | Model Variant | Hop Size [ms] | Dimension | Paper | Source | Model Hub |
|
|
150
151
|
| :--- | :--- | ---: | ---: | :---: | :---: | :---: |
|
|
151
|
-
| `higgs-audio` | `v2` | 40 | 1024 | | [GitHub](https://github.com/boson-ai/higgs-audio) | [🤗](https://huggingface.co/eustlb/higgs-audio-v2-tokenizer) |
|
|
152
|
+
| `higgs-audio` | `v2` | 40 | 1024 | [Blog](https://github.com/Render-AI-Code/cog-higgs-audio/blob/main/tech_blogs/TOKENIZER_BLOG.md) | [GitHub](https://github.com/boson-ai/higgs-audio) | [🤗](https://huggingface.co/eustlb/higgs-audio-v2-tokenizer) |
|
|
153
|
+
| `x-codec` | `hubert` | 20 | 1024 | [arXiv](https://arxiv.org/abs/2408.17175) | [GitHub](https://github.com/zhenye234/xcodec) | [🤗](https://huggingface.co/hf-audio/xcodec-hubert-librispeech) |
|
|
154
|
+
| | `wavlm` | 20 | 1024 | | | [🤗](https://huggingface.co/hf-audio/xcodec-wavlm-more-data) |
|
|
152
155
|
|
|
153
156
|
### Utterance-Level Features
|
|
154
157
|
|
|
155
|
-
| Model Name | Model Variant |
|
|
156
|
-
| :--- | :--- | ---: |
|
|
157
|
-
| `ecapa-tdnn` | `base` |
|
|
158
|
-
| `next-tdnn` | `light` |
|
|
159
|
-
| | `base` |
|
|
160
|
-
| | `base-v2` |
|
|
161
|
-
| `r-vector` | `base` |
|
|
162
|
-
| `redimnet` | `b0` |
|
|
163
|
-
| | `b1` |
|
|
164
|
-
| | `b2` |
|
|
165
|
-
| | `b3` |
|
|
166
|
-
| | `b4` |
|
|
167
|
-
| | `b5` |
|
|
168
|
-
| | `b6` |
|
|
169
|
-
| `
|
|
158
|
+
| Model Name | Model Variant | Dimension | Paper | Source | Model Hub |
|
|
159
|
+
| :--- | :--- | ---: | :---: | :---: | :---: |
|
|
160
|
+
| `ecapa-tdnn` | `base` | 192 | [arXiv](https://arxiv.org/abs/2005.07143) | [GitHub](https://github.com/speechbrain/speechbrain) | [🤗](https://huggingface.co/speechbrain/spkrec-ecapa-voxceleb) |
|
|
161
|
+
| `next-tdnn` | `light` | 192 | [arXiv](https://arxiv.org/abs/2312.08603) | [GitHub](https://github.com/dmlguq456/NeXt_TDNN_ASV) | |
|
|
162
|
+
| | `base` | 192 | | | |
|
|
163
|
+
| | `base-v2` | 192 | | | |
|
|
164
|
+
| `r-vector` | `base` | 256 | [arXiv](https://arxiv.org/abs/1910.12592) | [GitHub](https://github.com/speechbrain/speechbrain) | [🤗](https://huggingface.co/speechbrain/spkrec-resnet-voxceleb) |
|
|
165
|
+
| `redimnet` | `b0` | 192 | [arXiv](https://arxiv.org/abs/2407.18223) | [GitHub](https://github.com/IDRnD/redimnet) | |
|
|
166
|
+
| | `b1` | 192 | | | |
|
|
167
|
+
| | `b2` | 192 | | | |
|
|
168
|
+
| | `b3` | 192 | | | |
|
|
169
|
+
| | `b4` | 192 | | | |
|
|
170
|
+
| | `b5` | 192 | | | |
|
|
171
|
+
| | `b6` | 192 | | | |
|
|
172
|
+
| `wavlm-sv` | `base` | 512 | [arXiv](https://arxiv.org/abs/2110.13900) | [GitHub](https://github.com/microsoft/unilm/tree/master/wavlm) | [🤗](https://huggingface.co/microsoft/wavlm-base-sv) |
|
|
173
|
+
| | `base+` | 512 | | | [🤗](https://huggingface.co/microsoft/wavlm-base-plus-sv) |
|
|
174
|
+
| `x-vector` | `base` | 512 | [IEEE](https://ieeexplore.ieee.org/document/8461375) | [GitHub](https://github.com/speechbrain/speechbrain) | [🤗](https://huggingface.co/speechbrain/spkrec-xvect-voxceleb) |
|
|
170
175
|
|
|
171
176
|
> [!IMPORTANT]
|
|
172
177
|
> Users must comply with the respective licenses of the models.
|
|
@@ -97,25 +97,29 @@ pip install git+https://github.com/takenori-y/lfeats.git@master
|
|
|
97
97
|
|
|
98
98
|
| Model Name | Model Variant | Hop Size [ms] | Dimension | Paper | Source | Model Hub |
|
|
99
99
|
| :--- | :--- | ---: | ---: | :---: | :---: | :---: |
|
|
100
|
-
| `higgs-audio` | `v2` | 40 | 1024 | | [GitHub](https://github.com/boson-ai/higgs-audio) | [🤗](https://huggingface.co/eustlb/higgs-audio-v2-tokenizer) |
|
|
100
|
+
| `higgs-audio` | `v2` | 40 | 1024 | [Blog](https://github.com/Render-AI-Code/cog-higgs-audio/blob/main/tech_blogs/TOKENIZER_BLOG.md) | [GitHub](https://github.com/boson-ai/higgs-audio) | [🤗](https://huggingface.co/eustlb/higgs-audio-v2-tokenizer) |
|
|
101
|
+
| `x-codec` | `hubert` | 20 | 1024 | [arXiv](https://arxiv.org/abs/2408.17175) | [GitHub](https://github.com/zhenye234/xcodec) | [🤗](https://huggingface.co/hf-audio/xcodec-hubert-librispeech) |
|
|
102
|
+
| | `wavlm` | 20 | 1024 | | | [🤗](https://huggingface.co/hf-audio/xcodec-wavlm-more-data) |
|
|
101
103
|
|
|
102
104
|
### Utterance-Level Features
|
|
103
105
|
|
|
104
|
-
| Model Name | Model Variant |
|
|
105
|
-
| :--- | :--- | ---: |
|
|
106
|
-
| `ecapa-tdnn` | `base` |
|
|
107
|
-
| `next-tdnn` | `light` |
|
|
108
|
-
| | `base` |
|
|
109
|
-
| | `base-v2` |
|
|
110
|
-
| `r-vector` | `base` |
|
|
111
|
-
| `redimnet` | `b0` |
|
|
112
|
-
| | `b1` |
|
|
113
|
-
| | `b2` |
|
|
114
|
-
| | `b3` |
|
|
115
|
-
| | `b4` |
|
|
116
|
-
| | `b5` |
|
|
117
|
-
| | `b6` |
|
|
118
|
-
| `
|
|
106
|
+
| Model Name | Model Variant | Dimension | Paper | Source | Model Hub |
|
|
107
|
+
| :--- | :--- | ---: | :---: | :---: | :---: |
|
|
108
|
+
| `ecapa-tdnn` | `base` | 192 | [arXiv](https://arxiv.org/abs/2005.07143) | [GitHub](https://github.com/speechbrain/speechbrain) | [🤗](https://huggingface.co/speechbrain/spkrec-ecapa-voxceleb) |
|
|
109
|
+
| `next-tdnn` | `light` | 192 | [arXiv](https://arxiv.org/abs/2312.08603) | [GitHub](https://github.com/dmlguq456/NeXt_TDNN_ASV) | |
|
|
110
|
+
| | `base` | 192 | | | |
|
|
111
|
+
| | `base-v2` | 192 | | | |
|
|
112
|
+
| `r-vector` | `base` | 256 | [arXiv](https://arxiv.org/abs/1910.12592) | [GitHub](https://github.com/speechbrain/speechbrain) | [🤗](https://huggingface.co/speechbrain/spkrec-resnet-voxceleb) |
|
|
113
|
+
| `redimnet` | `b0` | 192 | [arXiv](https://arxiv.org/abs/2407.18223) | [GitHub](https://github.com/IDRnD/redimnet) | |
|
|
114
|
+
| | `b1` | 192 | | | |
|
|
115
|
+
| | `b2` | 192 | | | |
|
|
116
|
+
| | `b3` | 192 | | | |
|
|
117
|
+
| | `b4` | 192 | | | |
|
|
118
|
+
| | `b5` | 192 | | | |
|
|
119
|
+
| | `b6` | 192 | | | |
|
|
120
|
+
| `wavlm-sv` | `base` | 512 | [arXiv](https://arxiv.org/abs/2110.13900) | [GitHub](https://github.com/microsoft/unilm/tree/master/wavlm) | [🤗](https://huggingface.co/microsoft/wavlm-base-sv) |
|
|
121
|
+
| | `base+` | 512 | | | [🤗](https://huggingface.co/microsoft/wavlm-base-plus-sv) |
|
|
122
|
+
| `x-vector` | `base` | 512 | [IEEE](https://ieeexplore.ieee.org/document/8461375) | [GitHub](https://github.com/speechbrain/speechbrain) | [🤗](https://huggingface.co/speechbrain/spkrec-xvect-voxceleb) |
|
|
119
123
|
|
|
120
124
|
> [!IMPORTANT]
|
|
121
125
|
> Users must comply with the respective licenses of the models.
|
|
@@ -12,6 +12,8 @@ import os
|
|
|
12
12
|
import sys
|
|
13
13
|
from pathlib import Path
|
|
14
14
|
|
|
15
|
+
from tqdm import tqdm
|
|
16
|
+
|
|
15
17
|
logger = logging.getLogger("lfeats")
|
|
16
18
|
|
|
17
19
|
|
|
@@ -125,6 +127,12 @@ def get_arguments() -> argparse.Namespace:
|
|
|
125
127
|
"'mean', or 'auto'."
|
|
126
128
|
),
|
|
127
129
|
)
|
|
130
|
+
parser.add_argument(
|
|
131
|
+
"--normalize",
|
|
132
|
+
action=argparse.BooleanOptionalAction,
|
|
133
|
+
default=False,
|
|
134
|
+
help="Enable or disable L2 normalization of the extracted features.",
|
|
135
|
+
)
|
|
128
136
|
parser.add_argument(
|
|
129
137
|
"-q",
|
|
130
138
|
"--quiet",
|
|
@@ -163,6 +171,7 @@ def main() -> None:
|
|
|
163
171
|
for root, _, files in os.walk(args.source):
|
|
164
172
|
for file in files:
|
|
165
173
|
input_files.append(os.path.join(root, file))
|
|
174
|
+
input_files = sorted(input_files)
|
|
166
175
|
else:
|
|
167
176
|
raise ValueError(f"Invalid source: {args.source}")
|
|
168
177
|
|
|
@@ -197,12 +206,15 @@ def main() -> None:
|
|
|
197
206
|
device=args.device,
|
|
198
207
|
cache_dir=args.cache_dir,
|
|
199
208
|
)
|
|
209
|
+
logger.info(f"Loading {extractor.get_model_id()} model...")
|
|
200
210
|
extractor.load(quiet=args.quiet)
|
|
201
211
|
|
|
202
212
|
num_errors = 0
|
|
203
213
|
|
|
204
214
|
# Process each input file and extract features.
|
|
205
|
-
for input_file in
|
|
215
|
+
for input_file in tqdm(
|
|
216
|
+
input_files, desc="Processing files", unit="file", disable=args.quiet
|
|
217
|
+
):
|
|
206
218
|
if not os.path.isfile(input_file):
|
|
207
219
|
logger.error(f"Could not find file: {input_file}. Skipping.")
|
|
208
220
|
num_errors += 1
|
|
@@ -244,6 +256,7 @@ def main() -> None:
|
|
|
244
256
|
overlap_length_sec=args.overlap_length_sec,
|
|
245
257
|
upsample_factor=args.upsample_factor,
|
|
246
258
|
reduction=args.reduction,
|
|
259
|
+
normalize=args.normalize,
|
|
247
260
|
)
|
|
248
261
|
except Exception as e:
|
|
249
262
|
logger.error(f"Error processing file {input_file}: {e}. Skipping.")
|
|
@@ -102,6 +102,17 @@ class Extractor:
|
|
|
102
102
|
self.model_manager.to(device)
|
|
103
103
|
self.resampler_manager.to(device)
|
|
104
104
|
|
|
105
|
+
def get_model_id(self) -> str:
|
|
106
|
+
"""Return the identifier of the model being used.
|
|
107
|
+
|
|
108
|
+
Returns
|
|
109
|
+
-------
|
|
110
|
+
out : str
|
|
111
|
+
The identifier of the model being used.
|
|
112
|
+
|
|
113
|
+
"""
|
|
114
|
+
return self.model_manager.get_model().model_id
|
|
115
|
+
|
|
105
116
|
def __call__(
|
|
106
117
|
self,
|
|
107
118
|
source: np.ndarray | torch.Tensor | Audio,
|
|
@@ -113,6 +124,7 @@ class Extractor:
|
|
|
113
124
|
overlap_length_sec: int = 5,
|
|
114
125
|
upsample_factor: int = 1,
|
|
115
126
|
reduction: Literal["none", "mean", "auto"] = "auto",
|
|
127
|
+
normalize: bool = False,
|
|
116
128
|
) -> Features:
|
|
117
129
|
"""Extract features from the input waveform.
|
|
118
130
|
|
|
@@ -148,6 +160,9 @@ class Extractor:
|
|
|
148
160
|
determined based on the feature granularity ('none' for frame-level features
|
|
149
161
|
and 'mean' for utterance-level features).
|
|
150
162
|
|
|
163
|
+
normalize : bool, optional
|
|
164
|
+
If True, the extracted features will be L2-normalized.
|
|
165
|
+
|
|
151
166
|
Returns
|
|
152
167
|
-------
|
|
153
168
|
out : Features
|
|
@@ -188,6 +203,7 @@ class Extractor:
|
|
|
188
203
|
chunk_length_sec=chunk_length_sec,
|
|
189
204
|
overlap_length_sec=overlap_length_sec,
|
|
190
205
|
reduction=reduction,
|
|
206
|
+
normalize=normalize,
|
|
191
207
|
)
|
|
192
208
|
|
|
193
209
|
model = self.model_manager.get_model()
|
|
@@ -243,6 +259,7 @@ class Extractor:
|
|
|
243
259
|
chunk_length_sec: int = 30,
|
|
244
260
|
overlap_length_sec: int = 5,
|
|
245
261
|
reduction: Literal["none", "mean", "auto"] = "auto",
|
|
262
|
+
normalize: bool = False,
|
|
246
263
|
) -> Features:
|
|
247
264
|
"""Extract features from the input waveform.
|
|
248
265
|
|
|
@@ -275,6 +292,9 @@ class Extractor:
|
|
|
275
292
|
determined based on the feature granularity ('none' for frame-level features
|
|
276
293
|
and 'mean' for utterance-level features).
|
|
277
294
|
|
|
295
|
+
normalize : bool, optional
|
|
296
|
+
If True, the extracted features will be L2-normalized.
|
|
297
|
+
|
|
278
298
|
Returns
|
|
279
299
|
-------
|
|
280
300
|
out : Features
|
|
@@ -377,6 +397,10 @@ class Extractor:
|
|
|
377
397
|
):
|
|
378
398
|
features = features.reduce("mean")
|
|
379
399
|
|
|
400
|
+
# Apply normalization if specified.
|
|
401
|
+
if normalize:
|
|
402
|
+
features = features.normalize()
|
|
403
|
+
|
|
380
404
|
return features
|
|
381
405
|
|
|
382
406
|
@staticmethod
|
|
@@ -356,6 +356,26 @@ class Features(Container):
|
|
|
356
356
|
|
|
357
357
|
return Features(data=reduced_data, source=self.source, layers=self.layers)
|
|
358
358
|
|
|
359
|
+
def normalize(self) -> Features:
|
|
360
|
+
"""Normalize the features in the L2 sense along the feature dimension.
|
|
361
|
+
|
|
362
|
+
Returns
|
|
363
|
+
-------
|
|
364
|
+
out : Features
|
|
365
|
+
A new Features instance with normalized data.
|
|
366
|
+
|
|
367
|
+
"""
|
|
368
|
+
eps = 1e-12
|
|
369
|
+
if isinstance(self.data, np.ndarray):
|
|
370
|
+
norm = np.linalg.norm(self.array, ord=2, axis=-1, keepdims=True)
|
|
371
|
+
normalized_data = self.array / np.maximum(norm, eps)
|
|
372
|
+
else:
|
|
373
|
+
normalized_data = torch.nn.functional.normalize(
|
|
374
|
+
self.tensor, p=2, dim=-1, eps=eps
|
|
375
|
+
)
|
|
376
|
+
|
|
377
|
+
return Features(data=normalized_data, source=self.source, layers=self.layers)
|
|
378
|
+
|
|
359
379
|
def concat(self, other: Features) -> Features:
|
|
360
380
|
"""Concatenate this Features instance with another one along the time dimension.
|
|
361
381
|
|
|
@@ -22,7 +22,9 @@ from .sslzip import SSLZipModel
|
|
|
22
22
|
from .unispeech_sat import UniSpeechSATModel
|
|
23
23
|
from .wav2vec2 import Wav2Vec2Model
|
|
24
24
|
from .wavlm import WavLMModel
|
|
25
|
+
from .wavlm_sv import WavLMSVModel
|
|
25
26
|
from .whisper import WhisperModel
|
|
27
|
+
from .x_codec import XCodecModel
|
|
26
28
|
from .x_vector import XVectorModel
|
|
27
29
|
|
|
28
30
|
MODEL_MAP = {
|
|
@@ -44,11 +46,13 @@ MODEL_MAP = {
|
|
|
44
46
|
"unispeech-sat": UniSpeechSATModel,
|
|
45
47
|
"wav2vec2": Wav2Vec2Model,
|
|
46
48
|
"wavlm": WavLMModel,
|
|
49
|
+
"wavlm-sv": WavLMSVModel,
|
|
47
50
|
"whisper": WhisperModel,
|
|
51
|
+
"x-codec": XCodecModel,
|
|
48
52
|
"x-vector": XVectorModel,
|
|
49
53
|
}
|
|
50
54
|
|
|
51
55
|
__all__ = [
|
|
52
|
-
"ModelManager",
|
|
53
56
|
"MODEL_MAP",
|
|
57
|
+
"ModelManager",
|
|
54
58
|
]
|
|
@@ -9,7 +9,7 @@ from typing import Any
|
|
|
9
9
|
import torch
|
|
10
10
|
|
|
11
11
|
from ..interfaces.types import Audio, Features
|
|
12
|
-
from ..utils.io import
|
|
12
|
+
from ..utils.io import setup_transformers
|
|
13
13
|
from ..utils.validation import validate_enum
|
|
14
14
|
from .base import TokenLevelFeatureModel
|
|
15
15
|
|
|
@@ -73,7 +73,7 @@ class HiggsAudioTokenizerModel(TokenLevelFeatureModel):
|
|
|
73
73
|
|
|
74
74
|
from transformers import AutoFeatureExtractor, HiggsAudioV2TokenizerModel
|
|
75
75
|
|
|
76
|
-
with
|
|
76
|
+
with setup_transformers(quiet):
|
|
77
77
|
self.feature_extractor = AutoFeatureExtractor.from_pretrained(
|
|
78
78
|
self.variant.model_name, cache_dir=model_dir
|
|
79
79
|
)
|
|
@@ -123,6 +123,18 @@ class HiggsAudioTokenizerModel(TokenLevelFeatureModel):
|
|
|
123
123
|
|
|
124
124
|
return Features(data=vectors, source=self.model_id)
|
|
125
125
|
|
|
126
|
+
@property
|
|
127
|
+
def frame_shift(self) -> int:
|
|
128
|
+
"""Get the frame shift of the model.
|
|
129
|
+
|
|
130
|
+
Returns
|
|
131
|
+
-------
|
|
132
|
+
out : int
|
|
133
|
+
The frame shift in samples.
|
|
134
|
+
|
|
135
|
+
"""
|
|
136
|
+
return int(40.0 * self.sample_rate / 1000)
|
|
137
|
+
|
|
126
138
|
@property
|
|
127
139
|
def sample_rate(self) -> int:
|
|
128
140
|
"""Get the sample rate required by the model.
|
|
@@ -8,7 +8,7 @@ from enum import Enum
|
|
|
8
8
|
import torch
|
|
9
9
|
|
|
10
10
|
from ..interfaces.types import Audio, Features
|
|
11
|
-
from ..utils.io import
|
|
11
|
+
from ..utils.io import setup_transformers
|
|
12
12
|
from ..utils.validation import validate_enum
|
|
13
13
|
from .base import FrameLevelFeatureModel
|
|
14
14
|
|
|
@@ -33,9 +33,7 @@ class HuBERTVariant(str, Enum):
|
|
|
33
33
|
base = f"facebook/hubert-{self.value}"
|
|
34
34
|
if self.value == "base":
|
|
35
35
|
return f"{base}-ls960"
|
|
36
|
-
elif self.value == "large":
|
|
37
|
-
return f"{base}-ll60k"
|
|
38
|
-
elif self.value == "xlarge":
|
|
36
|
+
elif self.value == "large" or self.value == "xlarge":
|
|
39
37
|
return f"{base}-ll60k"
|
|
40
38
|
return base
|
|
41
39
|
|
|
@@ -77,7 +75,7 @@ class HuBERTModel(FrameLevelFeatureModel):
|
|
|
77
75
|
|
|
78
76
|
from transformers import HubertModel
|
|
79
77
|
|
|
80
|
-
with
|
|
78
|
+
with setup_transformers(quiet):
|
|
81
79
|
self.model = HubertModel.from_pretrained(
|
|
82
80
|
self.variant.model_name, cache_dir=model_dir
|
|
83
81
|
)
|
|
@@ -8,7 +8,7 @@ from enum import Enum
|
|
|
8
8
|
import torch
|
|
9
9
|
|
|
10
10
|
from ..interfaces.types import Audio, Features
|
|
11
|
-
from ..utils.io import
|
|
11
|
+
from ..utils.io import setup_transformers
|
|
12
12
|
from ..utils.paths import sanitize
|
|
13
13
|
from ..utils.validation import validate_enum
|
|
14
14
|
from .base import FrameLevelFeatureModel
|
|
@@ -73,7 +73,7 @@ class UniSpeechSATModel(FrameLevelFeatureModel):
|
|
|
73
73
|
|
|
74
74
|
from transformers import UniSpeechSatForPreTraining as _UniSpeechSATModel
|
|
75
75
|
|
|
76
|
-
with
|
|
76
|
+
with setup_transformers(quiet):
|
|
77
77
|
self.model = _UniSpeechSATModel.from_pretrained(
|
|
78
78
|
self.variant.model_name, cache_dir=model_dir
|
|
79
79
|
)
|
|
@@ -8,7 +8,7 @@ from enum import Enum
|
|
|
8
8
|
import torch
|
|
9
9
|
|
|
10
10
|
from ..interfaces.types import Audio, Features
|
|
11
|
-
from ..utils.io import
|
|
11
|
+
from ..utils.io import setup_transformers
|
|
12
12
|
from ..utils.paths import sanitize
|
|
13
13
|
from ..utils.validation import validate_enum
|
|
14
14
|
from .base import FrameLevelFeatureModel
|
|
@@ -71,7 +71,7 @@ class WavLMModel(FrameLevelFeatureModel):
|
|
|
71
71
|
|
|
72
72
|
from transformers import WavLMModel as _WavLMModel
|
|
73
73
|
|
|
74
|
-
with
|
|
74
|
+
with setup_transformers(quiet):
|
|
75
75
|
self.model = _WavLMModel.from_pretrained(
|
|
76
76
|
self.variant.model_name, cache_dir=model_dir
|
|
77
77
|
)
|
|
@@ -0,0 +1,120 @@
|
|
|
1
|
+
# Copyright (c) 2026 Takenori Yoshimura
|
|
2
|
+
# Released under the MIT License.
|
|
3
|
+
|
|
4
|
+
"""A module for the WavLM model."""
|
|
5
|
+
|
|
6
|
+
from enum import Enum
|
|
7
|
+
|
|
8
|
+
import torch
|
|
9
|
+
|
|
10
|
+
from ..interfaces.types import Audio, Features
|
|
11
|
+
from ..utils.io import setup_transformers
|
|
12
|
+
from ..utils.paths import sanitize
|
|
13
|
+
from ..utils.validation import validate_enum
|
|
14
|
+
from .base import UtteranceLevelFeatureModel
|
|
15
|
+
|
|
16
|
+
|
|
17
|
+
class WavLMSVVariant(str, Enum):
|
|
18
|
+
"""Enumeration of supported WavLM-for-speaker-verification model variants."""
|
|
19
|
+
|
|
20
|
+
BASE = "base"
|
|
21
|
+
BASE_PLUS = "base+"
|
|
22
|
+
|
|
23
|
+
@property
|
|
24
|
+
def model_name(self) -> str:
|
|
25
|
+
"""Return the model name corresponding to the variant.
|
|
26
|
+
|
|
27
|
+
Returns
|
|
28
|
+
-------
|
|
29
|
+
out : str
|
|
30
|
+
The model name corresponding to the variant.
|
|
31
|
+
|
|
32
|
+
"""
|
|
33
|
+
return f"microsoft/wavlm-{sanitize(self.value)}-sv"
|
|
34
|
+
|
|
35
|
+
|
|
36
|
+
class WavLMSVModel(UtteranceLevelFeatureModel):
|
|
37
|
+
"""A class for the WavLM-for-speaker-verification model."""
|
|
38
|
+
|
|
39
|
+
def __init__(self, variant: str | None = None, device: str = "cpu") -> None:
|
|
40
|
+
"""Initialize the WavLM-for-speaker-verification model.
|
|
41
|
+
|
|
42
|
+
Parameters
|
|
43
|
+
----------
|
|
44
|
+
variant : str | None, optional
|
|
45
|
+
The variant of the model to use.
|
|
46
|
+
|
|
47
|
+
device : str, optional
|
|
48
|
+
The device to run the model on (e.g., 'cpu' or 'cuda').
|
|
49
|
+
|
|
50
|
+
"""
|
|
51
|
+
super().__init__(variant, device)
|
|
52
|
+
|
|
53
|
+
self.variant = validate_enum(variant, WavLMSVVariant, WavLMSVVariant.BASE_PLUS)
|
|
54
|
+
self._model_id = f"wavlm-{self.variant.value}"
|
|
55
|
+
|
|
56
|
+
self.feature_extractor = None
|
|
57
|
+
|
|
58
|
+
def load(self, model_dir: str, quiet: bool = False) -> None:
|
|
59
|
+
"""Load the model from the specified directory.
|
|
60
|
+
|
|
61
|
+
Parameters
|
|
62
|
+
----------
|
|
63
|
+
model_dir : str
|
|
64
|
+
The directory where the model checkpoint will be stored.
|
|
65
|
+
|
|
66
|
+
quiet : bool, optional
|
|
67
|
+
Whether to suppress output during the loading process.
|
|
68
|
+
|
|
69
|
+
"""
|
|
70
|
+
if self.model is not None:
|
|
71
|
+
return
|
|
72
|
+
|
|
73
|
+
from transformers import Wav2Vec2FeatureExtractor, WavLMForXVector
|
|
74
|
+
|
|
75
|
+
with setup_transformers(quiet):
|
|
76
|
+
self.feature_extractor = Wav2Vec2FeatureExtractor.from_pretrained(
|
|
77
|
+
self.variant.model_name, cache_dir=model_dir
|
|
78
|
+
)
|
|
79
|
+
self.model = WavLMForXVector.from_pretrained(
|
|
80
|
+
self.variant.model_name, cache_dir=model_dir
|
|
81
|
+
)
|
|
82
|
+
self.model.eval()
|
|
83
|
+
self.model.to(self.device) # type: ignore
|
|
84
|
+
|
|
85
|
+
def extract_features_impl(self, audio: Audio, layers: list[int]) -> Features:
|
|
86
|
+
"""Extract features from the input audio using the model.
|
|
87
|
+
|
|
88
|
+
Parameters
|
|
89
|
+
----------
|
|
90
|
+
audio : Audio
|
|
91
|
+
The input audio data with shape (B, T).
|
|
92
|
+
|
|
93
|
+
layers : list[int]
|
|
94
|
+
The layer(s) from which to extract features.
|
|
95
|
+
|
|
96
|
+
Returns
|
|
97
|
+
-------
|
|
98
|
+
out : Features
|
|
99
|
+
The extracted features.
|
|
100
|
+
|
|
101
|
+
Raises
|
|
102
|
+
------
|
|
103
|
+
RuntimeError
|
|
104
|
+
If the model is not loaded.
|
|
105
|
+
|
|
106
|
+
"""
|
|
107
|
+
if self.feature_extractor is None or self.model is None:
|
|
108
|
+
raise RuntimeError("Model not loaded. Call 'load' method first.")
|
|
109
|
+
|
|
110
|
+
with torch.inference_mode():
|
|
111
|
+
inputs = self.feature_extractor(
|
|
112
|
+
[x for x in audio.array],
|
|
113
|
+
sampling_rate=audio.sample_rate,
|
|
114
|
+
padding=True,
|
|
115
|
+
return_tensors="pt",
|
|
116
|
+
).to(self.device)
|
|
117
|
+
embeddings = self.model(**inputs).embeddings
|
|
118
|
+
embeddings = embeddings.unsqueeze(1)
|
|
119
|
+
|
|
120
|
+
return Features(data=embeddings, source=self.model_id)
|
|
@@ -8,7 +8,7 @@ from enum import Enum
|
|
|
8
8
|
import torch
|
|
9
9
|
|
|
10
10
|
from ..interfaces.types import Audio, Features
|
|
11
|
-
from ..utils.io import
|
|
11
|
+
from ..utils.io import setup_transformers
|
|
12
12
|
from ..utils.validation import validate_enum
|
|
13
13
|
from .base import FrameLevelFeatureModel
|
|
14
14
|
|
|
@@ -76,7 +76,7 @@ class WhisperModel(FrameLevelFeatureModel):
|
|
|
76
76
|
|
|
77
77
|
from transformers import WhisperModel, WhisperProcessor
|
|
78
78
|
|
|
79
|
-
with
|
|
79
|
+
with setup_transformers(quiet):
|
|
80
80
|
self.processor = WhisperProcessor.from_pretrained(
|
|
81
81
|
self.variant.model_name, cache_dir=model_dir
|
|
82
82
|
)
|