o
    Ni,                     @  s   d Z ddlmZ ddlZddlm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 d	dlmZ G dd deZ	ddddZdS ) zC
This module contains the implementation of the LoRA-FA optimizer.
    )annotationsN)Iterable)Callable)is_bf16_available)autocast)	Optimizer   )	PeftModel)infer_devicec                      sB   e Zd ZdZ					dd fddZe ddddZ  ZS )LoraFAOptimizera;  
    Implements the LoRA-FA optimizer designed specifically for training Low-Rank Adaptation (LoRA) parameters
    efficiently. Note that LoraFAOptimizer is based on adamw-hf in transformers, with only LoRA part modified. Without
    LoRA it will fall back to adamw-hf.

    Args:
        params (Iterable[nn.parameter.Parameter]): Parameters to optimize.
        lr (float, optional): Learning rate (default: 1e-3).
        betas (Tuple[float, float], optional):
            Coefficients for computing running averages of gradient and squared gradient (default: (0.9, 0.999)).
        eps (float, optional): Term added to denominator to improve numerical stability (default: 1e-6).
        weight_decay (float, optional): Weight decay (L2 penalty) (default: 0.0).
        correct_bias (bool, optional): Whether to apply bias correction as in original Adam (default: True).

    Args in sub-function step:
        closure (Callable, optional): A closure that reevaluates the model and returns the loss.

    Reference:
        - LoRA-FA: https://huggingface.co/papers/2308.03303
    MbP?g?g+?ư>        Tparams Iterable[nn.parameter.Parameter]lrfloatbetastuple[float, float]epsweight_decaycorrect_biasboolc                   s   |dk rt d| dd|d   krdk s#n t d|d  dd|d   kr/dk s:n t d|d  dd|ksFt d	| d|||||d
}t || d S )Nr   zInvalid learning rate: z - should be >= 0.0r         ?zInvalid beta parameter: z - should be in [0.0, 1.0)   zInvalid epsilon value: )r   r   r   r   r   )
ValueErrorsuper__init__)selfr   r   r   r   r   r   defaults	__class__ J/home/ubuntu/.local/lib/python3.10/site-packages/peft/optimizers/lorafa.pyr   9   s   	zLoraFAOptimizer.__init__Nclosurer   c              
   C  s  d}|dur	| }| j D ]}|d }g }g }t|d |d D ]\}}d|vr/|jdu r/q |j}	d|v rZ|| || t|dkrR|d|d d }
n
t|dkrYq n|}
| j|
 }t|dkrt|dkrd|d	< t|d |d
< t|d |d< nd|d	< t||d< t||d< t|dkr|d }|d }|j}d}||j	 }tj
||t|jd |j  }t }t rt|tjd d|d  ||  }W d   n1 sw   Y  n
d|d  ||  }|j|jjkr||jj}|d
 |d }}|d \}}|d	  d7  < ||j|d| d ||j||d| d | |d }|d }|d r_d||d	   }d||d	   }|t| | }|j||| d |d dkr}|j||d  |d  d g }g }q |d |d }}|d \}}|d	  d7  < ||j|	d| d ||j|	|	d| d | |d }|d }|d rd||d	   }d||d	   }|t| | }|j||| d |d dkr|j||d  |d  d q q|S )z
        Performs a single optimization step.

        Arguments:
            closure (`Callable`, *optional*): A closure that reevaluates the model and returns the loss.
        Nscaling_factorr   nameslorar   r   r   step	exp_avg_Bexp_avg_sq_Bexp_avg
exp_avg_sqg:0yE>)device_typedtyper   r   )alpha)valuer   r   r   r   r   )param_groupszipgradappendlenfindstatetorch
zeros_likeTlinalgpinveyeshapetodevicer
   r   r   bfloat16r/   mul_add_addcmul_sqrtmathaddcdiv_)r   r%   lossgroupr&   
param_list	name_listpnr4   namer8   ABgrad_B_orindeltaAA_TAA_T_invr.   grad_Br*   r+   beta1beta2denom_B	step_sizebias_correction1bias_correction2r,   r-   denomr#   r#   r$   r)   S   s   



(


qzLoraFAOptimizer.step)r   r   r   r   T)r   r   r   r   r   r   r   r   r   r   r   r   )N)r%   r   )	__name__
__module____qualname____doc__r   r9   no_gradr)   __classcell__r#   r#   r!   r$   r   #   s    r   r   Fmodelr	   rint
lora_alphar   r   r   
use_rslorar   returnr   c           
      C  sl   |   D ]\}}d|v r|d q|r|t| n|| }|  |dd |   D |d|dg}	t|	S )a+  
    Helper function to instantiate a lorafa optimizer specifically configured for a given model using the LoRA method.

    This function will:
    - Disable gradient updates for the "lora_A" parameters (these are typically frozen during LoRA training).
    - Compute the scaling factor based on provided `lora_alpha` and rank `r` for proper gradient projection.
    - Create and configure parameter groups for the optimizer including specified learning rate, weight decay, and
      additional optimizer options.

    For hyper-params, LoRA-FA uses the same hyper-params as AdamW, except for the LoRA hyper-params (r, lora_alpha,
    use_rslora). One can always use the same hyper-params such as lr and weight_decay, as AdamW in LoRA tuning.

    Args:
        model (PeftModel): The model containing LoRA-adapted parameters.
        r (int): Rank of the LoRA decomposition.
        lora_alpha (int): Scaling factor for LoRA parameterization.
        lr (float): Learning rate for optimizer updates.
        weight_decay (float): Weight decay for AdamW.
        use_rslora (bool):
            whether to use rslora. In rslora, the lora scaling factor becomes to lora_alpha / math.sqrt(r) instead of
            lora_alpha / r.

    Returns:
        Optimizer: Configured lorafa optimizer instance ready for training.
    lora_AFc                 S  s   g | ]\}}|qS r#   r#   ).0rO   _r#   r#   r$   
<listcomp>   s    z+create_lorafa_optimizer.<locals>.<listcomp>r   )r   r   r'   r&   r   r   )named_parametersrequires_grad_rG   rF   
parametersr   )
rd   re   rg   r   r   rh   rO   paramlora_scalingr2   r#   r#   r$   create_lorafa_optimizer   s   

rs   )r   F)rd   r	   re   rf   rg   rf   r   r   r   r   rh   r   ri   r   )ra   
__future__r   rG   collections.abcr   typingr   r9   torch.nnnnaccelerate.utils.importsr   r   torch.optimr   
peft_modelr	   utils.otherr
   r   rs   r#   r#   r#   r$   <module>   s     6