Skip to content

Commit fd1b9a1

Browse files
commit tile size controls
1 parent 82fb897 commit fd1b9a1

File tree

8 files changed

+162
-9
lines changed

8 files changed

+162
-9
lines changed

invokeai/frontend/web/public/locales/en.json

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1775,6 +1775,20 @@
17751775
"Structure controls how closely the output image will keep to the layout of the original. Low structure allows major changes, while high structure strictly maintains the original composition and layout."
17761776
]
17771777
},
1778+
"tileSize": {
1779+
"heading": "Tile Size",
1780+
"paragraphs": [
1781+
"Controls the size of tiles used during the upscaling process. Larger tiles use more memory but may produce better results.",
1782+
"SD1.5 models default to 768, while SDXL models default to 1024. Reduce tile size if you encounter memory issues."
1783+
]
1784+
},
1785+
"tileOverlap": {
1786+
"heading": "Tile Overlap",
1787+
"paragraphs": [
1788+
"Controls the overlap between adjacent tiles during upscaling. Higher overlap values help reduce visible seams between tiles but use more memory.",
1789+
"The default value of 128 works well for most cases, but you can adjust based on your specific needs and memory constraints."
1790+
]
1791+
},
17781792
"fluxDevLicense": {
17791793
"heading": "Non-Commercial License",
17801794
"paragraphs": [
@@ -2396,6 +2410,8 @@
23962410
"upscaleModel": "Upscale Model",
23972411
"postProcessingModel": "Post-Processing Model",
23982412
"scale": "Scale",
2413+
"tileSize": "Tile Size",
2414+
"tileOverlap": "Tile Overlap",
23992415
"postProcessingMissingModelWarning": "Visit the <LinkComponent>Model Manager</LinkComponent> to install a post-processing (image to image) model.",
24002416
"missingModelsWarning": "Visit the <LinkComponent>Model Manager</LinkComponent> to install the required models:",
24012417
"mainModelDesc": "Main model (SD1.5 or SDXL architecture)",

invokeai/frontend/web/src/common/components/InformationalPopover/constants.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -67,6 +67,8 @@ export type Feature =
6767
| 'scale'
6868
| 'creativity'
6969
| 'structure'
70+
| 'tileSize'
71+
| 'tileOverlap'
7072
| 'optimizedDenoising'
7173
| 'fluxDevLicense';
7274

invokeai/frontend/web/src/features/modelManagerV2/subpanels/AddModelPanel/ModelInstallQueue/ModelInstallQueue.tsx

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -55,9 +55,7 @@ export const ModelInstallQueue = memo(() => {
5555
<Box layerStyle="first" p={3} borderRadius="base" w="full" h="full">
5656
<ScrollableContent>
5757
<Flex flexDir="column-reverse" gap="2" w="full">
58-
{data?.map((model) => (
59-
<ModelInstallQueueItem key={model.id} installJob={model} />
60-
))}
58+
{data?.map((model) => <ModelInstallQueueItem key={model.id} installJob={model} />)}
6159
</Flex>
6260
</ScrollableContent>
6361
</Box>

invokeai/frontend/web/src/features/nodes/util/graph/buildMultidiffusionUpscaleGraph.ts

Lines changed: 19 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,16 @@ import type { GraphBuilderReturn } from './types';
1212

1313
export const buildMultidiffusionUpscaleGraph = async (state: RootState): Promise<GraphBuilderReturn> => {
1414
const { model, upscaleCfgScale: cfg_scale, upscaleScheduler: scheduler, steps, vaePrecision, vae } = state.params;
15-
const { upscaleModel, upscaleInitialImage, structure, creativity, tileControlnetModel, scale } = state.upscale;
15+
const {
16+
upscaleModel,
17+
upscaleInitialImage,
18+
structure,
19+
creativity,
20+
tileControlnetModel,
21+
scale,
22+
tileSize,
23+
tileOverlap,
24+
} = state.upscale;
1625

1726
assert(model, 'No model selected');
1827
assert(model.base === 'sd-1' || model.base === 'sdxl', 'Multi-Diffusion upscaling requires a SD1.5 or SDXL model');
@@ -58,11 +67,13 @@ export const buildMultidiffusionUpscaleGraph = async (state: RootState): Promise
5867
g.addEdge(unsharpMask, 'width', noise, 'width');
5968
g.addEdge(unsharpMask, 'height', noise, 'height');
6069

70+
const effectiveTileSize = tileSize;
71+
6172
const i2l = g.addNode({
6273
type: 'i2l',
6374
id: getPrefixedId('i2l'),
6475
fp32: vaePrecision === 'fp32',
65-
tile_size: 1024,
76+
tile_size: effectiveTileSize,
6677
tiled: true,
6778
});
6879

@@ -72,7 +83,7 @@ export const buildMultidiffusionUpscaleGraph = async (state: RootState): Promise
7283
type: 'l2i',
7384
id: getPrefixedId('l2i'),
7485
fp32: vaePrecision === 'fp32',
75-
tile_size: 1024,
86+
tile_size: effectiveTileSize,
7687
tiled: true,
7788
board: getBoardField(state),
7889
is_intermediate: false,
@@ -81,9 +92,9 @@ export const buildMultidiffusionUpscaleGraph = async (state: RootState): Promise
8192
const tiledMultidiffusion = g.addNode({
8293
type: 'tiled_multi_diffusion_denoise_latents',
8394
id: getPrefixedId('tiled_multidiffusion_denoise_latents'),
84-
tile_height: 1024, // is this dependent on base model
85-
tile_width: 1024, // is this dependent on base model
86-
tile_overlap: 128,
95+
tile_height: effectiveTileSize,
96+
tile_width: effectiveTileSize,
97+
tile_overlap: tileOverlap || 128,
8798
steps,
8899
cfg_scale,
89100
scheduler,
@@ -184,6 +195,8 @@ export const buildMultidiffusionUpscaleGraph = async (state: RootState): Promise
184195
upscale_model: Graph.getModelMetadataField(upscaleModelConfig),
185196
creativity,
186197
structure,
198+
tile_size: effectiveTileSize,
199+
tile_overlap: tileOverlap || 128,
187200
upscale_initial_image: {
188201
image_name: upscaleInitialImage.image_name,
189202
width: upscaleInitialImage.width,
Lines changed: 53 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,53 @@
1+
import { CompositeNumberInput, CompositeSlider, FormControl, FormLabel } from '@invoke-ai/ui-library';
2+
import { useAppDispatch, useAppSelector } from 'app/store/storeHooks';
3+
import { selectTileOverlap, tileOverlapChanged } from 'features/parameters/store/upscaleSlice';
4+
import { useCallback } from 'react';
5+
import { useTranslation } from 'react-i18next';
6+
7+
const initial = 128;
8+
const sliderMin = 32;
9+
const sliderMax = 256;
10+
const numberInputMin = 16;
11+
const numberInputMax = 512;
12+
const coarseStep = 16;
13+
const fineStep = 8;
14+
const marks = [sliderMin, 128, sliderMax];
15+
16+
const ParamTileOverlap = () => {
17+
const tileOverlap = useAppSelector(selectTileOverlap);
18+
const dispatch = useAppDispatch();
19+
const { t } = useTranslation();
20+
const onChange = useCallback(
21+
(v: number) => {
22+
dispatch(tileOverlapChanged(v));
23+
},
24+
[dispatch]
25+
);
26+
27+
return (
28+
<FormControl>
29+
<FormLabel>{t('upscaling.tileOverlap')}</FormLabel>
30+
<CompositeSlider
31+
value={tileOverlap}
32+
defaultValue={initial}
33+
min={sliderMin}
34+
max={sliderMax}
35+
step={coarseStep}
36+
fineStep={fineStep}
37+
onChange={onChange}
38+
marks={marks}
39+
/>
40+
<CompositeNumberInput
41+
value={tileOverlap}
42+
defaultValue={initial}
43+
min={numberInputMin}
44+
max={numberInputMax}
45+
step={coarseStep}
46+
fineStep={fineStep}
47+
onChange={onChange}
48+
/>
49+
</FormControl>
50+
);
51+
};
52+
53+
export default ParamTileOverlap;
Lines changed: 53 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,53 @@
1+
import { CompositeNumberInput, CompositeSlider, FormControl, FormLabel } from '@invoke-ai/ui-library';
2+
import { useAppDispatch, useAppSelector } from 'app/store/storeHooks';
3+
import { selectTileSize, tileSizeChanged } from 'features/parameters/store/upscaleSlice';
4+
import { useCallback } from 'react';
5+
import { useTranslation } from 'react-i18next';
6+
7+
const initial = 1024;
8+
const sliderMin = 512;
9+
const sliderMax = 1536;
10+
const numberInputMin = 512;
11+
const numberInputMax = 1536;
12+
const coarseStep = 64;
13+
const fineStep = 32;
14+
const marks = [sliderMin, 1024, sliderMax];
15+
16+
const ParamTileSize = () => {
17+
const tileSize = useAppSelector(selectTileSize);
18+
const dispatch = useAppDispatch();
19+
const { t } = useTranslation();
20+
const onChange = useCallback(
21+
(v: number) => {
22+
dispatch(tileSizeChanged(v));
23+
},
24+
[dispatch]
25+
);
26+
27+
return (
28+
<FormControl>
29+
<FormLabel>{t('upscaling.tileSize')}</FormLabel>
30+
<CompositeSlider
31+
value={tileSize}
32+
defaultValue={initial}
33+
min={sliderMin}
34+
max={sliderMax}
35+
step={coarseStep}
36+
fineStep={fineStep}
37+
onChange={onChange}
38+
marks={marks}
39+
/>
40+
<CompositeNumberInput
41+
value={tileSize}
42+
defaultValue={initial}
43+
min={numberInputMin}
44+
max={numberInputMax}
45+
step={coarseStep}
46+
fineStep={fineStep}
47+
onChange={onChange}
48+
/>
49+
</FormControl>
50+
);
51+
};
52+
53+
export default ParamTileSize;

invokeai/frontend/web/src/features/parameters/store/upscaleSlice.ts

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,8 @@ export interface UpscaleState {
1313
tileControlnetModel: ControlNetModelConfig | null;
1414
scale: number;
1515
postProcessingModel: ParameterSpandrelImageToImageModel | null;
16+
tileSize: number;
17+
tileOverlap: number;
1618
}
1719

1820
const initialUpscaleState: UpscaleState = {
@@ -24,6 +26,8 @@ const initialUpscaleState: UpscaleState = {
2426
tileControlnetModel: null,
2527
scale: 4,
2628
postProcessingModel: null,
29+
tileSize: 1024,
30+
tileOverlap: 128,
2731
};
2832

2933
export const upscaleSlice = createSlice({
@@ -51,6 +55,12 @@ export const upscaleSlice = createSlice({
5155
postProcessingModelChanged: (state, action: PayloadAction<ParameterSpandrelImageToImageModel | null>) => {
5256
state.postProcessingModel = action.payload;
5357
},
58+
tileSizeChanged: (state, action: PayloadAction<number>) => {
59+
state.tileSize = action.payload;
60+
},
61+
tileOverlapChanged: (state, action: PayloadAction<number>) => {
62+
state.tileOverlap = action.payload;
63+
},
5464
},
5565
});
5666

@@ -62,6 +72,8 @@ export const {
6272
tileControlnetModelChanged,
6373
scaleChanged,
6474
postProcessingModelChanged,
75+
tileSizeChanged,
76+
tileOverlapChanged,
6577
} = upscaleSlice.actions;
6678

6779
/* eslint-disable-next-line @typescript-eslint/no-explicit-any */
@@ -88,3 +100,5 @@ export const selectTileControlNetModel = createUpscaleSelector((upscale) => upsc
88100
export const selectStructure = createUpscaleSelector((upscale) => upscale.structure);
89101
export const selectUpscaleInitialImage = createUpscaleSelector((upscale) => upscale.upscaleInitialImage);
90102
export const selectUpscaleScale = createUpscaleSelector((upscale) => upscale.scale);
103+
export const selectTileSize = createUpscaleSelector((upscale) => upscale.tileSize);
104+
export const selectTileOverlap = createUpscaleSelector((upscale) => upscale.tileOverlap);

invokeai/frontend/web/src/features/settingsAccordions/components/AdvancedSettingsAccordion/UpscaleTabAdvancedSettingsAccordion.tsx

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,8 @@ import { ParamSeed } from 'features/parameters/components/Seed/ParamSeed';
77
import ParamFLUXVAEModelSelect from 'features/parameters/components/VAEModel/ParamFLUXVAEModelSelect';
88
import ParamVAEModelSelect from 'features/parameters/components/VAEModel/ParamVAEModelSelect';
99
import ParamVAEPrecision from 'features/parameters/components/VAEModel/ParamVAEPrecision';
10+
import ParamTileOverlap from 'features/parameters/components/Upscale/ParamTileOverlap';
11+
import ParamTileSize from 'features/parameters/components/Upscale/ParamTileSize';
1012
import { useStandaloneAccordionToggle } from 'features/settingsAccordions/hooks/useStandaloneAccordionToggle';
1113
import { memo, useMemo } from 'react';
1214
import { useTranslation } from 'react-i18next';
@@ -73,6 +75,8 @@ export const UpscaleTabAdvancedSettingsAccordion = memo(() => {
7375
{!isFLUX && !isSD3 && <ParamVAEPrecision />}
7476
</Flex>
7577
<ParamSeed />
78+
<ParamTileSize />
79+
<ParamTileOverlap />
7680
</Flex>
7781
</StandaloneAccordion>
7882
);

0 commit comments

Comments
 (0)