o
    Zh                     @   sz   d 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 G dd	 d	eeZd
S )zRWKV models.

Based on https://github.com/saharNooby/rwkv.cpp/blob/master/rwkv/chat_with_bot.py
         https://github.com/BlinkDL/ChatRWKV/blob/main/v2/chat.py
    )AnyDictListMappingOptionalSet)CallbackManagerForLLMRun)LLM)pre_init)	BaseModel
ConfigDict)enforce_stop_tokensc                   @   s  e Zd ZU dZeed< 	 eed< 	 dZeed< 	 dZeed< 	 dZ	e
ed	< 	 d
Ze
ed< 	 dZe
ed< 	 dZe
ed< 	 dZeed< 	 dZeed< 	 dZeed< dZeed< dZeed< dZeed< dZeed< eddZedeeef fddZedee fddZededefd d!Z ede!eef fd"d#Z"edefd$d%Z#d3d'e$e d(edefd)d*Z%d+edefd,d-Z&		d4d+ed.e'e$e  d/e'e( d0edef
d1d2Z)dS )5RWKVa  RWKV language models.

    To use, you should have the ``rwkv`` python package installed, the
    pre-trained model file, and the model's config information.

    Example:
        .. code-block:: python

            from langchain_community.llms import RWKV
            model = RWKV(model="./models/rwkv-3b-fp16.bin", strategy="cpu fp32")

            # Simplest invocation
            response = model.invoke("Once upon a time, ")
    modeltokens_pathzcpu fp32strategyTrwkv_verboseg      ?temperatureg      ?top_pg?penalty_alpha_frequencypenalty_alpha_presence   	CHUNK_LENmax_tokens_per_generationNclient	tokenizerpipelinemodel_tokensmodel_stateZforbid)extrareturnc                 C   s"   | j | j| j| j| j| j| jdS )Get the identifying parameters.verboser   r   r   r   r   r   r"   self r&   T/var/www/html/lang_env/lib/python3.10/site-packages/langchain_community/llms/rwkv.py_default_paramsQ   s   zRWKV._default_paramsc                   C   s   dhS )r!   r#   r&   r&   r&   r&   r'   _rwkv_param_names^   s   zRWKV._rwkv_param_namesvaluesc                    s   zddl }W n ty   tdw zIddlm} ddlm} |j|d |d< |    fdd	|	 D }|d
 |d< ||d fd|d i||d< ||d |d |d< W |S  tyf   tdw )z;Validate that the python package exists in the environment.r   Nz\Could not import tokenizers python package. Please install it with `pip install tokenizers`.)r   )PIPELINEr   r   c                    s   i | ]\}}| v r||qS r&   r&   .0kvZ	rwkv_keysr&   r'   
<dictcomp>v   s    z-RWKV.validate_environment.<locals>.<dictcomp>r   r#   r   r   r   r   zPCould not import rwkv python package. Please install it with `pip install rwkv`.)

tokenizersImportErrorZ
rwkv.modelr   Z
rwkv.utilsr+   	Tokenizer	from_filer)   items)clsr*   r2   Z	RWKVMODELr+   Zmodel_kwargsr&   r0   r'   validate_environmente   s8   
zRWKV.validate_environmentc                 C   s$   d| j i| jdd | j D S )r!   r   c                 S   s"   i | ]\}}|t  v r||qS r&   )r   r)   r,   r&   r&   r'   r1      s   " z,RWKV._identifying_params.<locals>.<dictcomp>)r   r(   __dict__r6   r$   r&   r&   r'   _identifying_params   s   zRWKV._identifying_paramsc                 C   s   dS )zReturn the type of llm.Zrwkvr&   r$   r&   r&   r'   	_llm_type   s   zRWKV._llm_typer   _tokensnewline_adjc           
      C   s   g }d}|D ]}| j |}t|dksJ ||7 }qdd |D }|  j|7  _d }t|dkrN| j|d | j | j\}| _|| jd  }t|dks1d}	||	  |7  < | jd |v rfd|| jd < |S )	Nu   ，：？！   c                 S   s   g | ]}t |qS r&   )int)r-   xr&   r&   r'   
<listcomp>   s    z RWKV.run_rnn.<locals>.<listcomp>r      i6e)r   encodelenr   r   forwardr   r   )
r%   r<   r=   ZAVOID_REPEAT_TOKENSZAVOID_REPEATiddtokensoutZEND_OF_LINEr&   r&   r'   run_rnn   s(   

zRWKV.run_rnnpromptc                 C   s  d | _ g | _| | j|j}t| j}|}i }d}t| jD ]e}|D ]}||  | j	|| | j
  8  < q$| jj|| j| jd}	d}
|	|
krK |S |	|vrTd||	< n||	  d7  < | |	g}| j| j|d  }d|vr||7 }|| d }|| jd kr |S q |S )N )r   r   r   r>   u   �d   )r   r   rK   r   rD   ZidsrE   ranger   r   r   r   Zsample_logitsr   r   decode)r%   rL   ZlogitsbeginZout_lastZ
occurrencedecodedrG   ntokenZEND_OF_TEXTZxxxr&   r&   r'   rwkv_generate   sD   


 zRWKV.rwkv_generatestoprun_managerkwargsc                 K   s    |  |}|durt||}|S )a  RWKV generation

        Args:
            prompt: The prompt to pass into the model.
            stop: A list of strings to stop generation when encountered.

        Returns:
            The string generated by the model.

        Example:
            .. code-block:: python

                prompt = "Once upon a time, "
                response = model.invoke(prompt, n_predict=55)
        N)rU   r   )r%   rL   rV   rW   rX   textr&   r&   r'   _call   s   

z
RWKV._call)r   )NN)*__name__
__module____qualname____doc__str__annotations__r   r   boolr   floatr   r   r   r   r?   r   r   r   r   r   r   r   r   Zmodel_configpropertyr   r(   staticmethodr   r)   r
   r8   r   r:   r;   r   rK   rU   r   r   rZ   r&   r&   r&   r'   r      sn   
 )
r   N)r^   typingr   r   r   r   r   r   Zlangchain_core.callbacksr   Z#langchain_core.language_models.llmsr	   Zlangchain_core.utilsr
   Zpydanticr   r   Zlangchain_community.llms.utilsr   r   r&   r&   r&   r'   <module>   s     