o
    h'                     @   s   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	 G dd dZ
G dd	 d	ZG d
d deZG dd de	ZG dd dZG dd dZdS )    N)deepcopy   )AcceleratedOptimizer)AcceleratedSchedulerc                   @   sd   e Zd ZdZdd Zdd Zdd Zdd	d
ZdddZdd Z	dd Z
dd Zdd Zdd ZdS )HfDeepSpeedConfigaJ  
    This object contains a DeepSpeed configuration dictionary and can be quickly queried for things like zero stage.

    A `weakref` of this object is stored in the module's globals to be able to access the config from areas where
    things like the Trainer object is not available (e.g. `from_pretrained` and `_get_resized_embeddings`). Therefore
    it's important that this object remains alive while the program is still running.

    [`Trainer`] uses the `HfTrainerDeepSpeedConfig` subclass instead. That subclass has logic to sync the configuration
    with values of [`TrainingArguments`] by replacing special placeholder values: `"auto"`. Without this special logic
    the DeepSpeed configuration is not modified in any way.

    Args:
        config_file_or_dict (`Union[str, Dict]`): path to DeepSpeed config file or dict.

    c              
   C   s   t |tr
t|}nEtj|r.tj|ddd}t	|}W d    n1 s(w   Y  n!zt
|d}t|}W n tttfyN   td| w || _|   d S )Nrzutf-8)encodingzoExpected a string path to an existing deepspeed config, or a dictionary, or a base64 encoded string. Received: )
isinstancedictr   ospathexistsioopenjsonloadbase64urlsafe_b64decodedecodeloadsUnicodeDecodeErrorAttributeError
ValueErrorconfigset_stage_and_offload)selfconfig_file_or_dictr   fconfig_decoded r   P/var/www/html/ai/venv/lib/python3.10/site-packages/accelerate/utils/deepspeed.py__init__*   s"   

zHfDeepSpeedConfig.__init__c                 C   sj   |  dd| _d| _|  s|  r3tddg}t|  d|  dg}t||@ dkr1d	| _d S d S d S )
Nzzero_optimization.stageFcpunvmez*zero_optimization.offload_optimizer.devicez&zero_optimization.offload_param.devicer   T)	get_value_stage_offloadis_zero2is_zero3setlen)r   offload_devices_validoffload_devicesr   r   r    r   ?   s   
z'HfDeepSpeedConfig.set_stage_and_offloadc                 C   sH   | j }|d}| }|D ]}||}|d u rd |f  S q||fS )N.)r   splitpopget)r   ds_key_longr   nodesds_keynoder   r   r    find_config_nodeR   s   

z"HfDeepSpeedConfig.find_config_nodeNc                 C   s&   |  |\}}|du r|S |||S )zG
        Returns the set value or `default` if no value is set
        N)r6   r1   )r   r2   defaultr   r4   r   r   r    r%   _   s   zHfDeepSpeedConfig.get_valueFc                 C   sj   | j }|d}|D ]}|}||}|du r'|r$td| d| j   dS q
|dur3|| dS dS )z
        Deletes a sub-section of the config file if it's found.

        Unless `must_exist` is `True` the section doesn't have to exist.
        r.   NzCan't find z entry in the config: )r   r/   r1   r   r0   )r   r2   
must_existr   r3   r5   parent_configr   r   r    del_config_sub_treeh   s   

z%HfDeepSpeedConfig.del_config_sub_treec                 C   s   |  |}|du rdS t|S )z
        Returns `True`/``False` only if the value is set, always `False` otherwise. So use this method to ask the very
        specific question of whether the value is set to `True` (and it's not set to `False`` or isn't set).

        NFr%   boolr   r2   valuer   r   r    is_true   s   
zHfDeepSpeedConfig.is_truec                 C   s    |  |}|du rdS t| S )z
        Returns `True`/``False` only if the value is set, always `False` otherwise. So use this method to ask the very
        specific question of whether the value is set to `False` (and it's not set to `True`` or isn't set).
        NFr;   r=   r   r   r    is_false   s   
zHfDeepSpeedConfig.is_falsec                 C   
   | j dkS )Nr   r&   r   r   r   r    r(         
zHfDeepSpeedConfig.is_zero2c                 C   rA   )N   rB   rC   r   r   r    r)      rD   zHfDeepSpeedConfig.is_zero3c                 C   s   | j S N)r'   rC   r   r   r    
is_offload   s   zHfDeepSpeedConfig.is_offloadrF   )F)__name__
__module____qualname____doc__r!   r   r6   r%   r:   r?   r@   r(   r)   rG   r   r   r   r    r      s    

		r   c                   @   s    e Zd ZdZdd Zdd ZdS )DeepSpeedEngineWrapperz
    Internal wrapper for deepspeed.runtime.engine.DeepSpeedEngine. This is used to follow conventional training loop.

    Args:
        engine (deepspeed.runtime.engine.DeepSpeedEngine): deepspeed engine to wrap
    c                 C   s
   || _ d S rF   )engine)r   rM   r   r   r    r!      rD   zDeepSpeedEngineWrapper.__init__c                 K   s"   | j j|fi | | j   d S rF   )rM   backwardstep)r   losskwargsr   r   r    rN      s   	zDeepSpeedEngineWrapper.backwardN)rH   rI   rJ   rK   r!   rN   r   r   r   r    rL      s    rL   c                       s>   e Zd ZdZ fddZdddZdd Zed	d
 Z  Z	S )DeepSpeedOptimizerWrapperz
    Internal wrapper around a deepspeed optimizer.

    Args:
        optimizer (`torch.optim.optimizer.Optimizer`):
            The optimizer to wrap.
    c                    s$   t  j|dd d t| jd| _d S )NF)device_placementscaleroverflow)superr!   hasattr	optimizer__has_overflow__)r   rX   	__class__r   r    r!      s   z"DeepSpeedOptimizerWrapper.__init__Nc                 C      d S rF   r   )r   set_to_noner   r   r    	zero_grad      z#DeepSpeedOptimizerWrapper.zero_gradc                 C   r\   rF   r   rC   r   r   r    rO      r_   zDeepSpeedOptimizerWrapper.stepc                 C   s   | j r| jjS dS )zTWhether or not the optimizer step was done, or skipped because of gradient overflow.F)rY   rX   rU   rC   r   r   r    step_was_skipped   s   z*DeepSpeedOptimizerWrapper.step_was_skippedrF   )
rH   rI   rJ   rK   r!   r^   rO   propertyr`   __classcell__r   r   rZ   r    rR      s    
rR   c                       s(   e Zd ZdZ fddZdd Z  ZS )DeepSpeedSchedulerWrapperz
    Internal wrapper around a deepspeed scheduler.

    Args:
        scheduler (`torch.optim.lr_scheduler.LambdaLR`):
            The scheduler to wrap.
        optimizers (one or a list of `torch.optim.Optimizer`):
    c                    s   t  || d S rF   )rV   r!   )r   	scheduler
optimizersrZ   r   r    r!      s   z"DeepSpeedSchedulerWrapper.__init__c                 C   r\   rF   r   rC   r   r   r    rO      r_   zDeepSpeedSchedulerWrapper.step)rH   rI   rJ   rK   r!   rO   rb   r   r   rZ   r    rc      s    	rc   c                   @   s   e Zd ZdZdddZdS )
DummyOptima  
    Dummy optimizer presents model parameters or param groups, this is primarily used to follow conventional training
    loop when optimizer config is specified in the deepspeed config file.

    Args:
        lr (float):
            Learning rate.
        params (iterable): iterable of parameters to optimize or dicts defining
            parameter groups
        weight_decay (float):
            Weight decay.
        **kwargs:
            Other arguments.
    MbP?r   c                 K   s   || _ || _|| _|| _d S rF   )paramslrweight_decayrQ   )r   rh   ri   rj   rQ   r   r   r    r!      s   
zDummyOptim.__init__N)rg   r   rH   rI   rJ   rK   r!   r   r   r   r    rf      s    rf   c                   @   s   e Zd ZdZdddZdS )DummySchedulera  
    Dummy scheduler presents model parameters or param groups, this is primarily used to follow conventional training
    loop when scheduler config is specified in the deepspeed config file.

    Args:
        optimizer (`torch.optim.optimizer.Optimizer`):
            The optimizer to wrap.
        total_num_steps (int, *optional*):
            Total number of steps.
        warmup_num_steps (int, *optional*):
            Number of steps for warmup.
        lr_scheduler_callable (callable, *optional*):
            A callable function that creates an LR Scheduler. It accepts only one argument `optimizer`.
        **kwargs:
            Other arguments.
    Nr   c                 K   s"   || _ || _|| _|| _|| _d S rF   )rX   total_num_stepswarmup_num_stepslr_scheduler_callablerQ   )r   rX   rm   rn   ro   rQ   r   r   r    r!     s
   
zDummyScheduler.__init__)Nr   Nrk   r   r   r   r    rl      s    rl   )r   r   r   r   copyr   rX   r   rd   r   r   rL   rR   rc   rf   rl   r   r   r   r    <module>   s    