
    ^j@                        d dl mZ d dl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 G d de      Zy)    )annotationsN)Queue)TYPE_CHECKINGAnycast   )PreTrainedTokenizerBasec                      e Zd ZdZd Zd Zy)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     l/var/www/ramen.bs-engineer-server.com/venv/lib/python3.12/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                  6    e Zd ZdZdd	dZd Zd Zdd
dZd Zy)TextStreamera  
    Simple text streamer that prints the token(s) to stdout as soon as entire words are formed.

    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,
        ```
    c                X    || _         || _        || _        g | _        d| _        d| _        y )Nr   T)	tokenizerskip_promptdecode_kwargstoken_cache	print_lennext_tokens_are_prompt)r   r!   r"   r#   s       r   __init__zTextStreamer.__init__F   s2    "&* ')&*#r   c                h   t        |j                        dkD  r|j                  d   dkD  rt        d      t        |j                        dkD  r|d   }| j                  r| j                  rd| _        y| j
                  j                  |j                                t        t         | j                  j                  | j
                  fi | j                        }|j                  d      r|| j                  d }g | _        d| _        nt        |      dkD  rK| j                  t!        |d               r.|| j                  d }| xj                  t        |      z  c_        n?|| j                  |j#                  d      dz    }| xj                  t        |      z  c_        | j%                  |       y)	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.putP   sc    u{{aEKKNQ$6FGG!!HE ; ;*/D' 	/C...t/?/?V4CUCUVW ==!$.."23N!DDNY]t44Sb]C!$.."23NNNc.11N "$..4::c?Q3FGNNNc.11N~.r   c                &   t        | j                        dkD  r]t        t         | j                  j
                  | j                  fi | j                        }|| j                  d }g | _        d| _        nd}d| _        | j                  |d       y)z;Flushes any remaining cache and prints a newline to stdout.r   N T)
stream_end)
r-   r$   r   r2   r!   r3   r#   r%   r&   r8   )r   r9   r:   s      r   r   zTextStreamer.endr   s     t 1$2T^^2243C3CZtGYGYZ[D!$.."23N!DDNN&*#~$?r   c                4    t        |d|sd       yd       y)zNPrints the new text to stdout. If the stream is ending, also prints a newline.Tr<   N)flushr   )printr   r9   r=   s      r   r8   zTextStreamer.on_finalized_text   s    d$jBCdCr   c                    |dk\  r|dk  sF|dk\  r|dk  s<|dk\  r|dk  s2|dk\  r|dk  s(|d	k\  r|d
k  s|dk\  r|dk  s|dk\  r|dk  s
|dk\  r|dk  ryy)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   r5   zTextStreamer._is_chinese_char   sr     6\bFlfvg"-g"-g"-g"-fvg"-r   NF)r!   r	   r"   boolr#   r   r9   r2   r=   rE   )	r   r   r   r   r'   r   r   r8   r5   r   r   r   r   r   *   s#    6+ /D@Dr   r   c                  N     e Zd ZdZ	 	 d	 	 	 	 	 	 	 d fdZdd	dZd Zd Z xZS )
TextIteratorStreamerac  
    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).

    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,'
        ```
    c                b    t        |   ||fi | t               | _        d | _        || _        y N)superr'   r   
text_queuestop_signaltimeout)r   r!   r"   rN   r#   	__class__s        r   r'   zTextIteratorStreamer.__init__   s1     	KA=A'r   c                    | j                   j                  || j                         |r2| j                   j                  | j                  | j                         yy)\Put the new text in the queue. If the stream is ending, also put a stop signal in the queue.rN   N)rL   r   rN   rM   rA   s      r   r8   z&TextIteratorStreamer.on_finalized_text   sF    D$,,7OO 0 0$,,G r   c                    | S rJ   r   r   s    r   __iter__zTextIteratorStreamer.__iter__       r   c                    | j                   j                  | j                        }|| j                  k(  r
t	               |S NrR   )rL   getrN   rM   StopIterationr   s     r   __next__zTextIteratorStreamer.__next__   s8    ##DLL#9D$$$/!Lr   FNr!   r	   r"   rE   rN   float | Noner#   r   rD   rF   )	r   r   r   r   r'   r8   rT   rZ   __classcell__rO   s   @r   rH   rH      sL    %T " $	
*
 
 	

 
Hr   rH   c                  N     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).

    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,
        ```
    c                J   t        |   ||fi | t        j                         | _        d | _        || _        t        j                         | _        t        t        dd       }t        j                  dk\  xr t        |      | _        | j                  r|| _        y d | _        y )NrN   )      )rK   r'   asyncior   rL   rM   rN   get_running_looploopgetattrsysversion_infocallablehas_asyncio_timeoutasyncio_timeout)r   r!   r"   rN   r#   timeout_contextrO   s         r   r'   z"AsyncTextIteratorStreamer.__init__  s     	KA=A!--/,,.	!'9d;#&#3#3w#>#\8OC\ 262J2JPTr   c                    | j                   j                  | j                  j                  |       |r;| j                   j                  | j                  j                  | j                         yy)rQ   N)rg   call_soon_threadsaferL   
put_nowaitrM   rA   s      r   r8   z+AsyncTextIteratorStreamer.on_finalized_text!  sL    		&&t'A'A4HII**4??+E+EtGWGWX r   c                    | S rJ   r   r   s    r   	__aiter__z#AsyncTextIteratorStreamer.__aiter__'  rU   r   c                  K   	 | j                   rc| j                  W| j                  | j                        4 d {    | j                  j	                          d {   }d d d       d {    nAt        j                  | j                  j	                         | j                         d {   }| j                  k(  r
t               |S 7 7 s7 e# 1 d {  7  sw Y   3xY w7 :# t
        j                  $ r t               w xY wwrW   )
rl   rm   rN   rL   rX   re   wait_forrM   StopAsyncIterationTimeoutErrorr   s     r   	__anext__z#AsyncTextIteratorStreamer.__anext__*  s     	''D,@,@,L//= 8 8"&//"5"5"77E8 8 8 &..t/B/B/Ddll[[ ((((**878 8 8 8 \## 	!. 	!s   D7C, CC, CCC"C, -C.AC, /C*0C, 4DC, CC, C'CC'#C, ,D

Dr[   r\   rD   rF   )	r   r   r   r   r'   r8   rs   rx   r^   r_   s   @r   ra   ra      sQ    ,b " $	U*U U 	U
 U Yr   ra   c                  X     e Zd ZdZ	 	 d	 	 	 	 	 	 	 d fdZd Zd Z fdZ fdZ xZ	S )	TextDiffusionStreamera  
    Streamer that prints text diffusion outputs. Intermediate diffusion steps (drafts) are temporary
    and overwritten by subsequent drafts, and removed when confirmed text is printed.

    <Tip warning={true}>

    If you're running on an environment like tmux, the draft text may fail to overwrite itself.

    </Tip>


    Parameters:
        tokenizer (`AutoTokenizer`):
            The tokenized 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.
        sleep_time (`float`, *optional*):
            Time to sleep between diffusion drafts, which may be helpful to visualize intermediate outputs.
        decode_kwargs (`dict`, *optional*):
            Additional keyword arguments to pass to the tokenizer's `decode` method.

    Examples:

        ```python
        >>> from transformers import DiffusionGemmaForBlockDiffusion, AutoProcessor, TextDiffusionStreamer

        >>> model = DiffusionGemmaForBlockDiffusion.from_pretrained(
        ...     "google/diffusiongemma-26B-A4B-it", device_map="auto",
        ... )
        >>> processor = AutoProcessor.from_pretrained("google/diffusiongemma-26B-A4B-it")

        >>> chat = [{"role": "user", "content": "Why is the sky blue?"},]
        >>> input_ids = processor.apply_chat_template(
        ...     chat, tokenize=True, return_tensors="pt", add_generation_prompt=True
        ... )
        >>> streamer = TextDiffusionStreamer(tokenizer=processor.tokenizer)
        >>> model.generate(input_ids.to(model.device), max_new_tokens=512, streamer=streamer)
        ```
    c                R    t        |   ||fi | d| _        d| _        || _        y )NF)rK   r'   
_has_draft_takes_logits
sleep_time)r   r!   r"   r~   r#   rO   s        r   r'   zTextDiffusionStreamer.__init__c  s1     	KA=A #$r   c                H    | j                   rt        ddd       d| _         y y )Nz8[Jr<   Tr   r?   F)r|   r@   r   s    r   _clear_draftz"TextDiffusionStreamer._clear_draftr  s!    ??-Rt4#DO r   c                   | j                          t        |j                        dkD  r|j                  d   dkD  rt        d      t        |j                        dkD  r|d   } | j                  j
                  |fi | j                  }t        ddd       t        d| d	dd       d| _        | j                   t        j                  | j                         y
y
)z
        Receives the full sequence of draft tokens, decodes them, and prints them in yellow.
        Overwrites previous draft.
        r)   r   z0TextDiffusionStreamer only supports batch size 1z7r<   Tr   z[33mz[0mN)r   r-   r.   r/   r!   r3   r#   r@   r|   r~   timesleep)r   r   kwargsr9   s       r   	put_draftzTextDiffusionStreamer.put_draftx  s    
 	u{{aEKKNQ$6OPP!!HE$t~~$$UAd.@.@A 	g2T*g&Bd;??&JJt' 'r   c                D    | j                          t        | 	  |       y)zEReceives confirmed tokens, clears draft, and prints them permanently.N)r   rK   r   )r   r   rO   s     r   r   zTextDiffusionStreamer.put  s    Er   c                B    | j                          t        | 	          y)z1Flushes any remaining cache and prints a newline.N)r   rK   r   )r   rO   s    r   r   zTextDiffusionStreamer.end  s    r   r[   )r!   r	   r"   rE   r~   r]   r#   r   )
r   r   r   r   r'   r   r   r   r   r^   r_   s   @r   rz   rz   :  sU    &V "#'	%*% % !	%
 %$(,
 r   rz   )
__future__r   re   ri   r   queuer   typingr   r   r   tokenization_utils_baser	   r   r   rH   ra   rz   r   r   r   <module>r      si    #  
   + + A$ $p< pfB< BJU Up\L \r   