lfeats 0.2.0__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.0 → lfeats-0.2.2}/.gitignore +1 -0
- {lfeats-0.2.0 → lfeats-0.2.2}/PKG-INFO +34 -13
- {lfeats-0.2.0 → lfeats-0.2.2}/README.md +28 -9
- {lfeats-0.2.0 → lfeats-0.2.2}/lfeats/cli.py +18 -26
- {lfeats-0.2.0 → lfeats-0.2.2}/lfeats/interfaces/extractor.py +24 -0
- {lfeats-0.2.0 → lfeats-0.2.2}/lfeats/interfaces/types.py +77 -0
- {lfeats-0.2.0 → lfeats-0.2.2}/lfeats/models/__init__.py +9 -1
- {lfeats-0.2.0 → lfeats-0.2.2}/lfeats/models/base.py +52 -0
- {lfeats-0.2.0 → lfeats-0.2.2}/lfeats/models/ecapa_tdnn.py +4 -2
- lfeats-0.2.2/lfeats/models/higgs_audio.py +148 -0
- {lfeats-0.2.0 → lfeats-0.2.2}/lfeats/models/hubert.py +3 -5
- {lfeats-0.2.0 → lfeats-0.2.2}/lfeats/models/next_tdnn.py +4 -2
- lfeats-0.2.2/lfeats/models/redimnet.py +106 -0
- {lfeats-0.2.0 → lfeats-0.2.2}/lfeats/models/unispeech_sat.py +2 -2
- {lfeats-0.2.0 → lfeats-0.2.2}/lfeats/models/wavlm.py +2 -2
- lfeats-0.2.2/lfeats/models/wavlm_sv.py +120 -0
- {lfeats-0.2.0 → lfeats-0.2.2}/lfeats/models/whisper.py +2 -2
- lfeats-0.2.2/lfeats/models/x_codec.py +128 -0
- {lfeats-0.2.0 → lfeats-0.2.2}/lfeats/models/x_vector.py +4 -2
- {lfeats-0.2.0 → lfeats-0.2.2}/lfeats/resamplers/__init__.py +3 -1
- lfeats-0.2.2/lfeats/resamplers/scipy.py +90 -0
- {lfeats-0.2.0 → lfeats-0.2.2}/lfeats/third_party/s3prl/util/download.py +10 -3
- {lfeats-0.2.0 → lfeats-0.2.2}/lfeats/utils/io.py +51 -30
- {lfeats-0.2.0 → lfeats-0.2.2}/lfeats/utils/validation.py +27 -0
- {lfeats-0.2.0 → lfeats-0.2.2}/lfeats/version.py +1 -1
- {lfeats-0.2.0 → lfeats-0.2.2}/pyproject.toml +5 -3
- {lfeats-0.2.0 → lfeats-0.2.2}/LICENSE +0 -0
- {lfeats-0.2.0 → lfeats-0.2.2}/lfeats/__init__.py +0 -0
- {lfeats-0.2.0 → lfeats-0.2.2}/lfeats/interfaces/__init__.py +0 -0
- {lfeats-0.2.0 → lfeats-0.2.2}/lfeats/interfaces/resampler.py +0 -0
- {lfeats-0.2.0 → lfeats-0.2.2}/lfeats/interfaces/utils.py +0 -0
- {lfeats-0.2.0 → lfeats-0.2.2}/lfeats/models/contentvec.py +0 -0
- {lfeats-0.2.0 → lfeats-0.2.2}/lfeats/models/data2vec.py +0 -0
- {lfeats-0.2.0 → lfeats-0.2.2}/lfeats/models/data2vec2.py +0 -0
- {lfeats-0.2.0 → lfeats-0.2.2}/lfeats/models/emotion2vec.py +0 -0
- {lfeats-0.2.0 → lfeats-0.2.2}/lfeats/models/emotion2vec_plus.py +0 -0
- {lfeats-0.2.0 → lfeats-0.2.2}/lfeats/models/manager.py +0 -0
- {lfeats-0.2.0 → lfeats-0.2.2}/lfeats/models/r_spin.py +0 -0
- {lfeats-0.2.0 → lfeats-0.2.2}/lfeats/models/r_vector.py +0 -0
- {lfeats-0.2.0 → lfeats-0.2.2}/lfeats/models/spidr.py +0 -0
- {lfeats-0.2.0 → lfeats-0.2.2}/lfeats/models/spin.py +0 -0
- {lfeats-0.2.0 → lfeats-0.2.2}/lfeats/models/sslzip.py +0 -0
- {lfeats-0.2.0 → lfeats-0.2.2}/lfeats/models/wav2vec2.py +0 -0
- {lfeats-0.2.0 → lfeats-0.2.2}/lfeats/resamplers/base.py +0 -0
- {lfeats-0.2.0 → lfeats-0.2.2}/lfeats/resamplers/lilfilter.py +0 -0
- {lfeats-0.2.0 → lfeats-0.2.2}/lfeats/resamplers/manager.py +0 -0
- {lfeats-0.2.0 → lfeats-0.2.2}/lfeats/resamplers/soxr.py +0 -0
- {lfeats-0.2.0 → lfeats-0.2.2}/lfeats/resamplers/torchaudio.py +0 -0
- {lfeats-0.2.0 → lfeats-0.2.2}/lfeats/third_party/__init__.py +0 -0
- {lfeats-0.2.0 → lfeats-0.2.2}/lfeats/third_party/fairseq/LICENSE +0 -0
- {lfeats-0.2.0 → lfeats-0.2.2}/lfeats/third_party/fairseq/__init__.py +0 -0
- {lfeats-0.2.0 → lfeats-0.2.2}/lfeats/third_party/fairseq/checkpoint_utils.py +0 -0
- {lfeats-0.2.0 → lfeats-0.2.2}/lfeats/third_party/fairseq/config/__init__.py +0 -0
- {lfeats-0.2.0 → lfeats-0.2.2}/lfeats/third_party/fairseq/config/config.yaml +0 -0
- {lfeats-0.2.0 → lfeats-0.2.2}/lfeats/third_party/fairseq/data/__init__.py +0 -0
- {lfeats-0.2.0 → lfeats-0.2.2}/lfeats/third_party/fairseq/data/dictionary.py +0 -0
- {lfeats-0.2.0 → lfeats-0.2.2}/lfeats/third_party/fairseq/data/modality.py +0 -0
- {lfeats-0.2.0 → lfeats-0.2.2}/lfeats/third_party/fairseq/data/text_compressor.py +0 -0
- {lfeats-0.2.0 → lfeats-0.2.2}/lfeats/third_party/fairseq/dataclass/__init__.py +0 -0
- {lfeats-0.2.0 → lfeats-0.2.2}/lfeats/third_party/fairseq/dataclass/configs.py +0 -0
- {lfeats-0.2.0 → lfeats-0.2.2}/lfeats/third_party/fairseq/dataclass/constants.py +0 -0
- {lfeats-0.2.0 → lfeats-0.2.2}/lfeats/third_party/fairseq/dataclass/initialize.py +0 -0
- {lfeats-0.2.0 → lfeats-0.2.2}/lfeats/third_party/fairseq/dataclass/utils.py +0 -0
- {lfeats-0.2.0 → lfeats-0.2.2}/lfeats/third_party/fairseq/file_io.py +0 -0
- {lfeats-0.2.0 → lfeats-0.2.2}/lfeats/third_party/fairseq/incremental_decoding_utils.py +0 -0
- {lfeats-0.2.0 → lfeats-0.2.2}/lfeats/third_party/fairseq/logging/__init__.py +0 -0
- {lfeats-0.2.0 → lfeats-0.2.2}/lfeats/third_party/fairseq/logging/meters.py +0 -0
- {lfeats-0.2.0 → lfeats-0.2.2}/lfeats/third_party/fairseq/models/__init__.py +0 -0
- {lfeats-0.2.0 → lfeats-0.2.2}/lfeats/third_party/fairseq/models/data2vec/__init__.py +0 -0
- {lfeats-0.2.0 → lfeats-0.2.2}/lfeats/third_party/fairseq/models/data2vec/data2vec2.py +0 -0
- {lfeats-0.2.0 → lfeats-0.2.2}/lfeats/third_party/fairseq/models/data2vec/data2vec_audio.py +0 -0
- {lfeats-0.2.0 → lfeats-0.2.2}/lfeats/third_party/fairseq/models/data2vec/modalities/__init__.py +0 -0
- {lfeats-0.2.0 → lfeats-0.2.2}/lfeats/third_party/fairseq/models/data2vec/modalities/audio.py +0 -0
- {lfeats-0.2.0 → lfeats-0.2.2}/lfeats/third_party/fairseq/models/data2vec/modalities/base.py +0 -0
- {lfeats-0.2.0 → lfeats-0.2.2}/lfeats/third_party/fairseq/models/data2vec/modalities/modules.py +0 -0
- {lfeats-0.2.0 → lfeats-0.2.2}/lfeats/third_party/fairseq/models/fairseq_decoder.py +0 -0
- {lfeats-0.2.0 → lfeats-0.2.2}/lfeats/third_party/fairseq/models/fairseq_encoder.py +0 -0
- {lfeats-0.2.0 → lfeats-0.2.2}/lfeats/third_party/fairseq/models/fairseq_incremental_decoder.py +0 -0
- {lfeats-0.2.0 → lfeats-0.2.2}/lfeats/third_party/fairseq/models/fairseq_model.py +0 -0
- {lfeats-0.2.0 → lfeats-0.2.2}/lfeats/third_party/fairseq/models/hubert/__init__.py +0 -0
- {lfeats-0.2.0 → lfeats-0.2.2}/lfeats/third_party/fairseq/models/hubert/hubert.py +0 -0
- {lfeats-0.2.0 → lfeats-0.2.2}/lfeats/third_party/fairseq/models/wav2vec/__init__.py +0 -0
- {lfeats-0.2.0 → lfeats-0.2.2}/lfeats/third_party/fairseq/models/wav2vec/utils.py +0 -0
- {lfeats-0.2.0 → lfeats-0.2.2}/lfeats/third_party/fairseq/models/wav2vec/wav2vec2.py +0 -0
- {lfeats-0.2.0 → lfeats-0.2.2}/lfeats/third_party/fairseq/modules/__init__.py +0 -0
- {lfeats-0.2.0 → lfeats-0.2.2}/lfeats/third_party/fairseq/modules/ema_module.py +0 -0
- {lfeats-0.2.0 → lfeats-0.2.2}/lfeats/third_party/fairseq/modules/fairseq_dropout.py +0 -0
- {lfeats-0.2.0 → lfeats-0.2.2}/lfeats/third_party/fairseq/modules/fp32_group_norm.py +0 -0
- {lfeats-0.2.0 → lfeats-0.2.2}/lfeats/third_party/fairseq/modules/gelu.py +0 -0
- {lfeats-0.2.0 → lfeats-0.2.2}/lfeats/third_party/fairseq/modules/gumbel_vector_quantizer.py +0 -0
- {lfeats-0.2.0 → lfeats-0.2.2}/lfeats/third_party/fairseq/modules/layer_norm.py +0 -0
- {lfeats-0.2.0 → lfeats-0.2.2}/lfeats/third_party/fairseq/modules/multihead_attention.py +0 -0
- {lfeats-0.2.0 → lfeats-0.2.2}/lfeats/third_party/fairseq/modules/quant_noise.py +0 -0
- {lfeats-0.2.0 → lfeats-0.2.2}/lfeats/third_party/fairseq/modules/same_pad.py +0 -0
- {lfeats-0.2.0 → lfeats-0.2.2}/lfeats/third_party/fairseq/modules/transpose_last.py +0 -0
- {lfeats-0.2.0 → lfeats-0.2.2}/lfeats/third_party/fairseq/quantization_utils.py +0 -0
- {lfeats-0.2.0 → lfeats-0.2.2}/lfeats/third_party/fairseq/registry.py +0 -0
- {lfeats-0.2.0 → lfeats-0.2.2}/lfeats/third_party/fairseq/tasks/__init__.py +0 -0
- {lfeats-0.2.0 → lfeats-0.2.2}/lfeats/third_party/fairseq/tasks/audio_pretraining.py +0 -0
- {lfeats-0.2.0 → lfeats-0.2.2}/lfeats/third_party/fairseq/tasks/fairseq_task.py +0 -0
- {lfeats-0.2.0 → lfeats-0.2.2}/lfeats/third_party/fairseq/tasks/hubert_pretraining.py +0 -0
- {lfeats-0.2.0 → lfeats-0.2.2}/lfeats/third_party/fairseq/tokenizer.py +0 -0
- {lfeats-0.2.0 → lfeats-0.2.2}/lfeats/third_party/fairseq/utils.py +0 -0
- {lfeats-0.2.0 → lfeats-0.2.2}/lfeats/third_party/next_tdnn_asv/LICENSE +0 -0
- {lfeats-0.2.0 → lfeats-0.2.2}/lfeats/third_party/next_tdnn_asv/SpeakerNet.py +0 -0
- {lfeats-0.2.0 → lfeats-0.2.2}/lfeats/third_party/next_tdnn_asv/__init__.py +0 -0
- {lfeats-0.2.0 → lfeats-0.2.2}/lfeats/third_party/next_tdnn_asv/aggregation/__init__.py +0 -0
- {lfeats-0.2.0 → lfeats-0.2.2}/lfeats/third_party/next_tdnn_asv/aggregation/vap_bn_tanh_fc_bn.py +0 -0
- {lfeats-0.2.0 → lfeats-0.2.2}/lfeats/third_party/next_tdnn_asv/configs/NeXt_TDNN_C256_B3_K65_7.py +0 -0
- {lfeats-0.2.0 → 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.0 → lfeats-0.2.2}/lfeats/third_party/next_tdnn_asv/configs/NeXt_TDNN_light_C256_B3_K65.py +0 -0
- {lfeats-0.2.0 → lfeats-0.2.2}/lfeats/third_party/next_tdnn_asv/configs/__init__.py +0 -0
- {lfeats-0.2.0 → lfeats-0.2.2}/lfeats/third_party/next_tdnn_asv/main.py +0 -0
- {lfeats-0.2.0 → lfeats-0.2.2}/lfeats/third_party/next_tdnn_asv/models/NeXt_TDNN.py +0 -0
- {lfeats-0.2.0 → lfeats-0.2.2}/lfeats/third_party/next_tdnn_asv/models/TSConvNeXt.py +0 -0
- {lfeats-0.2.0 → lfeats-0.2.2}/lfeats/third_party/next_tdnn_asv/models/TSConvNeXt_light.py +0 -0
- {lfeats-0.2.0 → lfeats-0.2.2}/lfeats/third_party/next_tdnn_asv/models/__init__.py +0 -0
- {lfeats-0.2.0 → lfeats-0.2.2}/lfeats/third_party/next_tdnn_asv/models/utils.py +0 -0
- {lfeats-0.2.0 → lfeats-0.2.2}/lfeats/third_party/next_tdnn_asv/preprocessing/__init__.py +0 -0
- {lfeats-0.2.0 → lfeats-0.2.2}/lfeats/third_party/next_tdnn_asv/preprocessing/mel_transform.py +0 -0
- {lfeats-0.2.0 → lfeats-0.2.2}/lfeats/third_party/rspin/LICENSE +0 -0
- {lfeats-0.2.0 → lfeats-0.2.2}/lfeats/third_party/rspin/__init__.py +0 -0
- {lfeats-0.2.0 → lfeats-0.2.2}/lfeats/third_party/rspin/model.py +0 -0
- {lfeats-0.2.0 → lfeats-0.2.2}/lfeats/third_party/rspin/wavlm_config.py +0 -0
- {lfeats-0.2.0 → lfeats-0.2.2}/lfeats/third_party/s3prl/LICENSE +0 -0
- {lfeats-0.2.0 → lfeats-0.2.2}/lfeats/third_party/s3prl/__init__.py +0 -0
- {lfeats-0.2.0 → lfeats-0.2.2}/lfeats/third_party/s3prl/upstream/__init__.py +0 -0
- {lfeats-0.2.0 → lfeats-0.2.2}/lfeats/third_party/s3prl/upstream/hubert/__init__.py +0 -0
- {lfeats-0.2.0 → lfeats-0.2.2}/lfeats/third_party/s3prl/upstream/hubert/convert.py +0 -0
- {lfeats-0.2.0 → lfeats-0.2.2}/lfeats/third_party/s3prl/upstream/hubert/hubert_model.py +0 -0
- {lfeats-0.2.0 → lfeats-0.2.2}/lfeats/third_party/s3prl/upstream/utils.py +0 -0
- {lfeats-0.2.0 → lfeats-0.2.2}/lfeats/third_party/s3prl/upstream/wav2vec2/__init__.py +0 -0
- {lfeats-0.2.0 → lfeats-0.2.2}/lfeats/third_party/s3prl/upstream/wav2vec2/wav2vec2_model.py +0 -0
- {lfeats-0.2.0 → lfeats-0.2.2}/lfeats/third_party/s3prl/upstream/wavlm/WavLM.py +0 -0
- {lfeats-0.2.0 → lfeats-0.2.2}/lfeats/third_party/s3prl/upstream/wavlm/__init__.py +0 -0
- {lfeats-0.2.0 → lfeats-0.2.2}/lfeats/third_party/s3prl/upstream/wavlm/modules.py +0 -0
- {lfeats-0.2.0 → lfeats-0.2.2}/lfeats/third_party/s3prl/util/__init__.py +0 -0
- {lfeats-0.2.0 → lfeats-0.2.2}/lfeats/third_party/speechbrain/LICENSE +0 -0
- {lfeats-0.2.0 → lfeats-0.2.2}/lfeats/third_party/speechbrain/__init__.py +0 -0
- {lfeats-0.2.0 → lfeats-0.2.2}/lfeats/third_party/speechbrain/dataio/__init__.py +0 -0
- {lfeats-0.2.0 → lfeats-0.2.2}/lfeats/third_party/speechbrain/dataio/dataio.py +0 -0
- {lfeats-0.2.0 → lfeats-0.2.2}/lfeats/third_party/speechbrain/dataio/encoder.py +0 -0
- {lfeats-0.2.0 → lfeats-0.2.2}/lfeats/third_party/speechbrain/dataio/preprocess.py +0 -0
- {lfeats-0.2.0 → lfeats-0.2.2}/lfeats/third_party/speechbrain/inference/__init__.py +0 -0
- {lfeats-0.2.0 → lfeats-0.2.2}/lfeats/third_party/speechbrain/inference/classifiers.py +0 -0
- {lfeats-0.2.0 → lfeats-0.2.2}/lfeats/third_party/speechbrain/inference/interfaces.py +0 -0
- {lfeats-0.2.0 → lfeats-0.2.2}/lfeats/third_party/speechbrain/lobes/__init__.py +0 -0
- {lfeats-0.2.0 → lfeats-0.2.2}/lfeats/third_party/speechbrain/lobes/features.py +0 -0
- {lfeats-0.2.0 → lfeats-0.2.2}/lfeats/third_party/speechbrain/lobes/models/ECAPA_TDNN.py +0 -0
- {lfeats-0.2.0 → lfeats-0.2.2}/lfeats/third_party/speechbrain/lobes/models/ResNet.py +0 -0
- {lfeats-0.2.0 → lfeats-0.2.2}/lfeats/third_party/speechbrain/lobes/models/Xvector.py +0 -0
- {lfeats-0.2.0 → lfeats-0.2.2}/lfeats/third_party/speechbrain/lobes/models/__init__.py +0 -0
- {lfeats-0.2.0 → lfeats-0.2.2}/lfeats/third_party/speechbrain/nnet/CNN.py +0 -0
- {lfeats-0.2.0 → lfeats-0.2.2}/lfeats/third_party/speechbrain/nnet/containers.py +0 -0
- {lfeats-0.2.0 → lfeats-0.2.2}/lfeats/third_party/speechbrain/nnet/linear.py +0 -0
- {lfeats-0.2.0 → lfeats-0.2.2}/lfeats/third_party/speechbrain/nnet/normalization.py +0 -0
- {lfeats-0.2.0 → lfeats-0.2.2}/lfeats/third_party/speechbrain/nnet/pooling.py +0 -0
- {lfeats-0.2.0 → lfeats-0.2.2}/lfeats/third_party/speechbrain/processing/__init__.py +0 -0
- {lfeats-0.2.0 → lfeats-0.2.2}/lfeats/third_party/speechbrain/processing/features.py +0 -0
- {lfeats-0.2.0 → lfeats-0.2.2}/lfeats/third_party/speechbrain/utils/__init__.py +0 -0
- {lfeats-0.2.0 → lfeats-0.2.2}/lfeats/third_party/speechbrain/utils/_workarounds.py +0 -0
- {lfeats-0.2.0 → lfeats-0.2.2}/lfeats/third_party/speechbrain/utils/autocast.py +0 -0
- {lfeats-0.2.0 → lfeats-0.2.2}/lfeats/third_party/speechbrain/utils/checkpoints.py +0 -0
- {lfeats-0.2.0 → lfeats-0.2.2}/lfeats/third_party/speechbrain/utils/distributed.py +0 -0
- {lfeats-0.2.0 → lfeats-0.2.2}/lfeats/third_party/speechbrain/utils/fetching.py +0 -0
- {lfeats-0.2.0 → lfeats-0.2.2}/lfeats/third_party/speechbrain/utils/filter_analysis.py +0 -0
- {lfeats-0.2.0 → lfeats-0.2.2}/lfeats/third_party/speechbrain/utils/logger.py +0 -0
- {lfeats-0.2.0 → lfeats-0.2.2}/lfeats/third_party/speechbrain/utils/parameter_transfer.py +0 -0
- {lfeats-0.2.0 → lfeats-0.2.2}/lfeats/third_party/speechbrain/utils/run_opts.py +0 -0
- {lfeats-0.2.0 → lfeats-0.2.2}/lfeats/third_party/spin/LICENSE +0 -0
- {lfeats-0.2.0 → lfeats-0.2.2}/lfeats/third_party/spin/__init__.py +0 -0
- {lfeats-0.2.0 → lfeats-0.2.2}/lfeats/third_party/spin/model/__init__.py +0 -0
- {lfeats-0.2.0 → lfeats-0.2.2}/lfeats/third_party/spin/model/base.py +0 -0
- {lfeats-0.2.0 → lfeats-0.2.2}/lfeats/third_party/spin/model/spin.py +0 -0
- {lfeats-0.2.0 → lfeats-0.2.2}/lfeats/third_party/spin/nn/__init__.py +0 -0
- {lfeats-0.2.0 → lfeats-0.2.2}/lfeats/third_party/spin/nn/dnn.py +0 -0
- {lfeats-0.2.0 → lfeats-0.2.2}/lfeats/third_party/spin/nn/hubert.py +0 -0
- {lfeats-0.2.0 → lfeats-0.2.2}/lfeats/third_party/spin/nn/swav_vq_dis.py +0 -0
- {lfeats-0.2.0 → lfeats-0.2.2}/lfeats/third_party/spin/nn/wavlm.py +0 -0
- {lfeats-0.2.0 → lfeats-0.2.2}/lfeats/third_party/spin/util/__init__.py +0 -0
- {lfeats-0.2.0 → lfeats-0.2.2}/lfeats/third_party/spin/util/model_utils.py +0 -0
- {lfeats-0.2.0 → lfeats-0.2.2}/lfeats/third_party/spin/util/padding.py +0 -0
- {lfeats-0.2.0 → lfeats-0.2.2}/lfeats/third_party/timm/LICENSE +0 -0
- {lfeats-0.2.0 → lfeats-0.2.2}/lfeats/third_party/timm/__init__.py +0 -0
- {lfeats-0.2.0 → lfeats-0.2.2}/lfeats/third_party/timm/layers/__init__.py +0 -0
- {lfeats-0.2.0 → lfeats-0.2.2}/lfeats/third_party/timm/layers/drop.py +0 -0
- {lfeats-0.2.0 → lfeats-0.2.2}/lfeats/third_party/timm/layers/helpers.py +0 -0
- {lfeats-0.2.0 → lfeats-0.2.2}/lfeats/third_party/timm/layers/mlp.py +0 -0
- {lfeats-0.2.0 → lfeats-0.2.2}/lfeats/utils/__init__.py +0 -0
- {lfeats-0.2.0 → lfeats-0.2.2}/lfeats/utils/paths.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
|
|
@@ -28,11 +28,13 @@ Requires-Dist: onnxruntime>=1.19.0
|
|
|
28
28
|
Requires-Dist: parfive>=2.1.0
|
|
29
29
|
Requires-Dist: platformdirs>=2.0.0
|
|
30
30
|
Requires-Dist: requests>=2.27.0
|
|
31
|
+
Requires-Dist: scipy>=1.9.2
|
|
31
32
|
Requires-Dist: soundfile>=0.10.2
|
|
32
33
|
Requires-Dist: soxr>=0.4.0
|
|
33
34
|
Requires-Dist: torch>=2.6.0
|
|
34
35
|
Requires-Dist: torchaudio>=2.6.0
|
|
35
|
-
Requires-Dist:
|
|
36
|
+
Requires-Dist: tqdm>=4.63.0
|
|
37
|
+
Requires-Dist: transformers>=5.3.0
|
|
36
38
|
Provides-Extra: dev
|
|
37
39
|
Requires-Dist: build; extra == 'dev'
|
|
38
40
|
Requires-Dist: matplotlib; extra == 'dev'
|
|
@@ -40,7 +42,7 @@ Requires-Dist: mdformat; extra == 'dev'
|
|
|
40
42
|
Requires-Dist: numpydoc; extra == 'dev'
|
|
41
43
|
Requires-Dist: pkginfo; extra == 'dev'
|
|
42
44
|
Requires-Dist: pydata-sphinx-theme; extra == 'dev'
|
|
43
|
-
Requires-Dist: pyright; extra == 'dev'
|
|
45
|
+
Requires-Dist: pyright[nodejs]; extra == 'dev'
|
|
44
46
|
Requires-Dist: pytest; extra == 'dev'
|
|
45
47
|
Requires-Dist: pytest-cov; extra == 'dev'
|
|
46
48
|
Requires-Dist: ruff; extra == 'dev'
|
|
@@ -143,16 +145,33 @@ pip install git+https://github.com/takenori-y/lfeats.git@master
|
|
|
143
145
|
| | `large-v2` | 32 | 1280 | | | [🤗](https://huggingface.co/openai/whisper-large-v2) |
|
|
144
146
|
| | `large-v3` | 32 | 1280 | | | [🤗](https://huggingface.co/openai/whisper-large-v3) |
|
|
145
147
|
|
|
146
|
-
###
|
|
148
|
+
### Token-Level Features
|
|
147
149
|
|
|
148
|
-
| Model Name | Model Variant |
|
|
150
|
+
| Model Name | Model Variant | Hop Size [ms] | Dimension | Paper | Source | Model Hub |
|
|
149
151
|
| :--- | :--- | ---: | ---: | :---: | :---: | :---: |
|
|
150
|
-
| `
|
|
151
|
-
| `
|
|
152
|
-
| | `
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
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) |
|
|
155
|
+
|
|
156
|
+
### Utterance-Level Features
|
|
157
|
+
|
|
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) |
|
|
156
175
|
|
|
157
176
|
> [!IMPORTANT]
|
|
158
177
|
> Users must comply with the respective licenses of the models.
|
|
@@ -163,12 +182,14 @@ pip install git+https://github.com/takenori-y/lfeats.git@master
|
|
|
163
182
|
| Resampler Type | Quality Preset | Source | License |
|
|
164
183
|
| :--- | :--- | :---: | :--- |
|
|
165
184
|
| `lilfilter` | `base` | [GitHub](https://github.com/danpovey/filtering) | MIT |
|
|
185
|
+
| `scipy` | `fft` | [Document](https://docs.scipy.org/doc/scipy/reference/generated/scipy.signal.resample.html) | BSD 3-Clause |
|
|
186
|
+
| | `poly` | [Document](https://docs.scipy.org/doc/scipy/reference/generated/scipy.signal.resample_poly.html) | |
|
|
166
187
|
| `soxr` | `quick` | [GitHub](https://github.com/dofuuz/python-soxr) | LGPL v2.1+ |
|
|
167
188
|
| | `low` | | |
|
|
168
189
|
| | `medium` | | |
|
|
169
190
|
| | `high` | | |
|
|
170
191
|
| | `very-high` | | |
|
|
171
|
-
| `torchaudio` | `kaiser-fast` | [
|
|
192
|
+
| `torchaudio` | `kaiser-fast` | [Document](https://docs.pytorch.org/audio/stable/tutorials/audio_resampling_tutorial.html) | BSD 2-Clause |
|
|
172
193
|
| | `kaiser-best` | | |
|
|
173
194
|
|
|
174
195
|
## Examples
|
|
@@ -93,16 +93,33 @@ pip install git+https://github.com/takenori-y/lfeats.git@master
|
|
|
93
93
|
| | `large-v2` | 32 | 1280 | | | [🤗](https://huggingface.co/openai/whisper-large-v2) |
|
|
94
94
|
| | `large-v3` | 32 | 1280 | | | [🤗](https://huggingface.co/openai/whisper-large-v3) |
|
|
95
95
|
|
|
96
|
-
###
|
|
96
|
+
### Token-Level Features
|
|
97
97
|
|
|
98
|
-
| Model Name | Model Variant |
|
|
98
|
+
| Model Name | Model Variant | Hop Size [ms] | Dimension | Paper | Source | Model Hub |
|
|
99
99
|
| :--- | :--- | ---: | ---: | :---: | :---: | :---: |
|
|
100
|
-
| `
|
|
101
|
-
| `
|
|
102
|
-
| | `
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
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) |
|
|
103
|
+
|
|
104
|
+
### Utterance-Level Features
|
|
105
|
+
|
|
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) |
|
|
106
123
|
|
|
107
124
|
> [!IMPORTANT]
|
|
108
125
|
> Users must comply with the respective licenses of the models.
|
|
@@ -113,12 +130,14 @@ pip install git+https://github.com/takenori-y/lfeats.git@master
|
|
|
113
130
|
| Resampler Type | Quality Preset | Source | License |
|
|
114
131
|
| :--- | :--- | :---: | :--- |
|
|
115
132
|
| `lilfilter` | `base` | [GitHub](https://github.com/danpovey/filtering) | MIT |
|
|
133
|
+
| `scipy` | `fft` | [Document](https://docs.scipy.org/doc/scipy/reference/generated/scipy.signal.resample.html) | BSD 3-Clause |
|
|
134
|
+
| | `poly` | [Document](https://docs.scipy.org/doc/scipy/reference/generated/scipy.signal.resample_poly.html) | |
|
|
116
135
|
| `soxr` | `quick` | [GitHub](https://github.com/dofuuz/python-soxr) | LGPL v2.1+ |
|
|
117
136
|
| | `low` | | |
|
|
118
137
|
| | `medium` | | |
|
|
119
138
|
| | `high` | | |
|
|
120
139
|
| | `very-high` | | |
|
|
121
|
-
| `torchaudio` | `kaiser-fast` | [
|
|
140
|
+
| `torchaudio` | `kaiser-fast` | [Document](https://docs.pytorch.org/audio/stable/tutorials/audio_resampling_tutorial.html) | BSD 2-Clause |
|
|
122
141
|
| | `kaiser-best` | | |
|
|
123
142
|
|
|
124
143
|
## Examples
|
|
@@ -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",
|
|
@@ -147,9 +155,6 @@ def main() -> None:
|
|
|
147
155
|
datefmt="%Y-%m-%d %H:%M:%S",
|
|
148
156
|
)
|
|
149
157
|
|
|
150
|
-
import numpy as np
|
|
151
|
-
import torch
|
|
152
|
-
|
|
153
158
|
import lfeats
|
|
154
159
|
from lfeats.utils.io import load_audio
|
|
155
160
|
|
|
@@ -166,11 +171,13 @@ def main() -> None:
|
|
|
166
171
|
for root, _, files in os.walk(args.source):
|
|
167
172
|
for file in files:
|
|
168
173
|
input_files.append(os.path.join(root, file))
|
|
174
|
+
input_files = sorted(input_files)
|
|
169
175
|
else:
|
|
170
176
|
raise ValueError(f"Invalid source: {args.source}")
|
|
171
177
|
|
|
172
178
|
if len(input_files) == 0:
|
|
173
|
-
|
|
179
|
+
logging.info(f"No audio files found in the source: {args.source}")
|
|
180
|
+
sys.exit(0)
|
|
174
181
|
logger.info(f"Found {len(input_files)} audio files to process.")
|
|
175
182
|
|
|
176
183
|
# Parse the layers argument.
|
|
@@ -199,12 +206,15 @@ def main() -> None:
|
|
|
199
206
|
device=args.device,
|
|
200
207
|
cache_dir=args.cache_dir,
|
|
201
208
|
)
|
|
209
|
+
logger.info(f"Loading {extractor.get_model_id()} model...")
|
|
202
210
|
extractor.load(quiet=args.quiet)
|
|
203
211
|
|
|
204
212
|
num_errors = 0
|
|
205
213
|
|
|
206
214
|
# Process each input file and extract features.
|
|
207
|
-
for input_file in
|
|
215
|
+
for input_file in tqdm(
|
|
216
|
+
input_files, desc="Processing files", unit="file", disable=args.quiet
|
|
217
|
+
):
|
|
208
218
|
if not os.path.isfile(input_file):
|
|
209
219
|
logger.error(f"Could not find file: {input_file}. Skipping.")
|
|
210
220
|
num_errors += 1
|
|
@@ -216,7 +226,7 @@ def main() -> None:
|
|
|
216
226
|
path = Path(input_file).parent
|
|
217
227
|
# Remove the root part of the path.
|
|
218
228
|
dirs = path.relative_to(path.anchor).parts
|
|
219
|
-
if args.subdir_offset
|
|
229
|
+
if args.subdir_offset > len(dirs):
|
|
220
230
|
logger.error(
|
|
221
231
|
f"Subdir offset {args.subdir_offset} is too large for file: "
|
|
222
232
|
f"{input_file}. Skipping."
|
|
@@ -246,32 +256,14 @@ def main() -> None:
|
|
|
246
256
|
overlap_length_sec=args.overlap_length_sec,
|
|
247
257
|
upsample_factor=args.upsample_factor,
|
|
248
258
|
reduction=args.reduction,
|
|
259
|
+
normalize=args.normalize,
|
|
249
260
|
)
|
|
250
261
|
except Exception as e:
|
|
251
262
|
logger.error(f"Error processing file {input_file}: {e}. Skipping.")
|
|
252
263
|
num_errors += 1
|
|
253
264
|
continue
|
|
254
265
|
|
|
255
|
-
|
|
256
|
-
result = {
|
|
257
|
-
"features": features.array,
|
|
258
|
-
"source": features.source,
|
|
259
|
-
"layers": features.layers,
|
|
260
|
-
}
|
|
261
|
-
np.savez_compressed(output_file, **result)
|
|
262
|
-
elif args.output_format == "pt":
|
|
263
|
-
result = {
|
|
264
|
-
"features": features.tensor.cpu(),
|
|
265
|
-
"source": features.source,
|
|
266
|
-
"layers": features.layers,
|
|
267
|
-
}
|
|
268
|
-
torch.save(result, output_file)
|
|
269
|
-
elif args.output_format == "float":
|
|
270
|
-
features.array.tofile(output_file)
|
|
271
|
-
elif args.output_format == "double":
|
|
272
|
-
features.array.astype(np.float64).tofile(output_file)
|
|
273
|
-
else:
|
|
274
|
-
raise ValueError(f"Unsupported output format: {args.output_format}")
|
|
266
|
+
features.tofile(output_file, double=args.output_format == "double")
|
|
275
267
|
|
|
276
268
|
if num_errors > 0:
|
|
277
269
|
logger.error(f"{num_errors} files were skipped due to errors.")
|
|
@@ -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
|
|
@@ -9,6 +9,7 @@ from dataclasses import dataclass
|
|
|
9
9
|
from enum import Enum
|
|
10
10
|
|
|
11
11
|
import numpy as np
|
|
12
|
+
import soundfile as sf
|
|
12
13
|
import torch
|
|
13
14
|
import torch.nn.functional as F
|
|
14
15
|
|
|
@@ -164,6 +165,28 @@ class Audio(Container):
|
|
|
164
165
|
"""
|
|
165
166
|
return self.data.shape[1]
|
|
166
167
|
|
|
168
|
+
def tofile(self, path: str) -> None:
|
|
169
|
+
"""Save the audio to a file.
|
|
170
|
+
|
|
171
|
+
Parameters
|
|
172
|
+
----------
|
|
173
|
+
path : str
|
|
174
|
+
The path to save the audio to.
|
|
175
|
+
|
|
176
|
+
"""
|
|
177
|
+
ext = path.split(".")[-1].lower()
|
|
178
|
+
if ext in ("wav", "flac"):
|
|
179
|
+
sf.write(path, self.array.T, self.sample_rate)
|
|
180
|
+
elif ext == "npz":
|
|
181
|
+
np.savez_compressed(path, samples=self.array, sample_rate=self.sample_rate)
|
|
182
|
+
elif ext == "pt":
|
|
183
|
+
torch.save(
|
|
184
|
+
{"samples": self.tensor.cpu(), "sample_rate": self.sample_rate},
|
|
185
|
+
path,
|
|
186
|
+
)
|
|
187
|
+
else:
|
|
188
|
+
self.array.tofile(path)
|
|
189
|
+
|
|
167
190
|
def normalize(self, eps: float = 1e-5) -> Audio:
|
|
168
191
|
"""Normalize the audio samples to have zero mean and unit variance.
|
|
169
192
|
|
|
@@ -237,6 +260,40 @@ class Features(Container):
|
|
|
237
260
|
"""
|
|
238
261
|
return self.data.shape[1]
|
|
239
262
|
|
|
263
|
+
def tofile(self, path: str, double: bool = False) -> None:
|
|
264
|
+
"""Save the features to a file.
|
|
265
|
+
|
|
266
|
+
Parameters
|
|
267
|
+
----------
|
|
268
|
+
path : str
|
|
269
|
+
The path to save the features to.
|
|
270
|
+
|
|
271
|
+
double : bool, optional
|
|
272
|
+
Whether to save the features in double precision instead of single one.
|
|
273
|
+
|
|
274
|
+
"""
|
|
275
|
+
ext = path.split(".")[-1].lower()
|
|
276
|
+
if ext == "npz":
|
|
277
|
+
np.savez_compressed(
|
|
278
|
+
path,
|
|
279
|
+
features=self.array.astype(np.float64 if double else np.float32),
|
|
280
|
+
source=self.source,
|
|
281
|
+
layers=self.layers or [],
|
|
282
|
+
)
|
|
283
|
+
elif ext == "pt":
|
|
284
|
+
torch.save(
|
|
285
|
+
{
|
|
286
|
+
"features": self.tensor.cpu().to(
|
|
287
|
+
torch.float64 if double else torch.float32
|
|
288
|
+
),
|
|
289
|
+
"source": self.source,
|
|
290
|
+
"layers": self.layers,
|
|
291
|
+
},
|
|
292
|
+
path,
|
|
293
|
+
)
|
|
294
|
+
else:
|
|
295
|
+
self.array.astype(np.float64 if double else np.float32).tofile(path)
|
|
296
|
+
|
|
240
297
|
def trim(self, start: int, end: int) -> Features:
|
|
241
298
|
"""Trim the features along the time dimension.
|
|
242
299
|
|
|
@@ -299,6 +356,26 @@ class Features(Container):
|
|
|
299
356
|
|
|
300
357
|
return Features(data=reduced_data, source=self.source, layers=self.layers)
|
|
301
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
|
+
|
|
302
379
|
def concat(self, other: Features) -> Features:
|
|
303
380
|
"""Concatenate this Features instance with another one along the time dimension.
|
|
304
381
|
|
|
@@ -9,18 +9,22 @@ from .data2vec2 import Data2Vec2Model
|
|
|
9
9
|
from .ecapa_tdnn import EcapaTDNNModel
|
|
10
10
|
from .emotion2vec import Emotion2VecModel
|
|
11
11
|
from .emotion2vec_plus import Emotion2VecPlusModel
|
|
12
|
+
from .higgs_audio import HiggsAudioTokenizerModel
|
|
12
13
|
from .hubert import HuBERTModel
|
|
13
14
|
from .manager import ModelManager
|
|
14
15
|
from .next_tdnn import NeXtTDNNModel
|
|
15
16
|
from .r_spin import RSpinModel
|
|
16
17
|
from .r_vector import RVectorModel
|
|
18
|
+
from .redimnet import ReDimNetModel
|
|
17
19
|
from .spidr import SpidRModel
|
|
18
20
|
from .spin import SpinModel
|
|
19
21
|
from .sslzip import SSLZipModel
|
|
20
22
|
from .unispeech_sat import UniSpeechSATModel
|
|
21
23
|
from .wav2vec2 import Wav2Vec2Model
|
|
22
24
|
from .wavlm import WavLMModel
|
|
25
|
+
from .wavlm_sv import WavLMSVModel
|
|
23
26
|
from .whisper import WhisperModel
|
|
27
|
+
from .x_codec import XCodecModel
|
|
24
28
|
from .x_vector import XVectorModel
|
|
25
29
|
|
|
26
30
|
MODEL_MAP = {
|
|
@@ -30,21 +34,25 @@ MODEL_MAP = {
|
|
|
30
34
|
"ecapa-tdnn": EcapaTDNNModel,
|
|
31
35
|
"emotion2vec": Emotion2VecModel,
|
|
32
36
|
"emotion2vec+": Emotion2VecPlusModel,
|
|
37
|
+
"higgs-audio": HiggsAudioTokenizerModel,
|
|
33
38
|
"hubert": HuBERTModel,
|
|
34
39
|
"next-tdnn": NeXtTDNNModel,
|
|
35
40
|
"r-spin": RSpinModel,
|
|
36
41
|
"r-vector": RVectorModel,
|
|
42
|
+
"redimnet": ReDimNetModel,
|
|
37
43
|
"spidr": SpidRModel,
|
|
38
44
|
"spin": SpinModel,
|
|
39
45
|
"sslzip": SSLZipModel,
|
|
40
46
|
"unispeech-sat": UniSpeechSATModel,
|
|
41
47
|
"wav2vec2": Wav2Vec2Model,
|
|
42
48
|
"wavlm": WavLMModel,
|
|
49
|
+
"wavlm-sv": WavLMSVModel,
|
|
43
50
|
"whisper": WhisperModel,
|
|
51
|
+
"x-codec": XCodecModel,
|
|
44
52
|
"x-vector": XVectorModel,
|
|
45
53
|
}
|
|
46
54
|
|
|
47
55
|
__all__ = [
|
|
48
|
-
"ModelManager",
|
|
49
56
|
"MODEL_MAP",
|
|
57
|
+
"ModelManager",
|
|
50
58
|
]
|
|
@@ -256,6 +256,58 @@ class FrameLevelFeatureModel(BaseModel):
|
|
|
256
256
|
return Granularity.FRAME
|
|
257
257
|
|
|
258
258
|
|
|
259
|
+
class TokenLevelFeatureModel(BaseModel):
|
|
260
|
+
"""An abstract base class for frame-level feature extraction models."""
|
|
261
|
+
|
|
262
|
+
@property
|
|
263
|
+
def num_layers(self) -> int:
|
|
264
|
+
"""Get the number of layers in the model.
|
|
265
|
+
|
|
266
|
+
Returns
|
|
267
|
+
-------
|
|
268
|
+
out : int
|
|
269
|
+
The number of layers.
|
|
270
|
+
|
|
271
|
+
"""
|
|
272
|
+
return 0
|
|
273
|
+
|
|
274
|
+
@property
|
|
275
|
+
def frame_shift(self) -> int:
|
|
276
|
+
"""Get the frame shift of the model.
|
|
277
|
+
|
|
278
|
+
Returns
|
|
279
|
+
-------
|
|
280
|
+
out : int
|
|
281
|
+
The frame shift in samples.
|
|
282
|
+
|
|
283
|
+
"""
|
|
284
|
+
return int(20.0 * self.sample_rate / 1000)
|
|
285
|
+
|
|
286
|
+
@property
|
|
287
|
+
def center_offset(self) -> int:
|
|
288
|
+
"""Get the center offset of the model.
|
|
289
|
+
|
|
290
|
+
Returns
|
|
291
|
+
-------
|
|
292
|
+
out : int
|
|
293
|
+
The center offset in samples.
|
|
294
|
+
|
|
295
|
+
"""
|
|
296
|
+
return 0
|
|
297
|
+
|
|
298
|
+
@property
|
|
299
|
+
def granularity(self) -> Granularity:
|
|
300
|
+
"""Get the granularity of the features extracted by the model.
|
|
301
|
+
|
|
302
|
+
Returns
|
|
303
|
+
-------
|
|
304
|
+
out : str
|
|
305
|
+
The granularity of the features.
|
|
306
|
+
|
|
307
|
+
"""
|
|
308
|
+
return Granularity.FRAME
|
|
309
|
+
|
|
310
|
+
|
|
259
311
|
class UtteranceLevelFeatureModel(BaseModel):
|
|
260
312
|
"""An abstract base class for utterance-level feature extraction models."""
|
|
261
313
|
|
|
@@ -10,7 +10,7 @@ import torch
|
|
|
10
10
|
from ..interfaces.types import Audio, Features
|
|
11
11
|
from ..utils.io import silence_hf_hub
|
|
12
12
|
from ..utils.paths import setup_third_party_path
|
|
13
|
-
from ..utils.validation import validate_enum
|
|
13
|
+
from ..utils.validation import validate_enum, validate_length
|
|
14
14
|
from .base import UtteranceLevelFeatureModel
|
|
15
15
|
|
|
16
16
|
|
|
@@ -108,6 +108,8 @@ class EcapaTDNNModel(UtteranceLevelFeatureModel):
|
|
|
108
108
|
raise RuntimeError("Model is not loaded. Call 'load' method first.")
|
|
109
109
|
|
|
110
110
|
with torch.inference_mode():
|
|
111
|
-
|
|
111
|
+
inputs = audio.tensor.to(self.device)
|
|
112
|
+
inputs = validate_length(inputs, 640)
|
|
113
|
+
vectors = self.model.encode_batch(inputs)
|
|
112
114
|
|
|
113
115
|
return Features(data=vectors, source=self.model_id)
|