diff --git a/web/containers/ModelLabel/NotEnoughRamLabel.tsx b/web/containers/ModelLabel/NotEnoughMemoryLabel.tsx similarity index 83% rename from web/containers/ModelLabel/NotEnoughRamLabel.tsx rename to web/containers/ModelLabel/NotEnoughMemoryLabel.tsx index b24e42d63..c81245f04 100644 --- a/web/containers/ModelLabel/NotEnoughRamLabel.tsx +++ b/web/containers/ModelLabel/NotEnoughMemoryLabel.tsx @@ -10,9 +10,9 @@ import { } from '@janhq/uikit' import { InfoIcon } from 'lucide-react' -const NotEnoughRamLabel: React.FC = () => ( +const NotEnoughMemoryLabel = ({ unit }: { unit: string }) => ( - Not enough RAM + Not enough {unit} @@ -31,4 +31,4 @@ const NotEnoughRamLabel: React.FC = () => ( ) -export default React.memo(NotEnoughRamLabel) +export default React.memo(NotEnoughMemoryLabel) diff --git a/web/containers/ModelLabel/index.tsx b/web/containers/ModelLabel/index.tsx index 1cd9cbb85..54f2838af 100644 --- a/web/containers/ModelLabel/index.tsx +++ b/web/containers/ModelLabel/index.tsx @@ -4,13 +4,19 @@ import { useAtomValue } from 'jotai' import { useActiveModel } from '@/hooks/useActiveModel' -import NotEnoughRamLabel from './NotEnoughRamLabel' +import { useSettings } from '@/hooks/useSettings' + +import NotEnoughMemoryLabel from './NotEnoughMemoryLabel' import RecommendedLabel from './RecommendedLabel' import SlowOnYourDeviceLabel from './SlowOnYourDeviceLabel' -import { totalRamAtom, usedRamAtom } from '@/helpers/atoms/SystemBar.atom' +import { + availableVramAtom, + totalRamAtom, + usedRamAtom, +} from '@/helpers/atoms/SystemBar.atom' type Props = { size: number @@ -20,12 +26,21 @@ const ModelLabel: React.FC = ({ size }) => { const { activeModel } = useActiveModel() const totalRam = useAtomValue(totalRamAtom) const usedRam = useAtomValue(usedRamAtom) + const availableVram = useAtomValue(availableVramAtom) + const { settings } = useSettings() const getLabel = (size: number) => { const minimumRamModel = size * 1.25 - const availableRam = totalRam - usedRam + (activeModel?.metadata.size ?? 0) + const availableRam = + settings?.run_mode === 'gpu' + ? availableVram * 1000000 // MB to bytes + : totalRam - usedRam + (activeModel?.metadata.size ?? 0) if (minimumRamModel > totalRam) { - return + return ( + + ) } if (minimumRamModel < availableRam) { return diff --git a/web/helpers/atoms/SystemBar.atom.ts b/web/helpers/atoms/SystemBar.atom.ts index 5779ef822..ba91364ba 100644 --- a/web/helpers/atoms/SystemBar.atom.ts +++ b/web/helpers/atoms/SystemBar.atom.ts @@ -9,4 +9,5 @@ export const ramUtilitizedAtom = atom(0) export const gpusAtom = atom[]>([]) export const nvidiaTotalVramAtom = atom(0) +export const availableVramAtom = atom(0) export const systemMonitorCollapseAtom = atom(false) diff --git a/web/hooks/useGetSystemResources.ts b/web/hooks/useGetSystemResources.ts index ef2f30a61..877b652cb 100644 --- a/web/hooks/useGetSystemResources.ts +++ b/web/hooks/useGetSystemResources.ts @@ -12,6 +12,7 @@ import { nvidiaTotalVramAtom, gpusAtom, ramUtilitizedAtom, + availableVramAtom, } from '@/helpers/atoms/SystemBar.atom' export default function useGetSystemResources() { @@ -24,6 +25,7 @@ export default function useGetSystemResources() { const setUsedRam = useSetAtom(usedRamAtom) const setCpuUsage = useSetAtom(cpuUsageAtom) const setTotalNvidiaVram = useSetAtom(nvidiaTotalVramAtom) + const setAvailableVram = useSetAtom(availableVramAtom) const setRamUtilitized = useSetAtom(ramUtilitizedAtom) const getSystemResources = useCallback(async () => { @@ -64,6 +66,13 @@ export default function useGetSystemResources() { ) } setTotalNvidiaVram(totalNvidiaVram) + setAvailableVram( + gpus.reduce( + (total: number, gpu: { memoryFree: string }) => + total + Number(gpu.memoryFree), + 0 + ) + ) }, [ setUsedRam, setTotalRam, @@ -71,6 +80,7 @@ export default function useGetSystemResources() { setCpuUsage, setGpus, setTotalNvidiaVram, + setAvailableVram, ]) const watch = () => { diff --git a/web/hooks/useSettings.ts b/web/hooks/useSettings.ts index 378ca33fa..b3d9964d4 100644 --- a/web/hooks/useSettings.ts +++ b/web/hooks/useSettings.ts @@ -5,13 +5,24 @@ import { atom, useAtom } from 'jotai' export const isShowNotificationAtom = atom(false) +export type AppSettings = { + run_mode: 'cpu' | 'gpu' | undefined + notify: boolean + gpus_in_use: string[] + vulkan: boolean + gpus: string[] +} + export const useSettings = () => { const [isGPUModeEnabled, setIsGPUModeEnabled] = useState(false) // New state for GPU mode const [showNotification, setShowNotification] = useAtom( isShowNotificationAtom ) + const [settings, setSettings] = useState() useEffect(() => { + readSettings().then((settings) => setSettings(settings as AppSettings)) + setTimeout(() => validateSettings, 3000) // eslint-disable-next-line react-hooks/exhaustive-deps }, []) @@ -79,5 +90,6 @@ export const useSettings = () => { saveSettings, setShowNotification, validateSettings, + settings, } } diff --git a/web/screens/ExploreModels/ExploreModelItemHeader/index.tsx b/web/screens/ExploreModels/ExploreModelItemHeader/index.tsx index 465e69fa6..06444b402 100644 --- a/web/screens/ExploreModels/ExploreModelItemHeader/index.tsx +++ b/web/screens/ExploreModels/ExploreModelItemHeader/index.tsx @@ -24,6 +24,8 @@ import { MainViewState } from '@/constants/screens' import { useCreateNewThread } from '@/hooks/useCreateNewThread' import useDownloadModel from '@/hooks/useDownloadModel' +import { useSettings } from '@/hooks/useSettings' + import { toGibibytes } from '@/utils/converter' import { mainViewStateAtom } from '@/helpers/atoms/App.atom' @@ -45,11 +47,11 @@ type Props = { open: string } -const getLabel = (size: number, ram: number) => { +const getLabel = (size: number, ram: number, unit: string = 'RAM') => { if (size * 1.25 >= ram) { return ( - Not enough RAM + Not enough {unit} ) } else { @@ -67,13 +69,14 @@ const ExploreModelItemHeader: React.FC = ({ model, onClick, open }) => { const downloadedModels = useAtomValue(downloadedModelsAtom) const { requestCreateNewThread } = useCreateNewThread() const totalRam = useAtomValue(totalRamAtom) + const { settings } = useSettings() const nvidiaTotalVram = useAtomValue(nvidiaTotalVramAtom) const setMainViewState = useSetAtom(mainViewStateAtom) // Default nvidia returns vram in MB, need to convert to bytes to match the unit of totalRamW let ram = nvidiaTotalVram * 1024 * 1024 - if (ram === 0) { + if (ram === 0 || settings?.run_mode === 'cpu') { ram = totalRam } const serverEnabled = useAtomValue(serverEnabledAtom) @@ -158,7 +161,11 @@ const ExploreModelItemHeader: React.FC = ({ model, onClick, open }) => { {toGibibytes(model.metadata.size)} - {getLabel(model.metadata.size, ram)} + {getLabel( + model.metadata.size, + ram, + settings?.run_mode === 'gpu' ? 'VRAM' : 'RAM' + )} {downloadButton}