benchscope 1.0.0__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- benchscope/__init__.py +3 -0
- benchscope/__main__.py +4 -0
- benchscope/benches/__init__.py +1 -0
- benchscope/benches/base.py +54 -0
- benchscope/benches/runner.py +185 -0
- benchscope/benches/sglang_bench.py +77 -0
- benchscope/benches/vllm_bench.py +94 -0
- benchscope/cli.py +46 -0
- benchscope/config.py +91 -0
- benchscope/constants.py +49 -0
- benchscope/datasets.py +200 -0
- benchscope/gpu.py +39 -0
- benchscope/parser.py +93 -0
- benchscope/server/__init__.py +3 -0
- benchscope/server/api_config.py +97 -0
- benchscope/server/api_logs.py +356 -0
- benchscope/server/api_test.py +64 -0
- benchscope/server/app.py +99 -0
- benchscope/server/state.py +18 -0
- benchscope/server/status.py +97 -0
- benchscope/server/test_manager.py +367 -0
- benchscope/server/ws.py +56 -0
- benchscope/summary.py +148 -0
- benchscope/webui/assets/LogView-BDFIduo7.css +1 -0
- benchscope/webui/assets/LogView-BMsVPLVq.js +1 -0
- benchscope/webui/assets/MetricsCharts-D1wU0LbK.css +1 -0
- benchscope/webui/assets/MetricsCharts-DHO93JrC.js +1 -0
- benchscope/webui/assets/SettingsView-7uuTFqXU.css +1 -0
- benchscope/webui/assets/SettingsView-DJmFSQbU.js +1 -0
- benchscope/webui/assets/TestView-81VlxBZU.js +4 -0
- benchscope/webui/assets/TestView-BAwcOtR2.css +1 -0
- benchscope/webui/assets/antd-DWALckI0.js +478 -0
- benchscope/webui/assets/echarts-Bb6yjXMn.js +60 -0
- benchscope/webui/assets/index-Dfr0hp72.js +2 -0
- benchscope/webui/assets/index-EhoNt9Gv.css +1 -0
- benchscope/webui/assets/vue-Ch4zjUb1.js +37 -0
- benchscope/webui/index.html +19 -0
- benchscope-1.0.0.dist-info/METADATA +136 -0
- benchscope-1.0.0.dist-info/RECORD +43 -0
- benchscope-1.0.0.dist-info/WHEEL +5 -0
- benchscope-1.0.0.dist-info/entry_points.txt +2 -0
- benchscope-1.0.0.dist-info/licenses/LICENSE +176 -0
- benchscope-1.0.0.dist-info/top_level.txt +1 -0
|
@@ -0,0 +1,4 @@
|
|
|
1
|
+
import{_ as le,u as ce,a as te,b as ye}from"./index-Dfr0hp72.js";import{U as s,a6 as D,X as c,F as J,a7 as ee,Y as re,V as y,Z as ge,G as f,_ as w,a0 as ze,o as pe,S as r,k as e,W as t,u as o,a8 as Y,c as k,f as F,r as ie,w as de,j as ke,n as Pe}from"./vue-Ch4zjUb1.js";import{E as Se,M as Oe,f as Ve,g as Be,C as Me,a as Ie,h as qe,i as De,S as Ee,j as L,k as Re,D as Fe,U as je,b as Le,l as Ne,m as Ae,n as Ge,e as Ke,o as Ye,p as He,q as he,r as Xe,s as We,B as Ze}from"./antd-DWALckI0.js";import{_ as Je,M as Qe}from"./MetricsCharts-DHO93JrC.js";import"./echarts-Bb6yjXMn.js";const et={class:"subtabs"},tt={class:"group"},at=["onClick"],lt={__name:"SubTabBar",props:{modelValue:{type:String,default:"random"}},emits:["update:modelValue"],setup(p,{emit:h}){const i=[{key:"random",label:"Random",icon:Se},{key:"sharegpt",label:"ShareGPT",icon:Oe},{key:"custom",label:"Custom",icon:Ve}];return(z,a)=>(s(),D("div",et,[c("div",tt,[(s(),D(J,null,ee(i,$=>c("button",{key:$.key,class:re(["subtab",{active:p.modelValue===$.key}]),onClick:S=>z.$emit("update:modelValue",$.key)},[(s(),y(ge($.icon),{class:"subtab-icon"})),f(" "+w($.label),1)],10,at)),64))])]))}},nt=le(lt,[["__scopeId","data-v-5bdf780d"]]),me=ze("testForm",{state:()=>({model:"",tokenizer:"",precision:"",tpot_threshold_ms:100,concurrency_list:[1,4,8,16,32,40,64,128],request_rate:"inf",gpu:{auto:!0,name:"",count:8},force:!1,extra_args:[],curated:{},_initialized:!1}),actions:{initFromConfig(p,h){this._initialized||(p!=null&&p.tpot_threshold_ms&&(this.tpot_threshold_ms=p.tpot_threshold_ms),p!=null&&p.request_rate&&(this.request_rate=p.request_rate),h!=null&&h.config&&(this.gpu.name=h.config.name||"",this.gpu.count=h.config.count||8,this.gpu.auto=h.config.auto??!0),this._initialized=!0)},initCurated(p){if(!Object.keys(this.curated).length)for(const h of p||[])h.default!==void 0&&h.default!==null&&(this.curated[h.key]=h.default)}}}),ot={class:"field-label"},st={class:"env-footer"},ut={__name:"EnvPanel",setup(p){const h=ce(),i=me(),z=k(()=>h.apiBase),a=k(()=>{var M,_;return((_=(M=h.config)==null?void 0:M.api)==null?void 0:_.endpoint)||"/v1/chat/completions"}),$=k(()=>h.status||{}),S=k(()=>$.value.inference==="ready"),x=k(()=>$.value.models||[]),V=k(()=>x.value.length),m=F(!1),v=F(""),T=F(!1),P=F(0);pe(()=>{x.value.length||h.refreshStatus()});async function A(){await h.refreshStatus(),L.success("状态已刷新")}async function U(){var M,_,C,g,R;m.value=!0,v.value="";try{const I=await te.testConnection({base_url:z.value,endpoint:a.value,api_key:((_=(M=h.config)==null?void 0:M.api)==null?void 0:_.api_key)||"",extra_headers:((g=(C=h.config)==null?void 0:C.api)==null?void 0:g.extra_headers)||{}});T.value=I.ok,P.value=((R=I.models)==null?void 0:R.length)||0,v.value=I.ok?"":I.error||"未知错误",I.ok&&await h.refreshStatus()}finally{m.value=!1}}return(M,_)=>{const C=r("a-typography-link"),g=r("a-descriptions-item"),R=r("a-badge"),I=r("a-tag"),W=r("a-descriptions"),K=r("a-col"),H=r("a-select"),N=r("a-input"),u=r("a-row"),b=r("a-alert"),G=r("a-button"),Q=r("a-space");return s(),D("div",null,[e(u,{gutter:16},{default:t(()=>[e(K,{xs:24,md:10},{default:t(()=>[e(W,{size:"small",column:2},{default:t(()=>[e(g,{label:"Base URL",span:2},{default:t(()=>[e(C,{copyable:""},{default:t(()=>[f(w(z.value),1)]),_:1})]),_:1}),e(g,{label:"Endpoint"},{default:t(()=>[f(w(a.value),1)]),_:1}),e(g,{label:"模型数量"},{default:t(()=>[e(R,{count:V.value,"number-style":{backgroundColor:S.value?"#1677ff":"#bbb"}},null,8,["count","number-style"])]),_:1}),e(g,{label:"最近检测"},{default:t(()=>[f(w($.value.last_check||"-"),1)]),_:1}),e(g,{label:"执行方式"},{default:t(()=>[e(I,{color:"geekblue",style:{"margin-left":"0"}},{default:t(()=>[..._[4]||(_[4]=[f("本机子进程执行 bench",-1)])]),_:1})]),_:1})]),_:1})]),_:1}),e(K,{xs:24,md:14},{default:t(()=>[e(u,{gutter:16},{default:t(()=>[e(K,{span:16},{default:t(()=>[c("div",ot,[e(o(Be),{style:{color:"#1677ff"}}),_[5]||(_[5]=f(" 测试模型 Model",-1))]),x.value.length?(s(),y(H,{key:0,value:o(i).model,"onUpdate:value":_[0]||(_[0]=E=>o(i).model=E),options:x.value.map(E=>({value:E,label:E})),"show-search":"",placeholder:"选择模型(来自 /v1/models)",style:{width:"100%"},"allow-clear":!0},null,8,["value","options"])):(s(),y(N,{key:1,value:o(i).model,"onUpdate:value":_[1]||(_[1]=E=>o(i).model=E),placeholder:"推理环境离线,可手动输入模型名(需勾选强制开始)"},null,8,["value"]))]),_:1}),e(K,{span:8},{default:t(()=>[_[6]||(_[6]=c("div",{class:"field-label"},"Tokenizer(可空)",-1)),e(N,{value:o(i).tokenizer,"onUpdate:value":_[2]||(_[2]=E=>o(i).tokenizer=E),placeholder:"默认同模型",size:"middle"},null,8,["value"])]),_:1})]),_:1}),x.value.length?Y("",!0):(s(),y(b,{key:0,type:"warning","show-icon":"",message:`模型列表不可用:${$.value.error||"推理环境离线"}`,style:{"margin-top":"8px","font-size":"12px"}},null,8,["message"]))]),_:1})]),_:1}),c("div",st,[v.value?(s(),D("span",{key:0,class:re(["conn-msg",T.value?"ok":"bad"])},[T.value?(s(),D(J,{key:0},[e(o(Me)),f(" 连接成功("+w(P.value)+" 个模型) ",1)],64)):(s(),D(J,{key:1},[e(o(Ie)),f(" 连接失败:"+w(v.value),1)],64))],2)):Y("",!0),e(Q,null,{default:t(()=>[e(G,{size:"middle",onClick:A},{icon:t(()=>[e(o(qe))]),default:t(()=>[_[7]||(_[7]=f(" 刷新状态 ",-1))]),_:1}),e(G,{size:"middle",type:"primary",loading:m.value,onClick:U},{icon:t(()=>[e(o(De))]),default:t(()=>[_[8]||(_[8]=f(" 测试连接 ",-1))]),_:1},8,["loading"]),e(G,{size:"middle",type:"link",onClick:_[3]||(_[3]=E=>M.$router.push("/settings"))},{icon:t(()=>[e(o(Ee))]),default:t(()=>[_[9]||(_[9]=f(" 服务设置 ",-1))]),_:1})]),_:1})])])}}},rt=le(ut,[["__scopeId","data-v-eb27c687"]]),it={style:{display:"flex","flex-wrap":"wrap",gap:"8px","align-items":"center","margin-bottom":"8px"}},dt={__name:"ConcurrencyEditor",props:{modelValue:{type:Array,default:()=>[]}},emits:["update:modelValue"],setup(p,{emit:h}){const i=p,z=h,a=F("");function $(){const V=String(a.value).trim();if(V==="")return;const m=V.split(/[,,\s]+/).filter(Boolean).map(Number).filter(T=>Number.isInteger(T)&&T>0);if(!m.length)return;const v=[...i.modelValue];for(const T of m)v.includes(T)||v.push(T);v.sort((T,P)=>T-P),z("update:modelValue",v),a.value=""}function S(V){const m=i.modelValue.filter((v,T)=>T!==V);z("update:modelValue",m)}function x(){z("update:modelValue",[1,4,8,16,32,40,64,128])}return(V,m)=>{const v=r("a-tag"),T=r("a-input"),P=r("a-button");return s(),D("div",null,[c("div",it,[(s(!0),D(J,null,ee(p.modelValue,(A,U)=>(s(),y(v,{key:U,closable:"",color:"blue",style:{"font-size":"14px",padding:"2px 10px"},onClose:M=>S(U)},{default:t(()=>[f(w(A),1)]),_:2},1032,["onClose"]))),128)),e(T,{value:a.value,"onUpdate:value":m[0]||(m[0]=A=>a.value=A),placeholder:"添加并发数,回车确认",style:{width:"160px"},onPressEnter:$,onBlur:$},null,8,["value"]),e(P,{size:"small",type:"dashed",onClick:$},{default:t(()=>[...m[1]||(m[1]=[f("添加",-1)])]),_:1}),e(P,{size:"small",onClick:x},{default:t(()=>[...m[2]||(m[2]=[f("恢复默认 1,4,8,16,32,40,64,128",-1)])]),_:1})]),m[3]||(m[3]=c("div",{style:{color:"#999","font-size":"12px"}}," 测试时每个并发数分别执行一次 bench;--max-concurrency 与 --num-prompts 保持一致。 ",-1))])}}},ct={__name:"FreeArgsEditor",props:{modelValue:{type:Array,default:()=>[]}},emits:["update:modelValue"],setup(p,{emit:h}){const i=p,z=h;function a(){z("update:modelValue",[...i.modelValue,{flag:"",value:""}])}function $(S){z("update:modelValue",i.modelValue.filter((x,V)=>V!==S))}return(S,x)=>{const V=r("a-input"),m=r("a-button");return s(),D("div",null,[(s(!0),D(J,null,ee(p.modelValue,(v,T)=>(s(),D("div",{key:T,style:{display:"flex",gap:"8px","margin-bottom":"6px"}},[e(V,{value:v.flag,"onUpdate:value":P=>v.flag=P,placeholder:"参数名,如 --top-p",style:{width:"220px"}},null,8,["value","onUpdate:value"]),e(V,{value:v.value,"onUpdate:value":P=>v.value=P,placeholder:"参数值(布尔开关可留空)",style:{width:"220px"}},null,8,["value","onUpdate:value"]),e(m,{size:"small",danger:"",onClick:P=>$(T)},{default:t(()=>[...x[0]||(x[0]=[f("删除",-1)])]),_:1},8,["onClick"])]))),128)),e(m,{size:"small",type:"dashed",onClick:a},{default:t(()=>[...x[1]||(x[1]=[f("+ 添加其他参数",-1)])]),_:1}),x[2]||(x[2]=c("div",{style:{color:"#999","font-size":"12px","margin-top":"4px"}}," 自由添加 vLLM / SGLang bench 的其他参数,直接拼接到命令末尾。 ",-1))])}}},pt={style:{display:"flex","flex-wrap":"wrap",gap:"8px"}},mt={style:{display:"flex",gap:"8px","margin-top":"8px","align-items":"center"}},ft={style:{color:"#999","font-size":"12px","margin-top":"4px"}},vt={style:{display:"flex","align-items":"center",gap:"12px","flex-wrap":"wrap"}},_t={key:0,class:"path-text"},yt={style:{display:"flex",gap:"8px"}},gt={style:{display:"flex",gap:"8px"}},kt={key:1,style:{color:"#999","font-size":"12px","margin-top":"4px"}},ht={style:{color:"#999","font-size":"12px"}},bt={style:{color:"#999","font-size":"12px"}},wt={style:{display:"flex",gap:"12px","align-items":"center","justify-content":"flex-end"}},xt={style:{"max-height":"480px",overflow:"auto",background:"#f6f8fa",padding:"12px","font-size":"12px","white-space":"pre-wrap"}},$t={__name:"TestConfigPanel",props:{framework:{type:String,default:"vllm"},datasetType:{type:String,default:"random"}},setup(p,{expose:h}){const i=p,z=ce(),a=me(),$=k(()=>i.framework==="vllm"?"vLLM":"SGLang"),S=k(()=>{var d;return((d=z.status)==null?void 0:d.models)||[]}),x=k(()=>{var d;return(d=z.gpu)!=null&&d.auto_detected?z.gpu.auto_detected:null}),V=[{label:"3K1K",input:3072,output:1024},{label:"1K1K",input:1024,output:1024},{label:"256X256",input:256,output:256}],m=ie({type:i.datasetType,length_pairs:[...V],path:""}),v=ie({input:1024,output:512}),T=F(""),P=F([]),A=F([]),U=ie({state:"idle",path:null,error:null}),M=F(!1),_=F(""),C=F(100),g=k(()=>m.length_pairs.filter(d=>d.checked!==!1)),R=k(()=>P.value.filter(d=>!d.advanced)),I=k(()=>P.value.filter(d=>d.advanced));function W(d){return m.length_pairs.some(n=>n.label===d.label)}function K(d){const n=m.length_pairs.findIndex(O=>O.label===d.label);n>=0?m.length_pairs.splice(n,1):m.length_pairs.push({...d,checked:!0})}function H(){if(!v.input||!v.output){L.warning("请输入输入/输出长度");return}const d=`${v.input}X${v.output}`;if(m.length_pairs.some(n=>n.label===d)){L.warning("该长度组合已存在");return}m.length_pairs.push({label:d,input:v.input,output:v.output,checked:!0})}function N(d){d==="custom"?a.request_rate=String(C.value):a.request_rate="inf"}async function u(){try{await te.sharegptDownload(),U.state="downloading",b()}catch(d){L.error(d.message)}}async function b(){try{const d=await te.sharegptStatus();U.state=d.state,U.path=d.path,U.error=d.error,d.state==="downloading"&&setTimeout(b,2e3)}catch{}}const G=k(()=>U.state==="done"?"已就绪":U.state==="downloading"?"下载中…":U.state==="error"?`下载失败:${U.error}`:"未下载");function Q(d){const n=L.loading(`上传 ${d.name} 中…`,0);return te.uploadDataset(d).then(async O=>{L.success("上传成功"),await E(),m.path=O.path}).catch(O=>L.error(O.message)).finally(()=>n()),!1}async function E(){try{const d=await te.listDatasets();A.value=d.datasets||[]}catch{A.value=[]}}async function ne(){var q,X;if(!a.model)return L.warning("请选择测试模型(推理服务面板或此处)"),null;const d={type:i.datasetType};if(i.datasetType==="random"){if(!g.value.length)return L.warning("请至少选择一个输入/输出长度组合"),null;d.length_pairs=g.value.map(j=>[j.input,j.output,j.label])}else if(i.datasetType==="custom"){const j=m.path||T.value;if(!j)return L.warning("请选择或填写自定义数据集路径"),null;d.path=j}if(!a.concurrency_list.length)return L.warning("请至少添加一个并发数"),null;if(!a.force&&!S.value.length)return L.warning("推理服务离线,请确认服务可用或勾选“强制开始”"),null;const n={auto:a.gpu.auto,name:a.gpu.name||((q=x.value)==null?void 0:q.name)||"",count:a.gpu.count||((X=x.value)==null?void 0:X.count)||8},O={};for(const[j,Z]of Object.entries(a.curated))Z!=null&&Z!==""&&(O[j]=Z);return{framework:i.framework,model:a.model,tokenizer:a.tokenizer,dataset:d,concurrency_list:a.concurrency_list,gpu:n,request_rate:a.request_rate==="inf"?"inf":Number(a.request_rate),tpot_threshold_ms:a.tpot_threshold_ms,precision:a.precision,curated:O,extra_args:a.extra_args.filter(j=>j.flag),force:a.force}}async function oe(){const d=await ne();if(d)try{const O=(await te.previewTest(d)).commands||[];_.value=O.map(q=>`[${q.case} | 并发=${q.concurrency}]
|
|
2
|
+
${q.cmd}`).join(`
|
|
3
|
+
|
|
4
|
+
`),M.value=!0}catch(n){L.error(n.message)}}async function ae(){await z.loadParams(i.framework),P.value=z.params[i.framework],a.initCurated(P.value)}return pe(async()=>{a.initFromConfig(z.config,z.gpu),await ae(),E(),b()}),de(()=>i.framework,async()=>{for(const d of Object.keys(a.curated))delete a.curated[d];await ae()}),h({buildPayload:ne,preview:oe}),(d,n)=>{const O=r("a-input"),q=r("a-form-item"),X=r("a-col"),j=r("a-input-number"),Z=r("a-row"),be=r("a-checkable-tag"),se=r("a-button"),we=r("a-badge"),ue=r("a-select"),xe=r("a-upload"),fe=r("a-select-option"),$e=r("a-tag"),ve=r("a-switch"),_e=r("a-collapse-panel"),Ce=r("a-collapse"),Te=r("a-modal"),Ue=r("a-form");return s(),y(Ue,{layout:"vertical"},{default:t(()=>[e(Z,{gutter:16},{default:t(()=>[e(X,{span:6},{default:t(()=>[e(q,{label:"模型精度 Precision"},{default:t(()=>[e(O,{value:o(a).precision,"onUpdate:value":n[0]||(n[0]=l=>o(a).precision=l),placeholder:"如 W8A8(可空)"},null,8,["value"])]),_:1})]),_:1}),e(X,{span:6},{default:t(()=>[e(q,{label:"TPOT 阈值 (ms)"},{default:t(()=>[e(j,{value:o(a).tpot_threshold_ms,"onUpdate:value":n[1]||(n[1]=l=>o(a).tpot_threshold_ms=l),min:1,style:{width:"100%"}},null,8,["value"]),n[14]||(n[14]=c("div",{style:{color:"#999","font-size":"12px"}},"接近该阈值的行高亮",-1))]),_:1})]),_:1}),e(X,{span:12},{default:t(()=>[e(q,{label:"测试模型 Model"},{default:t(()=>[e(O,{value:o(a).model,disabled:"",placeholder:"在「① 推理服务」面板选择模型","addon-after":"去选择",onClick:n[2]||(n[2]=l=>d.$emit("pick-model"))},null,8,["value"]),n[15]||(n[15]=c("div",{style:{color:"#999","font-size":"12px"}}," 模型与 Tokenizer 在「① 推理服务」面板选择;服务地址等配置在「服务设置」中维护 ",-1))]),_:1})]),_:1})]),_:1}),p.datasetType==="random"?(s(),y(q,{key:0,label:"输入/输出长度组合(random 数据集)"},{default:t(()=>[c("div",pt,[(s(),D(J,null,ee(V,l=>e(be,{key:l.label,checked:W(l),onChange:B=>K(l)},{default:t(()=>[f(w(l.label)+"("+w(l.input)+"/"+w(l.output)+") ",1)]),_:2},1032,["checked","onChange"])),64))]),c("div",mt,[n[17]||(n[17]=c("span",null,"自定义:",-1)),e(j,{value:v.input,"onUpdate:value":n[3]||(n[3]=l=>v.input=l),min:1,placeholder:"输入长度",style:{width:"140px"}},null,8,["value"]),n[18]||(n[18]=c("span",null,"/",-1)),e(j,{value:v.output,"onUpdate:value":n[4]||(n[4]=l=>v.output=l),min:1,placeholder:"输出长度",style:{width:"140px"}},null,8,["value"]),e(se,{size:"small",type:"dashed",onClick:H},{icon:t(()=>[e(o(Re))]),default:t(()=>[n[16]||(n[16]=f(" 添加 ",-1))]),_:1})]),c("div",ft," 已选:"+w(g.value.map(l=>l.label).join("、")||"(未选择,无法开始)"),1)]),_:1})):p.datasetType==="sharegpt"?(s(),y(q,{key:1,label:"ShareGPT 数据集"},{default:t(()=>[c("div",vt,[e(we,{status:U.state==="done"?"success":U.state==="downloading"?"processing":U.state==="error"?"error":"default",text:G.value},null,8,["status","text"]),e(se,{size:"small",loading:U.state==="downloading",onClick:u},{icon:t(()=>[e(o(Fe))]),default:t(()=>[n[19]||(n[19]=f(" 下载 / 检查(modelscope) ",-1))]),_:1},8,["loading"]),U.path?(s(),D("span",_t,w(U.path),1)):Y("",!0)]),n[20]||(n[20]=c("div",{style:{color:"#999","font-size":"12px","margin-top":"4px"}}," 来源:https://www.modelscope.cn/datasets/gliang1001/ShareGPT_V3_unfiltered_cleaned_split ,未指定路径时测试开始前自动下载。 ",-1))]),_:1})):(s(),y(q,{key:2,label:"自定义数据集(与 sharegpt 功能一致)"},{default:t(()=>[e(ue,{value:m.path,"onUpdate:value":n[5]||(n[5]=l=>m.path=l),placeholder:"选择已上传的数据集,或填写服务器本地路径",style:{"margin-bottom":"8px",width:"100%"},options:A.value.map(l=>({value:l.path,label:`${l.name}(${l.path})`})),"allow-clear":""},null,8,["value","options"]),c("div",yt,[e(O,{value:T.value,"onUpdate:value":n[6]||(n[6]=l=>T.value=l),placeholder:"服务器本地 jsonl 路径,如 /data/sharegpt.jsonl"},null,8,["value"]),e(xe,{"before-upload":Q,"show-upload-list":!1},{default:t(()=>[e(se,{size:"small"},{icon:t(()=>[e(o(je))]),default:t(()=>[n[21]||(n[21]=f(" 上传文件 ",-1))]),_:1})]),_:1})])]),_:1})),e(Z,{gutter:16},{default:t(()=>[e(X,{span:12},{default:t(()=>[e(q,{label:"测试请求并发数(--max-concurrency = --num-prompts)"},{default:t(()=>[e(dt,{value:o(a).concurrency_list,"onUpdate:value":n[7]||(n[7]=l=>o(a).concurrency_list=l)},null,8,["value"])]),_:1})]),_:1}),e(X,{span:6},{default:t(()=>[e(q,{label:"请求速率 Request rate"},{default:t(()=>[e(ue,{value:o(a).request_rate,"onUpdate:value":n[8]||(n[8]=l=>o(a).request_rate=l),onChange:N},{default:t(()=>[e(fe,{value:"inf"},{default:t(()=>[...n[22]||(n[22]=[f("inf(不限速,推荐)",-1)])]),_:1}),e(fe,{value:"custom"},{default:t(()=>[...n[23]||(n[23]=[f("自定义(req/s)",-1)])]),_:1})]),_:1},8,["value"]),o(a).request_rate==="custom"?(s(),y(j,{key:0,value:C.value,"onUpdate:value":n[9]||(n[9]=l=>C.value=l),min:.01,style:{width:"100%","margin-top":"6px"}},null,8,["value"])):Y("",!0)]),_:1})]),_:1}),e(X,{span:6},{default:t(()=>[e(q,{label:"GPU(部署信息)"},{default:t(()=>[c("div",gt,[e(O,{value:o(a).gpu.name,"onUpdate:value":n[10]||(n[10]=l=>o(a).gpu.name=l),placeholder:"型号(自动获取优先)"},null,8,["value"]),e(j,{value:o(a).gpu.count,"onUpdate:value":n[11]||(n[11]=l=>o(a).gpu.count=l),min:1,style:{width:"90px"}},null,8,["value"])]),x.value?(s(),y($e,{key:0,color:"green",style:{"margin-top":"4px"}},{icon:t(()=>[e(o(Le))]),default:t(()=>[f(" 自动检测:"+w(x.value.name)+" × "+w(x.value.count),1)]),_:1})):(s(),D("div",kt,"未检测到 nvidia-smi,请手动填写"))]),_:1})]),_:1})]),_:1}),e(q,{label:`框架参数(${$.value} bench)`},{default:t(()=>[e(Ce,{ghost:"",bordered:!1},{default:t(()=>[e(_e,{key:"common",header:"常用参数"},{default:t(()=>[e(Z,{gutter:16},{default:t(()=>[(s(!0),D(J,null,ee(R.value,l=>(s(),y(X,{key:l.key,span:6},{default:t(()=>[e(q,{label:l.label},{default:t(()=>[l.type==="bool"?(s(),y(ve,{key:0,checked:o(a).curated[l.key],"onUpdate:checked":B=>o(a).curated[l.key]=B,"checked-children":"开","un-checked-children":"关"},null,8,["checked","onUpdate:checked"])):l.type==="select"?(s(),y(ue,{key:1,value:o(a).curated[l.key],"onUpdate:value":B=>o(a).curated[l.key]=B,options:l.options.map(B=>({value:B,label:B})),style:{width:"100%"}},null,8,["value","onUpdate:value","options"])):l.type==="int"||l.type==="float"?(s(),y(j,{key:2,value:o(a).curated[l.key],"onUpdate:value":B=>o(a).curated[l.key]=B,step:l.type==="float"?.1:1,style:{width:"100%"}},null,8,["value","onUpdate:value","step"])):(s(),y(O,{key:3,value:o(a).curated[l.key],"onUpdate:value":B=>o(a).curated[l.key]=B},null,8,["value","onUpdate:value"])),c("div",ht,w(l.help),1)]),_:2},1032,["label"])]),_:2},1024))),128))]),_:1})]),_:1}),e(_e,{key:"advanced",header:"高级参数"},{default:t(()=>[e(Z,{gutter:16},{default:t(()=>[(s(!0),D(J,null,ee(I.value,l=>(s(),y(X,{key:l.key,span:6},{default:t(()=>[e(q,{label:l.label},{default:t(()=>[l.type==="bool"?(s(),y(ve,{key:0,checked:o(a).curated[l.key],"onUpdate:checked":B=>o(a).curated[l.key]=B,"checked-children":"开","un-checked-children":"关"},null,8,["checked","onUpdate:checked"])):l.type==="select"?(s(),y(ue,{key:1,value:o(a).curated[l.key],"onUpdate:value":B=>o(a).curated[l.key]=B,options:l.options.map(B=>({value:B,label:B})),style:{width:"100%"}},null,8,["value","onUpdate:value","options"])):l.type==="int"||l.type==="float"?(s(),y(j,{key:2,value:o(a).curated[l.key],"onUpdate:value":B=>o(a).curated[l.key]=B,step:l.type==="float"?.1:1,style:{width:"100%"}},null,8,["value","onUpdate:value","step"])):(s(),y(O,{key:3,value:o(a).curated[l.key],"onUpdate:value":B=>o(a).curated[l.key]=B},null,8,["value","onUpdate:value"])),c("div",bt,w(l.help),1)]),_:2},1032,["label"])]),_:2},1024))),128))]),_:1})]),_:1})]),_:1})]),_:1},8,["label"]),e(q,{label:"其他参数(自由添加)"},{default:t(()=>[e(ct,{value:o(a).extra_args,"onUpdate:value":n[12]||(n[12]=l=>o(a).extra_args=l)},null,8,["value"])]),_:1}),e(q,null,{default:t(()=>[c("div",wt,[n[25]||(n[25]=c("span",{style:{color:"#999","font-size":"12px","margin-right":"auto"}},"开始 / 取消测试请在「测试进度」面板操作",-1)),e(se,{type:"primary",ghost:"",onClick:oe},{icon:t(()=>[e(o(Ne))]),default:t(()=>[n[24]||(n[24]=f(" 命令预览 ",-1))]),_:1})])]),_:1}),e(Te,{open:M.value,"onUpdate:open":n[13]||(n[13]=l=>M.value=l),title:"命令预览(首个用例)",width:"860px",footer:null},{default:t(()=>[c("pre",xt,w(_.value),1)]),_:1},8,["open"])]),_:1})}}},Ct=le($t,[["__scopeId","data-v-01937508"]]),Tt={class:"progress-row"},Ut={class:"progress-info"},zt={class:"progress-stats"},Pt={key:0},St={class:"progress-actions"},Ot={__name:"TestProgressPanel",props:{starting:{type:Boolean,default:!1}},emits:["start","stop"],setup(p,{emit:h}){const i=ye(),z=me(),a=F(null),$=F(["log"]),S=k(()=>i.running),x=k(()=>{var u;return((u=i.run)==null?void 0:u.status)||"idle"}),V=k(()=>{var u;return i.lastRunId||((u=i.run)==null?void 0:u.run_id)||""}),m=k(()=>{var u;return((u=i.run)==null?void 0:u.model)||""}),v=k(()=>{var u;return((u=i.run)==null?void 0:u.framework_name)||""}),T=k(()=>{var b;const u=(b=i.run)==null?void 0:b.gpu;return u?u.name?`${u.name}×${u.count}`:`×${u.count}`:""}),P=k(()=>{var u;return((u=i.run)==null?void 0:u.cases)||[]}),A=k(()=>{var u;return((u=i.run)==null?void 0:u.concurrency_list)||[]}),U=k(()=>P.value.length*A.value.length),M=k(()=>i.rows.filter(u=>u.metrics||u.error).length),_=k(()=>U.value?Math.round(M.value/U.value*100):0),C=k(()=>i.currentCase||""),g=k(()=>i.currentConc??null),R=k(()=>{const u=P.value.find(b=>b.label===C.value);return u?u.input_len?`${u.label}(${u.input_len}/${u.output_len})`:u.label:C.value||"-"}),I=k(()=>i.logLines.slice(-120)),W=k(()=>{var b;const u=(b=i.run)==null?void 0:b.summary;return u!=null&&u.xlsx?`共 ${u.rows} 条结果,汇总文件:${u.xlsx}`:M.value?`共 ${M.value} 条结果(无 xlsx 汇总,可能全部失败)`:"未产生结果"}),K=F(Date.now());let H=null;de(S,u=>{H&&clearInterval(H),u&&(K.value=Date.now(),H=setInterval(()=>K.value=Date.now(),1e3))},{immediate:!0}),ke(()=>{H&&clearInterval(H)});const N=k(()=>{var E;const u=(E=i.run)==null?void 0:E.started_at;if(!u)return"-";const b=Ke(u,"YYYY-MM-DD HH:mm:ss"),G=Math.max(0,K.value-b.valueOf()),Q=Math.floor(G/1e3);return`${Math.floor(Q/60)}分${Q%60}秒`});return de(()=>i.logLines.length,async()=>{await Pe(),a.value&&(a.value.scrollTop=a.value.scrollHeight)}),(u,b)=>{const G=r("a-alert"),Q=r("a-progress"),E=r("a-tag"),ne=r("a-space"),oe=r("a-checkbox"),ae=r("a-button"),d=r("a-collapse-panel"),n=r("a-collapse");return s(),D("div",null,[S.value?(s(),y(G,{key:0,type:"info","show-icon":"",message:`测试进行中:${R.value}(并发 ${g.value??"-"})`,description:`已出结果 ${M.value}/${U.value},运行 ${N.value},请勿关闭页面`,style:{"margin-bottom":"12px"}},null,8,["message","description"])):x.value==="done"?(s(),y(G,{key:1,type:"success","show-icon":"",message:"测试完成",description:W.value,style:{"margin-bottom":"12px"}},null,8,["description"])):x.value==="stopped"?(s(),y(G,{key:2,type:"warning","show-icon":"",message:"测试已取消",description:`已出结果 ${M.value}/${U.value}`,style:{"margin-bottom":"12px"}},null,8,["description"])):x.value==="error"?(s(),y(G,{key:3,type:"error","show-icon":"",message:"测试执行出错",description:o(i).error,style:{"margin-bottom":"12px"}},null,8,["description"])):(s(),y(G,{key:4,type:"info","show-icon":"",message:"等待开始测试",description:"配置好测试参数后,点击「开始测试」执行性能压测",style:{"margin-bottom":"12px"}})),c("div",Tt,[U.value>0?(s(),y(Q,{key:0,type:"circle",size:64,percent:_.value,status:_.value>=100?"success":S.value?"active":"normal"},null,8,["percent","status"])):Y("",!0),c("div",Ut,[e(ne,{wrap:""},{default:t(()=>[V.value?(s(),y(E,{key:0,color:"blue"},{default:t(()=>[f("Run "+w(V.value),1)]),_:1})):Y("",!0),m.value?(s(),y(E,{key:1},{default:t(()=>[f(w(m.value),1)]),_:1})):Y("",!0),v.value?(s(),y(E,{key:2,color:"purple"},{default:t(()=>[f(w(v.value),1)]),_:1})):Y("",!0),T.value?(s(),y(E,{key:3},{default:t(()=>[f("GPU: "+w(T.value),1)]),_:1})):Y("",!0)]),_:1}),c("div",zt,[c("span",null,[b[4]||(b[4]=f("进度:",-1)),c("b",null,w(M.value),1),f(" / "+w(U.value),1)]),S.value?(s(),D("span",Pt,"当前:"+w(R.value)+" @ 并发 "+w(g.value??"-"),1)):Y("",!0)])]),c("div",St,[e(oe,{checked:o(z).force,"onUpdate:checked":b[0]||(b[0]=O=>o(z).force=O),style:{"margin-right":"4px"}},{default:t(()=>[...b[5]||(b[5]=[f("离线强制开始",-1)])]),_:1},8,["checked"]),e(ae,{type:"primary",size:"large",loading:p.starting,disabled:S.value,onClick:b[1]||(b[1]=O=>u.$emit("start"))},{icon:t(()=>[e(o(Ae))]),default:t(()=>[b[6]||(b[6]=f(" 开始测试 ",-1))]),_:1},8,["loading","disabled"]),e(ae,{size:"large",danger:"",disabled:!S.value,onClick:b[2]||(b[2]=O=>u.$emit("stop"))},{icon:t(()=>[e(o(Ge))]),default:t(()=>[b[7]||(b[7]=f(" 取消测试 ",-1))]),_:1},8,["disabled"])])]),I.value.length?(s(),y(n,{key:5,ghost:"",style:{"margin-top":"12px"},activeKey:$.value,"onUpdate:activeKey":b[3]||(b[3]=O=>$.value=O)},{default:t(()=>[e(d,{key:"log",header:`实时输出(${I.value.length} 行,仅尾部)`},{default:t(()=>[c("pre",{class:"log-console",ref_key:"logBox",ref:a},w(I.value.join("")),513)]),_:1},8,["header"])]),_:1},8,["activeKey"])):Y("",!0)])}}},Vt=le(Ot,[["__scopeId","data-v-866c7da1"]]),Bt={key:0,style:{color:"#999","font-size":"12px"}},Mt={__name:"RealtimeResultPanel",props:{rows:{type:Array,default:()=>[]},threshold:{type:Number,default:null},running:{type:Boolean,default:!1}},setup(p){const h=p,i=[{key:"output_mean",label:"Output 吞吐 (tok/s)"},{key:"total_mean",label:"Total 吞吐 (tok/s)"},{key:"ttft_mean",label:"TTFT mean 耗时 (ms)"},{key:"tpot_mean",label:"TPOT mean 耗时 (ms)"},{key:"ttft_p99",label:"TTFT P99 耗时 (ms)"},{key:"tpot_p99",label:"TPOT P99 耗时 (ms)"}],z=k(()=>new Set(h.rows.map($=>$.label||$.case)).size);return(a,$)=>{const S=r("a-tag"),x=r("a-space"),V=r("a-divider");return s(),D("div",null,[e(x,{style:{"margin-bottom":"8px"},wrap:""},{default:t(()=>[e(S,{color:"blue"},{icon:t(()=>[e(o(Ye))]),default:t(()=>[f("用例 "+w(z.value)+" 个",1)]),_:1}),e(S,{color:"green"},{icon:t(()=>[e(o(He))]),default:t(()=>[f("已出结果 "+w(p.rows.length)+" 条",1)]),_:1}),e(S,{color:p.running?"processing":"default"},{icon:t(()=>[e(o(he),{spin:p.running},null,8,["spin"])]),default:t(()=>[f(" "+w(p.running?"测试进行中…":"空闲"),1)]),_:1},8,["color"]),p.threshold?(s(),D("span",Bt," TPOT 阈值 "+w(p.threshold)+"ms:绿色=低于阈值,金色=最佳并发 ",1)):Y("",!0)]),_:1}),e(Je,{rows:p.rows,threshold:p.threshold,pagination:{pageSize:20,showSizeChanger:!0}},null,8,["rows","threshold"]),e(V,{style:{margin:"12px 0"}},{default:t(()=>[...$[0]||($[0]=[f("实时曲线(横轴:并发数)",-1)])]),_:1}),e(Qe,{rows:p.rows,"metric-defs":i},null,8,["rows"])])}}},It=["onClick"],qt={class:"blocks-wrap"},Dt={id:"env",class:"block"},Et={id:"config",class:"block"},Rt={id:"progress",class:"block"},Ft={id:"result",class:"block"},jt={__name:"TestView",props:{framework:{type:String,default:"vllm"}},setup(p){const h=p,i=ye(),z=ce(),a=F("random"),$=F(null),S=F(!1),x=F(null),V=k(()=>{var C;return((C=z.config)==null?void 0:C.tpot_threshold_ms)??null}),m=k(()=>{var C;return((C=z.status)==null?void 0:C.inference)==="ready"}),v=[{id:"env",label:"测试环境",icon:Xe},{id:"config",label:"测试配置",icon:We},{id:"progress",label:"测试进度",icon:he},{id:"result",label:"测试结果",icon:Ze}],T=F("env");let P=null;function A(){var g;const C=((g=x.value)==null?void 0:g.$el)||x.value;if(!(!C||typeof C.getBoundingClientRect!="function")){P=new IntersectionObserver(R=>{for(const I of R)I.isIntersecting&&(T.value=I.target.id)},{root:C,rootMargin:"0px 0px -70% 0px",threshold:0});for(const R of v){const I=document.getElementById(R.id);I&&P.observe(I)}}}function U(C){var g;(g=document.getElementById(C))==null||g.scrollIntoView({behavior:"smooth",block:"start"}),T.value=C}pe(()=>{setTimeout(A,100)}),ke(()=>{P&&P.disconnect()});async function M(){var g;const C=await((g=$.value)==null?void 0:g.buildPayload());if(C){S.value=!0;try{const R=await i.start({...C,framework:h.framework});L.success(`测试已启动:${R.run_id}`)}catch(R){L.error(`启动失败:${R.message}`)}finally{S.value=!1}}}async function _(){try{await i.stop(),L.info("已发送取消请求")}catch(C){L.error(C.message)}}return(C,g)=>{const R=r("a-layout-sider"),I=r("a-tag"),W=r("a-card"),K=r("a-layout-content"),H=r("a-layout");return s(),y(H,{class:"page-layout"},{default:t(()=>[e(R,{width:"200",theme:"light",class:"workflow-sider"},{default:t(()=>[g[3]||(g[3]=c("div",{class:"sider-title"},"测试流程",-1)),(s(),D(J,null,ee(v,N=>c("a",{key:N.id,class:re(["side-item",{active:T.value===N.id}]),onClick:u=>U(N.id)},[(s(),y(ge(N.icon))),g[2]||(g[2]=f()),c("span",null,w(N.label),1)],10,It)),64))]),_:1}),e(K,{ref_key:"contentEl",ref:x,class:"page-content"},{default:t(()=>[e(nt,{modelValue:a.value,"onUpdate:modelValue":g[0]||(g[0]=N=>a.value=N),class:"subnav"},null,8,["modelValue"]),c("div",qt,[c("section",Dt,[e(W,{size:"small",class:"panel",title:"测试环境"},{extra:t(()=>[e(I,{color:m.value?"green":"red"},{default:t(()=>[c("span",{class:re(["dot",m.value?"ok":"bad"])},null,2),f(" "+w(m.value?"在线":"离线"),1)]),_:1},8,["color"])]),default:t(()=>[e(rt)]),_:1})]),c("section",Et,[e(W,{size:"small",class:"panel",title:"测试配置"},{default:t(()=>[e(Ct,{ref_key:"configPanel",ref:$,framework:p.framework,"dataset-type":a.value,onPickModel:g[1]||(g[1]=N=>U("env"))},null,8,["framework","dataset-type"])]),_:1})]),c("section",Rt,[e(W,{size:"small",class:"panel",title:"测试进度"},{default:t(()=>[e(Vt,{starting:S.value,onStart:M,onStop:_},null,8,["starting"])]),_:1})]),c("section",Ft,[e(W,{size:"small",class:"panel",title:"测试结果"},{default:t(()=>[e(Mt,{rows:o(i).rows,threshold:V.value,running:o(i).running},null,8,["rows","threshold","running"])]),_:1})])])]),_:1},512)]),_:1})}}},Yt=le(jt,[["__scopeId","data-v-a6a85fbb"]]);export{Yt as default};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
.subtabs[data-v-5bdf780d]{display:flex;align-items:center;background:#fff;border-bottom:1px solid #f0f0f0;padding:0 8px;height:44px}.group[data-v-5bdf780d]{display:flex;gap:4px}.subtab[data-v-5bdf780d]{display:inline-flex;align-items:center;gap:6px;background:transparent;border:none;border-bottom:2px solid transparent;padding:0 16px;height:44px;font-size:14px;color:#000000a6;cursor:pointer;transition:color .2s}.subtab-icon[data-v-5bdf780d]{font-size:14px}.subtab[data-v-5bdf780d]:hover{color:#1677ff}.subtab.active[data-v-5bdf780d]{color:#1677ff;border-bottom-color:#1677ff;font-weight:600}.field-label[data-v-eb27c687]{font-size:13px;font-weight:600;color:#000000a6;margin-bottom:6px}.env-footer[data-v-eb27c687]{margin-top:12px;display:flex;align-items:center;justify-content:flex-end;gap:12px;border-top:1px solid #f5f5f5;padding-top:12px}.conn-msg[data-v-eb27c687]{font-size:12px;display:inline-flex;align-items:center;gap:4px;margin-right:auto}.conn-msg.ok[data-v-eb27c687]{color:#52c41a}.conn-msg.bad[data-v-eb27c687]{color:#ff4d4f}.path-text[data-v-01937508]{color:#999;font-size:12px;max-width:420px;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.progress-row[data-v-866c7da1]{display:flex;align-items:center;gap:20px;flex-wrap:wrap}.progress-info[data-v-866c7da1]{flex:1;min-width:240px}.progress-stats[data-v-866c7da1]{margin-top:6px;color:#000000a6;font-size:13px;display:flex;gap:16px}.progress-actions[data-v-866c7da1]{display:flex;gap:10px;align-items:center}.log-console[data-v-866c7da1]{background:#1e1e1e;color:#d4d4d4;padding:10px 12px;border-radius:6px;font-size:12px;line-height:1.5;max-height:220px;overflow:auto;white-space:pre-wrap;word-break:break-all;margin:0}.page-layout[data-v-a6a85fbb]{height:100%}.workflow-sider[data-v-a6a85fbb]{border-right:1px solid #f0f0f0;height:100%;overflow:auto;padding:12px 0}.sider-title[data-v-a6a85fbb]{font-size:12px;color:#00000073;padding:0 16px 8px}.side-item[data-v-a6a85fbb]{display:flex;align-items:center;gap:8px;padding:11px 16px;cursor:pointer;color:#000000a6;font-size:14px;border-left:3px solid transparent;transition:all .2s}.side-item[data-v-a6a85fbb]:hover{color:#1677ff;background:#fafafa}.side-item.active[data-v-a6a85fbb]{color:#1677ff;background:#e6f4ff;border-left-color:#1677ff;font-weight:600}.page-content[data-v-a6a85fbb]{height:100%;background:#f5f5f5;overflow:auto;display:flex;flex-direction:column}.subnav[data-v-a6a85fbb]{position:sticky;top:0;z-index:20;flex-shrink:0}.blocks-wrap[data-v-a6a85fbb]{padding:16px 20px;max-width:1500px;width:100%}.block[data-v-a6a85fbb]{scroll-margin-top:56px;margin-bottom:16px}.panel[data-v-a6a85fbb]{border-radius:8px;box-shadow:0 1px 2px #0000000a}.dot[data-v-a6a85fbb]{display:inline-block;width:8px;height:8px;border-radius:50%;margin-right:6px}.dot.ok[data-v-a6a85fbb]{background:#52c41a}.dot.bad[data-v-a6a85fbb]{background:#ff4d4f}
|