o
    ꁱi                     @  s   d Z ddlmZ ddlmZ ddlmZ ddlmZ ddl	Z	ddl
mZ ddlmZ eeZeG dd	 d	ZG d
d dejZd%ddZd&ddZd'ddZd'ddZd(d)d#d$ZdS )*zEUtilities for loading fine-tuned LoRA adapters and connector weights.    )annotations)	dataclass)Path)OptionalN)loggingc                   @  sZ   e Zd ZU dZdZded< dZded< dZded< dZded< dZ	ded< d	Z
d
ed< d	S )_LoadReportz3Simple structure capturing what assets were loaded.Fboollanguage_modeldiffusion_head_loradiffusion_head_fullacoustic_connectorsemantic_connectorNzOptional[Path]adapter_root)__name__
__module____qualname____doc__r	   __annotations__r
   r   r   r   r    r   r   B/home/ubuntu/vibevoice-community/vibevoice/modular/lora_loading.pyr      s   
 r   c                      s*   e Zd ZdZd fddZdd Z  ZS )	_DiffusionHeadForwardShimzBWraps the diffusion head to expose the signature expected by PEFT.base	nn.Modulec                   s   t    || _d S N)super__init__r   )selfr   	__class__r   r   r       s   

z"_DiffusionHeadForwardShim.__init__c                 O  sL   t |dkr|d d \}}}n|d}|d}|d}| |||S )N   noisy_images	timesteps	condition)lengetr   )r   argskwargsr    r!   r"   r   r   r   forward$   s   


z!_DiffusionHeadForwardShim.forward)r   r   )r   r   r   r   r   r'   __classcell__r   r   r   r   r      s    r   checkpoint_pathr   returnc                 C  s&   |   r| j} | d  r| d S | S )z8Return the directory that actually holds adapter assets.lora)is_fileparentexists)r)   r   r   r   _resolve_adapter_root.   s
   r/   moduleOptional[nn.Module]pathdevicetorch.devicer   c                 C  sj   | d u s|  s
dS tj||d}| j|dd\}}|r$td|  |r.td|  | | dS )NFmap_locationstrictzConnector load missing keys: z Connector load unexpected keys: T)r.   torchloadload_state_dictloggerwarningto)r0   r2   r3   
state_dictmissing
unexpectedr   r   r   _load_connector9   s   
rB   r   reportNonec              
   C  sH  |d }|d }|d }|d }zddl m} W n ty) }	 ztd|	d }	~	ww | rX| s6| rXtd|  t| jj	}
|
|
|}|| || j_	d	|_d S |d
 }| sd|d
 }| rtd|  tj||d}| jj	j|dd\}}|rtd|  |rtd|  | jj	| d	|_d S d S )Ndiffusion_headadapter_config.jsonadapter_model.binadapter_model.safetensorsr   	PeftModelzEpeft is required to load diffusion head adapters but is not installedz!Loading diffusion head LoRA from Tzdiffusion_head_full.binz)Loading full diffusion head weights from r5   Fr7   z"Diffusion head load missing keys: z%Diffusion head load unexpected keys: )peftrJ   ImportErrorRuntimeErrorr.   r<   infor   modelprediction_headfrom_pretrainedr>   r
   r9   r:   r;   r=   r   )rO   r   r3   rC   diff_diradapter_configadapter_modeladapter_model_safetensorsrJ   excshim	peft_head	full_pathr?   r@   rA   r   r   r   _load_diffusion_headG   sH   

rZ   c           
   
   C  s   |d }|d }|d }|  r|  s|  sd S zddlm} W n ty3 } ztd|d }~ww td|  || jj	|}	|	
| |	| j_	t| drsz|   W n tyr } ztd	|  W Y d }~nd }~ww d
|_	d S )NrF   rG   rH   r   rI   zEpeft is required to load language model adapters but is not installedz!Loading language model LoRA from tie_weightsz5Failed to retie weights after loading language LoRA: T)r.   rK   rJ   rL   rM   r<   rN   rQ   rO   r	   r>   hasattrr[   	Exceptionr=   )
rO   r   r3   rC   config_filebin_filesafe_tensors_filerJ   rV   peft_lmr   r   r   _load_language_modelp   s6   


rb   checkpoint_dirstrOptional[torch.device]c                 C  s   t t|}| std| |pt|  j}t|d}t| ||| t	| ||| |d d }t
t| jdd||rAd|_|d d }t
t| jdd||rUd|_t|j satd |S )	a  Load LoRA adapters and connector weights onto an instantiated model.

    Args:
        model: The already instantiated `VibeVoiceForConditionalGenerationInference` model.
        checkpoint_dir: Directory produced during fine-tuning containing a `lora/` folder.
        device: Optional device to place loaded modules on. When ``None`` the function
            infers the device from the model parameters.

    Returns:
        `_LoadReport` summarizing which assets were successfully loaded.
    zAdapter directory not found: )r   r   zpytorch_model.binNTr   zdNo adapter assets were loaded. Ensure the checkpoint directory is correct and contains LoRA weights.)r/   r   r.   FileNotFoundErrornext
parametersr3   r   rb   rZ   rB   getattrrO   r   r   any__dict__valuesr<   r=   )rO   rc   r3   r   inferred_devicerC   ac_pathse_pathr   r   r   load_lora_assets   s$   
rp   )r)   r   r*   r   )r0   r1   r2   r   r3   r4   r*   r   )r   r   r3   r4   rC   r   r*   rD   r   )rc   rd   r3   re   r*   r   )r   
__future__r   dataclassesr   pathlibr   typingr   r9   torch.nnnntransformers.utilsr   
get_loggerr   r<   r   Moduler   r/   rB   rZ   rb   rp   r   r   r   r   <module>   s"    




)