mirror of
https://github.com/invoke-ai/InvokeAI.git
synced 2026-02-16 12:05:25 -05:00
recall CLIP skip
This commit is contained in:
committed by
psychedelicious
parent
6e32c7993c
commit
3fd10b68cd
@@ -770,6 +770,7 @@
|
||||
"allPrompts": "All Prompts",
|
||||
"cfgScale": "CFG scale",
|
||||
"cfgRescaleMultiplier": "$t(parameters.cfgRescaleMultiplier)",
|
||||
"clipSkip": "$t(parameters.clipSkip)",
|
||||
"createdBy": "Created By",
|
||||
"generationMode": "Generation Mode",
|
||||
"guidance": "Guidance",
|
||||
@@ -1290,6 +1291,7 @@
|
||||
"remixImage": "Remix Image",
|
||||
"usePrompt": "Use Prompt",
|
||||
"useSeed": "Use Seed",
|
||||
"useClipSkip": "Use CLIP Skip",
|
||||
"width": "Width",
|
||||
"gaussianBlur": "Gaussian Blur",
|
||||
"boxBlur": "Box Blur",
|
||||
|
||||
@@ -16,6 +16,7 @@ import {
|
||||
rgRefImageImageChanged,
|
||||
} from 'features/controlLayers/store/canvasSlice';
|
||||
import {
|
||||
selectCLIPSkip,
|
||||
selectMainModelConfig,
|
||||
selectNegativePrompt,
|
||||
selectPositivePrompt,
|
||||
@@ -81,6 +82,7 @@ const useSaveCanvas = ({ region, saveToGallery, toastOk, toastError, onSave, wit
|
||||
|
||||
if (withMetadata) {
|
||||
metadata = selectCanvasMetadata(state);
|
||||
metadata.clip_skip = selectCLIPSkip(state);
|
||||
metadata.positive_prompt = selectPositivePrompt(state);
|
||||
metadata.negative_prompt = selectNegativePrompt(state);
|
||||
metadata.seed = selectSeed(state);
|
||||
|
||||
@@ -484,7 +484,7 @@ export const selectCFGScale = createParamsSelector((params) => params.cfgScale);
|
||||
export const selectGuidance = createParamsSelector((params) => params.guidance);
|
||||
export const selectSteps = createParamsSelector((params) => params.steps);
|
||||
export const selectCFGRescaleMultiplier = createParamsSelector((params) => params.cfgRescaleMultiplier);
|
||||
export const selectCLIPSKip = createParamsSelector((params) => params.clipSkip);
|
||||
export const selectCLIPSkip = createParamsSelector((params) => params.clipSkip);
|
||||
export const selectCanvasCoherenceEdgeSize = createParamsSelector((params) => params.canvasCoherenceEdgeSize);
|
||||
export const selectCanvasCoherenceMinDenoise = createParamsSelector((params) => params.canvasCoherenceMinDenoise);
|
||||
export const selectCanvasCoherenceMode = createParamsSelector((params) => params.canvasCoherenceMode);
|
||||
|
||||
@@ -2,6 +2,7 @@ import { Menu, MenuButton, MenuItem, MenuList } from '@invoke-ai/ui-library';
|
||||
import { SubMenuButtonContent, useSubMenu } from 'common/hooks/useSubMenu';
|
||||
import { useImageDTOContext } from 'features/gallery/contexts/ImageDTOContext';
|
||||
import { useRecallAll } from 'features/gallery/hooks/useRecallAll';
|
||||
import { useRecallCLIPSkip } from 'features/gallery/hooks/useRecallCLIPSkip';
|
||||
import { useRecallDimensions } from 'features/gallery/hooks/useRecallDimensions';
|
||||
import { useRecallPrompts } from 'features/gallery/hooks/useRecallPrompts';
|
||||
import { useRecallRemix } from 'features/gallery/hooks/useRecallRemix';
|
||||
@@ -28,6 +29,7 @@ export const ImageMenuItemMetadataRecallActionsCanvasGenerateTabs = memo(() => {
|
||||
const recallPrompts = useRecallPrompts(imageDTO);
|
||||
const recallSeed = useRecallSeed(imageDTO);
|
||||
const recallDimensions = useRecallDimensions(imageDTO);
|
||||
const recallCLIPSkip = useRecallCLIPSkip(imageDTO);
|
||||
|
||||
return (
|
||||
<MenuItem {...subMenu.parentMenuItemProps} icon={<PiArrowBendUpLeftBold />}>
|
||||
@@ -55,6 +57,9 @@ export const ImageMenuItemMetadataRecallActionsCanvasGenerateTabs = memo(() => {
|
||||
<MenuItem icon={<PiRulerBold />} onClick={recallDimensions.recall} isDisabled={!recallDimensions.isEnabled}>
|
||||
{t('parameters.useSize')}
|
||||
</MenuItem>
|
||||
<MenuItem icon={<PiRulerBold />} onClick={recallCLIPSkip.recall} isDisabled={!recallCLIPSkip.isEnabled}>
|
||||
{t('parameters.useClipSkip')}
|
||||
</MenuItem>
|
||||
</MenuList>
|
||||
</Menu>
|
||||
</MenuItem>
|
||||
|
||||
@@ -0,0 +1,65 @@
|
||||
import { useAppSelector, useAppStore } from 'app/store/storeHooks';
|
||||
import { MetadataHandlers, MetadataUtils } from 'features/metadata/parsing';
|
||||
import { selectActiveTab } from 'features/ui/store/uiSelectors';
|
||||
import type { TabName } from 'features/ui/store/uiTypes';
|
||||
import { useCallback, useEffect, useMemo, useState } from 'react';
|
||||
import { useDebouncedMetadata } from 'services/api/hooks/useDebouncedMetadata';
|
||||
import type { ImageDTO } from 'services/api/types';
|
||||
|
||||
const ALLOWED_TABS: TabName[] = ['canvas', 'generate', 'upscaling'];
|
||||
|
||||
export const useRecallCLIPSkip = (imageDTO: ImageDTO) => {
|
||||
const store = useAppStore();
|
||||
const tab = useAppSelector(selectActiveTab);
|
||||
const [hasCLIPSkip, setCLIPSkip] = useState(false);
|
||||
|
||||
const { metadata, isLoading } = useDebouncedMetadata(imageDTO.image_name);
|
||||
|
||||
useEffect(() => {
|
||||
const parse = async () => {
|
||||
try {
|
||||
await MetadataHandlers.CLIPSkip.parse(metadata, store);
|
||||
setCLIPSkip(true);
|
||||
} catch {
|
||||
setCLIPSkip(false);
|
||||
}
|
||||
};
|
||||
|
||||
parse();
|
||||
}, [metadata, store]);
|
||||
|
||||
const isEnabled = useMemo(() => {
|
||||
if (isLoading) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!ALLOWED_TABS.includes(tab)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!metadata) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!hasCLIPSkip) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}, [hasCLIPSkip, isLoading, metadata, tab]);
|
||||
|
||||
const recall = useCallback(() => {
|
||||
if (!metadata) {
|
||||
return;
|
||||
}
|
||||
if (!isEnabled) {
|
||||
return;
|
||||
}
|
||||
MetadataUtils.recallByHandler({ metadata, handler: MetadataHandlers.CLIPSkip, store });
|
||||
}, [metadata, isEnabled, store]);
|
||||
|
||||
return {
|
||||
recall,
|
||||
isEnabled,
|
||||
};
|
||||
};
|
||||
@@ -15,6 +15,7 @@ import {
|
||||
selectBase,
|
||||
setCfgRescaleMultiplier,
|
||||
setCfgScale,
|
||||
setClipSkip,
|
||||
setGuidance,
|
||||
setImg2imgStrength,
|
||||
setRefinerCFGScale,
|
||||
@@ -41,6 +42,7 @@ import { modelSelected } from 'features/parameters/store/actions';
|
||||
import type {
|
||||
ParameterCFGRescaleMultiplier,
|
||||
ParameterCFGScale,
|
||||
ParameterCLIPSkip,
|
||||
ParameterGuidance,
|
||||
ParameterHeight,
|
||||
ParameterModel,
|
||||
@@ -63,6 +65,7 @@ import {
|
||||
zLoRAWeight,
|
||||
zParameterCFGRescaleMultiplier,
|
||||
zParameterCFGScale,
|
||||
zParameterCLIPSkip,
|
||||
zParameterGuidance,
|
||||
zParameterImageDimension,
|
||||
zParameterNegativePrompt,
|
||||
@@ -321,6 +324,24 @@ const CFGRescaleMultiplier: SingleMetadataHandler<ParameterCFGRescaleMultiplier>
|
||||
};
|
||||
//#endregion CFG Rescale Multiplier
|
||||
|
||||
//#region CLIP Skip
|
||||
const CLIPSkip: SingleMetadataHandler<ParameterCLIPSkip> = {
|
||||
[SingleMetadataKey]: true,
|
||||
type: 'CLIPSkip',
|
||||
parse: (metadata, _store) => {
|
||||
const raw = getProperty(metadata, 'clip_skip');
|
||||
const parsed = zParameterCLIPSkip.parse(raw);
|
||||
return Promise.resolve(parsed);
|
||||
},
|
||||
recall: (value, store) => {
|
||||
store.dispatch(setClipSkip(value));
|
||||
},
|
||||
i18nKey: 'metadata.clipSkip',
|
||||
LabelComponent: MetadataLabel,
|
||||
ValueComponent: ({ value }: SingleMetadataValueProps<ParameterCLIPSkip>) => <MetadataPrimitiveValue value={value} />,
|
||||
};
|
||||
//#endregion CLIP Skip
|
||||
|
||||
//#region Guidance
|
||||
const Guidance: SingleMetadataHandler<ParameterGuidance> = {
|
||||
[SingleMetadataKey]: true,
|
||||
@@ -883,6 +904,7 @@ export const MetadataHandlers = {
|
||||
NegativePrompt,
|
||||
CFGScale,
|
||||
CFGRescaleMultiplier,
|
||||
CLIPSkip,
|
||||
Guidance,
|
||||
Scheduler,
|
||||
Width,
|
||||
|
||||
@@ -1,14 +1,14 @@
|
||||
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 { selectCLIPSKip, selectModel, setClipSkip } from 'features/controlLayers/store/paramsSlice';
|
||||
import { selectCLIPSkip, selectModel, setClipSkip } from 'features/controlLayers/store/paramsSlice';
|
||||
import { CLIP_SKIP_MAP } from 'features/parameters/types/constants';
|
||||
import { selectCLIPSkipConfig } from 'features/system/store/configSlice';
|
||||
import { memo, useCallback, useMemo } from 'react';
|
||||
import { useTranslation } from 'react-i18next';
|
||||
|
||||
const ParamClipSkip = () => {
|
||||
const clipSkip = useAppSelector(selectCLIPSKip);
|
||||
const clipSkip = useAppSelector(selectCLIPSkip);
|
||||
const config = useAppSelector(selectCLIPSkipConfig);
|
||||
const model = useAppSelector(selectModel);
|
||||
|
||||
|
||||
@@ -4,8 +4,6 @@ import { buildZodTypeGuard } from 'common/util/zodUtils';
|
||||
import { zModelIdentifierField, zSchedulerField } from 'features/nodes/types/common';
|
||||
import { z } from 'zod';
|
||||
|
||||
import { CLIP_SKIP_MAP } from './constants';
|
||||
|
||||
/**
|
||||
* Schemas, types and type guards for parameters.
|
||||
*
|
||||
@@ -196,20 +194,21 @@ export const [zLoRAWeight, isParameterLoRAWeight] = buildParameter(z.number());
|
||||
export type ParameterLoRAWeight = z.infer<typeof zLoRAWeight>;
|
||||
// #endregion
|
||||
|
||||
// #region Max. CLIP
|
||||
export const [zParameterMaxCLIP, isParameterMaxCLIP] = buildParameter(
|
||||
z.union([
|
||||
z.discriminatedUnion('model', [
|
||||
z.object({ model: z.literal('sd-1'), maxClip: z.number().min(0).max(CLIP_SKIP_MAP['sd-1'].maxClip) }),
|
||||
z.object({ model: z.literal('sd-2'), maxClip: z.number().min(0).max(CLIP_SKIP_MAP['sd-2'].maxClip) }),
|
||||
z.object({ model: z.literal('sdxl'), maxClip: z.number().min(0).max(CLIP_SKIP_MAP['sdxl'].maxClip) }),
|
||||
z.object({
|
||||
model: z.literal('sdxl-refiner'),
|
||||
maxClip: z.number().min(0).max(CLIP_SKIP_MAP['sdxl-refiner'].maxClip),
|
||||
}),
|
||||
]),
|
||||
z.object({ model: z.string(), maxClip: z.number().min(0).max(0) }),
|
||||
])
|
||||
);
|
||||
export type ParameterMaxCLIP = z.infer<typeof zParameterMaxCLIP>;
|
||||
// #region CLIP skip
|
||||
// export const [zParameterCLIPSkip, isParameterCLIPSkip] = buildParameter(
|
||||
// z.union([
|
||||
// z.discriminatedUnion('model', [
|
||||
// z.object({ model: z.literal('sd-1'), clipSkip: z.number().min(0).max(CLIP_SKIP_MAP['sd-1'].maxClip) }),
|
||||
// z.object({ model: z.literal('sd-2'), clipSkip: z.number().min(0).max(CLIP_SKIP_MAP['sd-2'].maxClip) }),
|
||||
// z.object({ model: z.literal('sdxl'), clipSkip: z.number().min(0).max(CLIP_SKIP_MAP['sdxl'].maxClip) }),
|
||||
// z.object({
|
||||
// model: z.literal('sdxl-refiner'),
|
||||
// clipSkip: z.number().min(0).max(CLIP_SKIP_MAP['sdxl-refiner'].maxClip),
|
||||
// }),
|
||||
// ]),
|
||||
// z.object({ model: z.string(), clipSkip: z.number().min(0).max(0) }),
|
||||
// ])
|
||||
// );
|
||||
export const [zParameterCLIPSkip, isParameterCLIPSkip] = buildParameter(z.number().int().min(0));
|
||||
export type ParameterCLIPSkip = z.infer<typeof zParameterCLIPSkip>;
|
||||
// #endregion
|
||||
|
||||
@@ -10292,6 +10292,11 @@ export type components = {
|
||||
* @description The id of the board the image belongs to, if one exists.
|
||||
*/
|
||||
board_id?: string | null;
|
||||
/**
|
||||
* Clip Skip
|
||||
* @description The number of skipped CLIP layers
|
||||
*/
|
||||
clip_skip?: number | null;
|
||||
};
|
||||
/**
|
||||
* ImageField
|
||||
|
||||
@@ -61,6 +61,7 @@ const _zImageDTO = z.object({
|
||||
starred: z.boolean(),
|
||||
has_workflow: z.boolean(),
|
||||
board_id: z.string().nullish(),
|
||||
clip_skip: z.number().int().min(0).nullish(),
|
||||
});
|
||||
export type ImageDTO = z.infer<typeof _zImageDTO>;
|
||||
assert<Equals<ImageDTO, S['ImageDTO']>>();
|
||||
|
||||
Reference in New Issue
Block a user