preliminary usable features

This commit is contained in:
josc146
2023-05-17 11:39:00 +08:00
parent 53502a8c3d
commit c947052574
21 changed files with 1187 additions and 1080 deletions

File diff suppressed because it is too large Load Diff

View File

@@ -9,26 +9,26 @@
"preview": "vite preview"
},
"dependencies": {
"@fluentui/react-components": "^9.19.1",
"@fluentui/react-components": "^9.20.0",
"@fluentui/react-icons": "^2.0.201",
"mobx": "^6.9.0",
"mobx-react-lite": "^3.4.3",
"react": "^18.2.0",
"react-dom": "^18.2.0",
"react-router": "^6.11.0",
"react-router-dom": "^6.11.0",
"react-toastify": "^9.1.2",
"react-router": "^6.11.1",
"react-router-dom": "^6.11.1",
"react-toastify": "^9.1.3",
"usehooks-ts": "^2.9.1"
},
"devDependencies": {
"@types/react": "^18.0.17",
"@types/react-dom": "^18.0.6",
"@vitejs/plugin-react": "^2.0.1",
"@types/react": "^18.2.6",
"@types/react-dom": "^18.2.4",
"@vitejs/plugin-react": "^4.0.0",
"autoprefixer": "^10.4.14",
"postcss": "^8.4.23",
"rollup-plugin-visualizer": "^5.9.0",
"tailwindcss": "^3.3.2",
"typescript": "^4.6.4",
"vite": "^3.0.7"
"typescript": "^5.0.4",
"vite": "^4.3.6"
}
}

View File

@@ -85,8 +85,9 @@ const App: FC = () => {
style={{
width: '250px'
}}
position="top-right"
position="top-center"
autoClose={4000}
hideProgressBar={true}
newestOnTop={true}
closeOnClick={false}
rtl={false}

View File

@@ -0,0 +1,34 @@
import commonStore, {ModelStatus} from '../stores/commonStore';
export const readRoot = async () => {
const port = commonStore.getCurrentModelConfig().apiParameters.apiPort;
return fetch(`http://127.0.0.1:${port}`);
};
export const exit = async () => {
commonStore.setModelStatus(ModelStatus.Offline);
const port = commonStore.getCurrentModelConfig().apiParameters.apiPort;
return fetch(`http://127.0.0.1:${port}/exit`, {method: 'POST'});
};
export const switchModel = async (body: any) => {
const port = commonStore.getCurrentModelConfig().apiParameters.apiPort;
return fetch(`http://127.0.0.1:${port}/switch-model`, {
method: 'POST',
headers: {
'Content-Type': 'application/json'
},
body: JSON.stringify(body)
});
};
export const updateConfig = async (body: any) => {
const port = commonStore.getCurrentModelConfig().apiParameters.apiPort;
return fetch(`http://127.0.0.1:${port}/update-config`, {
method: 'POST',
headers: {
'Content-Type': 'application/json'
},
body: JSON.stringify(body)
});
};

View File

@@ -1,8 +1,10 @@
import React, {FC} from 'react';
import React, {FC, MouseEventHandler} from 'react';
import commonStore, {ModelStatus} from '../stores/commonStore';
import {StartServer} from '../../wailsjs/go/backend_golang/App';
import {Button} from '@fluentui/react-components';
import {observer} from 'mobx-react-lite';
import {exit, readRoot, switchModel, updateConfig} from '../apis';
import {toast} from 'react-toastify';
const mainButtonText = {
[ModelStatus.Offline]: 'Run',
@@ -12,28 +14,42 @@ const mainButtonText = {
};
const onClickMainButton = async () => {
const modelConfig = commonStore.getCurrentModelConfig();
const port = modelConfig.apiParameters.apiPort;
if (commonStore.modelStatus === ModelStatus.Offline) {
commonStore.setModelStatus(ModelStatus.Starting);
StartServer(commonStore.getStrategy(), `models\\${commonStore.getCurrentModelConfig().modelParameters.modelName}`);
StartServer(port);
let timeoutCount = 5;
let timeoutCount = 6;
let loading = false;
const intervalId = setInterval(() => {
fetch('http://127.0.0.1:8000')
readRoot()
.then(r => {
if (r.ok && !loading) {
clearInterval(intervalId);
commonStore.setModelStatus(ModelStatus.Loading);
loading = true;
fetch('http://127.0.0.1:8000/update-config', {
method: 'POST',
headers: {
'Content-Type': 'application/json'
},
body: JSON.stringify({})
}).then(async (r) => {
if (r.ok)
toast('Loading Model', {type: 'info'});
updateConfig({
max_tokens: modelConfig.apiParameters.maxResponseToken,
temperature: modelConfig.apiParameters.temperature,
top_p: modelConfig.apiParameters.topP,
presence_penalty: modelConfig.apiParameters.presencePenalty,
frequency_penalty: modelConfig.apiParameters.frequencyPenalty
});
switchModel({
model: `models\\${modelConfig.modelParameters.modelName}`,
strategy: commonStore.getStrategy(modelConfig)
}).then((r) => {
if (r.ok) {
commonStore.setModelStatus(ModelStatus.Working);
} else if (r.status === 304) {
toast('Loading Model', {type: 'info'});
} else {
commonStore.setModelStatus(ModelStatus.Offline);
toast('Failed to switch model', {type: 'error'});
}
});
}
}).catch(() => {
@@ -46,15 +62,18 @@ const onClickMainButton = async () => {
timeoutCount--;
}, 1000);
} else {
commonStore.setModelStatus(ModelStatus.Offline);
fetch('http://127.0.0.1:8000/exit', {method: 'POST'});
exit();
}
};
export const RunButton: FC = observer(() => {
export const RunButton: FC<{ onClickRun?: MouseEventHandler }> = observer(({onClickRun}) => {
return (
<Button disabled={commonStore.modelStatus === ModelStatus.Starting} appearance="primary" size="large"
onClick={onClickMainButton}>
onClick={async (e) => {
if (commonStore.modelStatus === ModelStatus.Offline)
await onClickRun?.(e);
await onClickMainButton();
}}>
{mainButtonText[commonStore.modelStatus]}
</Button>
);

View File

@@ -12,6 +12,7 @@ import {NumberInput} from '../components/NumberInput';
import {Page} from '../components/Page';
import {useNavigate} from 'react-router';
import {RunButton} from '../components/RunButton';
import {updateConfig} from '../apis';
export const Configs: FC = observer(() => {
const [selectedIndex, setSelectedIndex] = React.useState(commonStore.currentModelConfigIndex);
@@ -49,6 +50,18 @@ export const Configs: FC = observer(() => {
});
};
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('Config Saved', {autoClose: 300, type: 'success'});
};
return (
<Page title="Configs" content={
<div className="flex flex-col gap-2 overflow-hidden">
@@ -72,10 +85,7 @@ export const Configs: FC = observer(() => {
commonStore.deleteModelConfig(selectedIndex);
updateSelectedIndex(Math.min(selectedIndex, commonStore.modelConfigs.length - 1));
}}/>
<ToolTipButton desc="Save Config" icon={<Save20Regular/>} onClick={() => {
commonStore.setModelConfig(selectedIndex, selectedConfig);
toast('Config Saved', {hideProgressBar: true, autoClose: 300, position: 'top-center'});
}}/>
<ToolTipButton desc="Save Config" icon={<Save20Regular/>} onClick={onClickSave}/>
</div>
<div className="flex items-center gap-4">
<Label>Config Name</Label>
@@ -89,7 +99,7 @@ export const Configs: FC = observer(() => {
desc="Hover your mouse over the text to view a detailed description. Settings marked with * will take effect immediately after being saved."
content={
<div className="grid grid-cols-1 sm:grid-cols-2 gap-2">
<Labeled label="API Port" desc="127.0.0.1:8000" content={
<Labeled label="API Port" desc={`127.0.0.1:${selectedConfig.apiParameters.apiPort}`} content={
<NumberInput value={selectedConfig.apiParameters.apiPort} min={1} max={65535} step={1}
onChange={(e, data) => {
setSelectedConfigApiParams({
@@ -130,11 +140,11 @@ export const Configs: FC = observer(() => {
});
}}/>
}/>
<Labeled label="Count Penalty *" content={
<ValuedSlider value={selectedConfig.apiParameters.countPenalty} min={-2} max={2} step={0.1} input
<Labeled label="Frequency Penalty *" content={
<ValuedSlider value={selectedConfig.apiParameters.frequencyPenalty} min={-2} max={2} step={0.1} input
onChange={(e, data) => {
setSelectedConfigApiParams({
countPenalty: data.value
frequencyPenalty: data.value
});
}}/>
}/>
@@ -193,12 +203,12 @@ export const Configs: FC = observer(() => {
<Option>fp32</Option>
</Dropdown>
}/>
<Labeled label="Streamed Layers" content={
<ValuedSlider value={selectedConfig.modelParameters.streamedLayers} min={0}
max={selectedConfig.modelParameters.maxStreamedLayers} step={1} input
<Labeled label="Stored Layers" content={
<ValuedSlider value={selectedConfig.modelParameters.storedLayers} min={0}
max={selectedConfig.modelParameters.maxStoredLayers} step={1} input
onChange={(e, data) => {
setSelectedConfigModelParams({
streamedLayers: data.value
storedLayers: data.value
});
}}/>
}/>
@@ -215,7 +225,7 @@ export const Configs: FC = observer(() => {
/>
</div>
<div className="flex flex-row-reverse sm:fixed bottom-2 right-2">
<RunButton/>
<RunButton onClickRun={onClickSave}/>
</div>
</div>
}/>

View File

@@ -11,6 +11,8 @@ import {useNavigate} from 'react-router';
import commonStore from '../stores/commonStore';
import {observer} from 'mobx-react-lite';
import {RunButton} from '../components/RunButton';
import manifest from '../../../manifest.json';
import {BrowserOpenURL} from '../../wailsjs/runtime';
type NavCard = {
label: string;
@@ -94,8 +96,8 @@ export const Home: FC = observer(() => {
</div>
</div>
<div className="flex gap-4 items-end">
Version: 1.0.0
<Link>Help</Link>
Version: {manifest.version}
<Link onClick={() => BrowserOpenURL('https://github.com/josStorer/RWKV-Runner')}>Help</Link>
</div>
</div>
</div>

View File

@@ -27,7 +27,7 @@ export type ApiParameters = {
temperature: number;
topP: number;
presencePenalty: number;
countPenalty: number;
frequencyPenalty: number;
}
export type Device = 'CPU' | 'CUDA';
@@ -38,8 +38,8 @@ export type ModelParameters = {
modelName: string;
device: Device;
precision: Precision;
streamedLayers: number;
maxStreamedLayers: number;
storedLayers: number;
maxStoredLayers: number;
enableHighPrecisionForLastLayer: boolean;
}
@@ -59,14 +59,14 @@ export const defaultModelConfigs: ModelConfig[] = [
temperature: 1,
topP: 1,
presencePenalty: 0,
countPenalty: 0
frequencyPenalty: 0
},
modelParameters: {
modelName: 'RWKV-4-Raven-1B5-v11-Eng99%-Other1%-20230425-ctx4096.pth',
device: 'CUDA',
precision: 'fp16',
streamedLayers: 25,
maxStreamedLayers: 25,
storedLayers: 25,
maxStoredLayers: 25,
enableHighPrecisionForLastLayer: false
}
}
@@ -98,8 +98,8 @@ class CommonStore {
let strategy = '';
strategy += (params.device === 'CPU' ? 'cpu' : 'cuda') + ' ';
strategy += (params.precision === 'fp16' ? 'fp16' : params.precision === 'int8' ? 'fp16i8' : 'fp32');
if (params.streamedLayers < params.maxStreamedLayers)
strategy += ` *${params.streamedLayers}+`;
if (params.storedLayers < params.maxStoredLayers)
strategy += ` *${params.storedLayers}+`;
if (params.enableHighPrecisionForLastLayer)
strategy += ' -> cpu fp32 *1';
return strategy;

View File

@@ -16,4 +16,4 @@ export function ReadJson(arg1:string):Promise<any>;
export function SaveJson(arg1:string,arg2:any):Promise<void>;
export function StartServer(arg1:string,arg2:string):Promise<string>;
export function StartServer(arg1:number):Promise<string>;

View File

@@ -30,6 +30,6 @@ export function SaveJson(arg1, arg2) {
return window['go']['backend_golang']['App']['SaveJson'](arg1, arg2);
}
export function StartServer(arg1, arg2) {
return window['go']['backend_golang']['App']['StartServer'](arg1, arg2);
export function StartServer(arg1) {
return window['go']['backend_golang']['App']['StartServer'](arg1);
}