
    #j?4                        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m	Z	 erddl
mZ  G d d          Z G d	 d
e          Z G d de          Z G d de          ZdS )    )annotationsN)Queue)TYPE_CHECKINGAnycast   )PreTrainedTokenizerBasec                      e Zd ZdZd Zd ZdS )BaseStreamerzG
    Base class from which `.generate()` streamers should inherit.
    c                    t                      )z;Function that is called by `.generate()` to push new tokensNotImplementedErrorselfvalues     k/lsinfo/ai/hellotax_ai/base_platform/venv/lib/python3.11/site-packages/transformers/generation/streamers.pyputzBaseStreamer.put        !###    c                    t                      )zHFunction that is called by `.generate()` to signal the end of generationr   r   s    r   endzBaseStreamer.end$   r   r   N)__name__
__module____qualname____doc__r   r    r   r   r   r      s<         $ $ $$ $ $ $ $r   r   c                  8    e Zd ZdZddd	Zd
 Zd ZdddZd ZdS )TextStreamera)  
    Simple text streamer that prints the token(s) to stdout as soon as entire words are formed.

    <Tip warning={true}>

    The API for the streamer classes is still under development and may change in the future.

    </Tip>

    Parameters:
        tokenizer (`AutoTokenizer`):
            The tokenizer used to decode the tokens.
        skip_prompt (`bool`, *optional*, defaults to `False`):
            Whether to skip the prompt to `.generate()` or not. Useful e.g. for chatbots.
        decode_kwargs (`dict`, *optional*):
            Additional keyword arguments to pass to the tokenizer's `decode` method.

    Examples:

        ```python
        >>> from transformers import AutoModelForCausalLM, AutoTokenizer, TextStreamer

        >>> tok = AutoTokenizer.from_pretrained("openai-community/gpt2")
        >>> model = AutoModelForCausalLM.from_pretrained("openai-community/gpt2")
        >>> inputs = tok(["An increasing sequence: one,"], return_tensors="pt")
        >>> streamer = TextStreamer(tok)

        >>> # Despite returning the usual output, the streamer will also print the generated text to stdout.
        >>> _ = model.generate(**inputs, streamer=streamer, max_new_tokens=20)
        An increasing sequence: one, two, three, four, five, six, seven, eight, nine, ten, eleven,
        ```
    F	tokenizerr	   skip_promptbooldecode_kwargsr   c                Z    || _         || _        || _        g | _        d| _        d| _        d S )Nr   T)r    r!   r#   token_cache	print_lennext_tokens_are_prompt)r   r    r!   r#   s       r   __init__zTextStreamer.__init__K   s8    "&* ')&*###r   c                   t          |j                  dk    r |j        d         dk    rt          d          t          |j                  dk    r|d         }| j        r| j        r	d| _        dS | j                            |                                           t          t           | j
        j        | j        fi | j                  }|                    d          r|| j        d         }g | _        d| _        nt          |          dk    rU|                     t!          |d                             r-|| j        d         }| xj        t          |          z  c_        nB|| j        |                    d          dz            }| xj        t          |          z  c_        |                     |           dS )	zm
        Receives tokens, decodes them, and prints them to stdout as soon as they form entire words.
           r   z'TextStreamer only supports batch size 1FN
 )lenshape
ValueErrorr!   r'   r%   extendtolistr   strr    decoder#   endswithr&   _is_chinese_charordrfindon_finalized_text)r   r   textprintable_texts       r   r   zTextStreamer.putU   s    u{aEKNQ$6$6FGGG!!!HE 	 ; 	*/D'F 	///C..t/?VV4CUVVWW == 	2!$."2"23N!DDNNYY]]t44Sb]]CC]!$."2"23NNNc.111NNN "$.4::c??Q3F"FGNNNc.111NN~.....r   c                   t          | j                  dk    rNt          t           | j        j        | j        fi | j                  }|| j        d         }g | _        d| _        nd}d| _        | 	                    |d           dS )z;Flushes any remaining cache and prints a newline to stdout.r   N T)
stream_end)
r.   r%   r   r3   r    r4   r#   r&   r'   r9   )r   r:   r;   s      r   r   zTextStreamer.endw   s     t  1$$2T^243CZZtGYZZ[[D!$."2"23N!DDNNN&*#~$?????r   r:   r3   r>   c                2    t          |d|sdnd           dS )zNPrints the new text to stdout. If the stream is ending, also prints a newline.Tr=   N)flushr   )printr   r:   r>   s      r   r9   zTextStreamer.on_finalized_text   s&    d$j$BBBdCCCCCCr   c                    |dk    r|dk    sT|dk    r|dk    sH|dk    r|dk    s<|dk    r|dk    s0|d	k    r|d
k    s$|dk    r|dk    s|dk    r|dk    s|dk    r|dk    rdS dS )z6Checks whether CP is the codepoint of a CJK character.i N  i  i 4  iM  i   iߦ i  i? i@ i i  i i   i  i  i TFr   )r   cps     r   r6   zTextStreamer._is_chinese_char   s     6\\bFllfvg"--g"--g"--g"--fvg"--4ur   NF)r    r	   r!   r"   r#   r   r:   r3   r>   r"   )	r   r   r   r   r(   r   r   r9   r6   r   r   r   r   r   )   s         B+ + + + + /  /  /D@ @ @D D D D D    r   r   c                  @     e Zd ZdZ	 	 dd fdZdddZd Zd Z xZS )TextIteratorStreamera  
    Streamer that stores print-ready text in a queue, to be used by a downstream application as an iterator. This is
    useful for applications that benefit from accessing the generated text in a non-blocking way (e.g. in an interactive
    Gradio demo).

    <Tip warning={true}>

    The API for the streamer classes is still under development and may change in the future.

    </Tip>

    Parameters:
        tokenizer (`AutoTokenizer`):
            The tokenizer used to decode the tokens.
        skip_prompt (`bool`, *optional*, defaults to `False`):
            Whether to skip the prompt to `.generate()` or not. Useful e.g. for chatbots.
        timeout (`float`, *optional*):
            The timeout for the text queue. If `None`, the queue will block indefinitely. Useful to handle exceptions
            in `.generate()`, when it is called in a separate thread.
        decode_kwargs (`dict`, *optional*):
            Additional keyword arguments to pass to the tokenizer's `decode` method.

    Examples:

        ```python
        >>> from transformers import AutoModelForCausalLM, AutoTokenizer, TextIteratorStreamer
        >>> from threading import Thread

        >>> tok = AutoTokenizer.from_pretrained("openai-community/gpt2")
        >>> model = AutoModelForCausalLM.from_pretrained("openai-community/gpt2")
        >>> inputs = tok(["An increasing sequence: one,"], return_tensors="pt")
        >>> streamer = TextIteratorStreamer(tok)

        >>> # Run the generation in a separate thread, so that we can fetch the generated text in a non-blocking way.
        >>> generation_kwargs = dict(inputs, streamer=streamer, max_new_tokens=20)
        >>> thread = Thread(target=model.generate, kwargs=generation_kwargs)
        >>> thread.start()
        >>> generated_text = ""
        >>> for new_text in streamer:
        ...     generated_text += new_text
        >>> generated_text
        'An increasing sequence: one, two, three, four, five, six, seven, eight, nine, ten, eleven,'
        ```
    FNr    r	   r!   r"   timeoutfloat | Noner#   r   c                     t                      j        ||fi | t                      | _        d | _        || _        d S N)superr(   r   
text_queuestop_signalrI   )r   r    r!   rI   r#   	__class__s        r   r(   zTextIteratorStreamer.__init__   sD     	KAA=AAA''r   r:   r3   r>   c                    | j                             || j                   |r(| j                             | j        | j                   dS dS )\Put the new text in the queue. If the stream is ending, also put a stop signal in the queue.rI   N)rN   r   rI   rO   rB   s      r   r9   z&TextIteratorStreamer.on_finalized_text   sZ    D$,777 	HO 0$,GGGGG	H 	Hr   c                    | S rL   r   r   s    r   __iter__zTextIteratorStreamer.__iter__       r   c                x    | j                             | j                  }|| j        k    rt	                      |S NrS   )rN   getrI   rO   StopIterationr   s     r   __next__zTextIteratorStreamer.__next__   s9    ##DL#99D$$$//!Lr   FNr    r	   r!   r"   rI   rJ   r#   r   rE   rF   )	r   r   r   r   r(   r9   rU   r[   __classcell__rP   s   @r   rH   rH      s        + +` " $	
 
 
 
 
 
 
H H H H H        r   rH   c                  @     e Zd ZdZ	 	 dd fdZdddZd Zd Z xZS )AsyncTextIteratorStreamera'	  
    Streamer that stores print-ready text in a queue, to be used by a downstream application as an async iterator.
    This is useful for applications that benefit from accessing the generated text asynchronously (e.g. in an
    interactive Gradio demo).

    <Tip warning={true}>

    The API for the streamer classes is still under development and may change in the future.

    </Tip>

    Parameters:
        tokenizer (`AutoTokenizer`):
            The tokenizer used to decode the tokens.
        skip_prompt (`bool`, *optional*, defaults to `False`):
            Whether to skip the prompt to `.generate()` or not. Useful e.g. for chatbots.
        timeout (`float`, *optional*):
            The timeout for the text queue. If `None`, the queue will block indefinitely. Useful to handle exceptions
            in `.generate()`, when it is called in a separate thread.
        decode_kwargs (`dict`, *optional*):
            Additional keyword arguments to pass to the tokenizer's `decode` method.

    Raises:
        TimeoutError: If token generation time exceeds timeout value.

    Examples:

        ```python
        >>> from transformers import AutoModelForCausalLM, AutoTokenizer, AsyncTextIteratorStreamer
        >>> from threading import Thread
        >>> import asyncio

        >>> tok = AutoTokenizer.from_pretrained("openai-community/gpt2")
        >>> model = AutoModelForCausalLM.from_pretrained("openai-community/gpt2")
        >>> inputs = tok(["An increasing sequence: one,"], return_tensors="pt")

        >>> # Run the generation in a separate thread, so that we can fetch the generated text in a non-blocking way.
        >>> async def main():
        ...     # Important: AsyncTextIteratorStreamer must be initialized inside a coroutine!
        ...     streamer = AsyncTextIteratorStreamer(tok)
        ...     generation_kwargs = dict(inputs, streamer=streamer, max_new_tokens=20)
        ...     thread = Thread(target=model.generate, kwargs=generation_kwargs)
        ...     thread.start()
        ...     generated_text = ""
        ...     async for new_text in streamer:
        ...         generated_text += new_text
        >>>     print(generated_text)
        >>> asyncio.run(main())
        An increasing sequence: one, two, three, four, five, six, seven, eight, nine, ten, eleven,
        ```
    FNr    r	   r!   r"   rI   rJ   r#   r   c                N    t                      j        ||fi | t          j                    | _        d | _        || _        t          j                    | _        t          t          dd           }t          j        dk    ot          |          | _        | j        r|nd | _        d S )NrI   )      )rM   r(   asyncior   rN   rO   rI   get_running_looploopgetattrsysversion_infocallablehas_asyncio_timeoutasyncio_timeout)r   r    r!   rI   r#   timeout_contextrP   s         r   r(   z"AsyncTextIteratorStreamer.__init__"  s     	KAA=AAA!-//,..	!'9d;;#&#3w#>#\8OC\C\ 262JTPTr   r:   r3   r>   c                    | j                             | j        j        |           |r,| j                             | j        j        | j                   dS dS )rR   N)rg   call_soon_threadsaferN   
put_nowaitrO   rB   s      r   r9   z+AsyncTextIteratorStreamer.on_finalized_text2  sZ    	&&t'A4HHH 	YI**4?+EtGWXXXXX	Y 	Yr   c                    | S rL   r   r   s    r   	__aiter__z#AsyncTextIteratorStreamer.__aiter__8  rV   r   c                  K   	 | j         rk| j        d|                     | j                  4 d {V  | j                                         d {V }d d d           d {V  n# 1 d {V swxY w Y   n8t          j        | j                                        | j                   d {V }|| j        k    rt                      |S # t
          j	        $ r t                      w xY wrX   )
rl   rm   rI   rN   rY   re   wait_forrO   StopAsyncIterationTimeoutErrorr   s     r   	__anext__z#AsyncTextIteratorStreamer.__anext__;  s     	' \D,@,L//== 8 8 8 8 8 8 8 8"&/"5"5"7"7777777E8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 &.t/B/B/D/Ddl[[[[[[[[[ ((((*** # 	! 	! 	!.. 	!s.   .C	  A$C	 $
A..C	 1A.2<C	 	C'r\   r]   rE   rF   )	r   r   r   r   r(   r9   rs   rx   r^   r_   s   @r   ra   ra      s        2 2n " $	U U U U U U U Y Y Y Y Y        r   ra   )
__future__r   re   ri   queuer   typingr   r   r   tokenization_utils_baser	   r   r   rH   ra   r   r   r   <module>r}      sD   # " " " " "  



       + + + + + + + + + +  BAAAAAA$ $ $ $ $ $ $ $v v v v v< v v vrH H H H H< H H HV[ [ [ [ [ [ [ [ [ [r   