Ë
    Fêñi¡7  ã                  óŒ   — d dl mZ d dlZd dlmZ d
dd„Zddd„Z G d„ dej                  «      Z G d„ d	ej                  «      Zy)é    )ÚannotationsN)Úoptimc                ó¨  — t        | j                  «      dk(  sJ ‚| j                  «       }||j                  «       |z   z  }| j	                  d«      | j	                  d«      kD  r|j
                  }dD ].  \  }}}||j
                  z  }||z  ||z  |z  z   }||z  ||z  z   }Œ0 | j	                  d«      | j	                  d«      kD  r|j
                  }|S )a"  Compute the zeroth power / orthogonalization of matrix G using Newton-Schulz iteration.

    This function implements a quintic Newton-Schulz iteration to compute an approximate orthogonalization of the input
    matrix G. The iteration coefficients are optimized to maximize convergence slope at zero, producing a result similar
    to UV^T from SVD, where USV^T = G, but with relaxed convergence guarantees that empirically work well for
    optimization purposes.

    Args:
        G (torch.Tensor): Input 2D tensor/matrix to orthogonalize.
        eps (float, optional): Small epsilon value added to norm for numerical stability. Default: 1e-7.

    Returns:
        (torch.Tensor): Orthogonalized matrix with same shape as input G.

    Examples:
        >>> G = torch.randn(128, 64)
        >>> G_ortho = zeropower_via_newtonschulz5(G)
        >>> print(G_ortho.shape)
        torch.Size([128, 64])

    Notes:
        - Uses bfloat16 precision for computation.
        - Performs exactly 5 Newton-Schulz iteration steps with fixed coefficients.
        - Automatically transposes for efficiency when rows > columns.
        - Output approximates US'V^T where S' has diagonal entries ~ Uniform(0.5, 1.5).
        - Does not produce exact UV^T but works well empirically for neural network optimization.
    é   r   é   )©gu“VŽ@gš™™™™Àg�—nƒ@ @r   r   r   r   )ÚlenÚshapeÚbfloat16ÚnormÚsizeÚT)ÚGÚepsÚXÚaÚbÚcÚAÚBs           úX/var/www/pod-logistic/pod-ai/venv/lib/python3.12/site-packages/ultralytics/optim/muon.pyÚzeropower_via_newtonschulz5r   	   sÏ   € ô8 ˆq�w‰w‹<˜1ÒÐÐØ	�
‰
‹€AØˆ�‰‹�C‰Ñ€AØ‡v�vˆaƒy�1—6‘6˜!“9ÒØ�C‰Cˆðò ‰ˆˆ1ˆað �—‘‰GˆØ�‰E�A˜‘E˜A‘IÑˆØ�‰E�A˜‘E‰M‰ðð 	‡v�vˆaƒy�1—6‘6˜!“9ÒØ�C‰CˆØ€Hó    c                ó,  — |j                  | d|z
  «       |r| j                  ||«      n|}|j                  dk(  r|j                  t	        |«      d«      }t        |«      }|t        d| j                  d«      | j                  d«      z  «      dz  z  }|S )aX  Compute Muon optimizer update with momentum and orthogonalization.

    This function applies momentum to the gradient, optionally uses Nesterov acceleration, and then orthogonalizes the
    update using Newton-Schulz iterations. For convolutional filters (4D tensors), it reshapes before orthogonalization
    and scales the final update based on parameter dimensions.

    Args:
        grad (torch.Tensor): Gradient tensor to update. Can be 2D or 4D (for conv filters).
        momentum (torch.Tensor): Momentum buffer tensor, modified in-place via lerp.
        beta (float, optional): Momentum coefficient for exponential moving average. Default: 0.95.
        nesterov (bool, optional): Whether to use Nesterov momentum acceleration. Default: True.

    Returns:
        (torch.Tensor): Orthogonalized update tensor with same shape as input grad. For 4D inputs, returns reshaped
            result matching original dimensions.

    Examples:
        >>> grad = torch.randn(64, 128)
        >>> momentum = torch.zeros_like(grad)
        >>> update = muon_update(grad, momentum, beta=0.95, nesterov=True)
        >>> print(update.shape)
        torch.Size([64, 128])

    Notes:
        - Momentum buffer is updated in-place: momentum = beta * momentum + (1-beta) * grad.
        - With Nesterov: update = beta * momentum + (1-beta) * grad.
        - Without Nesterov: update = momentum.
        - 4D tensors (conv filters) are reshaped to 2D as (out_channels, in_channels*height*width) for orthogonalization.
        - Final update is scaled by sqrt(max(1, dim[-2] / dim[-1])) to account for parameter dimensions.
    r   é   éÿÿÿÿéþÿÿÿç      à?)Úlerp_ÚlerpÚndimÚviewr	   r   Úmaxr   )ÚgradÚmomentumÚbetaÚnesterovÚupdates        r   Úmuon_updater)   ;   s„   € ð> ‡N�N�4˜˜T™Ô"Ù*2ˆT�Y‰Y�x Ô&¸€FØ‡{�{�aÒØ—‘œS ›[¨"Ó-ˆÜ(¨Ó0€FØ
Œc�!�T—Y‘Y˜r“] T§Y¡Y¨r£]Ñ2Ó3°sÑ:Ñ:€FØ€Mr   c                  ó~   ‡ — e Zd ZdZ	 	 	 	 	 	 	 d	 	 	 	 	 	 	 	 	 	 	 	 	 dˆ fd„Z ej                  «       dd„«       Zˆ xZS )ÚMuSGDa"  Hybrid optimizer combining Muon and SGD updates for neural network training.

    This optimizer implements a combination of Muon (a momentum-based optimizer with orthogonalization via Newton-Schulz
    iterations) and standard SGD with momentum. It allows different parameter groups to use either the hybrid Muon+SGD
    approach or pure SGD.

    Args:
        params (Iterable): Parameters to optimize or dicts defining parameter groups.
        muon (float, optional): Weight factor for Muon updates in hybrid mode. Default: 0.5.
        sgd (float, optional): Weight factor for SGD updates in hybrid mode. Default: 0.5.

    Attributes:
        muon (float): Scaling factor applied to Muon learning rate.
        sgd (float): Scaling factor applied to SGD learning rate in hybrid mode.

    Examples:
        >>> param_groups = [
        ...     {
        ...         "params": model.conv_params,
        ...         "lr": 0.02,
        ...         "use_muon": True,
        ...         "momentum": 0.95,
        ...         "nesterov": True,
        ...         "weight_decay": 0.01,
        ...     },
        ...     {
        ...         "params": model.other_params,
        ...         "lr": 0.01,
        ...         "use_muon": False,
        ...         "momentum": 0.9,
        ...         "nesterov": False,
        ...         "weight_decay": 0,
        ...     },
        ... ]
        >>> optimizer = MuSGD(param_groups, muon=0.5, sgd=0.5)
        >>> loss = model(data)
        >>> loss.backward()
        >>> optimizer.step()

    Notes:
        - Parameter groups with 'use_muon': True will receive both Muon and SGD updates.
        - Parameter groups with 'use_muon': False will receive only SGD updates.
        - The Muon update uses orthogonalization which works best for 2D+ parameter tensors.
    c	                ób   •— t        |||||¬«      }	t        ‰
| �	  ||	«       || _        || _        y)aN  Initialize MuSGD optimizer with hybrid Muon and SGD capabilities.

        Args:
            params (Iterable): Iterable of parameters to optimize or dicts defining parameter groups.
            lr (float): Learning rate.
            momentum (float): Momentum factor for SGD.
            weight_decay (float): Weight decay (L2 penalty).
            nesterov (bool): Whether to use Nesterov momentum.
            use_muon (bool): Whether to enable Muon updates.
            muon (float): Scaling factor for Muon component.
            sgd (float): Scaling factor for SGD component.
        )Úlrr%   Úweight_decayr'   Úuse_muonN)ÚdictÚsuperÚ__init__ÚmuonÚsgd)ÚselfÚparamsr-   r%   r.   r'   r/   r3   r4   ÚdefaultsÚ	__class__s             €r   r2   zMuSGD.__init__‘   s=   ø€ ô. ØØØ%ØØô
ˆô 	‰Ñ˜ Ô*ØˆŒ	Øˆ�r   c           	     óø  — d}|�$t        j                  «       5   |«       }ddd«       | j                  D �]4  }|d   �rS|d   D �]H  }|d   }|j                  €Œ|j                  }| j                  |   }t        |«      dk(  r0t        j                  |«      |d<   t        j                  |«      |d<   t        ||d   |d   |d	   ¬
«      }|j                  |j                  |j                  «      || j                  z   ¬«       |d   dk7  r|j                  ||d   ¬«      }|d   j                  |d   «      j                  |«       |d	   r|j                  |d   |d   ¬«      n|d   }	|j                  |	|| j                  z   ¬«       �ŒK �Œ]|d   D ]Ð  }|d   }|j                  €Œ|j                  }|d   dk7  r|j                  ||d   ¬«      }| j                  |   }t        |«      dk(  rt        j                  |«      |d<   |d   j                  |d   «      j                  |«       |d	   r|j                  |d   |d   ¬«      n|d   }|j                  || ¬«       ŒÒ �Œ7 |S # 1 sw Y   �ŒPxY w)a#  Perform a single optimization step.

        Applies either hybrid Muon+SGD updates or pure SGD updates depending on the
        'use_muon' flag in each parameter group. For Muon-enabled groups, parameters
        receive both an orthogonalized Muon update and a standard SGD momentum update.

        Args:
            closure (Callable, optional): A closure that reevaluates the model
                and returns the loss. Default: None.

        Returns:
            (torch.Tensor | None): The loss value if closure is provided, otherwise None.

        Notes:
            - Parameters with None gradients are skipped.
            - Muon updates use Newton-Schulz orthogonalization and work best on 2D+ tensors.
            - Weight decay is applied only to the SGD component in hybrid mode.
        Nr/   r6   r-   r   Úmomentum_bufferÚmomentum_buffer_SGDr%   r'   )r&   r'   ©Úalphar.   )ÚtorchÚenable_gradÚparam_groupsr$   Ústater	   Ú
zeros_liker)   Úadd_Úreshaper
   r3   ÚaddÚmul_r4   )
r5   ÚclosureÚlossÚgroupÚpr-   r$   rA   r(   Ú
sgd_updates
             r   Ústepz
MuSGD.step³   s±  € ð( ˆØÐÜ×"Ñ"Ó$ñ !Ù“y�÷!ð ×&Ñ&ó .	.ˆEà�ZÓ à˜x™ó ?�AØ˜t™�BØ—v‘v�~Ø ØŸ6™6�DØ ŸJ™J q™M�EÜ˜5“z Q’Ü38×3CÑ3CÀAÓ3F˜Ð/Ñ0Ü7<×7GÑ7GÈÓ7J˜Ð3Ñ4ä(Ø˜eÐ$5Ñ6¸UÀ:Ñ=NÐY^Ð_iÑYjô�Fð —F‘F˜6Ÿ>™>¨!¯'©'Ó2¸BÀÇÁ¹NÐ:K�FÔLð ˜^Ñ,°Ò1Ø#Ÿx™x¨°°~Ñ1F˜xÓG˜ØÐ/Ñ0×5Ñ5°e¸JÑ6GÓH×MÑMÈdÔSð ! Ò,ð Ÿ™ Ð'<Ñ!=ÀUÈ:ÑEV˜ÔWà"Ð#8Ñ9ð ð
 —F‘F˜:¨r°D·H±H©}Ð-=�FÖ>ò1?ð4 ˜x™ò .�AØ˜t™�BØ—v‘v�~Ø ØŸ6™6�DØ˜^Ñ,°Ò1Ø#Ÿx™x¨°°~Ñ1F˜xÓG˜Ø ŸJ™J q™M�EÜ˜5“z Q’Ü38×3CÑ3CÀAÓ3F˜Ð/Ñ0ØÐ+Ñ,×1Ñ1°%¸
Ñ2CÓD×IÑIÈ$ÔOð ! Ò,ð Ÿ™ Ð'8Ñ!9ÀÀzÑAR˜ÔSà"Ð#4Ñ5ð ð
 —F‘F˜6¨"¨�FÕ-ò!.ð=.	.ð^ ˆ÷e!ñ !ús   ™I/É/I9)gü©ñÒMbP?ç        rM   FFr   r   )r-   Úfloatr%   rN   r.   rN   r'   Úboolr/   rO   r3   rN   r4   rN   ©N©	Ú__name__Ú
__module__Ú__qualname__Ú__doc__r2   r>   Úno_gradrL   Ú__classcell__©r8   s   @r   r+   r+   c   sŠ   ø„ ñ+ð` ØØ!ØØØØð ð ð ð ð	 ð
 ð ð ð ð ð ð ð ð õ ðD €U‡]�]ƒ_òGó ôGr   r+   c                  óV   ‡ — e Zd ZdZddˆ fd„Z ej                  «       dd„«       Zˆ xZS )ÚMuonaS  Muon optimizer for usage in non-distributed settings.

    This optimizer implements the Muon algorithm, which combines momentum-based updates with orthogonalization via
    Newton-Schulz iterations. It applies weight decay and learning rate scaling to parameter updates.

    Args:
        params (iterable): Iterable of parameters to optimize or dicts defining parameter groups.
        lr (float, optional): Learning rate. Default: 0.02.
        weight_decay (float, optional): Weight decay (L2 penalty) coefficient. Default: 0.
        momentum (float, optional): Momentum coefficient for exponential moving average. Default: 0.95.

    Attributes:
        param_groups (list): List of parameter groups with their optimization settings.
        state (dict): Dictionary containing optimizer state for each parameter.

    Examples:
        >>> model = YourModel()
        >>> optimizer = Muon(model.parameters(), lr=0.02, weight_decay=0.01, momentum=0.95)
        >>> loss = model(data)
        >>> loss.backward()
        >>> optimizer.step()

    Notes:
        - Designed for non-distributed training environments.
        - Uses Muon updates with orthogonalization for all parameters.
        - Weight decay is applied multiplicatively before parameter update.
        - Parameters with None gradients are assigned zero gradients for synchronization.
    c                óB   •— t        |||¬«      }t        ‰| �	  ||«       y)a}  Initialize Muon optimizer with orthogonalization-based updates.

        Args:
            params (Iterable): Iterable of parameters to optimize or dicts defining parameter groups.
            lr (float): Learning rate.
            weight_decay (float): Weight decay factor applied multiplicatively.
            momentum (float): Momentum factor for gradient accumulation.
        )r-   r.   r%   N)r0   r1   r2   )r5   r6   r-   r.   r%   r7   r8   s         €r   r2   zMuon.__init__  s"   ø€ ô ˜2¨LÀ8ÔLˆÜ‰Ñ˜ Õ*r   c                ó0  — d}|�$t        j                  «       5   |«       }ddd«       | j                  D ]Ò  }|d   D ]È  }|j                  €t        j                  |«      |_        | j
                  |   }t        |«      dk(  rt        j                  |«      |d<   t        |j                  |d   |d   ¬«      }|j                  d|d   |d	   z  z
  «       |j                  |j                  |j                  «      |d    ¬
«       ŒÊ ŒÔ |S # 1 sw Y   ŒìxY w)a³  Perform a single optimization step.

        Applies Muon updates to all parameters, incorporating momentum and orthogonalization.
        Weight decay is applied multiplicatively before the parameter update.

        Args:
            closure (Callable[[], torch.Tensor] | None, optional): A closure that reevaluates the model
                and returns the loss. Default: None.

        Returns:
            (torch.Tensor | None): The loss value if closure is provided, otherwise None.

        Examples:
            >>> optimizer = Muon(model.parameters())
            >>> loss = model(inputs)
            >>> loss.backward()
            >>> optimizer.step()

        Notes:
            - Parameters with None gradients are assigned zero gradients for synchronization.
            - Weight decay is applied as: p *= (1 - lr * weight_decay).
            - Muon update uses Newton-Schulz orthogonalization and works best on 2D+ tensors.
        Nr6   r   r:   r%   )r&   r   r-   r.   r<   )r>   r?   r@   r$   rB   rA   r	   r)   rF   rC   rD   r
   )r5   rG   rH   rI   rJ   rA   r(   s          r   rL   z	Muon.step(  s  € ð2 ˆØÐÜ×"Ñ"Ó$ñ !Ù“y�÷!ð ×&Ñ&ò 
	DˆEØ˜8‘_ò 	D�Ø—6‘6�>ä"×-Ñ-¨aÓ0�A”FØŸ
™
 1™�Ü�u“: ’?Ü/4×/?Ñ/?ÀÓ/B�EÐ+Ñ,Ü$ Q§V¡V¨UÐ3DÑ-EÈEÐR\ÑL]Ô^�Ø—‘�q˜5 ™;¨¨~Ñ)>Ñ>Ñ>Ô?Ø—‘�v—~‘~ a§g¡gÓ.°u¸T±{°l�ÕCñ	Dð
	Dð ˆ÷!ð !ús   ™DÄD)g{®Gáz”?r   çffffffî?)r-   rN   r.   rN   r%   rN   rP   rQ   rX   s   @r   rZ   rZ   þ   s)   ø„ ñö:
+ð €U‡]�]ƒ_ò)ó ô)r   rZ   )gH¯¼šò×z>)r   útorch.Tensorr   rN   Úreturnr^   )r]   T)
r$   r^   r%   r^   r&   rN   r'   rO   r_   r^   )	Ú
__future__r   r>   r   r   r)   Ú	Optimizerr+   rZ   © r   r   ú<module>rc      sA   ðõ #ã Ý ô/ôd%ôPXˆE�O‰Oô XôvTˆ5�?‰?õ Tr   