o
    Ti-9                  
   @   s   d dl Z ddlmZmZmZmZmZmZ ddlT d dl	m
Z
 zd dlmZ W n ey: Z zdZW Y dZ[ndZ[ww dd Zd	d
 ZdddZdddZdd ZdddZdd Zdd Zdd Zde jjfddZdS )     N   )Embedding_CompressLinearLayer_CompressConv2dLayer_CompressBNLayer_CompressColumnParallelLinear_CompressRowParallelLinear_Compress)*)logger)prunerc                 C   s&   | d}| }|D ]}t||}q	|S )z
    Recursively get the attribute of a module.
    Args:
        model (`torch.nn.Module`)
            The model to get the attribute from.
        module_name (`str`)
            The name of the module to get the attribute from.
    .)splitgetattr)modelmodule_name
split_listoutputname r   P/home/ubuntu/.local/lib/python3.10/site-packages/deepspeed/compression/helper.pyrecursive_getattr   s
   
	r   c                 C   s>   | d}| }|dd D ]}t||}q||d | dS )a:  
    Recursively set the attribute of a module.
    Args:
        model (`torch.nn.Module`)
            The model to set the attribute in.
        module_name (`str`)
            The name of the module to set the attribute in.
        module (`torch.nn.Module`)
            The module to set the attribute to.
    r   N)r   r   __setattr__)r   r   moduler   r   r   r   r   r   recursive_setattr!   s
   
r   c           	   
   C   s^  t | |}d}t|dr|jdurd}t|tst|tjjrJt|tr(|}nUt|j|j	|dj
|jj|jjd}|jj|j_|rH|jj|j_n3t|tsVt|tjjrt|tr_|}nt|j|j|j|j|j|j|j||j	j
|jj|jjd}|jj|j_|r|jj|j_nt|tjjrt|j|j|j|j|j
|jj|jj}|jj|j_|r|jj|j_|j j|j _|j!j|j!_nt|t"st|tjj#rt|t"r|}nt"|j$|j%|j&|j'|j(|j)|j*j
|jj|jjd}|jj|j_n|dur9t|t+s	t||j,r9t|t+r|}nkt+||j-|j.|j/|j0|dj
|jj|jjd}|jj|j_|r8|jj|j_nD|dur{t|t1sKt||j2r{t|t1rT|}n)t1||j-|j.|j3|j0|dj
|jj|jjd}|jj|j_|rz|jj|j_nd}|dur'|4 D ]\}}|t5kr|t6 r|7|t8 |t9  q|t:kr|t; r|<|t= |t>  q|t?kr|t@ r|A|tB |tC |tD  q|tEkr|tF r|G|tH |tI |tJ  q|tKkr
|tL r|M|tN |tO |tP |tQ |tR |tS  q|tTkr |tU r|V|tW |tX  qtYd	Z|t[| || dS )
a;  
    Replace a module with a new module.
    Args:
        model (`torch.nn.Module`)
            The model to replace the module in.
        module_name (`str`)
            The name of the module to replace.
        compression_technique (`str`)
            The compression technique to use for the new module.
    FbiasNTr   )devicedtype)gather_outputskip_bias_addr   )input_is_parallelr    r   z+Compression technique {} is not implemented)\r   hasattrr   
isinstancer   torchnnLinearin_featuresout_featurestoweightr   r   datar   Conv2din_channelsout_channelskernel_sizestridepaddingdilationgroupspadding_modeBatchNorm2dr   num_featuresepsmomentumaffinetrack_running_statsrunning_meanrunning_varr   	Embeddingnum_embeddingsembedding_dimpadding_idxmax_norm	norm_typescale_grad_by_freqsparser   ColumnParallelLinear
input_sizeoutput_sizer   r    r   RowParallelLinearr!   itemsSPARSE_PRUNINGSPARSE_PRUNING_ENABLEDenable_sparse_pruningSPARSE_PRUNING_DENSE_RATIOSPARSE_PRUNING_METHODROW_PRUNINGROW_PRUNING_ENABLEDenable_row_pruningROW_PRUNING_DENSE_RATIOROW_PRUNING_METHODHEAD_PRUNINGHEAD_PRUNING_ENABLEDenable_head_pruningHEAD_PRUNING_DENSE_RATIOHEAD_PRUNING_METHODHEAD_PRUNING_NUM_HEADSACTIVATION_QUANTIZATIONACTIVATION_QUANTIZATION_ENABLEDenable_activation_quantizationACTIVATION_QUANTIZE_BITSACTIVATION_QUANTIZE_TYPEACTIVATION_QUANTIZE_RANGEWEIGHT_QUANTIZATIONWEIGHT_QUANTIZE_ENABLEDenable_weight_quantizationWEIGHT_QUANTIZE_START_BITSWEIGHT_QUANTIZE_TARGET_BITSWEIGHT_QUANTIZATION_PERIOD"WEIGHT_QUANTIZE_IN_FORWARD_ENABLEDWEIGHT_QUANTIZE_TYPEWEIGHT_QUANTIZE_GROUPSCHANNEL_PRUNINGCHANNEL_PRUNING_ENABLEDenable_channel_pruningCHANNEL_PRUNING_DENSE_RATIOCHANNEL_PRUNING_METHODNotImplementedErrorformatr   )	r   r   compression_techniquempu
old_module	need_bias
new_modulekvr   r   r   module_replacement3   s   





















rw   c                 C   s`   t | tjjpt | tjjpt | tjjpt | tjj}|d ur.|p-t | |jp-t | |j}|S N)	r#   r$   r%   r&   r,   r=   r5   rH   rE   )r   rq   retr   r   r   is_module_compressible   s   rz   c           	      C   s^   |   D ]\}}t||rt| ||d q|D ]\}}}|D ]}|D ]}t| || q"qq| S )a+  
    Prepare the compression techniques of a model.
    Args:
        model (`torch.nn.Module`)
            The model to prepare the compression techniques of.
        compression_technique_list (`list`)
            The list of compression techniques to prepare the model to.
            list[]
    )rq   )named_modulesrz   rw   )	r   compression_technique_listrq   r   r   module_name_lists_rp   mnlr   r   r   compression_preparation   s   
r   Fc                 C   s   t | |}| D ]f\}}|tkr|t r|t r|   S |tkr-|t r-|   S |t	krB|t
 s9|durB|j||d  S |tkrZ|t sN|durZ|j||t |d  S |tkro|t sf|duro|j||d  S q	dS )aa  
    Fix the compression technique of a module.
    Args:
        model (`torch.nn.Module`)
            The model to fix the compression technique of.
        module_name (`str`)
            The name of the module to fix the compression technique of.
        compression_technique (`str`)
            The compression technique to fix the module to.
    N)dim_reduction)r   rI   r`   rf   ra   fix_weight_quantizationrJ   rK   fix_sparse_pruning_helperrO   rP   fix_row_col_pruning_helperrT   rU   fix_head_pruning_helperrY   ri   rj   fix_channel_pruning_helper)r   r   rp   maskr   r   ru   rv   r   r   r   fix_compression   s   
r   c                 C   s   t | dr	| j}n| }| D ]F\}}t||rUt||}tjj|jj	
d|jj	
d|jdur3dndd}|jj	  |j_	|jdurO|jj	d|j_	t||| q| S )	zZ
    This is a help function to convert conv1d to linear (e.g., convert GPT2 from HF)
    r   r   r   NTFr   r   )r"   r   r{   r#   r   r$   r%   r&   r*   r+   sizer   t
contiguousviewr   )r   convert_typec_modelr   r   rr   rt   r   r   r   convert_conv1d_to_linear   s    



r   c           	      C   s   t dusJ dddlm}m} ddlm} t|tjj	sJ || }g }|D ]0}|||}|i kr7t
d |||| dd | D |d	< t|d	 |d
< t
| q'|S )zGenerate pruners.
    Args:
        config (`neural_compressor.WeightPruningConfig`)
            The object to the class WeightPruningConfig.
        model (`torch.nn.module`)
            The torch module object to be pruned.
    Nzplease ensure the neural_compressor python package is installed by pip or conda if user wants to use snip_momentum sparse pruningr   )process_configparse_to_prune)
get_prunerz/one pruner hooks no layers, please have a checkc                 S   s   g | ]}|qS r   r   ).0keyr   r   r   
<listcomp>  s    z$generate_pruners.<locals>.<listcomp>moduleslen_of_modules)	nc_prunernc_pruner.utilsr   r   nc_pruner.prunersr   r#   r$   r%   Moduler
   warningappendkeysleninfo)	configr   r   r   r   pruners_infoprunersr   r   r   r   r   generate_pruners  s   

r   c                 C   s   dd }|  |}|S )zMount on_step_begin to the model.
    Args:
        model (`torch.nn.module`)
            The torch module object to be pruned.
    c                 S   s   | j D ]}|d qd S )Nr   )r   on_step_begin)r   inputr   r   r   r   hook"  s   
z$register_on_step_begin.<locals>.hook)register_forward_pre_hook)r   r   hook_handler   r   r   register_on_step_begin  s   
r   optc                 C   s,   ddd}| j | _ddl}||| | _ | S )zMount on_before/after_optimizer_step to the optimizer.
    Args:
        model (`torch.opt.Optimizer`)
            The torch optimizer object to be hooked.
    Nc                 S   s\   t | dr| jD ]}|  q|d ur| |}n|  }t | dr,| jD ]}|  q%|S )Nr   )r"   r   on_before_optimizer_step	orig_stepon_after_optimizer_step)selfclosurer   resr   r   r   new_step1  s   





z(rewrite_optimizer_step.<locals>.new_stepr   rx   )stepr   types
MethodType)r   r   r   r   r   r   rewrite_optimizer_step*  s
   
r   )NNrx   )NF)r$   basic_layerr   r   r   r   r   r   	constantsdeepspeed.utilsr
   neural_compressor.compressionr   r   ImportErrorer   r   rw   rz   r   r   r   r   r   optim	Optimizerr   r   r   r   r   <module>   s(    

z
