import { useState, useEffect } from 'react'; import { BarChart3, Layers, TrendingUp, RefreshCw, AlertTriangle } from 'lucide-react'; import { useQuantizationStore, useModelStore } from '../store'; import { motion } from 'framer-motion'; import { BarChart, Bar, XAxis, YAxis, CartesianGrid, Tooltip, ResponsiveContainer, Cell, Legend } from 'recharts'; /** * Analysis page - compare quantization methods and analyze weights */ export default function Analysis() { const { compareMethod } = useQuantizationStore(); const { modelInfo, layers, fetchLayers } = useModelStore(); const [comparison, setComparison] = useState(null); const [isLoading, setIsLoading] = useState(false); const [selectedMethods, setSelectedMethods] = useState(['int8', 'int4', 'nf4']); const [source, setSource] = useState('random'); // 'random' | 'layer' const [selectedLayer, setSelectedLayer] = useState(''); // Switch to layer mode if model is loaded // Switch to layer mode if model is loaded useEffect(() => { if (modelInfo) { setSource('layer'); if (layers.length === 0) fetchLayers(); } }, [modelInfo]); const runComparison = async () => { setIsLoading(true); const layerToCompare = source === 'layer' ? selectedLayer : null; const result = await compareMethod(selectedMethods, layerToCompare); setComparison(result); setIsLoading(false); }; const toggleMethod = (method) => { setSelectedMethods((prev) => prev.includes(method) ? prev.filter(m => m !== method) : [...prev, method] ); }; // Prepare chart data const getComparisonData = () => { if (!comparison?.comparison) return []; return comparison.comparison .filter(c => !c.error) .map(c => ({ method: c.method.toUpperCase(), meanError: c.mean_error, maxError: c.max_error, memorySavings: c.memory_savings_percent })); }; const COLORS = ['#6366f1', '#8b5cf6', '#a855f7']; return (
{/* Header */}

Analysis

Compare quantization methods and analyze weight distributions

{modelInfo && (
Active Model: {modelInfo.name}
)}
{/* Method Comparison */}

Method Comparison {comparison && ( Source: {comparison.source.startsWith('layer:') ? comparison.source.replace('layer:', '') : 'Random Weights'} )}

{/* Data Source Selection */}

Select data source:

{modelInfo && ( )}
{source === 'layer' && (
)}
{/* Method Selection */}

Select methods to compare:

{['int8', 'int4', 'nf4'].map((method) => ( ))}
{/* Comparison Results */} {comparison && (
{/* Error Chart */}

Quantization Error by Method

{getComparisonData().map((entry, index) => ( ))}
{/* Memory Savings Chart */}

Memory Savings by Method

[`${value.toFixed(1)}%`, 'Savings']} /> {getComparisonData().map((entry, index) => ( ))}
{/* Results Table */}
{comparison.comparison?.filter(c => !c.error).map((result) => ( ))}
Method Bits Max Error Mean Error Memory Savings
{result.method.toUpperCase()} {result.bits} {result.max_error?.toFixed(6)} {result.mean_error?.toFixed(6)} {result.memory_savings_percent?.toFixed(1)}%
)}
{/* Model Analysis (if model loaded) */} {modelInfo && (

Model Analysis

Model {modelInfo.name} is loaded with{' '} {modelInfo.num_quantizable_layers} quantizable layers.

Use the Models page to analyze individual layer weights and detect outliers.

)} {/* Info Section */}

Understanding Quantization Trade-offs

Lower bit precision (4-bit) provides better memory savings but introduces more error. 8-bit quantization offers a good balance between compression and accuracy for most models. NF4 uses a codebook optimized for normally distributed weights, ideal for LLMs.

); }