Spaces:
Runtime error
Runtime error
File size: 6,665 Bytes
c19ca42 |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 |
import gradio as gr
from diffusers.pipelines import StableDiffusionPipeline, StableDiffusionXLPipeline # pylint: disable=unused-import
from modules import shared, scripts, processing, sd_models, devices
"""
This is a simpler template for script for SD.Next that implements a custom pipeline
Items that can be added:
- Any pipeline already in diffusers
List of pipelines that can be directly used: <https://github.com/huggingface/diffusers/tree/main/src/diffusers/pipelines>
- Any pipeline for which diffusers definiotion exists and can be copied
List of pipelines with community definitions: <https://github.com/huggingface/diffusers/tree/main/examples/community>
- Any custom pipeline that you create
Author::
- Your details
Credits:
- Link to original implementation and author
Contributions:
- Submit a PR on SD.Next GitHub repo to be included in /scripts
- Before submitting a PR, make sure to test your script thoroughly and that it passes code quality checks
Lint rules are part of SD.Next CI/CD pipeline
> pip install ruff pylint
> ruff scripts/example.py
> pylint scriptts/example.py
"""
## Config
# script title
title = 'Example'
# is script available in txt2img tab
txt2img = False
# is script available in img2img tab
img2img = False
# is pipeline ok to run in pure latent mode without implicit conversions
# recommended so entire ecosystem can be used as-is, but requires that latent is in format that sdnext can understand
# some pipelines may not support this, in which case set to false and pipeline will implicitly do things like vae encode/decode on its own
latent = True
# base pipeline class from which this pipeline is derived, most commonly 'StableDiffusionPipeline' or 'StableDiffusionXLPipeline'
pipeline_base = 'StableDiffusionPipeline'
# class definition for this pipeline
# for built-in diffuser pipelines, simply import it from diffusers.pipelines above
# for example only, its set to same as base pipeline
# for community pipelines, copy class definition from community source code
# in which case only class definition code and required imports needs to be copied, not the entire source code
pipeline_class = StableDiffusionPipeline
# pipeline args values are defined in ui method below, here we need to define their exact names
# they also have to be in the exact order as they are defined in ui
# note: variable names should be exactly as defined in pipeline_class.__call__ method
# if pipeline requires a param and its not provided, it will result in runtime error
# if you provide param that is not defined by pipeline, sdnext will strip it
params = ['test1', 'test2', 'test3', 'test4']
### Script definition
class Script(scripts.Script):
def title(self):
return title
def show(self, is_img2img):
if shared.backend == shared.Backend.DIFFUSERS:
return img2img if is_img2img else txt2img
return False
# Define UI for pipeline
def ui(self, _is_img2img):
ui_controls = []
with gr.Row():
ui_controls.append(gr.Slider(minimum=0, maximum=1, step=0.1, value=0.5, label="Test1"))
ui_controls.append(gr.Slider(minimum=0, maximum=10, step=1, value=5, label="Test2"))
with gr.Row():
ui_controls.append(gr.Checkbox(label="Test3", value=True))
with gr.Row():
ui_controls.append(gr.Textbox(label="Test4", value="", placeholder="enter text here"))
with gr.Row():
gr.HTML('<a href="https://huggingface.co/docs/diffusers/api/pipelines/stable_diffusion/stable_diffusion_xl>Stable Diffusion SDXL pipeline docs</a>"')
return ui_controls
# Run pipeline
def run(self, p: processing.StableDiffusionProcessing, *args): # pylint: disable=arguments-differ
# prepare pipeline
c = shared.sd_model.__class__.__name__ if shared.sd_model is not None else ''
if c != pipeline_base:
shared.log.warning(f'{title}: pipeline={c} required={pipeline_base}')
return None
orig_pipeline = shared.sd_model # backup current pipeline definition
shared.sd_model = pipeline_class( # create new pipeline using currently loaded model which is always in `shared.sd_model`
# different pipelines may need different init params, so you may need to change this
# to see init params, see pipeline_class.__init__ method
# if init params are incorrect you will also see a runtime error with unrecognized or missing params
# for example:
# > TypeError: StableDiffusionPipeline.__init__() missing 2 required positional arguments: 'safety_checker' and 'feature_extractor'
vae = shared.sd_model.vae,
text_encoder=shared.sd_model.text_encoder,
tokenizer=shared.sd_model.tokenizer,
unet=shared.sd_model.unet,
scheduler=shared.sd_model.scheduler,
safety_checker=shared.sd_model.safety_checker,
feature_extractor=shared.sd_model.feature_extractor,
)
sd_models.copy_diffuser_options(shared.sd_model, orig_pipeline) # copy options from original pipeline
sd_models.set_diffuser_options(shared.sd_model) # set all model options such as fp16, offload, etc.
sd_models.move_model(shared.sd_model, devices.device) # move pipeline to device
shared.sd_model.to(dtype=devices.dtype)
# if pipeline also needs a specific type, you can set it here, but not commonly needed
# shared.sd_model = sd_models.set_diffuser_pipe(shared.sd_model, sd_models.DiffusersTaskType.IMAGE_2_IMAGE)
# prepare params
# all pipeline params go into p.task_args and are automatically handled by sdnext from there
for i in range(len(args)):
p.task_args[params[i]] = args[i]
# you can also re-use existing params from `p` object if pipeline wants them, but under a different name
# for example, if pipeline expects 'image' param, but you want to use 'init_images' instead which is what img2img tab uses
# p.task_args['image'] = p.init_images[0]
if not latent:
p.task_args['output_type'] = 'np'
shared.log.debug(f'{c}: args={p.task_args}')
# if you need to run any preprocessing, this is the place to do it
# run processing
processed: processing.Processed = processing.process_images(p)
# if you need to run any postprocessing, this is the place to do it
# you dont need to handle saving, metadata, etc - sdnext will do it for you
# restore original pipeline
shared.sd_model = orig_pipeline
return processed
|