import {Dropdown, Input, Label, Option, Select, Switch} from '@fluentui/react-components'; import {AddCircle20Regular, DataUsageSettings20Regular, Delete20Regular, Save20Regular} from '@fluentui/react-icons'; import React, {FC} from 'react'; import {Section} from '../components/Section'; import {Labeled} from '../components/Labeled'; import {ToolTipButton} from '../components/ToolTipButton'; import commonStore from '../stores/commonStore'; import {observer} from 'mobx-react-lite'; import {toast} from 'react-toastify'; import {ValuedSlider} from '../components/ValuedSlider'; import {NumberInput} from '../components/NumberInput'; import {Page} from '../components/Page'; import {useNavigate} from 'react-router'; import {RunButton} from '../components/RunButton'; import {updateConfig} from '../apis'; import {ConvertModel, FileExists} from '../../wailsjs/go/backend_golang/App'; import manifest from '../../../manifest.json'; import {getStrategy, refreshLocalModels} from '../utils'; import {useTranslation} from 'react-i18next'; export type ApiParameters = { apiPort: number maxResponseToken: number; temperature: number; topP: number; presencePenalty: number; frequencyPenalty: number; } export type Device = 'CPU' | 'CUDA'; export type Precision = 'fp16' | 'int8' | 'fp32'; export type ModelParameters = { // different models can not have the same name modelName: string; device: Device; precision: Precision; storedLayers: number; maxStoredLayers: number; enableHighPrecisionForLastLayer: boolean; } export type ModelConfig = { // different configs can have the same name name: string; apiParameters: ApiParameters modelParameters: ModelParameters } export const defaultModelConfigs: ModelConfig[] = [ { name: 'Default', apiParameters: { apiPort: 8000, maxResponseToken: 4100, temperature: 1, topP: 1, presencePenalty: 0, frequencyPenalty: 0 }, modelParameters: { modelName: 'RWKV-4-Raven-1B5-v11-Eng99%-Other1%-20230425-ctx4096.pth', device: 'CUDA', precision: 'fp16', storedLayers: 25, maxStoredLayers: 25, enableHighPrecisionForLastLayer: false } } ]; export const Configs: FC = observer(() => { const {t} = useTranslation(); const [selectedIndex, setSelectedIndex] = React.useState(commonStore.currentModelConfigIndex); const [selectedConfig, setSelectedConfig] = React.useState(commonStore.modelConfigs[selectedIndex]); const navigate = useNavigate(); const port = selectedConfig.apiParameters.apiPort; const updateSelectedIndex = (newIndex: number) => { setSelectedIndex(newIndex); setSelectedConfig(commonStore.modelConfigs[newIndex]); // if you don't want to update the config used by the current startup in real time, comment out this line commonStore.setCurrentConfigIndex(newIndex); }; const setSelectedConfigName = (newName: string) => { setSelectedConfig({...selectedConfig, name: newName}); }; const setSelectedConfigApiParams = (newParams: Partial) => { setSelectedConfig({ ...selectedConfig, apiParameters: { ...selectedConfig.apiParameters, ...newParams } }); }; const setSelectedConfigModelParams = (newParams: Partial) => { setSelectedConfig({ ...selectedConfig, modelParameters: { ...selectedConfig.modelParameters, ...newParams } }); }; const onClickSave = () => { commonStore.setModelConfig(selectedIndex, selectedConfig); updateConfig({ max_tokens: selectedConfig.apiParameters.maxResponseToken, temperature: selectedConfig.apiParameters.temperature, top_p: selectedConfig.apiParameters.topP, presence_penalty: selectedConfig.apiParameters.presencePenalty, frequency_penalty: selectedConfig.apiParameters.frequencyPenalty }); toast(t('Config Saved'), {autoClose: 300, type: 'success'}); }; return (
{ if (data.optionValue) { updateSelectedIndex(Number(data.optionValue)); } }}> {commonStore.modelConfigs.map((config, index) => )} } onClick={() => { commonStore.createModelConfig(); updateSelectedIndex(commonStore.modelConfigs.length - 1); }}/> } onClick={() => { commonStore.deleteModelConfig(selectedIndex); updateSelectedIndex(Math.min(selectedIndex, commonStore.modelConfigs.length - 1)); }}/> } onClick={onClickSave}/>
{ setSelectedConfigName(data.value); }}/>
{ setSelectedConfigApiParams({ apiPort: data.value }); }}/> }/> { setSelectedConfigApiParams({ maxResponseToken: data.value }); }}/> }/> { setSelectedConfigApiParams({ temperature: data.value }); }}/> }/> { setSelectedConfigApiParams({ topP: data.value }); }}/> }/> { setSelectedConfigApiParams({ presencePenalty: data.value }); }}/> }/> { setSelectedConfigApiParams({ frequencyPenalty: data.value }); }}/> }/>
} />
} onClick={() => { navigate({pathname: '/models'}); }}/> }/> { const modelPath = `${manifest.localModelDir}/${selectedConfig.modelParameters.modelName}`; if (await FileExists(modelPath)) { const strategy = getStrategy(selectedConfig); const newModelPath = modelPath + '-' + strategy.replace(/[> *+]/g, '-'); toast(t('Start Converting'), {autoClose: 1000, type: 'info'}); ConvertModel(modelPath, strategy, newModelPath).then(() => { toast(`${t('Convert Success')} - ${newModelPath}`, {type: 'success'}); refreshLocalModels({models: commonStore.modelSourceList}, false); }).catch(e => { toast(`${t('Convert Failed')} - ${e}`, {type: 'error'}); }); } else { toast(`${t('Model Not Found')} - ${modelPath}`, {type: 'error'}); } }}/> { if (data.optionText) { setSelectedConfigModelParams({ device: data.optionText as Device }); } }}> }/> { if (data.optionText) { setSelectedConfigModelParams({ precision: data.optionText as Precision }); } }}> }/> { setSelectedConfigModelParams({ storedLayers: data.value }); }}/> }/> { setSelectedConfigModelParams({ enableHighPrecisionForLastLayer: data.checked }); }}/> }/> } />
}/> ); });