diff --git a/web/public/locales/en/views/system.json b/web/public/locales/en/views/system.json index 98583134ca..10f6aa3a47 100644 --- a/web/public/locales/en/views/system.json +++ b/web/public/locales/en/views/system.json @@ -72,7 +72,9 @@ "toast": { "success": "Copied GPU info to clipboard" } - } + }, + "npuUsage": "NPU Usage", + "npuMemory": "NPU Memory" }, "otherProcesses": { "title": "Other Processes", diff --git a/web/src/types/stats.ts b/web/src/types/stats.ts index 8e41f2e384..611379be30 100644 --- a/web/src/types/stats.ts +++ b/web/src/types/stats.ts @@ -4,6 +4,7 @@ export interface FrigateStats { detectors: { [detectorKey: string]: DetectorStats }; embeddings?: EmbeddingsStats; gpu_usages?: { [gpuKey: string]: GpuStats }; + npu_usages?: { [npuKey: string]: NpuStats }; processes: { [processKey: string]: ExtraProcessStats }; service: ServiceStats; detection_fps: number; @@ -54,6 +55,11 @@ export type GpuStats = { pstate?: string; }; +export type NpuStats = { + npu: number; + mem: string; +}; + export type GpuInfo = "vainfo" | "nvinfo"; export type ServiceStats = { diff --git a/web/src/views/system/GeneralMetrics.tsx b/web/src/views/system/GeneralMetrics.tsx index 3596a7ad15..0310bff817 100644 --- a/web/src/views/system/GeneralMetrics.tsx +++ b/web/src/views/system/GeneralMetrics.tsx @@ -34,7 +34,7 @@ export default function GeneralMetrics({ const { data: initialStats } = useSWR( [ "stats/history", - { keys: "cpu_usages,detectors,gpu_usages,processes,service" }, + { keys: "cpu_usages,detectors,gpu_usages,npu_usages,processes,service" }, ], { revalidateOnFocus: false, @@ -369,8 +369,57 @@ export default function GeneralMetrics({ return Object.keys(series).length > 0 ? Object.values(series) : undefined; }, [statsHistory]); + // npu stats + + const npuSeries = useMemo(() => { + if (!statsHistory) { + return []; + } + + const series: { + [key: string]: { name: string; data: { x: number; y: number }[] }; + } = {}; + let hasValidNpu = false; + + statsHistory.forEach((stats, statsIdx) => { + if (!stats) { + return; + } + + Object.entries(stats.npu_usages || []).forEach(([key, stats]) => { + if (!(key in series)) { + series[key] = { name: key, data: [] }; + } + + if (stats.npu) { + hasValidNpu = true; + series[key].data.push({ x: statsIdx + 1, y: stats.npu }); + } + }); + }); + + if (!hasValidNpu) { + return []; + } + + return Object.keys(series).length > 0 ? Object.values(series) : []; + }, [statsHistory]); + // other processes stats + const hardwareType = useMemo(() => { + const hasGpu = statsHistory[0]?.gpu_usages != undefined; + const hasNpu = statsHistory[0]?.npu_usages != undefined; + + if (hasGpu && !hasNpu) { + return "GPUs"; + } else if (!hasGpu && hasNpu) { + return "NPUs"; + } else { + return "GPUs / NPUs"; + } + }, [statsHistory]); + const otherProcessCpuSeries = useMemo(() => { if (!statsHistory) { return []; @@ -533,11 +582,13 @@ export default function GeneralMetrics({ )} - {(statsHistory.length == 0 || statsHistory[0].gpu_usages) && ( + {(statsHistory.length == 0 || + statsHistory[0].gpu_usages || + statsHistory[0].npu_usages) && ( <>
- GPUs + {hardwareType}
{canGetGpuInfo && (