Skip to content

Commit

Permalink
feat(gui): load and merge server params with config
Browse files Browse the repository at this point in the history
  • Loading branch information
ssube committed Jan 10, 2023
1 parent 03fd728 commit 37efd51
Show file tree
Hide file tree
Showing 11 changed files with 144 additions and 144 deletions.
18 changes: 13 additions & 5 deletions gui/examples/config.json
Expand Up @@ -2,10 +2,18 @@
"api": {
"root": "http://127.0.0.1:5000"
},
"default": {
"model": "stable-diffusion-onnx-v1-5",
"platform": "amd",
"scheduler": "euler-a",
"prompt": "an astronaut eating a hamburger"
"params": {
"model": {
"default": "stable-diffusion-onnx-v1-5"
},
"platform": {
"default": "amd"
},
"scheduler": {
"default": "euler-a"
},
"prompt": {
"default": "an astronaut eating a hamburger"
}
}
}
2 changes: 2 additions & 0 deletions gui/package.json
Expand Up @@ -13,7 +13,9 @@
"@mui/icons-material": "^5.11.0",
"@mui/lab": "^5.0.0-alpha.114",
"@mui/material": "^5.11.3",
"@types/lodash": "^4.14.191",
"@types/node": "^18.11.18",
"lodash": "^4.17.21",
"noicejs": "^5.0.0-3",
"react": "^18.2.0",
"react-dom": "^18.2.0",
Expand Down
7 changes: 7 additions & 0 deletions gui/src/api/client.ts
@@ -1,4 +1,5 @@
import { doesExist, NotImplementedError } from '@apextoaster/js-utils';
import { ConfigParams } from '../config';

export interface BaseImgParams {
/**
Expand Down Expand Up @@ -57,6 +58,7 @@ export interface ApiResponse {

export interface ApiClient {
models(): Promise<Array<string>>;
params(): Promise<ConfigParams>;
platforms(): Promise<Array<string>>;
schedulers(): Promise<Array<string>>;

Expand Down Expand Up @@ -136,6 +138,11 @@ export function makeClient(root: string, f = fetch): ApiClient {
const res = await f(path);
return await res.json() as Array<string>;
},
async params(): Promise<ConfigParams> {
const path = new URL(joinPath('settings', 'params'), root);
const res = await f(path);
return await res.json() as ConfigParams;
},
async schedulers(): Promise<Array<string>> {
const path = new URL(joinPath('settings', 'schedulers'), root);
const res = await f(path);
Expand Down
52 changes: 29 additions & 23 deletions gui/src/components/ImageControl.tsx
@@ -1,28 +1,30 @@
import { doesExist } from '@apextoaster/js-utils';
import { Casino } from '@mui/icons-material';
import { IconButton, Stack, TextField } from '@mui/material';
import { Button, Stack, TextField } from '@mui/material';
import * as React from 'react';

import { BaseImgParams } from '../api/client.js';
import { CONFIG_DEFAULTS } from '../config.js';
import { ConfigParams } from '../config.js';
import { NumericField } from './NumericField.js';

export interface ImageControlProps {
config: ConfigParams;
params: BaseImgParams;

onChange?: (params: BaseImgParams) => void;
}

export function ImageControl(props: ImageControlProps) {
const { params } = props;
const { config, params } = props;

return <Stack spacing={2}>
<Stack direction='row' spacing={4}>
<NumericField
decimal
label='CFG'
min={CONFIG_DEFAULTS.cfg.min}
max={CONFIG_DEFAULTS.cfg.max}
step={CONFIG_DEFAULTS.cfg.step}
min={config.cfg.min}
max={config.cfg.max}
step={config.cfg.step}
value={params.cfg}
onChange={(cfg) => {
if (doesExist(props.onChange)) {
Expand All @@ -35,9 +37,9 @@ export function ImageControl(props: ImageControlProps) {
/>
<NumericField
label='Steps'
min={CONFIG_DEFAULTS.steps.min}
max={CONFIG_DEFAULTS.steps.max}
step={CONFIG_DEFAULTS.steps.step}
min={config.steps.min}
max={config.steps.max}
step={config.steps.step}
value={params.steps}
onChange={(steps) => {
if (doesExist(props.onChange)) {
Expand All @@ -50,9 +52,9 @@ export function ImageControl(props: ImageControlProps) {
/>
<NumericField
label='Seed'
min={CONFIG_DEFAULTS.seed.min}
max={CONFIG_DEFAULTS.seed.max}
step={CONFIG_DEFAULTS.seed.step}
min={config.seed.min}
max={config.seed.max}
step={config.seed.step}
value={params.seed}
onChange={(seed) => {
if (doesExist(props.onChange)) {
Expand All @@ -63,17 +65,21 @@ export function ImageControl(props: ImageControlProps) {
}
}}
/>
<IconButton onClick={() => {
const seed = Math.floor(Math.random() * CONFIG_DEFAULTS.seed.max);
if (doesExist(props.onChange)) {
props.onChange({
...params,
seed,
});
}
}}>
<Casino />
</IconButton>
<Button
variant='outlined'
startIcon={<Casino />}
onClick={() => {
const seed = Math.floor(Math.random() * config.seed.max);
if (doesExist(props.onChange)) {
props.onChange({
...params,
seed,
});
}
}}
>
New Seed
</Button>
</Stack>
<TextField label='Prompt' variant='outlined' value={params.prompt} onChange={(event) => {
if (doesExist(props.onChange)) {
Expand Down
24 changes: 12 additions & 12 deletions gui/src/components/Img2Img.tsx
Expand Up @@ -4,7 +4,7 @@ import * as React from 'react';
import { useMutation, useQuery } from 'react-query';

import { ApiClient, BaseImgParams } from '../api/client.js';
import { Config, CONFIG_DEFAULTS, IMAGE_FILTER, STALE_TIME } from '../config.js';
import { ConfigParams, IMAGE_FILTER, STALE_TIME } from '../config.js';
import { SCHEDULER_LABELS } from '../strings.js';
import { ImageInput } from './ImageInput.js';
import { ImageCard } from './ImageCard.js';
Expand All @@ -17,7 +17,7 @@ const { useState } = React;

export interface Img2ImgProps {
client: ApiClient;
config: Config;
config: ConfigParams;

model: string;
platform: string;
Expand All @@ -43,14 +43,14 @@ export function Img2Img(props: Img2ImgProps) {
});

const [source, setSource] = useState<File>();
const [strength, setStrength] = useState(CONFIG_DEFAULTS.strength.default);
const [strength, setStrength] = useState(config.strength.default);
const [params, setParams] = useState<BaseImgParams>({
cfg: CONFIG_DEFAULTS.cfg.default,
seed: CONFIG_DEFAULTS.seed.default,
steps: CONFIG_DEFAULTS.steps.default,
prompt: config.default.prompt,
cfg: config.cfg.default,
seed: config.seed.default,
steps: config.steps.default,
prompt: config.prompt.default,
});
const [scheduler, setScheduler] = useState(config.default.scheduler);
const [scheduler, setScheduler] = useState(config.scheduler.default);

return <Box>
<Stack spacing={2}>
Expand All @@ -67,15 +67,15 @@ export function Img2Img(props: Img2ImgProps) {
/>
</Stack>
<ImageInput filter={IMAGE_FILTER} label='Source' onChange={setSource} />
<ImageControl params={params} onChange={(newParams) => {
<ImageControl config={config} params={params} onChange={(newParams) => {
setParams(newParams);
}} />
<NumericField
decimal
label='Strength'
min={CONFIG_DEFAULTS.strength.min}
max={CONFIG_DEFAULTS.strength.max}
step={CONFIG_DEFAULTS.strength.step}
min={config.strength.min}
max={config.strength.max}
step={config.strength.step}
value={strength}
onChange={(value) => {
setStrength(value);
Expand Down
27 changes: 15 additions & 12 deletions gui/src/components/Inpaint.tsx
Expand Up @@ -5,7 +5,7 @@ import * as React from 'react';
import { useMutation, useQuery } from 'react-query';

import { ApiClient, ApiResponse, BaseImgParams, equalResponse } from '../api/client.js';
import { Config, CONFIG_DEFAULTS, DEFAULT_BRUSH, IMAGE_FILTER, STALE_TIME } from '../config.js';
import { Config, ConfigParams, DEFAULT_BRUSH, IMAGE_FILTER, STALE_TIME } from '../config.js';
import { SCHEDULER_LABELS } from '../strings.js';
import { ImageInput } from './ImageInput.js';
import { ImageCard } from './ImageCard.js';
Expand Down Expand Up @@ -57,7 +57,7 @@ export interface Point {

export interface InpaintProps {
client: ApiClient;
config: Config;
config: ConfigParams;

model: string;
platform: string;
Expand Down Expand Up @@ -166,12 +166,12 @@ export function Inpaint(props: InpaintProps) {
const [mask, setMask] = useState<File>();
const [source, setSource] = useState<File>();
const [params, setParams] = useState<BaseImgParams>({
cfg: CONFIG_DEFAULTS.cfg.default,
seed: CONFIG_DEFAULTS.seed.default,
steps: CONFIG_DEFAULTS.steps.default,
prompt: config.default.prompt,
cfg: config.cfg.default,
seed: config.seed.default,
steps: config.steps.default,
prompt: config.prompt.default,
});
const [scheduler, setScheduler] = useState(config.default.scheduler);
const [scheduler, setScheduler] = useState(config.scheduler.default);

useEffect(() => {
const canvas = mustExist(canvasRef.current);
Expand All @@ -190,11 +190,11 @@ export function Inpaint(props: InpaintProps) {
function renderCanvas() {
return <canvas
ref={canvasRef}
height={CONFIG_DEFAULTS.height.default}
width={CONFIG_DEFAULTS.width.default}
height={config.height.default}
width={config.width.default}
style={{
maxHeight: CONFIG_DEFAULTS.height.default,
maxWidth: CONFIG_DEFAULTS.width.default,
maxHeight: config.height.default,
maxWidth: config.width.default,
}}
onClick={(event) => {
const canvas = mustExist(canvasRef.current);
Expand Down Expand Up @@ -271,22 +271,25 @@ export function Inpaint(props: InpaintProps) {
}}
/>
<Button
variant='outlined'
startIcon={<FormatColorFill />}
onClick={() => floodMask(floodBelow)}>
Gray to black
</Button>
<Button
variant='outlined'
startIcon={<Gradient />}
onClick={() => grayscaleMask()}>
Grayscale
</Button>
<Button
variant='outlined'
startIcon={<FormatColorFill />}
onClick={() => floodMask(floodAbove)}>
Gray to white
</Button>
</Stack>
<ImageControl params={params} onChange={(newParams) => {
<ImageControl config={config} params={params} onChange={(newParams) => {
setParams(newParams);
}} />
<Button onClick={() => upload.mutate()}>Generate</Button>
Expand Down
8 changes: 4 additions & 4 deletions gui/src/components/OnnxWeb.tsx
Expand Up @@ -4,7 +4,7 @@ import * as React from 'react';
import { useQuery } from 'react-query';

import { ApiClient } from '../api/client.js';
import { Config, STALE_TIME } from '../config.js';
import { Config, ConfigParams, STALE_TIME } from '../config.js';
import { MODEL_LABELS, PLATFORM_LABELS } from '../strings.js';
import { Img2Img } from './Img2Img.js';
import { Inpaint } from './Inpaint.js';
Expand All @@ -15,15 +15,15 @@ const { useState } = React;

export interface OnnxWebProps {
client: ApiClient;
config: Config;
config: ConfigParams;
}

export function OnnxWeb(props: OnnxWebProps) {
const { client, config } = props;

const [tab, setTab] = useState('txt2img');
const [model, setModel] = useState(config.default.model);
const [platform, setPlatform] = useState(config.default.platform);
const [model, setModel] = useState(config.model.default);
const [platform, setPlatform] = useState(config.platform.default);

const models = useQuery('models', async () => client.models(), {
staleTime: STALE_TIME,
Expand Down
32 changes: 16 additions & 16 deletions gui/src/components/Txt2Img.tsx
Expand Up @@ -3,7 +3,7 @@ import * as React from 'react';
import { useMutation, useQuery } from 'react-query';

import { ApiClient, BaseImgParams } from '../api/client.js';
import { Config, CONFIG_DEFAULTS, STALE_TIME } from '../config.js';
import { ConfigParams, STALE_TIME } from '../config.js';
import { SCHEDULER_LABELS } from '../strings.js';
import { ImageCard } from './ImageCard.js';
import { ImageControl } from './ImageControl.js';
Expand All @@ -15,7 +15,7 @@ const { useState } = React;

export interface Txt2ImgProps {
client: ApiClient;
config: Config;
config: ConfigParams;

model: string;
platform: string;
Expand All @@ -40,15 +40,15 @@ export function Txt2Img(props: Txt2ImgProps) {
staleTime: STALE_TIME,
});

const [height, setHeight] = useState(CONFIG_DEFAULTS.height.default);
const [width, setWidth] = useState(CONFIG_DEFAULTS.width.default);
const [height, setHeight] = useState(config.height.default);
const [width, setWidth] = useState(config.width.default);
const [params, setParams] = useState<BaseImgParams>({
cfg: CONFIG_DEFAULTS.cfg.default,
seed: CONFIG_DEFAULTS.seed.default,
steps: CONFIG_DEFAULTS.steps.default,
prompt: config.default.prompt,
cfg: config.cfg.default,
seed: config.seed.default,
steps: config.steps.default,
prompt: config.prompt.default,
});
const [scheduler, setScheduler] = useState(config.default.scheduler);
const [scheduler, setScheduler] = useState(config.scheduler.default);

return <Box>
<Stack spacing={2}>
Expand All @@ -64,25 +64,25 @@ export function Txt2Img(props: Txt2ImgProps) {
}}
/>
</Stack>
<ImageControl params={params} onChange={(newParams) => {
<ImageControl config={config} params={params} onChange={(newParams) => {
setParams(newParams);
}} />
<Stack direction='row' spacing={4}>
<NumericField
label='Width'
min={CONFIG_DEFAULTS.width.min}
max={CONFIG_DEFAULTS.width.max}
step={CONFIG_DEFAULTS.width.step}
min={config.width.min}
max={config.width.max}
step={config.width.step}
value={width}
onChange={(value) => {
setWidth(value);
}}
/>
<NumericField
label='Height'
min={CONFIG_DEFAULTS.height.min}
max={CONFIG_DEFAULTS.height.max}
step={CONFIG_DEFAULTS.height.step}
min={config.height.min}
max={config.height.max}
step={config.height.step}
value={height}
onChange={(value) => {
setHeight(value);
Expand Down

0 comments on commit 37efd51

Please sign in to comment.