U
    h                     @   sF   d dl mZmZmZmZ d dlmZ d dlmZ G dd deeZ	dS )    )AnyDictListOptional)
Embeddings)	BaseModelc                       s   e Zd ZdZdeeeee ee eee ee e	dd
 fddZ
dd	d
dZG dd dZe	e	dddZee	e	dddZee	e	e	dddZee eee  dddZee eee  dddZeee dddZ  ZS ) QuantizedBiEncoderEmbeddingsaK  Quantized bi-encoders embedding models.

    Please ensure that you have installed optimum-intel and ipex.

    Input:
        model_name: str = Model name.
        max_seq_len: int = The maximum sequence length for tokenization. (default 512)
        pooling_strategy: str =
            "mean" or "cls", pooling strategy for the final layer. (default "mean")
        query_instruction: Optional[str] =
            An instruction to add to the query before embedding. (default None)
        document_instruction: Optional[str] =
            An instruction to add to each document before embedding. (default None)
        padding: Optional[bool] =
            Whether to add padding during tokenization or not. (default True)
        model_kwargs: Optional[Dict] =
            Parameters to add to the model during initialization. (default {})
        encode_kwargs: Optional[Dict] =
            Parameters to add during the embedding forward pass. (default {})

    Example:

    from langchain_community.embeddings import QuantizedBiEncoderEmbeddings

    model_name = "Intel/bge-small-en-v1.5-rag-int8-static"
    encode_kwargs = {'normalize_embeddings': True}
    hf = QuantizedBiEncoderEmbeddings(
        model_name,
        encode_kwargs=encode_kwargs,
        query_instruction="Represent this sentence for searching relevant passages: "
    )
       meanNT)

model_namemax_seq_lenpooling_strategyquery_instructiondocument_instructionpaddingmodel_kwargsencode_kwargskwargsreturnc	           
         sr   t  jf |	 || _|| _|| _|| _|p,i | _|p6i | _| jdd| _	| jdd| _
|| _|| _|   d S )NZnormalize_embeddingsF
batch_size    )super__init__model_name_or_pathr   poolingr   r   r   get	normalizer   r   r   
load_model)
selfr   r   r   r   r   r   r   r   r   	__class__ P/tmp/pip-unpacked-wheel-9gdii04g/langchain_community/embeddings/optimum_intel.pyr   )   s    

z%QuantizedBiEncoderEmbeddings.__init__)r   c              
   C   s   zddl m} W n, tk
r< } ztd|W 5 d }~X Y nX z$ddlm} |j| jf| j| _W n: t	k
r } zt	d| j d| dW 5 d }~X Y nX |j| jd| _
| j  d S )	Nr   )AutoTokenizerzQUnable to import transformers, please install with `pip install -U transformers`.)	IPEXModelz
Failed to load model z, due to the following error:
a  
Please ensure that you have installed optimum-intel and ipex correctly,using:

pip install optimum[neural-compressor]
pip install intel_extension_for_pytorch

For more information, please visit:
* Install optimum-intel as shown here: https://github.com/huggingface/optimum-intel.
* Install IPEX as shown here: https://intel.github.io/intel-extension-for-pytorch/index.html#installation?platform=cpu&version=v2.2.0%2Bcpu.
)Zpretrained_model_name_or_path)Ztransformersr#   ImportErrorZoptimum.intelr$   Zfrom_pretrainedr   r   transformer_model	Exceptiontransformer_tokenizereval)r   r#   er$   r!   r!   r"   r   E   s6    
z'QuantizedBiEncoderEmbeddings.load_modelc                   @   s   e Zd ZdZdS )z#QuantizedBiEncoderEmbeddings.ConfigZallowN)__name__
__module____qualname__extrar!   r!   r!   r"   Configg   s   r/   )inputsr   c              
   C   s   zdd l }W n, tk
r8 } ztd|W 5 d }~X Y nX | r | jf |}| jdkrl| ||d }n| jdkr| |}ntd| jr|j	j
j|ddd	}|W  5 Q R  S Q R X d S )
Nr   CUnable to import torch, please install with `pip install -U torch`.r
   attention_maskclszpooling method no supported      )pZdim)torchr%   Zinference_moder&   r   _mean_pooling_cls_pooling
ValueErrorr   nnZ
functional)r   r0   r7   r*   outputsZembr!   r!   r"   _embedj   s$    


z#QuantizedBiEncoderEmbeddings._embed)r<   r   c                 C   s,   t | tr| d }n| d }|d d df S )Nlast_hidden_stater   )
isinstancedict)r<   token_embeddingsr!   r!   r"   r9   ~   s    

z)QuantizedBiEncoderEmbeddings._cls_pooling)r<   r2   r   c              
   C   s   zdd l }W n, tk
r8 } ztd|W 5 d }~X Y nX t| trN| d }n| d }|d|  }||| d}|j	|ddd}|| S )Nr   r1   r>   r5   g&.>)min)
r7   r%   r?   r@   Z	unsqueezeexpandsizefloatsumclamp)r<   r2   r7   r*   rA   Zinput_mask_expandedZsum_embeddingsZsum_maskr!   r!   r"   r8      s     

z*QuantizedBiEncoderEmbeddings._mean_pooling)textsr   c                 C   s&   | j || jd| jdd}| | S )NTpt)
max_lengthZ
truncationr   Zreturn_tensors)r(   r   r   r=   tolist)r   rI   r0   r!   r!   r"   _embed_text   s    z(QuantizedBiEncoderEmbeddings._embed_textc           
   
      s   zddl }W n, tk
r8 } ztd|W 5 d}~X Y nX zddlm} W n, tk
rv } ztd|W 5 d}~X Y nX  fdd|D }|j|dgd	 }|d
  j |d< t|dgd t}g }||ddD ]}	| 	|	7 }q|S )zEmbed a list of text documents using the Optimized Embedder model.

        Input:
            texts: List[str] = List of text documents to embed.
        Output:
            List[List[float]] = The embeddings of each text document.
        r   NzEUnable to import pandas, please install with `pip install -U pandas`.)tqdmzAUnable to import tqdm, please install with `pip install -U tqdm`.c                    s    g | ]} j r j | n|qS r!   )r   ).0dr   r!   r"   
<listcomp>   s   z@QuantizedBiEncoderEmbeddings.embed_documents.<locals>.<listcomp>rI   )columnsindexZbatch_indexZBatches)desc)
Zpandasr%   rN   Z	DataFrameZreset_indexr   listgroupbyapplyrM   )
r   rI   pdr*   rN   ZdocsZtext_list_dfZbatchesZvectorsbatchr!   rQ   r"   embed_documents   s4    
z,QuantizedBiEncoderEmbeddings.embed_documents)textr   c                 C   s    | j r| j | }| |gd S )Nr   )r   rM   )r   r\   r!   r!   r"   embed_query   s    
z(QuantizedBiEncoderEmbeddings.embed_query)r	   r
   NNTNN)r+   r,   r-   __doc__strintr   boolr   r   r   r   r/   r=   staticmethodr9   r8   r   rF   rM   r[   r]   __classcell__r!   r!   r   r"   r      s<   $       "
'r   N)
typingr   r   r   r   Zlangchain_core.embeddingsr   Zlangchain_core.pydantic_v1r   r   r!   r!   r!   r"   <module>   s   