Create an Inpainting Checkpoint from Any Model
Merge SD checkpoints into inpainting variants with Add Difference. Why inpaint weights differ and how to control seed and noise for repeatable edits.
On this page
- TL;DR
- Why Convert a Checkpoint Instead of Downloading One?
- The Architecture Difference: 9 Channels vs. 4
- SD 1.5 Merge Recipe
- SDXL Merge Recipe
- How Add Difference Works (The Mechanism)
- Common Error: BigLust v1.0 Metadata Crash
- Controlling Seed and Noise for Repeatable Edits
- Workflow: From Sketch to Inpaint-Ready Result
- Quick Reference: SD 1.5 vs. SDXL Merge Settings
- FAQ
- Sources
Related reads: Stable Diffusion checkpoint training guide · ControlNet inpainting and outpainting · ComfyUI inpainting workflow tutorial
TL;DR
- Merge recipe: In Automatic1111's Checkpoint Merger, select Add Difference mode with Model A = inpainting base, Model B = your fine-tune, Model C = matching base model. Multiplier is ignored for this mode.
- Architecture difference: Inpainting UNets have 9 input channels (4 latent + 4 masked-image latent + 1 mask) vs. 4 for base models. The extra channels are zero-initialized during inpainting fine-tuning.
- Seed/noise control: For deterministic edits, pass both a seeded
torch.Generatorand explicitlatentstensor to the pipeline;strength < 1.0preserves some original latent signal.
Related reads: Stable Diffusion checkpoint training guide · ControlNet inpainting and outpainting · ComfyUI inpainting workflow tutorial
Why Convert a Checkpoint Instead of Downloading One?
Dedicated inpainting checkpoints exist for SD 1.5 and SDXL, but they're tied to the base model they were trained from. If you've fine-tuned a model on a specific style, character, or domain, the official inpainting weights won't carry those adaptations. The Add Difference merge (A + (B - C)) grafts the inpainting capability onto your checkpoint while preserving its learned concepts.
This technique works because the inpainting delta — the weights that changed when the base model was fine-tuned for inpainting — is isolated by subtracting the base (C) from the inpainting base (A). Applying that delta to your fine-tune (B) transfers only the inpainting-specific adaptation.
Related reads: Stable Diffusion checkpoint training guide · ControlNet inpainting and outpainting · ComfyUI inpainting workflow tutorial
The Architecture Difference: 9 Channels vs. 4
A standard Stable Diffusion UNet expects 4-channel latents from the VAE encoder. An inpainting UNet expects 9 channels:
| Channel group | Count | Purpose |
|---|---|---|
| Noisy latent | 4 | Standard diffusion input |
| Masked-image latent | 4 | VAE encoding of the image with masked regions zeroed |
| Mask | 1 | Downsampled binary mask (white = regenerate, black = preserve) |
The 5 additional channels are zero-initialized when inpainting training begins, so the model learns to condition on the masked region and mask from scratch. This is why a regular checkpoint simply fails at inpainting — its UNet has no weights for those extra inputs.
Source: The SD 1.5 inpainting model card states: "For inpainting, the UNet has 5 additional input channels (4 for the encoded masked-image and 1 for the mask itself) whose weights were zero-initialized after restoring the non-inpainting checkpoint."
Related reads: Stable Diffusion checkpoint training guide · ControlNet inpainting and outpainting · ComfyUI inpainting workflow tutorial
SD 1.5 Merge Recipe
| Slot | Model | Source |
|---|---|---|
| Model A | stable-diffusion-v1-5-inpainting (official) | HuggingFace |
| Model B | Your fine-tuned checkpoint | — |
| Model C | stable-diffusion-v1-5 (base) | HuggingFace |
| Mode | Add Difference | — |
| Multiplier | Ignored for this mode | — |
| Format | safetensors | — |
The output file appears as <YourModelName>.inpainting.safetensors in your models folder.
Note: The benjamin-paine repository mirrors the official CompVis/Stability weights. Use the official model card as the canonical source.
Related reads: Stable Diffusion checkpoint training guide · ControlNet inpainting and outpainting · ComfyUI inpainting workflow tutorial
SDXL Merge Recipe
| Slot | Model | Source |
|---|---|---|
| Model A | sd_xl_base_1.0_inpainting_0.1.safetensors | benjamin-paine/sd-xl-alternative-bases |
| Model B | Your SDXL fine-tune | — |
| Model C | sd_xl_base_1.0_fp16_vae.safetensors | Same repo |
| Mode | Add Difference | — |
| Multiplier | Ignored | — |
| Format | safetensors | — |
Critical: Model C must be the FP16 VAE version. The Diffusers team trained XL Inpainting with the FP16 VAE fused in; using a different base (fp32 VAE or no VAE) applies a mismatched delta and yields a broken VAE.
Source: Benjamin Paine's model card: "You must specifically use the two files present in this repository... using a different XL base will result in an incorrect delta being applied to the inpainting checkpoint, and the resulting VAE will be nonsensical."
Related reads: Stable Diffusion checkpoint training guide · ControlNet inpainting and outpainting · ComfyUI inpainting workflow tutorial
How Add Difference Works (The Mechanism)
The formula theta_A + (theta_B - theta_C) computes:
theta_A - theta_C= the inpainting delta (weights added/changed when the base model was fine-tuned for inpainting)theta_B + delta= your fine-tune with the inpainting adaptation grafted on
Because A and C share the same architecture (and for SDXL, the same VAE), the subtraction cancels out the shared base weights, leaving only the inpainting-specific changes: the 9-channel input projection, attention modifications, and any VAE statistics baked into the delta.
Source: A1111merge_models.pyimplementsadd_differenceastheta_0 + (theta_1 - theta_2)with no multiplier scaling.
Related reads: Stable Diffusion checkpoint training guide · ControlNet inpainting and outpainting · ComfyUI inpainting workflow tutorial
Common Error: BigLust v1.0 Metadata Crash
| Symptom | Cause | Fix |
|---|---|---|
TypeError: argument 'metadata': 'dict' object cannot be converted to 'PyString' during merge | Checkpoint contains metadata in an incompatible format (dict vs. PyString) | In Checkpoint Merger → Metadata section: uncheck "save metadata", click "read metadata from selected checkpoints", then Merge |
Source: Civitai article 833 workaround.
Related reads: Stable Diffusion checkpoint training guide · ControlNet inpainting and outpainting · ComfyUI inpainting workflow tutorial
Controlling Seed and Noise for Repeatable Edits
Three levers determine determinism in the StableDiffusionInpaintPipeline:
| Lever | Parameter | Effect |
|---|---|---|
| Seeded generator | generator=torch.Generator(device).manual_seed(seed) | Makes sampling deterministic if the pipeline generates its own noise |
| Explicit latents | latents=your_tensor | Bypasses random noise entirely — pipeline uses your tensor as the starting latent |
| Strength | strength=0.3–1.0 | At 1.0, masked region becomes pure noise; at <1.0, original latent signal is partially preserved |
For exact reproducibility across runs, supply both a seeded generator and explicit latents.
Source: diffusersStableDiffusionInpaintPipeline.__call__signature documentsgenerator("make generation deterministic") andlatents("Pre-generated noisy latents to be used as inputs").
Denoising Strength vs. Mask Interaction
The strength parameter controls how much noise is added to the input image before denoising the masked region:
- 1.0 → masked region = pure noise → full regeneration guided only by prompt
- 0.3–0.5 → retains more original content → finer edits, better structure preservation
- 0.7 → common starting point for "rough sketch → coherent image" (heuristic, not a rule)
Source: Pipeline docs: "A value of 1 essentially ignores image." Community workflow (Civitai 4451) recommends 0.7 for first pass, 0.3 for detail refinement.
Related reads: Stable Diffusion checkpoint training guide · ControlNet inpainting and outpainting · ComfyUI inpainting workflow tutorial
Workflow: From Sketch to Inpaint-Ready Result
- Prepare the inpainting checkpoint using the merge recipe above.
- Open an img2img/inpaint interface (A1111, ComfyUI, or Krita AI Diffusion).
- Draw a crude mask over the region to regenerate; set
strength ≈ 0.7. - Prompt the desired content for the masked area.
- Iterate: lower
strengthto 0.3–0.4, refine mask/prompt, re-run. - For exact reproducibility: capture the
latentstensor from a good run, then re-use it with the same seed.
Tooling: Krita AI Diffusion (ComfyUI) provides a fast sketch → inpaint loop. ControlNet's "inpaint only" processor handles outpainting. ADetailer automates face/body touch-ups.
Related reads: Stable Diffusion checkpoint training guide · ControlNet inpainting and outpainting · ComfyUI inpainting workflow tutorial
Quick Reference: SD 1.5 vs. SDXL Merge Settings
| Setting | SD 1.5 | SDXL |
|---|---|---|
| Model A (inpainting base) | stable-diffusion-v1-5-inpainting | sd_xl_base_1.0_inpainting_0.1.safetensors |
| Model B (your fine-tune) | Your .safetensors | Your .safetensors |
| Model C (base) | stable-diffusion-v1-5 | sd_xl_base_1.0_fp16_vae.safetensors |
| Mode | Add Difference | Add Difference |
| Multiplier | Ignored | Ignored |
| Output name | <name>.inpainting.safetensors | <name>.inpainting.safetensors |
Related reads: Stable Diffusion checkpoint training guide · ControlNet inpainting and outpainting · ComfyUI inpainting workflow tutorial
FAQ
Can I use a regular checkpoint for inpainting without merging?
No. The UNet lacks the 5 additional input channels (4 masked-image latent + 1 mask). It will either error or produce garbage.
Does the Multiplier setting matter for Add Difference?
No. The A1111 implementation ignores multiplier for this mode; the formula is fixed as A + (B - C).
Why must SDXL use the FP16 VAE as Model C?
The XL inpainting model was trained with the FP16 VAE fused in. The delta A - C contains VAE-specific statistics. A mismatched base applies the wrong delta and breaks the VAE.
How do I get the exact same inpaint result twice?
Pass the same seeded torch.Generator and the same latents tensor to the pipeline. strength must also match.
What does strength=0.5 actually do?
It adds noise halfway to pure noise. At 0.5, the masked region is noised halfway toward pure noise; the denoiser preserves more structure while still allowing prompt-guided changes.
Can I merge a LoRA into the inpainting checkpoint instead?
Yes — load the merged inpainting checkpoint, then apply LoRAs at inference time. The merge recipe only handles the base checkpoint architecture.
Where do I find the official SD 1.5 inpainting weights?
stable-diffusion-v1-5/stable-diffusion-inpainting on HuggingFace (CompVis/Stability). The benjamin-paine repo is a mirror.
Related reads: Stable Diffusion checkpoint training guide · ControlNet inpainting and outpainting · ComfyUI inpainting workflow tutorial
Sources
| # | Source | What it contributed |
|---|---|---|
| 1 | SD 1.5 Inpainting model card | 9-channel architecture, 440k training steps, zero-init weights |
| 2 | SDXL Alternative Bases | Add Difference formula, FP16 VAE requirement, filenames |
| 3 | diffusers InpaintPipeline docs | generator, latents, strength, mask_image semantics |
| 4 | A1111 merge_models.py | add_difference implementation, multiplier ignored |
| 5 | Civitai 833 | SD 1.5/SDXL merge recipes, BigLust metadata fix |
| 6 | Civitai 4451 | Denoising strength heuristics (0.7 / 0.3), img2img workflow |
| 7 | Civitai 482 | ControlNet inpaint-only outpainting, Krita AI Diffusion, ADetailer |
| 8 | Civitai 8261 | Civitai on-site generator localStorage hack (reference only) |
Related reads: Stable Diffusion checkpoint training guide · ControlNet inpainting and outpainting · ComfyUI inpainting workflow tutorial