
    Ngb                    p    d dl mZ d dlZd dlZd dlmZ d dlmZmZ d dl	m
Z
  G d dej                  ZdS )    )annotationsN)OrderedDict)Tensornn)import_from_stringc                  V     e Zd Zdd fdZdd	ZddZd ZddZed             Z	 xZ
S )AsymTsub_modulesdict[str, list[nn.Module]]allow_empty_keyboolc                @   || _         || _        t                      }|                                D ]J\  }}t	          |t
                    s|g}t          |          D ]\  }}|||dz   t          |          z   <   Kt                      	                    |           dS )a  
        This model allows to create asymmetric SentenceTransformer models, that apply different models depending on the specified input key.

        In the below example, we create two different Dense models for 'query' and 'doc'. Text that is passed as {'query': 'My query'} will
        be passed along along the first Dense model, and text that will be passed as {'doc': 'My document'} will use the other Dense model.

        Note, that when you call encode(), that only inputs of the same type can be encoded. Mixed-Types cannot be encoded.

        Example::
            word_embedding_model = models.Transformer(model_name)
            pooling_model = models.Pooling(word_embedding_model.get_word_embedding_dimension())
            asym_model = models.Asym({'query': [models.Dense(word_embedding_model.get_word_embedding_dimension(), 128)], 'doc': [models.Dense(word_embedding_model.get_word_embedding_dimension(), 128)]})
            model = SentenceTransformer(modules=[word_embedding_model, pooling_model, asym_model])

            model.encode([{'query': 'Q1'}, {'query': 'Q2'}]
            model.encode([{'doc': 'Doc1'}, {'doc': 'Doc2'}]

            #You can train it with InputExample like this. Note, that the order must always be the same:
            train_example = InputExample(texts=[{'query': 'Train query'}, {'doc': 'Document'}], label=1)

        Args:
            sub_modules: Dict in the format str -> List[models]. The
                models in the specified list will be applied for input
                marked with the respective key.
            allow_empty_key: If true, inputs without a key can be
                processed. If false, an exception will be thrown if no
                key is specified.
        -N)
r
   r   r   items
isinstancelist	enumeratestrsuper__init__)	selfr
   r   ordered_dictnamemodelsidxmodel	__class__s	           ]/var/www/html/ai-engine/env/lib/python3.11/site-packages/sentence_transformers/models/Asym.pyr   zAsym.__init__   s    : '."}}'--// 	< 	<LD&fd++ " '// < <
U6;TCZ#c((233<&&&&&    featuresdict[str, Tensor]c                    d|v rCt          |d                   dk    r*|d         d         }| j        |         D ]} ||          }n| j        st          d          |S )N	text_keysr   z;Input did not specify any keys and allow_empty_key is False)lenr
   r   
ValueError)r   r    text_keyr   s       r   forwardzAsym.forward6   s~    (""s8K+@'A'AA'E'E,Q/H)(3 + + 5??+% 	\Z[[[r   returnintc                    | j         D ]J}t          | j         |         d         d          r'| j         |         d                                         c S Kd S )Nr    get_sentence_embedding_dimension)r
   hasattrr+   )r   r   s     r   r+   z%Asym.get_sentence_embedding_dimension@   sg    $ 	T 	TDt'-a02TUU T'-a0QQSSSSSTtr   c                   i }i }i }| j                                         D ]z\  }}g ||<   |D ]m}t          t          |                    dz   t	          |          j        z   }|||<   t	          |          j        ||<   ||                             |           n{|                                D ]]\  }}t          j	        
                    |t          |                    }	t          j        |	d           |                    |	           ^t          t          j	        
                    |d          dd          5 }
t          j        ||d| j        id	|
d
           d d d            d S # 1 swxY w Y   d S )N_T)exist_okconfig.jsonwutf8)encodingr   )types	structure
parameters   )indent)r
   r   r   idtype__name__
__module__appendospathjoinmakedirssaveopenjsondumpr   )r   output_pathmodel_lookupmodel_typesmodel_structurer   r   r   model_id
model_pathfOuts              r   rB   z	Asym.saveF   s    ,2244 	7 	7LD&$&OD! 7 7r%yy>>C/$u++2FF).X&(,U(>H%%,,X6666	7  ,1133 	# 	#OHek3x==AAJK
T2222JJz"""""',,{M::C&QQQ 		UYI(!0#4d6J"K 
    		 		 		 		 		 		 		 		 		 		 		 		 		 		 		 		 		 		s   =#E--E14E1texts!list[str] | list[tuple[str, str]]c                   t          |d         t                    st          d          d}|D ]?}t          t	          |                                                    \  }}||}||k    sJ @ | j        |         d         j        |fi |S )z-Tokenizes a text and maps tokens to token-idsr   zDAsym. model requires that texts are passed as dicts: {'key': 'text'}N)r   dictAttributeErrornextiterr   r
   tokenize)r   rM   kwargs
module_keylookupr&   texts          r   rT   zAsym.tokenizec   s    %(D)) 	i !ghhh
 	* 	*F!$v||~~"6"677NHd!%
z)))))7t
+A.7HHHHHr   c                J   t          t          j                            | d                    5 }t	          j        |          }d d d            n# 1 swxY w Y   i }|d                                         D ]L\  }}t          |          }|                    t          j                            | |                    }|||<   Mi }|d                                         D ]0\  }	}
g ||	<   |
D ]#}||	                             ||                    $1t          |fi |d         }|S )Nr0   r4   r5   r6   )
rC   r>   r?   r@   rD   loadr   r   r=   r	   )
input_pathfInconfigmodulesrJ   
model_typemodule_classmodulerI   key_namemodels_listr   s               r   rZ   z	Asym.loadr   sv   "',,z=99:: 	$cYs^^F	$ 	$ 	$ 	$ 	$ 	$ 	$ 	$ 	$ 	$ 	$ 	$ 	$ 	$ 	$ $*7O$9$9$;$; 	' 	' Hj-j99L!&&rw||J'I'IJJF &GH%+K%8%>%>%@%@ 	D 	D!Hk(*OH%' D D)001BCCCCD _==|(<==s   AAA)T)r
   r   r   r   )r    r!   )r(   r)   )rM   rN   )r;   r<   __qualname__r   r'   r+   rB   rT   staticmethodrZ   __classcell__)r   s   @r   r	   r	      s        '' '' '' '' '' '' ''R        :I I I I   \    r   r	   )
__future__r   rD   r>   collectionsr   torchr   r   sentence_transformers.utilr   
Sequentialr	    r   r   <module>rm      s    " " " " " "  				 # # # # # #         9 9 9 9 9 9x x x x x2= x x x x xr   