+
    $Lj                         R t ^ RIHt ^ RIHtHtHt ^ RIt^RIH	t	H
t
 ]'       d   ]	! 4       '       d   ^ RIHt R R ltR R	 ltR
 R lt]
R R l4       t]
R]3R R ll4       tR# )z,
Needed utilities for torchao FP8 training.
)partial)TYPE_CHECKINGCallableOptionalN)is_torchao_availabletorchao_required)Float8LinearConfigc                L    V ^8  d   QhR\         P                  P                  /#    modeltorchnnModule)formats   "?/app/.local/lib/python3.14/site-packages/accelerate/utils/ao.py__annotate__r       s     % % %    c                    RRr!V P                  4        F9  w  r4\        V\        P                  P                  4      '       g   K1  Vf   TpTpK;  	  W3# )z
Finds the first and last linear layer names in a model.

This is needed during FP8 to avoid issues with instability by keeping the first and last layers unquantized.

Ref: https://x.com/xariusrke/status/1826669142604141052
N)named_modules
isinstancer   r   Linear)r   first_linearlast_linearnamemodules   &    r   find_first_last_linear_layersr       sP     !%d+++-fehhoo..##K	 .
 $$r   c                R    V ^8  d   QhR\         R\        \         ,          R\        /# )r   fqnlayers_to_filterreturn)strlistbool)r   s   "r   r   r   1   s%      c T#Y 4 r   c                    \        V \        P                  P                  4      '       d3   V P                  ^,          ^ 8w  g   V P
                  ^,          ^ 8w  d   R# W9   d   R# R# )an  
A function which will check if `module` is:
- a `torch.nn.Linear` layer
- has in_features and out_features divisible by 16
- is not part of `layers_to_filter`

Args:
    module (`torch.nn.Module`):
        The module to check.
    fqn (`str`):
        The fully qualified name of the layer.
    layers_to_filter (`List[str]`):
        The list of layers to filter.
FT)r   r   r   r   in_featuresout_features)r   r   r    s   &&&r   filter_linear_layersr(   1   sM     &%((//**"a'6+>+>+Cq+H
r   c                0    V ^8  d   QhR\         R\        /# )r   r   r!   )r"   r$   )r   s   "r   r   r   H   s     [ [S [T [r   c                8    \        V 4      w  r#\        WW#.R7      # )av  
A filter function which will filter out all linear layers except the first and last.

<Tip>

    For stability reasons, we skip the first and last linear layers Otherwise can lead to the model not training or
    converging properly

</Tip>

Args:
    module (`torch.nn.Module`):
        The module to check.
    fqn (`str`):
        The fully qualified name of the layer.
r    )r   r(   )r   r   r   r   s   &&  r   #filter_first_and_last_linear_layersr,   H   s!    " !>f EL|>YZZr   c                L    V ^8  d   QhR\         P                  P                  /# r
   r   )r   s   "r   r   r   ^   s       r   c                 l    ^ RI Hp V P                  4        F  w  r#\        W14      '       g   K   R# 	  R# )    )Float8LinearTF)torchao.float8.float8_linearr0   r   r   )r   r0   r   r   s   &   r   has_ao_layersr2   ]   s-    9++-f++ . r   c                    V ^8  d   QhR\         P                  P                  R\        R,          R\        \        ,          /# )r   r   configr   module_filter_func)r   r   r   r   r   )r   s   "r   r   r   h   s>     'Z 'Z88??'Z)*'Z !*'Zr   c                l    ^ RI Hp \        V 4      w  rEVf   \        \        WE.R7      pV! WVR7       R# )a  
Converts all `nn.Linear` layers in the model (except the first and last) to torchao's `Float8Linear` layer inplace.

Args:
    model (`torch.nn.Module`):
        The model to convert.
    config (`torchao.float8.Float8LinearConfig`, *optional*):
        The configuration for the FP8 training. Recommended to utilize
        `torchao.float8.recipe_name_to_linear_config` to generate this. In general, the default config should be
        sufficient (what is passed when set to `None`).
    module_filter_func (`Callable`, *optional*, defaults to `filter_linear_layers`):
        Optional function that must take in a module and layer name, and returns a boolean indicating whether the
        module should be converted to FP8. Defaults to `filter_linear_layers`. See it for an example.

Example:

```python
from accelerate.utils.ao import convert_model_to_fp8_ao
from accelerate import Accelerator

accelerator = Accelerator(

model = MyModel()
model.to(accelerator.device)
convert_to_float8_training(model)

model.train()
```
)convert_to_float8_trainingNr+   )module_filter_fnr4   )torchao.float8r7   r   r   r(   )r   r4   r5   r7   r   r   s   &&&   r   convert_model_to_fp8_aor:   g   s7    F : =e DL!$%9\LghuRXYr   )__doc__	functoolsr   typingr   r   r   r   importsr   r   r1   r   r   r(   r,   r2   r:    r   r   <module>r@      sn     4 4  ; C%".[*    .2-P'Z 'Zr   