mirror of
https://github.com/lone-cloud/gerbil
synced 2026-06-03 19:54:44 -07:00
improve gguf analysis to work with http models and present the data better
This commit is contained in:
parent
2480106943
commit
07eab89e58
4 changed files with 47 additions and 74 deletions
|
|
@ -1,7 +1,7 @@
|
||||||
{
|
{
|
||||||
"name": "gerbil",
|
"name": "gerbil",
|
||||||
"productName": "Gerbil",
|
"productName": "Gerbil",
|
||||||
"version": "1.7.4",
|
"version": "1.7.5",
|
||||||
"description": "Run Large Language Models locally",
|
"description": "Run Large Language Models locally",
|
||||||
"main": "out/main/index.js",
|
"main": "out/main/index.js",
|
||||||
"homepage": "./",
|
"homepage": "./",
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,5 @@
|
||||||
import { Modal } from '@/components/Modal';
|
import { Modal } from '@/components/Modal';
|
||||||
import { Stack, Group, Text, Divider, Alert, rem } from '@mantine/core';
|
import { Stack, Group, Text, Alert, rem } from '@mantine/core';
|
||||||
import { Info } from 'lucide-react';
|
import { Info } from 'lucide-react';
|
||||||
import type { ModelAnalysis } from '@/types';
|
import type { ModelAnalysis } from '@/types';
|
||||||
|
|
||||||
|
|
@ -21,7 +21,7 @@ const InfoRow = ({ label, value }: InfoRowProps) => {
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Group gap="md" wrap="nowrap">
|
<Group gap="md" wrap="nowrap">
|
||||||
<Text size="sm" c="dimmed" style={{ minWidth: rem(160) }}>
|
<Text size="sm" c="dimmed" style={{ minWidth: rem(150) }}>
|
||||||
{label}:
|
{label}:
|
||||||
</Text>
|
</Text>
|
||||||
<Text size="sm" fw={500}>
|
<Text size="sm" fw={500}>
|
||||||
|
|
@ -47,7 +47,6 @@ export const ModelAnalysisModal = ({
|
||||||
<Text>Model Analysis</Text>
|
<Text>Model Analysis</Text>
|
||||||
</Group>
|
</Group>
|
||||||
}
|
}
|
||||||
size="lg"
|
|
||||||
showCloseButton
|
showCloseButton
|
||||||
>
|
>
|
||||||
{loading && (
|
{loading && (
|
||||||
|
|
@ -63,72 +62,38 @@ export const ModelAnalysisModal = ({
|
||||||
)}
|
)}
|
||||||
|
|
||||||
{analysis && (
|
{analysis && (
|
||||||
<Stack gap="md">
|
<Stack gap="xs">
|
||||||
<div>
|
{analysis.general.name && (
|
||||||
<Text size="sm" fw={600} mb="xs">
|
<InfoRow label="Model Name" value={analysis.general.name} />
|
||||||
General Information
|
|
||||||
</Text>
|
|
||||||
<Stack gap="xs">
|
|
||||||
<InfoRow
|
|
||||||
label="Architecture"
|
|
||||||
value={analysis.general.architecture}
|
|
||||||
/>
|
|
||||||
{analysis.general.name && (
|
|
||||||
<InfoRow label="Model Name" value={analysis.general.name} />
|
|
||||||
)}
|
|
||||||
{analysis.general.parameterCount && (
|
|
||||||
<InfoRow
|
|
||||||
label="Parameters"
|
|
||||||
value={analysis.general.parameterCount}
|
|
||||||
/>
|
|
||||||
)}
|
|
||||||
<InfoRow label="File Size" value={analysis.general.fileSize} />
|
|
||||||
{analysis.architecture.layers && (
|
|
||||||
<InfoRow label="Layers" value={analysis.architecture.layers} />
|
|
||||||
)}
|
|
||||||
{analysis.architecture.expertCount && (
|
|
||||||
<InfoRow
|
|
||||||
label="Expert Count (MoE)"
|
|
||||||
value={analysis.architecture.expertCount}
|
|
||||||
/>
|
|
||||||
)}
|
|
||||||
</Stack>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
{analysis.context.maxContextLength && (
|
|
||||||
<>
|
|
||||||
<Divider />
|
|
||||||
<div>
|
|
||||||
<Text size="sm" fw={600} mb="xs">
|
|
||||||
Context
|
|
||||||
</Text>
|
|
||||||
<Stack gap="xs">
|
|
||||||
<InfoRow
|
|
||||||
label="Max Context Length"
|
|
||||||
value={analysis.context.maxContextLength}
|
|
||||||
/>
|
|
||||||
</Stack>
|
|
||||||
</div>
|
|
||||||
</>
|
|
||||||
)}
|
)}
|
||||||
|
<InfoRow label="Architecture" value={analysis.general.architecture} />
|
||||||
|
{analysis.general.parameterCount && (
|
||||||
|
<InfoRow label="Parameters" value={analysis.general.parameterCount} />
|
||||||
|
)}
|
||||||
|
<InfoRow label="File Size" value={analysis.general.fileSize} />
|
||||||
|
|
||||||
<Divider />
|
{analysis.architecture.expertCount && (
|
||||||
|
<InfoRow
|
||||||
<div>
|
label="Expert Count (MoE)"
|
||||||
<Text size="sm" fw={600} mb="xs">
|
value={analysis.architecture.expertCount}
|
||||||
Memory Estimates
|
/>
|
||||||
</Text>
|
)}
|
||||||
<Stack gap="xs">
|
{analysis.context.maxContextLength && (
|
||||||
<InfoRow label="Full VRAM" value={analysis.estimates.fullGpuVram} />
|
<InfoRow
|
||||||
<InfoRow label="Full RAM" value={analysis.estimates.systemRam} />
|
label="Max Context Length"
|
||||||
{analysis.estimates.vramPerLayer && (
|
value={analysis.context.maxContextLength}
|
||||||
<InfoRow
|
/>
|
||||||
label="VRAM per Layer"
|
)}
|
||||||
value={analysis.estimates.vramPerLayer}
|
{analysis.architecture.layers && (
|
||||||
/>
|
<InfoRow
|
||||||
)}
|
label="Layers / VRAM"
|
||||||
</Stack>
|
value={`${analysis.architecture.layers} (${analysis.estimates.vramPerLayer || 'N/A'} per layer) = ${analysis.estimates.fullGpuVram}`}
|
||||||
</div>
|
/>
|
||||||
|
)}
|
||||||
|
{!analysis.architecture.layers && (
|
||||||
|
<InfoRow label="Full VRAM" value={analysis.estimates.fullGpuVram} />
|
||||||
|
)}
|
||||||
|
<InfoRow label="Full RAM" value={analysis.estimates.systemRam} />
|
||||||
</Stack>
|
</Stack>
|
||||||
)}
|
)}
|
||||||
</Modal>
|
</Modal>
|
||||||
|
|
|
||||||
|
|
@ -46,8 +46,6 @@ export const ModelFileField = ({
|
||||||
return undefined;
|
return undefined;
|
||||||
};
|
};
|
||||||
|
|
||||||
const isLocalFile = value.trim() && validationState === 'local';
|
|
||||||
|
|
||||||
const handleAnalyzeModel = async () => {
|
const handleAnalyzeModel = async () => {
|
||||||
if (!value.trim()) return;
|
if (!value.trim()) return;
|
||||||
|
|
||||||
|
|
@ -99,7 +97,7 @@ export const ModelFileField = ({
|
||||||
</ActionIcon>
|
</ActionIcon>
|
||||||
</Tooltip>
|
</Tooltip>
|
||||||
)}
|
)}
|
||||||
{showAnalyze && isLocalFile && (
|
{showAnalyze && value.trim() && validationState !== 'invalid' && (
|
||||||
<Tooltip label="Analyze model">
|
<Tooltip label="Analyze model">
|
||||||
<ActionIcon
|
<ActionIcon
|
||||||
onClick={handleAnalyzeModel}
|
onClick={handleAnalyzeModel}
|
||||||
|
|
|
||||||
|
|
@ -43,11 +43,21 @@ function getMetadataValue(metadata: Record<string, unknown>, key: string) {
|
||||||
|
|
||||||
export async function analyzeGGUFModel(filePath: string) {
|
export async function analyzeGGUFModel(filePath: string) {
|
||||||
try {
|
try {
|
||||||
const stats = await stat(filePath);
|
const isUrl =
|
||||||
const fileSize = stats.size;
|
filePath.startsWith('http://') || filePath.startsWith('https://');
|
||||||
|
|
||||||
|
let fileSize: number;
|
||||||
|
if (isUrl) {
|
||||||
|
const response = await fetch(filePath, { method: 'HEAD' });
|
||||||
|
const contentLength = response.headers.get('content-length');
|
||||||
|
fileSize = contentLength ? parseInt(contentLength, 10) : 0;
|
||||||
|
} else {
|
||||||
|
const stats = await stat(filePath);
|
||||||
|
fileSize = stats.size;
|
||||||
|
}
|
||||||
|
|
||||||
const { metadata } = await gguf(filePath, {
|
const { metadata } = await gguf(filePath, {
|
||||||
allowLocalFile: true,
|
allowLocalFile: !isUrl,
|
||||||
});
|
});
|
||||||
|
|
||||||
const metadataRecord = metadata as Record<string, unknown>;
|
const metadataRecord = metadata as Record<string, unknown>;
|
||||||
|
|
|
||||||
Loading…
Add table
Reference in a new issue