U
    h0                     @  s   d dl mZ d dl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 d dlmZ d dlmZmZ d d	lmZmZ d d
lmZ eeZG dd deZdS )    )annotationsN)Path)AnyDictIteratorListOptionalUnion)CallbackManagerForLLMRun)LLM)GenerationChunk)Fieldroot_validator)get_pydantic_field_namespre_init)build_extra_kwargsc                   @  s  e Zd ZU dZded< ded< dZded< dZded	< ed
ddZded< edddZ	ded< edddZ
ded< edddZded< edddZded< edddZded< edddZded< edddZded< edddZded< edddZded< edZded< dZded< d Zd!ed"< d#Zd!ed$< edZded%< dZd&ed'< g Zd(ed)< d*Zd!ed+< d,Zded-< d.Zded/< dZd&ed0< d1Zd2ed3< d4Zd2ed5< eed6Z d7ed8< dZ!ded9< dZ"d:ed;< dZ#d<ed=< dZ$ded>< e%d?d?d@dAdBZ&e'ddCd7d7d@dDdEZ(e)d7dFdGdHZ*e)d7dFdIdJZ+e)ddFdKdLZ,dZd(d7dMdNdOZ-d[dd(dPdddQdRdSZ.d\dd(dPddTdQdUdVZ/dddWdXdYZ0dS )]LlamaCppa  llama.cpp model.

    To use, you should have the llama-cpp-python library installed, and provide the
    path to the Llama model as a named parameter to the constructor.
    Check out: https://github.com/abetlen/llama-cpp-python

    Example:
        .. code-block:: python

            from langchain_community.llms import LlamaCpp
            llm = LlamaCpp(model_path="/path/to/llama/model")
    r   clientstr
model_pathNzOptional[str]	lora_base	lora_pathi   n_ctx)aliasintn_partsseedTf16_kvboolF
logits_all
vocab_only	use_mlock	n_threadszOptional[int]   n_batchn_gpu_layerssuffix   
max_tokensg?zOptional[float]temperaturegffffff?top_plogprobszOptional[bool]echozOptional[List[str]]stopg?repeat_penalty(   top_k@   last_n_tokens_sizeuse_mmapg      ?floatrope_freq_scaleg     @rope_freq_base)default_factoryzDict[str, Any]model_kwargs	streamingzOptional[Union[str, Path]]grammar_pathzOptional[Union[str, Any]]grammarverboser   )valuesreturnc           
        sd  zddl m}m} W n tk
r0   tdY nX  d }ddddd	d
ddddddddddg} fdd|D } d dk	r d |d< | d  z||f| d< W n6 tk
r } ztd| d| W 5 d}~X Y nX  d r d r d } d }	td|d |	d!nBt d trB|	 d  d< n d r`|
 d  d< n  S )"z4Validate that llama-cpp-python library is installed.r   )LlamaLlamaGrammarzCould not import llama-cpp-python library. Please install the llama-cpp-python library to use this embedding model: pip install llama-cpp-pythonr   r6   r7   r   r   r   r   r   r   r    r!   r"   r#   r%   r4   r3   r=   c                   s   i | ]}| | qS  rB   ).0kr>   rB   E/tmp/pip-unpacked-wheel-9gdii04g/langchain_community/llms/llamacpp.py
<dictcomp>   s      z1LlamaCpp.validate_environment.<locals>.<dictcomp>r&   Nr9   r   z&Could not load Llama model from path: z. Received error r<   r;   zCCan only pass in one of grammar and grammar_path. Received grammar=z and grammar_path=.)Z	llama_cppr@   rA   ImportErrorupdate	Exception
ValueError
isinstancer   Zfrom_string	from_file)
clsr>   r@   rA   r   Zmodel_param_namesZmodel_paramser<   r;   rB   rE   rF   validate_environment   sZ    

zLlamaCpp.validate_environment)prec                 C  s(   t | }|di }t||||d< |S )z>Build extra kwargs from additional params that were passed in.r9   )r   getr   )rO   r>   Zall_required_field_namesextrarB   rB   rF   build_model_kwargs   s      zLlamaCpp.build_model_kwargs)r?   c              
   C  s>   | j | j| j| j| j| j| j| j| jd	}| j	r:| j	|d< |S )z1Get the default parameters for calling llama_cpp.)	r'   r)   r*   r+   r,   r-   stop_sequencesr/   r1   r<   )
r'   r)   r*   r+   r,   r-   r.   r/   r1   r<   )selfparamsrB   rB   rF   _default_params   s    
zLlamaCpp._default_paramsc                 C  s   d| j i| jS )zGet the identifying parameters.r   )r   rY   rW   rB   rB   rF   _identifying_params   s    zLlamaCpp._identifying_paramsc                 C  s   dS )zReturn type of llm.ZllamacpprB   rZ   rB   rB   rF   	_llm_type   s    zLlamaCpp._llm_type)r.   r?   c                 C  s<   | j r|dk	rtd| j}|d | j p2|p2g |d< |S )a  
        Performs sanity check, preparing parameters in format needed by llama_cpp.

        Args:
            stop (Optional[List[str]]): List of stop sequences for llama_cpp.

        Returns:
            Dictionary containing the combined parameters.
        Nz2`stop` found in both the input and default params.rV   r.   )r.   rL   rY   pop)rW   r.   rX   rB   rB   rF   _get_parameters   s    
zLlamaCpp._get_parametersz"Optional[CallbackManagerForLLMRun])promptr.   run_managerkwargsr?   c           	      K  sp   | j r6d}| jf |||d|D ]}||j7 }q"|S | |}||}| jf d|i|}|d d d S dS )a  Call the Llama model and return the output.

        Args:
            prompt: The prompt to use for generation.
            stop: A list of strings to stop generation when encountered.

        Returns:
            The generated text.

        Example:
            .. code-block:: python

                from langchain_community.llms import LlamaCpp
                llm = LlamaCpp(model_path="/path/to/local/llama/model.bin")
                llm.invoke("This is a prompt.")
         )r_   r.   r`   r_   choicesr   textN)r:   _streamrd   r^   r   )	rW   r_   r.   r`   ra   Zcombined_text_outputchunkrX   resultrB   rB   rF   _call  s    

zLlamaCpp._callzIterator[GenerationChunk]c           
      k  s   |  ||}| jf |dd|}|D ]R}|d d dd}t|d d d d|id}	|rt|j|	j| j|d	 |	V  q(dS )
a\  Yields results objects as they are generated in real time.

        It also calls the callback manager's on_llm_new_token event with
        similar parameters to the OpenAI LLM class method of the same name.

        Args:
            prompt: The prompts to pass into the model.
            stop: Optional list of stop words to use when generating.

        Returns:
            A generator representing the stream of tokens being generated.

        Yields:
            A dictionary like objects containing a string token and metadata.
            See llama-cpp-python docs and below for more.

        Example:
            .. code-block:: python

                from langchain_community.llms import LlamaCpp
                llm = LlamaCpp(
                    model_path="/path/to/local/model.bin",
                    temperature = 0.5
                )
                for chunk in llm.stream("Ask 'Hi, how are you?' like a pirate:'",
                        stop=["'","
"]):
                    result = chunk["choices"][0]
                    print(result["text"], end='', flush=True)  # noqa: T201

        T)r_   streamrc   r   r,   Nrd   )rd   Zgeneration_info)tokenr=   Z	log_probs)r^   r   rS   r   Zon_llm_new_tokenrd   r=   )
rW   r_   r.   r`   ra   rX   rg   partr,   rf   rB   rB   rF   re   .  s    %  zLlamaCpp._stream)rd   r?   c                 C  s   | j |d}t|S )Nzutf-8)r   tokenizeencodelen)rW   rd   Ztokenized_textrB   rB   rF   get_num_tokensa  s    zLlamaCpp.get_num_tokens)N)NN)NN)1__name__
__module____qualname____doc____annotations__r   r   r   r   r   r   r   r    r!   r"   r#   r%   r&   r'   r)   r*   r+   r,   r-   r.   r/   r1   r3   r4   r6   r7   dictr9   r:   r;   r<   r=   r   rQ   r   rU   propertyrY   r[   r\   r^   rh   re   ro   rB   rB   rB   rF   r      sf   
<	  -  3r   )
__future__r   loggingpathlibr   typingr   r   r   r   r   r	   Zlangchain_core.callbacksr
   Z#langchain_core.language_models.llmsr   Zlangchain_core.outputsr   Zlangchain_core.pydantic_v1r   r   Zlangchain_core.utilsr   r   Zlangchain_core.utils.utilsr   	getLoggerrp   loggerr   rB   rB   rB   rF   <module>   s    
