diff --git a/invokeai/app/invocations/metadata.py b/invokeai/app/invocations/metadata.py index 4f51bf10b8..d0549f8539 100644 --- a/invokeai/app/invocations/metadata.py +++ b/invokeai/app/invocations/metadata.py @@ -67,7 +67,10 @@ class CoreMetadata(BaseModelExcludeNull): ) refiner_steps: Union[int, None] = Field(default=None, description="The number of steps used for the refiner") refiner_scheduler: Union[str, None] = Field(default=None, description="The scheduler used for the refiner") - refiner_aesthetic_store: Union[float, None] = Field( + refiner_positive_aesthetic_store: Union[float, None] = Field( + default=None, description="The aesthetic score used for the refiner" + ) + refiner_negative_aesthetic_store: Union[float, None] = Field( default=None, description="The aesthetic score used for the refiner" ) refiner_start: Union[float, None] = Field(default=None, description="The start value used for refiner denoising") @@ -136,7 +139,10 @@ class MetadataAccumulatorInvocation(BaseInvocation): ) refiner_steps: Union[int, None] = Field(default=None, description="The number of steps used for the refiner") refiner_scheduler: Union[str, None] = Field(default=None, description="The scheduler used for the refiner") - refiner_aesthetic_store: Union[float, None] = Field( + refiner_positive_aesthetic_score: Union[float, None] = Field( + default=None, description="The aesthetic score used for the refiner" + ) + refiner_negative_aesthetic_score: Union[float, None] = Field( default=None, description="The aesthetic score used for the refiner" ) refiner_start: Union[float, None] = Field(default=None, description="The start value used for refiner denoising") diff --git a/invokeai/frontend/web/src/features/nodes/util/graphBuilders/addSDXLRefinerToGraph.ts b/invokeai/frontend/web/src/features/nodes/util/graphBuilders/addSDXLRefinerToGraph.ts index 53f068c91b..577f4e4b7d 100644 --- a/invokeai/frontend/web/src/features/nodes/util/graphBuilders/addSDXLRefinerToGraph.ts +++ b/invokeai/frontend/web/src/features/nodes/util/graphBuilders/addSDXLRefinerToGraph.ts @@ -25,7 +25,8 @@ export const addSDXLRefinerToGraph = ( ): void => { const { refinerModel, - refinerAestheticScore, + refinerPositiveAestheticScore, + refinerNegativeAestheticScore, refinerSteps, refinerScheduler, refinerCFGScale, @@ -40,7 +41,10 @@ export const addSDXLRefinerToGraph = ( if (metadataAccumulator) { metadataAccumulator.refiner_model = refinerModel; - metadataAccumulator.refiner_aesthetic_store = refinerAestheticScore; + metadataAccumulator.refiner_positive_aesthetic_score = + refinerPositiveAestheticScore; + metadataAccumulator.refiner_negative_aesthetic_score = + refinerNegativeAestheticScore; metadataAccumulator.refiner_cfg_scale = refinerCFGScale; metadataAccumulator.refiner_scheduler = refinerScheduler; metadataAccumulator.refiner_start = refinerStart; @@ -74,13 +78,13 @@ export const addSDXLRefinerToGraph = ( type: 'sdxl_refiner_compel_prompt', id: SDXL_REFINER_POSITIVE_CONDITIONING, style: craftedPositiveStylePrompt, - aesthetic_score: refinerAestheticScore, + aesthetic_score: refinerPositiveAestheticScore, }; graph.nodes[SDXL_REFINER_NEGATIVE_CONDITIONING] = { type: 'sdxl_refiner_compel_prompt', id: SDXL_REFINER_NEGATIVE_CONDITIONING, style: craftedNegativeStylePrompt, - aesthetic_score: refinerAestheticScore, + aesthetic_score: refinerNegativeAestheticScore, }; graph.nodes[SDXL_REFINER_DENOISE_LATENTS] = { type: 'denoise_latents', diff --git a/invokeai/frontend/web/src/features/parameters/hooks/useRecallParameters.ts b/invokeai/frontend/web/src/features/parameters/hooks/useRecallParameters.ts index 907107e95e..95caf9a9e1 100644 --- a/invokeai/frontend/web/src/features/parameters/hooks/useRecallParameters.ts +++ b/invokeai/frontend/web/src/features/parameters/hooks/useRecallParameters.ts @@ -4,16 +4,16 @@ import { refinerModelChanged, setNegativeStylePromptSDXL, setPositiveStylePromptSDXL, - setRefinerAestheticScore, setRefinerCFGScale, + setRefinerNegativeAestheticScore, + setRefinerPositiveAestheticScore, setRefinerScheduler, setRefinerStart, setRefinerSteps, } from 'features/sdxl/store/sdxlSlice'; import { useCallback } from 'react'; import { useTranslation } from 'react-i18next'; -import { UnsafeImageMetadata } from 'services/api/types'; -import { ImageDTO } from 'services/api/types'; +import { ImageDTO, UnsafeImageMetadata } from 'services/api/types'; import { initialImageSelected, modelSelected } from '../store/actions'; import { setCfgScale, @@ -34,8 +34,9 @@ import { isValidPositivePrompt, isValidSDXLNegativeStylePrompt, isValidSDXLPositiveStylePrompt, - isValidSDXLRefinerAestheticScore, isValidSDXLRefinerModel, + isValidSDXLRefinerNegativeAestheticScore, + isValidSDXLRefinerPositiveAestheticScore, isValidSDXLRefinerStart, isValidScheduler, isValidSeed, @@ -339,7 +340,8 @@ export const useRecallParameters = () => { refiner_cfg_scale, refiner_steps, refiner_scheduler, - refiner_aesthetic_store, + refiner_positive_aesthetic_store, + refiner_negative_aesthetic_store, refiner_start, } = metadata; @@ -398,8 +400,24 @@ export const useRecallParameters = () => { dispatch(setRefinerScheduler(refiner_scheduler)); } - if (isValidSDXLRefinerAestheticScore(refiner_aesthetic_store)) { - dispatch(setRefinerAestheticScore(refiner_aesthetic_store)); + if ( + isValidSDXLRefinerPositiveAestheticScore( + refiner_positive_aesthetic_store + ) + ) { + dispatch( + setRefinerPositiveAestheticScore(refiner_positive_aesthetic_store) + ); + } + + if ( + isValidSDXLRefinerNegativeAestheticScore( + refiner_negative_aesthetic_store + ) + ) { + dispatch( + setRefinerNegativeAestheticScore(refiner_negative_aesthetic_store) + ); } if (isValidSDXLRefinerStart(refiner_start)) { diff --git a/invokeai/frontend/web/src/features/parameters/types/parameterSchemas.ts b/invokeai/frontend/web/src/features/parameters/types/parameterSchemas.ts index 5221bf64a9..25905e1e14 100644 --- a/invokeai/frontend/web/src/features/parameters/types/parameterSchemas.ts +++ b/invokeai/frontend/web/src/features/parameters/types/parameterSchemas.ts @@ -353,22 +353,40 @@ export const isValidPrecision = (val: unknown): val is PrecisionParam => zPrecision.safeParse(val).success; /** - * Zod schema for SDXL refiner aesthetic score parameter + * Zod schema for SDXL refiner positive aesthetic score parameter */ -export const zSDXLRefinerAestheticScore = z.number().min(1).max(10); +export const zSDXLRefinerPositiveAestheticScore = z.number().min(1).max(10); /** - * Type alias for SDXL refiner aesthetic score parameter, inferred from its zod schema + * Type alias for SDXL refiner aesthetic positive score parameter, inferred from its zod schema */ -export type SDXLRefinerAestheticScoreParam = z.infer< - typeof zSDXLRefinerAestheticScore +export type SDXLRefinerPositiveAestheticScoreParam = z.infer< + typeof zSDXLRefinerPositiveAestheticScore >; /** - * Validates/type-guards a value as a SDXL refiner aesthetic score parameter + * Validates/type-guards a value as a SDXL refiner positive aesthetic score parameter */ -export const isValidSDXLRefinerAestheticScore = ( +export const isValidSDXLRefinerPositiveAestheticScore = ( val: unknown -): val is SDXLRefinerAestheticScoreParam => - zSDXLRefinerAestheticScore.safeParse(val).success; +): val is SDXLRefinerPositiveAestheticScoreParam => + zSDXLRefinerPositiveAestheticScore.safeParse(val).success; + +/** + * Zod schema for SDXL refiner negative aesthetic score parameter + */ +export const zSDXLRefinerNegativeAestheticScore = z.number().min(1).max(10); +/** + * Type alias for SDXL refiner aesthetic negative score parameter, inferred from its zod schema + */ +export type SDXLRefinerNegativeAestheticScoreParam = z.infer< + typeof zSDXLRefinerNegativeAestheticScore +>; +/** + * Validates/type-guards a value as a SDXL refiner negative aesthetic score parameter + */ +export const isValidSDXLRefinerNegativeAestheticScore = ( + val: unknown +): val is SDXLRefinerNegativeAestheticScoreParam => + zSDXLRefinerNegativeAestheticScore.safeParse(val).success; /** * Zod schema for SDXL start parameter diff --git a/invokeai/frontend/web/src/features/sdxl/components/ParamSDXLRefinerCollapse.tsx b/invokeai/frontend/web/src/features/sdxl/components/ParamSDXLRefinerCollapse.tsx index 37e1718dc6..3b186006f1 100644 --- a/invokeai/frontend/web/src/features/sdxl/components/ParamSDXLRefinerCollapse.tsx +++ b/invokeai/frontend/web/src/features/sdxl/components/ParamSDXLRefinerCollapse.tsx @@ -4,9 +4,10 @@ import { stateSelector } from 'app/store/store'; import { useAppSelector } from 'app/store/storeHooks'; import { defaultSelectorOptions } from 'app/store/util/defaultMemoizeOptions'; import IAICollapse from 'common/components/IAICollapse'; -import ParamSDXLRefinerAestheticScore from './SDXLRefiner/ParamSDXLRefinerAestheticScore'; import ParamSDXLRefinerCFGScale from './SDXLRefiner/ParamSDXLRefinerCFGScale'; import ParamSDXLRefinerModelSelect from './SDXLRefiner/ParamSDXLRefinerModelSelect'; +import ParamSDXLRefinerNegativeAestheticScore from './SDXLRefiner/ParamSDXLRefinerNegativeAestheticScore'; +import ParamSDXLRefinerPositiveAestheticScore from './SDXLRefiner/ParamSDXLRefinerPositiveAestheticScore'; import ParamSDXLRefinerScheduler from './SDXLRefiner/ParamSDXLRefinerScheduler'; import ParamSDXLRefinerStart from './SDXLRefiner/ParamSDXLRefinerStart'; import ParamSDXLRefinerSteps from './SDXLRefiner/ParamSDXLRefinerSteps'; @@ -38,7 +39,8 @@ const ParamSDXLRefinerCollapse = () => { - + + diff --git a/invokeai/frontend/web/src/features/sdxl/components/SDXLRefiner/ParamSDXLRefinerNegativeAestheticScore.tsx b/invokeai/frontend/web/src/features/sdxl/components/SDXLRefiner/ParamSDXLRefinerNegativeAestheticScore.tsx new file mode 100644 index 0000000000..4dad3f519a --- /dev/null +++ b/invokeai/frontend/web/src/features/sdxl/components/SDXLRefiner/ParamSDXLRefinerNegativeAestheticScore.tsx @@ -0,0 +1,60 @@ +import { createSelector } from '@reduxjs/toolkit'; +import { stateSelector } from 'app/store/store'; +import { useAppDispatch, useAppSelector } from 'app/store/storeHooks'; +import { defaultSelectorOptions } from 'app/store/util/defaultMemoizeOptions'; +import IAISlider from 'common/components/IAISlider'; +import { setRefinerNegativeAestheticScore } from 'features/sdxl/store/sdxlSlice'; +import { memo, useCallback } from 'react'; +import { useIsRefinerAvailable } from 'services/api/hooks/useIsRefinerAvailable'; + +const selector = createSelector( + [stateSelector], + ({ sdxl, hotkeys }) => { + const { refinerNegativeAestheticScore } = sdxl; + const { shift } = hotkeys; + + return { + refinerNegativeAestheticScore, + shift, + }; + }, + defaultSelectorOptions +); + +const ParamSDXLRefinerNegativeAestheticScore = () => { + const { refinerNegativeAestheticScore, shift } = useAppSelector(selector); + + const isRefinerAvailable = useIsRefinerAvailable(); + + const dispatch = useAppDispatch(); + + const handleChange = useCallback( + (v: number) => dispatch(setRefinerNegativeAestheticScore(v)), + [dispatch] + ); + + const handleReset = useCallback( + () => dispatch(setRefinerNegativeAestheticScore(2.5)), + [dispatch] + ); + + return ( + + ); +}; + +export default memo(ParamSDXLRefinerNegativeAestheticScore); diff --git a/invokeai/frontend/web/src/features/sdxl/components/SDXLRefiner/ParamSDXLRefinerAestheticScore.tsx b/invokeai/frontend/web/src/features/sdxl/components/SDXLRefiner/ParamSDXLRefinerPositiveAestheticScore.tsx similarity index 66% rename from invokeai/frontend/web/src/features/sdxl/components/SDXLRefiner/ParamSDXLRefinerAestheticScore.tsx rename to invokeai/frontend/web/src/features/sdxl/components/SDXLRefiner/ParamSDXLRefinerPositiveAestheticScore.tsx index 9c9c4b2f89..47842629f6 100644 --- a/invokeai/frontend/web/src/features/sdxl/components/SDXLRefiner/ParamSDXLRefinerAestheticScore.tsx +++ b/invokeai/frontend/web/src/features/sdxl/components/SDXLRefiner/ParamSDXLRefinerPositiveAestheticScore.tsx @@ -3,50 +3,50 @@ import { stateSelector } from 'app/store/store'; import { useAppDispatch, useAppSelector } from 'app/store/storeHooks'; import { defaultSelectorOptions } from 'app/store/util/defaultMemoizeOptions'; import IAISlider from 'common/components/IAISlider'; -import { setRefinerAestheticScore } from 'features/sdxl/store/sdxlSlice'; +import { setRefinerPositiveAestheticScore } from 'features/sdxl/store/sdxlSlice'; import { memo, useCallback } from 'react'; import { useIsRefinerAvailable } from 'services/api/hooks/useIsRefinerAvailable'; const selector = createSelector( [stateSelector], ({ sdxl, hotkeys }) => { - const { refinerAestheticScore } = sdxl; + const { refinerPositiveAestheticScore } = sdxl; const { shift } = hotkeys; return { - refinerAestheticScore, + refinerPositiveAestheticScore, shift, }; }, defaultSelectorOptions ); -const ParamSDXLRefinerAestheticScore = () => { - const { refinerAestheticScore, shift } = useAppSelector(selector); +const ParamSDXLRefinerPositiveAestheticScore = () => { + const { refinerPositiveAestheticScore, shift } = useAppSelector(selector); const isRefinerAvailable = useIsRefinerAvailable(); const dispatch = useAppDispatch(); const handleChange = useCallback( - (v: number) => dispatch(setRefinerAestheticScore(v)), + (v: number) => dispatch(setRefinerPositiveAestheticScore(v)), [dispatch] ); const handleReset = useCallback( - () => dispatch(setRefinerAestheticScore(6)), + () => dispatch(setRefinerPositiveAestheticScore(6)), [dispatch] ); return ( { ); }; -export default memo(ParamSDXLRefinerAestheticScore); +export default memo(ParamSDXLRefinerPositiveAestheticScore); diff --git a/invokeai/frontend/web/src/features/sdxl/store/sdxlSlice.ts b/invokeai/frontend/web/src/features/sdxl/store/sdxlSlice.ts index 7ee3ea1d4f..7670790f05 100644 --- a/invokeai/frontend/web/src/features/sdxl/store/sdxlSlice.ts +++ b/invokeai/frontend/web/src/features/sdxl/store/sdxlSlice.ts @@ -16,7 +16,8 @@ type SDXLInitialState = { refinerSteps: number; refinerCFGScale: number; refinerScheduler: SchedulerParam; - refinerAestheticScore: number; + refinerPositiveAestheticScore: number; + refinerNegativeAestheticScore: number; refinerStart: number; }; @@ -30,7 +31,8 @@ const sdxlInitialState: SDXLInitialState = { refinerSteps: 20, refinerCFGScale: 7.5, refinerScheduler: 'euler', - refinerAestheticScore: 6, + refinerPositiveAestheticScore: 6, + refinerNegativeAestheticScore: 2.5, refinerStart: 0.7, }; @@ -68,8 +70,17 @@ const sdxlSlice = createSlice({ setRefinerScheduler: (state, action: PayloadAction) => { state.refinerScheduler = action.payload; }, - setRefinerAestheticScore: (state, action: PayloadAction) => { - state.refinerAestheticScore = action.payload; + setRefinerPositiveAestheticScore: ( + state, + action: PayloadAction + ) => { + state.refinerPositiveAestheticScore = action.payload; + }, + setRefinerNegativeAestheticScore: ( + state, + action: PayloadAction + ) => { + state.refinerNegativeAestheticScore = action.payload; }, setRefinerStart: (state, action: PayloadAction) => { state.refinerStart = action.payload; @@ -87,7 +98,8 @@ export const { setRefinerSteps, setRefinerCFGScale, setRefinerScheduler, - setRefinerAestheticScore, + setRefinerPositiveAestheticScore, + setRefinerNegativeAestheticScore, setRefinerStart, } = sdxlSlice.actions; diff --git a/invokeai/frontend/web/src/services/api/schema.d.ts b/invokeai/frontend/web/src/services/api/schema.d.ts index a2076557b8..0bfa7c334f 100644 --- a/invokeai/frontend/web/src/services/api/schema.d.ts +++ b/invokeai/frontend/web/src/services/api/schema.d.ts @@ -1209,10 +1209,15 @@ export type components = { */ refiner_scheduler?: string; /** - * Refiner Aesthetic Store + * Refiner Positive Aesthetic Store * @description The aesthetic score used for the refiner */ - refiner_aesthetic_store?: number; + refiner_positive_aesthetic_store?: number; + /** + * Refiner Negative Aesthetic Store + * @description The aesthetic score used for the refiner + */ + refiner_negative_aesthetic_store?: number; /** * Refiner Start * @description The start value used for refiner denoising @@ -3599,10 +3604,15 @@ export type components = { */ refiner_scheduler?: string; /** - * Refiner Aesthetic Store + * Refiner Positive Aesthetic Score * @description The aesthetic score used for the refiner */ - refiner_aesthetic_store?: number; + refiner_positive_aesthetic_score?: number; + /** + * Refiner Negative Aesthetic Score + * @description The aesthetic score used for the refiner + */ + refiner_negative_aesthetic_score?: number; /** * Refiner Start * @description The start value used for refiner denoising @@ -5781,11 +5791,11 @@ export type components = { image?: components["schemas"]["ImageField"]; }; /** - * StableDiffusionOnnxModelFormat + * ControlNetModelFormat * @description An enumeration. * @enum {string} */ - StableDiffusionOnnxModelFormat: "olive" | "onnx"; + ControlNetModelFormat: "checkpoint" | "diffusers"; /** * StableDiffusion2ModelFormat * @description An enumeration. @@ -5793,23 +5803,23 @@ export type components = { */ StableDiffusion2ModelFormat: "checkpoint" | "diffusers"; /** - * ControlNetModelFormat + * StableDiffusionXLModelFormat * @description An enumeration. * @enum {string} */ - ControlNetModelFormat: "checkpoint" | "diffusers"; + StableDiffusionXLModelFormat: "checkpoint" | "diffusers"; + /** + * StableDiffusionOnnxModelFormat + * @description An enumeration. + * @enum {string} + */ + StableDiffusionOnnxModelFormat: "olive" | "onnx"; /** * StableDiffusion1ModelFormat * @description An enumeration. * @enum {string} */ StableDiffusion1ModelFormat: "checkpoint" | "diffusers"; - /** - * StableDiffusionXLModelFormat - * @description An enumeration. - * @enum {string} - */ - StableDiffusionXLModelFormat: "checkpoint" | "diffusers"; }; responses: never; parameters: never;