Skip to content
Open
Show file tree
Hide file tree
Changes from 7 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 4 additions & 4 deletions app/gpu-explorer/GpuBubbleChart.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -50,18 +50,18 @@ export function GpuBubbleChart({ data, width, height, xLabel, yLabel }: Props) {
const sizeValues = data.map(d => d.size);

const xMin = 0;
const xMax = Math.max(...xValues) * 1.1;
const xMax = Math.max(...xValues) * 1.1 || 1;
const yMin = 0;
const yMax = Math.max(...yValues) * 1.1;
const yMax = Math.max(...yValues) * 1.1 || 1;
const sizeMin = Math.min(...sizeValues);
const sizeMax = Math.max(...sizeValues);
const sizeRange = sizeMax - sizeMin || 1;
Comment thread
mazam-lab marked this conversation as resolved.
Outdated

// Scale functions
const scaleX = (val: number) => (val / xMax) * chartWidth;
const scaleY = (val: number) => chartHeight - (val / yMax) * chartHeight;
const scaleSize = (val: number) => {
// Map size values to radius 5-30px
const normalized = (val - sizeMin) / (sizeMax - sizeMin);
const normalized = (val - sizeMin) / sizeRange;
return 5 + normalized * 25;
};

Expand Down
27 changes: 15 additions & 12 deletions app/kv-cache/KvCacheCalc.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ import { useCountUp } from '@/app/performance/quickEstimateHelpers'
import { useAicCatalog } from '@/lib/hooks/useAicCatalog'
import { useSettings, type InferenceBackend } from '@/contexts/SettingsContext'
import { getAppConfig } from '@/lib/app-config'
import { ModelInput, type ModelStatus } from '@/components/ui/ModelInput'
import { ComboBox, type ComboBoxItem } from '@/components/ModelComboBox/ModelComboBox'
Comment thread
mazam-lab marked this conversation as resolved.
import { GpuSystemInput } from '@/components/ui/GpuSystemInput'
import type { KvCacheCalcResult } from '@/lib/api/kv-cache-calc'
import styles from './KvCacheCalc.module.css'
Expand All @@ -23,10 +23,16 @@ const BREAKDOWN_COLORS: Record<string, string> = {
}

export default function KvCacheCalc() {
const { hydrated, defaultModel: settingsDefaultModel, inferenceBackend, backendVersion: settingsBackendVersion } = useSettings()
const { hydrated, hfToken, defaultModel: settingsDefaultModel, inferenceBackend, backendVersion: settingsBackendVersion } = useSettings()
const { modelOptions: aicModels, gpuOptions: aicGpus, isLoading: catalogLoading } = useAicCatalog()
const MODEL_OPTIONS = aicModels

const modelItems: ComboBoxItem[] = React.useMemo(() =>
aicModels.map(m => {
const slash = m.indexOf('/');
return { value: m, label: m, group: slash > 0 ? m.slice(0, slash) : '' };
}), [aicModels]);

const [model, setModel] = React.useState('')
const [system, setSystem] = React.useState(() => getAppConfig().defaultSystem)
const [backend, setBackend] = React.useState(() => getAppConfig().defaultBackend)
Expand Down Expand Up @@ -111,11 +117,6 @@ export default function KvCacheCalc() {
};

const catalogMatch = MODEL_OPTIONS.includes(model)
const kvModelStatus: ModelStatus = getAppConfig().supportedModels.includes(model)
? 'supported'
: catalogMatch ? 'catalog'
: catalogLoading ? 'fetching'
: model ? 'idle' : 'idle'

async function handleCalculate() {
setLoading(true)
Expand Down Expand Up @@ -194,13 +195,15 @@ export default function KvCacheCalc() {
<div className={styles.inputCard}>
<div className={styles.inputRow}>
<div className={styles.field}>
<ModelInput
<ComboBox
id="kv-model"
model={model}
value={model}
onChange={setModel}
modelOptions={aicModels}
isLoading={catalogLoading}
status={kvModelStatus}
items={modelItems}
placeholder="Type model name or select from dropdown..."
allowCustom
supportedModels={getAppConfig().supportedModels}
hfToken={hfToken}
/>
</div>

Expand Down
63 changes: 29 additions & 34 deletions app/performance/PerformanceEstimate.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ import { fetchModelConfig, type HFModelConfig } from '@/lib/huggingface/fetch-co
import { saveEstimate, getSavedEstimateCount } from '@/lib/saved-estimates';
import { fetchEstimateAsInferenceResult, EstimateError } from '@/lib/api/estimate-adapter';
import { InfoStrip, InfoStripAction } from '@/components/ui/InfoStrip';
import { ModelInput, type ModelStatus } from '@/components/ui/ModelInput';
import { ComboBox, type ComboBoxItem } from '@/components/ModelComboBox/ModelComboBox';
import { GpuSystemInput } from '@/components/ui/GpuSystemInput';
import { useAicCatalog } from '@/lib/hooks/useAicCatalog';
import { GpuChipLoader } from '@/components/GpuChipLoader/GpuChipLoader';
Expand Down Expand Up @@ -78,6 +78,12 @@ export default function QuickEstimate() {
const { hydrated, hfToken, defaultModel: settingsDefaultModel, inferenceBackend, backendVersion } = useSettings();
const { gpuOptions: aicGpus, modelOptions: aicModels, modelSpecs, isLoading: catalogLoading } = useAicCatalog();

const modelItems: ComboBoxItem[] = React.useMemo(() =>
aicModels.map(m => {
const slash = m.indexOf('/');
return { value: m, label: m, group: slash > 0 ? m.slice(0, slash) : '' };
}), [aicModels]);

const [model, setModel] = React.useState('');
const [gpu, setGpu] = React.useState(() => getAppConfig().defaultSystem);

Expand Down Expand Up @@ -113,18 +119,6 @@ export default function QuickEstimate() {
const [isUsingFallback, setIsUsingFallback] = React.useState(false);
const [fallbackReason, setFallbackReason] = React.useState<string>('');

const modelStatus: ModelStatus = getAppConfig().supportedModels.includes(model)
? 'supported'
: aicModels.includes(model)
? 'catalog'
: isFetchingConfig || catalogLoading
? 'fetching'
: hfConfig
? 'fetched'
: testError
? 'error'
: 'idle';

// Collapsible state for "Why this GPU count?" card
const [whyGpuExpanded, setWhyGpuExpanded] = React.useState(false);

Expand Down Expand Up @@ -735,22 +729,22 @@ export default function QuickEstimate() {
},
],
},
{
id: 'hardware', title: 'Hardware',
summary: [{ k: 'GPU', v: currentAicGpu ? gpuOptionLabel(currentAicGpu.label, currentAicGpu.vramGb) : gpu }],
fields: [
{
label: 'GPU type',
value: gpu,
type: 'select' as const,
options: aicGpus.map(g => gpuOptionLabel(g.label, g.vramGb)),
onChange: (val: string) => {
const match = aicGpus.find(g => gpuOptionLabel(g.label, g.vramGb) === val)
if (match) setGpu(match.systemId)
}
},
],
},
// {
// id: 'hardware', title: 'Hardware',
// summary: [{ k: 'GPU', v: currentAicGpu ? gpuOptionLabel(currentAicGpu.label, currentAicGpu.vramGb) : gpu }],
// fields: [
// {
// label: 'GPU type',
// value: gpu,
// type: 'select' as const,
// options: aicGpus.map(g => gpuOptionLabel(g.label, g.vramGb)),
// onChange: (val: string) => {
// const match = aicGpus.find(g => gpuOptionLabel(g.label, g.vramGb) === val)
// if (match) setGpu(match.systemId)
// }
// },
// ],
// },
{
id: 'parallel',
title: 'Parallelism',
Expand Down Expand Up @@ -916,14 +910,15 @@ export default function QuickEstimate() {
<div className={styles.inputRow}>
{/* Column 1: Model field */}
<div>
<ModelInput
<ComboBox
id="qe-model"
model={model}
value={model}
onChange={setModel}
modelOptions={aicModels}
isLoading={catalogLoading}
items={modelItems}
placeholder="Type model name or select from dropdown..."
allowCustom
supportedModels={getAppConfig().supportedModels}
hfToken={hfToken}
status={modelStatus}
/>
</div>

Expand Down
40 changes: 13 additions & 27 deletions app/recommend/AdvancedEstimate.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -13,12 +13,11 @@ import CheckCircleIcon from '@patternfly/react-icons/dist/esm/icons/check-circle
import { InfoStrip, InfoStripAction } from '@/components/ui/InfoStrip';

import styles from './AdvancedEstimate.module.css';
import { fetchModelConfig } from '@/lib/huggingface/fetch-config';
import { useGpuSizer } from '@/contexts/GpuSizerContext';
import { useAicCatalog } from '@/lib/hooks/useAicCatalog';
import { useSettings } from '@/contexts/SettingsContext';
import { getAppConfig } from '@/lib/app-config';
import { ModelInput } from '@/components/ui/ModelInput';
import { ComboBox, type ComboBoxItem } from '@/components/ModelComboBox/ModelComboBox';
import { GpuSystemInput } from '@/components/ui/GpuSystemInput';

function modelSuggestions(): string {
Expand Down Expand Up @@ -136,6 +135,12 @@ export default function AdvancedEstimate() {
const { modelOptions: aicModels, gpuOptions: aicGpus, isLoading: catalogLoading } = useAicCatalog();
const MODEL_OPTIONS = aicModels;

const modelItems: ComboBoxItem[] = React.useMemo(() =>
aicModels.map(m => {
const slash = m.indexOf('/');
return { value: m, label: m, group: slash > 0 ? m.slice(0, slash) : '' };
}), [aicModels]);

// Input state
const [model, setModel] = React.useState('');

Expand All @@ -151,9 +156,6 @@ export default function AdvancedEstimate() {
const [osl, setOsl] = React.useState(128);
const [ttft, setTtft] = React.useState(1000);

// Model status + HF config
const [modelStatus, setModelStatus] = React.useState<'idle' | 'supported' | 'catalog' | 'fetching' | 'fetched' | 'error'>('idle');

// GPU sizer (persistent across navigation)
const { isLoading, result, error, errorCode, elapsed, debugRequest, debugResponse, debugStatus, debugDuration, startSizing } = useGpuSizer();
const [debugOpen, setDebugOpen] = React.useState(false);
Expand Down Expand Up @@ -194,22 +196,6 @@ export default function AdvancedEstimate() {
};


// Model status check + fetch HF config
React.useEffect(() => {
if (catalogLoading) { setModelStatus('idle'); return; }
const timer = setTimeout(() => {
if (!model.includes('/')) { setModelStatus('idle'); return; }
if (getAppConfig().supportedModels.includes(model)) { setModelStatus('supported'); return; }
const inCatalog = MODEL_OPTIONS.includes(model);
if (inCatalog) { setModelStatus('catalog'); return; }
setModelStatus('fetching');
fetchModelConfig(model, hfToken).then(r => {
setModelStatus(r.success && r.config ? 'fetched' : 'error');
});
}, 500);
return () => clearTimeout(timer);
}, [model, hfToken, MODEL_OPTIONS, catalogLoading, hydrated]);

// Fetch live pricing
React.useEffect(() => {
const fetchPricing = async () => {
Expand Down Expand Up @@ -267,15 +253,15 @@ export default function AdvancedEstimate() {
{/* Model + GPU row */}
<div className={styles.inputGrid}>
<div>
<ModelInput
<ComboBox
id="adv-model"
model={model}
value={model}
onChange={setModel}
modelOptions={aicModels}
isLoading={catalogLoading}
hfToken={hfToken}
status={modelStatus}
items={modelItems}
placeholder="e.g. meta-llama/Llama-3.1-70B-Instruct"
allowCustom
supportedModels={getAppConfig().supportedModels}
hfToken={hfToken}
/>
</div>

Expand Down
6 changes: 3 additions & 3 deletions app/settings/Settings.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -125,7 +125,7 @@ export function Settings() {
</div>
</div>

{/* ── Validated models ── */}
{/* ── Tested models ── */}
<div className={styles.section}>
<div
className={styles.sectionHead}
Expand All @@ -134,13 +134,13 @@ export function Settings() {
>
<div>
<div className={styles.sectionTitle}>
Validated models
Tested models
<span style={{ fontSize: '11px', fontWeight: 400, marginLeft: '8px', color: '#6a6e73' }}>
{validatedOpen ? '▲' : '▼'}
</span>
</div>
<div className={styles.sectionDesc}>
Models validated for use with the AIConfigurator sizing engine.
Models tested for use with the AIConfigurator sizing engine.
Comment thread
mazam-lab marked this conversation as resolved.
</div>
</div>
<Label color="blue" isCompact>{getAppConfig().supportedModels.length} models</Label>
Expand Down
Loading
Loading