feat(ui): separate upscaling settings so that tab does not inherit from main generation settings

This commit is contained in:
Mary Hipp
2025-02-12 11:32:54 -05:00
committed by Mary Hipp Rogers
parent b51312f1ba
commit 76618fee9c
5 changed files with 121 additions and 3 deletions

View File

@@ -49,6 +49,8 @@ export type ParamsState = {
optimizedDenoisingEnabled: boolean;
iterations: number;
scheduler: ParameterScheduler;
upscaleScheduler: ParameterScheduler;
upscaleCfgScale: ParameterCFGScale;
seed: ParameterSeed;
shouldRandomizeSeed: boolean;
steps: ParameterSteps;
@@ -96,6 +98,8 @@ const initialState: ParamsState = {
optimizedDenoisingEnabled: true,
iterations: 1,
scheduler: 'dpmpp_3m_k',
upscaleScheduler: 'dpmpp_3m_k',
upscaleCfgScale: 7.5,
seed: 0,
shouldRandomizeSeed: true,
steps: 30,
@@ -139,6 +143,9 @@ export const paramsSlice = createSlice({
setCfgScale: (state, action: PayloadAction<ParameterCFGScale>) => {
state.cfgScale = action.payload;
},
setUpscaleCfgScale: (state, action: PayloadAction<ParameterCFGScale>) => {
state.upscaleCfgScale = action.payload;
},
setGuidance: (state, action: PayloadAction<ParameterGuidance>) => {
state.guidance = action.payload;
},
@@ -148,6 +155,10 @@ export const paramsSlice = createSlice({
setScheduler: (state, action: PayloadAction<ParameterScheduler>) => {
state.scheduler = action.payload;
},
setUpscaleScheduler: (state, action: PayloadAction<ParameterScheduler>) => {
state.upscaleScheduler = action.payload;
},
setSeed: (state, action: PayloadAction<number>) => {
state.seed = action.payload;
state.shouldRandomizeSeed = false;
@@ -315,6 +326,8 @@ export const {
setCfgRescaleMultiplier,
setGuidance,
setScheduler,
setUpscaleScheduler,
setUpscaleCfgScale,
setSeed,
setImg2imgStrength,
setOptimizedDenoisingEnabled,
@@ -409,6 +422,9 @@ export const selectVAEPrecision = createParamsSelector((params) => params.vaePre
export const selectIterations = createParamsSelector((params) => params.iterations);
export const selectShouldUseCPUNoise = createParamsSelector((params) => params.shouldUseCpuNoise);
export const selectUpscaleScheduler = createParamsSelector((params) => params.upscaleScheduler);
export const selectUpscaleCfgScale = createParamsSelector((params) => params.upscaleCfgScale);
export const selectRefinerCFGScale = createParamsSelector((params) => params.refinerCFGScale);
export const selectRefinerModel = createParamsSelector((params) => params.refinerModel);
export const selectIsRefinerModelSelected = createParamsSelector((params) => Boolean(params.refinerModel));

View File

@@ -13,7 +13,15 @@ import { getBoardField, getPresetModifiedPrompts } from './graphBuilderUtils';
export const buildMultidiffusionUpscaleGraph = async (
state: RootState
): Promise<{ g: Graph; noise: Invocation<'noise'>; posCond: Invocation<'compel' | 'sdxl_compel_prompt'> }> => {
const { model, cfgScale: cfg_scale, scheduler, steps, vaePrecision, seed, vae } = state.params;
const {
model,
upscaleCfgScale: cfg_scale,
upscaleScheduler: scheduler,
steps,
vaePrecision,
seed,
vae,
} = state.params;
const { upscaleModel, upscaleInitialImage, structure, creativity, tileControlnetModel, scale } = state.upscale;
assert(model, 'No model found in state');

View File

@@ -0,0 +1,48 @@
import { CompositeNumberInput, CompositeSlider, FormControl, FormLabel } from '@invoke-ai/ui-library';
import { useAppDispatch, useAppSelector } from 'app/store/storeHooks';
import { InformationalPopover } from 'common/components/InformationalPopover/InformationalPopover';
import { selectUpscaleCfgScale, setUpscaleCfgScale } from 'features/controlLayers/store/paramsSlice';
import { selectCFGScaleConfig } from 'features/system/store/configSlice';
import { memo, useCallback, useMemo } from 'react';
import { useTranslation } from 'react-i18next';
const ParamUpscaleCFGScale = () => {
const cfgScale = useAppSelector(selectUpscaleCfgScale);
const config = useAppSelector(selectCFGScaleConfig);
const dispatch = useAppDispatch();
const { t } = useTranslation();
const marks = useMemo(
() => [config.sliderMin, Math.floor(config.sliderMax / 2), config.sliderMax],
[config.sliderMax, config.sliderMin]
);
const onChange = useCallback((v: number) => dispatch(setUpscaleCfgScale(v)), [dispatch]);
return (
<FormControl>
<InformationalPopover feature="paramCFGScale">
<FormLabel>{t('parameters.cfgScale')}</FormLabel>
</InformationalPopover>
<CompositeSlider
value={cfgScale}
defaultValue={config.initial}
min={config.sliderMin}
max={config.sliderMax}
step={config.coarseStep}
fineStep={config.fineStep}
onChange={onChange}
marks={marks}
/>
<CompositeNumberInput
value={cfgScale}
defaultValue={config.initial}
min={config.numberInputMin}
max={config.numberInputMax}
step={config.coarseStep}
fineStep={config.fineStep}
onChange={onChange}
/>
</FormControl>
);
};
export default memo(ParamUpscaleCFGScale);

View File

@@ -0,0 +1,38 @@
import type { ComboboxOnChange } from '@invoke-ai/ui-library';
import { Combobox, FormControl, FormLabel } from '@invoke-ai/ui-library';
import { useAppDispatch, useAppSelector } from 'app/store/storeHooks';
import { InformationalPopover } from 'common/components/InformationalPopover/InformationalPopover';
import { selectUpscaleScheduler, setUpscaleScheduler } from 'features/controlLayers/store/paramsSlice';
import { SCHEDULER_OPTIONS } from 'features/parameters/types/constants';
import { isParameterScheduler } from 'features/parameters/types/parameterSchemas';
import { memo, useCallback, useMemo } from 'react';
import { useTranslation } from 'react-i18next';
const ParamUpscaleScheduler = () => {
const dispatch = useAppDispatch();
const { t } = useTranslation();
const scheduler = useAppSelector(selectUpscaleScheduler);
const onChange = useCallback<ComboboxOnChange>(
(v) => {
if (!isParameterScheduler(v?.value)) {
return;
}
dispatch(setUpscaleScheduler(v.value));
},
[dispatch]
);
const value = useMemo(() => SCHEDULER_OPTIONS.find((o) => o.value === scheduler), [scheduler]);
return (
<FormControl>
<InformationalPopover feature="paramScheduler">
<FormLabel>{t('parameters.scheduler')}</FormLabel>
</InformationalPopover>
<Combobox value={value} options={SCHEDULER_OPTIONS} onChange={onChange} />
</FormControl>
);
};
export default memo(ParamUpscaleScheduler);

View File

@@ -14,6 +14,8 @@ import ParamSteps from 'features/parameters/components/Core/ParamSteps';
import { NavigateToModelManagerButton } from 'features/parameters/components/MainModel/NavigateToModelManagerButton';
import ParamMainModelSelect from 'features/parameters/components/MainModel/ParamMainModelSelect';
import { UseDefaultSettingsButton } from 'features/parameters/components/MainModel/UseDefaultSettingsButton';
import ParamUpscaleCFGScale from 'features/parameters/components/Upscale/ParamUpscaleCFGScale';
import ParamUpscaleScheduler from 'features/parameters/components/Upscale/ParamUpscaleScheduler';
import { useExpanderToggle } from 'features/settingsAccordions/hooks/useExpanderToggle';
import { useStandaloneAccordionToggle } from 'features/settingsAccordions/hooks/useStandaloneAccordionToggle';
import { selectActiveTab } from 'features/ui/store/uiSelectors';
@@ -31,6 +33,9 @@ export const GenerationSettingsAccordion = memo(() => {
const activeTabName = useAppSelector(selectActiveTab);
const isFLUX = useAppSelector(selectIsFLUX);
const isSD3 = useAppSelector(selectIsSD3);
const isUpscaling = useMemo(() => {
return activeTabName === 'upscaling';
}, [activeTabName]);
const selectBadges = useMemo(
() =>
createMemoizedSelector(selectLoRAsSlice, (loras) => {
@@ -75,9 +80,12 @@ export const GenerationSettingsAccordion = memo(() => {
<Expander label={t('accordions.advanced.options')} isOpen={isOpenExpander} onToggle={onToggleExpander}>
<Flex gap={4} flexDir="column" pb={4}>
<FormControlGroup formLabelProps={formLabelProps}>
{!isFLUX && !isSD3 && <ParamScheduler />}
{!isFLUX && !isSD3 && !isUpscaling && <ParamScheduler />}
{isUpscaling && <ParamUpscaleScheduler />}
<ParamSteps />
{isFLUX ? <ParamGuidance /> : <ParamCFGScale />}
{isFLUX && <ParamGuidance />}
{isUpscaling && <ParamUpscaleCFGScale />}
{!isFLUX && !isUpscaling && <ParamCFGScale />}
</FormControlGroup>
</Flex>
</Expander>