o
    ia                     @   s  d Z ddlZddlZddlZddlZddlZddlZddlmZm	Z	m
Z
 ddlZzddlZdZW n ey;   dZY nw dZdZdZd	Zd
d Zdd Zdd Zd4ddZdd ZG dd deZG dd dZG dd deedZdd ZG dd deedZG d d! d!eZd"d# Z G d$d% d%eZ!G d&d' d'eZ"G d(d) d)eZ#G d*d+ d+eZ$d,d- Z%G d.d/ d/ej&Z'G d0d1 d1e'Z(G d2d3 d3e'Z)dS )5zSpecifications declare the expected variables layout of CTranslate2 models
that do not load a computation graph. The model converter should make sure that
each required variable of the specification is set.
    N)DictListOptionalTF
__optional   )int8int8_float32int8_float16int8_bfloat16int16float16bfloat16float32)rotary_scaling_long_factorrotary_scaling_short_factorc                 C   s   | s|S d| |f S )Nz%s/%s )scopenamer   r   Y/home/ubuntu/sommelier/.venv/lib/python3.10/site-packages/ctranslate2/specs/model_spec.py_join_scope)   s   r   c                 C   s
   |  dS )N/)splitr   r   r   r   _split_scope/      
r   c                 C   s,   t | }|d d |d } }d| |fS )Nr   )r   join)r   keysattrr   r   r   _parent_scope3   s   r    c              
   C   s   t | j D ]@\}}|drqt|t r.t|D ]\}}t||t|d||f d qqt|tr>t||t||d q|| t||| qdS )z Recursively visits a layer spec._%s_%dr   N)	list__dict__items
startswith
isinstance	enumerate
visit_specr   	LayerSpec)specfnr   r   valueielemr   r   r   r)   9   s   


r)   c              	   C   s`   |s| S t |}|D ]#}zt| |} W q
 ty-   |dd\}}t| |t| } Y q
w | S )Nr!      )r   getattrAttributeErrorrsplitint)r+   indexr   keyr   r   r   r   
index_specG   s   r7   c                          e Zd Z fddZ  ZS )
FrozenMetac                    s   t  j|i |}d|_|S )NT)super__call___frozen)selfargskwargsinstance	__class__r   r   r;   U   s   zFrozenMeta.__call__)__name__
__module____qualname__r;   __classcell__r   r   rA   r   r9   T       r9   c                       r8   )
FrozenAttrc                    s2   t | drt | |std| t || d S )Nr<   zAttribute %s does not exist)hasattrr2   r:   __setattr__r=   r6   r-   rA   r   r   rJ   \   s   zFrozenAttr.__setattr__)rC   rD   rE   rJ   rF   r   r   rA   r   rH   [   rG   rH   c                	   @   sp   e Zd ZdZdddZ		dded	edeeej	f fd
dZ
dd Zdd Zddee ddfddZdd ZdS )r*   zPA layer specification declares the weights that should be set by the converters.returnNc                    s4   g   fdd}|  |  rtdd  dS )zVerify that the required weights are set.

        Raises:
          ValueError: If a required weight is not set in the specification.
        c                    s   |d u r  | d S t|tjr|jtjkr|tj}n0t|tr,td	|}n"t|t
r:td	|}nt|trN|tkrNtj|dtjd}t|tjsZt|tjr_t|}ntrkt|tjrkt|}t|d }t| || d S )Nr   r   utf-8)dtyper   )appendr'   npndarrayrN   float64astyper   floattypeboolstrOPTIONAL
frombufferencoder   genericNumpyVariabletorch_is_availabletorchTensorPyTorchVariabler   setattr)r+   r   r-   	attr_nameunset_attributesr   r   _checkm   s(   




z"LayerSpec.validate.<locals>._checkz/Some required model attributes are not set:

%s
N)_visit
ValueErrorr   )r=   re   r   rc   r   validatee   s   
zLayerSpec.validater    Fprefixorderedc                    s<   i  fdd}|  | |rtt dd dS S )a!  Recursively returns the weights from this layer and its children.

        Arguments:
          prefix: Prefix to prepend to all variable names.
          ordered: If set, an ordered list is returned instead.

        Returns:
          Dictionary mapping variables name to value.
        c                    s(   t |tr|tkrd S |t |< d S N)r'   rW   rX   r   )r+   r   r-   rj   varr   r   _register_var   s   z*LayerSpec.variables.<locals>._register_varc                 S   s   | d S Nr   r   )xr   r   r   <lambda>   s    z%LayerSpec.variables.<locals>.<lambda>)r6   )rg   r#   sortedr%   )r=   rj   rk   ro   r   rm   r   	variables   s   
zLayerSpec.variablesc           	      C   s|   | j dd}t|D ]1\}}|D ]*\}}||kr n!t|\}}| s:||r:|tvr:t| |}t|||  nqq
dS )z4Find duplicate variables in spec and create aliases.Trk   N)rt   reversedr   	is_scalarequalSKIP_CREATING_ALIASr7   ra   )	r=   rt   r   r-   
other_nameother_valuer   rb   r+   r   r   r   _alias_variables   s    
zLayerSpec._alias_variablesc                    s@    dur t vrtd dt f  fdd}| | dS )z-Possibly quantizes the variable of the layer.Nz;%s is not a valid quantization type. Accepted types are: %s, c           	         s  t |tr	| rd S t|d }d }t| d| }|jdv }|rÈ dkrb|d }t	dt
t| }||9 }t|}t|ttjjttjj}|tj}t|}t|}n dv r|d }d }t|jdkr|j}||jd	 d}tj
t|d
d}d||d	k< d| }|t|d
9 }t|}|tj}|r||}t|}t|}n) dv r| }n|r dv r|d}n dv r|d}n	 dv r|d}t| || |d urt| d| | d S d S )Nr   z%s_scale)r   r   r   r   r   i   )r   r   r	   r
      r   r0   )axisg     _@)r   r   r   )r   r	   r   )r   r
   r   )r   r   r   )r'   Variablerw   r   rI   rN   tonumpyrP   r   amaxabsoluterintclipiinfor   minmaxrS   r\   lenshapereshapeexpand_dimsr   ra   )	r+   r   r-   r6   scaleis_quantizableis_convertible	old_shaper   quantizationr   r   	_quantize   s`   







z&LayerSpec._quantize.<locals>._quantize)ACCEPTED_MODEL_TYPESrh   r   rg   )r=   r   r   r   r   r   r      s   =zLayerSpec._quantizer   c                 C   s   |    | | dS )aR  Recursively applies some optimizations to this layer:

        * Alias variables with the same shape and value.
        * Quantize weights.

        Arguments:
          quantization: Weight quantization scheme (possible values are: int8, int8_float32,
            int8_float16, int8_bfloat16, int16, float16, bfloat16, float32).
        N)r|   r   )r=   r   r   r   r   optimize  s   
zLayerSpec.optimizec                 C   s   t | | dS )z/Recursively visits this layer and its children.N)r)   )r=   r,   r   r   r   rg     s   zLayerSpec._visitrL   N)r    Frl   )rC   rD   rE   __doc__ri   rW   rV   r   rP   rQ   rt   r|   r   r   r   rg   r   r   r   r   r*   b   s     
,
Gr*   )	metaclassc              	   C   s6   d}z| | W S  ty   td| d|f w )N)r   r   r   int32r   r   z)%s is not in list of supported dtypes: %sr}   )r5   rh   r   )object_dtypedtypesr   r   r   _dtype_to_type_id  s   r   c                   @   s0   e Zd ZdZdd Zdd Zdd Zdd	 Zd
S )ModelConfigz$Base class for model configurations.c                 K   s"   |  D ]
\}}t| || qdS )z7Initializes the configuration with a set of parameters.N)r%   ra   )r=   r?   r6   r-   r   r   r   __init__'  s   zModelConfig.__init__c                 C   s   dd | j  D S )z*Returns the configuration as a dictionary.c                 S   s    i | ]\}}| d s||qS )r!   )r&   ).0r6   r-   r   r   r   
<dictcomp>.  s    z'ModelConfig.to_dict.<locals>.<dictcomp>)r$   r%   r=   r   r   r   to_dict,  s   zModelConfig.to_dictc                 C   s   || j |< d S rl   )r$   rK   r   r   r   add_attribute4     zModelConfig.add_attributec                 C   sT   t |ddd}tj|  |ddd |d W d   dS 1 s#w   Y  dS )	z'Saves the configuration as a JSON file.wrM   encoding   T)indent	sort_keysrf   N)openjsondumpr   write)r=   pathconfig_filer   r   r   save_as_json7  s   "zModelConfig.save_as_jsonN)rC   rD   rE   r   r   r   r   r   r   r   r   r   r   $  s    r   c                   @   sz   e Zd ZdZdd Zedd Zedd Zedd	 Zd
d Z	dde
dee
 ddfddZde
ddfddZdd ZdS )	ModelSpecz"The top level layer specification.c                 C   s   |   | _i | _dS )z$Initializes the model specification.N)get_default_config_config_filesr   r   r   r   r   F     

zModelSpec.__init__c                 C      t  )z$The name of the model specification.NotImplementedErrorr   r   r   r   r   K     zModelSpec.namec                 C      dS )zThe model specification revision.

        This value is incremented each time the weights layout of the model is
        changed (e.g. a weight is renamed).
        r0   r   r   r   r   r   revisionP  s   zModelSpec.revisionc                 C      | j S )zThe model configuration.)r   r   r   r   r   configY  r   zModelSpec.configc                 C   r   )z5Returns the default configuration used by this model.Nr   r   r   r   r   r   ^  s   zModelSpec.get_default_configNr   filenamerL   c                 C   sP   t j|std| |du rt j|}|| jv r!td| || j|< dS )z4Registers a file to be saved in the model directory.zFile %s does not existNz*A file with name %s was already registered)osr   isfilerh   basenamer   )r=   r   r   r   r   r   register_fileb  s   
zModelSpec.register_file
output_dirc                 C   s~   |  tj|d | jdur| jtj|d | j D ]\}}tj||}tj|r6t	d| t
|| qdS )zwSaves this model on disk.

        Arguments:
          output_dir: Output directory where the model is saved.
        z	model.binNzconfig.jsonz-File %s already exists in the model directory)
_serializer   r   r   r   r   r   r%   existsRuntimeErrorshutilcopy)r=   r   r   r   destinationr   r   r   savel  s   
zModelSpec.savec              	      s|  g }g }| j ddD ]}t|d tr|| q
|| q
t|d  fdd} tdt || j	  td| j
  tdt| |D ]A\}}||  tdt|j |jD ]} td| qg tdt|j  td|   |  qP tdt| |D ]\}	}
||	 ||
 qW d	   d	S 1 sw   Y  d	S )
zSerializes the model variables.Tru   r0   wbc                    s@     tdt| d    | d   tdd d S )NHr0   rM   Br   )r   structpackr   rZ   )stringmodelr   r   _write_string  s   z+ModelSpec._serialize.<locals>._write_stringIr   N)rt   r'   rW   rO   r   r   r   r   CURRENT_BINARY_VERSIONr   r   r   r   r   rN   	num_bytesto_bytes)r=   r   rt   aliasesvariabler   r   r-   dimaliasvariable_namer   r   r   r   ~  s4   


"zModelSpec._serializerl   )rC   rD   rE   r   r   propertyr   r   r   r   rW   r   r   r   r   r   r   r   r   r   C  s    



r   c                 c   s\    |   D ]&\}}t|dkr||d fV  qt|D ]\}}d||d f |fV  qqd S )Nr0   r   r"   )r%   r   r(   )vocabulariesr   
vocabularyr.   vocabr   r   r   _flatten_vocabularies  s   r   c                       sL   e Zd ZdZ						ddededed	ee d
edef fddZ  ZS )SequenceToSequenceModelConfigz.Configuration for sequence-to-sequence models.<unk><s></s>F	unk_token	bos_token	eos_tokendecoder_start_tokenadd_source_bosadd_source_eosc              	      s$   t  jd||||||d| dS )a  Initializes the configuration for sequence-to-sequence models.

        Args:
          unk_token: The unknown token.
          bos_token: The start of sentence token.
          eos_token: The end of sentence token.
          decoder_start_token: The decoder start token. If ``None``, the token should
            be passed by the user in the target prefix.
          add_source_bos: If ``True``, ``bos_token`` will be automatically added to
            the source input.
          add_source_eos: If ``True``, ``eos_token`` will be automatically added to
            the source input.
          **kwargs: Additional configuration.
        )r   r   r   r   r   r   Nr   r:   r   )r=   r   r   r   r   r   r   r?   rA   r   r   r     s   
z&SequenceToSequenceModelConfig.__init__)r   r   r   r   FF)	rC   rD   rE   r   rW   r   rV   r   rF   r   r   rA   r   r     s*    r   c                       s   e Zd ZdZ fddZdd Zejdd Zejdd	 Z	d
e
e ddfddZd
e
e ddfddZdeddfddZd fddZdeddf fddZ  ZS )SequenceToSequenceModelSpecz3Base specification for sequence to sequence models.c                    s   t    g g d| _dS )z7Initializes a sequence to sequence model specification.sourcetargetN)r:   r   _vocabulariesr   rA   r   r   r     s   
z$SequenceToSequenceModelSpec.__init__c                 C      t  S rl   )r   r   r   r   r   r        z.SequenceToSequenceModelSpec.get_default_configc                 C   r   )z9Returns the source vocabulary size expected by the model.r   r   r   r   r   get_source_vocabulary_size  r   z6SequenceToSequenceModelSpec.get_source_vocabulary_sizec                 C   r   )z9Returns the target vocabulary size expected by the model.r   r   r   r   r   get_target_vocabulary_size  r   z6SequenceToSequenceModelSpec.get_target_vocabulary_sizetokensrL   Nc                 C      | j d | dS )znRegisters a source vocabulary of tokens.

        Arguments:
          tokens: List of source tokens.
        r   Nr   rO   r=   r   r   r   r   register_source_vocabulary     z6SequenceToSequenceModelSpec.register_source_vocabularyc                 C   r   )znRegisters a target vocabulary of tokens.

        Arguments:
          tokens: List of target tokens.
        r   Nr   r   r   r   r   register_target_vocabulary  r   z6SequenceToSequenceModelSpec.register_target_vocabularyr   c                 C   s   |  |d dS )zvRegisters a vocabulary mapping file.

        Arguments:
          path: Path to the vocabulary mapping file.
        zvmap.txtN)r   )r=   r   r   r   r   register_vocabulary_mapping  s   z7SequenceToSequenceModelSpec.register_vocabulary_mappingc                    s   t    |  |  d}| D ]H\}}t|ts|g}| j| }t|t|kr8t	d|t|t|f t
t||D ]\}\}}t||krYt	d| |t||f q?qd S )Nr   zCIncorrect number of %s vocabularies: %d registered, but expected %dzK%s vocabulary %d has size %d but the model expected a vocabulary of size %d)r:   ri   r   r   r%   r'   r#   r   r   rh   r(   zip
capitalize)r=   vocabulary_sizesr   sizesr   r.   r   expected_sizerA   r   r   ri      s0   


z$SequenceToSequenceModelSpec.validater   c                    sn   t t| j}t|  t fdd D rd d i}| D ]\}}t|d| | q"t 	| d S )Nc                 3   s    | ]	}| d  kV  qdS )r   Nr   )r   r   all_vocabulariesr   r   	<genexpr>  s    z3SequenceToSequenceModelSpec.save.<locals>.<genexpr>sharedr   z%s_vocabulary)
dictr   r   r#   valuesallr%   _save_vocabularyr:   r   )r=   r   r   r   r   rA   r  r   r     s   z SequenceToSequenceModelSpec.saver   )rC   rD   rE   r   r   r   abcabstractmethodr   r   r   rW   r   r   r   ri   r   rF   r   r   rA   r   r     s    

r   c                       s6   e Zd ZdZ			d
dededef fdd	Z  ZS )LanguageModelConfigz"Configuration for language models.r   r   r   r   r   r   c                    s   t  jd|||d| dS )a  Initializes the configuration for language models.

        Args:
          unk_token: The unknown token.
          bos_token: The start of sentence token.
          eos_token: The end of sentence token.
          **kwargs: Additional configuration.
        )r   r   r   Nr   r   )r=   r   r   r   r?   rA   r   r   r   +  s   
zLanguageModelConfig.__init__)r   r   r   )rC   rD   rE   r   rW   r   rF   r   r   rA   r   r  (  s    r  c                       sp   e Zd ZdZ fddZdd Zejdd Zde	e
 d	d
fddZd fddZde
d	d
f fddZ  ZS )LanguageModelSpecz'Base specification for language models.c                    s   t    g | _dS )z+Initializes a language model specification.N)r:   r   _vocabularyr   rA   r   r   r   E  r   zLanguageModelSpec.__init__c                 C   r   rl   )r  r   r   r   r   r   J  r   z$LanguageModelSpec.get_default_configc                 C   r   )z2Returns the vocabulary size expected by the model.r   r   r   r   r   get_vocabulary_sizeM  r   z%LanguageModelSpec.get_vocabulary_sizer   rL   Nc                 C   s   t || _dS )zbRegisters the vocabulary of tokens.

        Arguments:
          tokens: List of tokens.
        N)r#   r  r   r   r   r   register_vocabularyR  s   z%LanguageModelSpec.register_vocabularyc                    s:   t    |  }t| j|krtdt| j|f d S )NzEVocabulary has size %d but the model expected a vocabulary of size %d)r:   ri   r  r   r  rh   )r=   expected_vocabulary_sizerA   r   r   ri   Z  s   
zLanguageModelSpec.validater   c                    s   t |d| j t | d S )Nr   )r  r  r:   r   )r=   r   rA   r   r   r   d  s   zLanguageModelSpec.saver   )rC   rD   rE   r   r   r   r  r  r  r   rW   r  ri   r   rF   r   r   rA   r   r  B  s    

r  c                 C   sV   t j| d| }t|ddd}tj||dd W d    d S 1 s$w   Y  d S )Nz%s.jsonr   rM   r   r   )r   )r   r   r   r   r   r   )r   r   r   vocabulary_pathvocabulary_filer   r   r   r  l  s   "r  c                   @   s   e Zd ZdZeejdee fddZ	de
fddZeejdefddZd	edd fd
dZejdejfddZde
fddZejdefddZejdefddZejd	edd fddZejde
fddZdS )r   z(Abstract base class for model variables.rL   c                 C   r   rl   r   r   r   r   r   r   v  r   zVariable.shapec                 C   s   t | jdkS rp   )r   r   r   r   r   r   rw   {  r   zVariable.is_scalarc                 C   r   rl   r   r   r   r   r   rN   ~  r   zVariable.dtyperN   c                 C   s   || j kr| S | |S rl   )rN   _tor=   rN   r   r   r   r     s   

zVariable.toc                 C   r   rl   r   r   r   r   r   r        zVariable.numpyc                 C   s   t | t |u o| |S rl   )rU   _equalr=   otherr   r   r   rx     s   zVariable.equalc                 C   r   rl   r   r   r   r   r   r     r  zVariable.num_bytesc                 C   r   rl   r   r   r   r   r   r     r  zVariable.to_bytesc                 C   r   rl   r   r  r   r   r   r    r  zVariable._toc                 C   r   rl   r   r  r   r   r   r    r  zVariable._equalN)rC   rD   rE   r   r   r  r  r   r4   r   rV   rw   rW   rN   r   rP   rQ   r   rx   r   bytesr   r  r  r   r   r   r   r   s  s*    r   c                   @   s   e Zd ZdZdd Zedee fddZede	fddZ
dejfd	d
ZdefddZdefddZde	defddZdefddZdS )r\   z Model variable as a Numpy array.c                 C   s
   || _ d S rl   array)r=   r  r   r   r   r     r   zNumpyVariable.__init__rL   c                 C      | j jS rl   )r  r   r   r   r   r   r     s   zNumpyVariable.shapec                 C   s
   | j jjS rl   )r  rN   r   r   r   r   r   rN     s   
zNumpyVariable.dtypec                 C   r   rl   r  r   r   r   r   r     r   zNumpyVariable.numpyc                 C   r   rl   )r  nbytesr   r   r   r   r     s   zNumpyVariable.num_bytesc                 C   s
   | j  S rl   )r  tobytesr   r   r   r   r     r   zNumpyVariable.to_bytesrN   c                 C   sB   |dkrt s
tdt| j|S t|}| j|| _| S )Nr   z5Converting to bfloat16 requires torch to be installed)	r]   r   r`   
from_numpyr  r   rP   rN   rS   r  r   r   r   r    s   
zNumpyVariable._toc                 C   sL   | j }|j }||u p%|j|jko%|j|jko%|jd |jd ko%t||S rp   )r  rN   r   flatrP   array_equalr=   r  abr   r   r   r    s   

zNumpyVariable._equalN)rC   rD   rE   r   r   r   r   r4   r   rW   rN   rP   rQ   r   r   r  r   r   r  rV   r  r   r   r   r   r\     s    r\   c                   @   s   e Zd ZdZdd Zedd Zedee	 fddZ
edefd	d
ZdejfddZde	fddZdefddZdedefddZdefddZdS )r`   z#Model variable as a PyTorch tensor.c                 C   s"   t |tjjr
|j}| | _d S rl   )r'   r^   nn	Parameterdata
contiguoustensor)r=   r-  r   r   r   r     s   zPyTorchVariable.__init__c                 C   s   t |}| |S rl   )r^   r#  )clsr  r-  r   r   r   r#    s   
zPyTorchVariable.from_numpyrL   c                 C   s   t | jjS rl   )r#   r-  r   r   r   r   r   r     s   zPyTorchVariable.shapec                 C   s   t | jjddS )Nztorch.r    )rW   r-  rN   replacer   r   r   r   rN     s   zPyTorchVariable.dtypec                 C   s   | j   S rl   )r-  detachr   r   r   r   r   r     r   zPyTorchVariable.numpyc                 C   s   | j  | j   S rl   )r-  numelelement_sizer   r   r   r   r     s   zPyTorchVariable.num_bytesc                 C   sf   d}|   }d}d}|dkr1||kr|n|}t| j | |}||7 }||7 }||8 }|dks|S )Ni    r   )r   ctypes	string_atr-  data_ptr)r=   max_sizer   outputoffset
chunk_sizechunkr   r   r   r     s   zPyTorchVariable.to_bytesrN   c                 C   s   t t|}| j|| _| S rl   )r1   r^   r-  r   r  r   r   r   r    s   
zPyTorchVariable._toc                 C   s,   | j }|j }||u p|j|jkot||S rl   )r-  rN   r^   rx   r&  r   r   r   r    s    zPyTorchVariable._equalN)rC   rD   rE   r   r   classmethodr#  r   r   r4   r   rW   rN   rP   rQ   r   r   r  r   r   r  rV   r  r   r   r   r   r`     s    
r`   )r    )*r   r  r4  r   r   r   r   typingr   r   r   r   rP   r^   r]   ImportErrorrX   r   r   ry   r   r   r   r)   r7   rU   r9   rH   r*   r   r   r   r   r   r   r  r  r  ABCr   r\   r`   r   r   r   r   <module>   sP    
 7^	&X*-.