o
    پi)                     @   s   d dl Z d dlmZmZmZmZmZ erd dlZG dd deZG dd dZ	e	Z
G dd dZeZd	ed
edgdf fddZded
edgdf fddZded
edgdf fddZG dd dZeZdS )    N)TYPE_CHECKINGCallableOptionalProtocolTuplec                   @   s0   e Zd ZU eed< 								ddd	Zd
S )Samplersamplesnext_token_logitstorch.DoubleTensorsequence_weightsrngtorch.Generatorreturnc                 C   s   d S N )selfr	   r   r   r   r   E/home/ubuntu/.local/lib/python3.10/site-packages/outlines/samplers.py__call__   s   zSampler.__call__N)r	   r
   r   r
   r   r   r   r
   )__name__
__module____qualname__int__annotations__r   r   r   r   r   r      s   
 r   c                   @   s.   e Zd ZdZdd Z						ddd	Zd
S )GreedySamplera  Greedy Sampling algorithm.

    Greedy sampling consists in choosing the token with the largest
    likelihood at every step.

    We don't allow more than one sample. We could attribute this a meaning, for
    instance the k-th sample represents the k-th most likely token. In which
    case it would be equivalent to beam search without the sequence weights.

    Attributes
    ----------
    samples
        The number of samples taken for each input sequence.

    c                 C   s
   d| _ d S )N   r   )r   r   r   r   __init__%      
zGreedySampler.__init__r	   r
   r   r   c           	      C   s`   ddl }|jjj|dd}|j|ddd}|j|jd |jd}|||d|	  }|||fS )	a  Call the greedy sampler.

        Parameters
        ----------
        next_token_logits
            A tensor of shape ``(n_seqs, vocab_size,)`` that represents the
            probability distribution of the next token over the vocabulary.
        sequence_weights
            A tensor of shape ``(n_seqs,)`` that represents the cumulative
            weight of each sequence.
        rng
            A random number generator.

        Returns
        -------
        A tuple with an array that contains the ids of the sampled tokens of
        shape ``(n_seqs, 1)``, an array that contains the ancestors of each
        sampled id of shape ``(n_seqs,)`` and an array that contains the updated
        cumulative weights of each sequence of shape ``(n_seqs,)``.

        r   NdimT)r    keepdimdevicer   )
torchnn
functionallog_softmaxargmaxarangeshaper#   gathersqueeze)	r   r	   r   _r$   logprobsnext_token_ids	ancestorsweightsr   r   r   r   (   s   
zGreedySampler.__call__N)r	   r
   r   r
   r   r
   )r   r   r   __doc__r   r   r   r   r   r   r      s    r   c                   @   sb   e Zd ZdZ	ddddddedee dee dee fd	d
Zddddddded fddZ	dS )MultinomialSamplera<  Multinomial sampling algorithm.

    Multinomial sampling consists in randomly sampling the next token assuming
    its distribution is a Categorical distribution parametrized by the
    next-token logits.


    Attributes
    ----------
    samples
        The number of samples taken for each input sequence.

    r   N)top_ktop_ptemperaturer   r4   r5   r6   c                C   sp   || _ || _|| _|| _g | _|d ur| jt| n|d ur(| jt| |d ur6| jt| d S d S r   )	r   r4   r5   r6   logits_processorsappendkeep_top_k_logitskeep_top_p_logitsrescale_logits)r   r   r4   r5   r6   r   r   r   r   b   s   zMultinomialSampler.__init__r	   r
   r   r   r   r   r
   r
   r
   c                 C   s   ddl }|}| jD ]}||}q	|jjj|dd}|j|d|d}|jjj|dd}	|j|jd |j	d}
||
|	d|  }||
|fS )a  Call the multinomial sampler.

        Parameters
        ----------
        next_token_logits
            A tensor of shape ``(n_seqs, vocab_size,)`` that represents the
            probability distribution of the next token over the vocabulary.
        sequence_weights
            A tensor of shape ``(n_seqs,)`` that represents the cumulative
            weight of each sequence.
        rng
            A random number generator.

        Returns
        -------
        A tuple with an array that contains the ids of the sampled tokens of
        shape ``(n_seqs, 1)``, an array that contains the ancestors of each
        sampled id of shape ``(n_seqs,)`` and an array that contains the updated
        cumulative weights of each sequence of shape ``(n_seqs,)``.

        r   Nr   r   r   )num_samples	generatorr"   )r$   r7   r%   r&   softmaxmultinomialr'   r)   r*   r#   r+   r,   )r   r	   r   r   r$   altered_next_token_logitslogit_processorprobsr/   r.   r0   r1   r   r   r   r   x   s   


zMultinomialSampler.__call__r   )
r   r   r   r2   r   r   floatr   r   r   r   r   r   r   r3   S   s2    
r3   kr   torch.Tensorc                    sJ   ddl t tr dk rtd  ddjdjf fdd	}|S )
zBuild a function that masks logits values smaller than the top `k` ones.

    Parameters
    ----------
    k
        The ranking below which logit values are replaced by `-math.inf`.

    r   Nr   z.`k` must be a strictly positive integers, got 	 instead.logitsr   c                    s8   t  | d}| | |d d k }| |tj S )Nr   r   ).r   N)minsizetopkmasked_fillmathinf)rI   num_to_keepmask_idxrF   r$   r   r   logits_processor   s   z+keep_top_k_logits.<locals>.logits_processor)r$   
isinstancer   
ValueErrorTensor)rF   rS   r   rR   r   r9      s
   	r9   pc                    sH   ddl  dks dkrtd  ddjdjf fd	d
}|S )a  Build a function that masks the lowest probability tokens whose
    cumulative probability is below a certain threshold.

    Parameters
    ----------
    p
        The value of the threshold. We keep the highest probability tokens whose
        cumulative distribution is greater than or equal to `p` and mask the
        others. Its value must be between 0 (excluded) and 1 (included).

    r   N        g      ?zO`p` must be a floating point number between 0 (excluded) and 1 (included), got rH   rI   r   c                    sX   j | dd\}}jjj|ddjdd}|d  k}|d||}| |tj S )NF)
descendingr   r   r   )	sortr%   r&   r?   cumsumscatterrM   rN   rO   )rI   sorted_logits
sorted_idxcumulative_probabiltiessorted_masked_idxrQ   rW   r$   r   r   rS      s   z+keep_top_p_logits.<locals>.logits_processor)r$   rU   rV   )rW   rS   r   ra   r   r:      s   

r:   r6   c                    sD   t  tr	 dk rtd  d dkrtdd fdd	}|S )zBuild a function that rescales the token probabilities exponentially.

    Parameters
    ----------
    temperature
        The value by which we rescale the logits.

    rX   zE`temperature` must be a strictly positive floating point number, got rH   zFPlease use the greedy sampler instead of setting the temperature to 0.rI   rG   r   c                    s   |   S r   r   )rI   r6   r   r   rS      s   z(rescale_logits.<locals>.logits_processorN)rI   rG   r   rG   )rT   rE   rU   )r6   rS   r   rb   r   r;      s   

r;   c                   @   s:   e Zd ZdZddefddZddddd	ed
 fddZdS )BeamSearchSamplerzBeam Search sampling algorithm.

    Attributes
    ----------
    samples
        The number of samples taken for each input sequence. Equivalent to the
        number of beams.
    r   beamsc                 C   s
   || _ d S r   r   )r   rd   r   r   r   r     r   zBeamSearchSampler.__init__r	   r
   r   r   r<   c                 C   s  ddl }|jjj|dd}||d| }|jd | j }|jd }||| j| }|	|dkr>|ddd|f }|j
|| jdddd\}}	|j|	|dd	}
|	| }|jd|| j | j|jd
d}|
| }
|
| j| }
|| j| }|| j| d}||
|fS )a  Call the beam search sampler.

        Parameters
        ----------
        next_token_logits
            A tensor of shape ``(n_seqs, vocab_size,)`` that represents the
            probability distribution of the next token over the vocabulary.
        sequence_weights
            A tensor of shape ``(n_seqs,)`` that represents the cumulative
            weight of each sequence.
        rng
            A random number generator.

        Returns
        -------
        A tuple with an array that contains the ids of the sampled tokens of
        shape ``(n_seqs, 1)``, an array that contains the ancestors of each
        sampled id of shape ``(n_seqs,)`` and an array that contains the updated
        cumulative weights of each sequence of shape ``(n_seqs,)``.

        r   Nr   r   r   T)r    largestsortedfloor)rounding_moder"   )r$   r%   r&   r'   	unsqueeze	expand_asr*   r   viewallrL   divr)   r#   )r   r	   r   r-   r$   r.   r1   
batch_size
vocab_sizeindicesr0   r/   first_batch_idxr   r   r   r     s.   


zBeamSearchSampler.__call__NrD   )r   r   r   r2   r   r   r   r   r   r   r   r   rc      s    	rc   )rN   typingr   r   r   r   r   r$   r   r   greedyr3   r@   r   r9   rE   r:   r;   rc   beam_searchr   r   r   r   <module>   s    <R M