feat(llm): Kontext-Auswahl zeigt den Grafikspeicher und geht bis zum Modell-Maximum

Der Adapter liest den Kopf der GGUF-Datei (nur Metadaten): trainiertes
Maximum (context_length) und KV-Cache pro Token — bei Sliding-Window-Modellen
(Gemma) waechst nur der globale Teil mit dem Kontext. Daraus pro Stufe eine
Schaetzung Modell + mmproj + KV (f16) + 1,4 GB Aufschlag (gemessen: Gemma 4
12B @32k geschaetzt 8,8 GB, belegt 8,77 GB).

Diagnostic: Liste kommt von der Box (statt fest 4k..128k), bis zum Maximum
des Modells (auch krumme wie 40960), mit "ca. X GB" und "passt nicht",
wenn es die Karte sprengt. Alte Box ohne Angaben: feste Liste wie bisher.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
2026-10-25 14:28:32 +01:00
co-authored by Claude Opus 5.5
parent bbeea24759
commit d3f36d8292
2 changed files with 155 additions and 6 deletions
+15 -5
View File
@@ -9241,16 +9241,26 @@
const jobTxt = job ? (job.phase === 'download' && job.percent != null ? `lädt ${job.percent.toFixed(0)} %` : 'lädt …') : '';
// Kontextfenster dieser Karte. Mehr Kontext = mehr VRAM; passt es
// nicht, setzt die Box die Karte von selbst zurueck.
const CTX = [4096, 8192, 16384, 32768, 65536, 131072];
// Liste + Speicherbedarf kommen von der Box (aus der Modelldatei:
// trainiertes Maximum, KV-Cache pro Token). Alte Box: feste Liste.
const curCtx = sl.ctx || 0;
const ctxOpts = (curCtx && !CTX.includes(curCtx) ? [curCtx, ...CTX] : CTX)
.map(n => `<option value="${n}"${n === curCtx ? ' selected' : ''}>${n >= 1024 ? (n / 1024) + 'k' : n} Tokens</option>`).join('');
let ctxList = Array.isArray(sl.options) && sl.options.length
? sl.options.map(o => ({ ctx: o.ctx, est: o.estMB }))
: [4096, 8192, 16384, 32768, 65536, 131072].map(n => ({ ctx: n, est: 0 }));
if (curCtx && !ctxList.some(o => o.ctx === curCtx)) ctxList = [{ ctx: curCtx, est: 0 }, ...ctxList];
const vramMB = sl.vramMB || 0;
const ctxOpts = ctxList.map(o => {
const label = o.ctx >= 1024 ? (o.ctx % 1024 ? (o.ctx / 1024).toFixed(1) : o.ctx / 1024) + 'k' : o.ctx;
const gb = o.est ? ` · ca. ${(o.est / 1024).toFixed(1).replace('.', ',')} GB` : '';
const tooBig = o.est && vramMB && o.est > vramMB * 0.97 ? ' ⚠ passt nicht' : '';
return `<option value="${o.ctx}"${o.ctx === curCtx ? ' selected' : ''}>${label} Tokens${gb}${tooBig}</option>`;
}).join('');
const ctxSel = sl.model
? `<select data-box="${escapeHtml(b.instanceId)}" data-gpu="${escapeHtml(sl.gpu)}" data-model="${escapeHtml(sl.model)}" data-current="${curCtx}"
onchange="onLlmCardCtx(this)" ${job ? 'disabled' : ''} title="Kontextfenster (Eingabe + Ausgabe). Mehr braucht mehr Grafikspeicher."
onchange="onLlmCardCtx(this)" ${job ? 'disabled' : ''} title="Kontextfenster (Eingabe + Ausgabe). GB = geschätzter Grafikspeicher für Modell + Kontext auf dieser Karte.${sl.ctxMax ? ' Das Modell kann höchstens ' + sl.ctxMax + ' Tokens.' : ''}"
style="background:#1E1E2E;border:1px solid #333;border-radius:4px;padding:5px 6px;color:#E0E0F0;font-size:12px;">${ctxOpts}</select>`
: '<span></span>';
rows.push(`<div style="display:grid;grid-template-columns:minmax(220px,1fr) minmax(260px,2fr) 130px 160px;gap:10px;align-items:center;">
rows.push(`<div style="display:grid;grid-template-columns:minmax(220px,1fr) minmax(260px,2fr) 230px 160px;gap:10px;align-items:center;">
<div><b style="color:#E0E0F0;">${escapeHtml(b.node)}</b> · Karte ${escapeHtml(sl.gpu)}
<div style="color:#555570;font-size:11px;">${escapeHtml(sl.gpuName || '')}${vramGB ? ' · ' + vramGB.toFixed(0) + ' GB' : ''}${sl.vramUsedMB >= 0 ? ' · belegt ' + (sl.vramUsedMB / 1024).toFixed(1) + ' GB' : ''}${sl.ctx ? ' · Kontext ' + sl.ctx : ''}</div>
${sl.onCpu ? '<div style="color:#FF9F0A;font-size:11px;" title="llama.cpp findet die Karte nicht und rechnet langsam auf der CPU. Ursache meist: Treiber zu alt fuer das CUDA im llama-swap-Image. Abhilfe: auf der Box sudo ./bootstrap.sh --upgrade-driver">⚠ Modell läuft auf der CPU, Karte leer — Treiber zu alt? (bootstrap.sh --upgrade-driver)</div>' : ''}</div>