o
    ۷iV                     @   s:  d Z ddlZddlZddlZddlZddlZddl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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mZ ddlmZ eeZ dZ!e"e#ddZ$e% Z&dd Z'dd Z(de)ej*B fddZ+dd Z,dd Z-dd Z.dd Z/d4d!d"Z0d#d$ Z1e			 				 	d5d%e)ej*B d&e)d'e)dB d(e)ej*B dB d)e2d*e3e)e)f dB d+e2e)B dB d,e)dB d-e2d.e)dB fd/d0Z4e				 				 	d6d%e)ej*B d&e)d'e)dB d1e)dB d(e)ej*B dB d)e2d*e3e)e)f dB d+e2e)B dB d,e)dB d-e2d.e)dB fd2d3Z5dS )7z3Utilities to dynamically load objects from the Hub.    N)Path)
ModuleType)request)hf_hub_download
model_info)RevisionNotFoundErrorvalidate_hf_hub_args)version   )__version__   )DIFFUSERS_DYNAMIC_MODULE_NAMEHF_MODULES_CACHElogging)DIFFUSERS_DISABLE_REMOTE_CODEz$diffusers/community-pipelines-mirrorDIFFUSERS_TIMEOUT_REMOTE_CODE   c                  C   s0   d} t t|  d  }t|dd dS )Nz$https://pypi.org/pypi/diffusers/jsonreleasesc                 S   s
   t | S )N)r	   Version)x r   [/home/ubuntu/vllm_env/lib/python3.10/site-packages/diffusers/utils/dynamic_modules_utils.py<lambda>1   s   
 z(get_diffusers_versions.<locals>.<lambda>)key)jsonloadsr   urlopenreadkeyssorted)urlr   r   r   r   get_diffusers_versions.   s   r!   c                  C   sL   t tjv rdS tjt  tjt dd tt d } |  s$|   dS dS )z_
    Creates the cache directory for modules with an init, and adds it to the Python path.
    NTexist_ok__init__.py)	r   syspathappendosmakedirsr   existstouch)	init_pathr   r   r   init_hf_modules4   s   
r-   namec                 C   sT   t   tt|  }|j st|j tj|dd |d }| s(|  dS dS )zF
    Creates a dynamic module in the cache directory for modules.
    Tr"   r$   N)	r-   r   r   parentr*   create_dynamic_moduler(   r)   r+   )r.   dynamic_module_pathr,   r   r   r   r0   C   s   

r0   c                 C   sj   t | ddd}| }W d   n1 sw   Y  tjd|tjd}|tjd|tjd7 }tt|S )z
    Get the list of modules that are relatively imported in a module file.

    Args:
        module_file (`str` or `os.PathLike`): The module file to inspect.
    rutf-8encodingNz^\s*import\s+\.(\S+)\s*$flagsz^\s*from\s+\.(\S+)\s+import)openr   refindall	MULTILINElistset)module_filefcontentrelative_importsr   r   r   get_relative_importsR   s   
rB   c                    s   d}| g}g  |sBg }|D ]	}| t| qt| jfdd|D } fdd|D }dd |D }t|dk}  | |r	 S )a)  
    Get the list of all files that are needed for a given module. Note that this function recurses through the relative
    imports (if a imports b and b imports c, it will return module files for b and c).

    Args:
        module_file (`str` or `os.PathLike`): The module file to inspect.
    Fc                    s   g | ]}t  | qS r   )str).0m)module_pathr   r   
<listcomp>w       z-get_relative_import_files.<locals>.<listcomp>c                    s   g | ]}| vr|qS r   r   rD   r?   )all_relative_importsr   r   rG   x   rH   c                 S   s   g | ]}| d qS ).pyr   rI   r   r   r   rG   y   s    r   )extendrB   r   r/   len)r>   	no_changefiles_to_checknew_importsr?   new_import_filesr   )rJ   rF   r   get_relative_import_filesd   s   

rR   c              	   C   s   t | ddd}| }W d   n1 sw   Y  tjd|tjd}|tjd|tjd7 }dd	 |D }tt|}g }|D ]}zt| W q@ t	yW   |
| Y q@w t|d
krptdd| dd| d t| S )zi
    Check if the current Python environment contains all the libraries that are imported in a file.
    r2   r3   r4   Nz^\s*import\s+(\S+)\s*$r6   z^\s*from\s+(\S+)\s+importc                 S   s$   g | ]}| d s|d d qS ).r   )
startswithsplit)rD   impr   r   r   rG      s   $ z!check_imports.<locals>.<listcomp>r   zaThis modeling file might require the following packages that were not found in your environment: , z. Run `pip install  `)r8   r   r9   r:   r;   r<   r=   	importlibimport_moduleImportErrorr'   rM   loggerwarningjoinrB   )filenamer?   r@   importsmissing_packagesrV   r   r   r   check_imports   s.   
rc   c                 C   sb   | ot  } t rtd |r"| s"d| d}|t rdnd7 }t||r/| r/td| d | S )NzDownloading remote code is disabled globally via the DIFFUSERS_DISABLE_REMOTE_CODE environment variable. Ignoring `trust_remote_code`.zThe repository for z contains custom code. zhDownloading remote code is disabled globally via the DIFFUSERS_DISABLE_REMOTE_CODE environment variable.zCPass `trust_remote_code=True` to allow loading remote code modules.z6`trust_remote_code` is enabled. Downloading code from z9. Please ensure you trust the contents of this repository)r   r]   r^   
ValueError)trust_remote_code
model_namehas_remote_code	error_msgr   r   r   resolve_trust_remote_code   s$   

ri   Fc                 C   s   t j|}|dr|dd }|t jjd}tt| }t; |r/t	j
|d t  t	j
|}tjj||d}|du rMtj|}|t	j
|< n|}|j| W d   n1 s_w   Y  | du rlt|S t|| S )zY
    Import a module on the cache directory for modules and extract a class from it.
    rK   NrS   )location)r(   r&   normpathendswithreplacesepr   r   _HF_REMOTE_CODE_LOCKr%   modulespoprZ   invalidate_cachesgetutilspec_from_file_locationmodule_from_specloaderexec_modulefind_pipeline_classgetattr)
class_namerF   force_reloadr.   r>   cached_modulemodule_specmoduler   r   r   get_class_in_module   s(   

r   c                 C   s   ddl m} tt| tj}d}| D ]1\}}||jkrFt||rF|j	
dd dkrF|durDtd|j d|j d	| d
|  d	|}q|S )z
    Retrieve pipeline class that inherits from `DiffusionPipeline`. Note that there has to be exactly one class
    inheriting from `DiffusionPipeline`.
    r
   )DiffusionPipelineNrS   r   	diffusersz#Multiple classes that inherit from z have been found: z, and z). Please make sure to define only one in )	pipelinesr   dictinspect
getmembersisclassitems__name__
issubclass
__module__rU   rd   )loaded_moduler   cls_memberspipeline_classcls_nameclsr   r   r   rz      s*   

rz   pretrained_model_name_or_pathr>   	subfolder	cache_dirforce_downloadproxiestokenrevisionlocal_files_only	local_dirc
                 C   s  t | } |durtj| ||}
ntj| |}
tj|
r#|
}d}n| ddkrt }ddtddd  }|du rU|dd |v rI|nd	}t	
d
| d n"||v r_d| }n|d	krf|}ntd| dd|d	g  dzttd| d|  d|||||	d}d}| d }W nZ ty } z	td| d|d}~w ty   t	d| d|  d  w zt| |||||||	||d
}tjdd| d}W n ty   t	d| d|  d  w t|}ttjj | }t| tt| }|dks|dkrft|||  |D ]N}t|ddkrAd|d}|dd }tj|| sAt||  | d}|durTtj| ||}ntj| |}t|||  qnxt| ||dj}|| }|tjj | }t| ||  st|ddkr|dd }tj|| st||  t|||  |D ]-}t|ddkrd|d}||  st| | d||||||||	d
 qtj||S )a	  
    Prepares Downloads a module from a local folder or a distant repo and returns its path inside the cached
    Transformers module.

    Args:
        pretrained_model_name_or_path (`str` or `os.PathLike`):
            This can be either:

            - a string, the *model id* of a pretrained model configuration hosted inside a model repo on
              huggingface.co. Valid model ids can be located at the root-level, like `bert-base-uncased`, or namespaced
              under a user or organization name, like `dbmdz/bert-base-german-cased`.
            - a path to a *directory* containing a configuration file saved using the
              [`~PreTrainedTokenizer.save_pretrained`] method, e.g., `./my_model_directory/`.

        module_file (`str`):
            The name of the module file containing the class to look for.
        cache_dir (`str` or `os.PathLike`, *optional*):
            Path to a directory in which a downloaded pretrained model configuration should be cached if the standard
            cache should not be used.
        force_download (`bool`, *optional*, defaults to `False`):
            Whether or not to force to (re-)download the configuration files and override the cached versions if they
            exist.
        proxies (`dict[str, str]`, *optional*):
            A dictionary of proxy servers to use by protocol or endpoint, e.g., `{'http': 'foo.bar:3128',
            'http://hostname': 'foo.bar:4012'}.` The proxies are used on each request.
        token (`str` or *bool*, *optional*):
            The token to use as HTTP bearer authorization for remote files. If `True`, will use the token generated
            when running `transformers-cli login` (stored in `~/.huggingface`).
        revision (`str`, *optional*, defaults to `"main"`):
            The specific model version to use. It can be a branch name, a tag name, or a commit id, since we use a
            git-based system for storing models and other artifacts on huggingface.co, so `revision` can be any
            identifier allowed by git.
        local_files_only (`bool`, *optional*, defaults to `False`):
            If `True`, will only try to load the tokenizer configuration from local files.

    > [!TIP] > You may pass a token in `token` if you are not logged in (`hf auth login`) and want to use private or
    [gated > models](https://huggingface.co/docs/hub/models-gated#gated-models).

    Returns:
        `str`: The path to the module inside the cache.
    Nlocal/r   vrS      r   mainzDefaulting to latest_version: z`custom_revision`: z3 does not exist. Please make sure to choose one of rW   datasetrK   )repo_id	repo_typer`   r   r   r   r   r   gitz
Revision 'a  ' not found in the community pipelines mirror. Check available revisions on https://huggingface.co/datasets/diffusers/community-pipelines-mirror/tree/main. If you don't find the revision you are looking for, please open an issue on https://github.com/huggingface/diffusers/issues.zCould not locate the z inside )r   r   r   r   r   r   r   r   z--r
   )r   r   r   r   r   r   r   r   r   r   )rC   r(   r&   r_   isfilecountr!   r   rU   r]   inford   r   COMMUNITY_PIPELINES_MIRROR_IDr   EnvironmentErrorerrorrc   r   ro   r0   r   r   shutilcopyfilerM   r*   r)   r   shaget_cached_module_file)r   r>   r   r   r   r   r   r   r   r   module_file_or_urlresolved_module_file	submoduleavailable_versionslatest_versionemodules_neededfull_submodulesubmodule_pathmodule_neededmodule_foldersource_pathcommit_hashr   r   r   r      s   7



r   r|   c                 C   s&   t | ||||||||	|
d
}t||S )a  
    Extracts a class from a module file, present in the local folder or repository of a model.

    > [!WARNING] > Calling this function will execute the code in the module file found locally or downloaded from the
    Hub. It should > therefore only be called on trusted repos.

    Args:
        pretrained_model_name_or_path (`str` or `os.PathLike`):
            This can be either:

            - a string, the *model id* of a pretrained model configuration hosted inside a model repo on
              huggingface.co. Valid model ids can be located at the root-level, like `bert-base-uncased`, or namespaced
              under a user or organization name, like `dbmdz/bert-base-german-cased`.
            - a path to a *directory* containing a configuration file saved using the
              [`~PreTrainedTokenizer.save_pretrained`] method, e.g., `./my_model_directory/`.

        module_file (`str`):
            The name of the module file containing the class to look for.
        class_name (`str`):
            The name of the class to import in the module.
        cache_dir (`str` or `os.PathLike`, *optional*):
            Path to a directory in which a downloaded pretrained model configuration should be cached if the standard
            cache should not be used.
        force_download (`bool`, *optional*, defaults to `False`):
            Whether or not to force to (re-)download the configuration files and override the cached versions if they
            exist.
        proxies (`dict[str, str]`, *optional*):
            A dictionary of proxy servers to use by protocol or endpoint, e.g., `{'http': 'foo.bar:3128',
            'http://hostname': 'foo.bar:4012'}.` The proxies are used on each request.
        token (`str` or `bool`, *optional*):
            The token to use as HTTP bearer authorization for remote files. If `True`, will use the token generated
            when running `transformers-cli login` (stored in `~/.huggingface`).
        revision (`str`, *optional*, defaults to `"main"`):
            The specific model version to use. It can be a branch name, a tag name, or a commit id, since we use a
            git-based system for storing models and other artifacts on huggingface.co, so `revision` can be any
            identifier allowed by git.
        local_files_only (`bool`, *optional*, defaults to `False`):
            If `True`, will only try to load the tokenizer configuration from local files.

    > [!TIP] > You may pass a token in `token` if you are not logged in (`hf auth login`) and want to use private or
    [gated > models](https://huggingface.co/docs/hub/models-gated#gated-models).

    Returns:
        `type`: The class, dynamically imported from the module.

    Examples:

    ```python
    # Download module `modeling.py` from huggingface.co and cache then extract the class `MyBertModel` from this
    # module.
    cls = get_class_from_dynamic_module("sgugger/my-bert-model", "modeling.py", "MyBertModel")
    ```r   )r   r   )r   r>   r   r|   r   r   r   r   r   r   r   final_moduler   r   r   get_class_from_dynamic_module  s   C
r   )F)NNFNNNFN)	NNNFNNNFN)6__doc__rZ   r   r   r(   r9   r   r%   	threadingpathlibr   typesr   urllibr   huggingface_hubr   r   huggingface_hub.utilsr   r   	packagingr	    r   r   r   r   	constantsr   
get_loggerr   r]   r   intgetenvTIME_OUT_REMOTE_CODELockrp   r!   r-   rC   PathLiker0   rB   rR   rc   ri   r   rz   boolr   r   r   r   r   r   r   <module>   s   
 
!
	
 <
	
