feat(diagnostic): Beliebtheit im Modell-Katalog — Downloads und Likes von HuggingFace
HF hat keine Sternebewertung; es gibt Downloads (30 Tage, gesamt) und Likes. Beide sagen 'viel benutzt', nicht 'gut' (viele Downloads sind Automatik, Likes oft beim Entdecken). Angezeigt unter dem Modellnamen mit Hinweis im Tooltip; beim Hinzufuegen sofort, beim taeglichen Abgleich aufgefrischt. ℹ: Zeile Beliebtheit mit Einordnung. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
@@ -9836,6 +9836,10 @@
|
|||||||
+ (m.tools ? ' <span title="Kann Werkzeuge aufrufen (laut Chat-Vorlage) — z.B. Websuche, wenn ARIA es lokal nutzt" style="font-size:10px;color:#34C759;border:1px solid #34C759;border-radius:8px;padding:0 5px;">🔧</span>' : '')
|
+ (m.tools ? ' <span title="Kann Werkzeuge aufrufen (laut Chat-Vorlage) — z.B. Websuche, wenn ARIA es lokal nutzt" style="font-size:10px;color:#34C759;border:1px solid #34C759;border-radius:8px;padding:0 5px;">🔧</span>' : '')
|
||||||
+ (m.uncensored ? ' <span title="Unzensierte Fassung — lehnt kaum etwas ab" style="font-size:10px;color:#FFB020;border:1px solid #FFB020;border-radius:8px;padding:0 5px;">unzensiert</span>' : '')
|
+ (m.uncensored ? ' <span title="Unzensierte Fassung — lehnt kaum etwas ab" style="font-size:10px;color:#FFB020;border:1px solid #FFB020;border-radius:8px;padding:0 5px;">unzensiert</span>' : '')
|
||||||
+ (m.added_at && (Date.now() - new Date(m.added_at).getTime()) < 7 * 864e5 ? ' <span title="In den letzten 7 Tagen in den Katalog gekommen" style="font-size:10px;color:#4DB8FF;border:1px solid #4DB8FF;border-radius:8px;padding:0 5px;">neu</span>' : '')
|
+ (m.added_at && (Date.now() - new Date(m.added_at).getTime()) < 7 * 864e5 ? ' <span title="In den letzten 7 Tagen in den Katalog gekommen" style="font-size:10px;color:#4DB8FF;border:1px solid #4DB8FF;border-radius:8px;padding:0 5px;">neu</span>' : '')
|
||||||
|
+ (m.popularity ? '<div title="HuggingFace: Downloads der letzten 30 Tage (insgesamt) und Likes. Sagt „viel benutzt“, nicht „gut“ — viele Downloads sind Automatik." style="font-size:10px;color:#6a6a88;font-weight:normal;">↓ '
|
||||||
|
+ Number(m.popularity.downloads).toLocaleString('de') + '/Monat'
|
||||||
|
+ (m.popularity.downloadsAll ? ' (' + Number(m.popularity.downloadsAll).toLocaleString('de') + ' ges.)' : '')
|
||||||
|
+ ' · ♥ ' + Number(m.popularity.likes).toLocaleString('de') + '</div>' : '')
|
||||||
+ (m.hfRepo ? ' <button class="btn secondary" onclick="openModelInfo(' + i + ')" title="Was kann das Modell? Zensiert oder nicht?" style="padding:0 6px;font-size:11px;margin-left:4px;">ℹ</button>' : '')
|
+ (m.hfRepo ? ' <button class="btn secondary" onclick="openModelInfo(' + i + ')" title="Was kann das Modell? Zensiert oder nicht?" style="padding:0 6px;font-size:11px;margin-left:4px;">ℹ</button>' : '')
|
||||||
+ '</td>' +
|
+ '</td>' +
|
||||||
'<td ' + td + 'color:#9a9ab5;min-width:220px;">' + escapeHtml(m.description || m.hfRepo || '')
|
'<td ' + td + 'color:#9a9ab5;min-width:220px;">' + escapeHtml(m.description || m.hfRepo || '')
|
||||||
@@ -10288,7 +10292,7 @@
|
|||||||
${row('Grundmodell', j.base ? escapeHtml(j.base) : '')}
|
${row('Grundmodell', j.base ? escapeHtml(j.base) : '')}
|
||||||
${row('Von', escapeHtml(j.author))}
|
${row('Von', escapeHtml(j.author))}
|
||||||
${row('Lizenz', escapeHtml(j.license))}
|
${row('Lizenz', escapeHtml(j.license))}
|
||||||
${row('Beliebtheit', '↓ ' + Number(j.downloads).toLocaleString('de') + ' · ♥ ' + j.likes)}
|
${row('Beliebtheit', '↓ ' + Number(j.downloads).toLocaleString('de') + ' Downloads (30 Tage) · ♥ ' + j.likes + ' Likes <span style="color:#6a6a88;font-size:11px;">— sagt „viel benutzt“, nicht „gut“; HuggingFace hat keine Sterne</span>')}
|
||||||
${row('Stand', date(j.updated))}
|
${row('Stand', date(j.updated))}
|
||||||
${row('Schlagworte', (j.tags || []).map(t => '<span style="color:#9a9ab5;">' + escapeHtml(t) + '</span>').join(', '))}
|
${row('Schlagworte', (j.tags || []).map(t => '<span style="color:#9a9ab5;">' + escapeHtml(t) + '</span>').join(', '))}
|
||||||
</table>
|
</table>
|
||||||
|
|||||||
+17
-5
@@ -573,12 +573,16 @@ async function refreshLlmCatalogFromHF() {
|
|||||||
e.quant = q.quant; e.sizeGB = q.sizeGB; e.quants = q.quants; delete e.unusable;
|
e.quant = q.quant; e.sizeGB = q.sizeGB; e.quants = q.quants; delete e.unusable;
|
||||||
}));
|
}));
|
||||||
}
|
}
|
||||||
// Werkzeug-Faehigkeit + Sicherheits-Scan nachtragen (wo noch keine Angabe)
|
// Werkzeug-Faehigkeit + Sicherheits-Scan nachtragen (wo noch keine Angabe),
|
||||||
const noTools = [...byId.values()].filter(e => e.hfRepo && (e.tools === undefined || e.safety === undefined));
|
// Beliebtheit bei jedem Abgleich frisch (aendert sich taeglich)
|
||||||
for (let i = 0; i < noTools.length; i += 6) {
|
const today = new Date().toISOString().slice(0, 10);
|
||||||
await Promise.all(noTools.slice(i, i + 6).map(async e => {
|
const toEnrich = [...byId.values()].filter(e => e.hfRepo && (e.tools === undefined || e.safety === undefined
|
||||||
|
|| !e.popularity || e.popularity.at !== today));
|
||||||
|
for (let i = 0; i < toEnrich.length; i += 6) {
|
||||||
|
await Promise.all(toEnrich.slice(i, i + 6).map(async e => {
|
||||||
if (e.tools === undefined) e.tools = await hfToolSupport(e.hfRepo);
|
if (e.tools === undefined) e.tools = await hfToolSupport(e.hfRepo);
|
||||||
if (e.safety === undefined) e.safety = await hfRepoSafety(e.hfRepo);
|
if (e.safety === undefined) e.safety = await hfRepoSafety(e.hfRepo);
|
||||||
|
if (!e.popularity || e.popularity.at !== today) e.popularity = await hfPopularity(e.hfRepo) || e.popularity;
|
||||||
}));
|
}));
|
||||||
}
|
}
|
||||||
let added = 0;
|
let added = 0;
|
||||||
@@ -862,6 +866,14 @@ function knownGgufAuthor(a) { // Funktion: TRUSTED_GGUF_AUTHORS steht we
|
|||||||
return TRUSTED_GGUF_AUTHORS.has(a) || EXTRA_KNOWN_GGUF_AUTHORS.has(a);
|
return TRUSTED_GGUF_AUTHORS.has(a) || EXTRA_KNOWN_GGUF_AUTHORS.has(a);
|
||||||
}
|
}
|
||||||
const RISKY_FILE_RE = /\.(py|sh|bash|bat|cmd|ps1|exe|dll|so|dylib|pkl|pickle|pt|pth|ckpt|joblib|npy|zip|tar|gz|7z|jar|js|vbs)$|(^|\/)pytorch_model[^/]*\.bin$/i;
|
const RISKY_FILE_RE = /\.(py|sh|bash|bat|cmd|ps1|exe|dll|so|dylib|pkl|pickle|pt|pth|ckpt|joblib|npy|zip|tar|gz|7z|jar|js|vbs)$|(^|\/)pytorch_model[^/]*\.bin$/i;
|
||||||
|
// Beliebtheit: HF hat keine Sterne — nur Downloads (30 Tage / gesamt) und Likes.
|
||||||
|
async function hfPopularity(repo) {
|
||||||
|
const d = await hfJson(`https://huggingface.co/api/models/${repo}?expand[]=downloads&expand[]=likes&expand[]=downloadsAllTime`);
|
||||||
|
if (!d) return null;
|
||||||
|
return { downloads: d.downloads || 0, downloadsAll: d.downloadsAllTime || 0, likes: d.likes || 0,
|
||||||
|
at: new Date().toISOString().slice(0, 10) };
|
||||||
|
}
|
||||||
|
|
||||||
async function hfRepoSafety(repo) {
|
async function hfRepoSafety(repo) {
|
||||||
const author = String(repo).split("/")[0].toLowerCase();
|
const author = String(repo).split("/")[0].toLowerCase();
|
||||||
const out = { known: knownGgufAuthor(author), flagged: [], risky: [], scanned: 0 };
|
const out = { known: knownGgufAuthor(author), flagged: [], risky: [], scanned: 0 };
|
||||||
@@ -896,7 +908,7 @@ async function addHfRepoToCatalog(repo, description = "") {
|
|||||||
cat.push({ id, hfRepo: repo, quant: q.quant, ctx: 8192, sizeGB: q.sizeGB, quants: q.quants,
|
cat.push({ id, hfRepo: repo, quant: q.quant, ctx: 8192, sizeGB: q.sizeGB, quants: q.quants,
|
||||||
description: description || "Aus den HuggingFace-Trends übernommen", source: "hf",
|
description: description || "Aus den HuggingFace-Trends übernommen", source: "hf",
|
||||||
tools: await hfToolSupport(repo), uncensored: UNCENSORED_RE.test(repo),
|
tools: await hfToolSupport(repo), uncensored: UNCENSORED_RE.test(repo),
|
||||||
safety: await hfRepoSafety(repo),
|
safety: await hfRepoSafety(repo), popularity: await hfPopularity(repo),
|
||||||
added_at: new Date().toISOString().slice(0, 10) });
|
added_at: new Date().toISOString().slice(0, 10) });
|
||||||
saveLlmCatalog(cat);
|
saveLlmCatalog(cat);
|
||||||
return { models: cat, id, existed: false };
|
return { models: cat, id, existed: false };
|
||||||
|
|||||||
Reference in New Issue
Block a user