Merge branch 'main' into doc/manual-install-fixes

This commit is contained in:
Lincoln Stein 2023-02-09 21:55:21 -05:00 committed by GitHub
commit 35da7f5b96
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
20 changed files with 177 additions and 128 deletions

3
.gitignore vendored
View File

@ -1,4 +1,5 @@
# ignore default image save location and model symbolic link # ignore default image save location and model symbolic link
.idea/
embeddings/ embeddings/
outputs/ outputs/
models/ldm/stable-diffusion-v1/model.ckpt models/ldm/stable-diffusion-v1/model.ckpt
@ -232,4 +233,4 @@ installer/update.bat
installer/update.sh installer/update.sh
# no longer stored in source directory # no longer stored in source directory
models models

View File

@ -680,7 +680,8 @@ class InvokeAIWebServer:
image = self.esrgan.process( image = self.esrgan.process(
image=image, image=image,
upsampler_scale=postprocessing_parameters["upscale"][0], upsampler_scale=postprocessing_parameters["upscale"][0],
strength=postprocessing_parameters["upscale"][1], denoise_str=postprocessing_parameters["upscale"][1],
strength=postprocessing_parameters["upscale"][2],
seed=seed, seed=seed,
) )
elif postprocessing_parameters["type"] == "gfpgan": elif postprocessing_parameters["type"] == "gfpgan":
@ -1064,6 +1065,7 @@ class InvokeAIWebServer:
image = self.esrgan.process( image = self.esrgan.process(
image=image, image=image,
upsampler_scale=esrgan_parameters["level"], upsampler_scale=esrgan_parameters["level"],
denoise_str=esrgan_parameters['denoise_str'],
strength=esrgan_parameters["strength"], strength=esrgan_parameters["strength"],
seed=seed, seed=seed,
) )
@ -1071,6 +1073,7 @@ class InvokeAIWebServer:
postprocessing = True postprocessing = True
all_parameters["upscale"] = [ all_parameters["upscale"] = [
esrgan_parameters["level"], esrgan_parameters["level"],
esrgan_parameters['denoise_str'],
esrgan_parameters["strength"], esrgan_parameters["strength"],
] ]
@ -1287,7 +1290,8 @@ class InvokeAIWebServer:
{ {
"type": "esrgan", "type": "esrgan",
"scale": int(parameters["upscale"][0]), "scale": int(parameters["upscale"][0]),
"strength": float(parameters["upscale"][1]), "denoise_str": int(parameters["upscale"][1]),
"strength": float(parameters["upscale"][2]),
} }
) )
@ -1361,7 +1365,8 @@ class InvokeAIWebServer:
if parameters["type"] == "esrgan": if parameters["type"] == "esrgan":
postprocessing_metadata["type"] = "esrgan" postprocessing_metadata["type"] = "esrgan"
postprocessing_metadata["scale"] = parameters["upscale"][0] postprocessing_metadata["scale"] = parameters["upscale"][0]
postprocessing_metadata["strength"] = parameters["upscale"][1] postprocessing_metadata["denoise_str"] = parameters["upscale"][1]
postprocessing_metadata["strength"] = parameters["upscale"][2]
elif parameters["type"] == "gfpgan": elif parameters["type"] == "gfpgan":
postprocessing_metadata["type"] = "gfpgan" postprocessing_metadata["type"] = "gfpgan"
postprocessing_metadata["strength"] = parameters["facetool_strength"] postprocessing_metadata["strength"] = parameters["facetool_strength"]

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View File

@ -5,8 +5,8 @@
<meta name="viewport" content="width=device-width, initial-scale=1.0" /> <meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>InvokeAI - A Stable Diffusion Toolkit</title> <title>InvokeAI - A Stable Diffusion Toolkit</title>
<link rel="shortcut icon" type="icon" href="./assets/favicon-0d253ced.ico" /> <link rel="shortcut icon" type="icon" href="./assets/favicon-0d253ced.ico" />
<script type="module" crossorigin src="./assets/index-252612ad.js"></script> <script type="module" crossorigin src="./assets/index-ad762ffd.js"></script>
<link rel="stylesheet" href="./assets/index-b0bf79f4.css"> <link rel="stylesheet" href="./assets/index-fecb6dd4.css">
</head> </head>
<body> <body>

View File

@ -20,6 +20,7 @@
"upscaling": "Upscaling", "upscaling": "Upscaling",
"upscale": "Upscale", "upscale": "Upscale",
"upscaleImage": "Upscale Image", "upscaleImage": "Upscale Image",
"denoisingStrength": "Denoising Strength",
"scale": "Scale", "scale": "Scale",
"otherOptions": "Other Options", "otherOptions": "Other Options",
"seamlessTiling": "Seamless Tiling", "seamlessTiling": "Seamless Tiling",

View File

@ -20,6 +20,7 @@
"upscaling": "Upscaling", "upscaling": "Upscaling",
"upscale": "Upscale", "upscale": "Upscale",
"upscaleImage": "Upscale Image", "upscaleImage": "Upscale Image",
"denoisingStrength": "Denoising Strength",
"scale": "Scale", "scale": "Scale",
"otherOptions": "Other Options", "otherOptions": "Other Options",
"seamlessTiling": "Seamless Tiling", "seamlessTiling": "Seamless Tiling",

View File

@ -92,6 +92,7 @@ export declare type ESRGANMetadata = CommonPostProcessedImageMetadata & {
type: 'esrgan'; type: 'esrgan';
scale: 2 | 4; scale: 2 | 4;
strength: number; strength: number;
denoise_str: number;
}; };
export declare type FacetoolMetadata = CommonPostProcessedImageMetadata & { export declare type FacetoolMetadata = CommonPostProcessedImageMetadata & {

View File

@ -93,11 +93,15 @@ const makeSocketIOEmitters = (
dispatch(setIsProcessing(true)); dispatch(setIsProcessing(true));
const { const {
postprocessing: { upscalingLevel, upscalingStrength }, postprocessing: {
upscalingLevel,
upscalingDenoising,
upscalingStrength,
},
} = getState(); } = getState();
const esrganParameters = { const esrganParameters = {
upscale: [upscalingLevel, upscalingStrength], upscale: [upscalingLevel, upscalingDenoising, upscalingStrength],
}; };
socketio.emit('runPostprocessing', imageToProcess, { socketio.emit('runPostprocessing', imageToProcess, {
type: 'esrgan', type: 'esrgan',

View File

@ -69,6 +69,7 @@ export type BackendGenerationParameters = {
export type BackendEsrGanParameters = { export type BackendEsrGanParameters = {
level: UpscalingLevel; level: UpscalingLevel;
denoise_str: number;
strength: number; strength: number;
}; };
@ -111,13 +112,12 @@ export const frontendToBackendParameters = (
shouldRunFacetool, shouldRunFacetool,
upscalingLevel, upscalingLevel,
upscalingStrength, upscalingStrength,
upscalingDenoising,
} = postprocessingState; } = postprocessingState;
const { const {
cfgScale, cfgScale,
height, height,
img2imgStrength, img2imgStrength,
infillMethod, infillMethod,
initialImage, initialImage,
@ -136,11 +136,9 @@ export const frontendToBackendParameters = (
shouldFitToWidthHeight, shouldFitToWidthHeight,
shouldGenerateVariations, shouldGenerateVariations,
shouldRandomizeSeed, shouldRandomizeSeed,
steps, steps,
threshold, threshold,
tileSize, tileSize,
variationAmount, variationAmount,
width, width,
} = generationState; } = generationState;
@ -190,6 +188,7 @@ export const frontendToBackendParameters = (
if (shouldRunESRGAN) { if (shouldRunESRGAN) {
esrganParameters = { esrganParameters = {
level: upscalingLevel, level: upscalingLevel,
denoise_str: upscalingDenoising,
strength: upscalingStrength, strength: upscalingStrength,
}; };
} }

View File

@ -34,6 +34,7 @@ import {
setFacetoolStrength, setFacetoolStrength,
setFacetoolType, setFacetoolType,
setHiresFix, setHiresFix,
setUpscalingDenoising,
setUpscalingLevel, setUpscalingLevel,
setUpscalingStrength, setUpscalingStrength,
} from 'features/parameters/store/postprocessingSlice'; } from 'features/parameters/store/postprocessingSlice';
@ -147,11 +148,11 @@ const ImageMetadataViewer = memo(
postprocessing, postprocessing,
prompt, prompt,
sampler, sampler,
scale,
seamless, seamless,
seed, seed,
steps, steps,
strength, strength,
denoise_str,
threshold, threshold,
type, type,
variations, variations,
@ -184,27 +185,6 @@ const ImageMetadataViewer = memo(
{['esrgan', 'gfpgan'].includes(type) && ( {['esrgan', 'gfpgan'].includes(type) && (
<MetadataItem label="Original image" value={orig_path} /> <MetadataItem label="Original image" value={orig_path} />
)} )}
{type === 'gfpgan' && strength !== undefined && (
<MetadataItem
label="Fix faces strength"
value={strength}
onClick={() => dispatch(setFacetoolStrength(strength))}
/>
)}
{type === 'esrgan' && scale !== undefined && (
<MetadataItem
label="Upscaling scale"
value={scale}
onClick={() => dispatch(setUpscalingLevel(scale))}
/>
)}
{type === 'esrgan' && strength !== undefined && (
<MetadataItem
label="Upscaling strength"
value={strength}
onClick={() => dispatch(setUpscalingStrength(strength))}
/>
)}
{prompt && ( {prompt && (
<MetadataItem <MetadataItem
label="Prompt" label="Prompt"
@ -331,7 +311,7 @@ const ImageMetadataViewer = memo(
i: number i: number
) => { ) => {
if (postprocess.type === 'esrgan') { if (postprocess.type === 'esrgan') {
const { scale, strength } = postprocess; const { scale, strength, denoise_str } = postprocess;
return ( return (
<Flex <Flex
key={i} key={i}
@ -354,6 +334,15 @@ const ImageMetadataViewer = memo(
dispatch(setUpscalingStrength(strength)) dispatch(setUpscalingStrength(strength))
} }
/> />
{denoise_str !== undefined && (
<MetadataItem
label="Denoising strength"
value={denoise_str}
onClick={() =>
dispatch(setUpscalingDenoising(denoise_str))
}
/>
)}
</Flex> </Flex>
); );
} else if (postprocess.type === 'gfpgan') { } else if (postprocess.type === 'gfpgan') {

View File

@ -1,5 +0,0 @@
.upscale-settings {
display: grid;
grid-template-columns: auto 1fr;
column-gap: 1rem;
}

View File

@ -1,6 +1,7 @@
import { useAppDispatch, useAppSelector } from 'app/storeHooks'; import { useAppDispatch, useAppSelector } from 'app/storeHooks';
import { import {
setUpscalingDenoising,
setUpscalingLevel, setUpscalingLevel,
setUpscalingStrength, setUpscalingStrength,
UpscalingLevel, UpscalingLevel,
@ -8,20 +9,25 @@ import {
import { createSelector } from '@reduxjs/toolkit'; import { createSelector } from '@reduxjs/toolkit';
import { UPSCALING_LEVELS } from 'app/constants'; import { UPSCALING_LEVELS } from 'app/constants';
import IAINumberInput from 'common/components/IAINumberInput';
import IAISelect from 'common/components/IAISelect'; import IAISelect from 'common/components/IAISelect';
import { postprocessingSelector } from 'features/parameters/store/postprocessingSelectors'; import { postprocessingSelector } from 'features/parameters/store/postprocessingSelectors';
import { systemSelector } from 'features/system/store/systemSelectors'; import { systemSelector } from 'features/system/store/systemSelectors';
import { isEqual } from 'lodash'; import { isEqual } from 'lodash';
import { ChangeEvent } from 'react'; import { ChangeEvent } from 'react';
import { useTranslation } from 'react-i18next'; import { useTranslation } from 'react-i18next';
import IAISlider from 'common/components/IAISlider';
import { Flex } from '@chakra-ui/react';
const parametersSelector = createSelector( const parametersSelector = createSelector(
[postprocessingSelector, systemSelector], [postprocessingSelector, systemSelector],
({ upscalingLevel, upscalingStrength }, { isESRGANAvailable }) => { (
{ upscalingLevel, upscalingStrength, upscalingDenoising },
{ isESRGANAvailable }
) => {
return { return {
upscalingLevel, upscalingLevel,
upscalingDenoising,
upscalingStrength, upscalingStrength,
isESRGANAvailable, isESRGANAvailable,
}; };
@ -38,8 +44,12 @@ const parametersSelector = createSelector(
*/ */
const UpscaleSettings = () => { const UpscaleSettings = () => {
const dispatch = useAppDispatch(); const dispatch = useAppDispatch();
const { upscalingLevel, upscalingStrength, isESRGANAvailable } = const {
useAppSelector(parametersSelector); upscalingLevel,
upscalingStrength,
upscalingDenoising,
isESRGANAvailable,
} = useAppSelector(parametersSelector);
const { t } = useTranslation(); const { t } = useTranslation();
@ -49,7 +59,7 @@ const UpscaleSettings = () => {
const handleChangeStrength = (v: number) => dispatch(setUpscalingStrength(v)); const handleChangeStrength = (v: number) => dispatch(setUpscalingStrength(v));
return ( return (
<div className="upscale-settings"> <Flex flexDir="column" rowGap="1rem" minWidth="20rem">
<IAISelect <IAISelect
isDisabled={!isESRGANAvailable} isDisabled={!isESRGANAvailable}
label={t('parameters:scale')} label={t('parameters:scale')}
@ -57,17 +67,39 @@ const UpscaleSettings = () => {
onChange={handleChangeLevel} onChange={handleChangeLevel}
validValues={UPSCALING_LEVELS} validValues={UPSCALING_LEVELS}
/> />
<IAINumberInput <IAISlider
isDisabled={!isESRGANAvailable} label={t('parameters:denoisingStrength')}
label={t('parameters:strength')} value={upscalingDenoising}
step={0.05}
min={0} min={0}
max={1} max={1}
onChange={handleChangeStrength} step={0.01}
value={upscalingStrength} onChange={(v) => {
isInteger={false} dispatch(setUpscalingDenoising(v));
}}
handleReset={() => dispatch(setUpscalingDenoising(0.75))}
withSliderMarks
withInput
withReset
isSliderDisabled={!isESRGANAvailable}
isInputDisabled={!isESRGANAvailable}
isResetDisabled={!isESRGANAvailable}
/> />
</div> <IAISlider
label={`${t('parameters:upscale')} ${t('parameters:strength')}`}
value={upscalingStrength}
min={0}
max={1}
step={0.05}
onChange={handleChangeStrength}
handleReset={() => dispatch(setUpscalingStrength(0.75))}
withSliderMarks
withInput
withReset
isSliderDisabled={!isESRGANAvailable}
isInputDisabled={!isESRGANAvailable}
isResetDisabled={!isESRGANAvailable}
/>
</Flex>
); );
}; };

View File

@ -16,6 +16,7 @@ export interface PostprocessingState {
shouldRunESRGAN: boolean; shouldRunESRGAN: boolean;
shouldRunFacetool: boolean; shouldRunFacetool: boolean;
upscalingLevel: UpscalingLevel; upscalingLevel: UpscalingLevel;
upscalingDenoising: number;
upscalingStrength: number; upscalingStrength: number;
} }
@ -29,6 +30,7 @@ const initialPostprocessingState: PostprocessingState = {
shouldRunESRGAN: false, shouldRunESRGAN: false,
shouldRunFacetool: false, shouldRunFacetool: false,
upscalingLevel: 4, upscalingLevel: 4,
upscalingDenoising: 0.75,
upscalingStrength: 0.75, upscalingStrength: 0.75,
}; };
@ -47,6 +49,9 @@ export const postprocessingSlice = createSlice({
setUpscalingLevel: (state, action: PayloadAction<UpscalingLevel>) => { setUpscalingLevel: (state, action: PayloadAction<UpscalingLevel>) => {
state.upscalingLevel = action.payload; state.upscalingLevel = action.payload;
}, },
setUpscalingDenoising: (state, action: PayloadAction<number>) => {
state.upscalingDenoising = action.payload;
},
setUpscalingStrength: (state, action: PayloadAction<number>) => { setUpscalingStrength: (state, action: PayloadAction<number>) => {
state.upscalingStrength = action.payload; state.upscalingStrength = action.payload;
}, },
@ -88,6 +93,7 @@ export const {
setShouldRunESRGAN, setShouldRunESRGAN,
setShouldRunFacetool, setShouldRunFacetool,
setUpscalingLevel, setUpscalingLevel,
setUpscalingDenoising,
setUpscalingStrength, setUpscalingStrength,
} = postprocessingSlice.actions; } = postprocessingSlice.actions;

View File

@ -27,7 +27,6 @@
@use '../features/parameters/components/ProcessButtons/ProcessButtons.scss'; @use '../features/parameters/components/ProcessButtons/ProcessButtons.scss';
@use '../features/parameters/components/MainParameters/MainParameters.scss'; @use '../features/parameters/components/MainParameters/MainParameters.scss';
@use '../features/parameters/components/AccordionItems/AdvancedSettings.scss'; @use '../features/parameters/components/AccordionItems/AdvancedSettings.scss';
@use '../features/parameters/components/AdvancedParameters/Upscale/UpscaleSettings.scss';
@use '../features/parameters/components/AdvancedParameters/Canvas/BoundingBox/BoundingBoxSettings.scss'; @use '../features/parameters/components/AdvancedParameters/Canvas/BoundingBox/BoundingBoxSettings.scss';
// gallery // gallery

File diff suppressed because one or more lines are too long

View File

@ -671,6 +671,12 @@ class Args(object):
default=400, default=400,
help='Tile size for background sampler, 0 for no tile during testing. Default: 400.', help='Tile size for background sampler, 0 for no tile during testing. Default: 400.',
) )
postprocessing_group.add_argument(
'--esrgan_denoise_str',
type=float,
default=0.75,
help='esrgan denoise str. 0 is no denoise, 1 is max denoise. Default: 0.75',
)
postprocessing_group.add_argument( postprocessing_group.add_argument(
'--gfpgan_model_path', '--gfpgan_model_path',
type=str, type=str,

View File

@ -128,7 +128,7 @@ script do it for you. Manual installation is described at:
https://invoke-ai.github.io/InvokeAI/installation/020_INSTALL_MANUAL/ https://invoke-ai.github.io/InvokeAI/installation/020_INSTALL_MANUAL/
You may download the recommended models (about 15GB total), install all models (40 GB!!) You may download the recommended models (about 15GB total), install all models (40 GB!!)
select a customized set, or completely skip this step. select a customized set, or completely skip this step.
""" """
) )
@ -583,7 +583,7 @@ def new_config_file_contents(successfully_downloaded: dict, config_file: Path, o
# model is a diffusers (indicated with a path) # model is a diffusers (indicated with a path)
if conf.get(model) and Path(successfully_downloaded[model]).is_dir(): if conf.get(model) and Path(successfully_downloaded[model]).is_dir():
offer_to_delete_weights(model, conf[model], opt.yes_to_all) offer_to_delete_weights(model, conf[model], opt.yes_to_all)
stanza = {} stanza = {}
mod = Datasets[model] mod = Datasets[model]
stanza["description"] = mod["description"] stanza["description"] = mod["description"]
@ -635,7 +635,7 @@ def offer_to_delete_weights(model_name: str, conf_stanza: dict, yes_to_all: bool
weights.unlink() weights.unlink()
except OSError as e: except OSError as e:
print(str(e)) print(str(e))
# --------------------------------------------- # ---------------------------------------------
# this will preload the Bert tokenizer fles # this will preload the Bert tokenizer fles
def download_bert(): def download_bert():
@ -683,10 +683,18 @@ def download_clip():
def download_realesrgan(): def download_realesrgan():
print("Installing models from RealESRGAN...", file=sys.stderr) print("Installing models from RealESRGAN...", file=sys.stderr)
model_url = "https://github.com/xinntao/Real-ESRGAN/releases/download/v0.2.5.0/realesr-general-x4v3.pth" model_url = "https://github.com/xinntao/Real-ESRGAN/releases/download/v0.2.5.0/realesr-general-x4v3.pth"
wdn_model_url = "https://github.com/xinntao/Real-ESRGAN/releases/download/v0.2.5.0/realesr-general-wdn-x4v3.pth"
model_dest = os.path.join( model_dest = os.path.join(
Globals.root, "models/realesrgan/realesr-general-x4v3.pth" Globals.root, "models/realesrgan/realesr-general-x4v3.pth"
) )
wdn_model_dest = os.path.join(
Globals.root, "models/realesrgan/realesr-general-wdn-x4v3.pth"
)
download_with_progress_bar(model_url, model_dest, "RealESRGAN") download_with_progress_bar(model_url, model_dest, "RealESRGAN")
download_with_progress_bar(wdn_model_url, wdn_model_dest, "RealESRGANwdn")
def download_gfpgan(): def download_gfpgan():

View File

@ -16,7 +16,7 @@ class ESRGAN():
else: else:
use_half_precision = True use_half_precision = True
def load_esrgan_bg_upsampler(self): def load_esrgan_bg_upsampler(self, denoise_str):
if not torch.cuda.is_available(): # CPU or MPS on M1 if not torch.cuda.is_available(): # CPU or MPS on M1
use_half_precision = False use_half_precision = False
else: else:
@ -26,14 +26,16 @@ class ESRGAN():
from realesrgan import RealESRGANer from realesrgan import RealESRGANer
model = SRVGGNetCompact(num_in_ch=3, num_out_ch=3, num_feat=64, num_conv=32, upscale=4, act_type='prelu') model = SRVGGNetCompact(num_in_ch=3, num_out_ch=3, num_feat=64, num_conv=32, upscale=4, act_type='prelu')
model_path = os.path.join(Globals.root,'models/realesrgan/realesr-general-x4v3.pth') model_path = os.path.join(Globals.root, 'models/realesrgan/realesr-general-x4v3.pth')
wdn_model_path = os.path.join(Globals.root, 'models/realesrgan/realesr-general-wdn-x4v3.pth')
scale = 4 scale = 4
bg_upsampler = RealESRGANer( bg_upsampler = RealESRGANer(
scale=scale, scale=scale,
model_path=model_path, model_path=[model_path, wdn_model_path],
model=model, model=model,
tile=self.bg_tile_size, tile=self.bg_tile_size,
dni_weight=[denoise_str, 1 - denoise_str],
tile_pad=10, tile_pad=10,
pre_pad=0, pre_pad=0,
half=use_half_precision, half=use_half_precision,
@ -41,13 +43,13 @@ class ESRGAN():
return bg_upsampler return bg_upsampler
def process(self, image: ImageType, strength: float, seed: str = None, upsampler_scale: int = 2): def process(self, image: ImageType, strength: float, seed: str = None, upsampler_scale: int = 2, denoise_str: float = 0.75):
with warnings.catch_warnings(): with warnings.catch_warnings():
warnings.filterwarnings('ignore', category=DeprecationWarning) warnings.filterwarnings('ignore', category=DeprecationWarning)
warnings.filterwarnings('ignore', category=UserWarning) warnings.filterwarnings('ignore', category=UserWarning)
try: try:
upsampler = self.load_esrgan_bg_upsampler() upsampler = self.load_esrgan_bg_upsampler(denoise_str)
except Exception: except Exception:
import traceback import traceback
import sys import sys
@ -60,7 +62,7 @@ class ESRGAN():
if seed is not None: if seed is not None:
print( print(
f'>> Real-ESRGAN Upscaling seed:{seed} : scale:{upsampler_scale}x' f'>> Real-ESRGAN Upscaling seed:{seed}, scale:{upsampler_scale}x, tile:{self.bg_tile_size}, denoise:{denoise_str}'
) )
# ESRGAN outputs images with partial transparency if given RGBA images; convert to RGB # ESRGAN outputs images with partial transparency if given RGBA images; convert to RGB
image = image.convert("RGB") image = image.convert("RGB")