feat: setting toggle vulkan (#5126)

* feat: setting toggle vulkan

* feat: add vulkan toggle setting

* chore: default flash attention disable

* chore: fix vulkan retrieval

* fix: vulkan setting does not affect engine run

* Update web-app/src/routes/settings/hardware.tsx

Co-authored-by: ellipsis-dev[bot] <65095814+ellipsis-dev[bot]@users.noreply.github.com>

---------

Co-authored-by: Louis <louis@jan.ai>
Co-authored-by: ellipsis-dev[bot] <65095814+ellipsis-dev[bot]@users.noreply.github.com>
This commit is contained in:
Faisal Amir 2025-06-03 13:56:23 +07:00 committed by GitHub
parent de9c59d309
commit 6861c46ac6
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
7 changed files with 75 additions and 7 deletions

View File

@ -271,8 +271,16 @@ export default class JanEngineManagementExtension extends EngineManagementExtens
* This is to use built-in engine variant in case there is no default engine set * This is to use built-in engine variant in case there is no default engine set
*/ */
async updateDefaultEngine() { async updateDefaultEngine() {
const systemInfo = await systemInformation()
try { try {
const variant = await this.getDefaultEngineVariant('llama-cpp') const variant = await this.getDefaultEngineVariant('llama-cpp')
if (
(systemInfo.gpuSetting.vulkan && !variant.variant.includes('vulkan')) ||
(systemInfo.gpuSetting.vulkan === false &&
variant.variant.includes('vulkan'))
) {
throw new EngineError('Switch engine.')
}
const installedEngines = await this.getInstalledEngines('llama-cpp') const installedEngines = await this.getInstalledEngines('llama-cpp')
if ( if (
!installedEngines.some( !installedEngines.some(
@ -289,7 +297,6 @@ export default class JanEngineManagementExtension extends EngineManagementExtens
(error instanceof HTTPError && error.response.status === 400) || (error instanceof HTTPError && error.response.status === 400) ||
error instanceof EngineError error instanceof EngineError
) { ) {
const systemInfo = await systemInformation()
const variant = await engineVariant(systemInfo.gpuSetting) const variant = await engineVariant(systemInfo.gpuSetting)
// TODO: Use correct provider name when moving to llama.cpp extension // TODO: Use correct provider name when moving to llama.cpp extension
await this.setDefaultEngineVariant('llama-cpp', { await this.setDefaultEngineVariant('llama-cpp', {

View File

@ -45,7 +45,9 @@ const os = (settings?: GpuSetting): string => {
* @param settings * @param settings
* @returns * @returns
*/ */
const cudaVersion = (settings?: GpuSetting): 'cu12.0' | 'cu11.7' | undefined => { const cudaVersion = (
settings?: GpuSetting
): 'cu12.0' | 'cu11.7' | undefined => {
return settings.gpus?.some((gpu) => gpu.version.includes('12')) return settings.gpus?.some((gpu) => gpu.version.includes('12'))
? 'cu12.0' ? 'cu12.0'
: 'cu11.7' : 'cu11.7'
@ -70,9 +72,9 @@ export const engineVariant = async (
const runMode = gpuRunMode(gpuSetting) const runMode = gpuRunMode(gpuSetting)
// Only Nvidia GPUs have addition_information set and activated by default // Only Nvidia GPUs have addition_information set and activated by default
let engineVariant = let engineVariant =
!gpuSetting?.vulkan || !gpuSetting?.vulkan &&
!gpuSetting.gpus?.length || (!gpuSetting.gpus?.length ||
gpuSetting.gpus.some((e) => e.additional_information && e.activated) gpuSetting.gpus.some((e) => e.additional_information && e.activated))
? [ ? [
platform, platform,
...(runMode === RunMode.Cuda ...(runMode === RunMode.Cuda

View File

@ -58,7 +58,7 @@
"description": "Optimizes memory usage and speeds up model inference using an efficient attention implementation.", "description": "Optimizes memory usage and speeds up model inference using an efficient attention implementation.",
"controllerType": "checkbox", "controllerType": "checkbox",
"controllerProps": { "controllerProps": {
"value": true "value": false
} }
}, },
{ {

View File

@ -10,6 +10,7 @@ export const localStorageKey = {
settingLocalApiServer: 'setting-local-api-server', settingLocalApiServer: 'setting-local-api-server',
settingProxyConfig: 'setting-proxy-config', settingProxyConfig: 'setting-proxy-config',
settingHardware: 'setting-hardware', settingHardware: 'setting-hardware',
settingVulkan: 'setting-vulkan',
productAnalyticPrompt: 'productAnalyticPrompt', productAnalyticPrompt: 'productAnalyticPrompt',
productAnalytic: 'productAnalytic', productAnalytic: 'productAnalytic',
toolApproval: 'tool-approval', toolApproval: 'tool-approval',

View File

@ -0,0 +1,34 @@
import { create } from 'zustand'
import { persist, createJSONStorage } from 'zustand/middleware'
import { localStorageKey } from '@/constants/localStorage'
interface VulkanStore {
// Vulkan state
vulkanEnabled: boolean
// Update functions
setVulkanEnabled: (enabled: boolean) => void
toggleVulkan: () => void
}
export const useVulkan = create<VulkanStore>()(
persist(
(set) => ({
vulkanEnabled: false,
setVulkanEnabled: (enabled) =>
set({
vulkanEnabled: enabled,
}),
toggleVulkan: () =>
set((state) => ({
vulkanEnabled: !state.vulkanEnabled,
})),
}),
{
name: localStorageKey.settingVulkan,
storage: createJSONStorage(() => localStorage),
}
)
)

View File

@ -6,6 +6,7 @@ import {
} from '@janhq/core' } from '@janhq/core'
import { invoke, InvokeArgs } from '@tauri-apps/api/core' import { invoke, InvokeArgs } from '@tauri-apps/api/core'
import { ExtensionManager } from './extension' import { ExtensionManager } from './extension'
import { useVulkan } from '@/hooks/useVulkan'
export const AppRoutes = [ export const AppRoutes = [
'installExtensions', 'installExtensions',
@ -54,7 +55,7 @@ export const systemInformation = async () => {
const gpuSettingInfo = { const gpuSettingInfo = {
gpus: hardwareInfo.gpus.filter((gpu) => gpu.total_vram > 0), gpus: hardwareInfo.gpus.filter((gpu) => gpu.total_vram > 0),
vulkan: false, vulkan: useVulkan.getState().vulkanEnabled,
cpu: hardwareInfo.cpu, cpu: hardwareInfo.cpu,
} }

View File

@ -7,6 +7,7 @@ import { Switch } from '@/components/ui/switch'
import { Progress } from '@/components/ui/progress' import { Progress } from '@/components/ui/progress'
import { useTranslation } from 'react-i18next' import { useTranslation } from 'react-i18next'
import { useHardware } from '@/hooks/useHardware' import { useHardware } from '@/hooks/useHardware'
import { useVulkan } from '@/hooks/useVulkan'
import type { GPU, HardwareData } from '@/hooks/useHardware' import type { GPU, HardwareData } from '@/hooks/useHardware'
import { useEffect } from 'react' import { useEffect } from 'react'
import { import {
@ -122,6 +123,7 @@ function Hardware() {
updateRAMAvailable, updateRAMAvailable,
reorderGPUs, reorderGPUs,
} = useHardware() } = useHardware()
const { vulkanEnabled, setVulkanEnabled } = useVulkan()
useEffect(() => { useEffect(() => {
getHardwareInfo().then((data) => getHardwareInfo().then((data) =>
@ -337,6 +339,27 @@ function Hardware() {
/> />
</Card> </Card>
{/* Vulkan Settings */}
<Card title="Vulkan">
<CardItem
title="Enable Vulkan"
description="Enable Vulkan API for GPU acceleration"
actions={
<div className="flex items-center gap-4">
<Switch
checked={vulkanEnabled}
onCheckedChange={(checked) => {
setVulkanEnabled(checked)
setTimeout(() => {
window.location.reload()
}, 500) // Reload after 500ms to apply changes
}}
/>
</div>
}
/>
</Card>
{/* GPU Information */} {/* GPU Information */}
<Card title="GPUs"> <Card title="GPUs">
{hardwareData.gpus.length > 0 ? ( {hardwareData.gpus.length > 0 ? (