ó
    Ë�¡jz  ã                   ó0   • S SK r S SKJrJr   " S S5      rg)é    N)ÚAcceleratorÚDistributedTypec            	       óv   • \ rS rSrSrS rS rSS\S\R                  R                  S\S\4S	 jjrS
 rS rSrg)ÚLocalSGDé   uú  
A helper class to support local SGD on top of Accelerator. It simply runs a given number of updates independently
on each device, and averages model weights every K synchronization step.

It should be used only in the multi-GPU (or multi-CPU) setup without extensions such as DeepSpeed. In particular,
this is a simple implementation that cannot support scenarios such as model parallelism.


Although we are not aware of the true origins of this simple approach, the idea of local SGD is quite old and goes
back to at least:

Zhang, J., De Sa, C., Mitliagkas, I., & RÃ©, C. (2016). [Parallel SGD: When does averaging help?. arXiv preprint
arXiv:1606.07365.](https://huggingface.co/papers/1606.07365)

We credit the term Local SGD to the following paper (but there might be earlier references we are not aware of).

Stich, Sebastian Urban. ["Local SGD Converges Fast and Communicates Little." ICLR 2019-International Conference on
Learning Representations. No. CONF. 2019.](https://huggingface.co/papers/1805.09767)

c                 óš   • U R                   (       a9  U R                  R                  5       U l        U R                  R	                  5         U $ ©N)ÚenabledÚmodelÚno_syncÚmodel_sync_objÚ	__enter__©Úselfs    Ú¢C:\Users\johnn\AppData\Local\Packages\PythonSoftwareFoundation.Python.3.13_qbz5n2kfra8p0\LocalCache\local-packages\Python313\site-packages\accelerate/local_sgd.pyr   ÚLocalSGD.__enter__)   s5   € Ø�<�<Ø"&§*¡*×"4Ñ"4Ó"6ˆDÔØ×Ñ×)Ñ)Ô+àˆó    c                 ó€   • U R                   (       a-  U R                  5         U R                  R                  XU5        g g r	   )r
   Ú_sync_and_avg_model_paramsr   Ú__exit__)r   ÚtypeÚvalueÚtbs       r   r   ÚLocalSGD.__exit__0   s0   € Ø�<�<à×+Ñ+Ô-Ø×Ñ×(Ñ(¨°bÕ9ð r   Úacceleratorr   Úlocal_sgd_stepsr
   c                 ó  • UR                   [        R                  [        R                  [        R                  [        R
                  [        R                  [        R                  [        R                  [        R                  [        R                  [        R                  4
;  a  [        S5      eU=(       a    UR                   [        R                  :g  U l        SU l        U R                  (       a  Xl        X l        X0l        gg)ai  
Constructor.

Args:
    model (`torch.nn.Module):
        The model whose parameters we need to average.
    accelerator (`Accelerator`):
        Accelerator object.
    local_sgd_steps (`int`):
        A number of local SGD steps (before model parameters are synchronized).
    enabled (`bool):
        Local SGD is disabled if this parameter set to `False`.
zILocalSGD is supported only for CPUs and GPUs (no DeepSpeed or MegatronLM)r   N)Údistributed_typer   ÚNOÚ	MULTI_CPUÚ	MULTI_GPUÚ	MULTI_XPUÚ	MULTI_MLUÚ	MULTI_HPUÚ
MULTI_SDAAÚ
MULTI_MUSAÚ	MULTI_NPUÚMULTI_NEURONÚNotImplementedErrorr
   Ú	num_stepsr   r   r   )r   r   r   r   r
   s        r   Ú__init__ÚLocalSGD.__init__6   sÀ   € ð ×'Ñ'Ü×ÑÜ×%Ñ%Ü×%Ñ%Ü×%Ñ%Ü×%Ñ%Ü×%Ñ%Ü×&Ñ&Ü×&Ñ&Ü×%Ñ%Ü×(Ñ(ð0
ó 
ô &Ð&qÓrÐrØ×U ;×#?Ñ#?Ä?×CUÑCUÑ#UˆŒØˆŒØ�<�<Ø*ÔØŒJØ#2Õ ð r   c                 ó®   • U =R                   S-  sl         U R                  (       d  gU R                   U R                  -  S:X  a  U R                  5         gg)zN
This function makes a "step" and synchronizes model parameters if necessary.
é   Nr   )r*   r
   r   r   r   s    r   ÚstepÚLocalSGD.stepX   sD   € ð 	�Š˜!Ñ�Ø�|�|Øà�>‰>˜D×0Ñ0Ñ0°AÓ5Ø×+Ñ+Õ-ð 6r   c                 ó4  • U R                   R                  5         U R                   R                  5          U R                  R	                  5        H,  nU R                   R                  UR                  SS9Ul        M.     SSS5        g! , (       d  f       g= f)z8
Synchronize + Average model parameters across all GPUs
Úmean)Ú	reductionN)r   Úwait_for_everyoneÚautocastr   Ú
parametersÚreduceÚdata)r   Úparams     r   r   Ú#LocalSGD._sync_and_avg_model_paramsc   sl   € ð
 	×Ñ×*Ñ*Ô,Ø×Ñ×&Ñ&Õ(ØŸ™×.Ñ.Ö0�Ø!×-Ñ-×4Ñ4°U·Z±ZÈ6Ð4ÐR�–
ñ 1÷ )×(Ö(ús   µAB	Â	
B)r   r
   r   r   r   r*   N)T)Ú__name__Ú
__module__Ú__qualname__Ú__firstlineno__Ú__doc__r   r   r   ÚtorchÚnnÚModuleÚintÚboolr+   r/   r   Ú__static_attributes__© r   r   r   r      sH   † ñò*ò:ñ 3 Kð  3¸¿¹¿¹ð  3ÐZ]ð  3Ðhlõ  3òD	.õSr   r   )r@   Ú
accelerater   r   r   rF   r   r   Ú<module>rH      s   ðó ç 3÷XSò XSr   