Fix live inference rate display

This commit is contained in:
Mikei386
2026-09-03 13:39:13 +02:00
parent 6d9f31dff0
commit f1fdca3efd
+22 -6
View File
@@ -651,6 +651,21 @@ const deNum=n=>n==null?'–':Number(n).toLocaleString('de-DE',{maximumFractionDi
const bytesRate=n=>n==null?'–':n>=1048576?`${(n/1048576).toFixed(1)} MiB/s`:`${(n/1024).toFixed(1)} KiB/s`; const bytesRate=n=>n==null?'–':n>=1048576?`${(n/1048576).toFixed(1)} MiB/s`:`${(n/1024).toFixed(1)} KiB/s`;
const metric=(value,label)=>`<div class="metric"><b>${value??'–'}</b><span>${label}</span></div>`; const metric=(value,label)=>`<div class="metric"><b>${value??'–'}</b><span>${label}</span></div>`;
const boolLabel=v=>v===true?'ja':v===false?'nein':'–'; const boolLabel=v=>v===true?'ja':v===false?'nein':'–';
const liveRateState={prompt:{tokens:null,seconds:null,value:null,seen:0},generation:{tokens:null,seconds:null,value:null,seen:0}};
function stableLiveRate(kind,tokensTotal,secondsTotal,gauge,active){
const now=Date.now(),state=liveRateState[kind],tokens=Number(tokensTotal),seconds=Number(secondsTotal),raw=Number(gauge);
let measured=Number.isFinite(raw)&&raw>0?raw:null;
if(Number.isFinite(tokens)&&Number.isFinite(seconds)&&state.tokens!=null&&tokens>=state.tokens&&seconds>state.seconds){
const derived=(tokens-state.tokens)/(seconds-state.seconds);
if(Number.isFinite(derived)&&derived>0) measured=measured??derived;
}
if(Number.isFinite(tokens)&&Number.isFinite(seconds)){
state.tokens=tokens;state.seconds=seconds;
}
if(measured!=null&&measured<100000){state.value=measured;state.seen=now;}
if(state.value!=null&&(active||now-state.seen<8000)) return {text:`${deNum(state.value)} tok/s`,fresh:now-state.seen<2500};
return {text:active?'misst …':'–',fresh:false};
}
function slotHtml(s){ function slotHtml(s){
let used=s.context_used||0,total=s.n_ctx||0,p=total?Math.min(100,used/total*100):0; let used=s.context_used||0,total=s.n_ctx||0,p=total?Math.min(100,used/total*100):0;
let state=s.processing?'arbeitet':'frei'; let state=s.processing?'arbeitet':'frei';
@@ -660,17 +675,18 @@ async function refreshFull(){
try{ try{
let response=await fetch('/api/status',{cache:'no-store'}); if(!response.ok) return; let response=await fetch('/api/status',{cache:'no-store'}); if(!response.ok) return;
let d=await response.json(),rt=d.router||{},lt=rt.llama_telemetry||{},met=lt.metrics||{},props=lt.props||{},lr=d.llama_runtime||{},cpu=d.cpu||{},net=cpu.network||{}; let d=await response.json(),rt=d.router||{},lt=rt.llama_telemetry||{},met=lt.metrics||{},props=lt.props||{},lr=d.llama_runtime||{},cpu=d.cpu||{},net=cpu.network||{};
let gen=met.predicted_tokens_seconds,prompt=met.prompt_tokens_seconds; let running=Number(met.requests_processing??(rt.qwen||{}).active_chats??0),waiting=Number(met.requests_deferred||0),active=running>0;
$('generationRate').textContent=gen==null?'–':`${deNum(gen)} tok/s`; let gen=stableLiveRate('generation',met.tokens_predicted_total,met.tokens_predicted_seconds_total,met.predicted_tokens_seconds,active);
let prompt=stableLiveRate('prompt',met.prompt_tokens_total,met.prompt_seconds_total,met.prompt_tokens_seconds,active);
$('generationRate').textContent=gen.text;
let genAvg=met.tokens_predicted_seconds_total?met.tokens_predicted_total/met.tokens_predicted_seconds_total:null; let genAvg=met.tokens_predicted_seconds_total?met.tokens_predicted_total/met.tokens_predicted_seconds_total:null;
$('generationSub').textContent=genAvg==null?'Aktuelle llama.cpp-Messung':`Gesamtdurchschnitt ${deNum(genAvg)} tok/s`; $('generationSub').textContent=active&&!gen.fresh?'Anfrage läuft · letzter Messwert':(genAvg==null?'Aktuelle llama.cpp-Messung':`Gesamtdurchschnitt ${deNum(genAvg)} tok/s`);
$('promptRate').textContent=prompt==null?'–':`${deNum(prompt)} tok/s`; $('promptRate').textContent=prompt.text;
let promptAvg=met.prompt_seconds_total?met.prompt_tokens_total/met.prompt_seconds_total:null; let promptAvg=met.prompt_seconds_total?met.prompt_tokens_total/met.prompt_seconds_total:null;
$('promptSub').textContent=promptAvg==null?'Aktuelle llama.cpp-Messung':`Gesamtdurchschnitt ${deNum(promptAvg)} tok/s`; $('promptSub').textContent=active&&!prompt.fresh?'Prompt wird verarbeitet · letzter Messwert':(promptAvg==null?'Aktuelle llama.cpp-Messung':`Gesamtdurchschnitt ${deNum(promptAvg)} tok/s`);
let cached=Number(met.prompt_tokens_cached_total||0),processed=Number(met.prompt_tokens_total||0),hit=(cached+processed)?cached/(cached+processed)*100:null; let cached=Number(met.prompt_tokens_cached_total||0),processed=Number(met.prompt_tokens_total||0),hit=(cached+processed)?cached/(cached+processed)*100:null;
$('cacheHit').textContent=hit==null?'–':`${hit.toFixed(1)} %`;$('cacheBar').style.width=`${hit||0}%`; $('cacheHit').textContent=hit==null?'–':`${hit.toFixed(1)} %`;$('cacheBar').style.width=`${hit||0}%`;
$('cacheSub').textContent=hit==null?'Keine Cache-Metrik':`${deNum(cached)} wiederverwendet · ${deNum(processed)} neu`; $('cacheSub').textContent=hit==null?'Keine Cache-Metrik':`${deNum(cached)} wiederverwendet · ${deNum(processed)} neu`;
let running=Number(met.requests_processing??(rt.qwen||{}).active_chats??0),waiting=Number(met.requests_deferred||0);
$('requestState').textContent=`${running} aktiv · ${waiting} wartet`; $('requestState').textContent=`${running} aktiv · ${waiting} wartet`;
$('requestSub').textContent=`${(lt.slots||[]).filter(s=>!s.processing).length} freie Slots`; $('requestSub').textContent=`${(lt.slots||[]).filter(s=>!s.processing).length} freie Slots`;
$('slotCards').innerHTML=(lt.slots||[]).map(slotHtml).join('')||'<div class="sub">Slot-Telemetrie momentan nicht verfügbar</div>'; $('slotCards').innerHTML=(lt.slots||[]).map(slotHtml).join('')||'<div class="sub">Slot-Telemetrie momentan nicht verfügbar</div>';