o
    پi]                     @  s  U d Z ddlm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
 ddlmZ ddlmZ ddlmZ d	ZeG d
d dZeG dd dZeG dd dZeG dd dZeddG dd dZeddG dd dZdddZeG d d! d!Zed"d#d$Zed%d&d'Zed(d)d*gdd+Zed,d-gd.dd/d0Zd1Zed2d3dd+Zed2d3dd4d.d.d5Z ed6ed7d8d9eed:ed7d8dd;eed<ed=d8d9eed>ed?d8d9eed@edAd8d9eedBed?d8ddCdDeedEed	d8d9eedFed	d8dGdHdIeedJedKd8d9eedLedMd8d9eedNedOd8d9eedPedQd8d9egZ!dRe"dS< edTedUdVdVdWeedXedYedUdVdVddZeedXed[edUdVdVdWeedd\ed]edUdVdVd^d_d`edadbdcedded?d8d9eedeedfdVdVdWeedXedgedhdVdVdWeediedjdVdVdWegZ#dRe"dk< e$ se#%edledmdVdVdWeedX ednedodVdVdWeedpedqdVdVdCdreedXedsedqdVdVdCdtduedvdXedwedxdVdCdVdyeedzd$ed{edUdVdVdCdd|eedXed}eed8dCd~gdegZ&e$ se&%ededdVdVdCdCde  ededdVdVdCdreededdVdVdCddueededdVdVdCdreeded7d8dCd^dCdeeded	d8dCdCdeeded=d8dCdeeded?d8dCdCdegZ'e(e
e)*d+e
e)j,d d Z-dS )a  
Configuration and data structures for diffusion performance tests.

Usage:

pytest python/sglang/multimodal_gen/test/server/test_server_a.py
# for a single testcase, look for the name of the testcases in DIFFUSION_CASES
pytest python/sglang/multimodal_gen/test/server/test_server_a.py -k qwen_image_t2i


To add a new testcase:
1. add your testcase with case-id: `my_new_test_case_id` to DIFFUSION_CASES
2. run `SGLANG_GEN_BASELINE=1 pytest -s python/sglang/multimodal_gen/test/server/ -k my_new_test_case_id`
3. insert or override the corresponding scenario in `scenarios` section of perf_baselines.json with the output baseline of step-2


    )annotationsN)	dataclassfield)Path)Sequence)current_platform)RequestPerfRecordzTongyi-MAI/Z-Image-Turboc                   @  sH   e Zd ZU dZded< ded< ded< ded< ded< edddZdS )ToleranceConfigz,Tolerance ratios for performance validation.floate2edenoise_stagenon_denoise_stagedenoise_stepdenoise_aggall_tolerancesdictprofile_namestrreturnc                 C  s   d|v rt |d ts|}d}n|||di }||v r |nd}|s,td| dtd| d | ttd|d ttd	|d
 ttd|d ttd|d ttd|d dS )z@Load a specific tolerance profile from a dictionary of profiles.r   zlegacy/flatpr_testz No tolerance profile found for 'z*' and no default 'pr_test' profile exists.z#--- Performance Tolerance Profile: z ---SGLANG_E2E_TOLERANCESGLANG_STAGE_TIME_TOLERANCEr   'SGLANG_NON_DENOISE_STAGE_TIME_TOLERANCEr   SGLANG_DENOISE_STEP_TOLERANCEr   SGLANG_DENOISE_AGG_TOLERANCEr   )r   r   r   r   r   )
isinstancer   get
ValueErrorprintr
   osgetenv)clsr   r   tol_dataactual_profile r$   f/home/ubuntu/.local/lib/python3.10/site-packages/sglang/multimodal_gen/test/server/testcase_configs.pyload_profile,   s>   
zToleranceConfig.load_profileN)r   r   r   r   r   r	   )__name__
__module____qualname____doc____annotations__classmethodr&   r$   r$   r$   r%   r	   "   s   
 r	   c                   @  s:   e Zd ZU dZded< ded< ded< ded< ded	< d
S )ScenarioConfigz1Expected performance metrics for a test scenario.dict[str, float]	stages_msdict[int, float]denoise_step_msr
   expected_e2e_msexpected_avg_denoise_msexpected_median_denoise_msNr'   r(   r)   r*   r+   r$   r$   r$   r%   r-   V   s   
 r-   c                   @  sJ   e Zd ZU dZded< ded< ded< ded	< edddZdddZdS )BaselineConfigzFull baseline configuration.zdict[str, ScenarioConfig]	scenariosSequence[float]step_fractionsr	   
tolerancesr
   improvement_thresholdpathr   r   c           	   	   C  s   |j ddd}t|}W d   n1 sw   Y  d}t|di |}i }|d  D ]&\}}t|d d	d
 |d  D t|d t|d t|d d||< q0| |t	|d d ||di dddS )+Load baseline configuration from JSON file.rutf-8encodingNr   r:   r7   r/   c                 S     i | ]	\}}t ||qS r$   int.0kvr$   r$   r%   
<dictcomp>z       z'BaselineConfig.load.<locals>.<dictcomp>r1   r2   r3   r4   r/   r1   r2   r3   r4   samplingr9   improvement_reporting	thresholdg?)r7   r9   r:   r;   )
openjsonloadr	   r&   r   itemsr-   r
   tuple)	r!   r<   fhdatar   r:   r7   namecfgr$   r$   r%   rQ   j   s0   


zBaselineConfig.loadc              	   C  s   |j ddd}t|}W d   n1 sw   Y  i }|d  D ]&\}}t|d dd |d	  D t|d
 t|d t|d d||< q$| j| | S )r=   r>   r?   r@   Nr7   r/   c                 S  rB   r$   rC   rE   r$   r$   r%   rI      rJ   z)BaselineConfig.update.<locals>.<dictcomp>r1   r2   r3   r4   rK   )rO   rP   rQ   rR   r-   r
   r7   update)selfr<   rT   rU   scenarios_newrV   rW   r$   r$   r%   rX      s   


zBaselineConfig.updateN)r<   r   r   r6   )r<   r   )r'   r(   r)   r*   r+   r,   rQ   rX   r$   r$   r$   r%   r6   a   s   
 r6   c                   @  s   e Zd ZU dZded< dZded< dZded< d	Zd
ed< dZded< dZ	ded< dZ
ded< dZded< dZded< dZded< dZded< dZded< dZded< dZded< dZded< edd dZded < d!d" ZdS )#DiffusionServerArgs4Configuration for a single model/scenario test case.r   
model_pathimagemodalityN
str | Nonecustom_validator   rD   num_gpus
int | Nonetp_sizeulysses_degreering_degreezbool | Nonecfg_parallel	lora_pathdynamic_lora_pathsecond_lora_pathFbooldit_layerwise_offloadzint | float | Nonedit_offload_prefetch_sizeenable_cache_dittext_encoder_cpu_offloadc                   C  s   g S )Nr$   r$   r$   r$   r%   <lambda>   s    zDiffusionServerArgs.<lambda>)default_factoryz	list[str]extrasc                 C  s,   | j dkr
d| _d S | j dkrd| _d S d S )Nr^   video)r_   ra   )rY   r$   r$   r%   __post_init__   s
   



z!DiffusionServerArgs.__post_init__)r'   r(   r)   r*   r+   r_   ra   rc   re   rf   rg   rh   ri   rj   rk   rm   rn   ro   rp   r   rs   ru   r$   r$   r$   r%   r[      s,   
 


r[   T)frozenc                   @  s   e Zd ZU dZdZded< dZded< dZded	< d
Zded< dZ	ded< dZ
ded< dZded< dZded< d
Zded< dZded< dS )DiffusionSamplingParamsr\    r   output_sizeNr`   promptzPath | str | None
image_pathrb   rD   secondsrd   
num_framesfpsFrl   direct_url_testoutput_formatnum_outputs_per_promptenable_teacache)r'   r(   r)   r*   ry   r+   rz   r{   r|   r}   r~   r   r   r   r   r$   r$   r$   r%   rw      s   
 rw   c                   @  s*   e Zd ZU dZded< ded< ded< dS )	DiffusionTestCaser\   r   idr[   server_argsrw   sampling_paramsNr5   r$   r$   r$   r%   r      s
   
 r   step_mapr0   	fractionsr8   r   	list[int]c              	   C  sZ   | sg S t |  }t }|D ]}t|t dtt|| }|| v r(|| qt|S )Nr   )maxkeyssetminrD   roundaddsorted)r   r   max_idxindicesfractionidxr$   r$   r%   sample_step_indices   s   
r   c                   @  s|   e Zd ZU dZded< ded< ded< ded< ded	< d
ed< d
ed< dZded< dZded< dZded< edddZ	dS )PerformanceSummaryzASummary of performance of a request, built from RequestPerfRecordr
   e2e_msavg_denoise_msmedian_denoise_msr.   stage_metricszlist[float]step_metricsr0   sampled_stepsall_denoise_stepsNzfloat | Noneframes_per_secondrd   total_framesavg_frame_time_msrecordr   r9   r8   c              	     s   | j }| j}d}d}|rt|t| }t|}dd t|D  t |} fdd|D }i }| jD ]}	t	|	t
rLd|	v rL|	dd}
|
||	d < q5t|||||| dS )zBCollect all performance metrics into a summary without validation.g        c                 S  s   i | ]\}}||qS r$   r$   )rF   indexsr$   r$   r%   rI         z;PerformanceSummary.from_req_perf_record.<locals>.<dictcomp>c                   s   i | ]}| | qS r$   r$   )rF   r   per_stepr$   r%   rI     r   rV   execution_time_ms)r   r   r   r   r   r   r   )total_duration_msstepssumlen
statisticsmedian	enumerater   stagesr   r   r   r   )r   r9   r   step_durationsavg_denoisemedian_denoisesample_indicesr   r   itemvalr$   r   r%   from_req_perf_record  s2   


z'PerformanceSummary.from_req_perf_record)r   r   r9   r8   )
r'   r(   r)   r*   r+   r   r   r   staticmethodr   r$   r$   r$   r%   r      s   
 r   zDoraemon is eating dorayaki	1024x1024)rz   ry   zConvert 2D style to 3D stylez`https://github.com/lm-sys/lm-sys.github.io/releases/download/test/TI2I_Qwen_Image_Edit_Input.jpg)rz   r{   zsThe magician bear is on the left, the alchemist bear is on the right, facing each other in the central park square.zRhttps://qianwen-res.oss-cn-beijing.aliyuncs.com/Qwen-Image/edit2509/edit2509_1.jpgzRhttps://qianwen-res.oss-cn-beijing.aliyuncs.com/Qwen-Image/edit2509/edit2509_2.jpg)rz   r{   r   zQa high quality, cute halloween themed illustration, consistent style and lightingzYhttps://raw.githubusercontent.com/QwenLM/Qwen-Image-Layered/main/assets/test_images/4.png   png)rz   r{   r}   r   r   zA curious raccoonzThe man in the picture slowly turns his head, his expression enigmatic and otherworldly. The camera performs a slow, cinematic dolly out, focusing on his face. Moody lighting, neon signs glowing in the background, shallow depth of field.zhttps://is1-ssl.mzstatic.com/image/thumb/Music114/v4/5f/fa/56/5ffa56c2-ea1f-7a17-6bad-192ff9b6476d/825646124206.jpg/600x600bb.jpg960x960)rz   r{   r   ry   r}   r~   qwen_image_t2izQwen/Qwen-Imager^   )r]   r_    qwen_image_t2i_cache_dit_enabled)r]   r_   ro   flux_image_t2izblack-forest-labs/FLUX.1-devflux_2_image_t2izblack-forest-labs/FLUX.2-devflux_2_klein_image_t2iz!black-forest-labs/FLUX.2-klein-4B"flux_2_image_t2i_layerwise_offload   )r]   r_   rm   rn   zimage_image_t2izimage_image_t2i_multi_loraz8reverentelusarca/elusarca-anime-style-lora-z-image-turboz)tarn59/pixel_art_style_lora_z_image_turbo)r]   r_   ri   rk   qwen_image_edit_ti2izQwen/Qwen-Image-Editqwen_image_edit_2509_ti2izQwen/Qwen-Image-Edit-2509qwen_image_edit_2511_ti2izQwen/Qwen-Image-Edit-2511qwen_image_layered_i2izQwen/Qwen-Image-Layeredzlist[DiffusionTestCase]ONE_GPU_CASES_Azwan2_1_t2v_1.3bz Wan-AI/Wan2.1-T2V-1.3B-Diffusersrt   )r]   r_   ra   )rz   z(wan2_1_t2v_1.3b_text_encoder_cpu_offload)r]   r_   ra   rp   z wan2_1_t2v_1.3b_teacache_enabled)rz   r   wan2_1_t2v_1_3b_lora_1gpurb   zCseti/Wan-LoRA-Arcane-Jinx-v1)r]   r_   ra   rc   rj   zOcsetiarcane Nfj1nx with blue hair, a woman walking in a cyberpunk city at night   )rz   r}   flux_2_ti2ifast_hunyuan_videozFastVideo/FastHunyuan-diffuserswan2_2_ti2v_5bzWan-AI/Wan2.2-TI2V-5B-Diffusersfastwan2_2_ti2v_5bz/FastVideo/FastWan2.2-TI2V-5B-FullAttn-DiffusersONE_GPU_CASES_Bzturbo_wan2_1_t2v_1.3bz*IPostYellow/TurboWan2.1-T2V-1.3B-Diffuserswan2_2_i2v_a14b_2gpuz Wan-AI/Wan2.2-I2V-A14B-Diffuserswan2_2_t2v_a14b_2gpuz Wan-AI/Wan2.2-T2V-A14B-Diffusers)r]   r_   ra   rc   wan2_2_t2v_a14b_lora_2gpuz$Cseti/wan2.2-14B-Arcane_Jinx-lora-v1)r]   r_   ra   rc   ri   zCNfj1nx with blue hair, a woman walking in a cyberpunk city at nightwan2_1_t2v_14b_2gpuzWan-AI/Wan2.1-T2V-14B-Diffusers)r]   r_   rc   ra   832x480zwan2_1_t2v_1.3b_cfg_parallel)r]   r_   ra   rc   rh   zfsdp-inferencez--use-fsdp-inference)r]   r_   rc   rs   turbo_wan2_2_i2v_a14b_2gpuz*IPostYellow/TurboWan2.2-I2V-A14B-Diffusers)r]   r_   ra   rc   re   wan2_1_i2v_14b_480P_2gpuz$Wan-AI/Wan2.1-I2V-14B-480P-Diffuserswan2_1_i2v_14b_lora_2gpuz$Wan-AI/Wan2.1-I2V-14B-720P-Diffusersz$starsfriday/Wan2.1-Divine-Power-LoRAwan2_1_i2v_14b_720P_2gpuqwen_image_t2i_2_gpus)r]   r_   rc   rf   rg   zimage_image_t2i_2_gpus)r]   r_   rc   rf   flux_image_t2i_2_gpus)r]   r_   rc   flux_2_image_t2i_2_gpus)r]   r_   rc   re   zperf_baselines.jsonascendzperf_baselines_npu.json)r   r0   r   r8   r   r   ).r*   
__future__r   rP   r   r   dataclassesr   r   pathlibr   typingr   'sglang.multimodal_gen.runtime.platformsr   /sglang.multimodal_gen.runtime.utils.perf_loggerr   DEFAULT_SMALL_MODELr	   r-   r6   r[   rw   r   r   r   T2I_sampling_paramsTI2I_sampling_params MULTI_IMAGE_TI2I_sampling_paramsMULTI_FRAME_I2I_sampling_params
T2V_PROMPTTI2V_sampling_paramsTURBOWAN_I2V_sampling_paramsr   r+   r   is_hipappendTWO_GPU_CASES_ATWO_GPU_CASES_BrQ   __file__	with_namerX   parentBASELINE_CONFIGr$   r$   r$   r%   <module>   s4   3
:&
3
	





_	
j	
K

	M