File size: 5,883 Bytes
e7ba29d ad5cef3 e7ba29d 6ebf2fd ad5cef3 117cfaa 6ebf2fd 4d810fa 6ebf2fd 117cfaa 6ebf2fd ad5cef3 f3b30b4 ad5cef3 f3b30b4 ad5cef3 e7ba29d ad5cef3 e7ba29d f3b30b4 ad5cef3 6ebf2fd 4d810fa ad5cef3 6ebf2fd f3b30b4 6ebf2fd f3b30b4 6ebf2fd f3b30b4 6ebf2fd f3b30b4 6ebf2fd f3b30b4 6ebf2fd f3b30b4 6ebf2fd f3b30b4 6ebf2fd f3b30b4 6ebf2fd f3b30b4 6ebf2fd f3b30b4 6ebf2fd f3b30b4 6ebf2fd f3b30b4 6ebf2fd f3b30b4 6ebf2fd f3b30b4 6ebf2fd 117cfaa 6ebf2fd 117cfaa 6ebf2fd ad5cef3 6ebf2fd f3b30b4 6ebf2fd |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 |
import {
Bot,
Heart,
Download,
Cpu,
DatabaseIcon,
CheckCircle,
XCircle,
ExternalLink
} from 'lucide-react'
import { getModelSize } from '../lib/huggingface'
import { useModel } from '../contexts/ModelContext'
import ModelLoader from './ModelLoader'
import Tooltip from './Tooltip'
const ModelInfo = () => {
const formatNumber = (num: number) => {
if (num >= 1000000000) {
return (num / 1000000000).toFixed(1) + 'B'
} else if (num >= 1000000) {
return (num / 1000000).toFixed(1) + 'M'
} else if (num >= 1000) {
return (num / 1000).toFixed(1) + 'K'
}
return num.toString()
}
const { models, modelInfo, selectedQuantization, isFetching } = useModel()
const ModelInfoSkeleton = () => (
<div className="bg-gradient-to-r from-blue-50 to-indigo-50 px-3 py-3 rounded-lg border border-blue-200 space-y-3 animate-pulse w-4/5">
<div className="flex items-center space-x-2">
<Bot className="w-4 h-4 text-blue-300" />
<div className="h-4 bg-gray-300 rounded flex-1"></div>
<div className="w-4 h-4 bg-gray-300 rounded-full"></div>
</div>
<div className="flex items-center space-x-2 ml-6">
<div className="h-3 bg-gray-200 rounded w-32"></div>
</div>
<div className="grid grid-cols-2 gap-2 text-xs">
<div className="flex items-center space-x-1">
<Heart className="w-3 h-3 text-red-300" />
<div className="h-3 bg-gray-200 rounded w-8"></div>
</div>
<div className="flex items-center space-x-1">
<Download className="w-3 h-3 text-green-300" />
<div className="h-3 bg-gray-200 rounded w-8"></div>
</div>
<div className="flex items-center space-x-1">
<Cpu className="w-3 h-3 text-purple-300" />
<div className="h-3 bg-gray-200 rounded w-8"></div>
</div>
<div className="flex items-center space-x-1">
<DatabaseIcon className="w-3 h-3 text-purple-300" />
<div className="h-3 bg-gray-200 rounded w-12"></div>
</div>
</div>
<hr className="border-gray-200" />
<div className="h-8 bg-gray-200 rounded w-full"></div>
</div>
)
if (!modelInfo || isFetching || models.length === 0) {
return <ModelInfoSkeleton />
}
return (
<div className="relative bg-gradient-to-r from-blue-50 to-indigo-50 px-3 py-3 rounded-lg border border-blue-200 space-y-3 h-full w-4/5">
{/* Model Name Row */}
<div className="flex justify-center items-center space-x-2">
{/* Compatibility Status */}
{typeof modelInfo.isCompatible === 'boolean' && (
<div className="flex-shrink-0 ">
{modelInfo.isCompatible ? (
<CheckCircle className="w-4 h-4 text-green-500" />
) : (
<XCircle className="w-4 h-4 text-red-500" />
)}
</div>
)}
<div className="flex-1 min-w-0">
<a
href={`https://huggingface.co/${modelInfo.name}`}
target="_blank"
rel="noopener noreferrer"
className="text-sm font-medium text-gray-700 hover:underline block truncate"
title={modelInfo.name}
>
<ExternalLink className="w-3 h-3 inline-block mr-1" />
{modelInfo.name}
</a>
{/* Base Model Link */}
{modelInfo.baseId && modelInfo.baseId !== modelInfo.id && (
<a
href={`https://huggingface.co/${modelInfo.baseId}`}
target="_blank"
rel="noopener noreferrer"
className="text-xs text-gray-500 hover:underline block truncate mt-1"
title={`Base model: ${modelInfo.baseId}`}
>
<ExternalLink className="w-3 h-3 inline-block mr-1" />(
{modelInfo.baseId})
</a>
)}
</div>
</div>
{/* Stats Grid */}
<div className="grid grid-cols-2 gap-2 text-xs text-gray-600">
{modelInfo.likes > 0 && (
<div className="flex items-center space-x-1">
<Heart className="w-3 h-3 text-red-500" />
<span>{formatNumber(modelInfo.likes)}</span>
</div>
)}
{modelInfo.downloads > 0 && (
<div className="flex items-center space-x-1">
<Download className="w-3 h-3 text-green-500" />
<span>{formatNumber(modelInfo.downloads)}</span>
</div>
)}
<Tooltip content="Model parameters according to Hugging Face API">
<div className="flex items-center space-x-1 cursor-default">
<Cpu className="w-3 h-3 text-purple-500" />
{modelInfo.parameters ? (
<span>{formatNumber(modelInfo.parameters)}</span>
) : (
<span>?</span>
)}
</div>
</Tooltip>
<Tooltip
content={`Estimated size with ${selectedQuantization} quantization`}
>
<div className="flex items-center space-x-1 cursor-default">
<DatabaseIcon className="w-3 h-3 text-purple-500" />
{modelInfo.parameters ? (
<span>
{`~${getModelSize(
modelInfo.parameters,
selectedQuantization
).toFixed(1)}MB`}
</span>
) : (
<span>?</span>
)}
</div>
</Tooltip>
</div>
<ModelLoader />
{/* Incompatibility Message */}
{modelInfo.isCompatible === false && modelInfo.incompatibilityReason && (
<div className="bg-red-50 border border-red-200 rounded-md px-2 py-2">
<p className="text-xs text-red-700 whitespace-break-spaces">
{modelInfo.incompatibilityReason}
</p>
</div>
)}
</div>
)
}
export default ModelInfo
|