o
    :/i=                     @   s  d dl Z d dlZd dlZd dlZd dlmZ d dlmZ d dl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 ddlmZ zd dlZW n ey[   edZY nw ejdddee dee dedededefddZdeeef dededefddZdedB dee dededede	defdd Z d!d"d#e	d$ed%ed&e!ed'f fd(d)Z"d*e	dedB fd+d,Z#d$ed-ed#e	fd.d/Z$dddee dee ded$ed0ed#e	dedefd1d2Z%d$ed%ed3ee!eef  d4efd5d6Z&dedB dee d$ed%ed3ee!eef  d*e	d7edefd8d9Z'dee dee dee deded:ed0ed3ee!eef  d#e	d7edefd;d<Z(eG d=d> d>Z)d?e)fd@dAZ*d?e j+fdBdCZ,e-dDkroe j.e)j/dEZ0e)1e0 e,e02  dS dS )F    N)contextmanager)	dataclass)datetime)Path)ClassVar)PlaceholderModule   )ParameterSweepParameterSweepItem)ServerProcess)sanitize_filenamepandas,  )server_ready_timeout	serve_cmdafter_bench_cmdshow_stdoutserve_overridesdry_runr   c                c   s    | | }td td|  td|  |r#d V  td d S t|||d}|j|d |V  W d    n1 s>w   Y  td d S )Nz[BEGIN SERVER]zServer overrides: zServer command: z[END SERVER])r   )timeout)apply_to_cmdprintr   wait_until_ready)r   r   r   r   r   r   
server_cmdserver r   h/lsinfo/ai/hellotax_ai/llm_service/venv_vllm/lib/python3.10/site-packages/vllm/benchmarks/sweep/serve.py
run_server   s   

r   run_databench_overrides
run_numberc                 C   s    || d< |  | |  | | S )Nr    )update)r   r   r   r    r   r   r   _update_run_data5   s   

r"   r   	bench_cmdoutput_pathc          
      C   s  g | |ddddt|jd|j}td td|  td|  td	|  td
|  | rftd td |d}t|}	t	|	|||W  d    S 1 saw   Y  | d u ry|sst
d| td d S |jjddd | | |   |d}t|}	W d    n1 sw   Y  t	|	|||}	|d}tj|	|dd W d    n1 sw   Y  td |	S )Nz--percentile-metricszttft,tpot,itl,e2elz--save-resultz--result-dirz--result-filenamez[BEGIN BENCHMARK]zBenchmark overrides: zRun Number: zBenchmark command: zOutput file: zFound existing results.z[SKIPPED BENCHMARK]rbzCannot find results at z[END BENCHMARK]T)parentsexist_okw   indent)r   strparentnamer   existsopenjsonloadr"   
ValueErrormkdirrun_subcommandafter_benchdump)
r   r#   r   r   r    r$   r   benchmark_cmdfr   r   r   r   run_benchmarkB   sp   

 	
r:   r   )extra_partsexperiment_dir
serve_comb
bench_combr;   .c                C   sR   t t  }|r|d|jf |r|d|jf |r || | td| S )NzSERVE-zBENCH--)listr,   extendr.   r   join)r<   r=   r>   r;   partsr   r   r   _get_comb_base_path   s   

rD   	base_pathc                 C   s    |d u r| d S | d| d S )Nzsummary.jsonzrun=z.jsonr   )rE   r    r   r   r   _get_comb_run_path   s   rF   bench_combsc                 C   s0   |D ]}t || |}t|d d s dS qdS )Nr    TF)rD   rF   r/   )r=   rG   r<   r>   rE   r   r   r   _comb_needs_server   s   rI   bench_paramsc                C   s(   t |||s
t S t| |||||dS )N)r   r   r   r   )rI   
contextlibnullcontextr   )r   r   r   r=   rJ   r<   r   r   r   r   r   
server_ctx   s   rM   	link_varsreturnc                    s   t  fdd|D S )Nc                 3   s4    | ]\}}|v o| v o|  | kV  qd S Nr   ).0	serve_key	bench_keyr>   r=   r   r   	<genexpr>   s    
z!_comb_is_valid.<locals>.<genexpr>)all)r=   r>   rN   r   rT   r   _comb_is_valid   s   rW   num_runsc             
   C   s   t |||sd S ttttf   }t|D ]}	t| ||||	t||	|d}
|
d ur.||
 q|r3d S t|d d	d}t
j||dd W d    |S 1 sPw   Y  |S )N)r   r   r    r$   r   rH   r(   r)   r*   )rW   r@   dictr,   objectranger:   rF   appendr0   r1   r7   )r   r#   r=   r>   rN   rE   rX   r   	comb_datar    r   r9   r   r   r   run_comb   s0   


r^   serve_paramsc                C   s   t tttf   }|D ]>}t| ||||||
|d(}|D ]}t|||}t|||||||	|
d}|d ur9|| qW d    n1 sDw   Y  q|
rNd S tj	
|}||d  |S )N)r   r=   rJ   r<   r   r   )r=   r>   rN   rE   rX   r   zsummary.csv)r@   rY   r,   rZ   rM   rD   r^   rA   pd	DataFramefrom_recordsto_csv)r   r#   r   r   r   r_   rJ   rN   r<   rX   r   all_datar=   r   r>   rE   r]   combined_dfr   r   r   	run_combs   sH   	
rf   c                   @   s  e Zd ZU ee ed< ee ed< ee ed< eed< eed< eed< eed< ee	eef  ed< e
ed	< eed
< eed< eed< eed< dZee ed< dZee ed< edejfddZedejdejfddZededee	eef  fddZde
fddZede
fdd Zd!S )"SweepServeArgsr   r#   r   r   r   r_   rJ   rN   
output_direxperiment_namerX   r   resumeserveparser_namez2Run vLLM server benchmark under multiple settings.parser_helpargsc           
      C   s   t |j}t |j}|jd u rg nt |j}|jr#t|j}nti g}|j	r3t|j	}nti g}| 
|j}|jrF|j}nt d}|j}	|	dk rXtd| ||||j|||t|j||	|j|j|jdS )Nz%Y%m%d_%H%M%Sr   z `num_runs` should be at least 1.)r   r#   r   r   r_   rJ   rN   rh   ri   rX   r   rj   r   )shlexsplitr   r#   r   r_   r	   	read_jsonrb   rJ   parse_link_varsrN   ri   r   nowstrftimerX   r3   r   r   rh   r   rj   r   )
clsrn   r   r#   r   r_   rJ   rN   ri   rX   r   r   r   from_cli_argsC  s@   zSweepServeArgs.from_cli_argsparserrO   c                 C   s   |j dtddd |j dtddd |j dtd dd	 |j d
ddd |j dtddd	 |j dtd dd	 |j dtddd	 |j dtd dd	 |j ddtddd	 |j ddtd dd	 |j dtd d!d	 |j d"dd#d |j d$dd%d |S )&Nz--serve-cmdTz4The command used to run the server: `vllm serve ...`)typerequiredhelpz--bench-cmdz=The command used to run the benchmark: `vllm bench serve ...`z--after-bench-cmdzlAfter a benchmark run is complete, invoke this command instead of the default `ServerWrapper.clear_cache()`.)rx   defaultrz   z--show-stdout
store_truez^If set, logs the standard output of subcommands. Useful for debugging but can be quite spammy.)actionrz   z--server-ready-timeoutr   z:Timeout in seconds to wait for the server to become ready.z--serve-paramsa  Path to JSON file containing parameter combinations for the `vllm serve` command. Can be either a list of dicts or a dict where keys are benchmark names. If both `serve_params` and `bench_params` are given, this script will iterate over their Cartesian product.z--link-vars zComma-separated list of linked variables between serve and bench, e.g. max_num_seqs=max_concurrency,max_model_len=random_input_lenz--bench-paramsa  Path to JSON file containing parameter combinations for the `vllm bench serve` command. Can be either a list of dicts or a dict where keys are benchmark names. If both `serve_params` and `bench_params` are given, this script will iterate over their Cartesian product.z-oz--output-dirresultsz0The main directory to which results are written.z-ez--experiment-namezwThe name of this experiment (defaults to current timestamp). Results will be stored under `output_dir/experiment_name`.z
--num-runs   z)Number of runs per parameter combination.z	--dry-runzFIf set, prints the commands to run, then exits without executing them.z--resumezResume a previous execution of this script, i.e., only run parameter combinations for which there are still no output files under `output_dir/experiment_name`.)add_argumentr,   int)ru   rw   r   r   r   add_cli_argsr  s   


zSweepServeArgs.add_cli_argssc                 C   sD   | sg S g }|  dD ]}| d\}}|| | f q|S )N,=)rp   r\   strip)r   pairsitemabr   r   r   rr     s   zSweepServeArgs.parse_link_varsc                 C   sF   | j | j }| jr| std||S | r!td||S )Nz/Cannot resume from non-existent experiment_dir=z)Cannot overwrite existing experiment_dir=)rh   ri   rj   r/   r3   )selfr<   r   r   r   resolve_experiment_dir  s   z%SweepServeArgs.resolve_experiment_dirr<   c              
   c   s^    | j rd V  td|  d S zd V  td|  W d S  ty. } ztd|d }~ww )NzExperiment will be saved at: zExperiment has been saved at: z`The script was terminated early. Use `--resume` to continue the script from its last checkpoint.)r   r   BaseExceptionRuntimeError)r   r<   excr   r   r   run_ctx  s    zSweepServeArgs.run_ctxN)__name__
__module____qualname__r@   r,   __annotations__boolr   r	   tupler   rl   r   rm   classmethodargparse	Namespacerv   ArgumentParserr   staticmethodrr   r   r   r   r   r   r   r   rg   0  s2   
 .d 	rg   rn   c                 C   sh   |   }| |! t| j| j| j| j| j| j| j	| j
|| j| jdW  d    S 1 s-w   Y  d S )N)r   r#   rN   r   r   r   r_   rJ   r<   rX   r   )r   r   rf   r   r#   rN   r   r   r   r_   rJ   rX   r   )rn   r<   r   r   r   run_main  s    $r   c                 C   s   t t|  d S rP   )r   rg   rv   )rn   r   r   r   main  s   r   __main__)description)3r   rK   r1   ro   r   dataclassesr   r   pathlibr   typingr   vllm.utils.import_utilsr   param_sweepr	   r
   r   r   utilsr   r   r`   ImportErrorr@   r,   r   r   r   rY   rZ   r"   r:   r   rD   rF   rI   rM   rW   r^   rf   rg   r   r   r   r   r   rm   rw   r   
parse_argsr   r   r   r   <module>   s0  


M


	

	
'	

4 N

