U
    h                     @   sV   d dl Zd dlZ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 )    N)AnyDictListOptional)
Embeddings)	BaseModelc                       s  e Zd ZdZdddddddddee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 )!QuantizedBgeEmbeddingsai  Leverage Itrex runtime to unlock the performance of compressed NLP models.

    Please ensure that you have installed intel-extension-for-transformers.

    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 {})
        onnx_file_name: Optional[str] =
            File name of onnx optimized model which is exported by itrex.
            (default "int8-model.onnx")

    Example:
        .. code-block:: python

            from langchain_community.embeddings import QuantizedBgeEmbeddings

            model_name = "Intel/bge-small-en-v1.5-sts-int8-static-inc"
            encode_kwargs = {'normalize_embeddings': True}
            hf = QuantizedBgeEmbeddings(
                model_name,
                encode_kwargs=encode_kwargs,
                query_instruction="Represent this sentence for searching relevant passages: "
            )
    i   meanNTzint8-model.onnx)max_seq_lenpooling_strategyquery_instructiondocument_instructionpaddingmodel_kwargsencode_kwargsonnx_file_name)
model_namer
   r   r   r   r   r   r   r   kwargsreturnc                   s   t  jf |
 tjdd kr&tdtjdd kr>tdtjdd krVtd|| _|| _|| _|| _	|pti | _
|p~i | _| j
dd| _| j
d	d
| _|| _|| _|	| _|   d S )NZ intel_extension_for_transformerszCould not import intel_extension_for_transformers python package. Please install it with `pip install -U intel-extension-for-transformers`.torchzUCould not import torch python package. Please install it with `pip install -U torch`.ZonnxzSCould not import onnx python package. Please install it with `pip install -U onnx`.Znormalize_embeddingsF
batch_size    )super__init__	importlibutil	find_specImportErrormodel_name_or_pathr
   poolingr   r   r   get	normalizer   r   r   r   
load_model)selfr   r
   r   r   r   r   r   r   r   r   	__class__ H/tmp/pip-unpacked-wheel-9gdii04g/langchain_community/embeddings/itrex.pyr   /   s2    

zQuantizedBgeEmbeddings.__init__)r   c                 C   s   ddl m} ddlm} ddlm}m} || jj	| _	|| j| _
tj| j| j}tj|st|| j| jd}|j|dd| _d S )Nr   )hf_hub_download)	AutoModel)
AutoConfigAutoTokenizer)filenameT)Zuse_embedding_runtime)Zhuggingface_hubr(   Z-intel_extension_for_transformers.transformersr)   Ztransformersr*   r+   Zfrom_pretrainedr   hidden_sizetransformer_tokenizerospathjoinr   existstransformer_model)r#   r(   r)   r*   r+   Zonnx_model_pathr&   r&   r'   r"   e   s&      z!QuantizedBgeEmbeddings.load_modelc                   @   s   e Zd ZdZdS )zQuantizedBgeEmbeddings.ConfigZallowN)__name__
__module____qualname__extrar&   r&   r&   r'   Configy   s   r8   )inputsr   c                 C   s   dd l }dd | D }| j|}d|kr8|d }ndd | D d }|||d jd |d jd | j}| jdkr| 	||d	 }n| jd
kr| 
|}ntd| jr|jjj|ddd}|S )Nr   c                 S   s   g | ]}|qS r&   r&   ).0valuer&   r&   r'   
<listcomp>   s     z1QuantizedBgeEmbeddings._embed.<locals>.<listcomp>zlast_hidden_state:0c                 S   s   g | ]}|qS r&   r&   )r:   outr&   r&   r'   r<      s     Z	input_ids   r	   attention_maskclszpooling method no supported   )pZdim)r   valuesr3   generateZtensorZreshapeshaper-   r   _mean_pooling_cls_pooling
ValueErrorr!   nnZ
functional)r#   r9   r   Zengine_inputoutputslast_hidden_stateZembr&   r&   r'   _embed|   s&    

  

zQuantizedBgeEmbeddings._embed)rK   r   c                 C   s   | d d df S Nr   r&   )rK   r&   r&   r'   rG      s    z#QuantizedBgeEmbeddings._cls_pooling)rK   r?   r   c              
   C   s~   zdd l }W n, tk
r8 } ztd|W 5 d }~X Y nX |d|   }|| | d}|j|ddd}|| S )Nr   zCUnable to import torch, please install with `pip install -U torch`.r>   g&.>)min)r   r   Z	unsqueezeexpandsizefloatsumclamp)rK   r?   r   eZinput_mask_expandedZsum_embeddingsZsum_maskr&   r&   r'   rF      s    z$QuantizedBgeEmbeddings._mean_pooling)textsr   c                 C   s&   | j || jd| jdd}| | S )NTpt)
max_lengthZ
truncationr   Zreturn_tensors)r.   r
   r   rL   tolist)r#   rV   r9   r&   r&   r'   _embed_text   s    z"QuantizedBgeEmbeddings._embed_textc           	   
      s   zddl }W n, tk
r8 } 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 ]}| |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`.c                    s    g | ]} j r j | n|qS r&   )r   )r:   dr#   r&   r'   r<      s   z:QuantizedBgeEmbeddings.embed_documents.<locals>.<listcomp>rV   )columnsindexZbatch_index)	Zpandasr   Z	DataFrameZreset_indexr   listgroupbyapplyrZ   )	r#   rV   pdrU   ZdocsZtext_list_dfZbatchesZvectorsbatchr&   r\   r'   embed_documents   s$    
z&QuantizedBgeEmbeddings.embed_documents)textr   c                 C   s    | j r| j | }| |gd S rM   )r   rZ   )r#   re   r&   r&   r'   embed_query   s    
z"QuantizedBgeEmbeddings.embed_query)r4   r5   r6   __doc__strintr   boolr   r   r   r"   r8   rL   staticmethodrG   rF   r   rR   rZ   rd   rf   __classcell__r&   r&   r$   r'   r   	   s@   )6
!r   )importlib.utilr   r/   typingr   r   r   r   Zlangchain_core.embeddingsr   Zlangchain_core.pydantic_v1r   r   r&   r&   r&   r'   <module>   s
   