Add ReplayServe Frontier vLLM alignment report
This commit is contained in:
BIN
docs/assets/frontier_vllm_alignment/completion_prefix.png
Normal file
BIN
docs/assets/frontier_vllm_alignment/completion_prefix.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 129 KiB |
@@ -0,0 +1,10 @@
|
||||
run_id,label,tp,request_count,scale_label,scale_value,fixture,kv_blocks,frontier_completed,frontier_total,frontier_complete,vllm_completed,vllm_total,frontier_preemptions,vllm_preemptions,frontier_prefix_hit,vllm_prefix_hit,prefix_hit_delta,frontier_rps,vllm_rps,rps_ratio,frontier_total_tps,vllm_total_tps,total_tps_ratio,frontier_decode_tps,vllm_decode_tps,decode_tps_ratio,frontier_ttft_p50_s,vllm_ttft_p50_s,ttft_p50_ratio,frontier_ttft_p95_s,vllm_ttft_p95_s,ttft_p95_ratio,frontier_tpot_p50_s,vllm_tpot_p50_s,tpot_p50_ratio,frontier_tpot_p95_s,vllm_tpot_p95_s,tpot_p95_ratio,frontier_e2e_p50_s,vllm_e2e_p50_s,e2e_p50_ratio,frontier_e2e_p95_s,vllm_e2e_p95_s,e2e_p95_ratio,notes
|
||||
tp1_n100_scale1,TP1 N100 raw,1,100,raw,1,coder_100,15281,96,100,false,100,100,0,8,0.2487845616,0.2510820686,-0.002297507075,0.4048148795,0.6879880691,0.588403924,2348.908821,3832.320581,0.6129207541,347.7992338,567.4456795,0.6129207541,0.9087481136,4.503025495,0.201808343,12.76295815,29.06046906,0.4391862402,0.05688966428,0.06608134396,0.8609035603,0.1456880793,0.6211491471,0.2345460505,30.93928316,41.84076733,0.7394530534,119.6361376,97.36622969,1.228723121,Frontier incomplete before lifecycle fix; included as TP1 100-request baseline.
|
||||
tp1_n500_scale1,TP1 N500 raw,1,500,raw,1,coder_500,15281,439,500,false,500,500,0,63,0.1192374692,0.3868498695,-0.2676124002,0.660990472,0.8401719451,0.7867323776,4733.748762,5282.903731,0.896050544,656.2204998,732.3476384,0.896050544,136.7755789,185.6581683,0.7367064976,340.2371222,375.8950067,0.9051387119,0.05643274739,0.04975253624,1.134268756,0.08942839773,0.0918798539,0.9733188935,177.7998574,224.2697872,0.7927945162,397.29145,417.3562933,0.9519239469,Frontier incomplete; useful as high-pressure stress signal.
|
||||
tp1_n200_scale0667,TP1 N200 scale 0.667,1,200,0.667,0.6666666667,coder_200_ts0667,15281,176,200,false,200,200,0,26,0.170276008,0.2697549478,-0.09947893984,0.5830903706,0.8236788215,0.7079098737,3913.437526,4864.778909,0.8044430383,593.287826,737.51378,0.8044430383,20.58014532,34.56323652,0.595434554,96.71793818,120.8039818,0.800618794,0.05837096651,0.05145431897,1.13442307,0.235894569,0.2534757496,0.9306395954,73.20731169,83.6219905,0.875455263,189.2402903,183.726977,1.030008186,Dense-arrival run; Frontier incomplete before lifecycle fix.
|
||||
tp1_n200_scale2,TP1 N200 scale 2,1,200,2,2,coder_200_ts2,15281,200,200,true,200,200,33,43,0.23134169,0.2697549478,-0.03841325784,0.5936627655,0.8029813635,0.7393232178,3506.267279,4742.53641,0.7393232178,531.5597036,718.9814831,0.7393232178,9.595321274,9.216767096,1.041072338,77.50341053,69.21141595,1.119806747,0.05421362546,0.04970337519,1.09074334,0.06653162646,0.06863309532,0.9693811149,61.45769412,55.00248734,1.117362088,174.4840836,142.3375087,1.225847531,After Frontier decode-preemption lifecycle fix.
|
||||
tp1_n200_scale3,TP1 N200 scale 3,1,200,3,3,coder_200_ts3,15281,200,200,true,200,200,20,16,0.2176751278,0.2697549478,-0.05207982007,0.5739781652,0.7802265504,0.735655772,3390.00688,4608.142843,0.735655772,513.9343094,698.607051,0.735655772,1.001474116,1.166151478,0.8587856162,45.9466567,32.25842447,1.424330464,0.05339333437,0.04616159714,1.156661331,0.06861254671,0.0713836296,0.9611804148,44.76058145,33.21267588,1.34769573,154.5483135,122.7887113,1.258652459,After Frontier decode-preemption lifecycle fix.
|
||||
tp2_n200_scale2,TP2 N200 scale 2,2,200,2,2,coder_200_ts2,69055,200,200,true,200,200,0,0,0.2697549478,0.2697549478,0,0.7756823572,1.277818683,0.607036325,4581.304111,7547.001591,0.607036325,694.5382258,1144.14607,0.607036325,0.2690959621,0.225119116,1.195349231,6.744624223,0.715071776,9.432094022,0.04295527658,0.03004499679,1.429698158,0.05288764732,0.04340382318,1.218502046,26.05122482,16.44861007,1.583794905,106.7591651,72.5347179,1.471835394,Uses true-mixed TP2/TP4 attention profile.
|
||||
tp2_n200_scale3,TP2 N200 scale 3,2,200,3,3,coder_200_ts3,69055,200,200,true,200,200,0,0,0.2697549478,0.2697549478,0,0.6877705321,1.088050278,0.6321128225,4062.082806,6426.199028,0.6321128225,615.8228567,974.2293382,0.6321128225,0.1341535495,0.153530943,0.8737883511,0.5741378218,0.6270455511,0.9156237864,0.03937896849,0.01905767256,2.06630523,0.04670767225,0.02799082097,1.668678182,21.78596494,9.956003374,2.188223941,101.5918393,53.98348621,1.881905864,Uses true-mixed TP2/TP4 attention profile.
|
||||
tp4_n200_scale2,TP4 N200 scale 2,4,200,2,2,coder_200_ts2,177077,200,200,true,200,200,0,0,0.2697549478,0.2697549478,0,0.8525337931,1.536203537,0.5549614829,5035.200987,9073.063884,0.5549614829,763.350233,1375.501285,0.5549614829,0.09755515041,0.1704972619,0.5721801589,0.3856872342,1.419861408,0.2716372401,0.03366585047,0.01634437735,2.059781767,0.03838265621,0.02831690026,1.355468143,18.65216282,9.260885488,2.014079846,84.93775414,43.62188903,1.947136083,Uses true-mixed TP2/TP4 attention profile.
|
||||
tp4_n200_scale3,TP4 N200 scale 3,4,200,3,3,coder_200_ts3,177077,200,200,true,200,200,0,0,0.2697549478,0.2697549478,0,0.7373665172,1.253504493,0.5882440162,4355.004629,7403.398096,0.5882440162,660.2306059,1122.375388,0.5882440162,0.08859749135,0.100106278,0.885034317,0.3458954617,0.3184188101,1.086290919,0.03106778109,0.009410284212,3.301471071,0.03578285082,0.01279276668,2.79711588,16.90291941,5.54948732,3.045852424,83.00995365,27.86907583,2.978568581,Uses true-mixed TP2/TP4 attention profile.
|
||||
|
434
docs/assets/frontier_vllm_alignment/frontier_vllm_alignment.json
Normal file
434
docs/assets/frontier_vllm_alignment/frontier_vllm_alignment.json
Normal file
@@ -0,0 +1,434 @@
|
||||
[
|
||||
{
|
||||
"decode_tps_ratio": 0.6129207541251469,
|
||||
"e2e_p50_ratio": 0.7394530533987747,
|
||||
"e2e_p95_ratio": 1.2287231205931113,
|
||||
"fixture": "coder_100",
|
||||
"frontier_complete": false,
|
||||
"frontier_completed": 96,
|
||||
"frontier_decode_tps": 347.79923381681954,
|
||||
"frontier_e2e_p50_s": 30.939283157873398,
|
||||
"frontier_e2e_p95_s": 119.6361375789676,
|
||||
"frontier_preemptions": 0,
|
||||
"frontier_prefix_hit": 0.24878456156190046,
|
||||
"frontier_rps": 0.4048148795016268,
|
||||
"frontier_total": 100,
|
||||
"frontier_total_tps": 2348.908820556559,
|
||||
"frontier_tpot_p50_s": 0.056889664283438265,
|
||||
"frontier_tpot_p95_s": 0.14568807925543142,
|
||||
"frontier_ttft_p50_s": 0.9087481136376141,
|
||||
"frontier_ttft_p95_s": 12.762958146117297,
|
||||
"kv_blocks": 15281,
|
||||
"label": "TP1 N100 raw",
|
||||
"notes": "Frontier incomplete before lifecycle fix; included as TP1 100-request baseline.",
|
||||
"prefix_hit_delta": -0.0022975070751777016,
|
||||
"request_count": 100,
|
||||
"rps_ratio": 0.5884039239601411,
|
||||
"run_id": "tp1_n100_scale1",
|
||||
"scale_label": "raw",
|
||||
"scale_value": 1.0,
|
||||
"total_tps_ratio": 0.6129207541251469,
|
||||
"tp": 1,
|
||||
"tpot_p50_ratio": 0.8609035602986401,
|
||||
"tpot_p95_ratio": 0.23454605053898236,
|
||||
"ttft_p50_ratio": 0.20180834300191677,
|
||||
"ttft_p95_ratio": 0.439186240241972,
|
||||
"vllm_completed": 100,
|
||||
"vllm_decode_tps": 567.445679520595,
|
||||
"vllm_e2e_p50_s": 41.84076732886024,
|
||||
"vllm_e2e_p95_s": 97.36622968502343,
|
||||
"vllm_preemptions": 8,
|
||||
"vllm_prefix_hit": 0.25108206863707816,
|
||||
"vllm_rps": 0.6879880691092217,
|
||||
"vllm_total": 100,
|
||||
"vllm_total_tps": 3832.3205810011714,
|
||||
"vllm_tpot_p50_s": 0.06608134395878643,
|
||||
"vllm_tpot_p95_s": 0.6211491471318447,
|
||||
"vllm_ttft_p50_s": 4.503025494981557,
|
||||
"vllm_ttft_p95_s": 29.060469059972093
|
||||
},
|
||||
{
|
||||
"decode_tps_ratio": 0.8960505440100501,
|
||||
"e2e_p50_ratio": 0.7927945162118318,
|
||||
"e2e_p95_ratio": 0.951923946910999,
|
||||
"fixture": "coder_500",
|
||||
"frontier_complete": false,
|
||||
"frontier_completed": 439,
|
||||
"frontier_decode_tps": 656.2204997652797,
|
||||
"frontier_e2e_p50_s": 177.7998574092898,
|
||||
"frontier_e2e_p95_s": 397.29145000151055,
|
||||
"frontier_preemptions": 0,
|
||||
"frontier_prefix_hit": 0.11923746923408568,
|
||||
"frontier_rps": 0.6609904720097601,
|
||||
"frontier_total": 500,
|
||||
"frontier_total_tps": 4733.748762075876,
|
||||
"frontier_tpot_p50_s": 0.05643274739314083,
|
||||
"frontier_tpot_p95_s": 0.08942839772817235,
|
||||
"frontier_ttft_p50_s": 136.77557892500107,
|
||||
"frontier_ttft_p95_s": 340.237122196321,
|
||||
"kv_blocks": 15281,
|
||||
"label": "TP1 N500 raw",
|
||||
"notes": "Frontier incomplete; useful as high-pressure stress signal.",
|
||||
"prefix_hit_delta": -0.2676124002320734,
|
||||
"request_count": 500,
|
||||
"rps_ratio": 0.786732377640824,
|
||||
"run_id": "tp1_n500_scale1",
|
||||
"scale_label": "raw",
|
||||
"scale_value": 1.0,
|
||||
"total_tps_ratio": 0.8960505440100502,
|
||||
"tp": 1,
|
||||
"tpot_p50_ratio": 1.134268756171416,
|
||||
"tpot_p95_ratio": 0.9733188934802052,
|
||||
"ttft_p50_ratio": 0.736706497600023,
|
||||
"ttft_p95_ratio": 0.9051387119015346,
|
||||
"vllm_completed": 500,
|
||||
"vllm_decode_tps": 732.3476383692921,
|
||||
"vllm_e2e_p50_s": 224.26978715602309,
|
||||
"vllm_e2e_p95_s": 417.3562933159992,
|
||||
"vllm_preemptions": 63,
|
||||
"vllm_prefix_hit": 0.38684986946615907,
|
||||
"vllm_rps": 0.8401719451179492,
|
||||
"vllm_total": 500,
|
||||
"vllm_total_tps": 5282.903730956031,
|
||||
"vllm_tpot_p50_s": 0.049752536236317216,
|
||||
"vllm_tpot_p95_s": 0.09187985389702198,
|
||||
"vllm_ttft_p50_s": 185.6581683079712,
|
||||
"vllm_ttft_p95_s": 375.8950067239348
|
||||
},
|
||||
{
|
||||
"decode_tps_ratio": 0.8044430383408974,
|
||||
"e2e_p50_ratio": 0.8754552629577944,
|
||||
"e2e_p95_ratio": 1.030008185534932,
|
||||
"fixture": "coder_200_ts0667",
|
||||
"frontier_complete": false,
|
||||
"frontier_completed": 176,
|
||||
"frontier_decode_tps": 593.287826008356,
|
||||
"frontier_e2e_p50_s": 73.20731168652793,
|
||||
"frontier_e2e_p95_s": 189.24029025053343,
|
||||
"frontier_preemptions": 0,
|
||||
"frontier_prefix_hit": 0.17027600800712456,
|
||||
"frontier_rps": 0.5830903705506575,
|
||||
"frontier_total": 200,
|
||||
"frontier_total_tps": 3913.43752605849,
|
||||
"frontier_tpot_p50_s": 0.05837096651496554,
|
||||
"frontier_tpot_p95_s": 0.23589456903741046,
|
||||
"frontier_ttft_p50_s": 20.58014532403832,
|
||||
"frontier_ttft_p95_s": 96.7179381828816,
|
||||
"kv_blocks": 15281,
|
||||
"label": "TP1 N200 scale 0.667",
|
||||
"notes": "Dense-arrival run; Frontier incomplete before lifecycle fix.",
|
||||
"prefix_hit_delta": -0.09947893983522305,
|
||||
"request_count": 200,
|
||||
"rps_ratio": 0.7079098737399896,
|
||||
"run_id": "tp1_n200_scale0667",
|
||||
"scale_label": "0.667",
|
||||
"scale_value": 0.6666666666666666,
|
||||
"total_tps_ratio": 0.8044430383408974,
|
||||
"tp": 1,
|
||||
"tpot_p50_ratio": 1.1344230703885074,
|
||||
"tpot_p95_ratio": 0.930639595403931,
|
||||
"ttft_p50_ratio": 0.5954345540217358,
|
||||
"ttft_p95_ratio": 0.800618794003408,
|
||||
"vllm_completed": 200,
|
||||
"vllm_decode_tps": 737.5137800085473,
|
||||
"vllm_e2e_p50_s": 83.62199050490744,
|
||||
"vllm_e2e_p95_s": 183.7269770358689,
|
||||
"vllm_preemptions": 26,
|
||||
"vllm_prefix_hit": 0.2697549478423476,
|
||||
"vllm_rps": 0.8236788215286605,
|
||||
"vllm_total": 200,
|
||||
"vllm_total_tps": 4864.778908559713,
|
||||
"vllm_tpot_p50_s": 0.051454318973762715,
|
||||
"vllm_tpot_p95_s": 0.2534757495838373,
|
||||
"vllm_ttft_p50_s": 34.563236522022635,
|
||||
"vllm_ttft_p95_s": 120.80398175423034
|
||||
},
|
||||
{
|
||||
"decode_tps_ratio": 0.7393232177681209,
|
||||
"e2e_p50_ratio": 1.1173620884379967,
|
||||
"e2e_p95_ratio": 1.2258475306262637,
|
||||
"fixture": "coder_200_ts2",
|
||||
"frontier_complete": true,
|
||||
"frontier_completed": 200,
|
||||
"frontier_decode_tps": 531.5597035900641,
|
||||
"frontier_e2e_p50_s": 61.45769412455945,
|
||||
"frontier_e2e_p95_s": 174.48408358603848,
|
||||
"frontier_preemptions": 33,
|
||||
"frontier_prefix_hit": 0.23134168999974056,
|
||||
"frontier_rps": 0.5936627654877362,
|
||||
"frontier_total": 200,
|
||||
"frontier_total_tps": 3506.267279013048,
|
||||
"frontier_tpot_p50_s": 0.054213625462090735,
|
||||
"frontier_tpot_p95_s": 0.06653162646338621,
|
||||
"frontier_ttft_p50_s": 9.595321273711544,
|
||||
"frontier_ttft_p95_s": 77.50341053197451,
|
||||
"kv_blocks": 15281,
|
||||
"label": "TP1 N200 scale 2",
|
||||
"notes": "After Frontier decode-preemption lifecycle fix.",
|
||||
"prefix_hit_delta": -0.038413257842607046,
|
||||
"request_count": 200,
|
||||
"rps_ratio": 0.7393232177681209,
|
||||
"run_id": "tp1_n200_scale2",
|
||||
"scale_label": "2",
|
||||
"scale_value": 2.0,
|
||||
"total_tps_ratio": 0.7393232177681209,
|
||||
"tp": 1,
|
||||
"tpot_p50_ratio": 1.0907433399899442,
|
||||
"tpot_p95_ratio": 0.9693811149298648,
|
||||
"ttft_p50_ratio": 1.0410723384685256,
|
||||
"ttft_p95_ratio": 1.1198067467817787,
|
||||
"vllm_completed": 200,
|
||||
"vllm_decode_tps": 718.9814830849542,
|
||||
"vllm_e2e_p50_s": 55.002487340942025,
|
||||
"vllm_e2e_p95_s": 142.3375087250024,
|
||||
"vllm_preemptions": 43,
|
||||
"vllm_prefix_hit": 0.2697549478423476,
|
||||
"vllm_rps": 0.8029813635231063,
|
||||
"vllm_total": 200,
|
||||
"vllm_total_tps": 4742.53640998563,
|
||||
"vllm_tpot_p50_s": 0.049703375188695206,
|
||||
"vllm_tpot_p95_s": 0.06863309532102842,
|
||||
"vllm_ttft_p50_s": 9.216767095960677,
|
||||
"vllm_ttft_p95_s": 69.2114159471821
|
||||
},
|
||||
{
|
||||
"decode_tps_ratio": 0.7356557719569122,
|
||||
"e2e_p50_ratio": 1.3476957295017153,
|
||||
"e2e_p95_ratio": 1.258652459348984,
|
||||
"fixture": "coder_200_ts3",
|
||||
"frontier_complete": true,
|
||||
"frontier_completed": 200,
|
||||
"frontier_decode_tps": 513.9343093668691,
|
||||
"frontier_e2e_p50_s": 44.76058145123308,
|
||||
"frontier_e2e_p95_s": 154.54831351855702,
|
||||
"frontier_preemptions": 20,
|
||||
"frontier_prefix_hit": 0.21767512777477313,
|
||||
"frontier_rps": 0.573978165231764,
|
||||
"frontier_total": 200,
|
||||
"frontier_total_tps": 3390.0068803652352,
|
||||
"frontier_tpot_p50_s": 0.053393334371887605,
|
||||
"frontier_tpot_p95_s": 0.06861254670772189,
|
||||
"frontier_ttft_p50_s": 1.0014741156186515,
|
||||
"frontier_ttft_p95_s": 45.94665669959886,
|
||||
"kv_blocks": 15281,
|
||||
"label": "TP1 N200 scale 3",
|
||||
"notes": "After Frontier decode-preemption lifecycle fix.",
|
||||
"prefix_hit_delta": -0.05207982006757447,
|
||||
"request_count": 200,
|
||||
"rps_ratio": 0.7356557719569123,
|
||||
"run_id": "tp1_n200_scale3",
|
||||
"scale_label": "3",
|
||||
"scale_value": 3.0,
|
||||
"total_tps_ratio": 0.7356557719569123,
|
||||
"tp": 1,
|
||||
"tpot_p50_ratio": 1.1566613307426805,
|
||||
"tpot_p95_ratio": 0.9611804148017213,
|
||||
"ttft_p50_ratio": 0.8587856162345445,
|
||||
"ttft_p95_ratio": 1.4243304641052532,
|
||||
"vllm_completed": 200,
|
||||
"vllm_decode_tps": 698.607050957755,
|
||||
"vllm_e2e_p50_s": 33.2126758818049,
|
||||
"vllm_e2e_p95_s": 122.78871134808287,
|
||||
"vllm_preemptions": 16,
|
||||
"vllm_prefix_hit": 0.2697549478423476,
|
||||
"vllm_rps": 0.7802265503945264,
|
||||
"vllm_total": 200,
|
||||
"vllm_total_tps": 4608.1428428781355,
|
||||
"vllm_tpot_p50_s": 0.04616159713544178,
|
||||
"vllm_tpot_p95_s": 0.07138362959869063,
|
||||
"vllm_ttft_p50_s": 1.1661514779552817,
|
||||
"vllm_ttft_p95_s": 32.25842447206378
|
||||
},
|
||||
{
|
||||
"decode_tps_ratio": 0.6070363250137228,
|
||||
"e2e_p50_ratio": 1.5837949050918096,
|
||||
"e2e_p95_ratio": 1.4718353941122981,
|
||||
"fixture": "coder_200_ts2",
|
||||
"frontier_complete": true,
|
||||
"frontier_completed": 200,
|
||||
"frontier_decode_tps": 694.538225813865,
|
||||
"frontier_e2e_p50_s": 26.05122481685102,
|
||||
"frontier_e2e_p95_s": 106.75916510714146,
|
||||
"frontier_preemptions": 0,
|
||||
"frontier_prefix_hit": 0.2697549478423476,
|
||||
"frontier_rps": 0.7756823572006221,
|
||||
"frontier_total": 200,
|
||||
"frontier_total_tps": 4581.304110804026,
|
||||
"frontier_tpot_p50_s": 0.042955276577521156,
|
||||
"frontier_tpot_p95_s": 0.05288764732371923,
|
||||
"frontier_ttft_p50_s": 0.2690959621493789,
|
||||
"frontier_ttft_p95_s": 6.744624223172184,
|
||||
"kv_blocks": 69055,
|
||||
"label": "TP2 N200 scale 2",
|
||||
"notes": "Uses true-mixed TP2/TP4 attention profile.",
|
||||
"prefix_hit_delta": 0.0,
|
||||
"request_count": 200,
|
||||
"rps_ratio": 0.6070363250137228,
|
||||
"run_id": "tp2_n200_scale2",
|
||||
"scale_label": "2",
|
||||
"scale_value": 2.0,
|
||||
"total_tps_ratio": 0.6070363250137228,
|
||||
"tp": 2,
|
||||
"tpot_p50_ratio": 1.4296981582601855,
|
||||
"tpot_p95_ratio": 1.218502045500008,
|
||||
"ttft_p50_ratio": 1.1953492307083635,
|
||||
"ttft_p95_ratio": 9.432094021900193,
|
||||
"vllm_completed": 200,
|
||||
"vllm_decode_tps": 1144.1460703330465,
|
||||
"vllm_e2e_p50_s": 16.448610065039247,
|
||||
"vllm_e2e_p95_s": 72.53471789998002,
|
||||
"vllm_preemptions": 0,
|
||||
"vllm_prefix_hit": 0.2697549478423476,
|
||||
"vllm_rps": 1.2778186827338327,
|
||||
"vllm_total": 200,
|
||||
"vllm_total_tps": 7547.001591215254,
|
||||
"vllm_tpot_p50_s": 0.030044996791346416,
|
||||
"vllm_tpot_p95_s": 0.043403823177019754,
|
||||
"vllm_ttft_p50_s": 0.22511911601759493,
|
||||
"vllm_ttft_p95_s": 0.7150717759504914
|
||||
},
|
||||
{
|
||||
"decode_tps_ratio": 0.6321128225155744,
|
||||
"e2e_p50_ratio": 2.1882239414176055,
|
||||
"e2e_p95_ratio": 1.8819058641979227,
|
||||
"fixture": "coder_200_ts3",
|
||||
"frontier_complete": true,
|
||||
"frontier_completed": 200,
|
||||
"frontier_decode_tps": 615.822856748031,
|
||||
"frontier_e2e_p50_s": 21.785964943721574,
|
||||
"frontier_e2e_p95_s": 101.59183927019191,
|
||||
"frontier_preemptions": 0,
|
||||
"frontier_prefix_hit": 0.2697549478423476,
|
||||
"frontier_rps": 0.6877705321122985,
|
||||
"frontier_total": 200,
|
||||
"frontier_total_tps": 4062.0828059403734,
|
||||
"frontier_tpot_p50_s": 0.0393789684875167,
|
||||
"frontier_tpot_p95_s": 0.04670767224504207,
|
||||
"frontier_ttft_p50_s": 0.13415354950526392,
|
||||
"frontier_ttft_p95_s": 0.574137821753455,
|
||||
"kv_blocks": 69055,
|
||||
"label": "TP2 N200 scale 3",
|
||||
"notes": "Uses true-mixed TP2/TP4 attention profile.",
|
||||
"prefix_hit_delta": 0.0,
|
||||
"request_count": 200,
|
||||
"rps_ratio": 0.6321128225155745,
|
||||
"run_id": "tp2_n200_scale3",
|
||||
"scale_label": "3",
|
||||
"scale_value": 3.0,
|
||||
"total_tps_ratio": 0.6321128225155745,
|
||||
"tp": 2,
|
||||
"tpot_p50_ratio": 2.066305230245682,
|
||||
"tpot_p95_ratio": 1.668678182045304,
|
||||
"ttft_p50_ratio": 0.8737883511042303,
|
||||
"ttft_p95_ratio": 0.9156237864420547,
|
||||
"vllm_completed": 200,
|
||||
"vllm_decode_tps": 974.229338201501,
|
||||
"vllm_e2e_p50_s": 9.956003373954445,
|
||||
"vllm_e2e_p95_s": 53.98348621092737,
|
||||
"vllm_preemptions": 0,
|
||||
"vllm_prefix_hit": 0.2697549478423476,
|
||||
"vllm_rps": 1.0880502777577379,
|
||||
"vllm_total": 200,
|
||||
"vllm_total_tps": 6426.199028481642,
|
||||
"vllm_tpot_p50_s": 0.01905767256023186,
|
||||
"vllm_tpot_p95_s": 0.02799082096692385,
|
||||
"vllm_ttft_p50_s": 0.15353094297461212,
|
||||
"vllm_ttft_p95_s": 0.6270455510821193
|
||||
},
|
||||
{
|
||||
"decode_tps_ratio": 0.554961482872708,
|
||||
"e2e_p50_ratio": 2.0140798462106178,
|
||||
"e2e_p95_ratio": 1.9471360828275543,
|
||||
"fixture": "coder_200_ts2",
|
||||
"frontier_complete": true,
|
||||
"frontier_completed": 200,
|
||||
"frontier_decode_tps": 763.3502329676248,
|
||||
"frontier_e2e_p50_s": 18.65216281946347,
|
||||
"frontier_e2e_p95_s": 84.93775413567799,
|
||||
"frontier_preemptions": 0,
|
||||
"frontier_prefix_hit": 0.2697549478423476,
|
||||
"frontier_rps": 0.8525337930595883,
|
||||
"frontier_total": 200,
|
||||
"frontier_total_tps": 5035.200987216818,
|
||||
"frontier_tpot_p50_s": 0.03366585046876145,
|
||||
"frontier_tpot_p95_s": 0.03838265621202119,
|
||||
"frontier_ttft_p50_s": 0.09755515041058871,
|
||||
"frontier_ttft_p95_s": 0.3856872342439675,
|
||||
"kv_blocks": 177077,
|
||||
"label": "TP4 N200 scale 2",
|
||||
"notes": "Uses true-mixed TP2/TP4 attention profile.",
|
||||
"prefix_hit_delta": 0.0,
|
||||
"request_count": 200,
|
||||
"rps_ratio": 0.5549614828727081,
|
||||
"run_id": "tp4_n200_scale2",
|
||||
"scale_label": "2",
|
||||
"scale_value": 2.0,
|
||||
"total_tps_ratio": 0.5549614828727081,
|
||||
"tp": 4,
|
||||
"tpot_p50_ratio": 2.0597817670263323,
|
||||
"tpot_p95_ratio": 1.3554681431066735,
|
||||
"ttft_p50_ratio": 0.5721801588631308,
|
||||
"ttft_p95_ratio": 0.27163724014492546,
|
||||
"vllm_completed": 200,
|
||||
"vllm_decode_tps": 1375.5012852715674,
|
||||
"vllm_e2e_p50_s": 9.26088548800908,
|
||||
"vllm_e2e_p95_s": 43.621889032190666,
|
||||
"vllm_preemptions": 0,
|
||||
"vllm_prefix_hit": 0.2697549478423476,
|
||||
"vllm_rps": 1.5362035373095158,
|
||||
"vllm_total": 200,
|
||||
"vllm_total_tps": 9073.06388391597,
|
||||
"vllm_tpot_p50_s": 0.016344377354773947,
|
||||
"vllm_tpot_p95_s": 0.02831690025857032,
|
||||
"vllm_ttft_p50_s": 0.1704972619190812,
|
||||
"vllm_ttft_p95_s": 1.4198614079505205
|
||||
},
|
||||
{
|
||||
"decode_tps_ratio": 0.5882440161960838,
|
||||
"e2e_p50_ratio": 3.045852424279607,
|
||||
"e2e_p95_ratio": 2.9785685814353515,
|
||||
"fixture": "coder_200_ts3",
|
||||
"frontier_complete": true,
|
||||
"frontier_completed": 200,
|
||||
"frontier_decode_tps": 660.2306058712501,
|
||||
"frontier_e2e_p50_s": 16.902919407154563,
|
||||
"frontier_e2e_p95_s": 83.00995364867583,
|
||||
"frontier_preemptions": 0,
|
||||
"frontier_prefix_hit": 0.2697549478423476,
|
||||
"frontier_rps": 0.7373665172396945,
|
||||
"frontier_total": 200,
|
||||
"frontier_total_tps": 4355.004629460394,
|
||||
"frontier_tpot_p50_s": 0.031067781092248118,
|
||||
"frontier_tpot_p95_s": 0.035782850818878296,
|
||||
"frontier_ttft_p50_s": 0.08859749134958328,
|
||||
"frontier_ttft_p95_s": 0.3458954617429286,
|
||||
"kv_blocks": 177077,
|
||||
"label": "TP4 N200 scale 3",
|
||||
"notes": "Uses true-mixed TP2/TP4 attention profile.",
|
||||
"prefix_hit_delta": 0.0,
|
||||
"request_count": 200,
|
||||
"rps_ratio": 0.5882440161960838,
|
||||
"run_id": "tp4_n200_scale3",
|
||||
"scale_label": "3",
|
||||
"scale_value": 3.0,
|
||||
"total_tps_ratio": 0.5882440161960839,
|
||||
"tp": 4,
|
||||
"tpot_p50_ratio": 3.301471070786272,
|
||||
"tpot_p95_ratio": 2.7971158799197804,
|
||||
"ttft_p50_ratio": 0.8850343170011207,
|
||||
"ttft_p95_ratio": 1.086290918512101,
|
||||
"vllm_completed": 200,
|
||||
"vllm_decode_tps": 1122.3753879226379,
|
||||
"vllm_e2e_p50_s": 5.549487320007756,
|
||||
"vllm_e2e_p95_s": 27.869075825903565,
|
||||
"vllm_preemptions": 0,
|
||||
"vllm_prefix_hit": 0.2697549478423476,
|
||||
"vllm_rps": 1.2535044929278167,
|
||||
"vllm_total": 200,
|
||||
"vllm_total_tps": 7403.398095950554,
|
||||
"vllm_tpot_p50_s": 0.00941028421153152,
|
||||
"vllm_tpot_p95_s": 0.01279276667647553,
|
||||
"vllm_ttft_p50_s": 0.1001062779687345,
|
||||
"vllm_ttft_p95_s": 0.3184188101440668
|
||||
}
|
||||
]
|
||||
BIN
docs/assets/frontier_vllm_alignment/latency_ratios.png
Normal file
BIN
docs/assets/frontier_vllm_alignment/latency_ratios.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 90 KiB |
BIN
docs/assets/frontier_vllm_alignment/throughput_ratio.png
Normal file
BIN
docs/assets/frontier_vllm_alignment/throughput_ratio.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 91 KiB |
BIN
docs/assets/frontier_vllm_alignment/tp_scaling_total_tps.png
Normal file
BIN
docs/assets/frontier_vllm_alignment/tp_scaling_total_tps.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 91 KiB |
253
docs/comparison.md
Normal file
253
docs/comparison.md
Normal file
@@ -0,0 +1,253 @@
|
||||
# RS2 Simulator Comparison
|
||||
|
||||
Checked on 2026-06-24. RS2 compares simulator capabilities and first local
|
||||
ReplayServe results. It does not start the RS3 sweep and does not make
|
||||
performance-quality claims.
|
||||
|
||||
## Sources
|
||||
|
||||
| Source | Local path | Commit / HEAD | RS2 use |
|
||||
|---|---|---:|---|
|
||||
| ReplayServe | `/home/gahow/phd/replayserve` | local RS0/RS1/RS1B artifacts | Adapter, fixtures, runs, postprocess summaries |
|
||||
| Qwen trace | `/home/gahow/phd/qwen-bailian-usagetraces-anon` | `5f7439c51ec248a0c585f7d90a41a6f57773b912` | Source `qwen_coder_blksz_16.jsonl` |
|
||||
| Frontier canonical | `/tmp/toc-llm-sim-research/Frontier` | `d9cfeb6d8791fbf2f295dd9744c56a666171776e` | RS1 fixed config and source inspection |
|
||||
| Frontier patched scratch | `/tmp/replayserve-frontier-rs1b` | base `d9cfeb6...` plus `patches/frontier-vllm-v1-prefix-cache-chunked-prefill.patch` | RS1B unblock verification |
|
||||
| Vidur | `/tmp/toc-llm-sim-research/vidur` | `8383d2935bc62723a212090baa9f98ada206fc14` | Source inspection for baseline capability |
|
||||
| AIConfigurator | `/tmp/toc-llm-sim-research/aiconfigurator` | `e46ece7510e727fafefb8212e5846172145a30ea` | Source/docs inspection for config-estimator capability |
|
||||
|
||||
Key local evidence:
|
||||
|
||||
- Frontier trace replay: `/tmp/toc-llm-sim-research/Frontier/frontier/request_generator/trace_replay_request_generator.py`
|
||||
- Frontier prefix-cache validation: `/tmp/toc-llm-sim-research/Frontier/frontier/scheduler/cluster_scheduler/base_cluster_scheduler.py`
|
||||
- Frontier prefix-cache request metrics: `/tmp/toc-llm-sim-research/Frontier/frontier/metrics/metrics_store.py`
|
||||
- Vidur trace replay: `/tmp/toc-llm-sim-research/vidur/vidur/request_generator/trace_replay_request_generator.py`
|
||||
- Vidur request entity: `/tmp/toc-llm-sim-research/vidur/vidur/entities/request.py`
|
||||
- AIConfigurator CLI/docs: `/tmp/toc-llm-sim-research/aiconfigurator/README.md` and `/tmp/toc-llm-sim-research/aiconfigurator/src/aiconfigurator/cli/main.py`
|
||||
|
||||
## Capability Matrix
|
||||
|
||||
| Capability | Frontier | Vidur | AIConfigurator |
|
||||
|---|---|---|---|
|
||||
| Per-request timestamp replay | Yes. `trace_replay` consumes `arrived_at` and RS1 runs `simulation_mode=online`. | Yes. `TraceReplayRequestGenerator` consumes `arrived_at`. | No per-request replay. CLI consumes workload summaries such as `--isl`, `--osl`, and SLA targets. |
|
||||
| Input/output length replay | Yes. Consumes `num_prefill_tokens` and `num_decode_tokens`. Frontier can clip overflows internally, so ReplayServe adapter validates before run. | Yes. Consumes `num_prefill_tokens` and `num_decode_tokens`; current code clips prefill length if total exceeds max tokens. | Only summary lengths, not per-request traces. |
|
||||
| Explicit `block_hash_ids` / prefix KV reuse replay | Yes. Current Frontier parses `session_id` and `block_hash_ids`, validates they are present when prefix caching is enabled, and applies prefix-cache accounting in vLLM v1. RS1B needs a patch for prefix cache plus chunked prefill under pressure. | No in this checkout. Request objects carry arrival/prefill/decode lengths and processed-token state, but no `session_id`, block hashes, or explicit prefix-reuse replay. README says prefix-caching work lives on a canary branch with sharp edges, not this main checkout. | No. `--prefix` is an aggregate prefix length/workload parameter, not an explicit hash/session replay model. |
|
||||
| Online arrival pattern | Yes. RS1 fixed config uses online mode and trace replay. | Yes for trace replay baseline. | No event-level online replay. It estimates candidate deployments from summary workload/SLA inputs. |
|
||||
| Prefix-cache hit-ratio output | Yes. Frontier emits request metrics including cached prefill tokens, query blocks, and hit blocks when present. ReplayServe postprocess adds token-weighted hit ratio using sidecar partial-block counts. | No native prefix-hit ratio in current main because no explicit prefix replay. | No prefix-hit replay metric. |
|
||||
| TTFT / TPOT / E2E / throughput output | Yes. Request and system metrics are emitted under Frontier metrics dirs. RS1 uses dummy execution predictor, so values are plumbing-only. | Yes. Vidur metrics include request E2E, prefill/TTFT-style, decode-normalized, and system metrics. Fidelity depends on matching profiles. | Yes as estimates: best throughput, per-GPU throughput, per-user throughput, TTFT, TPOT, and request latency. These are configuration-search outputs, not replay observations. |
|
||||
| TP / EP / DP / config knobs | Yes. Frontier has model, device, network device, attention TP/DP, MoE TP/EP, PP, scheduler, block, batch, prefix-cache, chunked-prefill, and memory-planner knobs. | Partial. Vidur exposes model, device, network device, tensor parallel size, pipeline stages, scheduler and batch/KV knobs. The inspected checkout is not a faithful EP/DP prefix-replay candidate. | Strong for config search. Supports TP/PP/DP and expert TP/EP style search across supported backends/systems. |
|
||||
| Arbitrary model/hardware/config boundary | Not arbitrary. Model/device configs may exist, but reliable latency/throughput requires compute/network profiles, scheduler support, matching parallel semantics, and bug-free code paths. RS1 Qwen3-32B on A800 uses dummy predictor because public A800 dense Qwen3-32B compute profiles are absent. | Not arbitrary. README lists supported model/device/profile combinations; docs say profiling on actual GPUs is needed for new model/hardware fidelity. Current public device/profile coverage does not match A800 Qwen3-32B. | Not arbitrary. It depends on supported model families, backend/system databases, and estimate modes. The support matrix includes H100/H200/B200/GB200/A100 variants; no A800 built-in silicon database was found. |
|
||||
| Needs profile/calibration | Yes for performance claims. Dummy predictor plus analytical comm is only a smoke. | Yes for performance claims. New model/device requires compute, network, and CPU-overhead style profiling. | Yes for production-quality estimates. It relies on collected silicon/perf databases or rough estimate modes; README warns memory/results need validation. |
|
||||
|
||||
## First Results
|
||||
|
||||
### Frontier Canonical
|
||||
|
||||
Fixed RS1 config:
|
||||
|
||||
- `simulation_mode=online`
|
||||
- `sys_arch=co-location`
|
||||
- `replica_scheduler=vllm_v1`
|
||||
- `device=a800`
|
||||
- `network_device=a800_dgx`
|
||||
- `model_name=Qwen/Qwen3-32B`
|
||||
- `attn_tensor_parallel_size=2`
|
||||
- dummy execution predictor
|
||||
- analytical communication backend
|
||||
- `trace_request_generator_config_max_tokens=32768`
|
||||
- prefix caching enabled
|
||||
- block size 16
|
||||
- chunked prefill enabled
|
||||
- batch cap 128
|
||||
- max batch tokens 32768
|
||||
- KV capacity from Frontier memory planner with `gpu_memory_utilization=0.9` and `non_kv_cache_overhead_bytes=0`
|
||||
|
||||
Results:
|
||||
|
||||
| Run | Result | Evidence | Notes |
|
||||
|---|---|---|---|
|
||||
| `coder_100` | Pass | `runs/rs1/coder_100/` | Frontier block hit ratio `0.04948661841440835`; ReplayServe token-weighted hit ratio `0.04956232588915065`; no preemptions. |
|
||||
| `coder_2000` | Fail | `runs/rs1/coder_2000/` | Exit code 1 after 4 seconds with `ValueError: Request 194 already scheduled.` Traceback ends at Frontier vLLM v1 waiting scheduling calling `request.on_cache_hit(prefix_cached_tokens)`. |
|
||||
|
||||
The canonical failure was minimized in `docs/rs1_frontier_blocker.md`: first-N
|
||||
`N=192` passes, `N=193` fails as `Request 192 already scheduled`, and larger
|
||||
fixed-config probes fail around the same preempted prefix-cache path. Prefix off,
|
||||
chunked-prefill off, or a high long-prefill threshold avoids the failure, so this
|
||||
is not a bad Qwen trace row.
|
||||
|
||||
### Frontier Patched Scratch
|
||||
|
||||
Patch:
|
||||
|
||||
- File: `patches/frontier-vllm-v1-prefix-cache-chunked-prefill.patch`
|
||||
- Documentation: `docs/rs1_frontier_patch.md`
|
||||
- Scratch checkout only: `/tmp/replayserve-frontier-rs1b`
|
||||
|
||||
The patch resets preempted request scheduler/cache-hit admission state before
|
||||
the request re-enters the waiting path. As of 2026-06-25 it also replays
|
||||
decode-phase preemption by moving already-produced tokens into the next prefill
|
||||
segment, preserves user-facing lengths for metrics, and fails fast if
|
||||
sequential simulation drains before all generated requests complete. It keeps
|
||||
the canonical Frontier checkout clean.
|
||||
|
||||
| Run | Result | Evidence | Hit ratios | Preemption | Memory planner facts |
|
||||
|---|---|---|---|---|---|
|
||||
| `N=193` fixed config | Pass | `runs/rs1b/patched/n193_fixed_v2/` | Frontier block `0.12458971786194112`; ReplayServe token-weighted `0.12476981408429115` | 5 total events, 1 request | `num_blocks=36902`, `gpu_memory_utilization=0.9`, non-KV overhead `0`, weight shard estimate `26.953125 GiB` |
|
||||
| `coder_100` fixed config | Pass | `runs/rs1b/patched/coder_100/` | Frontier block `0.04948661841440835`; ReplayServe token-weighted `0.04956232588915065` | 0 | same derived memory planner point |
|
||||
| `coder_2000` fixed config | Pass | `runs/rs1b/patched/coder_2000/` | Frontier block `0.12318930248025924`; ReplayServe token-weighted `0.12332978217090633` | 35940 total events, 1061 requests | same derived memory planner point |
|
||||
|
||||
Metrics caveats:
|
||||
|
||||
- These are plumbing-smoke metrics. The run uses dummy 1 ms execution time and
|
||||
analytical communication, not calibrated Qwen3-32B A800 compute profiles.
|
||||
- `coder_2000` produced `request_metrics.csv` with 2000 rows, but 745 rows have
|
||||
blank request-level prefix-cache fields. ReplayServe token-weighted hit ratio
|
||||
therefore uses the 1255 rows with complete cache metrics. Frontier's aggregate
|
||||
prefix-cache statistics in the same summary also report 1255 requests with
|
||||
cache metrics. This is acceptable for blocker removal evidence, but it is not
|
||||
a final metric-quality result.
|
||||
- No allocation/OOM pressure log lines were found in the postprocess summaries.
|
||||
|
||||
### Vidur
|
||||
|
||||
No Vidur baseline run was executed for RS2. Based on source inspection, Vidur is
|
||||
useful as an arrival-and-length baseline candidate, but it cannot faithfully
|
||||
compare ReplayServe prefix reuse without additional code:
|
||||
|
||||
- `vidur/request_generator/trace_replay_request_generator.py` consumes
|
||||
`arrived_at`, `num_prefill_tokens`, and `num_decode_tokens`.
|
||||
- `vidur/entities/request.py` stores arrival, prefill length, decode length,
|
||||
processed tokens, schedule/completion timestamps, and preemption state.
|
||||
- The inspected request path does not carry `session_id`, `block_hash_ids`, or
|
||||
sidecar block-token accounting.
|
||||
- Current Vidur trace replay clips prefill lengths when total tokens exceed
|
||||
`max_tokens`; ReplayServe must keep its own hard-fail validation if Vidur is
|
||||
used later as a length-only baseline.
|
||||
|
||||
Conclusion for Vidur in RS2: it can likely replay `coder_100`/`coder_2000`
|
||||
arrival and length after a simple CSV compatibility conversion, but it would
|
||||
measure a different workload because prefix KV reuse is absent.
|
||||
|
||||
### AIConfigurator
|
||||
|
||||
No AIConfigurator run was executed for RS2 because it is not a per-request
|
||||
replay simulator. Source/docs show it is a deployment/config search estimator:
|
||||
|
||||
- CLI examples take workload summaries such as `--isl`, `--osl`, `--prefix`,
|
||||
`--ttft`, `--tpot`, `--total-gpus`, `--system`, and model path.
|
||||
- Outputs are best throughput, per-GPU throughput, per-user throughput, TTFT,
|
||||
TPOT, request latency, concurrency, and parallel deployment choices.
|
||||
- It models operations and searches aggregated/disaggregated serving
|
||||
configurations using collected or estimated performance data.
|
||||
|
||||
Conclusion for AIConfigurator in RS2: it is useful for config candidates and
|
||||
reference sizing assumptions. It cannot directly compare faithful per-request
|
||||
prefix-hit replay on Qwen trace fixtures.
|
||||
|
||||
## Metric Definitions
|
||||
|
||||
`TTFT`:
|
||||
Time from request arrival to first generated token / prefill completion. Frontier
|
||||
and Vidur both have request-level prefill/first-token style timing fields, but
|
||||
RS1 Frontier values are not performance claims because the execution predictor is
|
||||
dummy.
|
||||
|
||||
`TPOT`:
|
||||
Decode time per output token. Tools differ on whether they report total decode
|
||||
normalized by output tokens, inter-token latency, or a configured SLA target.
|
||||
Use each tool's native field only within that tool unless calibrated against the
|
||||
same serving definition.
|
||||
|
||||
`E2E latency`:
|
||||
Completion time minus arrival time for one request.
|
||||
|
||||
`Throughput`:
|
||||
Completed tokens or requests per unit time. AIConfigurator reports estimated
|
||||
tokens/s style capacity; Frontier/Vidur report simulated metrics. RS1 Frontier
|
||||
throughput is plumbing-only because compute is dummy.
|
||||
|
||||
`KV-cache hit ratio`:
|
||||
|
||||
- Frontier native block-level ratio:
|
||||
`sum(request_prefix_cache_hit_blocks) / sum(request_prefix_cache_query_blocks)`.
|
||||
- ReplayServe token-weighted ratio:
|
||||
use sidecar `block_token_counts` and count the first
|
||||
`request_prefix_cache_hit_blocks` blocks by true token count, so a partial
|
||||
final block contributes its actual token count instead of always 16.
|
||||
|
||||
For `coder_2000` patched, both ratios are computed only for request rows with
|
||||
complete cache fields because 745 request metric rows have blank cache fields.
|
||||
This is a metrics completeness caveat, not evidence that the trace has invalid
|
||||
hashes.
|
||||
|
||||
## Non-Comparable Items
|
||||
|
||||
- Frontier canonical and patched scratch are not equivalent artifacts. The
|
||||
patched result demonstrates an RS1 unblock path; it is not an upstream
|
||||
Frontier release.
|
||||
- Frontier/Vidur simulator timings and AIConfigurator estimator timings are not
|
||||
directly comparable without shared profiles, calibration, and metric
|
||||
definitions.
|
||||
- Prefix-reuse fidelity is not comparable across all three tools. Only Frontier
|
||||
currently consumes explicit block hash traces in the inspected checkouts.
|
||||
- AIConfigurator's `prefix` workload parameter is not the same as ReplayServe
|
||||
`block_hash_ids`; it cannot recover session-level sharing or partial-block
|
||||
token accounting.
|
||||
|
||||
## Conclusions
|
||||
|
||||
There is no best open-source implementation that satisfies ReplayServe's target
|
||||
out of the box.
|
||||
|
||||
Frontier is the closest because it supports online trace replay, prefix-cache
|
||||
metadata, vLLM v1 style scheduler controls, memory planning, and request/system
|
||||
metrics. It is still not out of the box for ReplayServe: RS0 needed an adapter,
|
||||
RS1B needed a local patch or upstream fix for prefix cache plus chunked prefill,
|
||||
and performance-quality claims need Qwen3-32B A800 profiles/calibration.
|
||||
|
||||
Vidur can be a useful arrival-plus-length baseline, but not a faithful prefix KV
|
||||
reuse replay engine in the inspected checkout.
|
||||
|
||||
AIConfigurator can guide candidate deployment/config choices, but it is a
|
||||
workload-summary estimator rather than a per-request simulator.
|
||||
|
||||
Frontier also does not support arbitrary model plus arbitrary hardware plus
|
||||
arbitrary config in a performance-reliable sense. A model/device config may be
|
||||
accepted syntactically, but fidelity depends on compute profiles, network
|
||||
profiles, scheduler support, parallelism semantics, memory-planner assumptions,
|
||||
and bug surface. For RS1, A800 network profiles exist, but the public checkout
|
||||
does not provide dense Qwen3-32B A800 compute profiles, so latency/throughput
|
||||
remain plumbing smoke.
|
||||
|
||||
## Next Steps
|
||||
|
||||
RS3 sweep prerequisites:
|
||||
|
||||
- Decide whether RS3 uses the local RS1B patch, waits for upstream Frontier, or
|
||||
carries both canonical and patched modes explicitly.
|
||||
- Keep fixed-config smoke and any sweep configs separate from performance claims.
|
||||
- Add a small run manifest/check script that records Frontier commit, patch
|
||||
status, fixture, command, and metric completeness.
|
||||
- Treat the `coder_2000` blank cache fields as a metrics issue to investigate
|
||||
before using request-level hit ratios as a headline metric.
|
||||
|
||||
RS4 calibration prerequisites:
|
||||
|
||||
- Collect or obtain dense `Qwen/Qwen3-32B` A800 compute profiles for the Frontier
|
||||
predictor path.
|
||||
- Verify the A800 network profile and node SKU semantics match the target
|
||||
deployment.
|
||||
- Add non-KV memory overhead assumptions from a real serving stack instead of
|
||||
using `0`.
|
||||
- Validate simulator TTFT/TPOT/E2E/throughput against measured vLLM runs before
|
||||
making performance conclusions.
|
||||
|
||||
Patch path recommendation:
|
||||
|
||||
- Keep `patches/frontier-vllm-v1-prefix-cache-chunked-prefill.patch` pinned in
|
||||
ReplayServe until an upstream Frontier fix is available; it now covers both
|
||||
the original prefix-cache/chunked-prefill preemption bug and the RS10
|
||||
decode-phase preemption lifecycle bug.
|
||||
- Open an upstream issue or PR with the RS1B minimal repro (`N=193`) and
|
||||
evidence from `docs/rs1_frontier_blocker.md`.
|
||||
- Re-run `coder_100`, `N=193`, and `coder_2000` when changing Frontier commit or
|
||||
patch status.
|
||||
177
docs/frontier_vllm_alignment_summary_20260625.md
Normal file
177
docs/frontier_vllm_alignment_summary_20260625.md
Normal file
@@ -0,0 +1,177 @@
|
||||
# Frontier vs vLLM H20 Alignment Summary
|
||||
|
||||
Date: 2026-06-25
|
||||
|
||||
This document summarizes the current ReplayServe comparison between Frontier
|
||||
simulation and real vLLM runs on H20 for Qwen3-30B-A3B. It covers TP=1/2/4,
|
||||
different timestamp scales, and 100/200/500-request windows from
|
||||
`qwen_coder_blksz_16.jsonl`.
|
||||
|
||||
The source data and plots are generated by:
|
||||
|
||||
```bash
|
||||
~/.venv/plot/bin/python tools/build_frontier_vllm_alignment_report.py
|
||||
```
|
||||
|
||||
Generated artifacts:
|
||||
|
||||
- `docs/assets/frontier_vllm_alignment/frontier_vllm_alignment.csv`
|
||||
- `docs/assets/frontier_vllm_alignment/frontier_vllm_alignment.json`
|
||||
- `docs/assets/frontier_vllm_alignment/throughput_ratio.png`
|
||||
- `docs/assets/frontier_vllm_alignment/latency_ratios.png`
|
||||
- `docs/assets/frontier_vllm_alignment/tp_scaling_total_tps.png`
|
||||
- `docs/assets/frontier_vllm_alignment/completion_prefix.png`
|
||||
|
||||
## Bottom Line
|
||||
|
||||
Functional replay is now usable for the clean 200-request runs:
|
||||
|
||||
- TP1 scale 2/3 after the Frontier lifecycle fix: `200/200` completed.
|
||||
- TP2/TP4 scale 2/3: `200/200` completed, no preemption on either side, matched
|
||||
vLLM KV block counts, and exact trace-side prefix reuse ratio.
|
||||
|
||||
Performance is not fully calibrated:
|
||||
|
||||
- TP1 scale 2/3 is the closest current operating point: Frontier throughput is
|
||||
about `0.74x` vLLM and TPOT p50/p95 is close.
|
||||
- TP2/TP4 is functionally aligned but slower: Frontier throughput is only
|
||||
`0.55-0.63x` vLLM, and TP4 TPOT is too pessimistic.
|
||||
- Frontier underestimates the TP2->TP4 speedup. vLLM improves total throughput
|
||||
by `1.15-1.20x`; Frontier improves by only `1.07-1.10x`.
|
||||
|
||||
Current use: acceptable for integration work and rough qualitative trends, not
|
||||
yet acceptable as a calibrated absolute performance predictor.
|
||||
|
||||
## Run Matrix
|
||||
|
||||
All vLLM runs use vLLM 0.11.1, H20, Qwen3-30B-A3B,
|
||||
`max_model_len=32768`, `max_num_seqs=64`,
|
||||
`max_num_batched_tokens=32768`, `gpu_memory_utilization=0.85`, prefix caching,
|
||||
and chunked prefill.
|
||||
|
||||
| run | Frontier rows | preempt F/V | prefix hit F/V | total tok/s F/V | ratio | TPOT p50 F/V | E2E p95 F/V |
|
||||
|---|---:|---:|---:|---:|---:|---:|---:|
|
||||
| TP1 N100 raw | 96/100 | 0/8 | 0.249/0.251 | 2349/3832 | 0.61 | 0.0569/0.0661s | 119.6/97.4s |
|
||||
| TP1 N500 raw | 439/500 | 0/63 | 0.119/0.387 | 4734/5283 | 0.90 | 0.0564/0.0498s | 397.3/417.4s |
|
||||
| TP1 N200 scale 0.667 | 176/200 | 0/26 | 0.170/0.270 | 3913/4865 | 0.80 | 0.0584/0.0515s | 189.2/183.7s |
|
||||
| TP1 N200 scale 2 | 200/200 | 33/43 | 0.231/0.270 | 3506/4743 | 0.74 | 0.0542/0.0497s | 174.5/142.3s |
|
||||
| TP1 N200 scale 3 | 200/200 | 20/16 | 0.218/0.270 | 3390/4608 | 0.74 | 0.0534/0.0462s | 154.5/122.8s |
|
||||
| TP2 N200 scale 2 | 200/200 | 0/0 | 0.270/0.270 | 4581/7547 | 0.61 | 0.0430/0.0300s | 106.8/72.5s |
|
||||
| TP2 N200 scale 3 | 200/200 | 0/0 | 0.270/0.270 | 4062/6426 | 0.63 | 0.0394/0.0191s | 101.6/54.0s |
|
||||
| TP4 N200 scale 2 | 200/200 | 0/0 | 0.270/0.270 | 5035/9073 | 0.55 | 0.0337/0.0163s | 84.9/43.6s |
|
||||
| TP4 N200 scale 3 | 200/200 | 0/0 | 0.270/0.270 | 4355/7403 | 0.59 | 0.0311/0.0094s | 83.0/27.9s |
|
||||
|
||||
Important prefix caveat: the vLLM prefix-hit column in this table is the
|
||||
trace-side synthetic estimate from the vLLM summaries. For TP1 runs with
|
||||
preemption and finite KV pressure, the observed vLLM scheduler `computed:`
|
||||
signal is the better comparator. Earlier analysis in
|
||||
`docs/rs4_frontier_h20_tp1_alignment.md` records those finite-cache comparisons.
|
||||
For TP2/TP4, no preemption occurs and the trace-side prefix ratio matches
|
||||
Frontier exactly.
|
||||
|
||||
## Plots
|
||||
|
||||

|
||||
|
||||

|
||||
|
||||

|
||||
|
||||

|
||||
|
||||
## Interpretation
|
||||
|
||||
### TP1
|
||||
|
||||
The early TP1 100/500/scale-0.667 runs are still useful as historical stress
|
||||
points, but they were run before the decode-preemption lifecycle fix. Frontier
|
||||
therefore missed rows in those runs:
|
||||
|
||||
- `96/100` for N100 raw
|
||||
- `439/500` for N500 raw
|
||||
- `176/200` for N200 scale 0.667
|
||||
|
||||
After the lifecycle fix, TP1 scale 2 and scale 3 both complete `200/200`.
|
||||
Preemption is now in the same order as vLLM:
|
||||
|
||||
- scale 2: Frontier 33 vs vLLM 43
|
||||
- scale 3: Frontier 20 vs vLLM 16
|
||||
|
||||
TP1 timing is the closest current calibrated region. Throughput is about
|
||||
`0.74x` vLLM, TPOT p50/p95 is close, and E2E p95 is about `1.23-1.26x` vLLM.
|
||||
This is not perfect, but it is usable for integration-level trend checks.
|
||||
|
||||
### TP2 and TP4
|
||||
|
||||
The TP2/TP4 runs are functionally cleaner than TP1:
|
||||
|
||||
- `200/200` completed for all four runs.
|
||||
- Frontier and vLLM both report no preemption.
|
||||
- Frontier uses explicit vLLM KV capacities:
|
||||
- TP2: 69,055 blocks
|
||||
- TP4: 177,077 blocks
|
||||
- Prefix hit ratio matches exactly: `0.2697549478`.
|
||||
|
||||
We did profile TP2/TP4 true-mixed attention. The active RS12 profile includes:
|
||||
|
||||
- `attention_tp2_tp4_combined.csv`: 36,163 rows, including 1,260 true-mixed
|
||||
prefill+decode rows for TP2/TP4.
|
||||
- `linear_op_tp2_tp4_full32k.csv`: covers up to 32,768 tokens.
|
||||
- `moe_tp2_tp4_full32k.csv`: covers up to 32,768 tokens.
|
||||
|
||||
Without the true-mixed rows, Frontier fails with missing
|
||||
`attn_decode_in_mixed` predictions. With them, all RS12 runs complete.
|
||||
|
||||
The remaining TP2/TP4 gap is therefore not a missing-profile blocker. It is a
|
||||
timing-model gap:
|
||||
|
||||
- TP2 throughput is `0.61-0.63x` vLLM.
|
||||
- TP4 throughput is `0.55-0.59x` vLLM.
|
||||
- TP4 TPOT p50 is `2.06-3.30x` vLLM.
|
||||
|
||||
## Scaling
|
||||
|
||||
For the same first-200 request fixtures:
|
||||
|
||||
| fixture | metric | Frontier TP4/TP2 | vLLM TP4/TP2 |
|
||||
|---|---|---:|---:|
|
||||
| scale 2 | total tok/s | 1.10 | 1.20 |
|
||||
| scale 2 | decode tok/s | 1.10 | 1.20 |
|
||||
| scale 2 | TPOT p50 | 0.78 | 0.54 |
|
||||
| scale 3 | total tok/s | 1.07 | 1.15 |
|
||||
| scale 3 | decode tok/s | 1.07 | 1.15 |
|
||||
| scale 3 | TPOT p50 | 0.79 | 0.49 |
|
||||
|
||||
Frontier sees some TP4 improvement, but much less than real vLLM. This is the
|
||||
clearest current evidence that the simulator is not yet modeling vLLM's
|
||||
TP-dependent decode execution path well enough.
|
||||
|
||||
## Likely Gap Sources
|
||||
|
||||
The main unresolved issues are:
|
||||
|
||||
- CPU/scheduler overhead is still skipped (`skip_cpu_overhead_modeling=true`).
|
||||
- Decode CUDA graph behavior is not modeled in the current Frontier runs
|
||||
(`decode_cuda_graph_mode=none`).
|
||||
- Random-forest predictors interpolate over profile grids, while real online
|
||||
mixed batches may concentrate on shapes not directly sampled.
|
||||
- Some TP4 predictor fit errors are nontrivial, for example
|
||||
`attn_kv_cache_save` MAPE around 11% in the TP4 profile log.
|
||||
- Frontier's scheduler and preemption behavior is close but not identical for
|
||||
TP1 under finite KV pressure.
|
||||
|
||||
## ReplayServe TODO
|
||||
|
||||
1. Rerun the 500-request TP1 stress after the decode-preemption lifecycle fix,
|
||||
so the 500-row result is no longer mixed with the old incomplete behavior.
|
||||
2. Record vLLM observed scheduler prefix/preemption metrics in machine-readable
|
||||
summaries, not only in docs, especially first-start and last-start
|
||||
`computed:` ratios.
|
||||
3. Add a shape-ledger analysis: compare Frontier's actual online batch shapes
|
||||
against the profile grid and identify hot shapes that are interpolated.
|
||||
4. Profile or import vLLM CPU overhead and test
|
||||
`skip_cpu_overhead_modeling=false`.
|
||||
5. Collect kernel-only / decode-CUDA-graph timing profiles before enabling a
|
||||
Frontier CUDA-graph decode mode.
|
||||
6. Calibrate TP2/TP4 timing only after the above, because current functional
|
||||
replay is aligned but the TP scaling is not.
|
||||
199
docs/rs1_frontier_blocker.md
Normal file
199
docs/rs1_frontier_blocker.md
Normal file
@@ -0,0 +1,199 @@
|
||||
# RS1 Frontier Blocker: Prefix Cache + Chunked Prefill
|
||||
|
||||
This note narrows the RS1 `coder_2000` failure into a small Frontier repro.
|
||||
It does not change the RS1 fixed config or make performance claims.
|
||||
|
||||
## Status
|
||||
|
||||
- Frontier repo: `/tmp/toc-llm-sim-research/Frontier`
|
||||
- Frontier HEAD: `d9cfeb6d8791fbf2f295dd9744c56a666171776e`
|
||||
- ReplayServe canonical fixtures were not changed.
|
||||
- Frontier source was not modified.
|
||||
- Diagnostic artifacts live under `runs/rs1/blocker_request_194/`.
|
||||
|
||||
The original `coder_2000` run failed with:
|
||||
|
||||
```text
|
||||
ValueError: Request 194 already scheduled.
|
||||
```
|
||||
|
||||
First-N probing shows the smaller blocker is not a single malformed row 194.
|
||||
The smallest observed first-N failure is `N=193`, which fails as:
|
||||
|
||||
```text
|
||||
ValueError: Request 192 already scheduled.
|
||||
```
|
||||
|
||||
`N=192` passes under the same fixed config.
|
||||
|
||||
## Repro Commands
|
||||
|
||||
Generate diagnostic slices:
|
||||
|
||||
```bash
|
||||
cd /home/gahow/phd/replayserve
|
||||
for n in 190 191 192 193 194 195 200; do
|
||||
out="runs/rs1/blocker_request_194/fixtures/coder_${n}"
|
||||
mkdir -p "$out"
|
||||
python3 tools/qwen_to_frontier.py \
|
||||
--input /home/gahow/phd/qwen-bailian-usagetraces-anon/qwen_coder_blksz_16.jsonl \
|
||||
--frontier-csv "$out/frontier.csv" \
|
||||
--sidecar-jsonl "$out/sidecar.jsonl" \
|
||||
--source-jsonl "$out/source.jsonl" \
|
||||
--manifest-json "$out/manifest.json" \
|
||||
--fixture-name "blocker_coder_${n}" \
|
||||
--limit "$n" \
|
||||
--max-tokens 32768 \
|
||||
--block-size 16 \
|
||||
--fail-on-overflow
|
||||
done
|
||||
```
|
||||
|
||||
Minimal failing command:
|
||||
|
||||
```bash
|
||||
cd /home/gahow/phd/replayserve
|
||||
scripts/run_frontier_blocker_probe.sh \
|
||||
n193_default \
|
||||
runs/rs1/blocker_request_194/fixtures/coder_193
|
||||
```
|
||||
|
||||
The exact Frontier CLI for every probe is preserved in each
|
||||
`runs/rs1/blocker_request_194/probes/<name>/command.txt`.
|
||||
|
||||
## First-N Matrix
|
||||
|
||||
All default rows use the RS1 fixed config: prefix caching on, chunked prefill
|
||||
on, `long_prefill_token_threshold=64`, batch cap 128, max batch tokens 32768.
|
||||
|
||||
| probe | rows | prefix cache | chunked prefill | threshold | exit | result |
|
||||
|---|---:|---|---|---:|---:|---|
|
||||
| `n190_default` | 190 | on | on | 64 | 0 | pass |
|
||||
| `n191_default` | 191 | on | on | 64 | 0 | pass |
|
||||
| `n192_default` | 192 | on | on | 64 | 0 | pass |
|
||||
| `n193_default` | 193 | on | on | 64 | 1 | `Request 192 already scheduled` |
|
||||
| `n194_default` | 194 | on | on | 64 | 1 | `Request 192 already scheduled` |
|
||||
| `n195_default` | 195 | on | on | 64 | 1 | `Request 194 already scheduled` |
|
||||
| `n200_default` | 200 | on | on | 64 | 1 | `Request 194 already scheduled` |
|
||||
|
||||
## Diagnostic Variants
|
||||
|
||||
These are diagnosis only. They are not replacements for the RS1 fixed config.
|
||||
|
||||
| probe | rows | prefix cache | chunked prefill | threshold | exit | result |
|
||||
|---|---:|---|---|---:|---:|---|
|
||||
| `n193_prefix_off` | 193 | off | on | 64 | 0 | pass |
|
||||
| `n193_chunked_off` | 193 | on | off | 64 | 1 | Frontier config rejects this combination |
|
||||
| `n193_chunked_off_threshold_0` | 193 | on | off | 0 | 0 | pass |
|
||||
| `n193_threshold_32768` | 193 | on | on | 32768 | 0 | pass |
|
||||
| `n195_prefix_off` | 195 | off | on | 64 | 0 | pass |
|
||||
| `n195_chunked_off` | 195 | on | off | 64 | 1 | Frontier config rejects this combination |
|
||||
| `n195_chunked_off_threshold_0` | 195 | on | off | 0 | 0 | pass |
|
||||
| `n195_threshold_32768` | 195 | on | on | 32768 | 0 | pass |
|
||||
| `n200_prefix_off` | 200 | off | on | 64 | 0 | pass |
|
||||
| `n200_chunked_off_threshold_0` | 200 | on | off | 0 | 0 | pass |
|
||||
| `n200_threshold_32768` | 200 | on | on | 32768 | 0 | pass |
|
||||
|
||||
Frontier enforces:
|
||||
|
||||
```text
|
||||
VllmV1SchedulerConfig.long_prefill_token_threshold > 0 requires enable_chunked_prefill=True
|
||||
```
|
||||
|
||||
So a valid chunked-off diagnostic also sets
|
||||
`LONG_PREFILL_TOKEN_THRESHOLD=0`.
|
||||
|
||||
## Local Trace Analysis
|
||||
|
||||
Generated files:
|
||||
|
||||
- `runs/rs1/blocker_request_194/analysis/request_192_analysis.json`
|
||||
- `runs/rs1/blocker_request_194/analysis/request_192_analysis.md`
|
||||
- `runs/rs1/blocker_request_194/analysis/request_194_analysis.json`
|
||||
- `runs/rs1/blocker_request_194/analysis/request_194_analysis.md`
|
||||
|
||||
Request 192, the minimal first-N failure target:
|
||||
|
||||
- `timestamp=43.406`
|
||||
- `chat_id=192`, `parent_chat_id=-1`, `turn=1`, `type=coder`
|
||||
- `input_length=13436`, `output_length=1425`, total `14861`
|
||||
- `hash_count=840`
|
||||
- partial final block: yes, final block token count `12`
|
||||
- top prior prefix overlap: 7 blocks, 112 tokens
|
||||
- no parent candidate in the sidecar
|
||||
|
||||
Request 194, the original `coder_2000` failing request:
|
||||
|
||||
- `timestamp=43.931`
|
||||
- `chat_id=194`, `parent_chat_id=-1`, `turn=1`, `type=coder`
|
||||
- `input_length=2064`, `output_length=2278`, total `4342`
|
||||
- `hash_count=129`
|
||||
- partial final block: no, final block token count `16`
|
||||
- top prior prefix overlap: 1 block, 16 tokens
|
||||
- no parent candidate in the sidecar
|
||||
|
||||
Interpretation:
|
||||
|
||||
- The failing requests are independent first turns, not child turns in a chat.
|
||||
- Request 192 has a partial final block, but its observed prior prefix overlap
|
||||
is only the first 7 full blocks.
|
||||
- Request 194 has no partial final block and only a 1-block prefix overlap.
|
||||
- The failure is therefore not explained by a malformed partial final block,
|
||||
deep shared-prefix trace structure, or a parent/child chat mismatch.
|
||||
- Fixture validation confirms monotonic timestamps, max-token compliance,
|
||||
sidecar hash lengths, and block token counts.
|
||||
|
||||
## Frontier Source Localization
|
||||
|
||||
Relevant Frontier files:
|
||||
|
||||
- `/tmp/toc-llm-sim-research/Frontier/frontier/scheduler/replica_scheduler/vllm_v1_engine_replica_scheduler.py`
|
||||
- `/tmp/toc-llm-sim-research/Frontier/frontier/entities/request.py`
|
||||
- `/tmp/toc-llm-sim-research/Frontier/frontier/config/config.py`
|
||||
|
||||
Key path:
|
||||
|
||||
- `VllmV1EngineReplicaScheduler._prepare_prefix_cache_admission`
|
||||
at `vllm_v1_engine_replica_scheduler.py:1178` calls
|
||||
`kv_cache_manager.get_computed_blocks(request)` and returns
|
||||
`prefix_cached_tokens`.
|
||||
- `_schedule_waiting_requests` at
|
||||
`vllm_v1_engine_replica_scheduler.py:3075` runs prefix-cache admission for
|
||||
any waiting request with prefix caching enabled and incomplete prefill.
|
||||
- The same waiting path allocates KV and then calls
|
||||
`request.on_cache_hit(prefix_cached_tokens)` at
|
||||
`vllm_v1_engine_replica_scheduler.py:3179`.
|
||||
- `Request.on_cache_hit` at `request.py:503` raises if `_scheduled` is already
|
||||
true.
|
||||
- `Request.on_batch_schedule` at `request.py:1058` sets `_scheduled=True`.
|
||||
- Chunked-prefill continuations run through `_schedule_running_requests`
|
||||
around `vllm_v1_engine_replica_scheduler.py:2696`, with long-prefill
|
||||
capping applied around `:2826`.
|
||||
- Valid chunked-off CLI requires `long_prefill_token_threshold=0`; otherwise
|
||||
`config.py:714` rejects the configuration.
|
||||
|
||||
The evidence points to a Frontier scheduler state issue: with prefix caching
|
||||
enabled and chunked prefill active, a request that has already been scheduled
|
||||
can later reach waiting-admission prefix-cache handling and receive
|
||||
`on_cache_hit` again. That violates `Request.on_cache_hit`'s current invariant.
|
||||
|
||||
This is more consistent with a repeated cache-hit application or scheduled
|
||||
request re-admission path than with bad ReplayServe trace/hash data.
|
||||
|
||||
## Suggested Next Steps
|
||||
|
||||
1. Add temporary Frontier instrumentation around `_schedule_waiting_requests`
|
||||
before `request.on_cache_hit` to log `request.id`, `_scheduled`,
|
||||
`_preempted`, `is_prefill_complete`, `num_processed_tokens`,
|
||||
`prefix_cached_tokens`, and whether the request came from
|
||||
`_preempted_requests` or `_request_queue`.
|
||||
2. Decide Frontier semantics for prefix-cache hits after a request has already
|
||||
been scheduled once. A likely fix is to apply `on_cache_hit` only for a
|
||||
first admission with `_scheduled=False` and `num_processed_tokens=0`, or to
|
||||
reset/request-restart state before re-admission if that is the intended
|
||||
vLLM parity behavior.
|
||||
3. Keep RS1 fixed config blocked for `coder_2000` until Frontier behavior is
|
||||
patched or a documented upstream-compatible workaround is selected.
|
||||
4. Do not use the passing diagnosis variants as RS1 performance evidence:
|
||||
prefix-off, chunked-off, and threshold-32768 change the fixed config.
|
||||
|
||||
150
docs/rs1_frontier_patch.md
Normal file
150
docs/rs1_frontier_patch.md
Normal file
@@ -0,0 +1,150 @@
|
||||
# RS1B Frontier Patch
|
||||
|
||||
This document records the scratch Frontier patch used to unblock RS1 fixed
|
||||
config replay. It is not applied to the canonical Frontier checkout.
|
||||
|
||||
## Patch
|
||||
|
||||
- Patch file:
|
||||
`patches/frontier-vllm-v1-prefix-cache-chunked-prefill.patch`
|
||||
- Canonical Frontier checkout:
|
||||
`/tmp/toc-llm-sim-research/Frontier`
|
||||
- Scratch Frontier checkout:
|
||||
`/tmp/replayserve-frontier-rs1b`
|
||||
- Frontier base HEAD:
|
||||
`d9cfeb6d8791fbf2f295dd9744c56a666171776e`
|
||||
|
||||
Apply from a Frontier checkout at the same base commit:
|
||||
|
||||
```bash
|
||||
cd /path/to/Frontier
|
||||
git apply /home/gahow/phd/replayserve/patches/frontier-vllm-v1-prefix-cache-chunked-prefill.patch
|
||||
```
|
||||
|
||||
Check applicability without modifying a checkout:
|
||||
|
||||
```bash
|
||||
cd /path/to/Frontier
|
||||
git apply --check /home/gahow/phd/replayserve/patches/frontier-vllm-v1-prefix-cache-chunked-prefill.patch
|
||||
```
|
||||
|
||||
## Root Cause
|
||||
|
||||
Instrumentation in the scratch checkout showed the minimal `N=193` failure
|
||||
has two admissions for request 192:
|
||||
|
||||
```text
|
||||
req=192 source=request_queue scheduled=False preempted=False prefill_complete=False num_processed_tokens=0 prefix_cached_tokens=112 num_new_tokens=64
|
||||
req=192 source=preempted_requests scheduled=True preempted=True prefill_complete=False num_processed_tokens=0 prefix_cached_tokens=1232 num_new_tokens=64
|
||||
```
|
||||
|
||||
The second admission comes from `_preempted_requests`. Frontier preemption
|
||||
resets `victim._num_processed_tokens` and removes the explicit scheduler
|
||||
frontier, but it leaves `victim._scheduled=True`. The request then re-enters
|
||||
waiting admission, prefix-cache admission finds cached blocks, and
|
||||
`request.on_cache_hit(prefix_cached_tokens)` raises because `on_cache_hit`
|
||||
requires `_scheduled=False`.
|
||||
|
||||
The failure is therefore a Frontier runtime-state reset issue for preempted
|
||||
chunked-prefill requests with prefix caching enabled, not bad ReplayServe
|
||||
trace data.
|
||||
|
||||
## Patch Rationale
|
||||
|
||||
The first patch reset two request runtime fields in
|
||||
`VLLMv1EngineReplicaScheduler._preempt_request`:
|
||||
|
||||
```python
|
||||
victim._num_prefill_tokens_cached = 0
|
||||
victim._scheduled = False
|
||||
```
|
||||
|
||||
This matches the existing preemption intent in the same block: computed tokens
|
||||
are reset and the request is re-entered into a waiting queue for recomputation.
|
||||
After that reset, waiting admission can apply prefix-cache hit state through
|
||||
the existing `Request.on_cache_hit` path before the request is scheduled again.
|
||||
|
||||
An earlier conservative experiment skipped `on_cache_hit` for already scheduled
|
||||
requests and advanced only the scheduler frontier. That avoided the immediate
|
||||
exception but left request 192 incomplete at simulation shutdown, because the
|
||||
request object's processed-token state never reflected the cached prefix.
|
||||
|
||||
The 2026-06-25 RS10 debug runs exposed a second lifecycle bug. Missing request
|
||||
metrics for `coder_200_ts2` and `coder_200_ts3` were not postprocess artifacts:
|
||||
Frontier drained with `completed_requests < total_requests`. Missing requests
|
||||
had this state pattern:
|
||||
|
||||
```text
|
||||
preempted=True
|
||||
is_prefill_complete=True
|
||||
num_processed_tokens=0
|
||||
scheduled=False
|
||||
completed=False
|
||||
```
|
||||
|
||||
They had been preempted after entering decode. Frontier cleared processed
|
||||
tokens but kept the request in prefill-complete state. The next waiting
|
||||
admission therefore computed `num_new_tokens=0` and dropped the request from
|
||||
the waiting queue.
|
||||
|
||||
The current patch now also:
|
||||
|
||||
- replays decode-phase preemption by turning already-produced tokens into the
|
||||
next prefill segment and leaving the remaining tokens as decode work;
|
||||
- preserves user-facing prompt/output lengths for metrics after runtime token
|
||||
splitting;
|
||||
- preserves unfinished zero-token waiting requests instead of silently dropping
|
||||
them;
|
||||
- makes sequential simulation fail fast if the event queue drains before all
|
||||
generated requests complete, with per-request debug snapshots.
|
||||
|
||||
## Verification Matrix
|
||||
|
||||
All patched runs used RS1 fixed config unless explicitly stated otherwise:
|
||||
online, co-location, vLLM v1, A800, Qwen/Qwen3-32B, TP2, dummy predictor,
|
||||
analytical communication backend, `max_tokens=32768`, prefix cache on, block
|
||||
size 16, chunked prefill on, batch cap 128, max batch tokens 32768, memory
|
||||
planner KV capacity.
|
||||
|
||||
| run | Frontier root | result | runtime | notes |
|
||||
|---|---|---:|---:|---|
|
||||
| `runs/rs1b/instrumentation/n193_instrumented_print` | scratch instrumentation | fail | 4s | Proved request 192 re-entered from `_preempted_requests` with `_scheduled=True`. |
|
||||
| `runs/rs1b/patched/n193_fixed_v2` | patched scratch | pass | 11s | `N=193` fixed config passed. |
|
||||
| `runs/rs1b/patched/coder_100` | patched scratch | pass | 8s | Prefix hit ratios matched original RS1 `coder_100`. |
|
||||
| `runs/rs1b/patched/coder_2000` | patched scratch | pass | 87s | Full fixed config run completed. |
|
||||
| `runs/rs10_preemption_replay_fix_ts2/.../coder_200_ts2` | patched scratch | pass | 462s | RS10 H20 TP1 full32K profile; completion `200/200`; 33 preemption events. |
|
||||
| `runs/rs10_preemption_replay_fix_ts3/.../coder_200_ts3` | patched scratch | pass | 465s | RS10 H20 TP1 full32K profile; completion `200/200`; 20 preemption events. |
|
||||
|
||||
Prefix cache summaries:
|
||||
|
||||
| run | Frontier block hit ratio | ReplayServe token-weighted hit ratio | preemption events |
|
||||
|---|---:|---:|---:|
|
||||
| original `runs/rs1/coder_100` | 0.0494866184 | 0.0495623259 | 0 |
|
||||
| patched `runs/rs1b/patched/coder_100` | 0.0494866184 | 0.0495623259 | 0 |
|
||||
| patched `runs/rs1b/patched/n193_fixed_v2` | 0.1245897179 | 0.1247698141 | 5 |
|
||||
| patched `runs/rs1b/patched/coder_2000` | 0.1231893025 | 0.1233297822 | 35940 |
|
||||
| patched `runs/rs10_preemption_replay_fix_ts2/.../coder_200_ts2` | 0.2310157359 | 0.2313416900 | 33 |
|
||||
| patched `runs/rs10_preemption_replay_fix_ts3/.../coder_200_ts3` | 0.2173684294 | 0.2176751278 | 20 |
|
||||
|
||||
For `coder_2000`, ReplayServe postprocess skipped 745 request rows whose
|
||||
Frontier request metrics had blank prefix-cache fields. The run still completed
|
||||
and produced `system_metrics.json` and `request_metrics.csv`.
|
||||
|
||||
## Risks
|
||||
|
||||
- The patch touches Frontier private `Request` fields from scheduler code,
|
||||
matching existing local style but still relying on internal state layout.
|
||||
- Resetting `_scheduled` during preemption may affect request scheduling
|
||||
accounting outside this RS1 path. It does not clear `_scheduled_at`, so
|
||||
schedule history remains present, but downstream assumptions about the
|
||||
boolean should be reviewed upstream.
|
||||
- Resetting `_num_prefill_tokens_cached` means request-level cached-prefill
|
||||
metrics reflect the current post-preemption admission rather than stale
|
||||
pre-preemption state. This is necessary for the existing `on_cache_hit` path
|
||||
to model cached-prefix progress, but metrics semantics should be confirmed
|
||||
with Frontier maintainers.
|
||||
- The decode-phase preemption replay mutates Frontier private request token
|
||||
fields. Metrics are explicitly anchored to user-facing prompt/output lengths,
|
||||
but upstream should review whether this should become a public Request method.
|
||||
- The patched `coder_2000` run has many preemptions. RS1 remains a plumbing
|
||||
smoke; latency and throughput should not be treated as performance evidence.
|
||||
163
docs/rs1_frontier_smoke.md
Normal file
163
docs/rs1_frontier_smoke.md
Normal file
@@ -0,0 +1,163 @@
|
||||
# RS1 Frontier Smoke
|
||||
|
||||
RS1 runs Frontier trace replay as a plumbing smoke for the Qwen coder fixtures
|
||||
generated in RS0. It checks that Frontier can consume ReplayServe's Frontier CSV,
|
||||
preserve online arrivals, run vLLM v1 prefix caching, and emit request/system
|
||||
metrics. It does not make latency or throughput claims.
|
||||
|
||||
## Fixed Configuration
|
||||
|
||||
- `simulation_mode=online`
|
||||
- `sys_arch=co-location`
|
||||
- `cluster_scheduler=sticky_round_robin`
|
||||
- `replica_scheduler=vllm_v1`
|
||||
- `device=a800`
|
||||
- `network_device=a800_dgx`
|
||||
- `model_name=Qwen/Qwen3-32B`
|
||||
- `attn_tensor_parallel_size=2`
|
||||
- dummy execution predictor, 1 ms per model execution
|
||||
- analytical communication backend
|
||||
- `trace_request_generator_config_max_tokens=32768`
|
||||
- prefix caching enabled
|
||||
- block size 16
|
||||
- chunked prefill enabled
|
||||
- batch cap 128
|
||||
- max batch tokens 32768
|
||||
- `num_blocks_mode=memory_planner`
|
||||
- `gpu_memory_utilization=0.9`
|
||||
- `non_kv_cache_overhead_bytes=0`
|
||||
|
||||
The memory planner point uses Frontier's A800 device config
|
||||
(`total_memory_gb=80`) and analytical parameter memory. The non-KV overhead is
|
||||
set to 0 for this smoke, so the derived KV block count is a permissive plumbing
|
||||
budget, not a calibrated serving budget.
|
||||
|
||||
Frontier also ships an `a800_pairwise_nvlink` network profile, but
|
||||
`replica_config_network_device` is used to construct a node SKU in the current
|
||||
co-location path. This checkout has `A800_DGX` as a node SKU and does not have an
|
||||
`A800_PAIRWISE_NVLINK` node SKU, so RS1 uses `a800_dgx`.
|
||||
|
||||
## Reproduce
|
||||
|
||||
From `/home/gahow/phd/replayserve`:
|
||||
|
||||
```bash
|
||||
PIP_CACHE_DIR=/home/gahow/phd/replayserve/.cache/pip python3 -m pip install \
|
||||
--target /home/gahow/phd/replayserve/.deps/python \
|
||||
'ddsketch>=3.0,<4' 'fasteners>=0.19,<1' 'numpy>=1.23' 'pandas>=1.5' \
|
||||
'plotly>=5.0' 'pyyaml>=6.0' 'scikit-learn>=1.1' 'scipy>=1.9' 'tqdm>=4.64'
|
||||
scripts/run_frontier_smoke.sh coder_100
|
||||
scripts/run_frontier_smoke.sh coder_2000
|
||||
```
|
||||
|
||||
Each run writes:
|
||||
|
||||
- `runs/rs1/<fixture>/command.txt`
|
||||
- `runs/rs1/<fixture>/stdout.log`
|
||||
- `runs/rs1/<fixture>/stderr.log`
|
||||
- `runs/rs1/<fixture>/exit_code.txt`
|
||||
- `runs/rs1/<fixture>/runtime_seconds.txt`
|
||||
- `runs/rs1/<fixture>/frontier_metrics/.../config.json`
|
||||
- `runs/rs1/<fixture>/frontier_metrics/.../system_metrics.json`
|
||||
- `runs/rs1/<fixture>/frontier_metrics/.../request_metrics.csv`
|
||||
- `runs/rs1/<fixture>/postprocess_summary.json`
|
||||
- `runs/rs1/<fixture>/postprocess_summary.md`
|
||||
|
||||
## Current Results
|
||||
|
||||
Initial local attempt with `network_device=a800_pairwise_nvlink` failed during
|
||||
config reconstruction:
|
||||
|
||||
```text
|
||||
ValueError: [BaseNodeSKUConfig] Invalid type string: a800_pairwise_nvlink
|
||||
```
|
||||
|
||||
The preserved failed run context is under
|
||||
`runs/rs1/coder_100_failed_a800_pairwise_nvlink/`.
|
||||
|
||||
The first `a800_dgx` attempt failed because the base Python environment lacked
|
||||
Frontier runtime dependencies:
|
||||
|
||||
```text
|
||||
ModuleNotFoundError: No module named 'plotly'
|
||||
```
|
||||
|
||||
Dependencies were installed into ReplayServe-local `.deps/python` with pip
|
||||
`--target`; Frontier source was not installed or modified.
|
||||
|
||||
### coder_100
|
||||
|
||||
Status: passed.
|
||||
|
||||
- Run dir: `runs/rs1/coder_100/`
|
||||
- Runtime: 7 seconds
|
||||
- Metrics dir:
|
||||
`runs/rs1/coder_100/frontier_metrics/qwen_qwen3_32b/online_serving/rs1_coder_100/`
|
||||
- Frontier block-level prefix hit ratio: `0.04948661841440835`
|
||||
- ReplayServe token-weighted prefix hit ratio: `0.04956232588915065`
|
||||
- Frontier total query blocks: `29705`
|
||||
- Frontier total hit blocks: `1470`
|
||||
- ReplayServe total query tokens: `474554`
|
||||
- ReplayServe total hit tokens: `23520`
|
||||
- Memory planner mode: `memory_planner`
|
||||
- GPU memory utilization: `0.9`
|
||||
- A800 memory budget: `80 GiB * 0.9 = 77309411328 bytes`
|
||||
- Qwen3-32B TP2 analytical weight shard estimate:
|
||||
`28940697600 bytes` (`26.953125 GiB`)
|
||||
- Non-KV overhead assumption: `0 bytes`
|
||||
- Available KV budget under this smoke assumption: `48368713728 bytes`
|
||||
- Derived KV blocks: `36902`
|
||||
- Preemption events: `0`
|
||||
- Allocation/preemption/OOM log lines: `0`
|
||||
|
||||
The derived KV block count is recomputed by ReplayServe postprocess with the
|
||||
same formula as Frontier `MemoryPlanner.get_num_blocks` because this run did
|
||||
not emit Frontier's `[MEMORY_STATE]` line in stdout/stderr.
|
||||
|
||||
### coder_2000
|
||||
|
||||
Status: blocked by Frontier runtime error under the fixed RS1 configuration.
|
||||
|
||||
- Run dir: `runs/rs1/coder_2000/`
|
||||
- Runtime: 4 seconds
|
||||
- Config:
|
||||
`runs/rs1/coder_2000/frontier_metrics/qwen_qwen3_32b/online_serving/rs1_coder_2000/config.json`
|
||||
- Failure summary: `runs/rs1/coder_2000/failure_summary.md`
|
||||
|
||||
Frontier failed during vLLM v1 prefix-cache scheduling:
|
||||
|
||||
```text
|
||||
ValueError: Request 194 already scheduled.
|
||||
```
|
||||
|
||||
The traceback reaches
|
||||
`vllm_v1_engine_replica_scheduler.py:3185`, where the scheduler calls
|
||||
`request.on_cache_hit(prefix_cached_tokens)`, and then
|
||||
`request.py:505`, where `Request.on_cache_hit()` rejects cache-hit updates after
|
||||
the request has already been scheduled.
|
||||
|
||||
No Frontier source changes were made. RS1 stops here rather than changing
|
||||
scheduler knobs, because disabling prefix caching or chunked prefill would no
|
||||
longer match the fixed smoke point.
|
||||
|
||||
## Metric Semantics
|
||||
|
||||
Frontier reports prefix-cache hits at block granularity. ReplayServe postprocess
|
||||
uses `sidecar.jsonl` to weight each request's first `hit_blocks` by
|
||||
`block_token_counts`, so a hit on a partial final block contributes the true
|
||||
partial token count rather than 16 tokens.
|
||||
|
||||
If Frontier omits `request_cached_prefill_tokens`,
|
||||
`request_prefix_cache_query_blocks`, or `request_prefix_cache_hit_blocks` from
|
||||
`request_metrics.csv`, ReplayServe cannot compute token-weighted hit ratio from
|
||||
that run without additional simulator instrumentation.
|
||||
|
||||
## Limitations
|
||||
|
||||
- Frontier's public A800 compute profiles in the checked source do not include a
|
||||
dense `Qwen/Qwen3-32B` profile.
|
||||
- Dummy execution predictor is enabled, so TTFT, TPOT, E2E latency, and
|
||||
throughput are only pipeline smoke outputs.
|
||||
- Memory planner uses analytical parameter memory and a 0-byte non-KV overhead
|
||||
assumption. The derived KV capacity must be replaced by calibrated overhead or
|
||||
runtime profiling before interpreting capacity pressure.
|
||||
143
docs/rs3_sweep_harness.md
Normal file
143
docs/rs3_sweep_harness.md
Normal file
@@ -0,0 +1,143 @@
|
||||
# RS3 Sweep Harness
|
||||
|
||||
RS3 adds a reproducible Frontier sweep harness and a tiny smoke. This is not the
|
||||
full TP/EP/DP/config scan.
|
||||
|
||||
## Files
|
||||
|
||||
- Config: `configs/rs3_tiny_sweep.json`
|
||||
- Runner: `tools/run_frontier_sweep.py`
|
||||
- Aggregator: `tools/aggregate_runs.py`
|
||||
- Tiny smoke outputs: `runs/rs3_tiny_smoke_20260624/`
|
||||
|
||||
The output layout is:
|
||||
|
||||
```text
|
||||
runs/<suite>/<sim>/<fixture>/<config_id>/
|
||||
command.txt
|
||||
env.txt
|
||||
run_manifest.json
|
||||
run_status.json
|
||||
stdout.log
|
||||
stderr.log
|
||||
exit_code.txt
|
||||
runtime_seconds.txt
|
||||
frontier_metrics/...
|
||||
postprocess_summary.json
|
||||
postprocess_summary.md
|
||||
runs/<suite>/summary.csv
|
||||
runs/<suite>/summary.md
|
||||
```
|
||||
|
||||
## Config Scheme
|
||||
|
||||
`configs/rs3_tiny_sweep.json` is intentionally small JSON:
|
||||
|
||||
- `suite_id`: output suite under `runs/`.
|
||||
- `sim`: simulator/mode name used in the run path.
|
||||
- `frontier`: Frontier checkout metadata. The tiny smoke points at patched
|
||||
scratch `/tmp/replayserve-frontier-rs1b`, not canonical Frontier.
|
||||
- `fixtures`: fixture names under `traces/fixtures/`.
|
||||
- `defaults`: fixed Frontier knobs shared by each config.
|
||||
- `configs`: named variants with optional `overrides`.
|
||||
|
||||
The exposed Frontier knobs include:
|
||||
|
||||
- parallelism: `attn_tensor_parallel_size`, `attn_data_parallel_size`,
|
||||
`moe_tensor_parallel_size`, `moe_expert_parallel_size`,
|
||||
`num_pipeline_stages`, `num_replicas`
|
||||
- scheduler: `batch_size_cap` / max-num-seqs equivalent,
|
||||
`max_tokens_in_batch` / max-batch-tokens equivalent, `block_size`,
|
||||
`enable_prefix_caching`, `enable_chunked_prefill`,
|
||||
`long_prefill_token_threshold`
|
||||
- fixed smoke context: model, device, network device, trace max tokens,
|
||||
memory-planner mode, GPU memory utilization, non-KV overhead, and dummy
|
||||
execution time
|
||||
|
||||
For dense `Qwen/Qwen3-32B`, the EP-like knobs stay at `1` in the tiny smoke.
|
||||
They are present so later MoE configs can be represented without changing the
|
||||
harness schema.
|
||||
|
||||
## Run Commands
|
||||
|
||||
From `/home/gahow/phd/replayserve`:
|
||||
|
||||
```bash
|
||||
python3 tools/run_frontier_sweep.py \
|
||||
--config configs/rs3_tiny_sweep.json \
|
||||
--suite-id rs3_tiny_smoke_20260624
|
||||
|
||||
python3 tools/aggregate_runs.py runs/rs3_tiny_smoke_20260624
|
||||
```
|
||||
|
||||
The runner refuses to replace an existing selected run directory unless
|
||||
`--force` is passed. Use `--dry-run` to emit commands/manifests without running
|
||||
Frontier, and `--only-config` / `--only-fixture` to narrow the selected matrix.
|
||||
|
||||
## Frontier Mode
|
||||
|
||||
The RS3 tiny smoke uses:
|
||||
|
||||
- `frontier.root=/tmp/replayserve-frontier-rs1b`
|
||||
- `frontier.mode=patched_scratch`
|
||||
- patch file `patches/frontier-vllm-v1-prefix-cache-chunked-prefill.patch`
|
||||
|
||||
The canonical checkout `/tmp/toc-llm-sim-research/Frontier` remains clean and is
|
||||
not modified by the harness. `summary.csv` records `frontier_dirty=true` for the
|
||||
patched scratch because the local patch is applied there; that is expected.
|
||||
|
||||
To run canonical mode for a safe config, copy the JSON config, set
|
||||
`frontier.root` to `/tmp/toc-llm-sim-research/Frontier`, change `sim`, and run a
|
||||
small selected config. Do not use canonical fixed `coder_2000` until the
|
||||
prefix-cache chunked-prefill bug is fixed upstream.
|
||||
|
||||
## Tiny Smoke Results
|
||||
|
||||
Command:
|
||||
|
||||
```bash
|
||||
python3 tools/run_frontier_sweep.py \
|
||||
--config configs/rs3_tiny_sweep.json \
|
||||
--suite-id rs3_tiny_smoke_20260624
|
||||
python3 tools/aggregate_runs.py runs/rs3_tiny_smoke_20260624
|
||||
```
|
||||
|
||||
Results:
|
||||
|
||||
| config | status | runtime | prefix cache | chunked prefill | Frontier block hit ratio | ReplayServe token hit ratio | preemptions |
|
||||
|---|---:|---:|---:|---:|---:|---:|---:|
|
||||
| `fixed_prefix_on` | pass | 8s | on | on | `0.049486618` | `0.049562326` | 0 |
|
||||
| `prefix_cache_off` | pass | 7s | off | on | n/a | n/a | 0 |
|
||||
|
||||
Aggregated files:
|
||||
|
||||
- `runs/rs3_tiny_smoke_20260624/summary.csv`
|
||||
- `runs/rs3_tiny_smoke_20260624/summary.md`
|
||||
|
||||
The prefix-off run does not have Frontier cache columns in `request_metrics.csv`;
|
||||
`summary.csv` records `cache_metrics_available=false` and the missing-column
|
||||
reason.
|
||||
|
||||
TTFT/TPOT/E2E/throughput fields are aggregated from Frontier `system_metrics.json`
|
||||
when present. In this tiny smoke they are dummy-predictor plumbing outputs, not
|
||||
performance results.
|
||||
|
||||
## Not Yet Run
|
||||
|
||||
- No `coder_2000` sweep was run in RS3.
|
||||
- No TP/DP/EP matrix was swept.
|
||||
- No batch cap, max batch tokens, block size, chunked-prefill, or threshold
|
||||
matrix was swept beyond the two-config smoke.
|
||||
- No canonical Frontier patched-vs-unpatched comparison was rerun.
|
||||
- No Vidur or AIConfigurator run is part of this harness yet.
|
||||
|
||||
## Next Harness Work
|
||||
|
||||
- Add a small checked-in config for a real RS3 candidate grid only after deciding
|
||||
the patch/upstream policy.
|
||||
- Add guardrails for invalid dense/MoE parallelism combinations before launching
|
||||
larger matrices.
|
||||
- Investigate `coder_2000` missing request-level cache fields before using
|
||||
request-level hit ratio as a headline sweep metric.
|
||||
- Keep latency/throughput result tables clearly separated by predictor/profile
|
||||
mode: dummy smoke, profiled Frontier, or calibrated run.
|
||||
740
docs/rs4_frontier_h20_tp1_alignment.md
Normal file
740
docs/rs4_frontier_h20_tp1_alignment.md
Normal file
@@ -0,0 +1,740 @@
|
||||
# RS4 Frontier H20 TP1 Alignment
|
||||
|
||||
This note compares Frontier H20 TP1 against the real vLLM TP1 run on dash2 for
|
||||
`coder_100`.
|
||||
|
||||
## Setup
|
||||
|
||||
Real vLLM:
|
||||
|
||||
- Runtime: vLLM 0.11.1
|
||||
- Host/GPU: dash2, NVIDIA H20
|
||||
- Model: `/home/admin/cpfs/wjh/models/Qwen/Qwen3-30B-A3B`
|
||||
- TP: 1
|
||||
- KV capacity: 244,496 tokens = 15,281 blocks at block size 16
|
||||
- Run: `runs/vllm_gpu_smoke_20260624/tp1_coder100_uncapped`
|
||||
|
||||
Frontier:
|
||||
|
||||
- Frontier root: `/tmp/replayserve-frontier-rs1b`
|
||||
- Frontier commit: `d9cfeb6d8791fbf2f295dd9744c56a666171776e`
|
||||
- Model config name: `qwen3-a3b-30b-moe`
|
||||
- Device: `h20`
|
||||
- Network node SKU: `h20_dgx`
|
||||
- TP: `attn_tensor_parallel_size=1`, `moe_tensor_parallel_size=1`,
|
||||
`moe_expert_parallel_size=1`
|
||||
- `max_tokens_in_batch=32768`, `batch_size_cap=64`, block size 16
|
||||
- Prefix cache on, chunked prefill on
|
||||
- `long_prefill_token_threshold=32768`
|
||||
- Config: `configs/rs4_frontier_h20_tp1.json`
|
||||
- Run: `runs/rs4_frontier_h20_tp1_20260624`
|
||||
|
||||
The high long-prefill threshold is deliberate. Frontier's earlier threshold 64
|
||||
run under-counted prefix hits because long prompts were admitted in 64-token
|
||||
chunks, unlike the current real vLLM run.
|
||||
|
||||
## KV Capacity
|
||||
|
||||
| run | KV blocks | KV tokens | note |
|
||||
|---|---:|---:|---|
|
||||
| Frontier `planner_kv` | 17,385 | 278,160 | Frontier H20 memory planner, no non-KV overhead |
|
||||
| Frontier `vllm_kv_15281` | 15,281 | 244,496 | Explicitly matched to real vLLM TP1 |
|
||||
| vLLM TP1 | 15,281 | 244,496 | From vLLM memory profiling |
|
||||
|
||||
So only `vllm_kv_15281` has the same KV block count as real vLLM TP1.
|
||||
|
||||
## Results
|
||||
|
||||
| run | completed | prefix hit tokens / ratio | preemptions | TTFT p50/p95 | TPOT p50/p95 | E2E p50/p95 | decode tok/s |
|
||||
|---|---:|---:|---:|---:|---:|---:|---:|
|
||||
| Frontier `planner_kv` | 96/100 | 110,608 / 0.240691 | 0 | 0.986/128.991s | 0.582/0.582s | 279.092/1706.675s | 19.4 |
|
||||
| Frontier `vllm_kv_15281` | 92/100 | 103,168 / 0.242542 | 0 | 0.964/182.639s | 0.582/0.582s | 305.290/1765.347s | 19.4 |
|
||||
| vLLM TP1 real | 100/100 | 119,152 / 0.251082 sidecar estimate | 8 | 4.503/29.060s | 0.066/0.621s | 41.841/97.366s | 567.4 |
|
||||
|
||||
The latency/throughput rows are not calibrated. Frontier still uses dummy
|
||||
execution timing, so TPOT is a constant simulator artifact.
|
||||
|
||||
## Prefix Admission Check
|
||||
|
||||
For TP1, real vLLM has preemption. Therefore the sidecar theoretical prefix-hit
|
||||
estimate is not the right observed comparator for every request. The observed
|
||||
vLLM scheduler signal is the first `computed:` value in `stdout.log` for each
|
||||
request start.
|
||||
|
||||
Using first-start `computed:` tokens:
|
||||
|
||||
| Frontier run | compared rows | Frontier computed sum | vLLM first-start computed sum | mismatch |
|
||||
|---|---:|---:|---:|---:|
|
||||
| `planner_kv` | 96 | 110,608 | 108,208 | one request differs |
|
||||
| `vllm_kv_15281` | 92 | 103,168 | 103,168 | exact match |
|
||||
|
||||
So with the KV block count explicitly matched, Frontier's prefix-cache admission
|
||||
matches real vLLM TP1 for every row where Frontier emits complete cache metrics.
|
||||
|
||||
## Current Alignment Judgment
|
||||
|
||||
Aligned:
|
||||
|
||||
- H20 device and Qwen3-30B-A3B structural model config can run in Frontier.
|
||||
- TP1 scheduler knobs can be matched.
|
||||
- KV block count can be matched explicitly at 15,281 blocks.
|
||||
- First-admission prefix-cache hit tokens match real vLLM TP1 on completed rows
|
||||
when KV blocks are explicit.
|
||||
|
||||
Not aligned:
|
||||
|
||||
- Frontier emits complete request/cache metrics for only 92/100 requests in the
|
||||
explicit-KV run, while vLLM completes 100/100.
|
||||
- Frontier reports 0 preemptions; real vLLM TP1 reports 8 preemptions across 5
|
||||
repeated-start requests.
|
||||
- Frontier timing is not comparable because it still uses dummy execution
|
||||
prediction. The current latency/throughput gap is expected and not a
|
||||
calibrated simulator error.
|
||||
|
||||
Next work:
|
||||
|
||||
- Treat RS6 as the current profiled baseline and investigate why it omits
|
||||
complete latency/cache metrics for requests `70`, `77`, `88`, and `90`.
|
||||
- Instrument Frontier's vLLM V1 scheduler around KV block allocation, free-block
|
||||
count, and preemption victim selection. Real vLLM TP1 has 8 preemptions, while
|
||||
Frontier still reports 0 with the same explicit 15,281-block capacity.
|
||||
- Add a per-request Frontier/vLLM comparator that reports TTFT/TPOT/E2E ratios,
|
||||
prefix hits, and completion/preemption status on the same request ids.
|
||||
- Calibrate CPU/scheduler/CUDA-graph effects separately from op profile timing;
|
||||
RS6 removed the 4096-token linear/MoE extrapolation as the primary explanation
|
||||
for the remaining gap.
|
||||
|
||||
## Performance Gap
|
||||
|
||||
Use Frontier `vllm_kv_15281` as the current aligned-KV simulator point. This
|
||||
matches the real vLLM TP1 KV block count, but it still uses Frontier dummy
|
||||
execution timing.
|
||||
|
||||
| metric | Frontier H20 TP1 explicit KV | real vLLM H20 TP1 | gap |
|
||||
|---|---:|---:|---:|
|
||||
| completed requests | 92/100 | 100/100 | not aligned |
|
||||
| TTFT p50 | 0.964s | 4.503s | Frontier 0.21x real |
|
||||
| TTFT p95 | 182.639s | 29.060s | Frontier 6.28x real |
|
||||
| TPOT p50 | 0.582s | 0.066s | Frontier 8.81x real |
|
||||
| TPOT p95 | 0.582s | 0.621s | Frontier 0.94x real |
|
||||
| E2E p50 | 305.290s | 41.841s | Frontier 7.30x real |
|
||||
| E2E p95 | 1765.347s | 97.366s | Frontier 18.13x real |
|
||||
| RPS | 0.0217 | 0.6880 | vLLM 31.74x Frontier |
|
||||
| decode tok/s | 19.4 | 567.4 | vLLM 29.20x Frontier |
|
||||
|
||||
Interpretation:
|
||||
|
||||
- The prefix admission path is close after explicit KV matching, but performance
|
||||
is not calibrated.
|
||||
- Frontier uses dummy execution timing; its TPOT is nearly constant at 582 ms,
|
||||
while real vLLM TP1 has p50 TPOT 66 ms and p95 TPOT 621 ms.
|
||||
- Frontier does not reproduce real vLLM's TP1 preemption behavior: real vLLM had
|
||||
8 preemptions, while Frontier reported 0.
|
||||
- Frontier emits complete request/cache metrics for only 92 rows in this run,
|
||||
so p95 and throughput are not yet on the same request set.
|
||||
- The TTFT sign is mixed: Frontier p50 TTFT is too optimistic, but p95 TTFT is
|
||||
far too pessimistic. This is consistent with uncalibrated execution timing plus
|
||||
different queue/preemption dynamics.
|
||||
|
||||
## RS5 Profiled Frontier Timing
|
||||
|
||||
Frontier does support replacing dummy timing with real CSV profiles through the
|
||||
random-forest execution-time predictor. The required non-dummy flags are wired
|
||||
in `tools/run_frontier_sweep.py`, and the active profiled config is
|
||||
`configs/rs5_frontier_h20_tp1_profile.json`.
|
||||
|
||||
Profile data collected on dash2 H20 TP1:
|
||||
|
||||
- Linear ops: `linear_op.csv`, CUDA event, max tokens 4096.
|
||||
- Attention: `attention_combined.csv`, CUDA event, max sequence/chunk 18000,
|
||||
with 15417 standard rows plus 612 true-mixed rows. Online replay needs the
|
||||
true-mixed rows to train `attn_prefill_mixed` and `attn_decode_in_mixed`.
|
||||
- MoE: `moe_vllm_fused.csv`, CUDA event, max tokens 4096, vLLM fused MoE
|
||||
backend.
|
||||
|
||||
Frontier vLLM 0.11.1 profiling needed local compatibility patches in
|
||||
`patches/frontier-vllm-0.11.1-profiling-compat.patch`:
|
||||
|
||||
- RoPE helper fallback when vLLM 0.11.1 `get_rope()` no longer accepts the
|
||||
legacy `rotary_dim` keyword.
|
||||
- `_get_config_dtype_str` fallback for vLLM fused MoE config dtype.
|
||||
- `ReplicatedLinear(disable_tp=True)` fallback to torch `Linear` when vLLM TP
|
||||
group is not initialized in standalone profiling.
|
||||
- `fused_topk()` variable-return handling.
|
||||
- `invoke_fused_moe_kernel()` 0.11.1 signature compatibility.
|
||||
|
||||
The first profiled MoE attempt used Frontier's `frontier_loop` backend and was
|
||||
not faithful to vLLM serving. It predicted `moe_grouped_gemm` at about 16 ms for
|
||||
24 tokens and 19 ms for 1024 tokens, causing TPOT around 0.93 s. The vLLM fused
|
||||
MoE profile predicts about 0.32 ms for 24 tokens and 0.87 ms for 1024 tokens.
|
||||
|
||||
| run | completed | prefix hit ratio | TTFT p50/p95 | TPOT p50/p95 | E2E p50/p95 | total tok/s | decode tok/s |
|
||||
|---|---:|---:|---:|---:|---:|---:|---:|
|
||||
| Frontier dummy `vllm_kv_15281` | 92/100 | 0.2422 | 0.964/182.639s | 0.582/0.582s | 305.290/1765.347s | 131.3 | 19.4 |
|
||||
| Frontier profiled `frontier_loop` MoE | 93/100 | 0.2492 | 3.320/310.235s | 0.930/1.767s | 492.097/2038.538s | 165.9 | 24.6 |
|
||||
| Frontier profiled vLLM fused MoE | 97/100 | 0.2376 | 0.355/13.695s | 0.056/0.098s | 27.032/119.019s | 2056.7 | 304.5 |
|
||||
| Frontier profiled vLLM fused MoE, linear/MoE 32K | 96/100 | 0.2484 | 0.909/12.763s | 0.057/0.146s | 30.939/119.636s | 2348.9 | 347.8 |
|
||||
| vLLM TP1 real | 100/100 | 0.2511 | 4.503/29.060s | 0.066/0.621s | 41.841/97.366s | 3832.3 | 567.4 |
|
||||
|
||||
Current judgment:
|
||||
|
||||
- The profiled vLLM fused MoE run is the first useful timing baseline. TPOT p50
|
||||
is close to real vLLM, but throughput is still about 54% of real vLLM and
|
||||
TTFT/E2E tails do not align.
|
||||
- After extending linear and MoE profiles to 32768 tokens and adding
|
||||
`prefill_hot` MoE rows, the cache hit ratio is nearly aligned
|
||||
(0.2484 vs vLLM 0.2511), throughput improves to about 61% of real vLLM, and
|
||||
TTFT p50 moves from 0.08x to 0.20x of real vLLM. This confirms that the 4096
|
||||
profile ceiling was a real source of error.
|
||||
- Prefix/cache accounting remains close but not exact: the profiled run emits
|
||||
complete cache metrics for 96/100 requests in the 32K run, with token hit
|
||||
ratio 0.2488 vs vLLM's sidecar estimate 0.2511.
|
||||
- Frontier still reports zero preemptions, while real vLLM TP1 had 8 preemption
|
||||
events. This affects completion set, TTFT tail, and E2E tail.
|
||||
- The remaining gaps are no longer explained by the linear/MoE 4096-token
|
||||
extrapolation alone. The 32K run still has TTFT p50 at 0.20x, TTFT p95 at
|
||||
0.44x, TPOT p95 at 0.23x, and throughput at 0.61x of real vLLM. This points
|
||||
to missing CPU/scheduler/CUDA-graph modeling plus Frontier's scheduler and
|
||||
completion/preemption fidelity.
|
||||
- The 32K run still completes only 96/100 requests in latency/cache metrics
|
||||
(`70`, `77`, `88`, `90` missing), while real vLLM completes 100/100. This is
|
||||
a Frontier lifecycle/metrics or scheduler-fidelity issue to debug separately.
|
||||
|
||||
## 2026-06-24 Follow-Up
|
||||
|
||||
Handled in the ReplayServe harness:
|
||||
|
||||
- `tools/run_frontier_sweep.py` now passes an absolute metrics output path into
|
||||
Frontier. Frontier runs with `cwd=/tmp/replayserve-frontier-rs1b`; relative
|
||||
metrics paths can otherwise be written under the Frontier scratch instead of
|
||||
ReplayServe's run directory.
|
||||
- `tools/postprocess_frontier_smoke.py` now emits a `completion` block with
|
||||
`completed_requests`, `total_requests`, and `missing_latency_request_ids`.
|
||||
- `tools/aggregate_runs.py` now marks a run as `incomplete` when postprocess
|
||||
reports missing latency rows. The latest RS6 summary is therefore incomplete,
|
||||
not a clean pass.
|
||||
|
||||
Latest RS6 vs real vLLM TP1 after the 32K profile and harness fixes:
|
||||
|
||||
| metric | Frontier RS6 32K profile | real vLLM TP1 | Frontier / vLLM |
|
||||
|---|---:|---:|---:|
|
||||
| completed requests | 96/100 | 100/100 | 0.96 |
|
||||
| prefix token hit ratio | 0.2488 | 0.2511 | 0.99 |
|
||||
| preemption events | 0 | 8 | 0.00 |
|
||||
| TTFT p50 | 0.909s | 4.503s | 0.20 |
|
||||
| TTFT p95 | 12.763s | 29.060s | 0.44 |
|
||||
| TPOT p50 | 0.0569s | 0.0661s | 0.86 |
|
||||
| TPOT p95 | 0.146s | 0.621s | 0.23 |
|
||||
| E2E p50 | 30.939s | 41.841s | 0.74 |
|
||||
| E2E p95 | 119.636s | 97.366s | 1.23 |
|
||||
| total tok/s | 2348.9 | 3832.3 | 0.61 |
|
||||
| decode tok/s | 347.8 | 567.4 | 0.61 |
|
||||
|
||||
Preemption experiment:
|
||||
|
||||
- A local trial enabled waiting-admission preemption in Frontier Phase 2. It did
|
||||
produce preemption events, but it was not a valid alignment improvement:
|
||||
Frontier completed only 79/100 requests and amplified the early-decode
|
||||
disappearance pattern. That config was removed from `configs/`.
|
||||
- This means the remaining preemption gap is not just "turn on preemption in
|
||||
Phase 2". Frontier's batch/runtime-epoch lifecycle needs a deeper fix before
|
||||
its preemption behavior can be considered faithful to vLLM TP1.
|
||||
|
||||
Current interpretation:
|
||||
|
||||
- Prefix/cache replay is close: token-weighted prefix hit ratio is within about
|
||||
1% relative of the vLLM synthetic replay estimate.
|
||||
- Completion/preemption is not aligned. Requests `70`, `77`, `88`, and `90`
|
||||
begin decode in RS6 but never reach completion metrics; vLLM completes all
|
||||
100 requests and logs 8 preemption events.
|
||||
- Timing is partially useful but not fully calibrated. Linear and MoE profiles
|
||||
now cover the trace's long-prefill range up to 32768 tokens, so the old 4096
|
||||
extrapolation is no longer the main explanation. The remaining TTFT/TPOT/E2E
|
||||
gap likely comes from missing CPU/scheduler overhead, decode CUDA graph
|
||||
modeling, and Frontier scheduler lifecycle differences.
|
||||
|
||||
## 2026-06-25 500-Request Stress
|
||||
|
||||
Generated `traces/fixtures/coder_500` from the first 500 rows of
|
||||
`qwen_coder_blksz_16.jsonl`:
|
||||
|
||||
- `row_count=500`
|
||||
- `max_total_tokens=21318`
|
||||
- `overflow_count=0`
|
||||
- `partial_final_block_rows=466`
|
||||
|
||||
Frontier RS8 used the same H20 TP1 Qwen3-30B-A3B full32K profile and explicit
|
||||
KV block count as RS6:
|
||||
|
||||
- Config:
|
||||
`configs/rs8_frontier_h20_tp1_profile_full32k_coder500.json`
|
||||
- Run:
|
||||
`runs/rs8_frontier_h20_tp1_profile_full32k_coder500_20260625`
|
||||
- Runtime: 492 seconds
|
||||
- Status: incomplete
|
||||
|
||||
| metric | Frontier RS6 100 reqs | Frontier RS8 500 reqs |
|
||||
|---|---:|---:|
|
||||
| completed requests | 96/100 | 439/500 |
|
||||
| missing latency/cache rows | 4 | 61 |
|
||||
| prefix token hit ratio | 0.2488 | 0.1192 |
|
||||
| preemption events | 0 | 0 |
|
||||
| TTFT p50/p95 | 0.909/12.763s | 136.776/340.237s |
|
||||
| TPOT p50/p95 | 0.0569/0.146s | 0.0564/0.0894s |
|
||||
| E2E p50/p95 | 30.939/119.636s | 177.800/397.291s |
|
||||
| total tok/s | 2348.9 | 4733.7 |
|
||||
| decode tok/s | 347.8 | 656.2 |
|
||||
|
||||
Missing request ids in RS8:
|
||||
|
||||
```text
|
||||
70,77,88,90,103,106,134,135,142,143,153,154,176,178,183,184,186,188,210,211,216,222,245,246,263,272,274,278,291,298,299,300,320,325,334,335,347,348,363,367,373,374,393,399,403,409,412,413,414,433,434,437,439,450,453,460,469,475,476,479,497
|
||||
```
|
||||
|
||||
The incomplete-row issue clearly scales: 4/100 missing in RS6 becomes 61/500
|
||||
missing in RS8. This makes RS8 invalid for final performance claims, but useful
|
||||
as a stress signal for Frontier lifecycle/metrics fidelity.
|
||||
|
||||
The lower prefix hit ratio is not by itself proof of adapter failure. The
|
||||
unbounded trace-side trie estimate for `coder_500` is 0.3868 token hit ratio,
|
||||
but the H20 TP1 configuration has finite KV capacity (`num_blocks=15281`, about
|
||||
244K tokens). The 500-request window has 2.7M prompt tokens, so KV eviction can
|
||||
substantially reduce real prefix hits. The dash1 vLLM run below is the current
|
||||
finite-cache comparator for whether Frontier's behavior is faithful.
|
||||
|
||||
Real vLLM TP1 500 was first attempted on dash2 with the same settings as
|
||||
`tp1_coder100_uncapped` (`max_num_seqs=64`, `max_num_batched_tokens=32768`,
|
||||
`gpu_memory_utilization=0.85`, `CUDA_VISIBLE_DEVICES=0`), but did not start
|
||||
because dash2 was already occupied by eight existing `agentic-kvc` vLLM serve
|
||||
processes on ports 8000-8007. Each H20 had about 89GB allocated, and vLLM failed
|
||||
with free memory below the required 0.85 utilization target. Those processes
|
||||
were not killed; the temporary ReplayServe GPU lock was released.
|
||||
|
||||
A replacement vLLM TP1 500 run completed on dash1:
|
||||
|
||||
- Run:
|
||||
`runs/vllm_gpu_smoke_20260625_dash1/tp1_coder500_uncapped`
|
||||
- Runtime: vLLM 0.11.1
|
||||
- Host/GPU: dash1, one NVIDIA H20 via `CUDA_VISIBLE_DEVICES=0`
|
||||
- Model: `/home/admin/cpfs/wjh/models/Qwen/Qwen3-30B-A3B`
|
||||
- Command knobs: `TP=1`, `max_model_len=32768`, `max_num_seqs=64`,
|
||||
`max_num_batched_tokens=32768`, `gpu_memory_utilization=0.85`,
|
||||
prefix caching on, chunked prefill on
|
||||
- vLLM profiled KV capacity: 244,496 tokens = 15,281 blocks at block size 16
|
||||
- Replay wall time after engine startup: 595.116 seconds
|
||||
- Process elapsed including model load/startup: 2026-06-25T03:08:18Z to
|
||||
2026-06-25T03:19:41Z
|
||||
|
||||
| metric | Frontier RS8 500 reqs | vLLM TP1 500 reqs | vLLM / Frontier |
|
||||
|---|---:|---:|---:|
|
||||
| completed requests | 439/500 | 500/500 | not aligned |
|
||||
| preemption events | 0 | 63 | not aligned |
|
||||
| repeated/preempted request ids | 0 | 57 | not aligned |
|
||||
| TTFT p50 | 136.776s | 185.658s | 1.36 |
|
||||
| TTFT p95 | 340.237s | 375.895s | 1.10 |
|
||||
| TPOT p50 | 0.0564s | 0.0498s | 0.88 |
|
||||
| TPOT p95 | 0.0894s | 0.0919s | 1.03 |
|
||||
| E2E p50 | 177.800s | 224.270s | 1.26 |
|
||||
| E2E p95 | 397.291s | 417.356s | 1.05 |
|
||||
| requests/s | 0.661 | 0.840 | 1.27 |
|
||||
| total tok/s | 4733.7 | 5282.9 | 1.12 |
|
||||
| decode tok/s | 656.2 | 732.3 | 1.12 |
|
||||
|
||||
Because Frontier emits latency/cache rows for only 439 requests, the latency
|
||||
comparison above mixes Frontier's completed subset with vLLM's complete 500-row
|
||||
run. Restricting vLLM to the same 439 request ids gives:
|
||||
|
||||
| metric | Frontier RS8 439 rows | vLLM same 439 ids | vLLM / Frontier |
|
||||
|---|---:|---:|---:|
|
||||
| TTFT p50 | 136.776s | 169.968s | 1.24 |
|
||||
| TTFT p95 | 340.237s | 375.760s | 1.10 |
|
||||
| TPOT p50 | 0.0564s | 0.0498s | 0.88 |
|
||||
| TPOT p95 | 0.0894s | 0.1071s | 1.20 |
|
||||
| E2E p50 | 177.800s | 218.606s | 1.23 |
|
||||
| E2E p95 | 397.291s | 416.110s | 1.05 |
|
||||
|
||||
Prefix/cache comparison needs careful metric naming:
|
||||
|
||||
- The unbounded ReplayServe trie estimate for all 500 rows is 1,047,632 hit
|
||||
tokens / 2,708,110 prompt tokens = 0.3868 token hit ratio.
|
||||
- vLLM's finite-cache scheduler log is much lower under this pressure:
|
||||
first-start `computed:` ratio is 0.0979, last-start ratio is 0.1643, and
|
||||
max-per-request ratio is 0.1655.
|
||||
- On the same 439 request ids where Frontier emits complete metrics, vLLM's
|
||||
first-start `computed:` ratio is 0.1050, last-start ratio is 0.1665, and
|
||||
max-per-request ratio is 0.1679.
|
||||
- Frontier RS8 reports `replayserve_token_hit_ratio=0.1192` and
|
||||
`frontier_block_hit_ratio=0.1191`, which is in the same order as vLLM's
|
||||
finite-cache scheduler signal but far below the unbounded trace-side estimate.
|
||||
|
||||
Current 500-request judgment:
|
||||
|
||||
- Frontier's timing profile is now in the right broad range for this stressed
|
||||
H20 TP1 run: TPOT p50/p95 and E2E p95 are close to vLLM, and aggregate token
|
||||
throughput is within about 12%.
|
||||
- The run is still not a faithful simulator result because completion and
|
||||
preemption diverge: Frontier drops 61 latency/cache rows and reports zero
|
||||
preemptions, while real vLLM completes all 500 requests and logs 63
|
||||
preemption events across 57 request ids.
|
||||
- The 500-request trace invalidates the earlier use of the unbounded sidecar
|
||||
prefix estimate as the primary comparator. Finite KV capacity, eviction, and
|
||||
preemption must be part of the prefix-cache replay metric.
|
||||
|
||||
ReplayServe TODO:
|
||||
|
||||
- Treat incomplete Frontier runs as invalid for final performance claims unless
|
||||
the comparison explicitly reports the missing request set.
|
||||
- Keep the focused Frontier debug guard in the local patch: sequential mode now
|
||||
fails if `completed_requests < total_requests` at drain time and reports the
|
||||
missing request state.
|
||||
- Add a comparator that reports both unbounded trace-side prefix reuse and
|
||||
finite-cache observed reuse from vLLM scheduler logs; do not compare
|
||||
Frontier's finite-cache hit ratio directly to the unbounded trie estimate.
|
||||
- Profile or import vLLM CPU overhead records for H20 TP1 before enabling
|
||||
`skip_cpu_overhead_modeling=false`; without those records Frontier falls back
|
||||
to zero CPU overhead.
|
||||
- Collect kernel-only/decode-CUDA-graph timing profiles before using
|
||||
`decode_cuda_graph_mode=full_decode_only`; the current RS6 profile is CUDA
|
||||
event/eager timing.
|
||||
|
||||
## 2026-06-25 200-Request Timestamp Scale 2/3
|
||||
|
||||
Generated `traces/fixtures/coder_200_ts0667` from the first 200 rows of
|
||||
`qwen_coder_blksz_16.jsonl`, with each timestamp multiplied by `2/3` in the
|
||||
fixture files:
|
||||
|
||||
- `row_count=200`
|
||||
- `timestamp_scale=0.6666666666666666`
|
||||
- `last_timestamp=30.711333333333332`
|
||||
- `max_total_tokens=18985`
|
||||
- `partial_final_block_rows=182`
|
||||
|
||||
Important: in the current replay semantics, smaller timestamp scale makes
|
||||
arrivals denser. It reduces the arrival window from about 46.1s to 30.7s for the
|
||||
first 200 requests. This does not reduce queue pressure relative to the same
|
||||
200 requests at scale 1.0; it only reduces the request count relative to the
|
||||
500-request stress.
|
||||
|
||||
Frontier RS9:
|
||||
|
||||
- Config:
|
||||
`configs/rs9_frontier_h20_tp1_profile_full32k_coder200_ts0667.json`
|
||||
- Run:
|
||||
`runs/rs9_frontier_h20_tp1_profile_full32k_coder200_ts0667`
|
||||
- Runtime: 460 seconds
|
||||
- Status: incomplete
|
||||
|
||||
vLLM dash1 TP1:
|
||||
|
||||
- Run:
|
||||
`runs/vllm_gpu_smoke_20260625_dash1/tp1_coder200_ts0667_uncapped`
|
||||
- Runtime: vLLM 0.11.1
|
||||
- Host/GPU: dash1, one NVIDIA H20 via `CUDA_VISIBLE_DEVICES=0`
|
||||
- vLLM profiled KV capacity: 244,496 tokens = 15,281 blocks at block size 16
|
||||
- Replay wall time after engine startup: 242.813 seconds
|
||||
|
||||
| metric | Frontier RS9 200 ts=2/3 | vLLM TP1 200 ts=2/3 | vLLM / Frontier |
|
||||
|---|---:|---:|---:|
|
||||
| completed requests | 176/200 | 200/200 | not aligned |
|
||||
| preemption events | 0 | 26 | not aligned |
|
||||
| TTFT p50 | 20.580s | 34.563s | 1.68 |
|
||||
| TTFT p95 | 96.718s | 120.804s | 1.25 |
|
||||
| TPOT p50 | 0.0584s | 0.0515s | 0.88 |
|
||||
| TPOT p95 | 0.2359s | 0.2535s | 1.07 |
|
||||
| E2E p50 | 73.207s | 83.622s | 1.14 |
|
||||
| E2E p95 | 189.240s | 183.727s | 0.97 |
|
||||
| requests/s | 0.583 | 0.824 | 1.41 |
|
||||
| total tok/s | 3913.4 | 4864.8 | 1.24 |
|
||||
| decode tok/s | 593.3 | 737.5 | 1.24 |
|
||||
|
||||
Restricting vLLM to the same 176 request ids where Frontier emits complete
|
||||
metrics gives:
|
||||
|
||||
| metric | Frontier RS9 176 rows | vLLM same 176 ids | vLLM / Frontier |
|
||||
|---|---:|---:|---:|
|
||||
| TTFT p50 | 20.580s | 27.896s | 1.36 |
|
||||
| TTFT p95 | 96.718s | 120.804s | 1.25 |
|
||||
| TPOT p50 | 0.0584s | 0.0520s | 0.89 |
|
||||
| TPOT p95 | 0.2359s | 0.2539s | 1.08 |
|
||||
| E2E p50 | 73.207s | 82.645s | 1.13 |
|
||||
| E2E p95 | 189.240s | 183.727s | 0.97 |
|
||||
|
||||
Prefix/cache comparison:
|
||||
|
||||
- The unbounded ReplayServe trie estimate for all 200 rows is 270,336 hit
|
||||
tokens / 1,002,154 prompt tokens = 0.2698 token hit ratio.
|
||||
- vLLM finite-cache scheduler signal for all 200 rows: first-start `computed:`
|
||||
ratio 0.1392, last-start ratio 0.2126, max-per-request ratio 0.2129.
|
||||
- On the same 176 request ids where Frontier emits complete metrics, vLLM
|
||||
first-start ratio is 0.1487, last-start ratio is 0.1926, and max-per-request
|
||||
ratio is 0.1927.
|
||||
- Frontier RS9 reports `replayserve_token_hit_ratio=0.1703` and
|
||||
`frontier_block_hit_ratio=0.1700`, again between vLLM first-start and
|
||||
last/max finite-cache scheduler signals.
|
||||
|
||||
Missing request ids in RS9:
|
||||
|
||||
```text
|
||||
70,78,80,86,87,89,96,101,102,105,125,126,131,132,135,144,145,146,147,148,149,150,151,198
|
||||
```
|
||||
|
||||
Current 200-request judgment:
|
||||
|
||||
- Reducing the request count from 500 to 200 substantially reduces TTFT and E2E
|
||||
tails, but `scale=2/3` is still a dense-arrival stress test. vLLM TTFT p95 is
|
||||
still 120.8s.
|
||||
- Frontier timing is closer than the old 100-request dummy/profile baselines:
|
||||
TPOT p50/p95 and E2E p50/p95 are broadly aligned.
|
||||
- Completion/preemption remains the blocking fidelity issue: Frontier drops 24
|
||||
rows and reports zero preemptions; vLLM completes all 200 and logs 26
|
||||
preemptions across 22 repeated-start request ids.
|
||||
- To actually reduce queue pressure for the same first 200 requests, use a
|
||||
timestamp scale greater than 1. The follow-up scale 2 and 3 runs below do
|
||||
this.
|
||||
|
||||
## 2026-06-25 200-Request Timestamp Scale 2 and 3
|
||||
|
||||
Generated two more first-200 fixtures from `qwen_coder_blksz_16.jsonl`:
|
||||
|
||||
| fixture | timestamp scale | last timestamp | max total tokens |
|
||||
|---|---:|---:|---:|
|
||||
| `coder_200_ts2` | 2.0 | 92.134s | 18,985 |
|
||||
| `coder_200_ts3` | 3.0 | 138.201s | 18,985 |
|
||||
|
||||
These are the intended lower-arrival-pressure runs. The request payloads are the
|
||||
same first 200 rows as `coder_200_ts0667`; only timestamps differ.
|
||||
|
||||
Frontier RS10:
|
||||
|
||||
- Config:
|
||||
`configs/rs10_frontier_h20_tp1_profile_full32k_coder200_ts2_ts3.json`
|
||||
- Run:
|
||||
`runs/rs10_frontier_h20_tp1_profile_full32k_coder200_ts2_ts3`
|
||||
- Status: incomplete for both fixtures
|
||||
|
||||
vLLM dash1 TP1:
|
||||
|
||||
- Runs:
|
||||
`runs/vllm_gpu_smoke_20260625_dash1/tp1_coder_200_ts2_uncapped`
|
||||
and `runs/vllm_gpu_smoke_20260625_dash1/tp1_coder_200_ts3_uncapped`
|
||||
- Runtime: vLLM 0.11.1
|
||||
- Host/GPU: dash1, one NVIDIA H20 via `CUDA_VISIBLE_DEVICES=0`
|
||||
- vLLM profiled KV capacity: 244,496 tokens = 15,281 blocks at block size 16
|
||||
|
||||
Run-level comparison:
|
||||
|
||||
| metric | Frontier scale 2 | vLLM scale 2 | Frontier scale 3 | vLLM scale 3 |
|
||||
|---|---:|---:|---:|---:|
|
||||
| completed requests | 182/200 | 200/200 | 184/200 | 200/200 |
|
||||
| preemption events | 0 | 43 | 0 | 16 |
|
||||
| TTFT p50 | 8.118s | 9.217s | 0.779s | 1.166s |
|
||||
| TTFT p95 | 67.850s | 69.211s | 35.918s | 32.258s |
|
||||
| TPOT p50 | 0.0544s | 0.0497s | 0.0544s | 0.0462s |
|
||||
| TPOT p95 | 0.0747s | 0.0686s | 0.0773s | 0.0714s |
|
||||
| E2E p50 | 51.118s | 55.002s | 40.641s | 33.213s |
|
||||
| E2E p95 | 162.607s | 142.338s | 158.434s | 122.789s |
|
||||
| requests/s | 0.593 | 0.803 | 0.544 | 0.780 |
|
||||
| total tok/s | 3846.1 | 4742.5 | 3490.6 | 4608.1 |
|
||||
| decode tok/s | 583.1 | 719.0 | 529.2 | 698.6 |
|
||||
|
||||
Restricting vLLM to the same request ids where Frontier emits complete metrics:
|
||||
|
||||
| metric | Frontier scale 2 182 rows | vLLM same 182 ids | Frontier scale 3 184 rows | vLLM same 184 ids |
|
||||
|---|---:|---:|---:|---:|
|
||||
| TTFT p50 | 8.118s | 8.574s | 0.779s | 0.945s |
|
||||
| TTFT p95 | 67.850s | 68.934s | 35.918s | 32.258s |
|
||||
| TPOT p50 | 0.0544s | 0.0501s | 0.0544s | 0.0461s |
|
||||
| TPOT p95 | 0.0747s | 0.0686s | 0.0773s | 0.0679s |
|
||||
| E2E p50 | 51.118s | 53.263s | 40.641s | 33.213s |
|
||||
| E2E p95 | 162.607s | 141.264s | 158.434s | 122.789s |
|
||||
|
||||
Prefix/cache comparison:
|
||||
|
||||
| metric | scale 2 | scale 3 |
|
||||
|---|---:|---:|
|
||||
| unbounded trace-side token hit ratio | 0.2698 | 0.2698 |
|
||||
| vLLM first-start `computed:` ratio | 0.1433 | 0.1471 |
|
||||
| vLLM last-start `computed:` ratio | 0.2382 | 0.1968 |
|
||||
| vLLM max-per-request `computed:` ratio | 0.2383 | 0.1998 |
|
||||
| Frontier `replayserve_token_hit_ratio` | 0.1448 | 0.1523 |
|
||||
| Frontier `frontier_block_hit_ratio` | 0.1446 | 0.1521 |
|
||||
|
||||
Current scale 2 and 3 judgment:
|
||||
|
||||
- The user's intended `scale=2` and `scale=3` runs do reduce queueing. vLLM
|
||||
TTFT p95 drops from 120.8s at `scale=2/3` to 69.2s at `scale=2` and 32.3s at
|
||||
`scale=3`.
|
||||
- `scale=3` is the first run where vLLM p50 TTFT is near 1s. The p95 is still
|
||||
high because long prompts and KV pressure remain, but the severe all-request
|
||||
queueing seen in the 500-request run is much reduced.
|
||||
- Frontier timing is now close on TTFT and TPOT for the completed-row subset,
|
||||
especially at `scale=2`. However, Frontier still misses completion/cache rows
|
||||
and still reports zero preemptions.
|
||||
- Completion/preemption is therefore still the main Frontier fidelity blocker:
|
||||
`scale=2` misses 18 rows and vLLM logs 43 preemptions; `scale=3` misses 16 rows
|
||||
and vLLM logs 16 preemptions.
|
||||
|
||||
## 2026-06-25 Frontier Lifecycle Fix For RS10
|
||||
|
||||
The missing-row root cause was Frontier lifecycle handling after decode-phase
|
||||
preemption. Missing requests were preempted after prefill/decode had started,
|
||||
then left in this inconsistent state:
|
||||
|
||||
```text
|
||||
preempted=True
|
||||
is_prefill_complete=True
|
||||
num_processed_tokens=0
|
||||
scheduled=False
|
||||
completed=False
|
||||
```
|
||||
|
||||
The next waiting admission computed `num_new_tokens=0` and removed the request
|
||||
from the queue, so sequential simulation drained with fewer completed requests
|
||||
but no remaining scheduler work.
|
||||
|
||||
The updated ReplayServe Frontier patch now:
|
||||
|
||||
- replays decode-phase preemption by treating already-produced tokens as the
|
||||
next prefill segment and the remaining tokens as decode work;
|
||||
- preserves unfinished zero-token waiting requests instead of silently dropping
|
||||
them;
|
||||
- reports metrics against user-facing trace prompt/output lengths after runtime
|
||||
token splitting;
|
||||
- fails fast if sequential mode drains before all generated requests complete.
|
||||
|
||||
Verification runs:
|
||||
|
||||
| run | old completion | fixed completion | Frontier preemptions | prefix token hit ratio | status |
|
||||
|---|---:|---:|---:|---:|---|
|
||||
| `coder_200_ts2` | 182/200 | 200/200 | 33 | 0.2313 | pass |
|
||||
| `coder_200_ts3` | 184/200 | 200/200 | 20 | 0.2177 | pass |
|
||||
|
||||
Fixed-run paths:
|
||||
|
||||
- `runs/rs10_preemption_replay_fix_ts2/frontier_h20_tp1_profile_full32k/coder_200_ts2/vllm_kv_15281_profile_full32k`
|
||||
- `runs/rs10_preemption_replay_fix_ts3/frontier_h20_tp1_profile_full32k/coder_200_ts3/vllm_kv_15281_profile_full32k`
|
||||
|
||||
Updated run-level comparison:
|
||||
|
||||
| metric | Frontier scale 2 fixed | vLLM scale 2 | Frontier scale 3 fixed | vLLM scale 3 |
|
||||
|---|---:|---:|---:|---:|
|
||||
| completed requests | 200/200 | 200/200 | 200/200 | 200/200 |
|
||||
| preemption events | 33 | 43 | 20 | 16 |
|
||||
| TTFT p50 | 9.595s | 9.217s | 1.001s | 1.166s |
|
||||
| TTFT p95 | 77.503s | 69.211s | 45.947s | 32.258s |
|
||||
| TPOT p50 | 0.0542s | 0.0497s | 0.0534s | 0.0462s |
|
||||
| TPOT p95 | 0.0665s | 0.0686s | 0.0686s | 0.0714s |
|
||||
| E2E p50 | 61.458s | 55.002s | 44.761s | 33.213s |
|
||||
| E2E p95 | 174.484s | 142.338s | 154.548s | 122.789s |
|
||||
| requests/s | 0.594 | 0.803 | 0.574 | 0.780 |
|
||||
| total tok/s | 3506.3 | 4742.5 | 3390.0 | 4608.1 |
|
||||
| decode tok/s | 531.6 | 719.0 | 513.9 | 698.6 |
|
||||
|
||||
Current judgment after the fix:
|
||||
|
||||
- The completion/preemption lifecycle blocker for RS10 is fixed: both scale 2
|
||||
and scale 3 now emit 200 request rows and complete postprocess.
|
||||
- Frontier preemption is now in the same order as vLLM, but not exact:
|
||||
scale 2 is 33 vs 43 events, scale 3 is 20 vs 16 events.
|
||||
- Prefix hit ratio changed materially because preempted requests now replay and
|
||||
re-enter prefix-cache admission instead of disappearing. It is no longer valid
|
||||
to compare the old incomplete RS10 prefix ratios against vLLM.
|
||||
- Timing remains close in TPOT but Frontier is still slower in aggregate
|
||||
throughput, about 0.74x of vLLM total/decode token throughput for both scale 2
|
||||
and scale 3. TTFT/E2E tails are still worse after the completion set becomes
|
||||
complete.
|
||||
- Remaining gap is no longer "missing metrics rows"; it is scheduler/preemption
|
||||
fidelity plus CPU/scheduler/CUDA-graph timing calibration.
|
||||
|
||||
## 2026-06-25 H20 TP2/TP4 Comparison
|
||||
|
||||
The TP2/TP4 comparison uses the same first-200 `coder_200_ts2` and
|
||||
`coder_200_ts3` fixtures. The vLLM runs are on dash1 with
|
||||
`/home/admin/cpfs/wjh/models/Qwen/Qwen3-30B-A3B`, vLLM 0.11.1,
|
||||
`max_model_len=32768`, `max_num_seqs=64`,
|
||||
`max_num_batched_tokens=32768`, `gpu_memory_utilization=0.85`,
|
||||
prefix caching on, and chunked prefill on.
|
||||
|
||||
vLLM measured KV capacity:
|
||||
|
||||
| TP | KV tokens | KV blocks |
|
||||
|---:|---:|---:|
|
||||
| 2 | 1,104,880 | 69,055 |
|
||||
| 4 | 2,833,232 | 177,077 |
|
||||
|
||||
Frontier RS12 uses explicit matching KV blocks and fresh H20 TP2/TP4 profiles:
|
||||
|
||||
- Config:
|
||||
`configs/rs12_frontier_h20_tp2_tp4_profile_full32k_coder200_ts2_ts3.json`
|
||||
- Run:
|
||||
`runs/rs12_frontier_h20_tp2_tp4_profile_full32k_coder200_ts2_ts3`
|
||||
- Profile source:
|
||||
`dash1:/home/admin/cpfs/wjh/replayserve_frontier_profiles/h20_tp2_tp4_qwen3_30ba3b_full32k_20260625_true_mixed`
|
||||
- Linear/MoE profiles cover TP2/TP4 up to 32768 tokens.
|
||||
- Attention profile covers TP2/TP4 standard attention plus 1260 true-mixed
|
||||
prefill+decode rows. The true-mixed rows are required; standard attention
|
||||
alone fails with missing `attn_decode_in_mixed` predictions.
|
||||
|
||||
All four Frontier runs completed 200/200 request rows. Neither Frontier nor the
|
||||
vLLM TP2/TP4 logs reported preemption events. Prefix token hit ratio is exactly
|
||||
the same in Frontier postprocess and vLLM's trace-side synthetic estimate:
|
||||
0.2697549478.
|
||||
|
||||
Run-level comparison:
|
||||
|
||||
| TP | fixture | metric | Frontier | vLLM | Frontier / vLLM |
|
||||
|---:|---|---|---:|---:|---:|
|
||||
| 2 | `coder_200_ts2` | requests/s | 0.776 | 1.278 | 0.61 |
|
||||
| 2 | `coder_200_ts2` | total tok/s | 4581 | 7547 | 0.61 |
|
||||
| 2 | `coder_200_ts2` | decode tok/s | 695 | 1144 | 0.61 |
|
||||
| 2 | `coder_200_ts2` | TTFT p50/p95 | 0.269/6.745s | 0.225/0.715s | 1.20/9.43 |
|
||||
| 2 | `coder_200_ts2` | TPOT p50/p95 | 0.0430/0.0529s | 0.0300/0.0434s | 1.43/1.22 |
|
||||
| 2 | `coder_200_ts2` | E2E p50/p95 | 26.05/106.76s | 16.45/72.53s | 1.58/1.47 |
|
||||
| 4 | `coder_200_ts2` | requests/s | 0.853 | 1.536 | 0.55 |
|
||||
| 4 | `coder_200_ts2` | total tok/s | 5035 | 9073 | 0.55 |
|
||||
| 4 | `coder_200_ts2` | decode tok/s | 763 | 1376 | 0.55 |
|
||||
| 4 | `coder_200_ts2` | TTFT p50/p95 | 0.098/0.386s | 0.170/1.420s | 0.57/0.27 |
|
||||
| 4 | `coder_200_ts2` | TPOT p50/p95 | 0.0337/0.0384s | 0.0163/0.0283s | 2.06/1.36 |
|
||||
| 4 | `coder_200_ts2` | E2E p50/p95 | 18.65/84.94s | 9.26/43.62s | 2.01/1.95 |
|
||||
| 2 | `coder_200_ts3` | requests/s | 0.688 | 1.088 | 0.63 |
|
||||
| 2 | `coder_200_ts3` | total tok/s | 4062 | 6426 | 0.63 |
|
||||
| 2 | `coder_200_ts3` | decode tok/s | 616 | 974 | 0.63 |
|
||||
| 2 | `coder_200_ts3` | TTFT p50/p95 | 0.134/0.574s | 0.154/0.627s | 0.87/0.92 |
|
||||
| 2 | `coder_200_ts3` | TPOT p50/p95 | 0.0394/0.0467s | 0.0191/0.0280s | 2.07/1.67 |
|
||||
| 2 | `coder_200_ts3` | E2E p50/p95 | 21.79/101.59s | 9.96/53.98s | 2.19/1.88 |
|
||||
| 4 | `coder_200_ts3` | requests/s | 0.737 | 1.254 | 0.59 |
|
||||
| 4 | `coder_200_ts3` | total tok/s | 4355 | 7403 | 0.59 |
|
||||
| 4 | `coder_200_ts3` | decode tok/s | 660 | 1122 | 0.59 |
|
||||
| 4 | `coder_200_ts3` | TTFT p50/p95 | 0.089/0.346s | 0.100/0.318s | 0.89/1.09 |
|
||||
| 4 | `coder_200_ts3` | TPOT p50/p95 | 0.0311/0.0358s | 0.0094/0.0128s | 3.30/2.80 |
|
||||
| 4 | `coder_200_ts3` | E2E p50/p95 | 16.90/83.01s | 5.55/27.87s | 3.05/2.98 |
|
||||
|
||||
TP scaling comparison:
|
||||
|
||||
| fixture | metric | Frontier TP4 / TP2 | vLLM TP4 / TP2 |
|
||||
|---|---|---:|---:|
|
||||
| `coder_200_ts2` | total tok/s speedup | 1.10 | 1.20 |
|
||||
| `coder_200_ts2` | decode tok/s speedup | 1.10 | 1.20 |
|
||||
| `coder_200_ts2` | TPOT p50 reduction | 0.78 | 0.54 |
|
||||
| `coder_200_ts3` | total tok/s speedup | 1.07 | 1.15 |
|
||||
| `coder_200_ts3` | decode tok/s speedup | 1.07 | 1.15 |
|
||||
| `coder_200_ts3` | TPOT p50 reduction | 0.79 | 0.49 |
|
||||
|
||||
Current TP2/TP4 judgment:
|
||||
|
||||
- Functional replay is aligned for this setting: same request rows, same
|
||||
trace-side prefix reuse ratio, matched vLLM KV block counts, and no
|
||||
preemption on either side.
|
||||
- Absolute performance is not aligned. Frontier reports only 55-63% of vLLM
|
||||
total/decode throughput across TP2/TP4, and TPOT is especially pessimistic at
|
||||
TP4.
|
||||
- Relative TP scaling is also under-estimated. vLLM's TP4 improves TPOT p50 by
|
||||
about 46-51% over TP2, while Frontier improves by only about 21-22%.
|
||||
- The remaining gap is therefore not caused by missing rows, prefix-cache
|
||||
mismatch, or KV capacity mismatch in these runs. It points to timing model
|
||||
limitations: missing CPU/scheduler/CUDA-graph modeling, random-forest profile
|
||||
interpolation error, and imperfect modeling of vLLM's TP-dependent decode
|
||||
execution path.
|
||||
- These RS12 results are acceptable for continuing ReplayServe integration and
|
||||
rough qualitative trends. They are not yet acceptable as calibrated absolute
|
||||
performance predictions.
|
||||
138
docs/rs4_vllm_gpu_smoke.md
Normal file
138
docs/rs4_vllm_gpu_smoke.md
Normal file
@@ -0,0 +1,138 @@
|
||||
# RS4 vLLM GPU Smoke
|
||||
|
||||
RS4 starts a real serving baseline for ReplayServe. This is separate from the
|
||||
Frontier dummy/patched simulator smoke: it checks whether the Qwen block-hash
|
||||
trace can drive a real vLLM engine with the intended arrival, prompt length,
|
||||
decode length, and prefix reuse patterns.
|
||||
|
||||
## Setup
|
||||
|
||||
- Host: `dash2`
|
||||
- GPU: NVIDIA H20
|
||||
- Model: `/home/admin/cpfs/wjh/models/Qwen/Qwen3-30B-A3B`
|
||||
- Runtime: Python 3.12.3, vLLM 0.11.1
|
||||
- Fixture: `traces/fixtures/coder_100`
|
||||
- Runner: `tools/vllm_synthetic_replay.py`
|
||||
- Replay mode: online, trace-relative timestamps preserved
|
||||
- Prompt mode: `prompt_token_ids`, generated synthetically from trace block
|
||||
hashes
|
||||
- Common vLLM knobs: `max_model_len=32768`, `block_size=16`,
|
||||
`max_num_batched_tokens=32768`, `gpu_memory_utilization=0.85`,
|
||||
prefix caching on, chunked prefill on
|
||||
|
||||
The Qwen trace does not expose original token IDs or text. The runner maps each
|
||||
block hash deterministically to one stable synthetic token block. Equal block
|
||||
hashes therefore produce equal token blocks, preserving arrival, length, and
|
||||
block-prefix sharing patterns, but not original text semantics.
|
||||
|
||||
## Runs
|
||||
|
||||
The first smoke used single-request runs for engine bring-up, 32-request capped
|
||||
runs for prefix-cache validation, 32-request uncapped runs for a first
|
||||
real-output baseline, and full `coder_100` uncapped runs for the first useful
|
||||
TP=1/2 comparison.
|
||||
|
||||
| run | TP | rows | prompt toks | gen toks | wall s | RPS | prompt tok/s | gen tok/s | TTFT p50/p95 | TPOT p50/p95 | E2E p50/p95 |
|
||||
|---|---:|---:|---:|---:|---:|---:|---:|---:|---:|---:|---:|
|
||||
| `tp1_limit1` | 1 | 1 | 1008 | 4 | 1.861 | 0.537 | 541.5 | 2.1 | 1.255/1.255 | 0.007/0.007 | 1.274/1.274 |
|
||||
| `tp2_limit1` | 2 | 1 | 1008 | 4 | 2.269 | 0.441 | 444.3 | 1.8 | 1.317/1.317 | 0.008/0.008 | 1.340/1.340 |
|
||||
| `tp1_limit32_o8` | 1 | 32 | 120813 | 253 | 11.244 | 2.846 | 10744.4 | 22.5 | 3.974/5.051 | 0.387/1.081 | 7.157/9.817 |
|
||||
| `tp2_limit32_o8` | 2 | 32 | 120813 | 253 | 9.071 | 3.528 | 13318.2 | 27.9 | 1.881/3.324 | 0.285/0.727 | 4.368/7.043 |
|
||||
| `tp1_limit32_uncapped` | 1 | 32 | 120813 | 22209 | 41.874 | 0.764 | 2885.1 | 530.4 | 1.276/1.842 | 0.024/0.102 | 14.366/29.523 |
|
||||
| `tp2_limit32_uncapped` | 2 | 32 | 120813 | 22209 | 33.588 | 0.953 | 3596.9 | 661.2 | 0.961/1.700 | 0.017/0.071 | 10.786/21.570 |
|
||||
| `tp1_coder100_uncapped` | 1 | 100 | 474554 | 82479 | 145.351 | 0.688 | 3264.9 | 567.4 | 4.503/29.060 | 0.066/0.621 | 41.841/97.366 |
|
||||
| `tp2_coder100_uncapped` | 2 | 100 | 474554 | 82479 | 102.001 | 0.980 | 4652.5 | 808.6 | 1.951/10.355 | 0.049/0.262 | 25.678/61.971 |
|
||||
|
||||
Artifacts were copied back from dash2 to:
|
||||
|
||||
```text
|
||||
runs/vllm_gpu_smoke_20260624/
|
||||
```
|
||||
|
||||
That directory is ignored by git. Each run contains `summary.json` and
|
||||
`request_metrics.csv`; the 32-request runs also keep `stdout.log`.
|
||||
|
||||
## KV Capacity
|
||||
|
||||
vLLM estimated KV capacity from actual H20 memory profiling:
|
||||
|
||||
| TP | weights memory | available KV memory | GPU KV cache size | max concurrency at 32768 tokens/request |
|
||||
|---:|---:|---:|---:|---:|
|
||||
| 1 | 56.93 GiB | 22.39 GiB | 244,512 tokens | 7.46x |
|
||||
| 2 | 28.50 GiB/rank | 50.58 GiB/rank | 1,104,880 tokens | 33.72x |
|
||||
|
||||
This satisfies the RS4 requirement that KV capacity comes from the real GPU
|
||||
memory planner rather than a manually fixed block count.
|
||||
|
||||
## Prefix-Cache Check
|
||||
|
||||
For the first 32 coder requests, ReplayServe estimated:
|
||||
|
||||
- query blocks: 7,564
|
||||
- hit blocks: 1,786
|
||||
- block hit ratio: 0.236118456
|
||||
- query tokens: 120,813
|
||||
- hit tokens: 28,576
|
||||
- token hit ratio: 0.236530837
|
||||
|
||||
The vLLM scheduler logs for both TP=1 and TP=2 reported exactly 32 request
|
||||
starts and `computed:` token sums of 28,576 in both capped and uncapped runs.
|
||||
The largest single hit was 11,552 tokens. Examples include:
|
||||
|
||||
```text
|
||||
Request 16 started running, prompt: 12296, computed: 11552
|
||||
Request 26 started running, prompt: 5836, computed: 4336
|
||||
Request 30 started running, prompt: 11017, computed: 10768
|
||||
```
|
||||
|
||||
So this smoke validates the core ReplayServe invariant: identical Qwen block
|
||||
hash prefixes become identical synthetic token prefixes, and vLLM's prefix cache
|
||||
actually reuses them.
|
||||
|
||||
For full `coder_100`, ReplayServe estimated:
|
||||
|
||||
- query blocks: 29,705
|
||||
- hit blocks: 7,447
|
||||
- block hit ratio: 0.250698536
|
||||
- query tokens: 474,554
|
||||
- hit tokens: 119,152
|
||||
- token hit ratio: 0.251082069
|
||||
|
||||
The TP=2 full `coder_100` run had no preemptions. Its vLLM `computed:` sum was
|
||||
119,152, matching the trace-side estimate exactly. The TP=1 run had 8
|
||||
preemptions across repeated starts for requests 70, 71, 72, 77, and 94. In that
|
||||
case, raw `computed:` sums are not a simple prefix-hit ratio:
|
||||
|
||||
| run | starts | unique requests | preemptions | all-start computed | first-start computed | last-start computed | max/request computed | estimated hit tokens |
|
||||
|---|---:|---:|---:|---:|---:|---:|---:|---:|
|
||||
| `tp1_coder100_uncapped` | 108 | 100 | 8 | 180896 | 108560 | 141744 | 141984 | 119152 |
|
||||
| `tp2_coder100_uncapped` | 100 | 100 | 0 | 119152 | 119152 | 119152 | 119152 | 119152 |
|
||||
|
||||
Use `tools/analyze_vllm_prefix_log.py` to reproduce this parsing.
|
||||
|
||||
## Reliability Boundary
|
||||
|
||||
These numbers are useful for mechanism validation and for seeding simulator
|
||||
calibration. They are not final serving throughput claims because:
|
||||
|
||||
- Some bring-up runs capped decode length to 4 or 8 tokens.
|
||||
- The largest real-output baseline so far is `coder_100`, not `coder_2000` or
|
||||
the full coder trace.
|
||||
- Synthetic token IDs preserve block identity and length but not original text
|
||||
distribution.
|
||||
- Prefix reuse in `request_metrics.csv` is a trace-side estimate. For real
|
||||
scheduler hit/miss behavior, use vLLM `stdout.log` `computed:` fields and
|
||||
account for preemption/re-admission.
|
||||
- This run uses H20 and `Qwen3-30B-A3B`, while the earlier Frontier smoke used
|
||||
dummy A800/Qwen3-32B plumbing. They should be compared as calibration inputs,
|
||||
not as one-to-one simulator accuracy evidence yet.
|
||||
|
||||
## Next
|
||||
|
||||
- Move to `coder_2000` once runtime and queueing cost are acceptable.
|
||||
- Add the vLLM log parser output into the run aggregation summary.
|
||||
- Compare vLLM real-backend TTFT/TPOT/E2E against Frontier outputs only after
|
||||
selecting a matched model/hardware/profile policy.
|
||||
|
||||
See `docs/rs4_frontier_h20_tp1_alignment.md` for the first Frontier H20 TP1
|
||||
alignment run against real vLLM TP1.
|
||||
45
docs/sources.md
Normal file
45
docs/sources.md
Normal file
@@ -0,0 +1,45 @@
|
||||
# Sources
|
||||
|
||||
Checked on 2026-06-24.
|
||||
|
||||
## Local Repositories
|
||||
|
||||
| Source | Local path | Commit / HEAD | Notes |
|
||||
|---|---|---|---|
|
||||
| Qwen Bailian usage traces | `/home/gahow/phd/qwen-bailian-usagetraces-anon` | `5f7439c51ec248a0c585f7d90a41a6f57773b912` | Primary RS0 input is `qwen_coder_blksz_16.jsonl`. |
|
||||
| Frontier | `/tmp/toc-llm-sim-research/Frontier` | `d9cfeb6d8791fbf2f295dd9744c56a666171776e` | Primary RS1 simulator candidate. |
|
||||
| Vidur | `/tmp/toc-llm-sim-research/vidur` | `8383d2935bc62723a212090baa9f98ada206fc14` | Baseline simulator candidate for arrival and length replay. |
|
||||
| AIConfigurator | `/tmp/toc-llm-sim-research/aiconfigurator` | `e46ece7510e727fafefb8212e5846172145a30ea` | Configuration search reference, not per-request faithful replay. |
|
||||
|
||||
All four local repositories were present when RS0 was generated. No external
|
||||
repository was cloned for RS0.
|
||||
|
||||
## Frontier Findings
|
||||
|
||||
- Frontier trace replay reads CSV columns `arrived_at`, `num_prefill_tokens`,
|
||||
and `num_decode_tokens`.
|
||||
- It also parses optional `session_id` and `block_hash_ids`; `block_hash_ids`
|
||||
can be `|` separated, matching `examples/fixtures/prefix_cache_shared_session_trace.csv`.
|
||||
- Frontier's trace replay generator can clip prefill tokens when total tokens
|
||||
exceed `trace_request_generator_config_max_tokens`. ReplayServe fixtures hard
|
||||
fail before Frontier sees the trace, so the RS1 smoke cannot silently clip.
|
||||
- Frontier has a built-in `Qwen/Qwen3-32B` model config.
|
||||
- Frontier has A800 network profiles:
|
||||
`data/profiling/network/a800_dgx/` and
|
||||
`data/profiling/network/a800_pairwise_nvlink/`.
|
||||
- Current public A800 compute profiles in this checkout include Llama2-7B and
|
||||
Qwen3 MoE / Qwen3-Next reduced variants, but no dense `Qwen/Qwen3-32B`
|
||||
compute profile. RS1 Qwen3-32B A800 latency and throughput results are only
|
||||
plumbing smoke until matching compute profiles or calibration data are added.
|
||||
|
||||
## Qwen Trace Findings
|
||||
|
||||
- The released JSONL rows contain `chat_id`, `parent_chat_id`, `timestamp`,
|
||||
`input_length`, `output_length`, `type`, `turn`, and `hash_ids`.
|
||||
- The trace README documents `hash_ids` as salted SipHash blocks with 16 tokens
|
||||
per block.
|
||||
- The released input lengths and hashes are already after the model-specific
|
||||
chat template has been applied. ReplayServe does not apply chat templates.
|
||||
- The final input block can be padded. ReplayServe records per-block token
|
||||
counts in the sidecar so partial final blocks can be accounted for by true
|
||||
token count.
|
||||
Reference in New Issue
Block a user