o
    0j)b                     @   sD   d dl Z d dlZd dlZd dlZd dlZd dlZG dd deZdS )    Nc                   @   s  e Zd ZdZ								d.ddZdd Zdd	 Zd
d Zdd Zdd Z	dd Z
dd Zdd Zedd Zedd Zd/ddZedd Ze				d0ddZe							d1d d!Ze				d0d"d#Zd$d% Zd&d' Zd(d) Zd*d+ Zd,d- ZdS )2Vocaba  
    The class used to convert between tokens and ids. It also includes some
    store/load functions.

    Args:
        counter (collections.Counter, optional): A Counter instance describes
            the tokens and their frequencies. Its keys will be indexed according
            to the order of frequency sorting to construct mapping relationship.
            If None, `token_to_idx` must be provided as the mapping relationship.
            Default: None.
        max_size (int, optional): Max size of vocab, not including special tokens.
            Default: None.
        min_freq (int, optional): Ignore tokens whose frequencies are less than
            `min_freq`. Default: 1.
        token_to_idx (dict, optional): A dict specifies the mapping relationship
            between tokens and indices to be used. If provided, adjust the tokens
            and indices mapping according to it. If None, counter must be provided.
            Default: None.
        unk_token (str, optional): Special token for unknown token. If no need,
            it also could be None. Default: None.
        pad_token (str, optional): Special token for padding token. If no need,
            it also could be None. Default: None.
        bos_token (str, optional): Special token for bos token. If no need, it
            also could be None. Default: None.
        eos_token (str, optional): Special token for eos token. If no need, it
            lso could be None. Default: None.

        kwargs (dict): Keyword arguments ending with `_token`. It can be used
            to specify further special tokens that will be exposed as attribute
            of the vocabulary and associated with an index.
    N   c	                    s  dfd|fd|fd|ff}
|
D ]\}}||	|< qg }|	  }t|}|D ]}|ds3td||	| }|d urD||vrD|| q%|d u r|sOJ d|D ]}||v s^J d|qQ| _d	d
 | D  _r j t	
fdd _ j| n7dd
 t|D  _t	
  _ jdd  j D   |||| |r | r fdd j_|	 _|	 D ] \}}|drtdt |rtd||t || qd S )N	unk_token	pad_token	bos_token	eos_token_tokenzc{} is invalid. Only keyword arguments that end in '_token' are supported to declare special tokens.z4token_to_idx should not be None when counter is Nonez{} is not in token_to_idxc                 S   s   i | ]\}}||qS  r	   ).0tokenidxr	   r	   p/var/www/html/Deteccion_Ine/venv/lib/python3.10/site-packages/paddlex/inference/models/common/tokenizer/vocab.py
<dictcomp>g   s    z"Vocab.__init__.<locals>.<dictcomp>c                      s    S Nr	   r	   )	unk_indexr	   r   <lambda>j   s    z Vocab.__init__.<locals>.<lambda>c                 S   s   i | ]\}}||qS r	   r	   )r
   r   special_tokenr	   r	   r   r   m   s    
c                 s   s    | ]	\}}||fV  qd S r   r	   )r
   r   r   r	   r	   r   	<genexpr>q   s    
z!Vocab.__init__.<locals>.<genexpr>c                      s
    j  S r   _token_to_idxr	   )selfr   r	   r   r   x   s    _zIt is not allowed to use identifiers starting with underscore. In Python identifier names beginning with underscore are internal.zJvocab.{} already exists. Please choose a different identifier for token {})keyssortedendswith
ValueErrorformatappendr   items_idx_to_tokencollectionsdefaultdictupdate	enumerate_index_counter_keys+_sort_index_according_to_user_specificationdefault_factory_identifiers_to_tokens
startswithhasattrsetattr)r   countermax_sizemin_freqtoken_to_idxr   r   r   r   kwargsZcombsnamevaluespecial_tokensZspecial_iterZspecial_token_namer   
identifierr   r	   )r   r   r   r   __init__9   sx   








zVocab.__init__c                 C   s   t | dd d}|jdd dd t|}|d u rd n|t| }|D ]1\}}||k s4t| j|kr7 d S ||vrV|| jtt| j dg d < t| j | j	|< q%d S )	Nc                 S      | d S )Nr   r	   xr	   r	   r   r          z+Vocab._index_counter_keys.<locals>.<lambda>)keyc                 S   r5   )Nr   r	   r6   r	   r	   r   r      r8   T)r9   reverser   )
r   r   sortsetlenr   maxlistr   r   )r   r+   r2   r,   r-   Ztoken_freqsr   freqr	   r	   r   r$      s    zVocab._index_counter_keysc                 C   s   t | | j stdtt | t|kr tdt| dk s3t| t| jkr=td	t| j|
 D ]"\}}| j| }| j| }|| j|< || j|< || j|< || j|< qAd S )Nz`User-specified token_to_idx mapping can only contain tokens that will be part of the vocabulary.z3User-specified indices must not contain duplicates.r   zUser-specified indices must not be < 0 or >= the number of tokens that will be in the vocabulary. The current vocab contains {}tokens.)r=   r   issubsetr.   r   r>   valuesminr?   r   r   idx_to_token)r   r.   r   Znew_idxZold_idxZousted_tokenr	   r	   r   r%      s*   




z1Vocab._sort_index_according_to_user_specificationc              	   C   s   d}t |tttjfs|g}d}t |ttfrt|}t |tjr3t|jdkr3td	t|jg }|D ]+}t |t
tjfsJtd t
|}z
|| j|  W q7 tyb   td	|w |ri|d S |S )uc  
        Maps the input indices to token list.

        Args:
            indices (int|list[int]|tuple[int]|numpy.ndarray): The input indice(s) for mapping.
                Must be an `int` or 1D `list[int]`|`tuple[int]`|`numpy.ndarray`.

        Returns:
            str|list[str]: Obtained token(s). If `indices` is an integer, it
            will return a str. If `indices` is a list/tuple of integers, it will
            return a list of str.

        Example:
            .. code-block:: python

                from paddlenlp.data import Vocab
                # The vocab file. The sample file can be downloaded firstly.
                # wget https://bj.bcebos.com/paddlenlp/data/senta_word_dict.txt
                vocab_file_path = './senta_word_dict.txt'
                # Initialize the Vocab
                vocab = Vocab.load_vocabulary(
                    vocab_file_path,
                    unk_token='[UNK]',
                    pad_token='[PAD]')
                tokens = vocab.to_tokens([0, 1, 2, 3])
                print(tokens)
                # ['[PAD]', '[UNK]', '一斤三', '意面屋']
        FTr   zEToken indices is invalid. Expected 1D array, but received {}D array. zfThe type of `to_tokens()`'s input `indices` is not `int` which will be forcibly transferred to `int`. z4Token index {} in the provided `indices` is invalid.r   )
isinstancer@   tuplenpZndarrayZasarrayr>   shaper   r   intintegerwarningswarnr   r   KeyError)r   indicesZ	to_reducetokensr   r	   r	   r   	to_tokens   s6   
zVocab.to_tokensc                 C      | | S )u  
        Maps the input tokens into indices.

        Args:
            tokens (str|list[str]|tuple[str], optional): The input token(s) for
                mapping.

        Returns:
            int|list[int]: Obationed indice(s). If `tokens` is a str, it will
            return an integer. If `tokens` is a list/tuple of str, it will
            return a list of integers.

        Example:
            .. code-block:: python

                from paddlenlp.data import Vocab
                # The vocab file. The sample file can be downloaded firstly.
                # wget https://bj.bcebos.com/paddlenlp/data/senta_word_dict.txt
                vocab_file_path = './senta_word_dict.txt'
                # Initialize the Vocab
                vocab = Vocab.load_vocabulary(
                    vocab_file_path,
                    unk_token='[UNK]',
                    pad_token='[PAD]')
                tokens = vocab.to_indices(['[PAD]', '[UNK]', '一斤三', '意面屋'])
                print(tokens)
                # [0, 1, 2, 3]
        r	   r   rP   r	   r	   r   
to_indices   s   zVocab.to_indicesc                    s@   t |ttfs| jv r j| S  j j S  fdd|D S )Nc                    s,   g | ]}| j v r j | n j  j qS r	   )r   r   )r
   r   r   r	   r   
<listcomp>  s    


z%Vocab.__getitem__.<locals>.<listcomp>)rF   r@   rG   r   r   rS   r	   rU   r   __getitem__  s   


zVocab.__getitem__c                 C   s
   t | jS r   )r>   r   rU   r	   r	   r   __len__'     
zVocab.__len__c                 C   s
   || j v S r   r   )r   r   r	   r	   r   __contains__*  rY   zVocab.__contains__c                 C   rR   )z
        Maps the input tokens into indices. Its function is the same as the
        :meth:`to_indices` method.

        See detail at `to_indices`.
        r	   rS   r	   r	   r   __call__-  s   zVocab.__call__c                 C      | j S r   )r   rU   r	   r	   r   rE   6     zVocab.idx_to_tokenc                 C   r\   r   r   rU   r	   r	   r   r.   ;  r]   zVocab.token_to_idxc                 C   s   i }t | j|d< t | j|d< | j|d< | j|d< t|}|r?tj|ddd}|	| W d   |S 1 s:w   Y  |S )	a?  
        Summarizes some information of vocab as JSON string. If path is gaven,
        the JSON string will be saved into files. The JSON string and the saved
        file all can be used to reconstruct the :class:`Vocab` by calling
        :meth:`from_json` method.

        Args:
            path (str, optional): The path to save JSON string. If None, the
                JSON will not be saved. Default: None.

        Returns:
            str: The JSON string including information of vocab.

        Example:
            .. code-block:: python

                from paddlenlp.data import Vocab
                # The vocab file. The sample file can be downloaded firstly.
                # wget https://bj.bcebos.com/paddlenlp/data/senta_word_dict.txt
                vocab_file_path = './senta_word_dict.txt'
                # Initialize the Vocab
                vocab = Vocab.load_vocabulary(
                    vocab_file_path,
                    unk_token='[UNK]',
                    pad_token='[PAD]')
                json_str = vocab.to_json(path='./vocab.json')
        rE   r.   r   identifiers_to_tokenswutf-8encodingN)
dictrE   r.   r   r'   jsondumpsioopenwrite)r   path
vocab_dictjson_strfr	   r	   r   to_json@  s   



zVocab.to_jsonc                 C   s   t j|r$tj|ddd}t|}W d   n1 sw   Y  nt|}|d}|d}|dt	 }d|v rA|d= | d	d||d|}|S )
ap  
        Loads :class:`Vocab` from JSON string or JSON file, which is gotten by
        calling :meth:`to_json` method.

        Args:
            json_str (str): JSON string or file path of JSON string.

        Returns:
            Vocab: An instance of :class:`Vocab` generated from information
            contained in JSON string.

        Example:
            .. code-block:: python

                from paddlenlp.data import Vocab
                # The vocab file. The sample file can be downloaded firstly.
                # wget https://bj.bcebos.com/paddlenlp/data/senta_word_dict.txt
                vocab_file_path = './senta_word_dict.txt'
                # Initialize the Vocab
                vocab = Vocab.load_vocabulary(
                    vocab_file_path,
                    unk_token='[UNK]',
                    pad_token='[PAD]')
                json_str = vocab.to_json(path='./vocab.json')

                vocab1 = Vocab.from_json(json_str)
                vocab2 = Vocab.from_json('./vocab.json')
                print(len(vocab), len(vocab1), len(vocab2))
                # 1256608 1256608 1256608
        rr`   ra   Nr.   r   r^   )r+   r.   r   r	   )
osri   isfilerf   rg   rd   loadloadsgetrc   )clsrk   rl   rj   r.   r   r^   vocabr	   r	   r   	from_jsong  s&    


zVocab.from_jsonc              	   K   s    | dd|||||d|}|S )a  
        Builds the :class:`Vocab` from a dict.

        Args:
            token_to_idx (dict): A dict describes the mapping relationship between
                tokens and indices.
            unk_token (str, optional): The special token for unknown token. If
                no need, it also could be None. Default: None.
            pad_token (str, optional): The special token for padding token. If
                no need, it also could be None. Default: None.
            bos_token (str, optional): The special token for bos token. If no
                need, it also could be None. Default: None.
            eos_token (str, optional): The special token for eos token. If no
                need, it also could be None. Default: None.

            kwargs (dict): Keyword arguments ending with `_token`. It can be
                used to specify further special tokens that will be exposed as
                attribute of the vocabulary and associated with an index.

        Returns:
            Vocab: An instance of :class:`Vocab` generated from the given dict
            and special tokens.

        Example:
            .. code-block:: python

                from paddlenlp.data import Vocab
                # The vocab file. The sample file can be downloaded firstly.
                # wget https://bj.bcebos.com/paddlenlp/data/senta_word_dict.txt
                vocab_file_path = './senta_word_dict.txt'
                # Initialize the Vocab
                vocab = Vocab.load_vocabulary(
                    vocab_file_path,
                    unk_token='[UNK]',
                    pad_token='[PAD]')

                vocab1 = Vocab.from_dict(vocab.token_to_idx)
                print(len(vocab), len(vocab.token_to_idx), len(vocab1))
                # 1256608 1256608 1256608
        N)r+   r.   r   r   r   r   r	   r	   )rt   r.   r   r   r   r   r/   ru   r	   r	   r   	from_dict  s   2	zVocab.from_dictc              
   K   s@   t  }	| D ]}
|	|
 qt|	f|||||||d|}|S )a	
  
        Builds the :class:`Vocab` according to given iterator and other
        information. Firstly, iterate over the `iterator` to construct a
        :class:`collections.Counter` and used to init the as  :class:`Vocab`.

        Args:
            iterator (collections.Iterable): Iterator of tokens. Each element
                should be a list of tokens if wordlevel vocab is needed.
            max_size (int, optional): The max size of vocab, not including
                special tokens. Default: None.
            min_freq (int, optional): Ignore tokens whose frequencies are less
                than `min_freq`. Default: 1.
            token_to_idx (dict, optional): A dict specifies the mapping
                relationship between tokens and indices to be used. If provided,
                adjust the tokens and indices mapping according to it. If None,
                counter must be provided. Default: None.
            unk_token (str, optional): The special token for unknown token
                '<unk>'. If no need, it also could be None. Default: None.
            pad_token (str, optional): The special token for padding token
                '<pad>'. If no need, it also could be None. Default: None.
            bos_token (str, optional): The special token for bos token '<bos>'.
                If no need, it also could be None. Default: None.
            eos_token (str, optional): The special token for eos token '<eos>'.
                If no need, it also could be None. Default: None.

            kwargs (dict): Keyword arguments ending with `_token`. It can be
                used to specify further special tokens that will be exposed as
                attribute of the vocabulary and associated with an index.

        Returns:
            Vocab: An instance of :class:`Vocab` generated from given iterator
            and other informations.

        Example:
            .. code-block:: python

                from paddlenlp.data import Vocab
                # The vocab file. The sample file can be downloaded firstly.
                # wget https://bj.bcebos.com/paddlenlp/data/senta_word_dict.txt
                vocab_file_path = './senta_word_dict.txt'
                # Initialize the Vocab
                vocab = Vocab.load_vocabulary(
                    vocab_file_path,
                    unk_token='[UNK]',
                    pad_token='[PAD]')

                vocab1 = Vocab.build_vocab([list(vocab.token_to_idx.keys())])
                print(len(vocab), len(vocab1))
                # 1256608 1256608
        )r,   r-   r.   r   r   r   r   )r    Counterr"   r   )iteratorr,   r-   r.   r   r   r   r   r/   r+   rP   ru   r	   r	   r   build_vocab  s"   >	zVocab.build_vocabc                 K   s|   i }t j| ddd}t|D ]\}}	|	d}
t|||
< qW d   n1 s)w   Y  tj|f||||d|}|S )a  
        Builds the :class:`Vocab` from a file reserving all tokens by calling
        :meth:`Vocab.from_dict` method. The file contains a token per line, and
        the line index would be the index of corresponding token.

        Args:
            filepath (str): the path of file to construct vocabulary.
            unk_token (str, optional): special token for unknown token. If no
                need, it also could be None. Default: None.
            pad_token (str, optional): special token for padding token. If no
                need, it also could be None. Default: None.
            bos_token (str, optional): special token for bos token. If no need,
                it also could be None. Default: None.
            eos_token (str, optional): special token for eos token. If no need,
                it also could be None. Default: None.

            kwargs (dict): Keyword arguments ending with `_token`. It can be
                used to specify further special tokens that will be exposed as
                attribute of the vocabulary and associated with an index.

        Returns:
            Vocab: An instance of :class:`Vocab` generated from the given file.

        Example:
            .. code-block:: python

                from paddlenlp.data import Vocab
                # The vocab file. The sample file can be downloaded firstly.
                # wget https://bj.bcebos.com/paddlenlp/data/senta_word_dict.txt
                vocab_file_path = './senta_word_dict.txt'
                # Initialize the Vocab
                vocab = Vocab.load_vocabulary(
                    vocab_file_path,
                    unk_token='[UNK]',
                    pad_token='[PAD]')
                print(len(vocab))
                # 1256608
        rn   r`   ra   
N)r   r   r   r   )rf   rg   r#   rstriprJ   r   rw   )filepathr   r   r   r   r/   r.   rl   indexliner   ru   r	   r	   r   load_vocabulary$  s$   /
zVocab.load_vocabularyc                 C   sX   t |d}tt| jD ]}|| j| d  qW d   dS 1 s%w   Y  dS )z
        Save the :class:`Vocab` to a specific file. Can be reloaded by calling `load_vocabulary`.

        Args:
            filepath (str): the path of file to save vocabulary.
        r_   r{   N)rg   ranger>   r   rh   )r   r}   rl   r   r	   r	   r   save_vocabularyb  s
   "zVocab.save_vocabularyc                 C      | j d ur| j| j  S | j S r   )r   r   rU   r	   r	   r   get_unk_token_idm  
   

zVocab.get_unk_token_idc                 C   r   r   )r   r   rU   r	   r	   r   get_bos_token_idt  r   zVocab.get_bos_token_idc                 C   r   r   )r   r   rU   r	   r	   r   get_eos_token_id{  r   zVocab.get_eos_token_idc                 C   r   r   )r   r   rU   r	   r	   r   get_pad_token_id  r   zVocab.get_pad_token_id)NNr   NNNNNr   )NNNN)Nr   NNNNN)__name__
__module____qualname____doc__r4   r$   r%   rQ   rT   rW   rX   rZ   r[   propertyrE   r.   rm   classmethodrv   rw   staticmethodrz   r   r   r   r   r   r   r	   r	   r	   r   r      sh    "
U<	


'
1<M=r   )	r    rf   rd   ro   rL   numpyrH   objectr   r	   r	   r	   r   <module>   s   