mirror of
https://github.com/vladmandic/automatic
synced 2026-09-19 17:24:32 +02:00
update cli
This commit is contained in:
+6477
File diff suppressed because one or more lines are too long
+126
-73
@@ -6,22 +6,22 @@ import re
|
||||
import gc
|
||||
import sys
|
||||
import json
|
||||
import http
|
||||
import time
|
||||
import shutil
|
||||
import pathlib
|
||||
import asyncio
|
||||
import logging
|
||||
import tempfile
|
||||
import argparse
|
||||
import warnings
|
||||
warnings.filterwarnings(action="ignore", category=DeprecationWarning)
|
||||
warnings.filterwarnings(action="ignore", category=UserWarning)
|
||||
warnings.filterwarnings(action="ignore", category=FutureWarning)
|
||||
sys.path.append('.')
|
||||
|
||||
# 3rd party imports
|
||||
import filetype
|
||||
import torch
|
||||
import requests
|
||||
import urllib3
|
||||
from tqdm.rich import tqdm
|
||||
|
||||
# local imports
|
||||
@@ -31,27 +31,39 @@ import process
|
||||
import latents
|
||||
import options
|
||||
|
||||
# console handler
|
||||
from rich.pretty import install as pretty_install
|
||||
from rich.traceback import install as traceback_install
|
||||
from rich.console import Console
|
||||
console = Console(log_time=True, log_time_format='%H:%M:%S-%f')
|
||||
pretty_install(console=console)
|
||||
traceback_install(console=console, extra_lines=1, width=console.width, word_wrap=False, indent_guides=False, suppress=[torch,asyncio,http,urllib3,requests])
|
||||
|
||||
# lora imports
|
||||
lora_path = os.path.abspath(os.path.join(os.path.dirname(__file__), os.pardir, 'modules', 'lora'))
|
||||
sys.path.append(lora_path)
|
||||
lycoris_path = os.path.abspath(os.path.join(os.path.dirname(__file__), os.pardir, 'modules', 'lycoris'))
|
||||
sys.path.append(lycoris_path)
|
||||
import train_network
|
||||
|
||||
# globals
|
||||
args = None
|
||||
log = logging.getLogger(__name__)
|
||||
valid_steps = ['original', 'face', 'body', 'blur', 'range', 'upscale', 'restore', 'interrogate', 'resize', 'square', 'segment']
|
||||
|
||||
# methods
|
||||
|
||||
def setup_logging(clean=False):
|
||||
try:
|
||||
if clean and os.path.isfile('setup.log'):
|
||||
os.remove('setup.log')
|
||||
time.sleep(0.1) # prevent race condition
|
||||
except:
|
||||
pass
|
||||
logging.basicConfig(level=logging.DEBUG, format='%(asctime)s | %(levelname)s | %(pathname)s | %(message)s', filename='setup.log', filemode='a', encoding='utf-8', force=True)
|
||||
from rich.theme import Theme
|
||||
from rich.logging import RichHandler
|
||||
from rich.console import Console
|
||||
from rich.pretty import install as pretty_install
|
||||
from rich.traceback import install as traceback_install
|
||||
console = Console(log_time=True, log_time_format='%H:%M:%S-%f', theme=Theme({
|
||||
"traceback.border": "black",
|
||||
"traceback.border.syntax_error": "black",
|
||||
"inspect.value.border": "black",
|
||||
}))
|
||||
pretty_install(console=console)
|
||||
traceback_install(console=console, extra_lines=1, width=console.width, word_wrap=False, indent_guides=False, suppress=[])
|
||||
rh = RichHandler(show_time=True, omit_repeated_times=False, show_level=True, show_path=False, markup=False, rich_tracebacks=True, log_time_format='%H:%M:%S-%f', level=logging.DEBUG if args.debug else logging.INFO, console=console)
|
||||
rh.set_name(logging.DEBUG if args.debug else logging.INFO)
|
||||
log.addHandler(rh)
|
||||
|
||||
|
||||
def mem_stats():
|
||||
gc.collect()
|
||||
if torch.cuda.is_available():
|
||||
@@ -62,7 +74,7 @@ def mem_stats():
|
||||
torch.cuda.ipc_collect()
|
||||
mem = util.get_memory()
|
||||
peak = { 'active': mem['gpu-active']['peak'], 'allocated': mem['gpu-allocated']['peak'], 'reserved': mem['gpu-reserved']['peak'] }
|
||||
console.log(f"memory cpu: {mem.ram} gpu current: {mem.gpu} gpu peak: {peak}")
|
||||
log.debug(f"memory cpu: {mem.ram} gpu current: {mem.gpu} gpu peak: {peak}")
|
||||
|
||||
|
||||
def parse_args():
|
||||
@@ -71,8 +83,8 @@ def parse_args():
|
||||
|
||||
group_main = parser.add_argument_group('Main')
|
||||
group_main.add_argument('--type', type=str, choices=['embedding', 'lora', 'lycoris', 'dreambooth'], default=None, required=True, help='training type')
|
||||
group_main.add_argument('--model', type=str, default='', required=False, help='base model to use for training, default: current loaded model')
|
||||
group_main.add_argument('--name', type=str, default=None, required=True, help='output filename')
|
||||
group_main.add_argument('--overwrite', default = False, action='store_true', help = "overwrite existing training, default: %(default)s")
|
||||
group_main.add_argument('--tag', type=str, default='person', required=False, help='primary tags, default: %(default)s')
|
||||
|
||||
group_data = parser.add_argument_group('Dataset')
|
||||
@@ -91,6 +103,10 @@ def parse_args():
|
||||
group_train.add_argument('--repeats', type=int, default=10, required=False, help='number of repeats per image, default: %(default)s')
|
||||
group_train.add_argument('--alpha', type=float, default=0, required=False, help='alpha for weights scaling, default: dim/2')
|
||||
|
||||
group_other = parser.add_argument_group('Other')
|
||||
group_other.add_argument('--overwrite', default = False, action='store_true', help = "overwrite existing training, default: %(default)s")
|
||||
group_other.add_argument('--debug', default = False, action='store_true', help = "enable debug level logging, default: %(default)s")
|
||||
|
||||
args = parser.parse_args()
|
||||
|
||||
|
||||
@@ -99,10 +115,10 @@ def prepare_server():
|
||||
server_status = util.Map(sdapi.progress())
|
||||
server_state = server_status['state']
|
||||
except:
|
||||
console.log('server error:', server_status)
|
||||
log.error(f'server error: {server_status}')
|
||||
exit(1)
|
||||
if server_state['job_count'] > 0:
|
||||
console.log('server not idle:', server_state)
|
||||
log.error(f'server not idle: {server_state}')
|
||||
exit(1)
|
||||
|
||||
server_options = util.Map(sdapi.options())
|
||||
@@ -114,36 +130,57 @@ def prepare_server():
|
||||
server_options.options.training_image_repeats_per_epoch = args.repeats
|
||||
server_options.options.training_write_csv_every = 0
|
||||
sdapi.postsync('/sdapi/v1/options', server_options.options)
|
||||
console.log('updated server options')
|
||||
log.info('updated server options')
|
||||
|
||||
|
||||
def verify_args():
|
||||
server_options = util.Map(sdapi.options())
|
||||
args.model = server_options.options.sd_model_checkpoint.split(' [')[0]
|
||||
if args.model != '':
|
||||
if not os.path.isfile(args.model):
|
||||
log.error(f'cannot find loaded model: {args.model}')
|
||||
exit(1)
|
||||
server_options.options.sd_model_checkpoint = args.model
|
||||
sdapi.postsync('/sdapi/v1/options', server_options.options)
|
||||
else:
|
||||
args.model = server_options.options.sd_model_checkpoint.split(' [')[0]
|
||||
args.lora_dir = server_options.options.lora_dir
|
||||
if not os.path.isabs(args.model) and not os.path.exists(args.model):
|
||||
args.model = os.path.abspath(os.path.join(args.lora_dir, os.pardir, 'Stable-diffusion', args.model))
|
||||
|
||||
if not os.path.exists(args.model) or not os.path.isfile(args.model):
|
||||
console.log('cannot find model:', args.model)
|
||||
args.lyco_dir = server_options.options.lyco_dir
|
||||
args.ckpt_dir = server_options.options.ckpt_dir
|
||||
args.embeddings_dir = server_options.options.embeddings_dir
|
||||
if not os.path.isfile(args.model):
|
||||
attempt = os.path.abspath(os.path.join(args.ckpt_dir, args.model))
|
||||
args.model = attempt if os.path.isfile(attempt) else args.model
|
||||
if not os.path.isfile(args.model):
|
||||
attempt = os.path.abspath(os.path.join(args.ckpt_dir, '..', args.model))
|
||||
args.model = attempt if os.path.isfile(attempt) else args.model
|
||||
if not os.path.isfile(args.model):
|
||||
log.error(f'cannot find loaded model: {args.model}')
|
||||
exit(1)
|
||||
if not os.path.exists(args.ckpt_dir) or not os.path.isdir(args.ckpt_dir):
|
||||
log.error(f'cannot find models folder: {args.ckpt_dir}')
|
||||
exit(1)
|
||||
if not os.path.exists(args.input) or not os.path.isdir(args.input):
|
||||
console.log('cannot find training folder:', args.input)
|
||||
log.error(f'cannot find training folder: {args.input}')
|
||||
exit(1)
|
||||
if not os.path.exists(args.lora_dir) or not os.path.isdir(args.lora_dir):
|
||||
console.log('cannot find lora folder:', args.lora_dir)
|
||||
log.error(f'cannot find lora folder: {args.lora_dir}')
|
||||
exit(1)
|
||||
if not os.path.exists(args.lyco_dir) or not os.path.isdir(args.lyco_dir):
|
||||
log.error(f'cannot find lyco folder: {args.lyco_dir}')
|
||||
exit(1)
|
||||
if args.output != '':
|
||||
args.process_dir = args.output
|
||||
else:
|
||||
args.process_dir = os.path.join(tempfile.gettempdir(), 'train', args.name)
|
||||
console.log(f'args: {vars(args)}')
|
||||
log.debug(f'args: {vars(args)}')
|
||||
log.debug(f'server flags: {server_options.flags}')
|
||||
log.debug(f'server options: {server_options.options}')
|
||||
|
||||
|
||||
async def training_loop():
|
||||
async def async_train():
|
||||
res = await sdapi.post('/sdapi/v1/train/embedding', options.embedding)
|
||||
console.log(f'train embedding result: {res}')
|
||||
log.info(f'train embedding result: {res}')
|
||||
|
||||
async def async_monitor():
|
||||
await asyncio.sleep(3)
|
||||
@@ -164,49 +201,74 @@ async def training_loop():
|
||||
|
||||
|
||||
def train_embedding():
|
||||
console.log(f'{args.type} options: {options.embedding}')
|
||||
log.info(f'{args.type} options: {options.embedding}')
|
||||
create_options = util.Map({
|
||||
"name": args.name,
|
||||
"num_vectors_per_token": args.dim,
|
||||
"overwrite_old": False,
|
||||
"init_text": args.tag,
|
||||
})
|
||||
server_options = util.Map(sdapi.options())
|
||||
fn = os.path.join(server_options.options.embeddings_dir, args.name) + '.pt'
|
||||
fn = os.path.join(args.embeddings_dir, args.name) + '.pt'
|
||||
if os.path.exists(fn) and args.overwrite:
|
||||
console.log(f'delete existing embedding {fn}')
|
||||
log.warning(f'delete existing embedding {fn}')
|
||||
os.remove(fn)
|
||||
else:
|
||||
console.log(f'embedding exists {fn}')
|
||||
log.error(f'embedding exists {fn}')
|
||||
return
|
||||
console.log(f'create embedding {create_options}')
|
||||
log.info(f'create embedding {create_options}')
|
||||
res = sdapi.postsync('/sdapi/v1/create/embedding', create_options)
|
||||
if 'info' in res and 'error' in res['info']: # formatted error
|
||||
console.log(res.info)
|
||||
log.error(res.info)
|
||||
elif 'info' in res: # no error
|
||||
asyncio.run(training_loop())
|
||||
else: # unknown error
|
||||
console.log(f'create embedding error {res}')
|
||||
log.error(f'create embedding error {res}')
|
||||
|
||||
|
||||
def train_lora():
|
||||
fn = os.path.join(args.lora_dir, args.name)
|
||||
fn = os.path.join(options.lora.output_dir, args.name)
|
||||
for ext in ['.ckpt', '.pt', '.safetensors']:
|
||||
if os.path.exists(fn + ext):
|
||||
if args.overwrite:
|
||||
console.log(f'delete existing lora: {fn + ext}')
|
||||
log.warning(f'delete existing lora: {fn + ext}')
|
||||
os.remove(fn + ext)
|
||||
else:
|
||||
console.log(f'lora exists: {fn + ext}')
|
||||
log.error(f'lora exists: {fn + ext}')
|
||||
return
|
||||
console.log(f'{args.type} options: {options.lora}')
|
||||
log.info(f'{args.type} options: {options.lora}')
|
||||
# lora imports
|
||||
lora_path = os.path.abspath(os.path.join(os.path.dirname(__file__), os.pardir, 'modules', 'lora'))
|
||||
sys.path.append(lora_path)
|
||||
if args.type == 'lycoris':
|
||||
lycoris_path = os.path.abspath(os.path.join(os.path.dirname(__file__), os.pardir, os.pardir, 'modules', 'lycoris'))
|
||||
sys.path.append(lycoris_path)
|
||||
log.debug('importing lora lib')
|
||||
import train_network
|
||||
train_network.train(options.lora)
|
||||
if args.type == 'lycoris':
|
||||
log.debug('importing lycoris lib')
|
||||
import importlib
|
||||
_network_module = importlib.import_module(options.lora.network_module)
|
||||
|
||||
|
||||
def prepare_options():
|
||||
if args.type == 'embedding':
|
||||
log.info('train embedding')
|
||||
options.lora.in_json = None
|
||||
if args.type == 'dreambooth':
|
||||
log.info('train using dreambooth style training')
|
||||
options.lora.in_json = None
|
||||
if args.type == 'lora':
|
||||
log.info('train using lora style training')
|
||||
options.lora.output_dir = args.lora_dir
|
||||
options.lora.in_json = os.path.join(args.process_dir, args.name + '.json')
|
||||
if args.type == 'lycoris':
|
||||
log.info('train using lycoris network')
|
||||
options.lora.output_dir = args.lyco_dir
|
||||
options.lora.network_module = 'lycoris.kohya'
|
||||
options.lora.in_json = os.path.join(args.process_dir, args.name + '.json')
|
||||
# lora specific
|
||||
options.lora.pretrained_model_name_or_path = args.model
|
||||
options.lora.output_dir = args.lora_dir
|
||||
options.lora.output_name = args.name
|
||||
options.lora.max_train_steps = args.steps
|
||||
options.lora.network_dim = args.dim
|
||||
@@ -216,19 +278,6 @@ def prepare_options():
|
||||
options.lora.train_batch_size = args.batch
|
||||
options.lora.network_alpha = args.dim // 2 if args.alpha == 0 else args.alpha
|
||||
options.lora.train_data_dir = args.process_dir
|
||||
if args.type == 'lycoris':
|
||||
console.log('train using lycoris network')
|
||||
options.lora.network_module = 'lycoris.kohya'
|
||||
options.lora.in_json = os.path.join(args.process_dir, args.name + '.json')
|
||||
if args.type == 'dreambooth':
|
||||
console.log('train using dreambooth style training')
|
||||
options.lora.in_json = None
|
||||
if args.type == 'lora':
|
||||
console.log('train using lora style training')
|
||||
options.lora.in_json = os.path.join(args.process_dir, args.name + '.json')
|
||||
if args.type == 'embedding':
|
||||
console.log('train embedding')
|
||||
options.lora.in_json = None
|
||||
# embedding specific
|
||||
options.embedding.embedding_name = args.name
|
||||
options.embedding.learn_rate = str(args.lr)
|
||||
@@ -243,17 +292,20 @@ def process_inputs():
|
||||
pathlib.Path(args.process_dir).mkdir(parents=True, exist_ok=True)
|
||||
processing_options = args.process.split(',') if isinstance(args.process, str) else args.process
|
||||
processing_options = [opt.strip() for opt in re.split(',| ', args.process)]
|
||||
console.log(f'processing steps: {processing_options}')
|
||||
log.info(f'processing steps: {processing_options}')
|
||||
for step in processing_options:
|
||||
if step not in valid_steps:
|
||||
console.log(f'invalid processing step: {[step]}')
|
||||
log.error(f'invalid processing step: {[step]}')
|
||||
exit(1)
|
||||
for root, _sub_dirs, folder in os.walk(args.input):
|
||||
files = [os.path.join(root, f) for f in folder if filetype.is_image(os.path.join(root, f))]
|
||||
console.log(f'processing input images: {len(files)}')
|
||||
log.info(f'processing input images: {len(files)}')
|
||||
if os.path.exists(args.process_dir):
|
||||
console.log('removing existing processed folder:', args.process_dir)
|
||||
shutil.rmtree(args.process_dir, ignore_errors=True)
|
||||
if args.overwrite:
|
||||
log.warning(f'removing existing processed folder: {args.process_dir}')
|
||||
shutil.rmtree(args.process_dir, ignore_errors=True)
|
||||
else:
|
||||
log.info(f'processed folder exists: {args.process_dir}')
|
||||
steps = [step for step in processing_options if step in ['face', 'body', 'original']]
|
||||
process.reset()
|
||||
metadata = {}
|
||||
@@ -264,7 +316,7 @@ def process_inputs():
|
||||
opts = [step for step in processing_options if step not in ['face', 'original', 'upscale', 'restore']] # body does not perform upscale or restore
|
||||
if step == 'original':
|
||||
opts = [step for step in processing_options if step not in ['face', 'body', 'upscale', 'restore', 'blur', 'range', 'segment']] # original does not perform most steps
|
||||
console.log(f'processing current step: {opts}')
|
||||
log.info(f'processing current step: {opts}')
|
||||
tag = step
|
||||
if tag == 'original' and args.tag is not None:
|
||||
concept = args.tag.split(',')[0].strip()
|
||||
@@ -274,8 +326,8 @@ def process_inputs():
|
||||
folder = os.path.join(args.process_dir, str(args.repeats) + '_' + concept) # separate concepts per folder
|
||||
if args.type in ['embedding']:
|
||||
folder = os.path.join(args.process_dir) # everything into same folder
|
||||
console.log('processing concept:', concept)
|
||||
console.log('processing output folder:', folder)
|
||||
log.info(f'processing concept: {concept}')
|
||||
log.info(f'processing output folder: {folder}')
|
||||
pathlib.Path(folder).mkdir(parents=True, exist_ok=True)
|
||||
results = {}
|
||||
for f in files:
|
||||
@@ -290,9 +342,9 @@ def process_inputs():
|
||||
if options.lora.in_json is None:
|
||||
with open(res.output.replace(options.process.format, '.txt'), "w", encoding='utf-8') as outfile:
|
||||
outfile.write(res.caption)
|
||||
console.log(f"processing {'saved' if res.image is not None else 'skipped'}: {f} => {res.output} {res.ops} {res.message}")
|
||||
log.info(f"processing {'saved' if res.image is not None else 'skipped'}: {f} => {res.output} {res.ops} {res.message}")
|
||||
folders = [os.path.join(args.process_dir, folder) for folder in os.listdir(args.process_dir) if os.path.isdir(os.path.join(args.process_dir, folder))]
|
||||
console.log(f'input datasets {folders}')
|
||||
log.info(f'input datasets {folders}')
|
||||
if options.lora.in_json is not None:
|
||||
with open(options.lora.in_json, "w", encoding='utf-8') as outfile: # write json at the end only
|
||||
outfile.write(json.dumps(metadata, indent=2))
|
||||
@@ -300,17 +352,18 @@ def process_inputs():
|
||||
latents.create_vae_latents(util.Map({ 'input': folder, 'json': options.lora.in_json }))
|
||||
latents.unload_vae()
|
||||
r = { 'inputs': len(files), 'outputs': results, 'metadata': options.lora.in_json }
|
||||
console.log(f'processing steps result: {r}')
|
||||
log.info(f'processing steps result: {r}')
|
||||
if args.gradient < 0:
|
||||
console.log(f"setting gradient accumulation to number of images: {results['total']}")
|
||||
log.info(f"setting gradient accumulation to number of images: {results['total']}")
|
||||
options.lora.gradient_accumulation_steps = results['total']
|
||||
options.embedding.gradient_step = results['total']
|
||||
process.unload()
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
console.log('train script for stable diffusion')
|
||||
log.info('train script for stable diffusion')
|
||||
parse_args()
|
||||
setup_logging()
|
||||
prepare_server()
|
||||
verify_args()
|
||||
prepare_options()
|
||||
@@ -323,7 +376,7 @@ if __name__ == '__main__':
|
||||
if args.type == 'lora' or args.type == 'lycoris' or args.type == 'dreambooth':
|
||||
train_lora()
|
||||
except KeyboardInterrupt as e:
|
||||
console.log('interrupt requested')
|
||||
log.error('interrupt requested')
|
||||
sdapi.interrupt()
|
||||
mem_stats()
|
||||
console.log('done')
|
||||
log.info('done')
|
||||
|
||||
@@ -182,7 +182,6 @@ class Api:
|
||||
script_args = default_script_args.copy()
|
||||
# position 0 in script_arg is the idx+1 of the selectable script that is going to be run when using scripts.scripts_*2img.run()
|
||||
if selectable_scripts:
|
||||
# TODO this can corrupt values for other scripts
|
||||
script_args[selectable_scripts.args_from:selectable_scripts.args_to] = request.script_args
|
||||
script_args[0] = selectable_script_idx + 1
|
||||
# Now check for always on scripts
|
||||
@@ -194,7 +193,6 @@ class Api:
|
||||
if not alwayson_script.alwayson:
|
||||
raise HTTPException(status_code=422, detail=f"Selectable script cannot be in always on params: {alwayson_script_name}")
|
||||
if "args" in request.alwayson_scripts[alwayson_script_name]:
|
||||
# TODO this can corrupt values for other scripts
|
||||
# min between arg length in scriptrunner and arg length in the request
|
||||
for idx in range(0, min((alwayson_script.args_to - alwayson_script.args_from), len(request.alwayson_scripts[alwayson_script_name]["args"]))):
|
||||
script_args[alwayson_script.args_from + idx] = request.alwayson_scripts[alwayson_script_name]["args"][idx]
|
||||
|
||||
@@ -123,7 +123,6 @@ def connect_paste_params_buttons():
|
||||
destination_height_component = next(iter([field for field, name in fields if name == "Size-2"] if fields else []), None)
|
||||
|
||||
if binding.source_image_component and destination_image_component:
|
||||
# print('HERE')
|
||||
if isinstance(binding.source_image_component, gr.Gallery):
|
||||
func = send_image_and_dimensions if destination_width_component else image_from_url_text
|
||||
jsfunc = "extract_image_from_gallery"
|
||||
|
||||
+1
-1
@@ -606,7 +606,7 @@ cmd_opts = cmd_args.compatibility_args(opts, cmd_opts)
|
||||
|
||||
os.makedirs(opts.hypernetwork_dir, exist_ok=True)
|
||||
prompt_styles = modules.styles.StyleDatabase(opts.styles_dir)
|
||||
cmd_opts.disable_extension_access = (cmd_opts.share or cmd_opts.listen or cmd_opts.server_name) and not cmd_opts.insecure
|
||||
cmd_opts.disable_extension_access = (cmd_opts.share or cmd_opts.listen or (cmd_opts.server_name or False)) and not cmd_opts.insecure
|
||||
devices.device, devices.device_interrogate, devices.device_gfpgan, devices.device_esrgan, devices.device_codeformer = (devices.cpu if any(y in cmd_opts.use_cpu for y in [x, 'all']) else devices.get_optimal_device() for x in ['sd', 'interrogate', 'gfpgan', 'esrgan', 'codeformer'])
|
||||
device = devices.device
|
||||
batch_cond_uncond = opts.always_batch_cond_uncond or not (cmd_opts.lowvram or cmd_opts.medvram)
|
||||
|
||||
+10
-13
@@ -14,6 +14,8 @@ from modules import sd_hijack, sd_models, script_callbacks, ui_extensions, deepb
|
||||
from modules.ui_components import FormRow, FormColumn, FormGroup, ToolButton, FormHTML # pylint: disable=unused-import
|
||||
from modules.paths import script_path, data_path
|
||||
from modules.shared import opts, cmd_opts
|
||||
from modules.sd_samplers import samplers, samplers_for_img2img
|
||||
from modules import prompt_parser
|
||||
import modules.codeformer_model
|
||||
import modules.generation_parameters_copypaste as parameters_copypaste
|
||||
import modules.gfpgan_model
|
||||
@@ -22,13 +24,9 @@ import modules.scripts
|
||||
import modules.shared as shared
|
||||
import modules.errors as errors
|
||||
import modules.styles
|
||||
import modules.textual_inversion.ui
|
||||
from modules import prompt_parser
|
||||
from modules.sd_hijack import model_hijack
|
||||
from modules.sd_samplers import samplers, samplers_for_img2img
|
||||
from modules.textual_inversion import textual_inversion
|
||||
from modules.generation_parameters_copypaste import image_from_url_text
|
||||
import modules.extras
|
||||
import modules.textual_inversion.ui
|
||||
from modules.textual_inversion import textual_inversion
|
||||
|
||||
errors.install()
|
||||
mimetypes.init()
|
||||
@@ -67,7 +65,8 @@ def plaintext_to_html(text):
|
||||
def send_gradio_gallery_to_image(x):
|
||||
if len(x) == 0:
|
||||
return None
|
||||
return image_from_url_text(x[0])
|
||||
return parameters_copypaste.image_from_url_text(x[0])
|
||||
|
||||
|
||||
def visit(x, func, path=""):
|
||||
if hasattr(x, 'children'):
|
||||
@@ -208,7 +207,7 @@ def update_token_counter(text, steps):
|
||||
prompt_schedules = [[[steps, text]]]
|
||||
flat_prompts = reduce(lambda list1, list2: list1+list2, prompt_schedules)
|
||||
prompts = [prompt_text for step, prompt_text in flat_prompts]
|
||||
token_count, max_length = max([model_hijack.get_prompt_lengths(prompt) for prompt in prompts], key=lambda args: args[0])
|
||||
token_count, max_length = max([sd_hijack.model_hijack.get_prompt_lengths(prompt) for prompt in prompts], key=lambda args: args[0])
|
||||
return f"<span class='gr-box gr-text-input'>{token_count}/{max_length}</span>"
|
||||
|
||||
|
||||
@@ -460,7 +459,7 @@ def create_ui():
|
||||
res_switch_btn.click(lambda w, h: (h, w), inputs=[width, height], outputs=[width, height], show_progress=False)
|
||||
|
||||
txt_prompt_img.change(
|
||||
fn=modules.images.image_data,
|
||||
fn=modules.images.image_data, # TODO
|
||||
inputs=[
|
||||
txt_prompt_img
|
||||
],
|
||||
@@ -503,9 +502,7 @@ def create_ui():
|
||||
*modules.scripts.scripts_txt2img.infotext_fields
|
||||
]
|
||||
parameters_copypaste.add_paste_fields("txt2img", None, txt2img_paste_fields, override_settings)
|
||||
parameters_copypaste.register_paste_params_button(parameters_copypaste.ParamBinding(
|
||||
paste_button=txt2img_paste, tabname="txt2img", source_text_component=txt2img_prompt, source_image_component=None,
|
||||
))
|
||||
parameters_copypaste.register_paste_params_button(parameters_copypaste.ParamBinding(paste_button=txt2img_paste, tabname="txt2img", source_text_component=txt2img_prompt, source_image_component=None))
|
||||
|
||||
txt2img_preview_params = [
|
||||
txt2img_prompt,
|
||||
@@ -736,7 +733,7 @@ def create_ui():
|
||||
connect_reuse_seed(subseed, reuse_subseed, generation_info, dummy_component, is_subseed=True)
|
||||
|
||||
img2img_prompt_img.change(
|
||||
fn=modules.images.image_data,
|
||||
fn=modules.images.image_data, # TODO
|
||||
inputs=[
|
||||
img2img_prompt_img
|
||||
],
|
||||
|
||||
@@ -18,25 +18,17 @@ def create_ui():
|
||||
with gr.Row().style(equal_height=False, variant='compact'):
|
||||
with gr.Column(variant='compact'):
|
||||
with gr.Tabs(elem_id="mode_extras"):
|
||||
|
||||
with gr.TabItem('Single Image', id="single_image", elem_id="extras_single_tab") as tab_single:
|
||||
extras_image = gr.Image(label="Source", source="upload", interactive=True, type="pil", elem_id="extras_image")
|
||||
|
||||
with gr.TabItem('Process Batch', id="batch_process", elem_id="extras_batch_process_tab") as tab_batch:
|
||||
image_batch = gr.Files(label="Batch Process", interactive=True, elem_id="extras_image_batch")
|
||||
|
||||
with gr.TabItem('Process Folder', id="batch_from_directory", elem_id="extras_batch_directory_tab") as tab_batch_dir:
|
||||
extras_batch_input_dir = gr.Textbox(label="Input directory", **shared.hide_dirs, placeholder="A directory on the same machine where the server is running.", elem_id="extras_batch_input_dir")
|
||||
extras_batch_output_dir = gr.Textbox(label="Output directory", **shared.hide_dirs, placeholder="Leave blank to save images to the default path.", elem_id="extras_batch_output_dir")
|
||||
show_extras_results = gr.Checkbox(label='Show result images', value=True, elem_id="extras_show_extras_results")
|
||||
|
||||
with gr.Row():
|
||||
buttons = parameters_copypaste.create_buttons(["txt2img", "img2img", "inpaint"])
|
||||
|
||||
# submit = gr.Button('Generate', elem_id="extras_generate", variant='primary') # TODO: add all
|
||||
|
||||
script_inputs = scripts.scripts_postproc.setup_ui()
|
||||
|
||||
with gr.Column():
|
||||
id_part = 'extras'
|
||||
with gr.Row(elem_id=f"{id_part}_generate_box", elem_classes="generate-box"):
|
||||
@@ -45,15 +37,12 @@ def create_ui():
|
||||
skip = gr.Button('Skip', elem_id=f"{id_part}_skip", variant='secondary')
|
||||
skip.click(fn=lambda: shared.state.skip(), inputs=[], outputs=[])
|
||||
interrupt.click(fn=lambda: shared.state.interrupt(), inputs=[], outputs=[])
|
||||
|
||||
result_images, html_info_x, html_info, _html_log = ui_common.create_output_panel("extras", shared.opts.outdir_extras_samples)
|
||||
html_info = gr.HTML(elem_id="pnginfo_html_info")
|
||||
generation_info = gr.Textbox(elem_id="pnginfo_generation_info", label="Parameters", visible=False)
|
||||
generation_info_pretty = gr.Textbox(elem_id="pnginfo_generation_info_pretty", label="Parameters")
|
||||
|
||||
gr.HTML('Full metadata')
|
||||
html2_info = gr.HTML(elem_id="pnginfo_html2_info")
|
||||
|
||||
for tabname, button in buttons.items():
|
||||
parameters_copypaste.register_paste_params_button(parameters_copypaste.ParamBinding(paste_button=button, tabname=tabname, source_text_component=generation_info, source_image_component=extras_image))
|
||||
|
||||
@@ -69,15 +58,12 @@ def create_ui():
|
||||
tab_single.select(fn=lambda: 0, inputs=[], outputs=[tab_index])
|
||||
tab_batch.select(fn=lambda: 1, inputs=[], outputs=[tab_index])
|
||||
tab_batch_dir.select(fn=lambda: 2, inputs=[], outputs=[tab_index])
|
||||
|
||||
generation_info.change(fn=pretty_geninfo, inputs=[generation_info], outputs=[generation_info_pretty])
|
||||
|
||||
extras_image.change(
|
||||
fn=wrap_gradio_call(run_pnginfo),
|
||||
inputs=[extras_image],
|
||||
outputs=[html_info, generation_info, html2_info],
|
||||
)
|
||||
|
||||
submit.click(
|
||||
fn=call_queue.wrap_gradio_gpu_call(submit_click, extra_outputs=[None, '']),
|
||||
inputs=[
|
||||
|
||||
Reference in New Issue
Block a user