lfeats 0.1.3__tar.gz → 0.2.0__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.1.3 → lfeats-0.2.0}/PKG-INFO +2 -1
- {lfeats-0.1.3 → lfeats-0.2.0}/lfeats/cli.py +40 -12
- {lfeats-0.1.3 → lfeats-0.2.0}/lfeats/interfaces/extractor.py +12 -0
- {lfeats-0.1.3 → lfeats-0.2.0}/lfeats/interfaces/resampler.py +11 -0
- {lfeats-0.1.3 → lfeats-0.2.0}/lfeats/models/base.py +19 -0
- {lfeats-0.1.3 → lfeats-0.2.0}/lfeats/models/contentvec.py +0 -2
- {lfeats-0.1.3 → lfeats-0.2.0}/lfeats/models/data2vec.py +0 -3
- {lfeats-0.1.3 → lfeats-0.2.0}/lfeats/models/data2vec2.py +0 -3
- {lfeats-0.1.3 → lfeats-0.2.0}/lfeats/models/ecapa_tdnn.py +1 -3
- {lfeats-0.1.3 → lfeats-0.2.0}/lfeats/models/emotion2vec.py +1 -3
- {lfeats-0.1.3 → lfeats-0.2.0}/lfeats/models/emotion2vec_plus.py +2 -4
- {lfeats-0.1.3 → lfeats-0.2.0}/lfeats/models/hubert.py +0 -2
- {lfeats-0.1.3 → lfeats-0.2.0}/lfeats/models/manager.py +13 -0
- {lfeats-0.1.3 → lfeats-0.2.0}/lfeats/models/next_tdnn.py +0 -2
- {lfeats-0.1.3 → lfeats-0.2.0}/lfeats/models/r_spin.py +0 -2
- {lfeats-0.1.3 → lfeats-0.2.0}/lfeats/models/r_vector.py +1 -3
- {lfeats-0.1.3 → lfeats-0.2.0}/lfeats/models/spidr.py +4 -8
- {lfeats-0.1.3 → lfeats-0.2.0}/lfeats/models/spin.py +3 -4
- {lfeats-0.1.3 → lfeats-0.2.0}/lfeats/models/sslzip.py +14 -1
- {lfeats-0.1.3 → lfeats-0.2.0}/lfeats/models/unispeech_sat.py +0 -2
- {lfeats-0.1.3 → lfeats-0.2.0}/lfeats/models/wav2vec2.py +0 -3
- {lfeats-0.1.3 → lfeats-0.2.0}/lfeats/models/wavlm.py +0 -2
- {lfeats-0.1.3 → lfeats-0.2.0}/lfeats/models/whisper.py +0 -1
- {lfeats-0.1.3 → lfeats-0.2.0}/lfeats/models/x_vector.py +1 -3
- {lfeats-0.1.3 → lfeats-0.2.0}/lfeats/resamplers/base.py +11 -0
- {lfeats-0.1.3 → lfeats-0.2.0}/lfeats/resamplers/lilfilter.py +13 -1
- {lfeats-0.1.3 → lfeats-0.2.0}/lfeats/resamplers/manager.py +13 -0
- {lfeats-0.1.3 → lfeats-0.2.0}/lfeats/resamplers/torchaudio.py +14 -1
- {lfeats-0.1.3 → lfeats-0.2.0}/lfeats/third_party/s3prl/util/download.py +24 -10
- {lfeats-0.1.3 → lfeats-0.2.0}/lfeats/third_party/speechbrain/utils/distributed.py +1 -1
- {lfeats-0.1.3 → lfeats-0.2.0}/lfeats/utils/io.py +54 -6
- {lfeats-0.1.3 → lfeats-0.2.0}/lfeats/version.py +1 -1
- {lfeats-0.1.3 → lfeats-0.2.0}/pyproject.toml +1 -0
- {lfeats-0.1.3 → lfeats-0.2.0}/.gitignore +0 -0
- {lfeats-0.1.3 → lfeats-0.2.0}/LICENSE +0 -0
- {lfeats-0.1.3 → lfeats-0.2.0}/README.md +0 -0
- {lfeats-0.1.3 → lfeats-0.2.0}/lfeats/__init__.py +0 -0
- {lfeats-0.1.3 → lfeats-0.2.0}/lfeats/interfaces/__init__.py +0 -0
- {lfeats-0.1.3 → lfeats-0.2.0}/lfeats/interfaces/types.py +0 -0
- {lfeats-0.1.3 → lfeats-0.2.0}/lfeats/interfaces/utils.py +0 -0
- {lfeats-0.1.3 → lfeats-0.2.0}/lfeats/models/__init__.py +0 -0
- {lfeats-0.1.3 → lfeats-0.2.0}/lfeats/resamplers/__init__.py +0 -0
- {lfeats-0.1.3 → lfeats-0.2.0}/lfeats/resamplers/soxr.py +0 -0
- {lfeats-0.1.3 → lfeats-0.2.0}/lfeats/third_party/__init__.py +0 -0
- {lfeats-0.1.3 → lfeats-0.2.0}/lfeats/third_party/fairseq/LICENSE +0 -0
- {lfeats-0.1.3 → lfeats-0.2.0}/lfeats/third_party/fairseq/__init__.py +0 -0
- {lfeats-0.1.3 → lfeats-0.2.0}/lfeats/third_party/fairseq/checkpoint_utils.py +0 -0
- {lfeats-0.1.3 → lfeats-0.2.0}/lfeats/third_party/fairseq/config/__init__.py +0 -0
- {lfeats-0.1.3 → lfeats-0.2.0}/lfeats/third_party/fairseq/config/config.yaml +0 -0
- {lfeats-0.1.3 → lfeats-0.2.0}/lfeats/third_party/fairseq/data/__init__.py +0 -0
- {lfeats-0.1.3 → lfeats-0.2.0}/lfeats/third_party/fairseq/data/dictionary.py +0 -0
- {lfeats-0.1.3 → lfeats-0.2.0}/lfeats/third_party/fairseq/data/modality.py +0 -0
- {lfeats-0.1.3 → lfeats-0.2.0}/lfeats/third_party/fairseq/data/text_compressor.py +0 -0
- {lfeats-0.1.3 → lfeats-0.2.0}/lfeats/third_party/fairseq/dataclass/__init__.py +0 -0
- {lfeats-0.1.3 → lfeats-0.2.0}/lfeats/third_party/fairseq/dataclass/configs.py +0 -0
- {lfeats-0.1.3 → lfeats-0.2.0}/lfeats/third_party/fairseq/dataclass/constants.py +0 -0
- {lfeats-0.1.3 → lfeats-0.2.0}/lfeats/third_party/fairseq/dataclass/initialize.py +0 -0
- {lfeats-0.1.3 → lfeats-0.2.0}/lfeats/third_party/fairseq/dataclass/utils.py +0 -0
- {lfeats-0.1.3 → lfeats-0.2.0}/lfeats/third_party/fairseq/file_io.py +0 -0
- {lfeats-0.1.3 → lfeats-0.2.0}/lfeats/third_party/fairseq/incremental_decoding_utils.py +0 -0
- {lfeats-0.1.3 → lfeats-0.2.0}/lfeats/third_party/fairseq/logging/__init__.py +0 -0
- {lfeats-0.1.3 → lfeats-0.2.0}/lfeats/third_party/fairseq/logging/meters.py +0 -0
- {lfeats-0.1.3 → lfeats-0.2.0}/lfeats/third_party/fairseq/models/__init__.py +0 -0
- {lfeats-0.1.3 → lfeats-0.2.0}/lfeats/third_party/fairseq/models/data2vec/__init__.py +0 -0
- {lfeats-0.1.3 → lfeats-0.2.0}/lfeats/third_party/fairseq/models/data2vec/data2vec2.py +0 -0
- {lfeats-0.1.3 → lfeats-0.2.0}/lfeats/third_party/fairseq/models/data2vec/data2vec_audio.py +0 -0
- {lfeats-0.1.3 → lfeats-0.2.0}/lfeats/third_party/fairseq/models/data2vec/modalities/__init__.py +0 -0
- {lfeats-0.1.3 → lfeats-0.2.0}/lfeats/third_party/fairseq/models/data2vec/modalities/audio.py +0 -0
- {lfeats-0.1.3 → lfeats-0.2.0}/lfeats/third_party/fairseq/models/data2vec/modalities/base.py +0 -0
- {lfeats-0.1.3 → lfeats-0.2.0}/lfeats/third_party/fairseq/models/data2vec/modalities/modules.py +0 -0
- {lfeats-0.1.3 → lfeats-0.2.0}/lfeats/third_party/fairseq/models/fairseq_decoder.py +0 -0
- {lfeats-0.1.3 → lfeats-0.2.0}/lfeats/third_party/fairseq/models/fairseq_encoder.py +0 -0
- {lfeats-0.1.3 → lfeats-0.2.0}/lfeats/third_party/fairseq/models/fairseq_incremental_decoder.py +0 -0
- {lfeats-0.1.3 → lfeats-0.2.0}/lfeats/third_party/fairseq/models/fairseq_model.py +0 -0
- {lfeats-0.1.3 → lfeats-0.2.0}/lfeats/third_party/fairseq/models/hubert/__init__.py +0 -0
- {lfeats-0.1.3 → lfeats-0.2.0}/lfeats/third_party/fairseq/models/hubert/hubert.py +0 -0
- {lfeats-0.1.3 → lfeats-0.2.0}/lfeats/third_party/fairseq/models/wav2vec/__init__.py +0 -0
- {lfeats-0.1.3 → lfeats-0.2.0}/lfeats/third_party/fairseq/models/wav2vec/utils.py +0 -0
- {lfeats-0.1.3 → lfeats-0.2.0}/lfeats/third_party/fairseq/models/wav2vec/wav2vec2.py +0 -0
- {lfeats-0.1.3 → lfeats-0.2.0}/lfeats/third_party/fairseq/modules/__init__.py +0 -0
- {lfeats-0.1.3 → lfeats-0.2.0}/lfeats/third_party/fairseq/modules/ema_module.py +0 -0
- {lfeats-0.1.3 → lfeats-0.2.0}/lfeats/third_party/fairseq/modules/fairseq_dropout.py +0 -0
- {lfeats-0.1.3 → lfeats-0.2.0}/lfeats/third_party/fairseq/modules/fp32_group_norm.py +0 -0
- {lfeats-0.1.3 → lfeats-0.2.0}/lfeats/third_party/fairseq/modules/gelu.py +0 -0
- {lfeats-0.1.3 → lfeats-0.2.0}/lfeats/third_party/fairseq/modules/gumbel_vector_quantizer.py +0 -0
- {lfeats-0.1.3 → lfeats-0.2.0}/lfeats/third_party/fairseq/modules/layer_norm.py +0 -0
- {lfeats-0.1.3 → lfeats-0.2.0}/lfeats/third_party/fairseq/modules/multihead_attention.py +0 -0
- {lfeats-0.1.3 → lfeats-0.2.0}/lfeats/third_party/fairseq/modules/quant_noise.py +0 -0
- {lfeats-0.1.3 → lfeats-0.2.0}/lfeats/third_party/fairseq/modules/same_pad.py +0 -0
- {lfeats-0.1.3 → lfeats-0.2.0}/lfeats/third_party/fairseq/modules/transpose_last.py +0 -0
- {lfeats-0.1.3 → lfeats-0.2.0}/lfeats/third_party/fairseq/quantization_utils.py +0 -0
- {lfeats-0.1.3 → lfeats-0.2.0}/lfeats/third_party/fairseq/registry.py +0 -0
- {lfeats-0.1.3 → lfeats-0.2.0}/lfeats/third_party/fairseq/tasks/__init__.py +0 -0
- {lfeats-0.1.3 → lfeats-0.2.0}/lfeats/third_party/fairseq/tasks/audio_pretraining.py +0 -0
- {lfeats-0.1.3 → lfeats-0.2.0}/lfeats/third_party/fairseq/tasks/fairseq_task.py +0 -0
- {lfeats-0.1.3 → lfeats-0.2.0}/lfeats/third_party/fairseq/tasks/hubert_pretraining.py +0 -0
- {lfeats-0.1.3 → lfeats-0.2.0}/lfeats/third_party/fairseq/tokenizer.py +0 -0
- {lfeats-0.1.3 → lfeats-0.2.0}/lfeats/third_party/fairseq/utils.py +0 -0
- {lfeats-0.1.3 → lfeats-0.2.0}/lfeats/third_party/next_tdnn_asv/LICENSE +0 -0
- {lfeats-0.1.3 → lfeats-0.2.0}/lfeats/third_party/next_tdnn_asv/SpeakerNet.py +0 -0
- {lfeats-0.1.3 → lfeats-0.2.0}/lfeats/third_party/next_tdnn_asv/__init__.py +0 -0
- {lfeats-0.1.3 → lfeats-0.2.0}/lfeats/third_party/next_tdnn_asv/aggregation/__init__.py +0 -0
- {lfeats-0.1.3 → lfeats-0.2.0}/lfeats/third_party/next_tdnn_asv/aggregation/vap_bn_tanh_fc_bn.py +0 -0
- {lfeats-0.1.3 → lfeats-0.2.0}/lfeats/third_party/next_tdnn_asv/configs/NeXt_TDNN_C256_B3_K65_7.py +0 -0
- {lfeats-0.1.3 → lfeats-0.2.0}/lfeats/third_party/next_tdnn_asv/configs/NeXt_TDNN_C256_B3_K65_7_cyclical_lr_step.py +0 -0
- {lfeats-0.1.3 → lfeats-0.2.0}/lfeats/third_party/next_tdnn_asv/configs/NeXt_TDNN_light_C256_B3_K65.py +0 -0
- {lfeats-0.1.3 → lfeats-0.2.0}/lfeats/third_party/next_tdnn_asv/configs/__init__.py +0 -0
- {lfeats-0.1.3 → lfeats-0.2.0}/lfeats/third_party/next_tdnn_asv/main.py +0 -0
- {lfeats-0.1.3 → lfeats-0.2.0}/lfeats/third_party/next_tdnn_asv/models/NeXt_TDNN.py +0 -0
- {lfeats-0.1.3 → lfeats-0.2.0}/lfeats/third_party/next_tdnn_asv/models/TSConvNeXt.py +0 -0
- {lfeats-0.1.3 → lfeats-0.2.0}/lfeats/third_party/next_tdnn_asv/models/TSConvNeXt_light.py +0 -0
- {lfeats-0.1.3 → lfeats-0.2.0}/lfeats/third_party/next_tdnn_asv/models/__init__.py +0 -0
- {lfeats-0.1.3 → lfeats-0.2.0}/lfeats/third_party/next_tdnn_asv/models/utils.py +0 -0
- {lfeats-0.1.3 → lfeats-0.2.0}/lfeats/third_party/next_tdnn_asv/preprocessing/__init__.py +0 -0
- {lfeats-0.1.3 → lfeats-0.2.0}/lfeats/third_party/next_tdnn_asv/preprocessing/mel_transform.py +0 -0
- {lfeats-0.1.3 → lfeats-0.2.0}/lfeats/third_party/rspin/LICENSE +0 -0
- {lfeats-0.1.3 → lfeats-0.2.0}/lfeats/third_party/rspin/__init__.py +0 -0
- {lfeats-0.1.3 → lfeats-0.2.0}/lfeats/third_party/rspin/model.py +0 -0
- {lfeats-0.1.3 → lfeats-0.2.0}/lfeats/third_party/rspin/wavlm_config.py +0 -0
- {lfeats-0.1.3 → lfeats-0.2.0}/lfeats/third_party/s3prl/LICENSE +0 -0
- {lfeats-0.1.3 → lfeats-0.2.0}/lfeats/third_party/s3prl/__init__.py +0 -0
- {lfeats-0.1.3 → lfeats-0.2.0}/lfeats/third_party/s3prl/upstream/__init__.py +0 -0
- {lfeats-0.1.3 → lfeats-0.2.0}/lfeats/third_party/s3prl/upstream/hubert/__init__.py +0 -0
- {lfeats-0.1.3 → lfeats-0.2.0}/lfeats/third_party/s3prl/upstream/hubert/convert.py +0 -0
- {lfeats-0.1.3 → lfeats-0.2.0}/lfeats/third_party/s3prl/upstream/hubert/hubert_model.py +0 -0
- {lfeats-0.1.3 → lfeats-0.2.0}/lfeats/third_party/s3prl/upstream/utils.py +0 -0
- {lfeats-0.1.3 → lfeats-0.2.0}/lfeats/third_party/s3prl/upstream/wav2vec2/__init__.py +0 -0
- {lfeats-0.1.3 → lfeats-0.2.0}/lfeats/third_party/s3prl/upstream/wav2vec2/wav2vec2_model.py +0 -0
- {lfeats-0.1.3 → lfeats-0.2.0}/lfeats/third_party/s3prl/upstream/wavlm/WavLM.py +0 -0
- {lfeats-0.1.3 → lfeats-0.2.0}/lfeats/third_party/s3prl/upstream/wavlm/__init__.py +0 -0
- {lfeats-0.1.3 → lfeats-0.2.0}/lfeats/third_party/s3prl/upstream/wavlm/modules.py +0 -0
- {lfeats-0.1.3 → lfeats-0.2.0}/lfeats/third_party/s3prl/util/__init__.py +0 -0
- {lfeats-0.1.3 → lfeats-0.2.0}/lfeats/third_party/speechbrain/LICENSE +0 -0
- {lfeats-0.1.3 → lfeats-0.2.0}/lfeats/third_party/speechbrain/__init__.py +0 -0
- {lfeats-0.1.3 → lfeats-0.2.0}/lfeats/third_party/speechbrain/dataio/__init__.py +0 -0
- {lfeats-0.1.3 → lfeats-0.2.0}/lfeats/third_party/speechbrain/dataio/dataio.py +0 -0
- {lfeats-0.1.3 → lfeats-0.2.0}/lfeats/third_party/speechbrain/dataio/encoder.py +0 -0
- {lfeats-0.1.3 → lfeats-0.2.0}/lfeats/third_party/speechbrain/dataio/preprocess.py +0 -0
- {lfeats-0.1.3 → lfeats-0.2.0}/lfeats/third_party/speechbrain/inference/__init__.py +0 -0
- {lfeats-0.1.3 → lfeats-0.2.0}/lfeats/third_party/speechbrain/inference/classifiers.py +0 -0
- {lfeats-0.1.3 → lfeats-0.2.0}/lfeats/third_party/speechbrain/inference/interfaces.py +0 -0
- {lfeats-0.1.3 → lfeats-0.2.0}/lfeats/third_party/speechbrain/lobes/__init__.py +0 -0
- {lfeats-0.1.3 → lfeats-0.2.0}/lfeats/third_party/speechbrain/lobes/features.py +0 -0
- {lfeats-0.1.3 → lfeats-0.2.0}/lfeats/third_party/speechbrain/lobes/models/ECAPA_TDNN.py +0 -0
- {lfeats-0.1.3 → lfeats-0.2.0}/lfeats/third_party/speechbrain/lobes/models/ResNet.py +0 -0
- {lfeats-0.1.3 → lfeats-0.2.0}/lfeats/third_party/speechbrain/lobes/models/Xvector.py +0 -0
- {lfeats-0.1.3 → lfeats-0.2.0}/lfeats/third_party/speechbrain/lobes/models/__init__.py +0 -0
- {lfeats-0.1.3 → lfeats-0.2.0}/lfeats/third_party/speechbrain/nnet/CNN.py +0 -0
- {lfeats-0.1.3 → lfeats-0.2.0}/lfeats/third_party/speechbrain/nnet/containers.py +0 -0
- {lfeats-0.1.3 → lfeats-0.2.0}/lfeats/third_party/speechbrain/nnet/linear.py +0 -0
- {lfeats-0.1.3 → lfeats-0.2.0}/lfeats/third_party/speechbrain/nnet/normalization.py +0 -0
- {lfeats-0.1.3 → lfeats-0.2.0}/lfeats/third_party/speechbrain/nnet/pooling.py +0 -0
- {lfeats-0.1.3 → lfeats-0.2.0}/lfeats/third_party/speechbrain/processing/__init__.py +0 -0
- {lfeats-0.1.3 → lfeats-0.2.0}/lfeats/third_party/speechbrain/processing/features.py +0 -0
- {lfeats-0.1.3 → lfeats-0.2.0}/lfeats/third_party/speechbrain/utils/__init__.py +0 -0
- {lfeats-0.1.3 → lfeats-0.2.0}/lfeats/third_party/speechbrain/utils/_workarounds.py +0 -0
- {lfeats-0.1.3 → lfeats-0.2.0}/lfeats/third_party/speechbrain/utils/autocast.py +0 -0
- {lfeats-0.1.3 → lfeats-0.2.0}/lfeats/third_party/speechbrain/utils/checkpoints.py +0 -0
- {lfeats-0.1.3 → lfeats-0.2.0}/lfeats/third_party/speechbrain/utils/fetching.py +0 -0
- {lfeats-0.1.3 → lfeats-0.2.0}/lfeats/third_party/speechbrain/utils/filter_analysis.py +0 -0
- {lfeats-0.1.3 → lfeats-0.2.0}/lfeats/third_party/speechbrain/utils/logger.py +0 -0
- {lfeats-0.1.3 → lfeats-0.2.0}/lfeats/third_party/speechbrain/utils/parameter_transfer.py +0 -0
- {lfeats-0.1.3 → lfeats-0.2.0}/lfeats/third_party/speechbrain/utils/run_opts.py +0 -0
- {lfeats-0.1.3 → lfeats-0.2.0}/lfeats/third_party/spin/LICENSE +0 -0
- {lfeats-0.1.3 → lfeats-0.2.0}/lfeats/third_party/spin/__init__.py +0 -0
- {lfeats-0.1.3 → lfeats-0.2.0}/lfeats/third_party/spin/model/__init__.py +0 -0
- {lfeats-0.1.3 → lfeats-0.2.0}/lfeats/third_party/spin/model/base.py +0 -0
- {lfeats-0.1.3 → lfeats-0.2.0}/lfeats/third_party/spin/model/spin.py +0 -0
- {lfeats-0.1.3 → lfeats-0.2.0}/lfeats/third_party/spin/nn/__init__.py +0 -0
- {lfeats-0.1.3 → lfeats-0.2.0}/lfeats/third_party/spin/nn/dnn.py +0 -0
- {lfeats-0.1.3 → lfeats-0.2.0}/lfeats/third_party/spin/nn/hubert.py +0 -0
- {lfeats-0.1.3 → lfeats-0.2.0}/lfeats/third_party/spin/nn/swav_vq_dis.py +0 -0
- {lfeats-0.1.3 → lfeats-0.2.0}/lfeats/third_party/spin/nn/wavlm.py +0 -0
- {lfeats-0.1.3 → lfeats-0.2.0}/lfeats/third_party/spin/util/__init__.py +0 -0
- {lfeats-0.1.3 → lfeats-0.2.0}/lfeats/third_party/spin/util/model_utils.py +0 -0
- {lfeats-0.1.3 → lfeats-0.2.0}/lfeats/third_party/spin/util/padding.py +0 -0
- {lfeats-0.1.3 → lfeats-0.2.0}/lfeats/third_party/timm/LICENSE +0 -0
- {lfeats-0.1.3 → lfeats-0.2.0}/lfeats/third_party/timm/__init__.py +0 -0
- {lfeats-0.1.3 → lfeats-0.2.0}/lfeats/third_party/timm/layers/__init__.py +0 -0
- {lfeats-0.1.3 → lfeats-0.2.0}/lfeats/third_party/timm/layers/drop.py +0 -0
- {lfeats-0.1.3 → lfeats-0.2.0}/lfeats/third_party/timm/layers/helpers.py +0 -0
- {lfeats-0.1.3 → lfeats-0.2.0}/lfeats/third_party/timm/layers/mlp.py +0 -0
- {lfeats-0.1.3 → lfeats-0.2.0}/lfeats/utils/__init__.py +0 -0
- {lfeats-0.1.3 → lfeats-0.2.0}/lfeats/utils/paths.py +0 -0
- {lfeats-0.1.3 → lfeats-0.2.0}/lfeats/utils/validation.py +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: lfeats
|
|
3
|
-
Version: 0.
|
|
3
|
+
Version: 0.2.0
|
|
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
|
|
@@ -18,6 +18,7 @@ Classifier: Programming Language :: Python :: 3.12
|
|
|
18
18
|
Classifier: Programming Language :: Python :: 3.13
|
|
19
19
|
Classifier: Programming Language :: Python :: 3.14
|
|
20
20
|
Requires-Python: >=3.10
|
|
21
|
+
Requires-Dist: filelock>=3.10.0
|
|
21
22
|
Requires-Dist: huggingface-hub>=0.23.0
|
|
22
23
|
Requires-Dist: hydra-core>=1.3.0
|
|
23
24
|
Requires-Dist: hyperpyyaml>=0.0.1
|
|
@@ -7,8 +7,10 @@
|
|
|
7
7
|
|
|
8
8
|
import argparse
|
|
9
9
|
import logging
|
|
10
|
+
import mimetypes
|
|
10
11
|
import os
|
|
11
12
|
import sys
|
|
13
|
+
from pathlib import Path
|
|
12
14
|
|
|
13
15
|
logger = logging.getLogger("lfeats")
|
|
14
16
|
|
|
@@ -21,14 +23,23 @@ def get_arguments() -> argparse.Namespace:
|
|
|
21
23
|
parser.add_argument(
|
|
22
24
|
"source",
|
|
23
25
|
type=str,
|
|
24
|
-
help="The source audio file, directory, or
|
|
26
|
+
help="The source audio file, directory, or scp file containing file paths.",
|
|
25
27
|
)
|
|
26
28
|
parser.add_argument(
|
|
27
29
|
"--output_dir",
|
|
28
30
|
type=str,
|
|
29
|
-
default=
|
|
31
|
+
default=".",
|
|
30
32
|
help="The directory where the extracted features will be saved.",
|
|
31
33
|
)
|
|
34
|
+
parser.add_argument(
|
|
35
|
+
"--subdir_offset",
|
|
36
|
+
type=int,
|
|
37
|
+
default=None,
|
|
38
|
+
help=(
|
|
39
|
+
"The offset from the beginning of the input file path to start creating "
|
|
40
|
+
"subdirectories in the output directory."
|
|
41
|
+
),
|
|
42
|
+
)
|
|
32
43
|
parser.add_argument(
|
|
33
44
|
"--output_format",
|
|
34
45
|
type=str,
|
|
@@ -127,6 +138,9 @@ def main() -> None:
|
|
|
127
138
|
"""Perform the main feature extraction process."""
|
|
128
139
|
args = get_arguments()
|
|
129
140
|
|
|
141
|
+
if args.subdir_offset is not None and args.subdir_offset < 0:
|
|
142
|
+
raise ValueError("Subdir offset must be a non-negative integer.")
|
|
143
|
+
|
|
130
144
|
logging.basicConfig(
|
|
131
145
|
level=logging.ERROR if args.quiet else logging.INFO,
|
|
132
146
|
format="%(asctime)s [%(levelname)s] %(name)s: %(message)s",
|
|
@@ -141,11 +155,12 @@ def main() -> None:
|
|
|
141
155
|
|
|
142
156
|
# Get the list of input files from the source argument.
|
|
143
157
|
if os.path.isfile(args.source):
|
|
144
|
-
|
|
158
|
+
mime_type, _ = mimetypes.guess_type(args.source)
|
|
159
|
+
if mime_type is not None and mime_type.startswith("audio/"):
|
|
160
|
+
input_files = [args.source]
|
|
161
|
+
else:
|
|
145
162
|
with open(args.source) as f:
|
|
146
163
|
input_files = [line.strip() for line in f if line.strip()]
|
|
147
|
-
else:
|
|
148
|
-
input_files = [args.source]
|
|
149
164
|
elif os.path.isdir(args.source):
|
|
150
165
|
input_files = []
|
|
151
166
|
for root, _, files in os.walk(args.source):
|
|
@@ -168,10 +183,6 @@ def main() -> None:
|
|
|
168
183
|
else:
|
|
169
184
|
raise ValueError(f"Invalid layers argument: {args.layers}")
|
|
170
185
|
|
|
171
|
-
# Prepare the output directory if specified.
|
|
172
|
-
if args.output_dir is not None:
|
|
173
|
-
os.makedirs(args.output_dir, exist_ok=True)
|
|
174
|
-
|
|
175
186
|
output_ext = {
|
|
176
187
|
"npz": "npz",
|
|
177
188
|
"pt": "pt",
|
|
@@ -199,10 +210,27 @@ def main() -> None:
|
|
|
199
210
|
num_errors += 1
|
|
200
211
|
continue
|
|
201
212
|
|
|
213
|
+
if args.subdir_offset is None:
|
|
214
|
+
subdir = ""
|
|
215
|
+
else:
|
|
216
|
+
path = Path(input_file).parent
|
|
217
|
+
# Remove the root part of the path.
|
|
218
|
+
dirs = path.relative_to(path.anchor).parts
|
|
219
|
+
if args.subdir_offset >= len(dirs):
|
|
220
|
+
logger.error(
|
|
221
|
+
f"Subdir offset {args.subdir_offset} is too large for file: "
|
|
222
|
+
f"{input_file}. Skipping."
|
|
223
|
+
)
|
|
224
|
+
num_errors += 1
|
|
225
|
+
continue
|
|
226
|
+
subdirs = dirs[args.subdir_offset :]
|
|
227
|
+
subdir = Path(*subdirs)
|
|
228
|
+
|
|
229
|
+
output_dir = os.path.join(args.output_dir, subdir)
|
|
230
|
+
os.makedirs(output_dir, exist_ok=True)
|
|
231
|
+
|
|
202
232
|
base, _ = os.path.splitext(os.path.basename(input_file))
|
|
203
|
-
output_file = f"{base}.{output_ext}"
|
|
204
|
-
if args.output_dir is not None:
|
|
205
|
-
output_file = os.path.join(args.output_dir, output_file)
|
|
233
|
+
output_file = os.path.join(output_dir, f"{base}.{output_ext}")
|
|
206
234
|
|
|
207
235
|
try:
|
|
208
236
|
audio, sample_rate = load_audio(input_file)
|
|
@@ -90,6 +90,18 @@ class Extractor:
|
|
|
90
90
|
"""
|
|
91
91
|
self.model_manager.get_model().load(self.cache_dir, quiet)
|
|
92
92
|
|
|
93
|
+
def to(self, device: str) -> None:
|
|
94
|
+
"""Move the model to the specified device.
|
|
95
|
+
|
|
96
|
+
Parameters
|
|
97
|
+
----------
|
|
98
|
+
device : str
|
|
99
|
+
The device to move the model to (e.g., 'cpu' or 'cuda').
|
|
100
|
+
|
|
101
|
+
"""
|
|
102
|
+
self.model_manager.to(device)
|
|
103
|
+
self.resampler_manager.to(device)
|
|
104
|
+
|
|
93
105
|
def __call__(
|
|
94
106
|
self,
|
|
95
107
|
source: np.ndarray | torch.Tensor | Audio,
|
|
@@ -45,6 +45,17 @@ class Resampler:
|
|
|
45
45
|
f"Supported resamplers are: {[k for k in RESAMPLER_MAP.keys()]}"
|
|
46
46
|
) from e
|
|
47
47
|
|
|
48
|
+
def to(self, device: str) -> None:
|
|
49
|
+
"""Move the resampler to the specified device.
|
|
50
|
+
|
|
51
|
+
Parameters
|
|
52
|
+
----------
|
|
53
|
+
device : str
|
|
54
|
+
The device to move the resampler to (e.g., 'cpu' or 'cuda').
|
|
55
|
+
|
|
56
|
+
"""
|
|
57
|
+
self.resampler_manager.to(device)
|
|
58
|
+
|
|
48
59
|
def __call__(
|
|
49
60
|
self,
|
|
50
61
|
source: np.ndarray | torch.Tensor | Audio,
|
|
@@ -25,6 +25,7 @@ class BaseModel(ABC):
|
|
|
25
25
|
"""
|
|
26
26
|
self.device = device
|
|
27
27
|
|
|
28
|
+
self.model = None
|
|
28
29
|
self._model_id = None # To be defined in subclasses
|
|
29
30
|
|
|
30
31
|
@abstractmethod
|
|
@@ -42,6 +43,24 @@ class BaseModel(ABC):
|
|
|
42
43
|
"""
|
|
43
44
|
raise NotImplementedError
|
|
44
45
|
|
|
46
|
+
def to(self, device: str) -> None:
|
|
47
|
+
"""Move the model to the specified device.
|
|
48
|
+
|
|
49
|
+
Parameters
|
|
50
|
+
----------
|
|
51
|
+
device : str
|
|
52
|
+
The device to move the model to (e.g., 'cpu' or 'cuda').
|
|
53
|
+
|
|
54
|
+
"""
|
|
55
|
+
self.device = device
|
|
56
|
+
if self.model is not None and hasattr(self.model, "to"):
|
|
57
|
+
self.model.to(device)
|
|
58
|
+
if hasattr(self.model, "device"):
|
|
59
|
+
try:
|
|
60
|
+
self.model.device = device
|
|
61
|
+
except AttributeError:
|
|
62
|
+
pass
|
|
63
|
+
|
|
45
64
|
def extract_features(self, audio: Audio, layers: list[int]) -> Features:
|
|
46
65
|
"""Extract features from the input audio data.
|
|
47
66
|
|
|
@@ -58,9 +58,6 @@ class Data2VecModel(FrameLevelFeatureModel):
|
|
|
58
58
|
self.variant = validate_enum(variant, Data2VecVariant, Data2VecVariant.BASE)
|
|
59
59
|
self._model_id = f"data2vec-{self.variant.value}"
|
|
60
60
|
|
|
61
|
-
self.processor = None
|
|
62
|
-
self.model = None
|
|
63
|
-
|
|
64
61
|
def load(self, model_dir: str, quiet: bool = False) -> None:
|
|
65
62
|
"""Load the model from the specified directory.
|
|
66
63
|
|
|
@@ -58,9 +58,6 @@ class Data2Vec2Model(FrameLevelFeatureModel):
|
|
|
58
58
|
self.variant = validate_enum(variant, Data2Vec2Variant, Data2Vec2Variant.BASE)
|
|
59
59
|
self._model_id = f"data2vec2-{self.variant.value}"
|
|
60
60
|
|
|
61
|
-
self.processor = None
|
|
62
|
-
self.model = None
|
|
63
|
-
|
|
64
61
|
def load(self, model_dir: str, quiet: bool = False) -> None:
|
|
65
62
|
"""Load the model from the specified directory.
|
|
66
63
|
|
|
@@ -40,8 +40,6 @@ class EcapaTDNNModel(UtteranceLevelFeatureModel):
|
|
|
40
40
|
self.variant = validate_enum(variant, EcapaTDNNVariant, EcapaTDNNVariant.BASE)
|
|
41
41
|
self._model_id = f"ecapa-tdnn-{self.variant.value}"
|
|
42
42
|
|
|
43
|
-
self.model = None
|
|
44
|
-
|
|
45
43
|
def load(self, model_dir: str, quiet: bool = False) -> None:
|
|
46
44
|
"""Load the model from the specified directory.
|
|
47
45
|
|
|
@@ -78,11 +76,11 @@ class EcapaTDNNModel(UtteranceLevelFeatureModel):
|
|
|
78
76
|
self.model = EncoderClassifier.from_hparams(
|
|
79
77
|
source="speechbrain/spkrec-ecapa-voxceleb",
|
|
80
78
|
fetch_config=fetch_config,
|
|
79
|
+
run_opts={"device": self.device},
|
|
81
80
|
)
|
|
82
81
|
if self.model is None:
|
|
83
82
|
raise RuntimeError("Failed to load the model.")
|
|
84
83
|
self.model.eval()
|
|
85
|
-
self.model.to(self.device)
|
|
86
84
|
|
|
87
85
|
def extract_features_impl(self, audio: Audio, layers: list[int]) -> Features:
|
|
88
86
|
"""Extract features from the input audio using the model.
|
|
@@ -55,8 +55,6 @@ class Emotion2VecModel(FrameLevelFeatureModel):
|
|
|
55
55
|
)
|
|
56
56
|
self._model_id = f"emotion2vec-{self.variant.value}"
|
|
57
57
|
|
|
58
|
-
self.model = None
|
|
59
|
-
|
|
60
58
|
def load(self, model_dir: str, quiet: bool = False) -> None:
|
|
61
59
|
"""Load the model from the specified directory.
|
|
62
60
|
|
|
@@ -78,7 +76,7 @@ class Emotion2VecModel(FrameLevelFeatureModel):
|
|
|
78
76
|
repo_id=repo_id,
|
|
79
77
|
filename=filename,
|
|
80
78
|
repo_type="model",
|
|
81
|
-
|
|
79
|
+
cache_dir=model_dir,
|
|
82
80
|
)
|
|
83
81
|
|
|
84
82
|
setup_third_party_path()
|
|
@@ -58,8 +58,6 @@ class Emotion2VecPlusModel(FrameLevelFeatureModel):
|
|
|
58
58
|
)
|
|
59
59
|
self._model_id = f"emotion2vec+-{self.variant.value}"
|
|
60
60
|
|
|
61
|
-
self.model = None
|
|
62
|
-
|
|
63
61
|
def load(self, model_dir: str, quiet: bool = False) -> None:
|
|
64
62
|
"""Load the model from the specified directory.
|
|
65
63
|
|
|
@@ -81,13 +79,13 @@ class Emotion2VecPlusModel(FrameLevelFeatureModel):
|
|
|
81
79
|
repo_id=repo_id,
|
|
82
80
|
filename="model.pt",
|
|
83
81
|
repo_type="model",
|
|
84
|
-
|
|
82
|
+
cache_dir=os.path.join(model_dir, sanitize(self.model_id)),
|
|
85
83
|
)
|
|
86
84
|
config = hf_hub_download(
|
|
87
85
|
repo_id=repo_id,
|
|
88
86
|
filename="config.yaml",
|
|
89
87
|
repo_type="model",
|
|
90
|
-
|
|
88
|
+
cache_dir=os.path.join(model_dir, sanitize(self.model_id)),
|
|
91
89
|
)
|
|
92
90
|
|
|
93
91
|
from hyperpyyaml import load_hyperpyyaml
|
|
@@ -60,8 +60,6 @@ class HuBERTModel(FrameLevelFeatureModel):
|
|
|
60
60
|
self.variant = validate_enum(variant, HuBERTVariant, HuBERTVariant.BASE)
|
|
61
61
|
self._model_id = f"hubert-{self.variant.value}"
|
|
62
62
|
|
|
63
|
-
self.model = None
|
|
64
|
-
|
|
65
63
|
def load(self, model_dir: str, quiet: bool = False) -> None:
|
|
66
64
|
"""Load the model from the specified directory.
|
|
67
65
|
|
|
@@ -32,6 +32,19 @@ class ModelManager:
|
|
|
32
32
|
|
|
33
33
|
self._cache: dict[str, BaseModel] = {}
|
|
34
34
|
|
|
35
|
+
def to(self, device: str) -> None:
|
|
36
|
+
"""Move all models to the specified device.
|
|
37
|
+
|
|
38
|
+
Parameters
|
|
39
|
+
----------
|
|
40
|
+
device : str
|
|
41
|
+
The device to move the models to (e.g., 'cpu' or 'cuda').
|
|
42
|
+
|
|
43
|
+
"""
|
|
44
|
+
self.device = device
|
|
45
|
+
for model in self._cache.values():
|
|
46
|
+
model.to(device)
|
|
47
|
+
|
|
35
48
|
def get_model(self) -> BaseModel:
|
|
36
49
|
"""Get the model instance.
|
|
37
50
|
|
|
@@ -66,8 +66,6 @@ class NeXtTDNNModel(UtteranceLevelFeatureModel):
|
|
|
66
66
|
self.variant = validate_enum(variant, NeXtTDNNVariant, NeXtTDNNVariant.BASE_V2)
|
|
67
67
|
self._model_id = f"next-tdnn-{self.variant.value}"
|
|
68
68
|
|
|
69
|
-
self.model = None
|
|
70
|
-
|
|
71
69
|
def load(self, model_dir: str, quiet: bool = False) -> None:
|
|
72
70
|
"""Load the model from the specified directory.
|
|
73
71
|
|
|
@@ -63,8 +63,6 @@ class RSpinModel(FrameLevelFeatureModel):
|
|
|
63
63
|
self.variant = validate_enum(variant, RSpinVariant, RSpinVariant.WAVLM_256)
|
|
64
64
|
self._model_id = f"r-spin-{self.variant.value}"
|
|
65
65
|
|
|
66
|
-
self.model = None
|
|
67
|
-
|
|
68
66
|
def load(self, model_dir: str, quiet: bool = False) -> None:
|
|
69
67
|
"""Load the model from the specified directory.
|
|
70
68
|
|
|
@@ -40,8 +40,6 @@ class RVectorModel(UtteranceLevelFeatureModel):
|
|
|
40
40
|
self.variant = validate_enum(variant, RVectorVariant, RVectorVariant.BASE)
|
|
41
41
|
self._model_id = f"r-vector-{self.variant.value}"
|
|
42
42
|
|
|
43
|
-
self.model = None
|
|
44
|
-
|
|
45
43
|
def load(self, model_dir: str, quiet: bool = False) -> None:
|
|
46
44
|
"""Load the model from the specified directory.
|
|
47
45
|
|
|
@@ -78,11 +76,11 @@ class RVectorModel(UtteranceLevelFeatureModel):
|
|
|
78
76
|
self.model = EncoderClassifier.from_hparams(
|
|
79
77
|
source="speechbrain/spkrec-resnet-voxceleb",
|
|
80
78
|
fetch_config=fetch_config,
|
|
79
|
+
run_opts={"device": self.device},
|
|
81
80
|
)
|
|
82
81
|
if self.model is None:
|
|
83
82
|
raise RuntimeError("Failed to load the model.")
|
|
84
83
|
self.model.eval()
|
|
85
|
-
self.model.to(self.device)
|
|
86
84
|
|
|
87
85
|
def extract_features_impl(self, audio: Audio, layers: list[int]) -> Features:
|
|
88
86
|
"""Extract features from the input audio using the model.
|
|
@@ -4,12 +4,11 @@
|
|
|
4
4
|
"""A module for the SpidR model."""
|
|
5
5
|
|
|
6
6
|
from enum import Enum
|
|
7
|
-
from typing import Any
|
|
8
7
|
|
|
9
8
|
import torch
|
|
10
9
|
|
|
11
10
|
from ..interfaces.types import Audio, Features
|
|
12
|
-
from ..utils.io import
|
|
11
|
+
from ..utils.io import safe_torch_hub_load
|
|
13
12
|
from ..utils.validation import validate_enum
|
|
14
13
|
from .base import FrameLevelFeatureModel
|
|
15
14
|
|
|
@@ -40,8 +39,6 @@ class SpidRModel(FrameLevelFeatureModel):
|
|
|
40
39
|
self.variant = validate_enum(variant, SpidRVariant, SpidRVariant.BASE)
|
|
41
40
|
self._model_id = f"spidr-{self.variant.value}"
|
|
42
41
|
|
|
43
|
-
self.model = None
|
|
44
|
-
|
|
45
42
|
def load(self, model_dir: str, quiet: bool = False) -> None:
|
|
46
43
|
"""Load the model from the specified directory.
|
|
47
44
|
|
|
@@ -57,10 +54,9 @@ class SpidRModel(FrameLevelFeatureModel):
|
|
|
57
54
|
if self.model is not None:
|
|
58
55
|
return
|
|
59
56
|
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
)
|
|
57
|
+
self.model = safe_torch_hub_load(
|
|
58
|
+
"facebookresearch/spidr", "spidr_base", model_dir, quiet=quiet
|
|
59
|
+
)
|
|
64
60
|
self.model.eval()
|
|
65
61
|
self.model.to(self.device)
|
|
66
62
|
|
|
@@ -117,8 +117,6 @@ class SpinModel(FrameLevelFeatureModel):
|
|
|
117
117
|
self.variant = validate_enum(variant, SpinVariant, SpinVariant.HUBERT_256)
|
|
118
118
|
self._model_id = f"spin-{self.variant.value}"
|
|
119
119
|
|
|
120
|
-
self.model = None
|
|
121
|
-
|
|
122
120
|
def load(self, model_dir: str, quiet: bool = False) -> None:
|
|
123
121
|
"""Load the model from the specified directory.
|
|
124
122
|
|
|
@@ -139,7 +137,7 @@ class SpinModel(FrameLevelFeatureModel):
|
|
|
139
137
|
repo_id="vectominist/spin_ckpt",
|
|
140
138
|
filename=self.variant.checkpoint_filename,
|
|
141
139
|
repo_type="dataset",
|
|
142
|
-
|
|
140
|
+
cache_dir=model_dir,
|
|
143
141
|
)
|
|
144
142
|
|
|
145
143
|
with lightning_mock_context():
|
|
@@ -147,11 +145,12 @@ class SpinModel(FrameLevelFeatureModel):
|
|
|
147
145
|
model_path, map_location=torch.device("cpu"), weights_only=False
|
|
148
146
|
)
|
|
149
147
|
|
|
150
|
-
from lfeats.third_party.s3prl.util.download import set_dir
|
|
148
|
+
from lfeats.third_party.s3prl.util.download import set_dir, set_progress
|
|
151
149
|
from lfeats.third_party.spin.model import SpinModel as _SpinModel
|
|
152
150
|
from lfeats.third_party.spin.util import len_to_padding
|
|
153
151
|
|
|
154
152
|
set_dir(model_dir)
|
|
153
|
+
set_progress(not quiet)
|
|
155
154
|
self.model = _SpinModel(checkpoint["hyper_parameters"])
|
|
156
155
|
self.model.load_state_dict(checkpoint["state_dict"])
|
|
157
156
|
self.model.eval()
|
|
@@ -63,6 +63,19 @@ class SSLZipModel(FrameLevelFeatureModel):
|
|
|
63
63
|
self.upstream = HuBERTModel(variant=HuBERTVariant.BASE.value, device=device)
|
|
64
64
|
self.model = None
|
|
65
65
|
|
|
66
|
+
def to(self, device: str) -> None:
|
|
67
|
+
"""Move the model to the specified device.
|
|
68
|
+
|
|
69
|
+
Parameters
|
|
70
|
+
----------
|
|
71
|
+
device : str
|
|
72
|
+
The device to move the model to (e.g., 'cpu' or 'cuda'). Note that the ONNX
|
|
73
|
+
model will be loaded on the specified device when calling the 'load' method.
|
|
74
|
+
|
|
75
|
+
"""
|
|
76
|
+
self.device = device
|
|
77
|
+
self.upstream.to(device)
|
|
78
|
+
|
|
66
79
|
def load(self, model_dir: str, quiet: bool = False) -> None:
|
|
67
80
|
"""Load the model from the specified directory.
|
|
68
81
|
|
|
@@ -86,7 +99,7 @@ class SSLZipModel(FrameLevelFeatureModel):
|
|
|
86
99
|
repo_id=repo_id,
|
|
87
100
|
filename=filename,
|
|
88
101
|
repo_type="model",
|
|
89
|
-
|
|
102
|
+
cache_dir=model_dir,
|
|
90
103
|
)
|
|
91
104
|
|
|
92
105
|
import onnxruntime as ort
|
|
@@ -64,9 +64,6 @@ class Wav2Vec2Model(FrameLevelFeatureModel):
|
|
|
64
64
|
self.variant = validate_enum(variant, Wav2Vec2Variant, Wav2Vec2Variant.BASE)
|
|
65
65
|
self._model_id = f"wav2vec2-{self.variant.value}"
|
|
66
66
|
|
|
67
|
-
self.processor = None
|
|
68
|
-
self.model = None
|
|
69
|
-
|
|
70
67
|
def load(self, model_dir: str, quiet: bool = False) -> None:
|
|
71
68
|
"""Load the model from the specified directory.
|
|
72
69
|
|
|
@@ -54,8 +54,6 @@ class WavLMModel(FrameLevelFeatureModel):
|
|
|
54
54
|
self.variant = validate_enum(variant, WavLMVariant, WavLMVariant.BASE_PLUS)
|
|
55
55
|
self._model_id = f"wavlm-{self.variant.value}"
|
|
56
56
|
|
|
57
|
-
self.model = None
|
|
58
|
-
|
|
59
57
|
def load(self, model_dir: str, quiet: bool = False) -> None:
|
|
60
58
|
"""Load the model from the specified directory.
|
|
61
59
|
|
|
@@ -58,7 +58,6 @@ class WhisperModel(FrameLevelFeatureModel):
|
|
|
58
58
|
self._model_id = f"whisper-{self.variant.value}"
|
|
59
59
|
|
|
60
60
|
self.processor = None
|
|
61
|
-
self.model = None
|
|
62
61
|
|
|
63
62
|
def load(self, model_dir: str, quiet: bool = False) -> None:
|
|
64
63
|
"""Load the model from the specified directory.
|
|
@@ -40,8 +40,6 @@ class XVectorModel(UtteranceLevelFeatureModel):
|
|
|
40
40
|
self.variant = validate_enum(variant, XVectorVariant, XVectorVariant.BASE)
|
|
41
41
|
self._model_id = f"x-vector-{self.variant.value}"
|
|
42
42
|
|
|
43
|
-
self.model = None
|
|
44
|
-
|
|
45
43
|
def load(self, model_dir: str, quiet: bool = False) -> None:
|
|
46
44
|
"""Load the model from the specified directory.
|
|
47
45
|
|
|
@@ -78,11 +76,11 @@ class XVectorModel(UtteranceLevelFeatureModel):
|
|
|
78
76
|
self.model = EncoderClassifier.from_hparams(
|
|
79
77
|
source="speechbrain/spkrec-xvect-voxceleb",
|
|
80
78
|
fetch_config=fetch_config,
|
|
79
|
+
run_opts={"device": self.device},
|
|
81
80
|
)
|
|
82
81
|
if self.model is None:
|
|
83
82
|
raise RuntimeError("Failed to load the model.")
|
|
84
83
|
self.model.eval()
|
|
85
|
-
self.model.to(self.device)
|
|
86
84
|
|
|
87
85
|
def extract_features_impl(self, audio: Audio, layers: list[int]) -> Features:
|
|
88
86
|
"""Extract features from the input audio using the model.
|
|
@@ -35,6 +35,17 @@ class BaseResampler(ABC):
|
|
|
35
35
|
self.dst_rate = dst_rate
|
|
36
36
|
self.device = device
|
|
37
37
|
|
|
38
|
+
def to(self, device: str) -> None:
|
|
39
|
+
"""Move the resampler to the specified device.
|
|
40
|
+
|
|
41
|
+
Parameters
|
|
42
|
+
----------
|
|
43
|
+
device : str
|
|
44
|
+
The device to move the resampler to (e.g., 'cpu' or 'cuda').
|
|
45
|
+
|
|
46
|
+
"""
|
|
47
|
+
self.device = device
|
|
48
|
+
|
|
38
49
|
def resample(self, audio: Audio) -> Audio:
|
|
39
50
|
"""Resample the given audio to the target sample rate.
|
|
40
51
|
|
|
@@ -56,7 +56,19 @@ class LilFilterResampler(BaseResampler):
|
|
|
56
56
|
dst_rate,
|
|
57
57
|
dtype=torch.float32,
|
|
58
58
|
)
|
|
59
|
-
self.
|
|
59
|
+
self.to(device)
|
|
60
|
+
|
|
61
|
+
def to(self, device: str) -> None:
|
|
62
|
+
"""Move the resampler to the specified device.
|
|
63
|
+
|
|
64
|
+
Parameters
|
|
65
|
+
----------
|
|
66
|
+
device : str
|
|
67
|
+
The device to move the resampler to (e.g., 'cpu' or 'cuda').
|
|
68
|
+
|
|
69
|
+
"""
|
|
70
|
+
super().to(device)
|
|
71
|
+
self.resampler.weights = self.resampler.weights.to(device)
|
|
60
72
|
|
|
61
73
|
def resample_impl(self, audio: Audio) -> Audio:
|
|
62
74
|
"""Resample the given audio to the target sample rate.
|
|
@@ -32,6 +32,19 @@ class ResamplerManager:
|
|
|
32
32
|
|
|
33
33
|
self._cache: dict[tuple[int, int], BaseResampler] = {}
|
|
34
34
|
|
|
35
|
+
def to(self, device: str) -> None:
|
|
36
|
+
"""Move all resamplers to the specified device.
|
|
37
|
+
|
|
38
|
+
Parameters
|
|
39
|
+
----------
|
|
40
|
+
device : str
|
|
41
|
+
The device to move the resamplers to (e.g., 'cpu' or 'cuda').
|
|
42
|
+
|
|
43
|
+
"""
|
|
44
|
+
self.device = device
|
|
45
|
+
for resampler in self._cache.values():
|
|
46
|
+
resampler.to(device)
|
|
47
|
+
|
|
35
48
|
def get_resampler(self, src_rate: int, dst_rate: int) -> BaseResampler:
|
|
36
49
|
"""Get the resampler instance.
|
|
37
50
|
|
|
@@ -73,7 +73,20 @@ class TorchAudioResampler(BaseResampler):
|
|
|
73
73
|
|
|
74
74
|
self.resampler = torchaudio.transforms.Resample(
|
|
75
75
|
orig_freq=src_rate, new_freq=dst_rate, dtype=torch.float32, **params
|
|
76
|
-
)
|
|
76
|
+
)
|
|
77
|
+
self.to(device)
|
|
78
|
+
|
|
79
|
+
def to(self, device: str) -> None:
|
|
80
|
+
"""Move the resampler to the specified device.
|
|
81
|
+
|
|
82
|
+
Parameters
|
|
83
|
+
----------
|
|
84
|
+
device : str
|
|
85
|
+
The device to move the resampler to (e.g., 'cpu' or 'cuda').
|
|
86
|
+
|
|
87
|
+
"""
|
|
88
|
+
super().to(device)
|
|
89
|
+
self.resampler.to(device)
|
|
77
90
|
|
|
78
91
|
def resample_impl(self, audio: Audio) -> Audio:
|
|
79
92
|
"""Resample the given audio to the target sample rate.
|