
    ##hE\                        d dl Z d dlZd dlZd dlZd dlZd dlZd dlmZmZ d dl	m
Z
mZ d dlmZ d dlmZ d dlZd dlmZmZ ddlmZ  ej,                         d	k7  rd dlZ e       rd d
lmZ d dlmZ d dlmZ  e       rd dlZd dlm Z m!Z!m"Z"m#Z#  e$ejJ                  ejL                  z         Z' e$ejJ                  ejP                  z   ejL                  z   dz         Z)dZ*g dZ+ddiddiddiddiddiddidZ,d Z-d Z.d Z/d Z0d Z1ded   fd Z2d! Z3d" Z4 G d# d$      Z5e
 G d% d&             Z6d'efd(Z7 G d) d*e      Z8y)+    N)ArgumentParser	Namespace)	dataclassfield)Thread)Optional)is_rich_availableis_torch_available   )BaseTransformersCLICommandWindows)Console)Live)Markdown)AutoModelForCausalLMAutoTokenizerBitsAndBytesConfigTextIteratorStreamerz .!\"#$%&'()*+,\-/:<=>?@[]^_`{|}~a#  
**TRANSFORMERS CHAT INTERFACE**

The chat interface is a simple tool to try out a chat model.

Besides talking to the model there are several commands:
- **help**: show this help message
- **clear**: clears the current conversation and start a new one
- **example {NAME}**: load example named `{NAME}` from the config and use it as the user input
- **set {SETTING_NAME}={SETTING_VALUE};**: change the system prompt or generation settings (multiple settings are separated by a ';').
- **reset**: same as clear but also resets the generation configs to defaults if they have been changed by **set**
- **save {SAVE_NAME} (optional)**: save the current chat and settings to file by default to `./chat_history/{MODEL_NAME}/chat_{DATETIME}.yaml` or `{SAVE_NAME}` if provided
- **exit**: closes the interface
)max_new_tokens	do_sample	num_beamstemperaturetop_ptop_krepetition_penaltytextz5There is a Llama in my lawn, how can I get rid of it?zyWrite a Python function that integrates any Python function f(x) numerically over an arbitrary interval [x_start, x_end].z4How many helicopters can a human eat in one sitting?z4Count to 10 but skip every number ending with an 'e'zWhy aren't birds real?z2Why is it important to eat socks after meditating?)llamacode
helicopternumbersbirdssocksc                      t        j                         dk(  rt        j                         S t	        j
                  t        j                               j                  S )Nr   )platformsystemosgetloginpwdgetpwuidgetuidpw_name     W/var/www/html/sandstorm/venv/lib/python3.12/site-packages/transformers/commands/chat.pyget_usernamer/   Z   s8    I%{{}||BIIK(000r-   c                 <    t        j                  d      }|  d| dS )Nz%Y-%m-%d_%H-%M-%Sz/chat_z.json)timestrftime)
model_nametime_strs     r.   create_default_filenamer5   a   s$    }}01H\z//r-   c                    i }t        |      |d<   | |d<   |j                  }|5t        |j                        }t        j
                  j                  ||      }t	        j                  t        j
                  j                  |      d       t        |d      5 }t        j                  ||d       d d d        t        j
                  j                  |      S # 1 sw Y   (xY w)Nsettingschat_historyT)exist_okw   )indent)varssave_folderr5   model_name_or_pathr&   pathjoinmakedirsdirnameopenjsondumpabspath)chatargsfilenameoutput_dictfolderfs         r.   	save_chatrN   f   s    K"4jK
"&KF*4+B+BC77<<1KK)D9	h	 ,		+q+,77??8$$, ,s   CC"c                     | g }|S d| dg}|S )Nr%   rolecontentr,   )system_promptrH   s     r.   clear_chat_historyrT   w   s(     K "m<=Kr-   c                 F   | dd  j                         j                  d      }|D cg c]9  }|j                  d      d   |t        |j                  d      d         dz   d  f; }}t        |      }d}|D ]  }t	        ||      r_	 t        t        ||      t              r"||   dk(  rd||<   n5||   d	k(  rd||<   n't         t        t        ||            ||         ||<   n|j                  d| d        |r|j                  d       |dfS |D ]-  }t        ||||          |j                  d| d||    d       / t        j                  d       |dfS c c}w # t        $ r5 |j                  d
| d||    dt        t        ||             d       Y )w xY w)Nr;   ;=r   r   FTrueTFalsezCannot cast setting z (=z) to .zThere is no 'z
' setting.zGThere was an issue parsing the settings. No settings have been changed.zSet z to g      ?)stripsplitlendicthasattr
isinstancegetattrbool
ValueErrortype	print_redsetattrprint_greenr1   sleep)
user_inputcurrent_args	interfacer7   settingerrornames          r.   parse_settingsro      s   !"~##%++C0HbjkW^s#A&GMM#4Fq4I0JQ0N0P(QRkHkH~HE B<&glD94@~/)-!$72).((%FT',*E%FxPT~%VHTN -vZ @A#B& efU"" 	FDL$7!!Dd8D>2B!"DE	F 	

3T!!A l   ##*4&HTN3C5gVbdhNiIjHkklms   >EAE"":F F returnr   c                     | j                   r:t        d| j                  | j                  | j                  | j                        }|S | j
                  rt        d      }|S d }|S )NT)load_in_4bitbnb_4bit_compute_dtypebnb_4bit_quant_typebnb_4bit_use_double_quantbnb_4bit_quant_storage)load_in_8bit)rr   r   torch_dtypert   use_bnb_nested_quantrw   )
model_argsquantization_configs     r.   get_quantization_configr|      st    0#-#9#9 * > >&0&E&E#-#9#9
  
	 	 0
  #r-   c                    t        j                  | j                  | j                  | j                        }| j
                  dv r| j
                  nt        t        | j
                        }t        |       }| j                  | j                  |d|d}t        j                  | j                  fd| j                  i|}t        |dd       |j                  | j                        }||fS )N)revisiontrust_remote_code)autoNr   )r~   attn_implementationrx   
device_mapr{   r   hf_device_map)r   from_pretrainedr?   model_revisionr   rx   ra   torchr|   r   r   todevice)rI   	tokenizerrx   r{   model_kwargsmodels         r.   load_model_and_tokenizerr      s    --$$00I '+&6&6.&H$""gV[]a]m]mNnK1$7''#77"2L !00373I3IMYE uot,4%)r-   c                    | j                   | j                  }n| j                   }g }|/|j                  | j                  |j	                  d                   |7|j                  |j	                  d      D cg c]  }t        |       c}       t        |      dk(  r|j                  | j                         ||fS c c}w )N,r   )pad_token_ideos_token_idextendconvert_tokens_to_idsr\   intr]   append)r   
eos_tokenseos_token_idsr   all_eos_token_idstoken_ids         r.   parse_eos_tokensr      s    % -- --  !@!@AQAQRUAV!WX   @S@STW@X!YH#h-!YZ
"  !7!78*** "Zs   9B?c                   >    e Zd Zd
dZd Zd Zd Zd Zd Zd Z	d	 Z
y)RichInterfaceNc                 f    t               | _        |d| _        n|| _        |d| _        y || _        y )N	assistantuser)r   _consoler3   	user_name)selfr3   r   s      r.   __init__zRichInterface.__init__   s3    	)DO(DO#DN&DNr-   c                 X   d}| j                   j                  d| j                   d       t        | j                   d      5 }t	        |      D ]  \  }}|r|dk(  r||z  }g }|j                         D ]G  }|j                  |       |j                  d      r|j                  d       7|j                  d	       I t        dj                  |      j                         d
      }|j                  |        	 ddd       | j                   j                          |S # 1 sw Y   %xY w)zStream output from a role. z[bold blue]<z>:r;   )consolerefresh_per_secondr   z```
z  
zgithub-dark)
code_themeN)r   printr3   r   	enumerate
splitlinesr   
startswithr   rA   r[   update)	r   output_streamr   liveioutputslineslinemarkdowns	            r.   stream_outputzRichInterface.stream_output   s    l4??*;2>?$--A> 	&$'6 &
7!q&  OO- -DLL&u- T*V,- $BGGEN$8$8$:}UH%5&	&: 	=	& 	&s   B8D  D)c                     | j                   j                  d| j                   d      }| j                   j                          |S )N[bold red]<z>:
)r   inputr   r   )r   r   s     r.   r   zRichInterface.input  s9    ##k$..1A$FGr-   c                 8    | j                   j                          y N)r   clearr   s    r.   r   zRichInterface.clear  s    r-   c                     | j                   j                  d| j                   d|        | j                   j                          y )Nr   z>:[/ bold red]
)r   r   r   r   r   s     r.   print_user_messagez RichInterface.print_user_message  s7    k$..)99I$PQr-   c                 t    | j                   j                  d|        | j                   j                          y )Nz[bold green]r   r   r   s     r.   rg   zRichInterface.print_green#  s+    l4&12r-   c                 t    | j                   j                  d|        | j                   j                          y )Nz
[bold red]r   r   s     r.   re   zRichInterface.print_red'  s+    j/0r-   c                     | j                   j                  t        t                     | j                   j                          y r   )r   r   r   HELP_STRINGr   s    r.   
print_helpzRichInterface.print_help+  s)    H[12r-   )NN)__name__
__module____qualname__r   r   r   r   r   rg   re   r   r,   r-   r.   r   r      s+    	'$L
r-   r   c                   T   e Zd ZU dZ eddi      Zeed<    edddi      Ze	e   ed	<    eddd
i      Z
e	e   ed<    edddi      Zeed<    edddi      Zeed<    edddi      Ze	e   ed<    edddi      Zeed<    edddi      Zeed<    edddi      Zeed<    edddi      Zeed<    ed dd!i      Zeed"<    eddd#i      Zeed$<    eddd%i      Zeed&<    eddd'i      Ze	e   ed(<    eddd)i      Ze	e   ed*<    ed+dd,i      Zeed-<    ed.d/g d0d1      Ze	e   ed2<    ed3dd4i      Zeed5<    eddd6i      Ze	e   ed7<    ed3dd8i      Zeed9<    ed3dd:i      Zeed;<    ed<d=d>d<gd1      Z eed?<    ed3dd@i      Z!eedA<   y)BChatArgumentsa%  
    Arguments for the chat script.

    Args:
        model_name_or_path (`str`):
            Name of the pre-trained model.
        user (`str` or `None`, *optional*, defaults to `None`):
            Username to display in chat interface.
        system_prompt (`str` or `None`, *optional*, defaults to `None`):
            System prompt.
        save_folder (`str`, *optional*, defaults to `"./chat_history/"`):
            Folder to save chat history.
        device (`str`, *optional*, defaults to `"cpu"`):
            Device to use for inference.
        examples_path (`str` or `None`, *optional*, defaults to `None`):
            Path to a yaml file with examples.
        max_new_tokens (`int`, *optional*, defaults to `256`):
            Maximum number of tokens to generate.
        do_sample (`bool`, *optional*, defaults to `True`):
            Whether to sample outputs during generation.
        num_beams (`int`, *optional*, defaults to `1`):
            Number of beams for beam search.
        temperature (`float`, *optional*, defaults to `1.0`):
            Temperature parameter for generation.
        top_k (`int`, *optional*, defaults to `50`):
            Value of k for top-k sampling.
        top_p (`float`, *optional*, defaults to `1.0`):
            Value of p for nucleus sampling.
        repetition_penalty (`float`, *optional*, defaults to `1.0`):
            Repetition penalty.
        eos_tokens (`str` or `None`, *optional*, defaults to `None`):
            EOS tokens to stop the generation. If multiple they should be comma separated.
        eos_token_ids (`str` or `None`, *optional*, defaults to `None`):
            EOS token IDs to stop the generation. If multiple they should be comma separated.
        model_revision (`str`, *optional*, defaults to `"main"`):
            Specific model version to use (can be a branch name, tag name or commit id).
        torch_dtype (`str` or `None`, *optional*, defaults to `None`):
            Override the default `torch.dtype` and load the model under this dtype. If `'auto'` is passed, the dtype
            will be automatically derived from the model's weights.
        trust_remote_code (`bool`, *optional*, defaults to `False`):
            Whether to trust remote code when loading a model.
        attn_implementation (`str` or `None`, *optional*, defaults to `None`):
            Which attention implementation to use; you can run --attn_implementation=flash_attention_2, in which case
            you must install this manually by running `pip install flash-attn --no-build-isolation`.
        load_in_8bit (`bool`, *optional*, defaults to `False`):
            Whether to use 8 bit precision for the base model - works only with LoRA.
        load_in_4bit (`bool`, *optional*, defaults to `False`):
            Whether to use 4 bit precision for the base model - works only with LoRA.
        bnb_4bit_quant_type (`str`, *optional*, defaults to `"nf4"`):
            Quantization type.
        use_bnb_nested_quant (`bool`, *optional*, defaults to `False`):
            Whether to use nested quantization.
    helpzName of the pre-trained model.)metadatar?   Nz&Username to display in chat interface.)defaultr   r   zSystem prompt.rS   z./chat_history/zFolder to save chat history.r>   cpuzDevice to use for inference.r   z"Path to a yaml file with examples.examples_path   z%Maximum number of tokens to generate.r   Tz,Whether to sample outputs during generation.r   r   z Number of beams for beam search.r   g      ?z%Temperature parameter for generation.r   2   zValue of k for top-k sampling.r   z Value of p for nucleus sampling.r   zRepetition penalty.r   zNEOS tokens to stop the generation. If multiple they should be comma separated.r   zQEOS token IDs to stop the generation. If multiple they should be comma separated.r   mainzLSpecific model version to use (can be a branch name, tag name or commit id).r   r   zOverride the default `torch.dtype` and load the model under this dtype. If `'auto'` is passed, the dtype will be automatically derived from the model's weights.)r   bfloat16float16float32)r   choicesrx   Fz2Whether to trust remote code when loading a model.r   zWhich attention implementation to use; you can run --attn_implementation=flash_attention_2, in which case you must install this manually by running `pip install flash-attn --no-build-isolation`.r   zIWhether to use 8 bit precision for the base model - works only with LoRA.rw   zIWhether to use 4 bit precision for the base model - works only with LoRA.rr   nf4zQuantization type.fp4rt   z#Whether to use nested quantization.ry   )"r   r   r   __doc__r   r?   str__annotations__r   r   rS   r>   r   r   r   r   r   rb   r   r   floatr   r   r   r   r   r   rx   r   r   rw   rr   rt   ry   r,   r-   r.   r   r   0  s   4n $f6V-WXX@h7ijD(3-j#(IY@Z#[M8C=[%6&JhAijKj9W0XYFCY#(Im@n#oM8C=o  v?f6ghNChDF<j3klItl18Z/[\Is\sf>e5fgKgrV5U,VWE3W8Z/[\E5\ %cVEZ<[ \\ %jk!J  $)mn$M8C=   hiNC  "'PA
"K#  $)] ^t  */ r
*#  efL$  efL$   %UFZhmotgu=vww!&uHm?n!o$or-   r   rI   c                     t        |       S )z;
    Factory function used to chat with a local model.
    )ChatCommandrI   s    r.   chat_command_factoryr     s     tr-   c                   H    e Zd Zedefd       Zd Zededefd       Z	d Z
y)	r   parserc                 n    t         f}| j                  dt        |      }|j                  t               y)z
        Register this command to argparse so it's available for the transformer-cli

        Args:
            parser: Root parser to register command-specific arguments
        rH   )r   dataclass_types)funcN)r   
add_parserr   set_defaultsr   )r   r   chat_parsers      r.   register_subcommandzChatCommand.register_subcommand  s6     )*''[Ra'b  &: ;r-   c                     || _         y r   r   )r   rI   s     r.   r   zChatCommand.__init__  s	    	r-   srp   c                    | j                  d      rd| vry| dd  j                  d      D cg c]#  }|j                         s|j                         % }}|D ]  }|j                  d      dk7  r y|j                  dd      \  }}|j                         }|j                         }|r|s yt	        |      j                  t              s yt	        |      j                  t              r y yc c}w )Nzset rW   Fr;   rV   r   T)r   r\   r[   countsetissubsetALLOWED_KEY_CHARSALLOWED_VALUE_CHARS)r   aassignments
assignmentkeyvalues         r.   is_valid_setting_commandz$ChatCommand.is_valid_setting_command  s     ||F#s!| +,AB%++c*:HQaggiqwwyHH% 	J$)#))#q1JC))+CKKMEe s8$$%67 u:&&':;#	& + Is   C0C0c                    t               st        d      t               st        d      | j                  }|j                  t
        }n3t        |j                        5 }t        j                  |      }d d d        t        j                  |      }|j                  t               }n|j                  }t        |      \  }}t        |dd      }t        ||j                   |j"                        \  }	}
t%        |j&                  |      }|j)                          t+        |j,                        }	 	 |j/                         }|dk(  r&t+        |j,                        }|j)                          =|dk(  r|j1                          S|dk(  ry |d	k(  r;|j)                          t        j                  |      }t+        |j,                        }|j3                  d
      rft5        |j7                               dk  rJ|j7                         }t5        |      dk(  r|d   }nd }t9        |||      }|j;                  d| d       | j=                  |      r&t?        |||      \  }}|rg }|j)                          G|j3                  d      rt5        |j7                               dk(  rz|j7                         d   }|v r2|j)                          g }|jA                  ||   d          ||   d   }n1|jC                  d| dtE        |jG                                d       |jI                  d|d       |jK                  |dd      jM                  |jN                        }tQ        jR                  |      }||||jT                  |jV                  |jX                  |jZ                  |j\                  |j^                  |j`                  |	|
d}tc        |jd                  |      }|jg                          |ji                  |      }|jk                          |jI                  d|d       # 1 sw Y   xY w# tl        $ r Y y w xY w)NzHYou need to install rich to use the chat interface. (`pip install rich`)zJYou need to install torch to use the chat interface. (`pip install torch`)T)skip_special_tokensskip_prompt)r3   r   r   r   exitresetsave   r   zChat saved in !exampler   zExample z* not found in list of available examples: rZ   r   rP   pt)return_tensorsadd_generation_prompt)inputsattention_maskstreamerr   r   r   r   r   r   r   r   r   )targetkwargsr   )7r	   ImportErrorr
   rI   r   DEFAULT_EXAMPLESrD   yaml	safe_loadcopydeepcopyr   r/   r   r   r   r   r   r   r?   r   rT   rS   r   r   r   r]   r\   rN   rg   r   ro   r   re   listkeysr   apply_chat_templater   r   r   	ones_liker   r   r   r   r   r   r   r   generatestartr   rA   KeyboardInterrupt)r   rI   examplesrM   rj   r   r   r   generation_streamerr   r   rk   rH   ri   split_inputrJ   successexample_namer  r  generation_kwargsthreadmodel_outputs                          r.   runzChatCommand.run  s    "hii!#jkkyy%'Hd(() -Q>>!,- }}T*99>D99D3D9y29RVdhi&6y$//SWSeSe&f#m!T-D-DPTU	!,"<"<=P&__.
(-l.H.HIDOO%'((*'(OO%#'==#6L-l.H.HID((0S9I9I9K5Lq5P","2"2"4K;'1,#.q>#'(|XFH))N8*A*FG00<,::|U^,_)L'!!) ((3J<L<L<N8OST8T#-#3#3#5a#8L#x/!)!!44Xl5KF5ST%-l%;F%C
!++&|n4^_cdldqdqds_t^uuvw !V
CD"66tDhl6mppLL "'!8$&4 3&2&A&A!-!7!7!-!7!7#/#;#;)//)//*6*I*I$0$1%!  u~~>OP(667JK[\JK] %- -D % sK   P(3:P5 .P5 P5 
?P5 
A5P5 5P5 8B%P5 DP5 (P25	Q QN)r   r   r   staticmethodr   r   r   r   rb   r   r  r,   r-   r.   r   r     sH    	<N 	< 	< C D  :mr-   r   )9r  rE   r&   r$   stringr1   argparser   r   dataclassesr   r   	threadingr   typingr   r  transformers.utilsr	   r
   r   r   r%   r(   rich.consoler   	rich.liver   rich.markdownr   r   transformersr   r   r   r   r   ascii_letters
whitespacer   digitsr   r   SUPPORTED_GENERATION_KWARGSr
  r/   r5   rN   rT   ro   r|   r   r   r   r   r   r   r,   r-   r.   <module>r.     s      	    . (    D ( 8??	!$&jj,,v/@/@@A 
6==(6+<+<<?bb    MN  L QRNO./JK	 10
%"""J84H+I &4+(H HV pp pp ppfy [, [r-   