o
    پiP                     @   s   d dl Z d dlmZ d dlmZ d dlmZmZmZmZm	Z	m
Z
 d dlmZ d dlmZmZmZ er6d dlZe
eeeee je je j f ZG dd dZed	d
G dd dZed	d
G dd dZG dd dZG dd deZdS )    N)copy)	dataclass)TYPE_CHECKINGAnyIteratorListOptionalUnion)sequence_generator)BeamSearchSamplerGreedySamplerMultinomialSamplerc                   @   s@  e Zd Zdd Zddddded fddZd	ee d
ee defddZded
e	ee  defddZ
dedefddZ			ddeeee f de	e de	eeee f  de	d deeee eee  f f
ddZ			ddeeee f de	e de	eeee f  de	d deeee eeee  f  f
ddZdS )SequenceGeneratorc                 C   s,   || _ || _|| _|j| _|| _|j| _d S N)fsmmodelsampler	tokenizerdevicesamplesnum_samples)selfr   r   r   r    r   I/home/ubuntu/.local/lib/python3.10/site-packages/outlines/generate/api.py__init__   s   zSequenceGenerator.__init__prompt_token_idsztorch.Tensor	token_idsreturnc                 C   s&   dd |D }dd t ||D }|S )aZ  Get the tokens generated so far.

        Parameters
        ----------
        prompt_token_ids
            Tensor that contains the token ids of the sequences' prompts.
        token_ids
            The generated token ids.

        Returns
        -------
        A tensor that contains the token ids that have been generated so far.

        c                 S   s   g | ]}t |qS r   len).0promptr   r   r   
<listcomp>3       z=SequenceGenerator.get_generated_token_ids.<locals>.<listcomp>c                 S   s   g | ]
\}}||d  qS r   r   )r    cur_token_idslengthr   r   r   r"   4   s    
)zip)r   r   r   prompt_lengthsr   r   r   get_generated_token_ids    s
   z)SequenceGenerator.get_generated_token_idsgenerated_sequencesstop_sequencesc                    s   t  fdd|D S )a  Determine whether one of the stop sequences has been generated.

        Parameters
        ----------
        generated_sequences
            The list of sequences generated so far.
        stop_sequences
            The list that contains the sequence which stop the generation when
            found.

        Returns
        -------
        True if at least one of the stop sequences has been found in each generated
        sequence.

        c                    s"   g | ] t  fd dD qS )c                    s   g | ]}| v qS r   r   r    seq	generatedr   r   r"   P   r#   zGSequenceGenerator.is_stop_sequence_found.<locals>.<listcomp>.<listcomp>)any)r    r*   r-   r   r"   O   s    z<SequenceGenerator.is_stop_sequence_found.<locals>.<listcomp>)all)r   r)   r*   r   r0   r   is_stop_sequence_found;   s
   
z(SequenceGenerator.is_stop_sequence_foundsequencec                    sd   |r0 fdd|D }t dd |D r0tdd |D }||} d|| t||     S )a  Remove the stop sequences from the generated sequences.

        Parameters
        ----------
        sequence
            One of the generated sequences.
        stop_sequences
            The list that contains the sequence which stop the generation when
            found.

        c                       g | ]}  |qS r   )findr+   r3   r   r   r"   d       z:SequenceGenerator.strip_stop_sequences.<locals>.<listcomp>c                 S   s   g | ]}|d kqS r   )r    indexr   r   r   r"   e   r#   c                 S   s   g | ]}|d kr|qS r8   r   )r    ir   r   r   r"   g   s    N)r/   minr:   r   )r   r3   r*   match_indexesmin_match_index_valuemin_match_index_posr   r6   r   strip_stop_sequencesU   s   

z&SequenceGenerator.strip_stop_sequencesc                 C      |S aX  Translate the generated sequence to another type.

        This method is for instance overridden when generating JSON to either
        return a dictionnary or a Pydantic model.

        Parameters
        ----------
        sequence
            A generated sequences.

        Returns
        -------
        The formatted sequence.

        r   r   r3   r   r   r   format_sequencep      z!SequenceGenerator.format_sequenceNprompts
max_tokensstop_atrngztorch.Generatorc              
      s@  ddl }t|tr|g}t|tr|g}| j}|du r(|j jd}|   j|\}}|	 j}|	 j} j}t
|}	|j||dd}|j||dd}dd t|	| D }
 fddt|	| D }|j|	| |j jd}t j j|||||
|d	}	 z-t|}|sr|j} ||}|rt
|d |krW nr  j|rW nW n	 ty   Y nw q|j} ||} j|} fdd|D } fdd|D }t }td|	| |D ]}|||||   q|	dkr	|dkr	|d d S |	dkr|d S |dkrdd |D S |S )a  Generate the full text sequence.

        Since `SequenceGenerator.stream` calls the tokenizer at every step this
        method loops over the generator returned by `sequence_generator` itself
        so the tokenizer is called only once after all token ids have been
        generated.

        Parameters
        ----------
        prompts
            A string or list of strings that are passed to the model before
            generating the first token.
        max_tokens
            An integer representing maximum number of tokens that will be generated
            (per prompt)
        stop_at
            A string or list of strings at which the text generated will stop
        rng
            The random number generator. Defaults to a non-seeded `torch.Generator`
            instance.

        Returns
        -------
        The generation(s), potentially cast to another type.
        r   Nr   dimc                 S      g | ]}d qS r   r   r    _r   r   r   r"          z.SequenceGenerator.__call__.<locals>.<listcomp>c                       g | ]} j  qS r   r   r   rO   r   r   r   r"      r7   dtyper   rI   Tc                    s   g | ]}  |qS r   )r@   r    r3   r   r*   r   r   r"      s    
c                    r4   r   )rD   rX   rT   r   r   r"      r7      c                 S      g | ]}|d  qS rN   r   r    r   r   r   r   r"      r#   )torch
isinstancestrr   	Generatorr   seedr   encodetor   repeat_interleaverangezerosfloatr
   r   r   nextr   r(   r2   decodeStopIterationlistappend)r   rF   rG   rH   rI   r]   r   r   attention_masks
batch_size
fsm_statesfsmsweightsstates
last_stater   generated_token_idsr.   stripped	formattedoutputr;   r   rY   r   __call__   s    



zSequenceGenerator.__call__c              
      sF  ddl }t|tr|g}t|tr|g}|jj|\}}|j}||j}jt| |j	|dd}|j	|dd}dd t
  D }fddt
  D }	|j  |j|jd}
|du rw|j|jd}|  tjj|	||
|||d	d
tttt tttt  f  f fdd}| S )a  Generate the text sequence one token at a time.

        Since `Tokenizer.decode` strips the whitespaces from the tokens we have no
        choice but to decode the generated token ids at each step and compare the
        current decoded strings to the previously decoded strings.

        Parameters
        ----------
        prompts
            A string or list of strings that are passed to the model before
            generating the first token.
        max_tokens
            An integer representing maximum number of tokens that will be generated
            (per prompt)
        stop_at
            A string or list of strings at which the text generated will stop
        rng
            The random number generator. Defaults to a non-seeded `torch.Generator`
            instance.

        Returns
        -------
        A string or list of strings that contain the generated text.

        r   NrK   c                 S   rM   rN   r   rO   r   r   r   r"   /  rQ   z,SequenceGenerator.stream.<locals>.<listcomp>c                    rR   r   rS   rO   rT   r   r   r"   0  r7   rU   rJ   rW   r   c            	      3   st   dd t  D  } d}dd t  D  }	 r |ks$t|r&d S z
t}|d7 }W n
 ty:   Y d S w |jd d | d f }j|}rifddt||D }fddt||D }d	d t|| |D }|} t }t d  D ]}|	|||   q dkrdkr|d d V  n dkr|d V  ndkrd
d |D V  n|V  q)Nc                 S   rM   ) r   rO   r   r   r   r"   G  s    zESequenceGenerator.stream.<locals>.token_generator.<locals>.<listcomp>r   c                 S   rM   )Fr   rO   r   r   r   r"   K  rQ   TrZ   c                    s"   g | ]\}}|p  |gqS r   )r2   )r    generated_sequencestoprY   r   r   r"   Y  s    c                    s*   g | ]\}}|r   |n|qS r   )rD   r@   )r    r3   r{   rY   r   r   r"   c  s    
c                 S   s"   g | ]\}}}|t |d  qS r   r   )r    tokenr3   r{   r   r   r   r"   m  s    c                 S   r[   rN   r   r\   r   r   r   r"     r#   )
re   r1   rh   rj   r   r   ri   r&   rk   rl   )	previously_generated_sequencesnum_generatedis_stop_at_reachedr3   rt   r)   next_tokensrw   r;   rn   rG   r   r   rr   r*   r   r   token_generatorF  sf   

z1SequenceGenerator.stream.<locals>.token_generator)r]   r^   r_   r   r   rb   rc   r   r   rd   re   rf   rg   r`   ra   r
   r   r   r   r	   r   )r   rF   rG   rH   rI   r]   r   rm   ro   rp   rq   r   r   r   r   stream   sH    

6?zSequenceGenerator.streamNNN)__name__
__module____qualname__r   r   r(   r_   boolr2   r   r@   FormattedOutputrD   r	   intrx   r   r   r   r   r   r   r      sh    




yr   T)frozenc                   @   sB   e Zd ZU dZee ed< eeee	e f  ed< ee ed< dS )GenerationParametersz3Generation parameters used in Outlines' public API.rG   rH   ra   N)
r   r   r   __doc__r   r   __annotations__r	   r_   r   r   r   r   r   r     s
   
 r   c                   @   sV   e Zd ZU dZeed< dZeed< dZe	e
 ed< dZe	e ed< dZe	e
 ed< dS )	SamplingParametersz*Sampling parameters available in Outlines.r   rZ   r   Ntop_ptop_ktemperature)r   r   r   r   r_   r   r   r   r   r   rg   r   r   r   r   r   r   r     s   
 r   c                   @   s   e Zd ZdZdd Zdee deeee	e f  dee fddZ
d	ed
efddZdd Z			ddeee	e f dee deeee	e f  dee fddZ			ddeee	e f dee deeee	e f  dee fddZdS )SequenceGeneratorAdaptera!  Class used to unify the interface to the model providers'
    generation functions.

    Attributes
    ----------
    model
        The wrapped model.
    logits_processor
        The logits processor to use to generate text.
    sampler
        The sampler to use to generate text.

    c                 C   s|   || _ || _t|trtd|j|j|j|j| _	d S t|t
r+td|jd d d| _	d S t|tr<td|jd d d| _	d S d S )Nmultinomialgreedyg        beam_searchg      ?)r   logits_processorr^   r   r   r   r   r   r   sampling_paramsr   r   )r   r   r   r   r   r   r   r     s&   





z!SequenceGeneratorAdapter.__init__rG   rH   ra   c                 C   s    t |tr|g}t|||}|S r   )r^   r_   r   )r   rG   rH   ra   generation_paramsr   r   r   prepare_generation_parameters  s   
z6SequenceGeneratorAdapter.prepare_generation_parametersr3   r   c                 C   rA   rB   r   rC   r   r   r   rD     rE   z(SequenceGeneratorAdapter.format_sequencec                    s&   t |tr fdd|D S  |S )z1Apply formatting to every string in a completion.c                    r4   r   )_formatrX   rT   r   r   r"     r7   z4SequenceGeneratorAdapter._format.<locals>.<listcomp>)r^   rk   rD   )r   	sequencesr   rT   r   r     s   

z SequenceGeneratorAdapter._formatNrF   c                 K   s:   |  |||}| jj||t| j| jfi |}| |S )z/Generate text from a prompt of list of prompts.)r   r   generater   r   r   r   )r   rF   rG   rH   ra   model_specific_paramsr   completionsr   r   r   rx     s   

z!SequenceGeneratorAdapter.__call__c                 K   s0   |  |||}| jj||t| j| jfi |S z;Return a text generator from a prompt or a list of prompts.)r   r   r   r   r   r   )r   rF   rG   rH   ra   r   r   r   r   r   r     s   	zSequenceGeneratorAdapter.streamr   )r   r   r   r   r   r   r   r	   r_   r   r   r   rD   r   rx   r   r   r   r   r   r     sH    


r   c                   @   s
  e Zd Z			ddeeee f deeef dee deeeee f  dee f
ddZ				ddeeee f deeeeeeeef  f  dee deeeee f  dee f
d	d
Z
edeeee f deeeeeeef  f deeee f fddZdS )VisionSequenceGeneratorAdapterNrF   mediarG   rH   ra   c           	      K   sL   |  ||\}}| |||}| jj|||t| j| jfi |}| |S )z
        Generate text from a prompt of list of prompts.

        Media: A URI to construct media or media object itself. Used as AutoProcessor argument.
        )_validate_prompt_media_typesr   r   r   r   r   r   r   )	r   rF   r   rG   rH   ra   r   r   r   r   r   r   rx     s   
	z'VisionSequenceGeneratorAdapter.__call__c                 K   sB   |  ||\}}| |||}| jj|||t| j| jfi |S r   )r   r   r   r   r   r   r   )r   rF   r   rG   rH   ra   r   r   r   r   r   r   7  s   
z%VisionSequenceGeneratorAdapter.streamr   c                 C   s.   dd }|||st d| d| ||fS )zi
        Prepare media as PIL.Image and ensure for every prompt str there is one List[PIL.Image]
        c                    s   ddl m  t| tr9t|trt| t|krdS t| |D ]\}}t|tr3t fdd|D s6 dS qdS t| trKt fdd|D sKdS dS )Nr   ImageFc                 3       | ]	}t | jV  qd S r   r^   r   r    mr   r   r   	<genexpr>_  s    
zcVisionSequenceGeneratorAdapter._validate_prompt_media_types.<locals>.valid_types.<locals>.<genexpr>c                 3   r   r   r   r   r   r   r   r   d  s    T)PILr   r^   rk   r   r&   r_   r1   )rF   r   	subpromptsubmediar   r   r   valid_typesX  s   

zPVisionSequenceGeneratorAdapter._validate_prompt_media_types.<locals>.valid_typeszsExpected (prompts, media) to be of type (str, List[Image])), or (List[str], List[List[Image]]) instead got prompts=z, media=)	TypeError)clsrF   r   r   r   r   r   r   N  s   

z;VisionSequenceGeneratorAdapter._validate_prompt_media_typesr   )r   r   r   r	   r_   r   r   r   r   rx   r   classmethodr   r   r   r   r   r     sJ    

#
r   )datetimer   dataclassesr   typingr   r   r   r   r   r	   outlines.generate.generatorr
   outlines.samplersr   r   r   r]   r_   r   rg   r   datetimer   r   r   r   r   r   r   r   r   r   <module>   s(       y
{