
    2VhB                         d dl Z d dlmZ d dlmZ d dlmZ d dlmZ d dlmZ d dlmZ d dlmZ d d	l	m
Z
 d d
lmZ d dlmZ  e
d       G d de             Zy)    N)backend)constraints)dtype_policies)initializers)ops)
quantizers)regularizers)keras_export)KerasTensor)Layerzkeras.layers.Embeddingc                        e Zd ZdZ	 	 	 	 	 	 	 d fd	ZddZed        Zd ZddZ	d Z
d Z	 	 	 dd	Zd
 Zd Z fdZd Z	 d Zd Zd Z fdZddZddZd Z xZS )	Embeddingau  Turns nonnegative integers (indexes) into dense vectors of fixed size.

    e.g. `[[4], [20]] -> [[0.25, 0.1], [0.6, -0.2]]`

    This layer can only be used on nonnegative integer inputs of a fixed range.

    Example:

    >>> model = keras.Sequential()
    >>> model.add(keras.layers.Embedding(1000, 64))
    >>> # The model will take as input an integer matrix of size (batch,
    >>> # input_length), and the largest integer (i.e. word index) in the input
    >>> # should be no larger than 999 (vocabulary size).
    >>> # Now model.output_shape is (None, 10, 64), where `None` is the batch
    >>> # dimension.
    >>> input_array = np.random.randint(1000, size=(32, 10))
    >>> model.compile('rmsprop', 'mse')
    >>> output_array = model.predict(input_array)
    >>> print(output_array.shape)
    (32, 10, 64)

    Args:
        input_dim: Integer. Size of the vocabulary,
            i.e. maximum integer index + 1.
        output_dim: Integer. Dimension of the dense embedding.
        embeddings_initializer: Initializer for the `embeddings`
            matrix (see `keras.initializers`).
        embeddings_regularizer: Regularizer function applied to
            the `embeddings` matrix (see `keras.regularizers`).
        embeddings_constraint: Constraint function applied to
            the `embeddings` matrix (see `keras.constraints`).
        mask_zero: Boolean, whether or not the input value 0 is a special
            "padding" value that should be masked out.
            This is useful when using recurrent layers which
            may take variable length input. If this is `True`,
            then all subsequent layers in the model need
            to support masking or an exception will be raised.
            If `mask_zero` is set to `True`, as a consequence,
            index 0 cannot be used in the vocabulary (`input_dim` should
            equal size of vocabulary + 1).
        weights: Optional floating-point matrix of size
            `(input_dim, output_dim)`. The initial embeddings values
            to use.
        lora_rank: Optional integer. If set, the layer's forward pass
            will implement LoRA (Low-Rank Adaptation)
            with the provided rank. LoRA sets the layer's embeddings
            matrix to non-trainable and replaces it with a delta over the
            original matrix, obtained via multiplying two lower-rank
            trainable matrices. This can be useful to reduce the
            computation cost of fine-tuning large embedding layers.
            You can also enable LoRA on an existing
            `Embedding` layer by calling `layer.enable_lora(rank)`.
        lora_alpha: Optional integer. If set, this parameter scales the
            low-rank adaptation delta (computed as the product of two lower-rank
            trainable matrices) during the forward pass. The delta is scaled by
            `lora_alpha / lora_rank`, allowing you to fine-tune the strength of
            the LoRA adjustment independently of `lora_rank`.

    Input shape:
        2D tensor with shape: `(batch_size, input_length)`.

    Output shape:
        3D tensor with shape: `(batch_size, input_length, output_dim)`.
    c
                    |
j                  dd       }|t        j                  d       t        |   di |
 || _        || _        t        j                  |      | _	        t        j                  |      | _        t        j                  |      | _        || _        || _        d| _        || _        |	|	n|| _        d| _        |C| j)                          t+        |t,              rt/        |      dk(  s|g}| j1                  |       y y )Ninput_lengthz6Argument `input_length` is deprecated. Just remove it.F    )popwarningswarnsuper__init__	input_dim
output_dimr   getembeddings_initializerr	   embeddings_regularizerr   embeddings_constraint	mask_zerosupports_maskingautocast	lora_rank
lora_alphalora_enabledbuild
isinstancelistlenset_weights)selfr   r   r   r   r   r   weightsr!   r"   kwargsr   	__class__s               O/home/dcms/DCMS/lib/python3.12/site-packages/keras/src/layers/core/embedding.pyr   zEmbedding.__init__R   s     zz.$7#MMH 	"6""$&2&6&67M&N#&2&6&67M&N#%0__5J%K"" )"(2(>*I!JJLw-#g,!2C")W%	     c                    | j                   ry | j                  | j                  f}| j                  | j	                  || j                         | j                  dk7  r:| j                  || j                  d| j                  | j                  d      | _	        d| _         | j                  r| j                  | j                         y y )N)modeint8
embeddingsT)shapeinitializernameregularizer
constraint	trainable)builtr   r   quantization_modequantized_build
add_weightr   r   r   _embeddingsr!   enable_lora)r)   input_shapeembeddings_shapes      r-   r$   zEmbedding.buildw   s    :: NNDOO<!!-  !18N8N O!!V+#& 77! 7755  /  D 
>>T^^, r.   c                     | j                   rQ| j                  | j                  | j                  z  t	        j
                  | j                  | j                        z  z   S | j                  S N)r#   r=   r"   r!   r   matmullora_embeddings_alora_embeddings_b)r)   s    r-   r2   zEmbedding.embeddings   s^    ##$..0

41143I3IJ'K K K r.   c                     |j                   dk7  r%|j                   dk7  rt        j                  |d      }t        j                  | j                  |d      }t        j                  || j
                        S )Nint32int64r   axisdtype)rL   r   casttaker2   compute_dtype)r)   inputsoutputss      r-   callzEmbedding.call   sV    <<7"v||w'>XXfg.F((4??F;xxt'9'9::r.   c                 H    | j                   sy t        j                  |d      S )Nr   )r   r   	not_equal)r)   rP   masks      r-   compute_maskzEmbedding.compute_mask   s    ~~}}VQ''r.   c                 $    g || j                   S rB   )r   )r)   r?   s     r-   compute_output_shapezEmbedding.compute_output_shape   s    ..doo..r.   c                     | j                  |j                        }t        |dd      }t        || j                  |      S )NraggedF)rL   rZ   )rX   r3   getattrr   rO   )r)   rP   output_shaperZ   s       r-   compute_output_speczEmbedding.compute_output_spec   s>    00>51 2 26
 	
r.   c                    | j                   rt        d      | j                  st        d      | j                  rt        d      | j                  j                          | j                  d| j                  j                  d   |ft        j                  |      | j                        | _        | j                  d|| j                  j                  d   ft        j                  |      | j                        | _        d	| j                  _        | j                  j                          d
| _        || _        ||| _        y || _        y )NzLora is incompatible with embedding constraints. In order to enable lora on this layer, remove the `embeddings_constraint` argument.z3Cannot enable lora on a layer that isn't yet built.z>lora is already enabled. This can only be done once per layer.rD   r   )r5   r3   r4   r6   rE   r   FT)r   
ValueErrorr9   r#   _trackerunlockr<   r2   r3   r   r   r   rD   rE   r8   lockr!   r"   )r)   rankr"   a_initializerb_initializers        r-   r>   zEmbedding.enable_lora   s4    %%4 
 zzE  P  	!%$??((+T2$((733	 "1 "
 "&$..q12$((733	 "1 "
 %*! (2(>*Dr.   c                    | j                   sy | j                         \  }}|g}| j                  <| j                  dk(  r|j                  |       n| j	                  | j                        t        |      D ]  \  }}||t        |      <    y Nr1   )r9    _get_embeddings_with_merged_lorar:   append_quantization_mode_error	enumeratestr)r)   storeembeddings_valueembeddings_scaletarget_variablesivariables          r-   save_own_variableszEmbedding.save_own_variables   s    zz 113 	+* --!!-%%/ ''(8933D4J4JKK$%56 	%KAx$E#a&M	%r.   c                    | j                   s| j                  |       | j                  sy | j                  g}| j                  F| j                  dk(  r|j                  | j                         n| j                  | j                        t        |      D ]"  \  }}|j                  |t        |                $ | j                   r| j                  j                  t        j                  | j                  j                               | j                  j                  t        j                  | j                  j                               y y rg   )r#   _check_load_own_variablesr9   r=   r:   ri   ro   rj   rk   assignrl   rD   r   zerosr3   rE   )r)   rm   rp   rq   rr   s        r-   load_own_variableszEmbedding.load_own_variables   s     **51zz !,,-!!-%%/ ''(=(=>33D4J4JKK$%56 	+KAxOOE#a&M*	+""))		$00667 ""))		$00667	 r.   c                    t         |          }| j                  | j                  t	        j
                  | j                        t        j
                  | j                        t        j
                  | j                        t        j
                  | j                        | j                  d}| j                  r| j                  |d<   | j                  |d<   i ||S )N)r   r   r   r   activity_regularizerr   r   r!   r"   )r   
get_configr   r   r   	serializer   r	   r   rz   r   r   r   r!   r"   )r)   base_configconfigr,   s      r-   r{   zEmbedding.get_config   s    g(*//&2&<&<++' '3&<&<++' %1$:$:))% &1%:%:**& 
" >>"&..F;#'??F< (+(((r.   c                 
   | j                   | j                  z   }t        |j                               t        |      k7  rt        |      dk(  rY| j                  sMt        d| j                   dt        |j                                d| j                   d| j                   d	      t        d| j                   dt        |       dt        |j                                d	|D cg c]  }|j                   c}       y c c}w )
Nr   zLayer 'zY' was never built and thus it doesn't have any variables. However the weights file lists z variables for this layer.
In most cases, this error indicates that either:

1. The layer is owned by a parent layer that implements a `build()` method, but calling the parent's `build()` method did NOT create the state of the child layer 'z'. A `build()` method must create ALL state for the layer, including the state of any children layers.

2. You need to implement the `def build_from_config(self, config)` method on layer 'a-  ', to specify how to rebuild it during loading. In this case, you might also want to implement the method that generates the build config at saving time, `def get_build_config(self)`. The method `build_from_config()` is meant to create the state of the layer (i.e. its variables) upon deserialization.z' expected z variables, but received z% variables during loading. Expected: )_trainable_variables_non_trainable_variablesr'   keysr9   r_   r5   )r)   rm   all_varsvs       r-   ru   z#Embedding._check_load_own_variables  s    ,,t/L/LLuzz|H-8}!$** dii[ )669%**,6G5H I( )-		{ 3!
 "& ,NN . $))KH ? uzz|$% &.67aff78: 3 .: 8s   #D c                     t        d|       S )NzHInvalid quantization mode. Expected 'int8'. Received: quantization_mode=)NotImplementedError)r)   r0   s     r-   rj   z"Embedding._quantization_mode_error6  s    "++/&2
 	
r.   c                 `    |dk(  r| j                  |       d| _        y | j                  |      )Nr1   T)_int8_buildrj   _is_quantized)r)   r@   r0   s      r-   r;   zEmbedding.quantized_build<  s5    6>-. " //55r.   c                     | j                  d|ddd      | _        | j                  d| j                  fdd      | _        y )	Nr2   rw   r1   F)r5   r3   r4   rL   r8   ro   ones)r5   r3   r4   r8   )r<   r=   r   ro   )r)   r@   s     r-   r   zEmbedding._int8_buildC  sR    ??" + 
 !%#>>#	 !0 !
r.   c                 v    | j                   dk7  r| j                  | j                         t        |   |i |S rg   )r:   rj   r   quantized_call)r)   argsr+   r,   s      r-   r   zEmbedding.quantized_callU  s=    !!V+//0F0FGGw%t6v66r.   c                    t        j                  |j                        dvrt        j                  |d      }t        j
                  | j                  |d      }t        j
                  | j                  |d      }t        j                  t        j                  || j                        t        j                  |d            }| j                  rrt        j
                  | j                  |d      }t        j                  || j                        }t        j                  || j                   | j"                  z  |z        }|S )N)rG   rH   rG   r   rI   rK   )r   standardize_dtyperL   r   rM   rN   ro   r=   dividerO   expand_dimsr#   rD   rC   rE   addr"   r!   )r)   rP   trainingro   rQ   lora_outputss         r-   
_int8_callzEmbedding._int8_callZ  s     $$V\\2:LLXXfg.F88D$9$96J((4++V!<**HHWD$6$67OO,26
 88D$:$:FKL::lD4J4JKLgg$//DNN:lJG r.   c                 H   |r,t        |       t        ur| j                  | j                        | j                  | j
                  f}|dk(  r>t        j                  | j                  dd      \  }}t        j                  |d      }| `| j                  ||       |dk(  r6| j                  j                         | j                  j                         | j                  j                  6t!        j"                  | d| j                  j$                         }|| _        y y )Nr1   r   TrJ   to_numpyrI   _from_)typer   _not_implemented_errorquantizer   r   r   abs_max_quantizer=   r   squeezer;   rv   ro   dtype_policyr:   r   r   r5   )r)   r0   
type_checkr@   rn   ro   policys          r-   r   zEmbedding.quantizen  s
   4:Y6--dmm<< NNDOO<6> 2<1L1L  rD2..  #{{+;"E -t46>##$45!!(()9: ..6#''4&t7H7H7M7M6N(OPF &D 7r.   c                    | j                   j                  | j                  }| j                  }| j                  rt        j                  |t        j                  |d            }t        j                  |t        j                  | j                  | j                              }t        j                  |dd      \  }}t        j                  |d      }||fS | j                  d fS )Nr   rI   Tr   )r   r:   r=   ro   r#   r   r   r   r   rC   rD   rE   r   r   r   r2   )r)   rn   ro   s      r-   rh   z*Embedding._get_embeddings_with_merged_lora  s    ..:#//#44   $'::$coo6FR&P$  $'77$JJt55t7M7MN$ 
 //(rD 3 "2
 $';;/?b#I #%555$$r.   )uniformNNFNNNrB   )N
he_uniformrw   )T)__name__
__module____qualname____doc__r   r$   propertyr2   rR   rV   rX   r]   r>   rs   rx   r{   ru   rj   r;   r   r   r   r   rh   __classcell__)r,   s   @r-   r   r      s    ?J  )#"#&J-&    ;(
/
 "&IP%$0)0 D .
"
$7
('0%r.   r   )r   	keras.srcr   r   r   r   r   r   r	   keras.src.api_exportr
   keras.src.backendr   keras.src.layers.layerr   r   r   r.   r-   <module>r      sJ      ! $ "    " - ) ( &'K% K% (K%r.   