This commit is contained in:
2026-05-14 18:37:18 +08:00
parent 5e6d8046e1
commit 7a2ffc91a2
15 changed files with 200 additions and 56 deletions
+29 -5
View File
@@ -4,6 +4,7 @@ from __future__ import annotations
统一的补全(Inpaint)模型加载入口。
当前支持:
- FLUX Filldiffusers FluxFillPipeline,如 FLUX.1-Fill-dev
- SDXL Inpaintdiffusers AutoPipelineForInpainting
- ControlNetStable Diffusion + ControlNet Inpaint
- LaMatorchscript big-lama,本地封装)
@@ -11,7 +12,7 @@ from __future__ import annotations
from dataclasses import dataclass
from enum import Enum
from typing import Callable
from typing import Any, Callable
import numpy as np
from PIL import Image
@@ -21,10 +22,12 @@ from config_loader import (
get_sdxl_base_model_from_app,
get_controlnet_base_model_from_app,
get_controlnet_model_from_app,
get_flux_fill_model_from_app,
)
class InpaintBackend(str, Enum):
FLUX_FILL = "flux_fill"
SDXL_INPAINT = "sdxl_inpaint"
CONTROLNET = "controlnet"
LAMA = "lama"
@@ -36,6 +39,7 @@ class UnifiedInpaintConfig:
device: str | None = None
# SDXL base model (HF id 或本地目录),不填则用 config.py 的默认值
sdxl_base_model: str | None = None
flux_fill_model: str | None = None
@dataclass
@@ -100,7 +104,7 @@ def _make_sdxl_inpaint_predictor(
- 输出:PIL RGB 结果图
"""
import torch
from diffusers import AutoPipelineForText2Image, AutoPipelineForInpainting
from diffusers import AutoPipelineForInpainting
app_cfg = load_app_config()
base_model = cfg.sdxl_base_model or get_sdxl_base_model_from_app(app_cfg)
@@ -112,13 +116,12 @@ def _make_sdxl_inpaint_predictor(
torch_dtype = torch.float16 if device == "cuda" else torch.float32
pipe_t2i = AutoPipelineForText2Image.from_pretrained(
pipe = AutoPipelineForInpainting.from_pretrained(
base_model,
torch_dtype=torch_dtype,
variant="fp16" if device == "cuda" else None,
use_safetensors=True,
).to(device)
pipe = AutoPipelineForInpainting.from_pipe(pipe_t2i).to(device)
# 省显存设置(尽量不改变输出语义)
# 注意:CPU offload 会明显变慢,但能显著降低显存占用。
@@ -149,6 +152,7 @@ def _make_sdxl_inpaint_predictor(
guidance_scale: float = 7.5,
num_inference_steps: int = 30,
max_side: int = 1024,
**_: Any,
) -> Image.Image:
image = image.convert("RGB")
# diffusers 要求 mask 为单通道,白色区域为需要重绘
@@ -257,6 +261,7 @@ def _make_controlnet_predictor(_: UnifiedInpaintConfig):
num_inference_steps: int = 30,
controlnet_conditioning_scale: float = 1.0,
max_side: int = 768,
**_: Any,
) -> Image.Image:
import cv2
import numpy as np
@@ -316,6 +321,22 @@ def _make_controlnet_predictor(_: UnifiedInpaintConfig):
return _predict
def _make_flux_fill_predictor(cfg: UnifiedInpaintConfig):
import torch
from .flux_fill.loader import make_flux_fill_predictor as _flux_fill_factory
app_cfg = load_app_config()
model_id = cfg.flux_fill_model or get_flux_fill_model_from_app(app_cfg)
device = cfg.device
if device is None:
device = app_cfg.inpaint.device
device = "cuda" if device.startswith("cuda") and torch.cuda.is_available() else "cpu"
return _flux_fill_factory(model_id=model_id, device=device)
def _make_lama_predictor(cfg: UnifiedInpaintConfig):
import torch
@@ -340,7 +361,7 @@ def _make_lama_predictor(cfg: UnifiedInpaintConfig):
max_side: int = 1024,
**_kwargs,
) -> Image.Image:
# LaMa 不使用 prompt/negative_prompt,也不使用 strength/steps 等扩散参数
# big-lama:仅 (RGB, mask);无文本条件。
_ = (strength, guidance_scale, num_inference_steps, max_side)
return lama(image, mask)
@@ -355,6 +376,9 @@ def build_inpaint_predictor(
"""
cfg = cfg or UnifiedInpaintConfig()
if cfg.backend == InpaintBackend.FLUX_FILL:
return _make_flux_fill_predictor(cfg), InpaintBackend.FLUX_FILL
if cfg.backend == InpaintBackend.SDXL_INPAINT:
return _make_sdxl_inpaint_predictor(cfg), InpaintBackend.SDXL_INPAINT