feat: imporve UI/UX gpu acceleration feature (#1990)
This commit is contained in:
parent
4e83cf3904
commit
6f520b4534
@ -36,7 +36,7 @@ const GPUDriverPrompt: React.FC = () => {
|
||||
<Modal open={showNotification} onOpenChange={openChanged}>
|
||||
<ModalContent>
|
||||
<ModalHeader>
|
||||
<ModalTitle>
|
||||
<ModalTitle className="pr-4 leading-relaxed">
|
||||
Checking for machine that does not meet the requirements.
|
||||
</ModalTitle>
|
||||
</ModalHeader>
|
||||
|
||||
@ -63,6 +63,17 @@ const BottomBar = () => {
|
||||
return Math.round(((total - free) / total) * 100)
|
||||
}
|
||||
|
||||
const calculateUtilization = () => {
|
||||
let sum = 0
|
||||
const util = gpus.map((x) => {
|
||||
return Number(x['utilization'])
|
||||
})
|
||||
util.forEach((num) => {
|
||||
sum += num
|
||||
})
|
||||
return sum
|
||||
}
|
||||
|
||||
return (
|
||||
<div className="fixed bottom-0 left-16 z-20 flex h-12 w-[calc(100%-64px)] items-center justify-between border-t border-border bg-background/80 px-3">
|
||||
<div className="flex flex-shrink-0 items-center gap-x-2">
|
||||
@ -126,15 +137,39 @@ const BottomBar = () => {
|
||||
<SystemItem name="Mem:" value={`${ram}%`} />
|
||||
</div>
|
||||
{gpus.length > 0 && (
|
||||
<div className="flex items-center gap-x-2">
|
||||
{gpus.map((gpu, index) => (
|
||||
<Tooltip>
|
||||
<TooltipTrigger>
|
||||
<div className="flex cursor-pointer items-center">
|
||||
<SystemItem
|
||||
key={index}
|
||||
name={`GPU ${gpu.id}:`}
|
||||
value={`${gpu.utilization}% Util, ${calculateGpuMemoryUsage(gpu)}% Mem`}
|
||||
name={`${gpus.length} GPU `}
|
||||
value={`${calculateUtilization()}% `}
|
||||
/>
|
||||
))}
|
||||
</div>
|
||||
</TooltipTrigger>
|
||||
{gpus.length > 1 && (
|
||||
<TooltipContent
|
||||
side="top"
|
||||
sideOffset={10}
|
||||
className="min-w-[240px]"
|
||||
>
|
||||
<span>
|
||||
{gpus.map((gpu, index) => (
|
||||
<div
|
||||
key={index}
|
||||
className="flex items-center justify-between"
|
||||
>
|
||||
<div>
|
||||
<span>{gpu.name}</span>
|
||||
<span>{gpu.vram}MB VRAM</span>
|
||||
</div>
|
||||
<span>{gpu.utilization}%</span>
|
||||
</div>
|
||||
))}
|
||||
</span>
|
||||
<TooltipArrow />
|
||||
</TooltipContent>
|
||||
)}
|
||||
</Tooltip>
|
||||
)}
|
||||
{/* VERSION is defined by webpack, please see next.config.js */}
|
||||
<span className="text-xs text-muted-foreground">
|
||||
|
||||
@ -24,7 +24,7 @@ export const useSettings = () => {
|
||||
((settings.nvidia_driver?.exist && !settings.cuda?.exist) ||
|
||||
!settings.nvidia_driver?.exist)
|
||||
) {
|
||||
setShowNotification(true)
|
||||
setShowNotification(false)
|
||||
}
|
||||
|
||||
// Check if run_mode is 'gpu' or 'cpu' and update state accordingly
|
||||
|
||||
@ -383,8 +383,8 @@ const LocalServerScreen = () => {
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
>
|
||||
<path
|
||||
fill-rule="evenodd"
|
||||
clip-rule="evenodd"
|
||||
fillRule="evenodd"
|
||||
clipRule="evenodd"
|
||||
d="M9.00033 17.3337C13.6027 17.3337 17.3337 13.6027 17.3337 9.00033C17.3337 4.39795 13.6027 0.666992 9.00033 0.666992C4.39795 0.666992 0.666992 4.39795 0.666992 9.00033C0.666992 10.9978 1.36978 12.8311 2.54157 14.2666L0.910703 15.9111C0.390085 16.436 0.758808 17.3337 1.49507 17.3337H9.00033ZM5.25033 7.33366C5.25033 6.87342 5.62342 6.50033 6.08366 6.50033H11.917C12.3772 6.50033 12.7503 6.87342 12.7503 7.33366C12.7503 7.7939 12.3772 8.16699 11.917 8.16699H6.08366C5.62342 8.16699 5.25033 7.7939 5.25033 7.33366ZM6.08366 9.83366C5.62342 9.83366 5.25033 10.2068 5.25033 10.667C5.25033 11.1272 5.62342 11.5003 6.08366 11.5003H8.58366C9.0439 11.5003 9.41699 11.1272 9.41699 10.667C9.41699 10.2068 9.0439 9.83366 8.58366 9.83366H6.08366Z"
|
||||
fill="#2563EB"
|
||||
/>
|
||||
|
||||
@ -8,12 +8,32 @@ import {
|
||||
ChangeEvent,
|
||||
} from 'react'
|
||||
|
||||
import { openExternalUrl } from '@janhq/core'
|
||||
|
||||
import { fs } from '@janhq/core'
|
||||
import { Switch, Button, Input } from '@janhq/uikit'
|
||||
import {
|
||||
Switch,
|
||||
Button,
|
||||
Input,
|
||||
Select,
|
||||
Checkbox,
|
||||
SelectContent,
|
||||
SelectGroup,
|
||||
SelectPortal,
|
||||
SelectLabel,
|
||||
SelectTrigger,
|
||||
SelectValue,
|
||||
Tooltip,
|
||||
TooltipArrow,
|
||||
TooltipContent,
|
||||
TooltipTrigger,
|
||||
} from '@janhq/uikit'
|
||||
|
||||
import { AlertTriangleIcon, AlertCircleIcon } from 'lucide-react'
|
||||
|
||||
import ShortcutModal from '@/containers/ShortcutModal'
|
||||
|
||||
import { toaster } from '@/containers/Toast'
|
||||
import { snackbar, toaster } from '@/containers/Toast'
|
||||
|
||||
import { FeatureToggleContext } from '@/context/FeatureToggle'
|
||||
|
||||
@ -40,6 +60,12 @@ const Advanced = () => {
|
||||
const { readSettings, saveSettings, validateSettings, setShowNotification } =
|
||||
useSettings()
|
||||
|
||||
const selectedGpu = gpuList
|
||||
.filter((x) => gpusInUse.includes(x.id))
|
||||
.map((y) => {
|
||||
return y['name']
|
||||
})
|
||||
|
||||
const onProxyChange = useCallback(
|
||||
(event: ChangeEvent<HTMLInputElement>) => {
|
||||
const value = event.target.value || ''
|
||||
@ -77,6 +103,7 @@ const Advanced = () => {
|
||||
}
|
||||
|
||||
const handleGPUChange = (gpuId: string) => {
|
||||
// TODO detect current use GPU nvidia or AMD
|
||||
let updatedGpusInUse = [...gpusInUse]
|
||||
if (updatedGpusInUse.includes(gpuId)) {
|
||||
updatedGpusInUse = updatedGpusInUse.filter((id) => id !== gpuId)
|
||||
@ -127,15 +154,55 @@ const Advanced = () => {
|
||||
|
||||
{/* CPU / GPU switching */}
|
||||
{!isMac && (
|
||||
<div className="flex w-full items-start justify-between border-b border-border py-4 first:pt-0 last:border-none">
|
||||
<div className="flex-shrink-0 space-y-1.5">
|
||||
<div className="flex w-full flex-col items-start justify-between border-b border-border py-4 first:pt-0 last:border-none">
|
||||
<div className="flex items-start justify-between">
|
||||
<div className="space-y-1.5">
|
||||
<div className="flex gap-x-2">
|
||||
<h6 className="text-sm font-semibold capitalize">Nvidia GPU</h6>
|
||||
<h6 className="text-sm font-semibold capitalize">
|
||||
GPU Acceleration
|
||||
</h6>
|
||||
</div>
|
||||
<p className="leading-relaxed">
|
||||
Enable GPU acceleration for Nvidia GPUs.
|
||||
<p className="pr-8 leading-relaxed">
|
||||
Enable to enhance model performance by utilizing your devices
|
||||
GPU for acceleration. Read{' '}
|
||||
<span>
|
||||
{' '}
|
||||
<span
|
||||
className="cursor-pointer text-blue-600"
|
||||
onClick={() =>
|
||||
openExternalUrl(
|
||||
'https://jan.ai/guides/troubleshooting/gpu-not-used/'
|
||||
)
|
||||
}
|
||||
>
|
||||
troubleshooting guide
|
||||
</span>{' '}
|
||||
</span>{' '}
|
||||
for further assistance.
|
||||
</p>
|
||||
</div>
|
||||
{gpuList.length > 0 && !gpuEnabled && (
|
||||
<Tooltip>
|
||||
<TooltipTrigger>
|
||||
<AlertCircleIcon size={20} className="mr-2 text-yellow-600" />
|
||||
</TooltipTrigger>
|
||||
<TooltipContent
|
||||
side="right"
|
||||
sideOffset={10}
|
||||
className="max-w-[240px]"
|
||||
>
|
||||
<span>
|
||||
Disabling GPU Acceleration may result in reduced
|
||||
performance. It is recommended to keep this enabled for
|
||||
optimal user experience.
|
||||
</span>
|
||||
<TooltipArrow />
|
||||
</TooltipContent>
|
||||
</Tooltip>
|
||||
)}
|
||||
|
||||
<Tooltip>
|
||||
<TooltipTrigger>
|
||||
<Switch
|
||||
checked={gpuEnabled}
|
||||
onCheckedChange={(e) => {
|
||||
@ -143,50 +210,115 @@ const Advanced = () => {
|
||||
saveSettings({ runMode: 'gpu' })
|
||||
setGpuEnabled(true)
|
||||
setShowNotification(false)
|
||||
snackbar({
|
||||
description: 'Successfully turned on GPU Accelertion',
|
||||
type: 'success',
|
||||
})
|
||||
setTimeout(() => {
|
||||
validateSettings()
|
||||
}, 300)
|
||||
} else {
|
||||
saveSettings({ runMode: 'cpu' })
|
||||
setGpuEnabled(false)
|
||||
snackbar({
|
||||
description: 'Successfully turned off GPU Accelertion',
|
||||
type: 'success',
|
||||
})
|
||||
}
|
||||
}}
|
||||
/>
|
||||
</div>
|
||||
</TooltipTrigger>
|
||||
{gpuList.length === 0 && (
|
||||
<TooltipContent
|
||||
side="right"
|
||||
sideOffset={10}
|
||||
className="max-w-[240px]"
|
||||
>
|
||||
<span>
|
||||
Your current device does not have a compatible GPU for
|
||||
monitoring. To enable GPU monitoring, please ensure your
|
||||
device has a supported Nvidia or AMD GPU with updated
|
||||
drivers.
|
||||
</span>
|
||||
<TooltipArrow />
|
||||
</TooltipContent>
|
||||
)}
|
||||
{/* Directory */}
|
||||
</Tooltip>
|
||||
</div>
|
||||
|
||||
{gpuEnabled && (
|
||||
<div className="mt-4">
|
||||
<label className="block text-sm font-medium text-gray-700">
|
||||
Select GPU(s)
|
||||
<div className="mt-2 w-full rounded-lg bg-secondary p-4">
|
||||
<label className="mb-1 inline-block font-medium">
|
||||
Choose GPU
|
||||
</label>
|
||||
<div className="mt-2 space-y-2">
|
||||
{gpuList.map((gpu) => (
|
||||
<div key={gpu.id}>
|
||||
<input
|
||||
type="checkbox"
|
||||
<Select value={selectedGpu.join()}>
|
||||
<SelectTrigger className="w-[340px] bg-white">
|
||||
<SelectValue placeholder="Select GPU">
|
||||
<span className="line-clamp-1 w-full pr-8">
|
||||
{selectedGpu.join()}
|
||||
</span>
|
||||
</SelectValue>
|
||||
</SelectTrigger>
|
||||
<SelectPortal>
|
||||
<SelectContent className="w-[400px] px-1 pb-2">
|
||||
<SelectGroup>
|
||||
<SelectLabel>Nvidia</SelectLabel>
|
||||
<div className="px-4 pb-2">
|
||||
<div className="rounded-lg bg-secondary p-3">
|
||||
{gpuList
|
||||
.filter((gpu) =>
|
||||
gpu.name.toLowerCase().includes('nvidia')
|
||||
)
|
||||
.map((gpu) => (
|
||||
<div
|
||||
key={gpu.id}
|
||||
className="my-1 flex items-center space-x-2"
|
||||
>
|
||||
<Checkbox
|
||||
id={`gpu-${gpu.id}`}
|
||||
name="gpu"
|
||||
name="gpu-nvidia"
|
||||
className="bg-white"
|
||||
value={gpu.id}
|
||||
checked={gpusInUse.includes(gpu.id)}
|
||||
onChange={() => handleGPUChange(gpu.id)}
|
||||
onCheckedChange={() =>
|
||||
handleGPUChange(gpu.id)
|
||||
}
|
||||
/>
|
||||
<label htmlFor={`gpu-${gpu.id}`}>
|
||||
{' '}
|
||||
{gpu.name} (VRAM: {gpu.vram} MB)
|
||||
<label
|
||||
className="flex w-full items-center justify-between"
|
||||
htmlFor={`gpu-${gpu.id}`}
|
||||
>
|
||||
<span>{gpu.name}</span>
|
||||
<span>{gpu.vram}MB VRAM</span>
|
||||
</label>
|
||||
</div>
|
||||
))}
|
||||
</div>
|
||||
</div>
|
||||
)}
|
||||
{/* Warning message */}
|
||||
{gpuEnabled && gpusInUse.length > 1 && (
|
||||
<p className="mt-2 italic text-red-500">
|
||||
If enabling multi-GPU without the same GPU model or without NVLink, it
|
||||
may affect token speed.
|
||||
<div className="mt-2 flex items-start space-x-2 text-yellow-500">
|
||||
<AlertTriangleIcon
|
||||
size={16}
|
||||
className="flex-shrink-0"
|
||||
/>
|
||||
<p className="text-xs leading-relaxed">
|
||||
If multi-GPU is enabled with different GPU models
|
||||
or without NVLink, it could impact token speed.
|
||||
</p>
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
</SelectGroup>
|
||||
|
||||
{/* TODO enable this when we support AMD */}
|
||||
</SelectContent>
|
||||
</SelectPortal>
|
||||
</Select>
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
)}
|
||||
|
||||
<DataFolder />
|
||||
{/* Proxy */}
|
||||
<div className="flex w-full items-start justify-between border-b border-border py-4 first:pt-0 last:border-none">
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user