Ë
    S^(hr  ã                  óø  — d dl mZ d dlZd dlmZmZ d dlmZmZm	Z	m
Z
 d dlZd dlmZ ddlmZmZ ej                   gZ ej$                  e«      Zej*                  j-                  «       Z ed«      rerd d	lmZmZmZmZ d#d
„Zej<                  ej>                  ej@                  ejB                  ejD                  ejF                  ejH                  ejJ                  ejL                  ejN                  ejP                  dœZ)d„ Z*d„ Z+	 	 	 d$	 	 	 d%d„Z, G d„ d«      Z- G d„ de-«      Z. G d„ de-«      Z/ G d„ de-«      Z0 G d„ de0«      Z1 G d„ de-«      Z2 G d„ de2«      Z3 G d„ de-«      Z4h d£Z5ed&d „«       Z6d!„ Z7d"„ Z8y)'é    )ÚannotationsN)Ú	lru_cacheÚpartial)ÚListÚOptionalÚTupleÚUnion)Únné   )Úis_torch_greater_or_equalÚloggingz2.5)ÚDTensorÚ	PlacementÚ	ReplicateÚShardc                óÖ   — t        |t        «      r8t        |«      }| |z  dk(  sJ d| › d|› �«       ‚| |z  }|D �cg c]  }||z  ‘Œ	 c}S | |z  dk(  s
J d|› �«       ‚| |z  }|g|z  S c c}w )aÃ  
    Convert block count or proportions to block sizes.

    This function accepts

    - The number of blocks (int), in which case the block size is
      total_size//blocks; or
    - A list of block sizes (List[int]).

    In the second case, if sum(blocks) < total_size, the ratios between
    the block sizes will be preserved. For instance, if blocks is
    [2, 1, 1] and total_size is 1024, the returned block sizes are
    [512, 256, 256].
    r   zCannot split z in proportional blocks: zPrepacked is not divisible by )Ú
isinstanceÚlistÚsum)Ú
total_sizeÚblocksÚtotal_blocksÚ	part_sizeÚblockÚsingle_sizes         úg/var/www/skyplay_api_hub/venv/lib/python3.12/site-packages/transformers/integrations/tensor_parallel.pyÚ_blocks_to_block_sizesr   &   s›   € ô �&œ$ÔÜ˜6“{ˆØ˜LÑ(¨AÒ-Ðl°¸z¸lÐJcÐdjÐckÐ/lÓlÐ-Ø ,Ñ.ˆ	Ø/5Ö6 e�	˜EÓ!Ò6Ð6à˜FÑ" aÒ'ÐRÐ+IÈ&ÈÐ)RÓRÐ'Ø  FÑ*ˆØˆ}˜vÑ%Ð%ùò	 7s   ºA&)ÚBOOLÚU8ÚI8ÚI16ÚF16ÚBF16ÚI32ÚF32ÚF64ÚI64ÚF8_E4M3c                óð  — | }|j                   |   }|j                  «       }t        |d¬«      }g }	d}
|D ].  }||z  }||z  }|dz   |z  }|	t        |
|z   |
|z   «      z  }	|
|z  }
Œ0 |j	                  «       }|dk(  r"|d   j                  t        j                  «      }|dk(  r||	df   }n6|dk(  s|dk(  r|dd…|	df   }n!|dk(  s|d	k(  r|d|	f   }nt        d
|› d�«      ‚|j                  t        |   «      S )uä  
    When weights are packed (gate_up_proj), we need to make sure each shard gets its correct share.
    So if you have: gate_proj       ( 16, 5120, 8190)
    and             up_proj         ( 16, 5120, 8190)
    packed as       gate_up_proj    ( 16, 5120, 2 * 8190)
    And you shard along the last dimension, you need to interleave the gate and up values:

    Now, if we shard along the last dimension across TP_size (Tensor Parallelism size), we must interleave the values from gate and up projections correctly.

    Let's take TP_size = 4 for an example:

    Packed tensor `gate_up_proj`
    ---------------------------------------------------------------
    [ G0  G1  G2  G3 | G4  G5  G6  G7 | ... | U0  U1  U2  U3 | U4  U5  U6  U7 | ... ]
     â†‘â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â†‘   â†‘â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â†‘        â†‘â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â†‘  â†‘â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â†‘
       Gate Slice 0      Gate Slice 1            Up Slice 0       Up Slice 1

    Explanation:
    - The first half of the tensor (left of the center) holds the gate_proj values.
    - The second half (right of the center) holds the up_proj values.
    - For TP=4, we divide each half into 4 slices. In this example, we show two slices for brevity.
    - Each shard receives one slice from the gate part and the corresponding slice from the up part.

    For instance:
    â€¢ Shard 0 gets: [ Gate Slice 0, Up Slice 0 ] = [ G0, G1, G2, G3, U0, U1, U2, U3 ]
    â€¢ Shard 1 gets: [ Gate Slice 1, Up Slice 1 ] = [ G4, G5, G6, G7, U4, U5, U6, U7 ]
    â€¢ â€¦ and so on.

    This ensures that each shard receives an equal portion of both gate and up projections, maintaining consistency across tensor parallelism.
    r   )r   r   r   é   r(   .éþÿÿÿNéÿÿÿÿúUnsupported dim ú", only dim 0, 1 or 2 are supported)
ÚshapeÚsizer   ÚrangeÚ	get_dtypeÚtoÚtorchÚfloat16Ú
ValueErrorÚstr_to_torch_dtype)ÚparamÚempty_paramÚdevice_meshÚrankÚdimÚslice_r   Ú
world_sizeÚblock_sizesÚtensors_slicesÚblock_offsetÚ
block_sizeÚshard_block_sizeÚstartÚstopÚslice_dtypeÚtensors                    r   Úget_packed_weightsrH   O   sA  € ð> €FØ×"Ñ" 3Ñ'€JØ×!Ñ!Ó#€JÜ(°JÀqÔI€Kà€NØ€LØ!ò #ˆ
Ø%¨Ñ3ÐØÐ'Ñ'ˆØ�q‘Ð,Ñ,ˆØœ% ¨uÑ 4°lÀTÑ6IÓJÑJˆØ˜
Ñ"‰ð#ð ×"Ñ"Ó$€Kð �iÒØ˜‘—‘¤§¡Ó.ˆà
ˆa‚xØ˜¨Ð+Ñ,‰Ø	�Š�S˜B’YØš˜>¨3Ð.Ñ/‰Ø	�Š�S˜B’YØ˜˜^Ð+Ñ,‰äÐ+¨C¨5Ð0RÐSÓTÐTØ�9‰9Ô'¨Ñ4Ó5Ð5ó    c                óö  — |dk(  rE|j                   d   }| |||j                  «       z  z  |dz   ||j                  «       z  z  …df   } | S |dk(  s|dk(  rH|j                   d   }| d|||j                  «       z  z  |dz   ||j                  «       z  z  …d d …f   } | S |dk(  s|dk(  rE|j                   d   }| d|||j                  «       z  z  |dz   ||j                  «       z  z  …f   } | S t        d|› d�«      ‚)	Nr   r*   .r+   r   r,   r-   r.   )r/   r0   r6   )r8   r9   r:   r;   r<   Úsize_s         r   Úget_tensor_shardrL   �   sG  € Ø
ˆa‚xØ×!Ñ! !Ñ$ˆØ�d˜e {×'7Ñ'7Ó'9Ñ9Ñ:¸dÀQ¹hÈ5ÐT_×TdÑTdÓTfÑKfÑ=gÐgÐilÐlÑmˆð €Lð 
�Š�S˜B’YØ×!Ñ! "Ñ%ˆØ�c˜4 5¨K×,<Ñ,<Ó,>Ñ#>Ñ?À4È!Á8ÐPUÐYd×YiÑYiÓYkÑPkÑBlÐlÒnoÐoÑpˆð €Lð 
�Š�S˜B’YØ×!Ñ! "Ñ%ˆØ�c˜4 5¨K×,<Ñ,<Ó,>Ñ#>Ñ?À4È!Á8ÐPUÐYd×YiÑYiÓYkÑPkÑBlÐlÐlÑmˆð €Lô Ð+¨C¨5Ð0RÐSÓTÐTrI   c                ó˜   ‡‡‡— t        | j                  «      dk(  r.‰�| j                  ˆˆfd„«       ‰�| j                  ˆˆfd„«       | S )zŸ
    Copy pasted from torch's function but we remove the communications (partitionning)
    as well as buffer registering that is similarly not efficient.
    r   c                ó   •—  ‰| |‰«      S ©N© )ÚmodÚinputsr:   Úinput_fns     €€r   ú<lambda>z#distribute_module.<locals>.<lambda>¨   s   ø€ ÁÈ#ÈvÐWbÓAc€ rI   c                ó   •—  ‰| |‰«      S rO   rP   )rQ   rR   Úoutputsr:   Ú	output_fns      €€r   rT   z#distribute_module.<locals>.<lambda>ª   s   ø€ ÁiÐPSÐU\Ð^iÓFj€ rI   )ÚlenÚ_forward_pre_hooksÚregister_forward_pre_hookÚregister_forward_hook)Úmoduler:   rS   rW   s    ```r   Údistribute_moduler]   œ   sG   ú€ ô ˆ6×$Ñ$Ó%¨Ò*ØÐØ×,Ñ,Ô-cÔdØÐ Ø×(Ñ(Ô)jÔkØ€MrI   c                  óB   — e Zd ZdZdZed„ «       Zed„ «       Zd„ Zdd„Z	y)	ÚTensorParallelLayerú9
    General tensor parallel layer for transformers.
    Tc                 ó   — y rO   rP   ©Úinput_layoutsÚdesired_input_layoutsrQ   rR   r:   s        r   Ú_prepare_input_fnz%TensorParallelLayer._prepare_input_fnµ   s   € Ø[^rI   c                 ó   — y rO   rP   ©Úoutput_layoutsÚuse_local_outputrQ   rV   r:   s        r   Ú_prepare_output_fnz&TensorParallelLayer._prepare_output_fn¸   s   € ØY\rI   c                ó   — t         ‚rO   )ÚNotImplementedError)Úselfr8   r9   Ú
param_typeÚparam_casting_dtypeÚto_contiguousr;   r:   s           r   Úpartition_tensorz$TensorParallelLayer.partition_tensor»   s   € Ü!Ð!rI   c           
     óÞ   — | j                   rat        ||t        | j                  | j                  | j
                  «      t        | j                  | j                  | j                  «      «       y y rO   )	Úuse_dtensorr]   r   re   rc   rd   rj   rh   ri   ©rm   r\   r:   s      r   Úprepare_module_tpz%TensorParallelLayer.prepare_module_tp¾   sZ   € Ø×ÒÜØØÜ˜×.Ñ.°×0BÑ0BÀD×D^ÑD^Ó_Ü˜×/Ñ/°×1DÑ1DÀd×F[ÑF[Ó\õ	ð rI   N©r\   ú	nn.ModuleÚreturnrw   )
Ú__name__Ú
__module__Ú__qualname__Ú__doc__rs   Ústaticmethodre   rj   rq   ru   rP   rI   r   r_   r_   ®   s4   „ ñð €KàÙ^ó Ø^àÙ\ó Ø\ò"ôrI   r_   c                  óX   ‡ — e Zd ZdZddddœ	 	 	 	 	 dˆ fd„Zed„ «       Zed„ «       Zˆ xZS )	ÚGatherParallelzi
    Simple class used to define the hooks to add to a layer when we just want to gather the outputs
    NT)rc   rh   ri   c               ó†   •— t         ‰| �  «        |xs
 t        «       f| _        || _        t        «       f| _        || _        y rO   )ÚsuperÚ__init__r   rc   rh   rd   ri   )rm   rc   rh   ri   Ú	__class__s       €r   r‚   zGatherParallel.__init__Ï   s>   ø€ ô 	‰ÑÔØ+Ò:¬y«{Ð<ˆÔØ,ˆÔÜ&/£k ^ˆÔ"Ø 0ˆÕrI   c                óV   — |r&t        |d   t        «      r|d   j                  «       }|S ©Nr   ©r   r   Úto_localrb   s        r   re   z GatherParallel._prepare_input_fnÜ   s)   € á”j ¨¡¬GÔ4Ø˜A‘Y×'Ñ'Ó)ˆFØˆrI   c                ó”   — t         j                  j                  |d   t         j                  j                  j                  d¬«       |S )Nr   F)ÚopÚasync_op)r4   ÚdistributedÚ
all_reduceÚReduceOpÚSUMrg   s        r   rj   z!GatherParallel._prepare_output_fnâ   s;   € ô 	×Ñ×$Ñ$ W¨Q¡Z´E×4EÑ4E×4NÑ4N×4RÑ4RÐ]bÐ$ÔcØˆrI   ©rc   úOptional[Placement]rh   r�   ri   Úbool)	ry   rz   r{   r|   r‚   r}   re   rj   Ú__classcell__©rƒ   s   @r   r   r   Ê   s^   ø„ ñð .2Ø.2Ø!%ñ1ð +ð1ð ,ð	1ð
 õ1ð ñó ðð
 ñó ôrI   r   c                  ó<   — e Zd ZdZedd„«       Zedd„«       Zdd„Zy)ÚIsolatedParallelzŽ
    This class is used to isolate computation in a TP layer from the rest of the world.
    Parameters need to be LOCAL, so not dtensors
    Nc                óP   — |d   }t        |t        «      r|j                  «       }|S r…   r†   ©rc   rd   rQ   rR   r:   Úinput_tensors         r   re   z"IsolatedParallel._prepare_input_fnï   s+   € ð ˜a‘yˆÜ�l¤GÔ,Ø'×0Ñ0Ó2ˆLØÐrI   c                ó   — |S rO   rP   rg   s        r   rj   z#IsolatedParallel._prepare_output_fn÷   s	   € ð ˆrI   c           
     ót   — t        ||t        | j                  d d «      t        | j                  d d «      «       y rO   )r]   r   re   rj   rt   s      r   ru   z"IsolatedParallel.prepare_module_tpü   s4   € ÜØØÜ�D×*Ñ*¨D°$Ó7Ü�D×+Ñ+¨T°4Ó8õ		
rI   rO   rv   )ry   rz   r{   r|   r}   re   rj   ru   rP   rI   r   r•   r•   é   s4   „ ñð
 òó ðð òó ðô
rI   r•   c                  ó`   ‡ — e Zd ZdZdddddœ	 	 	 	 	 d	ˆ fd„Zed„ «       Zd„ Zed„ «       Zˆ xZ	S )
ÚColwiseParallelr`   NT©rc   rh   ri   rs   c               ó°   •— t         ‰| �  «        |xs
 t        «       f| _        |xs t	        d«      f| _        t        «       f| _        || _        || _        y ©Nr,   )	r�   r‚   r   rc   r   rh   rd   ri   rs   ©rm   rc   rh   ri   rs   rƒ   s        €r   r‚   zColwiseParallel.__init__
  sR   ø€ ô 	‰ÑÔØ+Ò:¬y«{Ð<ˆÔØ-Ò:´°r³Ð<ˆÔÜ&/£k ^ˆÔ"Ø 0ˆÔØ&ˆÕrI   c                ó’   — |d   }t        |t        «      st        j                  ||| d¬«      }| |k7  r|j                  |d¬«      }|S )Nr   F©Ú	run_check©Ú
placementsrŠ   ©r   r   Ú
from_localÚredistributer—   s         r   re   z!ColwiseParallel._prepare_input_fn  sV   € ð ˜a‘yˆÜ˜,¬Ô0Ü"×-Ñ-¨l¸KÈÐbgÔhˆLð Ð1Ò1Ø'×4Ñ4Ð@UÐ`eÐ4ÓfˆLØÐrI   c                ó4  — |dk(  rt        ||||d«      }t        d«      g}	nt        d«      g}	t        ||||d«      }|j                  |«      }|r|j                  «       }| j                  rt        j                  |||	d¬«      }t        j                  |«      S )NÚbiasr,   r+   Fr¢   )	rL   r   r3   Ú
contiguousrs   r   r§   r
   Ú	Parameter©
rm   r8   r9   rn   ro   rp   r;   r:   Ú	parameterÚshards
             r   rq   z ColwiseParallel.partition_tensor&  s—   € ð ˜ÒÜ(¨°¸[È$ÐPRÓSˆIÜ˜2“Y�K‰Eä˜2“Y�KˆEÜ(¨°¸[È$ÐPRÓSˆIà—L‘LÐ!4Ó5ˆ	ÙØ!×,Ñ,Ó.ˆIØ×ÒÜ×*Ñ*¨9°kÀ5ÐTYÔZˆIÜ�|‰|˜IÓ&Ð&rI   c                ón   — |j                   | k7  r|j                  | d¬«      }|r|j                  «       S |S )NFr¤   )r¥   r¨   r‡   rg   s        r   rj   z"ColwiseParallel._prepare_output_fn8  s=   € ð ×Ñ Ò/Ø×*Ñ*°nÈuÐ*ÓUˆGá%5ˆw×ÑÓ!ÐB¸7ÐBrI   r�   )
ry   rz   r{   r|   r‚   r}   re   rq   rj   r’   r“   s   @r   rœ   rœ     sh   ø„ ñð .2Ø.2Ø!%Øñ'ð +ð'ð ,ð	'ð
 õ'ð ñ
ó ð
ò'ð$ ñCó ôCrI   rœ   c                  ó   — e Zd Zd„ Zy)ÚPackedColwiseParallelc                óî   — t        ||||d«      }|j                  |«      }|r|j                  «       }| j                  r#t	        j
                  ||t        d«      gd¬«      }t        j                  |«      S )Nr+   Fr¢   ©	rH   r3   r«   rs   r   r§   r   r
   r¬   ©	rm   r8   r9   rn   ro   rp   r;   r:   r®   s	            r   rq   z&PackedColwiseParallel.partition_tensorB  ók   € ô ' u¨k¸;ÈÈbÓQˆ	Ø—L‘LÐ!4Ó5ˆ	ÙØ!×,Ñ,Ó.ˆIØ×ÒÜ×*Ñ*¨9°kÄEÈ"ÃIÀ;ÐZ_Ô`ˆIÜ�|‰|˜IÓ&Ð&rI   N©ry   rz   r{   rq   rP   rI   r   r²   r²   A  ó   „ ó
'rI   r²   c                  óh   ‡ — e Zd ZdZdddddœ	 	 	 	 	 d
ˆ fd„Zd„ Zed„ «       Zed„ «       Zdd	„Z	ˆ xZ
S )ÚRowwiseParallela  
    Partition a compatible nn.Module in a row-wise fashion. Currently supports nn.Linear and nn.Embedding.
    Users can compose it with ColwiseParallel to achieve the sharding of more complicated modules.
    (i.e. MLP, Attention)

    Keyword Args:
        input_layouts (Placement, optional):
            The DTensor layout of input tensor for the nn.Module, this is used to annotate the input tensor to
            become a DTensor. If not specified, we assume the input tensor to be sharded on the last dimension.
        output_layouts (Placement, optional):
            The DTensor layout of the output for the nn.Module, this is used to ensure the output of the nn.Module
            with the user desired layout. If not specified, the output tensor is replicated.
        use_local_output (bool, optional):
            Whether to use local :class:`torch.Tensor` instead of :class:`DTensor` for the module output, default: True.
    Returns:
        A :class:`ParallelStyle` object that represents Rowwise sharding of the nn.Module.
    NTr�   c               ó�   •— t         ‰| �  «        |xs t        d«      f| _        |xs
 t	        «       f| _        || _        || _        y rŸ   )r�   r‚   r   rc   r   rh   ri   rs   r    s        €r   r‚   zRowwiseParallel.__init__b  sF   ø€ ô 	‰ÑÔØ+Ò8¬u°R«yÐ:ˆÔØ-Ò<´³Ð>ˆÔØ 0ˆÔØ&ˆÕrI   c                ó  — |dk7  rt        ||||d«      }t        d«      g}	nt        «       g}	|d d  }|j                  |«      }|r|j	                  «       }| j
                  rt        j                  |||	d¬«      }t        j                  |«      S )Nrª   r,   Fr¢   )
rL   r   r   r3   r«   rs   r   r§   r
   r¬   r­   s
             r   rq   z RowwiseParallel.partition_tensorp  s‹   € ð ˜ÒÜ(¨°¸[È$ÐPRÓSˆIÜ˜2“Y�K‰Eä“[�MˆEØ™a˜ˆIà—L‘LÐ!4Ó5ˆ	ÙØ!×,Ñ,Ó.ˆIØ×ÒÜ×*Ñ*¨9°kÀ5ÐTYÔZˆIÜ�|‰|˜IÓ&Ð&rI   c                óò   — t        |d«      r$|j                  �|j                  |_        d |_        |d   }t        |t        «      st	        j
                  ||| d¬«      }| |k7  r|j                  |d¬«      }|S )Nrª   r   Fr¢   Tr¤   )Úhasattrrª   Ú_biasr   r   r§   r¨   r—   s         r   re   z!RowwiseParallel._prepare_input_fn‚  sw   € ä�3˜Ô C§H¡HÐ$8ØŸ™ˆCŒIØˆCŒHà˜a‘yˆÜ˜,¬Ô0Ü"×-Ñ-¨l¸KÈÐbgÔhˆLàÐ1Ò1Ø'×4Ñ4Ð@UÐ`dÐ4ÓeˆLØÐrI   c                ó¤   — |j                   | k7  r|j                  | d¬«      }t        |d«      r||j                  z  }|r|j	                  «       S |S )NTr¤   r¿   )r¥   r¨   r¾   r¿   r‡   rg   s        r   rj   z"RowwiseParallel._prepare_output_fn�  sU   € ð
 ×Ñ Ò/Ø×*Ñ*°nÈtÐ*ÓTˆGÜ�3˜Ô Ø�s—y‘yÑ ˆGá%5ˆw×ÑÓ!ÐB¸7ÐBrI   c           
     ó  — d|_         | j                  rït        |t        j                  «      rt        d«      f| _        nbt        |t        j                  «      rt        «       f| _        n7t        |t        j                  «      rt        d«      f| _        nt        d«      ‚t        ||t        | j                  | j                  | j                  «      t        | j                  | j                   | j"                  «      «       y y )NTr,   zBRowwiseParallel currently only support nn.Linear and nn.Embedding!)Ú_distribute_module_appliedrs   r   r
   ÚLinearr   rd   Ú	Embeddingr   r¬   rl   r]   r   re   rc   rj   rh   ri   rt   s      r   ru   z!RowwiseParallel.prepare_module_tpœ  sÀ   € Ø,0ˆÔ)Ø×ÒÜ˜&¤"§)¡)Ô,äEJÈ2ÃYÀL�Õ*Ü˜F¤B§L¡LÔ1ä.7«k¨^�Õ*Ü˜F¤B§L¡LÔ1ä.3°B«i¨\�Õ*ä)Ð*nÓoÐoäØØÜ˜×.Ñ.°×0BÑ0BÀD×D^ÑD^Ó_Ü˜×/Ñ/°×1DÑ1DÀd×F[ÑF[Ó\õ	ð rI   r�   rv   )ry   rz   r{   r|   r‚   rq   r}   re   rj   ru   r’   r“   s   @r   rº   rº   O  sm   ø„ ñð* .2Ø.2Ø!%Øñ'ð +ð'ð ,ð	'ð
 õ'ò'ð$ ñó ðð ñ	Có ð	C÷rI   rº   c                  ó   — e Zd Zd„ Zy)ÚPackedRowwiseParallelc                óî   — t        ||||d«      }|j                  |«      }|r|j                  «       }| j                  r#t	        j
                  ||t        d«      gd¬«      }t        j                  |«      S )Nr,   Fr¢   r´   rµ   s	            r   rq   z&PackedRowwiseParallel.partition_tensor´  r¶   rI   Nr·   rP   rI   r   rÆ   rÆ   ³  r¸   rI   rÆ   c                  óT   ‡ — e Zd ZdZddddœd	ˆ fd„Zed„ «       Zed„ «       Zd„ Zˆ xZ	S )
ÚSequenceParallelaa
  
    SequenceParallel replicates a compatible ``nn.Module`` parameters and runs the sharded computation with
    input sharded on the sequence dimension. This currently supports ``nn.LayerNorm``, ``nn.Dropout``, and the
    `RMSNorm python implementation <https://github.com/facebookresearch/llama/blob/main/llama/model.py#L34>`__

    This style implements the operation that is described in the paper
    `Reducing Activation Recomputation in Large Transformer Models <https://arxiv.org/abs/2205.05198>`__

    If the input passed in to this ``nn.Module`` is a :class:`torch.Tensor`, it assumes that the input is already sharded
    on the sequence dimension and converts the input to a :class:`DTensor` sharded on the sequence dimension. If the input
    passed in to this ``nn.Module`` is already a :class:`DTensor` but is not sharded on the sequence dimension, it would
    redistribute the input to be sharded on the sequence dimension.

    The output of the ``nn.Module`` will be sharded on the sequence dimension.

    Keyword Args:
        sequence_dim (int, optional):
            The sequence dimension of the input tensor for the ``nn.Module``, this is used to annotate the input tensor to
            become a DTensor that is sharded on the sequence dimension, default: 1.
        use_local_output (bool, optional):
            Whether to use local :class:`torch.Tensor` instead of :class:`DTensor` for the module output, default: False.
    Returns:
        A :class:`ParallelStyle` object that represents Sequence Parallel of the ``nn.Module``.

    Example::
        >>> # xdoctest: +SKIP(failing)
        >>> from torch.distributed.tensor.parallel import parallelize_module, SequenceParallel
        >>> from torch.distributed.device_mesh import init_device_mesh
        >>> ...
        >>> m = Model(...)  # m is a nn.Module that contains a "norm" nn.LayerNorm submodule
        >>> tp_mesh = init_device_mesh("cuda", (8,))
        >>>
        >>> # By default, the input of the "norm" will be converted to DTensor that shards on the sequence dim
        >>> # and the output of "norm" will return a sharded on sequence dimension :class:`DTensor`.
        >>>
        >>> sharded_mod = parallelize_module(m, tp_mesh, {"norm": SequenceParallel()}),
        >>> ...

    .. note:: SequenceParallel style assumes ones initialization if there are weights in the nn.Module (i.e.
        ``nn.LayerNorm`` or ``RMSNorm``, and they by default have ones initialization). If you have custom
        inits for the weights on those modules, you need to broadcast the weights before/after parallelizing
        to ensure that they are replicated.
    r*   F)Úsequence_dimri   rs   c               óÐ   •— t         ‰| �  «        t        «       f| _        t	        d«      f| _        t        «       f| _        || _        d| _        t	        |«      f| _	        || _        y )Nr*   T)
r�   r‚   r   rc   r   rd   rh   ri   rs   Úsequence_sharding)rm   rÊ   ri   rs   rƒ   s       €r   r‚   zSequenceParallel.__init__î  s\   ø€ Ü‰ÑÔÜ'›k˜^ˆÔÜ&+¨A£h [ˆÔ"Ü(›{˜nˆÔØ 0ˆÔØˆÔÜ"'¨Ó"5Ð!7ˆÔØ 0ˆÕrI   c                ó’   — |d   }t        |t        «      st        j                  ||| d¬«      }| |k7  r|j                  |d¬«      }|S )Nr   Fr¢   Tr¤   r¦   r—   s         r   re   z"SequenceParallel._prepare_input_fnø  sR   € à˜a‘yˆÜ˜,¬Ô0Ü"×-Ñ-¨l¸KÈÐbgÔhˆLØÐ1Ò1Ø'×4Ñ4Ð@UÐ`dÐ4ÓeˆLØÐrI   c                óZ   — |j                  t        «       fd¬«      }|j                  «       S )NTr¤   )r¨   r   r‡   rg   s        r   rj   z#SequenceParallel._prepare_output_fn  s1   € à×&Ñ&Ü!›�~°ð 'ó 
ˆð ×ÑÓ!Ð!rI   c                óØ   — |d d  }|j                  |«      }|r|j                  «       }| j                  r"t        j                  ||t        «       gd¬«      }t        j                  |«      S )NFr¢   )r3   r«   rs   r   r§   r   r
   r¬   rµ   s	            r   rq   z!SequenceParallel.partition_tensor  s`   € ð ™!�Hˆ	Ø—L‘LÐ!4Ó5ˆ	ÙØ!×,Ñ,Ó.ˆIØ×ÒÜ×*Ñ*¨9°kÄIÃKÀ=Ð\aÔbˆIÜ�|‰|˜IÓ&Ð&rI   )rÊ   Úintri   r‘   )
ry   rz   r{   r|   r‚   r}   re   rj   rq   r’   r“   s   @r   rÉ   rÉ   Á  sE   ø„ ñ*ðX /0È%Ð]b÷ 1ð ñó ðð ñ"ó ð"ö
'rI   rÉ   >
   ÚlocalÚgatherÚcolwiseÚrowwiseÚcolwise_repÚrowwise_repÚlocal_colwiseÚlocal_rowwiseÚsequence_parallelÚlocal_packed_rowwisec                óÎ  — t        | t        «      st        dt        | «      › d�«      ‚| dk(  r
t	        «       S | dk(  r
t        «       S | dk(  rt	        t        «       ¬«      S | dk(  rt        t        «       ¬«      S | d	k(  rt	        d
¬«      S | dk(  rt        d
¬«      S | dk(  r
t        «       S | dk(  r
t        «       S | dk(  rt        d
¬«      S | dk(  r
t        «       S t        d| › �«      ‚)zª
    In model configurations, we use a neutral type (string) to specify parallel
    styles, here we translate them into torch.distributed tensor-parallel
    types.
    z Unsupported parallel style type z, expected strrÓ   rÔ   rÕ   )rh   rÖ   )rc   r×   F)rs   rØ   rÑ   rÒ   rÚ   rÙ   z"Unsupported parallel style value: )r   Ústrr6   Útyperœ   rº   r   r•   r   rÆ   rÉ   )Ústyles    r   Ú!translate_to_torch_parallel_stylerß   #  sô   € ô �eœSÔ!ÜÐ;¼DÀ»K¸=ÈÐWÓXÐXà�	ÒÜÓ Ð Ø	�)Ò	ÜÓ Ð Ø	�-Ò	Ü¬i«kÔ:Ð:Ø	�-Ò	Ü¬Y«[Ô9Ð9Ø	�/Ò	!Ü¨5Ô1Ð1Ø	�/Ò	!Ü¨5Ô1Ð1Ø	�'Ò	ÜÓ!Ð!Ø	�(Ò	ÜÓÐØ	Ð(Ò	(Ü$°Ô7Ð7Ø	Ð%Ò	%ÜÓ!Ð!äÐ=¸e¸WÐEÓFÐFrI   c           	     ó€  — |�t        |«      }	 |j                  ||«       d|v rp|j	                  dd«      d   }t        j                  dd	|«      }	|j                  |	d
«      x}
r/t        |
«      }| j                  |«      }|j                  ||«       yyy# t        $ r}t        d|› d|› d|› �«       Y d}~Œ—d}~ww xY w)a£  
    Add hooks to the module holding the layer. Meaning:
    ```
    class MyModel(nn.Module):
        def __init__(self):
            self.layer = nn.Linear(10, 10)
    ```
    has state_dict like:
    ```
    {
        "layer.weight": torch.Tensor,
        "layer.bias": torch.Tensor
    }
    ```
    we add hooks to `MyModel` as well as `layer` to make sure that the tensors are correctly sharded and gathered.
    NúTrying to prepare ú0, but it's not supported. Corresponding module: z Fix it's TP plan: ú.r*   r   ú\d+Ú*F)	rß   ru   rl   ÚprintÚrsplitÚreÚsubÚgetÚget_submodule)Úmodelr\   Útp_planÚ
layer_nameÚcurrent_module_planr:   Útp_layerÚeÚparrent_layer_nameÚgeneric_nameÚmodule_planÚmodule_to_tp_s               r   Ú#add_tensor_parallel_hooks_to_modulerö   E  så   € ð& Ð&Ü4Ð5HÓIˆð	Ø×&Ñ& v¨{Ô;ð ˆjÑØ'×.Ñ.¨s°AÓ6°qÑ9ÐÜ—v‘v˜f cÐ+=Ó>ˆà!Ÿ+™+ l°EÓ:Ð:ˆ;Ð:Ü8¸ÓEˆHØ!×/Ñ/Ð0BÓCˆMØ×&Ñ& }°kÕBð ;ð	 øô #ò 	ÜØ$ Z LÐ0`ÐagÐ`hÐh{Ð|}Ð{~Ð÷ñ ûð	ús   �B Â	B=ÂB8Â8B=c                ó  — d|v r|j                  dd«      n|\  }}	| j                  }
| j                  |«      }d}t        |«      }t	        j
                  dd|«      }||
v r|
|   }n3d|v r/|j                  dd«      d   |
v r|
|j                  dd«      d      }t        |dd«      st        | ||
|||«       d	|_        |�$	 t        |«      }|j                  |||	||||«      }n&|d   j                  |«      }|r|j                  «       }t        |t         j"                  j$                  «      st         j"                  j%                  |«      }t'        ||	|«       |S # t        $ r!}t        d
|› d|› d› d|› �«       Y d}~Œwd}~ww xY w)a¯  
    Main uses cases:
    - column / rowise parallelism, you just shard all the weights of the layer (weight and bias)
    - packed layers: you slice the weights, then shard like above
    - custom operation:
        - you want to add an all-gather at the end of a local layer.
        - you want to have a layer that is isolated from the rest of the world (because torch.DTensor does not work well with `.view` for instance)

    rã   r*   Nrä   rå   r   Ú
_is_hookedFTrá   râ   z" Fix it's TP plan, current layer: z : .)rç   Ú_tp_planrë   rÐ   rè   ré   Úgetattrrö   rø   rß   rq   rl   ræ   r3   r«   r   r4   r
   r¬   Úsetattr)rì   r8   r9   Úparameter_namero   Úis_contiguousr;   r:   Ú
param_namern   rí   Úmodule_to_tprï   Úgeneric_param_namerð   rñ   s                   r   Úshard_and_distribute_moduler  l  sÙ  € ð ?BÀ^Ñ>S˜^×2Ñ2°3¸Ô:ÐYgÑ€J�
Ø�n‰n€GØ×&Ñ& zÓ2€LØÐÜˆt‹9€DÜŸ™ ¨¨^Ó<ÐØ˜WÑ$Ø%Ð&8Ñ9ÑØ	Ð"Ñ	"Ð'9×'@Ñ'@ÀÀaÓ'HÈÑ'KÈwÑ'VØ%Ð&8×&?Ñ&?ÀÀQÓ&GÈÑ&JÑKÐô �< ¨uÔ5Ü+¨E°<ÀÈ*ÐViÐkvÔwØ"&ˆÔàÐ&ð	Ü8Ð9LÓMˆHØ×-Ñ-Ø�{ JÐ0CÀ]ÐTXÐZeó‰Eð �c‘
—‘Ð1Ó2ˆÙØ×$Ñ$Ó&ˆEô �eœUŸX™X×/Ñ/Ô0Ü—‘×"Ñ" 5Ó)ˆÜˆL˜* eÔ,à€Løô# #ò 	ÜØ$ ^Ð$4Ð4dÐeqÐdrð  sUð  V^ð  U_ð  _bð  cdð  beð  f÷ñ ûð	ús   Ã"E Å	FÅ%FÆF)r   rÐ   r   zUnion[int, List[int]]rx   z	List[int])NNNrv   )rÞ   rÜ   )9Ú
__future__r   rè   Ú	functoolsr   r   Útypingr   r   r   r	   r4   r
   Úutilsr   r   Ú	LayerNormÚALL_LAYERNORM_LAYERSÚ
get_loggerry   Úloggerr‹   Úis_availableÚ_torch_distributed_availableÚtorch.distributed.tensorr   r   r   r   r   r‘   Úuint8Úint8Úint16r5   Úbfloat16Úint32Úfloat32Úfloat64Úint64Úfloat8_e4m3fnr7   rH   rL   r]   r_   r   r•   rœ   r²   rº   rÆ   rÉ   ÚSUPPORTED_TP_STYLESrß   rö   r  rP   rI   r   ú<module>r     s‹  ðõ #ã 	ß (ß /Ó /ã Ý ç 6ð Ÿ™�~Ð à	ˆ×	Ñ	˜HÓ	%€ð  %×0Ñ0×=Ñ=Ó?Ð ñ ˜UÔ#Ñ(DßMÓMó&ð6 �J‰JØ
�+‰+Ø
�*‰*Ø�;‰;Ø�=‰=Ø�N‰NØ�;‰;Ø�=‰=Ø�=‰=Ø�;‰;Ø×"Ñ"ñÐ ò;6ò|ð" ØØð	Øðð
 ó÷$ñ ô8Ð(ô ô>
Ð*ô 
ô89CÐ)ô 9Côx'˜Oô 'ôaÐ)ô aôH'˜Oô 'ôQ'Ð*ô Q'òhÐ ð òGó ðGòB$CóN4rI   