
    (HJjX2                        d dl Z d dlmZ d dlmZmZmZmZ d dlm	Z
 ddddd ddg fdededed	ed
edededee   dee
j                  ge
j                  f   fdZ	 	 	 	 	 	 	 d%deeeef      dee   dee   dee   dee   dee   dee   fdZ ee
j                   e
j"                  j$                  e
j"                  j$                        de
j                  d
ede
j                  fd       Z ee
j                   e
j"                  j$                  e
j"                  j$                        	 d&de
j                  ded	ede
j                  fd       Z ee
j                   e
j"                  j$                  e
j"                  j$                        de
j                  dede
j                  fd       Z ee
j                   e
j"                  j$                  e
j"                  j$                        de
j                  dededee   de
j                  f
d       Z ee
j                   e
j"                  j$                  e
j"                  j$                        d        Zd'd ed!efd"Zd'd ed!efd#Zd'd ed!efd$Zy)(    N)partial)CallableDictListOptional           temptop_pmin_pmin_tokens_to_keeptop_kxtc_probabilityxtc_thresholdxtc_special_tokensreturnc                    	  dk(  rd S g 	dkD  rdk  r	j                  fd       dk7  r	j                  fd       dkD  r	j                  fd       dkD  r	j                  fd       	 fd	}|S )
an  
    Make a sampler function for use with ``generate_step``.

    Args:
        temp (float): The temperature for sampling, if 0 the argmax is used.
          Default: ``0``.
        top_p (float, optional): Nulceus sampling, higher means model considers
          more less likely words.
        min_p (float, optional): The minimum value (scaled by the top token's
          probability) that a token probability must have to be considered.
        min_tokens_to_keep (int, optional): Minimum number of tokens that cannot
          be filtered by min_p sampling.
        top_k (int, optional): The top k tokens ranked by probability to constrain
          the sampling to.
        xtc_probability (float, optional): The probability of applying XTC
            sampling.
        xtc_threshold (float, optional): The threshold the probs need to reach
            for being sampled.
        xtc_special_tokens (list(int), optional): List of special tokens IDs to
            be excluded from XTC sampling.


    Returns:
        Callable[mx.array, mx.array]:
            A sampler which takes log-probabilities and returns tokens.
    r   c                 0    t        j                  | d      S )Naxis)mxargmax)xs    ]/Users/ahmed/devFolder/claude-voice/.venv/lib/python3.12/site-packages/mlx_lm/sample_utils.py<lambda>zmake_sampler.<locals>.<lambda>/   s    12.          ?c                     t        |       S N)apply_top_p)r   r   s    r   r   zmake_sampler.<locals>.<lambda>4       +a*?r   r   c                     t        |       S r    )apply_min_p)r   r   r   s    r   r   zmake_sampler.<locals>.<lambda>6   s    +a@R*Sr   c                      t        |       S r    )	apply_xtc)r   r   r   r   s    r   r   zmake_sampler.<locals>.<lambda>9   s    i?MCUVr   c                     t        |       S r    )apply_top_k)r   r   s    r   r   zmake_sampler.<locals>.<lambda><   r"   r   c                 :    D ]
  } ||       }  t        |       S r    )categorical_sampling)logprobsmethodsampling_methodsr
   s     r   samplerzmake_sampler.<locals>.sampler?   s&    &Fh'H ' $Hd33r   )append)
r
   r   r   r   r   r   r   r   r.   r-   s
   ```````` @r   make_samplerr0   
   s    H qy.. qyUS[ ?@| STV	
 qy ?@4 Nr   
logit_biasrepetition_penaltyrepetition_context_sizepresence_penaltypresence_context_sizefrequency_penaltyfrequency_context_sizec                 |   g }| rot        j                  t        | j                                     t        j                  t        | j	                                     fd}|j                  |       t        ||ft        ||ft        ||fg}	|	D ]'  \  }
}}|
|dk7  s|j                   |
||             ) |S )a  
    Make logits processors for use with ``generate_step``.

    Args:
        repetition_penalty (float, optional): A (sign-aware) multiplicative
          penalty for repeating tokens.
        repetition_context_size (int, optional): The number of tokens to
          consider for repetition penalty. Default: ``20``.
        presence_penalty (float, optional): An additive penalty to reduce
          repeating tokens.
        presence_context_size (int, optional): The number of tokens to consider
          for the presence penalty. Default: ``20``.
        frequency_penalty (float, optional): An additive penalty to reduce
          repeating tokens. The tokens are penalized proportionally to their
          frequency.
        frequency_context_size (int, optional): The number of tokens to consider
          for the frequency penalty. Default: ``20``.
        logit_bias (dictionary, optional): Additive logit bias.

    Returns:
        List[Callable[[mx.array, mx.array], mx.array]]:
            A list of logits processors. Each processor in the list is a
            callable which takes an array of tokens and an array of logits
            and returns the updated logits.
    c                 H    |j                   d d f   j                        S r    )atadd)_logitsindicesvaluess     r   logit_bias_processorz4make_logits_processors.<locals>.logit_bias_processoro   s!    99QZ(,,V44r   r   )	r   arraylistkeysr?   r/   make_repetition_penaltymake_presence_penaltymake_frequency_penalty)r1   r2   r3   r4   r5   r6   r7   logits_processorsr@   repetition_penaltiesmake_penaltypenaltycontext_sizer>   r?   s                @@r   make_logits_processorsrL   H   s    D ((4
 123$z00234	5 	  !56 
!"46MN	 02GH	!24JK 0D+g|7a<$$\'<%HI 0D r   )inputsoutputsr+   c           	      J   | j                   d   }t        |t              rd|cxk  r|k  sn t        d| d| d      t	        j
                  |  |dz
  d      d|d	f   }t	        j                  | |t	        j                  t        d
       | j                        d      }|S )z
    Sample from only the top K tokens ranked by probability.

    Args:
        logprobs: A vector of log probabilities.
        top_k (int): Top k tokens to sample from.
    r   r   z(`top_k` has to be an integer in the (0, z] interval, but is .r	   kthr   .Ninfr   )
shape
isinstanceint
ValueErrorr   argpartitionput_along_axisrA   floatdtype)r+   r   
vocab_sizemask_idxmasked_logprobss        r   r(   r(      s     #JeS!!e*@j*@6zl CgQ 
 	
 yeaibA#uv+NH''(BHHeEl]HNNC"O r   c                    d|cxk  rdk  sn t        d|       t        |t              r|dk  rt        d|       t        j                  | dd      }|t        j                  |      z   }| |k  }|dkD  r<t        j                  | | d	      }|d
| df   }t        j                  ||dd      }t        j                  |t        d       |       S )ag  
    Apply min-p sampling to the logprobs.

    Min-p keeps all tokens that are above a minimum probability, scaled by the
    probability of the most likely token. As a result, the filter is more
    aggressive given a very high-probability token.

    Args:
        logprobs: A vector of log probabilities.
        min_p (float): Minimum token probability. Typical values are in the
            0.01-0.2 range, comparably selective as setting `top_p` in the
            0.99-0.8 range.
        min_tokens_to_keep (int, optional): Minimum number of tokens that cannot
            be filtered. Default: ``1``.

    r   r   z9`min_p` has to be a float in the [0, 1] interval, but is r	   z:`min_tokens_to_keep` has to be a positive integer, but is r   T)r   keepdimsrQ   .NFr   rS   )rW   rU   rV   r   maxmathlogrX   rY   whererZ   )r+   r   r   top_logprobsscaled_min_ptokens_to_removetop_indicess          r   r$   r$      s    , #GwO
 	
 (#.3E3IHI[H\]
 	

 66(d;L$((5/1L,. Aooh5G4GbQ!#(:':';";<,,	
 88$uU|mX>>r   c                    t        j                  |       }t        j                  | d      }t        j                  ||d      }t        j                  |d      }t        j
                  t        j                  |      |t        j                  |j                  d   |j                        d      }t        j                  ||d      }t        j                  |d|z
  kD  | t        d             S )z
    Apply top-p (nucleus) sampling to logits.

    Args:
        logprobs: A vector of log probabilities.
        top_p: The cumulative probability threshold for top-p filtering.
    Returns:
        token selected based on the top-p criterion.
    r   r   )r[   r	   rS   )r   expargsorttake_along_axiscumsumrY   
zeros_likearangerT   r[   rd   rZ   )r+   r   probssorted_indicessorted_probscumulative_probsinverse_indicess          r   r!   r!      s     FF8EZZr2N%%e^"ELyyB7 ''
n%
		.&&r*.2F2FG	O ))*:ORTU 881u9$	u r   r=   c           	         d|cxk  rdk  sn t        d|       d|cxk  rdk  sn t        d|       t        j                  | d      }|t        j                  ||kD  |t        j                        j                         kD  }|rd|d|f<   t        j                  t        j                  j                  dd	      |kD  | t        j                  |t        j                   |             S )
a}  
    Apply XTC sampling to the logits.

    Args:
        logits: The logits from the model's output.
        xtc_probability (float): Probability of XTC sampling to happen for each token
        xtc_threshold (float): The threshold the probs need to reach for being sampled.
        special_tokens_ids (list(int)): List of special tokens IDs to be excluded from XTC sampling.
    r   g      ?z?`threshold` has to be a float in the [0, 0.5] interval, but is r   z?`probability` has to be a float in the [0, 1] interval, but is r   F.r	   )rW   r   softmaxrd   rS   minrandomuniform)r=   r   r   r   rp   masks         r   r&   r&      s      %#%Mm_]
 	
 'C'MoM^_
 	
 JJvr"E288EM15"&&AEEGGD(-S$$%88
		!Q/1
w' r   c                 L    t         j                  j                  | d|z  z        S )Nr	   )r   rx   categorical)r=   r
   s     r   r*   r*     s     99  1t8!455r   rJ   rK   c                 h      dk  st         t        t        f      st        d         fd}|S )ax  
    Make repetition penalty processor.

    Paper: https://arxiv.org/abs/1909.05858

    Args:
        penalty (float): The repetition penalty factor to be applied.
        context_size (int): The number of previous tokens to use.
            Default: ``20``.

    Returns:
        Callable[[mx.array, List[int]], mx.array]:
            The repetition penalty processor.
    r   z*penalty must be a non-negative float, got c                     t        |       dkD  r8|  d  } |d d | f   }t        j                  |dk  |z  |z        }||d d | f<   |S Nr   )lenr   rd   )tokensr=   selected_logitsrK   rJ   s      r   repetition_penalty_processorz=make_repetition_penalty.<locals>.repetition_penalty_processor,  se    v;?\MN+F$QY/O hh!#')')O
 !0F1f9r   )rU   rV   rZ   rW   )rJ   rK   r   s   `` r   rD   rD     s9     {*WsEl;EgYOPP
 ('r   c                       fd}|S )a  
    Make a presence penalty processor.

    Corresponds to the OpenAI option with the same name. Namely, subtracts
    ``penalty`` from a logit if the token has occured at least once in the
    ``context_size`` previous tokens.

    Args:
        penalty (float): The presence penalty to be applied.
        context_size (int): The number of previous tokens to use.
            Default: ``20``.

    Returns:
        Callable[[mx.array, List[int]], mx.array]
    c                 R    t        |       dkD  r|  d  } |d d | fxx   z  cc<   |S r   )r   r   r=   rK   rJ   s     r   presence_penalty_processorz9make_presence_penalty.<locals>.presence_penalty_processorL  s5    v;?\MN+F1f9(r    )rJ   rK   r   s   `` r   rE   rE   ;  s    " &%r   c                       fd}|S )aL  
    Make a frequency penalty processor.

    Corresponds to the OpenAI option with the same name. Namely, subtracts
    ``penalty`` from a logit for every time that the token has occured in the
    ``context_size`` previous tokens.

    The difference with the presence penalty is that the more often a token
    occurs the more it will be penalized.

    Args:
        penalty (float): The frequency penalty to be applied.
        context_size (int): The number of previous tokens to use.
            Default: ``20``.

    Returns:
        Callable[[mx.array, List[int]], mx.array]
    c                 t    t        |       dkD  r(|  d  } |j                  d d | f   j                        }|S r   )r   r:   subtractr   s     r   frequency_penalty_processorz;make_frequency_penalty.<locals>.frequency_penalty_processori  s>    v;?\MN+FYYq&y)227;Fr   r   )rJ   rK   r   s   `` r   rF   rF   U  s    ( '&r   )NN   Nr   Nr   )r	   )r   )rb   	functoolsr   typingr   r   r   r   mlx.corecorer   rZ   rV   rA   r0   rL   compilerx   stater(   r$   r!   r&   r*   rD   rE   rF   r   r   r   <module>r      s
     1 1   $&;
;; ; 	;
 ; ; ; S	; rxxj"(("#;~ .2*.-/(,+-)-,.6c5j)*6 6 &c]6 uo	6
 $C=6  6 %SM6r 	BIIOORYY__Ehh XX F0 	BIIOORYY__E  .?hh.?.? .? XX	.? F.?b 	BIIOORYY__E "((  5  RXX   F F 	BIIOORYY__E!HH!! ! S		!
 XX! F!H 	BIIOORYY__E6 F6(U (# (B&5 & &4'E ' 'r   