
    i                     P    d dl mZmZmZmZmZ ddlmZmZ ddl	m
Z
  G d d      Zy)    )DictIterableListUnioncast   )has_torch_amptorch)is_torch_arrayc                       e Zd ZdZ	 	 	 	 	 ddededededef
dZd Z	 dd	e	d
e
d
   f   de	d
ed
   f   fdZdd
ded   defdZd Zed        Zd Zd Zy)PyTorchGradScalera  
    Gradient scaler for the PyTorch shim.

    Gradients with small magnitudes are not representable in half-precision and
    will underflow to zero. A gradient scaler counters this issue by scaling
    up the loss before backpropagation, increasing the gradients by the same
    magnitude. A large enough scale will avoid that the gradients underflow.
    The gradients are unscaled in single precision after backpropagation, to
    provide the unscaled gradients to the optimizer.
    enabled
init_scalebackoff_factorgrowth_factorgrowth_intervalc                     || _         || _        || _        || _        t	        j
                  ddt        j                        | _        t	        j
                  d|      | _        d| _	        y)a  
        Construct a gradient scaler for the PyTorch shim.

        enabled (bool):
            Sets whether the gradient scalar is enabled. If it is disabled, the
            methods of the grad scaler are no-ops.

        init_scale (float):
            The initial scale used to increase the gradient magnitude.

        backoff_factor (float):
            The scale will be multiplied by this factor if any of the gradients
            overflows.

        growth_factor (float):
            The scale will be multiplied by this factor when none of the gradients
            overflowed for "growth_interval" steps.

        growth_interval (int):
            When no overflows were found for this number of steps, the scale will
            be multiplied by "growth_factor".
           r   )dtypeFN)
_enabled_growth_factor_backoff_factor_growth_intervalr
   fullint_growth_tracker_scale
_found_inf)selfr   r   r   r   r   s         p/var/www/vps2.regionflexible.com/Desarrollo/venv/lib/python3.12/site-packages/thinc/shims/pytorch_grad_scaler.py__init__zPyTorchGradScaler.__init__   sU    <  +- /$zz$Cjjz2    c                     | j                   j                  |      | _         | j                  j                  |      | _        y N)r   tor   )r    devices     r!   to_zPyTorchGradScaler.to_:   s/    #3366v>kknnV,r#   tensorstorch.Tensorreturnc                 H   | j                   st        d|      S t        d      }t               }t	        |      rt        d|      }| j                  |||      S t        |t              r:g }|D ]1  }t	        |      s||j                  | j                  |||             3 |S |)z)Scale up the values in the given tensors.r*   z>Input to gradient scaling must be a Tensor or Iterable[Tensor])	r   r   
ValueErrordictr   _scale_tensor
isinstancer   append)r    r)   inplaceincorrect_typescale_per_devicetensorscaled_tensorss          r!   scalezPyTorchGradScaler.scale>   s     }}00#L

 BF'".'2F%%f.>HH*N! %f-((%%&&v/?I	 "!r#   r5   r4   )ztorch.devicer*   r2   c                     t         st        d      |j                  sd}t        |      |j                  }||vr| j                  j                  |      ||<   ||   }|r|j                  |      S ||z  S )NzHGradient scaling is not supported, requires capable GPU and torch>=1.9.0zGradient scaling is only supported for CUDA tensors. If you are using PyTorch models, you can avoid this error by disabling mixed-precision support.r'   )r	   r-   is_cudar'   r   r&   mul_)r    r5   r4   r2   msgr'   r7   s          r!   r/   zPyTorchGradScaler._scale_tensor^   s     Z  ~~> 
 S/!))'+{{~~V~'DV$ (;;u%%E>!r#   c                     t               }|D ]/  }|j                  |j                  g       }|j                  |       1 |S r%   )r.   
setdefaultr'   r1   )r    r)   tensors_per_devicer5   device_tensorss        r!   _tensors_per_devicez%PyTorchGradScaler._tensors_per_device|   sE    !V 	*F/::6=="MN!!&)	* "!r#   c                     | j                   S r%   )r   )r    s    r!   	found_infzPyTorchGradScaler.found_inf   s    r#   c                    | j                   sy| j                  j                         j                         j	                         }| j                  |      }|j                         D ]\  \  }}t        j                  dd|      }|j                  |      }t        j                  |||       t        |dk7        sVd| _        ^ | j                  S )zNUnscale the given tensors. Returns True if any of the gradients were infinite.Fr           r9   r   T)r   r   double
reciprocalfloatrA   itemsr
   r   r&   *_amp_foreach_non_finite_check_and_unscale_boolr   )r    r)   	inv_scaler?   r'   r@   found_inf_deviceinv_scale_devices           r!   unscalezPyTorchGradScaler.unscale   s    }} KK&&(335;;=	 "55g>&8&>&>&@ 		'"FN$zz$FC(||6|:<< 02B $)*"&		' r#   c                 8   | j                   syt        j                  d| j                  rdnd| j                  j
                        }t        j                  | j                  | j                  || j                  | j                  | j                         d| _        y)z
        Update the scale factor and clear information about infinities.

        This method should be called after each optimization step.
        Nr   g      ?rE   r9   F)r   r
   r   r   r   r'   _amp_update_scale_r   r   r   r   )r    rM   s     r!   updatezPyTorchGradScaler.update   s}     }} ::#c$++:L:L
 	  KK    !!	
  r#   N)Fg      @g      ?g       @i  )F)__name__
__module____qualname____doc__rK   rH   r   r"   r(   r   r   r   r7   r   r/   rA   propertyrC   rO   rR    r#   r!   r   r      s    	 # #"#% %  %  	% 
 %  % N-
 QV^Xn-EEF	~tN33	4@"" =>" 	"<"  . r#   r   N)typingr   r   r   r   r   compatr	   r
   utilr   r   rX   r#   r!   <module>r\      s    4 4 ) !n  n r#   