o
    wi                     @   s   d dl mZ d dlmZmZ d dlmZ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 ed	d
\ZZed	d\ZZed	d\ZZeeeefZeG dd dZdS )    )defaultdict)	dataclassfield)DictListSetN)ColumnParallelLinearRowParallelLinear)nnwildcard_match)safe_import_fromz+megatron.core.extensions.transformer_engineTEColumnParallelLinearTELayerNormColumnParallelLinearTERowParallelLinearc                   @   sr   e Zd ZU dZedd dZee ed< ee	dZ
ee ed< edd dZeeef ed< dd
ejfddZd	S )ModuleMatchera  
    Implements the LoRA (Low-Rank Adaptation) module for parameter-efficient fine-tuning.

    LoRA uses a low-rank projection to adapt the weights of a pre-trained model to a new downstream task.
    This class facilitates the application of LoRA to specific modules within the model architecture.

    Args:
        target_modules (List[str], optional): A list of module names to apply LoRA to.
            Defaults to all linear layers ['linear_qkv', 'linear_proj', 'linear_fc1', 'linear_fc2'].
                - 'linear_qkv': Apply LoRA to the fused linear layer used for query, key, and value projections
                                in self-attention.
                - 'linear_proj': Apply LoRA to the linear layer used for projecting the output of self-attention.
                - 'linear_fc1': Apply LoRA to the first fully-connected layer in MLP.
                - 'linear_fc2': Apply LoRA to the second fully-connected layer in MLP.
            Target modules can also contain wildcards. For example, you can specify
                target_modules=['*.layers.0.*.linear_qkv', '*.layers.1.*.linear_qkv'] to add LoRA to only linear_qkv
                on the first two layers.
    c                   C   s   g dS )N)
linear_qkvlinear_proj
linear_fc1
linear_fc2 r   r   r   e/home/ubuntu/sommelier/.venv/lib/python3.10/site-packages/nemo/collections/llm/peft/module_matcher.py<lambda>=       zModuleMatcher.<lambda>)default_factorytarget_modulesexclude_modulesc                   C   s   t tS N)r   setr   r   r   r   r   @   r   canonical_mappingNmc                    s2  |r	| d| n| t | jpg dkr5	 t | jdksJ | jD ]}||ks,t| r2| f  S q!dS t | jp:g dkr^t | jdksGJ | jD ]}||ksUt| r[| f  S qJdS tttjg}t	rk|
t trr|
t try|
t t|}|| jvrt fdd| jD st||r| fS dS )a  
        Determines whether a given module matches specified target patterns.

        This function checks if the provided module `m` should be included based on predefined
        mapping rules (`canonical_mapping`, `target_modules`, and `exclude_modules`). It returns
        the matching pattern if a match is found; otherwise, it returns `None`.

        Args:
            m (nn.Module): The module being checked.
            name (str, optional): The module's name.
            prefix (str, optional): A prefix to be used in constructing `full_name`.

        Returns:
            str or None: The matching pattern if a match is found; otherwise, `None`.

        Matching Logic:
        1) If `canonical_mapping` is defined, it checks:
        - Whether `name` exactly matches a pattern.
        - Whether `full_name` matches any regex pattern in `canonical_mapping`.
        2) If `target_modules` is defined, it follows the same logic as `canonical_mapping`.
        3) If neither `canonical_mapping` nor `target_modules` are defined, it ensures:
        - `name` is not in `exclude_modules`.
        - `full_name` does not match any `target_modules` patterns.
        - `m` is an instance of `nn.Linear`.

        Notes:
        - `exclude_modules` should only be non-empty if neither `canonical_mapping` nor `target_modules` are set.
        - The function asserts that `exclude_modules` is empty when using `canonical_mapping` or `target_modules`.
        .r   c                 3   s    | ]}t | V  qd S r   r   ).0pattern	full_namer   r   	<genexpr>~   s    z&ModuleMatcher.match.<locals>.<genexpr>N)lenr   r   r   r   r   r	   r
   LinearHAVE_TE_COL_LINEARappendr   HAVE_TE_LN_COL_LINEARr   HAVE_TE_ROW_LINEARr   tupleany
isinstance)selfr    nameprefixr#   linear_typesr   r$   r   matchB   s>   





zModuleMatcher.match)NN)__name__
__module____qualname____doc__r   r   r   str__annotations__listr   r   r   r   r
   Moduler4   r   r   r   r   r   '   s   
 r   )collectionsr   dataclassesr   r   typingr   r   r   torch.nnr
   megatron.core.tensor_parallelr   r	   torchnemo.collections.llm.peft.utilsr   nemo.utils.import_utilsr   r   r)   r   r+   r   r,   allHAVE_TEr   r   r   r   r   <module>   s*   