o
    ॵi                     @   sn   d dl mZ d dlmZ d dlmZ d dlmZmZ d dl	m
Z
 d dlmZ e
jejdG dd	 d	eZd
S )    )Union)nn)Trainers)Model
TorchModel)TRAINERS)EpochBasedTrainer)module_namec                       sh   e Zd ZdZ fddZdeejef fddZ	 fddZ
 fd	d
Zg g fddZdddZ  ZS )VisionEfficientTuningTrainerz Vision Efficient Tuning Trainer based on EpochBasedTrainer

    The trainer freezes the parameters of the pre-trained model and
    tunes the extra parameters of the different parameter-efficient
    transfer learning (PETL) method.

    c                    s   t  j|i | d S N)super__init__selfargskwargs	__class__ j/home/ubuntu/.local/lib/python3.10/site-packages/modelscope/trainers/cv/vision_efficient_tuning_trainer.pyr      s   z%VisionEfficientTuningTrainer.__init__returnc                 C   sl   t j| j| jd}d| jd v r| j|fi | jd d }t|tjs,t|dr,|j	S t|tjr4|S dS )z Instantiate a pytorch model and return.

        By default, we will create a model using config from configuration file. You can
        override this method in a subclass.

        )cfg_dict
freeze_cfgmodelN)
r   from_pretrained	model_dircfgfreeze
isinstancer   Modulehasattrr   )r   r   r   r   r   build_model   s   z(VisionEfficientTuningTrainer.build_modelc                    s   |    t j|i | d S r   )print_model_params_statusr   trainr   r   r   r   r#   (   s   z"VisionEfficientTuningTrainer.trainc                    s   t  j|i |}|S r   )r   evaluate)r   r   r   metric_valuesr   r   r   r$   ,   s   z%VisionEfficientTuningTrainer.evaluatec                    sh  t |dr	|j}n|}|r^t|dkr^d|v r9|d }|jj D ]\ }t fdd|D dk}|r7d|_q!n%d|v r^|d }|jj D ]\ }t fdd|D dk}|r]d|_qG|rt|dkrd|v r|d }|jj D ]\ }t fd	d|D dk}|rd
|_qt|S d|v r|d }|jj D ]\ }t fdd|D dk}|rd
|_q|S )z Freeze or train the model based on the config.

        Args:
          model: the current model.
          freeze_part: the config of frozen parameters.
          train_part: the config of trainable parameters.
        moduler   backbonec                       g | ]}| v qS r   r   .0pnamer   r   
<listcomp>B       z7VisionEfficientTuningTrainer.freeze.<locals>.<listcomp>Fheadc                    r(   r   r   r)   r,   r   r   r.   H   r/   c                    r(   r   r   r)   r,   r   r   r.   Q   r/   Tc                    r(   r   r   r)   r,   r   r   r.   W   r/   )	r    r&   lenr   r'   named_parameterssumrequires_gradr0   )r   r   freeze_part
train_partfreeze_modelpartparamfreeze_flagr   r,   r   r   0   sH   
z#VisionEfficientTuningTrainer.freezeNc           	      C   s   |du r| j }|du r| j}i }d}| D ]5\}}|jrEd|ddd dddd }||v r?||  | 7  < n| ||< || 7 }qt| }|	d| d| d	|| d
d| d	 dS )z,Print the status and parameters of the modelNr   .      zLoad trainable params z / z = z.2%z, train part: )
r   loggerr2   r4   joinsplitnumelr3   valuesinfo)	r   r   r?   train_param_dictall_param_numelkeyvalsub_keytrain_param_numelr   r   r   r"   \   s*   &z6VisionEfficientTuningTrainer.print_model_params_status)NN)__name__
__module____qualname____doc__r   r   r   r   r   r!   r#   r$   r   r"   __classcell__r   r   r   r   r
      s    ,r
   N)typingr   torchr   modelscope.metainfor   modelscope.models.baser   r   modelscope.trainers.builderr   modelscope.trainers.trainerr   register_modulevision_efficient_tuningr
   r   r   r   r   <module>   s   