o
    pi*I                     @  s8  d dl mZ d dlZd dlZd dlmZ d dlmZ d dlm	Z	 d dl
mZ d dlmZmZmZmZ d dlZd dlmZ d dlZd dlmZ d d	lmZ d d
lmZ d dlmZ d dlmZmZ d dl m!Z! d dl"m#Z#m$Z$ d dl%m&Z& d dl'm(Z( d dl)m*Z*m+Z+ d dl,m-Z. 				dd ddZ/G dd de.Z-dS )!    )annotationsN)OrderedDict)Iteratorpartial)Path)CallableDictListOptional)Audio)BaseInference)	AudioFile)Model)track_pipeline_applytrack_pipeline_init)check_dependencies)AssetFileNamedownload_from_hf_hub)fix_reproducibility)get_class_by_name)
FileFinderProtocolFile)Pipelinemodel_id
str | Noneparent_revision	cache_dirPath | str | NonetokenreturnNonec           
      C  s$  t | trH|  D ]<\}}t |tr<|dr<d|ddd }d|v r/|d\}}n|}|||||d| |< q	t|||||d q	dS t | trt	| D ]>\}	}t |tr|drd|ddd }d|v rw|d\}}n|}|||||d| |	< qQt|||||d qQdS dS )a  Expand $model subfolders in config

    Processes `config` dictionary recursively and replaces "$model/{subfolder}"
    values with {"checkpoint": model_id,
                 "subfolder": {subfolder},
                 "token": token}

    Parameters
    ----------
    config : dict
    model_id : str, optional
        Model identifier when loading from the huggingface.co model hub.
    parent_revision : str, optional
        Revision when loading from the huggingface.co model hub.
    token : str or bool, optional
        Huggingface token to be used for downloading from Huggingface hub.
    cache_dir: Path or str, optional
        Path to the folder where files downloaded from Huggingface hub are stored.
    z$model//   N@)
checkpointrevision	subfolderr   r   r   r   r   )

isinstancedictitemsstr
startswithjoinsplitexpand_subfolderslist	enumerate)
configr   r   r   r   keyvaluer'   r&   idx r7   P/home/ubuntu/.local/lib/python3.10/site-packages/pyannote/audio/core/pipeline.pyr0   1   sV   

	r0   c                      s   e Zd Ze				d0d1ddZ fddZ fddZ fddZ fddZe	d2d3ddZ
dd  Zd4d"d#Zd5d6d'd(Zd7d+d,Zd2d8d.d/Z  ZS )9r   Nr%   str | Path | dictr&   r   hparams_filestr | Path | Noner   str | bool | Noner   r   r    Optional['Pipeline']c              
   C  s  t |tr|durtdt }|}d}nZtj|r1|dur$tdt|}|tj	j
 }	d}n?tj|rI|dur?tdt|j}|}	d}n't|}d|v rUtdt|tj	|||d}	|	du redS | drn|nd}t |tst|	d	}
tj|
tjd
}W d   n1 sw   Y  t|||||d d|v rd|d i|d< |d= |dt }t|d |d d }t|dd}|d di }|d| |d| |di |}||_||_t| d|v r|d }|| d|v r||d  |dur	|| d|v rZi }|di   D ]>\}}t |tr;t|d dd}|di }|di |||< qz
t!|d||< W q t"yV   |}|||< Y qw ||_#d|v rt$%|d }z|&| W |S  t'y } zt(| W Y d}~|S d}~ww |S )a  Load pretrained pipeline

        Parameters
        ----------
        checkpoint : str
            Pipeline checkpoint, provided as one of the following:
            * path to a local `config.yaml` pipeline checkpoint
            * path to a local directory containing such a file
            * identifier (str) of a pipeline on huggingface.co model hub
            * dictionary containing the actual content of a config file
        revision : str, optional
            Revision when loading from the huggingface.co model hub.
        hparams_file: Path or str, optional
        token : str or bool, optional
            Token to be used for the download.
        cache_dir: Path or str, optional
            Path to the folder where cached files are stored.
        Nz0Revisions cannot be used with local checkpoints.localr$   z:Revisions must be passed with `revision` keyword argument.)r&   r   r   )z	pyannote/zpyannoteai/huggingfacer)Loaderr(   versionzpyannote.audiodependenciesr   pipelinenamezpyannote.pipeline.blocks)default_module_nameparamsr   r   freezepreprocessors)database_ymldevicer7   ))r)   r*   
ValueErrorr   cwdospathisdirr   r   r5   isfileparentr,   r   lowerr-   openyamlload
SafeLoaderr0   getr   r   
setdefault_otel_origin
_otel_namer   rH   instantiateload_paramsr+   r   FileNotFoundErrorrI   torchrK   toRuntimeErrorprint)clsr%   r&   r:   r   r   r   r3   otel_origin
config_ymlfprC   pipeline_nameKlassrG   rD   rI   r4   preprocessortemplaterK   er7   r7   r8   from_pretrained   s   









zPipeline.from_pretrainedc                   s   t    t | _t | _d S N)super__init__r   _models_inferencesself	__class__r7   r8   ro   /  s   
zPipeline.__init__c                   sT   d| j v r| j d }||v r|| S d| j v r$| j d }||v r$|| S t |S )z(Advanced) attribute getter

        Adds support for Model and Inference attributes,
        which are iterated over by Pipeline.to() method.

        See pyannote.pipeline.Pipeline.__getattr__.
        rp   rq   )__dict__rn   __getattr__)rs   rE   rp   rq   rt   r7   r8   rw   4  s   
	


zPipeline.__getattr__c           
        s    fdd}| j d}| j d}| j d}| j d}| j d}t|tjrC|du r4d	}	t|	|| j |||| || < dS t|tra|du rRd
}	t|	|| j |||| || < dS t  | dS )z(Advanced) attribute setter

        Adds support for Model and Inference attributes,
        which are iterated over by Pipeline.to() method.

        See pyannote.pipeline.Pipeline.__setattr__.
        c                    s   | D ]	} |v r| = qd S rm   r7   )dictsdrE   r7   r8   remove_fromR  s
   z)Pipeline.__setattr__.<locals>.remove_from_parameters_instantiated
_pipelinesrp   rq   Nz4cannot assign models before Pipeline.__init__() callz8cannot assign inferences before Pipeline.__init__() call)	rv   rX   r)   nnModuleAttributeErrorr   rn   __setattr__)
rs   rE   r5   r{   r|   r}   r~   rp   rq   msgrt   rz   r8   r   I  s.   	
zPipeline.__setattr__c                   s<   || j v r| j |= d S || jv r| j|= d S t | d S rm   )rp   rq   rn   __delattr__)rs   rE   rt   r7   r8   r   q  s
   

zPipeline.__delattr__filer   hookCallable | Noner   c                 C  s   dd }t |p|| dS )Nc                  _  s   d S rm   r7   )argskwargsr7   r7   r8   noop}  s   z!Pipeline.setup_hook.<locals>.noop)r   r   )r   r   r   r7   r7   r8   
setup_hook{  s   zPipeline.setup_hookc                 C     t  rm   NotImplementedErrorrr   r7   r7   r8   default_parameters  s   zPipeline.default_parametersList | Iteratorc                 C  r   )a  Classes returned by the pipeline

        Returns
        -------
        classes : list of string or string iterator
            Finite list of strings when classes are known in advance
            (e.g. ["MALE", "FEMALE"] for gender classification), or
            infinite string iterator when they depend on the file
            (e.g. "SPEAKER_00", "SPEAKER_01", ... for speaker diarization)

        Usage
        -----
        >>> from collections.abc import Iterator
        >>> classes = pipeline.classes()
        >>> if isinstance(classes, Iterator):  # classes depend on the input file
        >>> if isinstance(classes, list):      # classes are known in advance

        r   rr   r7   r7   r8   classes  s   zPipeline.classesFpreloadboolc                 K  s  t t| dtd | js<z|  }W n ty   tdw z| | W n t	y2   tdw t
d| d t|}t| drMt|| jd}|rqd	t| dt v s\d	|v r`t	d
t |\|d	< |d< |dd t| |fi | | j|fi |S )a  Validate file, (optionally) load it in memory, then process it

        Parameters
        ----------
        file : AudioFile
            File to process
        preload : bool, optional
            Whether to preload waveform before applying the pipeline.
        kwargs : keyword arguments, optional
            Additional keyword arguments passed to `self.apply(...)`

        Returns
        -------
        output : Any
            Whatever `self.apply(...)` returns
        rK   cpuzaA pipeline must be instantiated with `pipeline.instantiate(parameters)` before it can be applied.zA pipeline must be instantiated with `pipeline.instantiate(paramaters)` before it can be applied. Tried to use parameters provided by `pipeline.default_parameters()` but those are not compatible. z6The pipeline has been automatically instantiated with .rI   )lazywaveformzXCannot preload audio: `waveform` key is already available or will be via a preprocessor.sample_ratechannelN)r   getattrr_   rK   instantiatedr   r   ra   r\   rL   warningswarnr   validate_filehasattrr   rI   r*   popr   apply)rs   r   r   r   r   r7   r7   r8   __call__  s@   


zPipeline.__call__rK   torch.devicec                 C  s   t |tjstdt|j d| j D ]\}}t|dr$|	|}q| j
 D ]	\}}|	|}q*| j D ]	\}}|	|}q9|| _| S )zSend pipeline to `device`z5`device` must be an instance of `torch.device`, got ``r`   )r)   r_   rK   	TypeErrortype__name__r~   r+   r   r`   rp   rq   )rs   rK   _rD   model	inferencer7   r7   r8   r`     s   

zPipeline.totorch.device | int | Nonec                 C  sP   |du r|  tdS t|tr|  td|S |jdkr#td|  |S )z3Send pipeline to (optionally specified) cuda deviceNcudazBExpected CUDA device. Use `Pipeline.to(device)` for other devices.)r`   r_   rK   r)   intr   rL   )rs   rK   r7   r7   r8   r     s   


zPipeline.cudaNNNN)r%   r9   r&   r   r:   r;   r   r<   r   r   r    r=   rm   )r   r   r   r   r    r   )r    r   )F)r   r   r   r   )rK   r   r    r   )rK   r   r    r   )r   
__module____qualname__classmethodrl   ro   rw   r   r   staticmethodr   r   r   r   r`   r   __classcell__r7   r7   rt   r8   r      s&     ((


Fr   r   )
r   r   r   r   r   r   r   r   r    r!   )0
__future__r   rN   r   collectionsr   collections.abcr   	functoolsr   pathlibr   typingr   r	   r
   r   r_   torch.nnr   rU   pyannote.audior   pyannote.audio.core.inferencer   pyannote.audio.core.ior   pyannote.audio.core.modelr   pyannote.audio.telemetryr   r   !pyannote.audio.utils.dependenciesr   pyannote.audio.utils.hf_hubr   r   $pyannote.audio.utils.reproducibilityr   pyannote.core.utils.helperr   pyannote.databaser   r   pyannote.pipeliner   	_Pipeliner0   r7   r7   r7   r8   <module>   s8   U