diff --git a/web-app/src/routes/system-monitor.tsx b/web-app/src/routes/system-monitor.tsx index 45f638bf2..be1dfff19 100644 --- a/web-app/src/routes/system-monitor.tsx +++ b/web-app/src/routes/system-monitor.tsx @@ -11,6 +11,7 @@ import { getActiveModels, stopModel } from '@/services/models' import { Button } from '@/components/ui/button' import { useTranslation } from '@/i18n/react-i18next-compat' import { toNumber } from '@/utils/number' +import { useModelProvider } from '@/hooks/useModelProvider' // eslint-disable-next-line @typescript-eslint/no-explicit-any export const Route = createFileRoute(route.systemMonitor as any)({ @@ -19,28 +20,85 @@ export const Route = createFileRoute(route.systemMonitor as any)({ function SystemMonitor() { const { t } = useTranslation() - const { hardwareData, systemUsage, setHardwareData, updateSystemUsage } = + const { hardwareData, systemUsage, updateHardwareDataPreservingGpuOrder, updateSystemUsage, updateGPUActivationFromDeviceString } = useHardware() const [activeModels, setActiveModels] = useState([]) + const { providers, getProviderByName } = useModelProvider() + const [isInitialized, setIsInitialized] = useState(false) + + // Determine backend type and filter GPUs accordingly (same logic as hardware.tsx) + const llamacpp = providers.find((p) => p.provider === 'llamacpp') + const versionBackend = llamacpp?.settings.find((s) => s.key === "version_backend")?.controller_props.value useEffect(() => { - // Initial data fetch + // Initial data fetch - use updateHardwareDataPreservingGpuOrder like hardware.tsx getHardwareInfo().then((data) => { - setHardwareData(data as unknown as HardwareData) + updateHardwareDataPreservingGpuOrder(data as unknown as HardwareData) }) getActiveModels().then(setActiveModels) // Set up interval for real-time updates const intervalId = setInterval(() => { getSystemUsage().then((data) => { - // setHardwareData(data as unknown as HardwareData) updateSystemUsage(data) }) getActiveModels().then(setActiveModels) }, 5000) return () => clearInterval(intervalId) - }, [setHardwareData, setActiveModels, updateSystemUsage]) + }, [updateHardwareDataPreservingGpuOrder, setActiveModels, updateSystemUsage]) + + // Initialize GPU activations from device setting on first load (same logic as hardware.tsx) + useEffect(() => { + if (hardwareData.gpus.length > 0 && !isInitialized) { + const llamacppProvider = getProviderByName('llamacpp') + const currentDeviceSetting = llamacppProvider?.settings.find(s => s.key === 'device')?.controller_props.value as string + + if (currentDeviceSetting) { + updateGPUActivationFromDeviceString(currentDeviceSetting) + } + + setIsInitialized(true) + } + }, [hardwareData.gpus.length, isInitialized, getProviderByName, updateGPUActivationFromDeviceString]) + + // Sync device setting when GPU activations change (only after initialization) - same logic as hardware.tsx + const { getActivatedDeviceString } = useHardware() + const { updateProvider } = useModelProvider() + const gpuActivationStates = hardwareData.gpus.map(gpu => gpu.activated) + + useEffect(() => { + if (isInitialized && hardwareData.gpus.length > 0) { + const llamacppProvider = getProviderByName('llamacpp') + const backendType = llamacppProvider?.settings.find(s => s.key === 'version_backend')?.controller_props.value as string + const deviceString = getActivatedDeviceString(backendType) + + if (llamacppProvider) { + const currentDeviceSetting = llamacppProvider.settings.find(s => s.key === 'device') + + // Sync device string when GPU activations change (only after initialization) + if (currentDeviceSetting && currentDeviceSetting.controller_props.value !== deviceString) { + + const updatedSettings = llamacppProvider.settings.map(setting => { + if (setting.key === 'device') { + return { + ...setting, + controller_props: { + ...setting.controller_props, + value: deviceString + } + } + } + return setting + }) + + updateProvider('llamacpp', { + settings: updatedSettings + }) + } + } + } + }, [isInitialized, gpuActivationStates, versionBackend, getActivatedDeviceString, updateProvider, getProviderByName, hardwareData.gpus.length]) const stopRunningModel = (modelId: string) => { stopModel(modelId) @@ -61,6 +119,33 @@ function SystemMonitor() { hardwareData.total_memory ) * 100 + // Determine backend type and filter GPUs accordingly + const isCudaBackend = typeof versionBackend === 'string' && versionBackend.includes('cuda') + const isVulkanBackend = typeof versionBackend === 'string' && versionBackend.includes('vulkan') + + // Check if GPU should be active based on backend compatibility + const isGPUCompatible = (gpu: any) => { + if (isCudaBackend) { + return gpu.nvidia_info !== null + } else if (isVulkanBackend) { + return gpu.vulkan_info !== null + } else { + // No valid backend - all GPUs are inactive + return false + } + } + + // Check if GPU is actually activated + const isGPUActive = (gpu: any) => { + const compatible = isGPUCompatible(gpu) + const activated = gpu.activated ?? false + const result = compatible && activated + return result + } + + // Filter to show only active GPUs + const activeGPUs = hardwareData.gpus.filter(gpu => isGPUActive(gpu)) + return (
@@ -220,11 +305,18 @@ function SystemMonitor() {

{t('system-monitor:activeGpus')}

- {hardwareData.gpus.length > 0 ? ( + {!isInitialized ? ( +
+ Initializing GPU states... +
+ ) : activeGPUs.length > 0 ? (
- {hardwareData.gpus - // .filter((gpu) => gpu.activated) - .map((gpu, index) => ( + {activeGPUs.map((gpu, index) => { + // Find the corresponding system usage data for this GPU + const gpuUsage = systemUsage.gpus.find(usage => usage.uuid === gpu.uuid) + const gpuIndex = hardwareData.gpus.findIndex(hwGpu => hwGpu.uuid === gpu.uuid) + + return (
- {formatMegaBytes( - gpu.total_memory - - systemUsage.gpus[index]?.used_memory - )}{' '} - / {formatMegaBytes(gpu.total_memory)} + {gpuUsage ? ( + <> + {formatMegaBytes(gpuUsage.used_memory)}{' '} + / {formatMegaBytes(gpu.total_memory)} + + ) : ( + <> + {formatMegaBytes(0)}{' '} + / {formatMegaBytes(gpu.total_memory)} + + )}
@@ -264,23 +362,22 @@ function SystemMonitor() { {gpu.nvidia_info?.compute_capability || - gpu.vulkan_info.api_version} + gpu.vulkan_info?.api_version || '-'}
- ))} + ) + })}
) : (
@@ -288,6 +385,7 @@ function SystemMonitor() {
)} + ) }