2022-08-21 23:57:48 +00:00
#!/usr/bin/env python3
2022-08-24 13:22:04 +00:00
# Copyright (c) 2022 Lincoln D. Stein (https://github.com/lstein)
2022-08-17 01:34:37 +00:00
import argparse
import shlex
2022-08-17 02:49:47 +00:00
import os
2022-08-29 16:54:40 +00:00
import re
2022-08-21 15:03:22 +00:00
import sys
2022-08-24 16:02:36 +00:00
import copy
2022-08-26 05:20:01 +00:00
import warnings
2022-08-31 04:33:23 +00:00
import time
2022-08-26 02:49:15 +00:00
import ldm . dream . readline
2022-08-26 07:15:42 +00:00
from ldm . dream . pngwriter import PngWriter , PromptFormatter
2022-08-28 20:37:27 +00:00
from ldm . dream . server import DreamServer , ThreadingDreamServer
2022-08-31 04:36:38 +00:00
from ldm . dream . image_util import make_grid
2022-09-01 18:04:31 +00:00
from omegaconf import OmegaConf
2022-08-18 16:43:59 +00:00
2022-09-09 22:49:51 +00:00
# Placeholder to be replaced with proper class that tracks the
# outputs and associates with the prompt that generated them.
# Just want to get the formatting look right for now.
output_cntr = 0
2022-09-11 19:47:12 +00:00
2022-08-17 01:34:37 +00:00
def main ( ) :
2022-08-26 07:15:42 +00:00
""" Initialize command-line parsers and the diffusion model """
2022-08-17 01:34:37 +00:00
arg_parser = create_argv_parser ( )
2022-08-26 07:15:42 +00:00
opt = arg_parser . parse_args ( )
2022-09-11 19:47:12 +00:00
2022-08-17 01:34:37 +00:00
if opt . laion400m :
2022-09-01 19:46:53 +00:00
print ( ' --laion400m flag has been deprecated. Please use --model laion400m instead. ' )
sys . exit ( - 1 )
if opt . weights != ' model ' :
2022-09-03 15:36:04 +00:00
print ( ' --weights argument has been deprecated. Please configure ./configs/models.yaml, and call it using --model instead. ' )
2022-09-01 19:46:53 +00:00
sys . exit ( - 1 )
2022-09-11 19:47:12 +00:00
2022-09-01 18:04:31 +00:00
try :
2022-09-11 19:47:12 +00:00
models = OmegaConf . load ( opt . config )
width = models [ opt . model ] . width
height = models [ opt . model ] . height
config = models [ opt . model ] . config
2022-09-01 18:04:31 +00:00
weights = models [ opt . model ] . weights
except ( FileNotFoundError , IOError , KeyError ) as e :
print ( f ' { e } . Aborting. ' )
2022-09-01 19:46:53 +00:00
sys . exit ( - 1 )
2022-08-17 01:34:37 +00:00
2022-08-26 07:15:42 +00:00
print ( ' * Initializing, be patient... \n ' )
2022-08-21 15:03:22 +00:00
sys . path . append ( ' . ' )
2022-08-17 01:34:37 +00:00
from pytorch_lightning import logging
2022-09-06 00:40:10 +00:00
from ldm . generate import Generate
2022-08-26 07:15:42 +00:00
2022-08-22 19:33:27 +00:00
# these two lines prevent a horrible warning message from appearing
# when the frozen CLIP tokenizer is imported
import transformers
2022-08-26 07:15:42 +00:00
2022-08-22 19:33:27 +00:00
transformers . logging . set_verbosity_error ( )
2022-08-26 07:15:42 +00:00
2022-08-17 01:34:37 +00:00
# creating a simple text2image object with a handful of
# defaults passed on the command line.
# additional parameters will be added (or overriden) during
# the user input loop
2022-09-06 00:40:10 +00:00
t2i = Generate (
2022-09-11 19:47:12 +00:00
width = width ,
height = height ,
sampler_name = opt . sampler_name ,
weights = weights ,
full_precision = opt . full_precision ,
config = config ,
grid = opt . grid ,
2022-08-28 04:05:00 +00:00
# this is solely for recreating the prompt
2022-09-11 19:47:12 +00:00
seamless = opt . seamless ,
embedding_path = opt . embedding_path ,
device_type = opt . device ,
ignore_ctrl_c = opt . infile is None ,
2022-08-22 02:48:40 +00:00
)
2022-08-17 01:34:37 +00:00
2022-08-17 02:49:47 +00:00
# make sure the output directory exists
if not os . path . exists ( opt . outdir ) :
os . makedirs ( opt . outdir )
2022-08-26 07:15:42 +00:00
2022-08-17 01:34:37 +00:00
# gets rid of annoying messages about random seed
2022-08-26 07:15:42 +00:00
logging . getLogger ( ' pytorch_lightning ' ) . setLevel ( logging . ERROR )
2022-08-17 01:34:37 +00:00
2022-08-26 11:10:37 +00:00
# load the infile as a list of lines
2022-08-23 04:30:06 +00:00
infile = None
2022-08-26 11:10:37 +00:00
if opt . infile :
2022-08-28 18:20:34 +00:00
try :
if os . path . isfile ( opt . infile ) :
2022-08-29 02:57:13 +00:00
infile = open ( opt . infile , ' r ' , encoding = ' utf-8 ' )
2022-08-28 20:14:29 +00:00
elif opt . infile == ' - ' : # stdin
2022-08-28 18:20:34 +00:00
infile = sys . stdin
else :
raise FileNotFoundError ( f ' { opt . infile } not found. ' )
2022-08-28 20:14:29 +00:00
except ( FileNotFoundError , IOError ) as e :
2022-08-28 18:20:34 +00:00
print ( f ' { e } . Aborting. ' )
sys . exit ( - 1 )
2022-08-23 04:30:06 +00:00
2022-09-03 13:39:35 +00:00
if opt . seamless :
print ( " >> changed to seamless tiling mode " )
2022-08-17 01:34:37 +00:00
# preload the model
2022-08-24 16:57:04 +00:00
t2i . load_model ( )
2022-08-26 02:57:30 +00:00
2022-08-28 18:20:34 +00:00
if not infile :
print (
2022-08-28 19:54:12 +00:00
" \n * Initialization done! Awaiting your command (-h for help, ' q ' to quit) "
2022-08-28 18:20:34 +00:00
)
2022-08-17 01:34:37 +00:00
2022-08-29 00:34:55 +00:00
cmd_parser = create_cmd_parser ( )
if opt . web :
2022-09-06 00:35:04 +00:00
dream_server_loop ( t2i , opt . host , opt . port , opt . outdir )
2022-08-29 00:34:55 +00:00
else :
2022-08-29 16:54:40 +00:00
main_loop ( t2i , opt . outdir , opt . prompt_as_dir , cmd_parser , infile )
2022-08-17 01:34:37 +00:00
2022-08-19 03:23:44 +00:00
2022-08-29 16:54:40 +00:00
def main_loop ( t2i , outdir , prompt_as_dir , parser , infile ) :
2022-08-26 07:15:42 +00:00
""" prompt/read/execute loop """
2022-09-11 19:47:12 +00:00
done = False
path_filter = re . compile ( r ' [<>: " / \\ |?*] ' )
2022-09-11 14:52:19 +00:00
last_results = list ( )
2022-08-29 16:54:40 +00:00
# os.pathconf is not available on Windows
if hasattr ( os , ' pathconf ' ) :
path_max = os . pathconf ( outdir , ' PC_PATH_MAX ' )
name_max = os . pathconf ( outdir , ' PC_NAME_MAX ' )
else :
path_max = 260
name_max = 255
2022-08-26 07:15:42 +00:00
2022-08-19 03:03:22 +00:00
while not done :
2022-08-17 01:34:37 +00:00
try :
2022-08-28 18:20:34 +00:00
command = get_next_command ( infile )
2022-08-17 01:34:37 +00:00
except EOFError :
2022-08-19 03:03:22 +00:00
done = True
2022-09-11 14:02:44 +00:00
continue
except KeyboardInterrupt :
done = True
continue
2022-09-11 19:47:12 +00:00
2022-08-26 11:10:37 +00:00
# skip empty lines
if not command . strip ( ) :
continue
2022-08-23 04:30:06 +00:00
2022-08-26 07:15:42 +00:00
if command . startswith ( ( ' # ' , ' // ' ) ) :
2022-08-23 04:30:06 +00:00
continue
2022-08-23 17:46:50 +00:00
# before splitting, escape single quotes so as not to mess
# up the parser
2022-08-26 07:15:42 +00:00
command = command . replace ( " ' " , " \\ ' " )
2022-08-23 17:46:50 +00:00
2022-08-22 20:55:06 +00:00
try :
elements = shlex . split ( command )
except ValueError as e :
print ( str ( e ) )
continue
2022-08-26 07:15:42 +00:00
if elements [ 0 ] == ' q ' :
2022-08-19 03:03:22 +00:00
done = True
break
2022-08-23 01:01:06 +00:00
2022-08-26 07:15:42 +00:00
if elements [ 0 ] . startswith (
' !dream '
) : # in case a stored prompt still contains the !dream command
2022-08-19 03:03:22 +00:00
elements . pop ( 0 )
2022-08-26 07:15:42 +00:00
2022-08-19 03:03:22 +00:00
# rearrange the arguments to mimic how it works in the Dream bot.
2022-08-17 01:34:37 +00:00
switches = [ ' ' ]
switches_started = False
for el in elements :
2022-08-26 07:15:42 +00:00
if el [ 0 ] == ' - ' and not switches_started :
2022-08-17 01:34:37 +00:00
switches_started = True
if switches_started :
switches . append ( el )
else :
switches [ 0 ] + = el
switches [ 0 ] + = ' '
2022-08-26 07:15:42 +00:00
switches [ 0 ] = switches [ 0 ] [ : len ( switches [ 0 ] ) - 1 ]
2022-08-17 16:35:49 +00:00
2022-08-17 01:34:37 +00:00
try :
2022-08-26 07:15:42 +00:00
opt = parser . parse_args ( switches )
2022-08-17 01:34:37 +00:00
except SystemExit :
parser . print_help ( )
2022-08-17 16:35:49 +00:00
continue
2022-08-26 07:15:42 +00:00
if len ( opt . prompt ) == 0 :
print ( ' Try again with a prompt! ' )
2022-08-17 16:35:49 +00:00
continue
2022-09-11 19:47:12 +00:00
# retrieve previous value!
if opt . init_img is not None and re . match ( ' ^- \\ d+$ ' , opt . init_img ) :
2022-09-11 14:52:19 +00:00
try :
opt . init_img = last_results [ int ( opt . init_img ) ] [ 0 ]
print ( f ' >> Reusing previous image { opt . init_img } ' )
except IndexError :
2022-09-11 19:47:12 +00:00
print (
f ' >> No previous initial image at position { opt . init_img } found ' )
2022-09-11 14:52:19 +00:00
opt . init_img = None
continue
2022-09-11 19:47:12 +00:00
2022-08-26 07:15:42 +00:00
if opt . seed is not None and opt . seed < 0 : # retrieve previous value!
2022-08-26 06:17:14 +00:00
try :
2022-09-11 14:52:19 +00:00
opt . seed = last_results [ opt . seed ] [ 1 ]
print ( f ' >> Reusing previous seed { opt . seed } ' )
2022-08-26 06:17:14 +00:00
except IndexError :
2022-09-11 14:52:19 +00:00
print ( f ' >> No previous seed at position { opt . seed } found ' )
2022-08-26 06:17:14 +00:00
opt . seed = None
2022-09-11 14:52:19 +00:00
continue
2022-08-26 07:15:42 +00:00
2022-09-11 19:47:12 +00:00
do_grid = opt . grid or t2i . grid
2022-09-01 02:31:52 +00:00
if opt . with_variations is not None :
# shotgun parsing, woo
parts = [ ]
2022-09-11 19:47:12 +00:00
broken = False # python doesn't have labeled loops...
2022-09-03 06:36:44 +00:00
for part in opt . with_variations . split ( ' , ' ) :
seed_and_weight = part . split ( ' : ' )
2022-09-01 02:31:52 +00:00
if len ( seed_and_weight ) != 2 :
print ( f ' could not parse with_variation part " { part } " ' )
broken = True
break
try :
seed = int ( seed_and_weight [ 0 ] )
weight = float ( seed_and_weight [ 1 ] )
except ValueError :
print ( f ' could not parse with_variation part " { part } " ' )
broken = True
break
parts . append ( [ seed , weight ] )
if broken :
continue
if len ( parts ) > 0 :
opt . with_variations = parts
else :
opt . with_variations = None
2022-08-25 04:42:37 +00:00
2022-08-28 19:54:12 +00:00
if opt . outdir :
if not os . path . exists ( opt . outdir ) :
os . makedirs ( opt . outdir )
current_outdir = opt . outdir
2022-08-29 16:54:40 +00:00
elif prompt_as_dir :
2022-08-30 00:10:15 +00:00
# sanitize the prompt to a valid folder name
subdir = path_filter . sub ( ' _ ' , opt . prompt ) [ : name_max ] . rstrip ( ' . ' )
2022-08-29 16:54:40 +00:00
# truncate path to maximum allowed length
2022-08-30 00:10:15 +00:00
# 27 is the length of '######.##########.##.png', plus two separators and a NUL
2022-08-29 16:54:40 +00:00
subdir = subdir [ : ( path_max - 27 - len ( os . path . abspath ( outdir ) ) ) ]
current_outdir = os . path . join ( outdir , subdir )
2022-09-11 19:47:12 +00:00
print ( ' Writing files to directory: " ' + current_outdir + ' " ' )
2022-08-29 16:54:40 +00:00
# make sure the output directory exists
if not os . path . exists ( current_outdir ) :
os . makedirs ( current_outdir )
2022-08-28 19:54:12 +00:00
else :
current_outdir = outdir
2022-08-24 23:47:59 +00:00
2022-08-28 17:05:01 +00:00
# Here is where the images are actually generated!
2022-09-11 14:52:19 +00:00
last_results = [ ]
2022-08-24 13:22:04 +00:00
try :
2022-08-31 04:21:04 +00:00
file_writer = PngWriter ( current_outdir )
2022-09-11 19:47:12 +00:00
prefix = file_writer . unique_prefix ( )
results = [ ] # list of filename, prompt pairs
grid_images = dict ( ) # seed -> Image, only used if `do_grid`
2022-08-31 04:21:04 +00:00
def image_writer ( image , seed , upscaled = False ) :
if do_grid :
grid_images [ seed ] = image
else :
if upscaled and opt . save_original :
filename = f ' { prefix } . { seed } .postprocessed.png '
else :
filename = f ' { prefix } . { seed } .png '
2022-09-01 02:31:52 +00:00
if opt . variation_amount > 0 :
2022-09-11 19:47:12 +00:00
iter_opt = argparse . Namespace ( * * vars ( opt ) ) # copy
2022-09-01 02:31:52 +00:00
this_variation = [ [ seed , opt . variation_amount ] ]
if opt . with_variations is None :
iter_opt . with_variations = this_variation
else :
iter_opt . with_variations = opt . with_variations + this_variation
iter_opt . variation_amount = 0
2022-09-11 19:47:12 +00:00
normalized_prompt = PromptFormatter (
t2i , iter_opt ) . normalize_prompt ( )
2022-09-01 02:31:52 +00:00
metadata_prompt = f ' { normalized_prompt } -S { iter_opt . seed } '
elif opt . with_variations is not None :
2022-09-11 19:47:12 +00:00
normalized_prompt = PromptFormatter (
t2i , opt ) . normalize_prompt ( )
# use the original seed - the per-iteration value is the last variation-seed
metadata_prompt = f ' { normalized_prompt } -S { opt . seed } '
2022-09-01 02:31:52 +00:00
else :
2022-09-11 19:47:12 +00:00
normalized_prompt = PromptFormatter (
t2i , opt ) . normalize_prompt ( )
2022-09-01 02:31:52 +00:00
metadata_prompt = f ' { normalized_prompt } -S { seed } '
2022-09-11 19:47:12 +00:00
path = file_writer . save_image_and_prompt_to_png (
image , metadata_prompt , filename )
2022-08-31 04:21:04 +00:00
if ( not upscaled ) or opt . save_original :
# only append to results if we didn't overwrite an earlier output
2022-09-01 02:31:52 +00:00
results . append ( [ path , metadata_prompt ] )
2022-09-11 19:47:12 +00:00
last_results . append ( [ path , seed ] )
2022-08-31 04:21:04 +00:00
t2i . prompt2image ( image_callback = image_writer , * * vars ( opt ) )
if do_grid and len ( grid_images ) > 0 :
2022-09-11 19:47:12 +00:00
grid_img = make_grid ( list ( grid_images . values ( ) ) )
2022-09-11 14:52:19 +00:00
first_seed = last_results [ 0 ] [ 1 ]
2022-09-11 19:47:12 +00:00
filename = f ' { prefix } . { first_seed } .png '
2022-08-31 04:21:04 +00:00
# TODO better metadata for grid images
2022-09-11 19:47:12 +00:00
normalized_prompt = PromptFormatter (
t2i , opt ) . normalize_prompt ( )
2022-09-01 02:31:52 +00:00
metadata_prompt = f ' { normalized_prompt } -S { first_seed } --grid -N { len ( grid_images ) } '
2022-08-31 04:21:04 +00:00
path = file_writer . save_image_and_prompt_to_png (
2022-08-26 07:15:42 +00:00
grid_img , metadata_prompt , filename
)
2022-09-01 02:31:52 +00:00
results = [ [ path , metadata_prompt ] ]
2022-08-25 04:42:37 +00:00
2022-08-24 13:22:04 +00:00
except AssertionError as e :
print ( e )
continue
2022-08-24 15:42:44 +00:00
2022-08-25 21:26:48 +00:00
except OSError as e :
print ( e )
continue
2022-09-11 19:47:12 +00:00
print ( ' Outputs: ' )
2022-08-29 00:34:55 +00:00
log_path = os . path . join ( current_outdir , ' dream_log.txt ' )
2022-09-01 02:31:52 +00:00
write_log_message ( results , log_path )
2022-08-26 07:15:42 +00:00
2022-09-11 19:47:12 +00:00
print ( ' goodbye! ' )
2022-08-19 03:23:44 +00:00
2022-08-19 03:03:22 +00:00
2022-09-11 19:47:12 +00:00
def get_next_command ( infile = None ) - > str : # command string
2022-08-28 18:20:34 +00:00
if infile is None :
2022-09-11 19:47:12 +00:00
command = input ( ' dream> ' )
2022-08-28 18:20:34 +00:00
else :
command = infile . readline ( )
if not command :
raise EOFError
else :
command = command . strip ( )
print ( f ' # { command } ' )
return command
2022-08-29 02:57:13 +00:00
2022-09-11 19:47:12 +00:00
2022-09-06 00:35:04 +00:00
def dream_server_loop ( t2i , host , port , outdir ) :
2022-08-28 20:37:27 +00:00
print ( ' \n * --web was specified, starting web server... ' )
# Change working directory to the stable-diffusion directory
os . chdir (
os . path . abspath ( os . path . join ( os . path . dirname ( __file__ ) , ' .. ' ) )
)
2022-08-26 02:57:30 +00:00
2022-08-28 20:37:27 +00:00
# Start server
DreamServer . model = t2i
2022-09-06 00:35:04 +00:00
DreamServer . outdir = outdir
2022-09-02 14:43:32 +00:00
dream_server = ThreadingDreamServer ( ( host , port ) )
2022-09-03 13:33:02 +00:00
print ( " >> Started Stable Diffusion dream server! " )
2022-09-02 18:56:52 +00:00
if host == ' 0.0.0.0 ' :
2022-09-11 19:47:12 +00:00
print (
f " Point your browser at http://localhost: { port } or use the host ' s DNS name or IP address. " )
2022-09-02 18:56:52 +00:00
else :
2022-09-03 13:33:02 +00:00
print ( " >> Default host address now 127.0.0.1 (localhost). Use --host 0.0.0.0 to bind any address. " )
print ( f " >> Point your browser at http:// { host } : { port } . " )
2022-08-28 20:37:27 +00:00
try :
dream_server . serve_forever ( )
except KeyboardInterrupt :
pass
dream_server . server_close ( )
2022-08-26 07:15:42 +00:00
2022-08-22 02:48:40 +00:00
2022-09-01 02:31:52 +00:00
def write_log_message ( results , log_path ) :
2022-08-29 00:34:55 +00:00
""" logs the name of the output image, prompt, and prompt args to the terminal and log file """
2022-09-09 22:49:51 +00:00
global output_cntr
2022-09-01 02:31:52 +00:00
log_lines = [ f ' { path } : { prompt } \n ' for path , prompt in results ]
2022-09-09 22:49:51 +00:00
for l in log_lines :
output_cntr + = 1
2022-09-11 19:47:12 +00:00
print ( output_cntr )
2022-08-22 02:48:40 +00:00
2022-08-29 02:57:13 +00:00
with open ( log_path , ' a ' , encoding = ' utf-8 ' ) as file :
2022-08-26 11:22:53 +00:00
file . writelines ( log_lines )
2022-08-22 02:48:40 +00:00
2022-08-26 07:15:42 +00:00
2022-09-11 19:47:12 +00:00
SAMPLER_CHOICES = [
2022-08-29 00:34:55 +00:00
' ddim ' ,
' k_dpm_2_a ' ,
' k_dpm_2 ' ,
' k_euler_a ' ,
' k_euler ' ,
' k_heun ' ,
' k_lms ' ,
' plms ' ,
]
2022-08-26 07:15:42 +00:00
2022-09-11 19:47:12 +00:00
2022-08-17 01:34:37 +00:00
def create_argv_parser ( ) :
2022-08-26 07:15:42 +00:00
parser = argparse . ArgumentParser (
2022-08-29 17:39:20 +00:00
description = """ Generate images using Stable Diffusion.
Use - - web to launch the web interface .
Use - - from_file to load prompts from a file path or standard input ( " - " ) .
Otherwise you will be dropped into an interactive command prompt ( type - h for help . )
Other command - line arguments are defaults that can usually be overridden
prompt the command prompt .
"""
2022-08-26 07:15:42 +00:00
)
parser . add_argument (
' --laion400m ' ,
' --latent_diffusion ' ,
' -l ' ,
dest = ' laion400m ' ,
action = ' store_true ' ,
2022-08-29 00:34:55 +00:00
help = ' Fallback to the latent diffusion (laion400m) weights and config ' ,
2022-08-26 07:15:42 +00:00
)
parser . add_argument (
' --from_file ' ,
dest = ' infile ' ,
type = str ,
2022-08-29 00:34:55 +00:00
help = ' If specified, load prompts from this file ' ,
2022-08-26 07:15:42 +00:00
)
parser . add_argument (
' -n ' ,
' --iterations ' ,
type = int ,
default = 1 ,
2022-08-29 00:34:55 +00:00
help = ' Number of images to generate ' ,
2022-08-26 07:15:42 +00:00
)
parser . add_argument (
' -F ' ,
' --full_precision ' ,
dest = ' full_precision ' ,
action = ' store_true ' ,
2022-09-03 13:43:18 +00:00
help = ' Use more memory-intensive full precision math for calculations ' ,
2022-08-26 07:15:42 +00:00
)
parser . add_argument (
2022-08-29 17:39:20 +00:00
' -g ' ,
' --grid ' ,
action = ' store_true ' ,
help = ' Generate a grid instead of individual images ' ,
)
2022-08-26 07:15:42 +00:00
parser . add_argument (
2022-08-28 23:01:45 +00:00
' -A ' ,
2022-08-26 07:15:42 +00:00
' -m ' ,
2022-08-28 23:01:45 +00:00
' --sampler ' ,
2022-08-26 07:15:42 +00:00
dest = ' sampler_name ' ,
2022-08-29 00:34:55 +00:00
choices = SAMPLER_CHOICES ,
metavar = ' SAMPLER_NAME ' ,
2022-08-26 07:15:42 +00:00
default = ' k_lms ' ,
2022-08-29 00:34:55 +00:00
help = f ' Set the initial sampler. Default: k_lms. Supported samplers: { " , " . join ( SAMPLER_CHOICES ) } ' ,
2022-08-26 07:15:42 +00:00
)
parser . add_argument (
' --outdir ' ,
' -o ' ,
type = str ,
default = ' outputs/img-samples ' ,
2022-08-29 00:34:55 +00:00
help = ' Directory to save generated images and a log of prompts and seeds. Default: outputs/img-samples ' ,
2022-08-26 07:15:42 +00:00
)
2022-09-03 06:13:31 +00:00
parser . add_argument (
' --seamless ' ,
action = ' store_true ' ,
help = ' Change the model to seamless tiling (circular) mode ' ,
)
2022-08-26 07:15:42 +00:00
parser . add_argument (
' --embedding_path ' ,
type = str ,
help = ' Path to a pre-trained embedding manager checkpoint - can only be set on command line ' ,
)
2022-08-29 16:54:40 +00:00
parser . add_argument (
' --prompt_as_dir ' ,
' -p ' ,
2022-08-30 00:10:15 +00:00
action = ' store_true ' ,
help = ' Place images in subdirectories named after the prompt. ' ,
2022-08-29 16:54:40 +00:00
)
2022-08-26 02:57:30 +00:00
# GFPGAN related args
2022-08-26 07:15:42 +00:00
parser . add_argument (
' --gfpgan_bg_upsampler ' ,
type = str ,
default = ' realesrgan ' ,
2022-09-05 01:39:15 +00:00
help = ' Background upsampler. Default: realesrgan. Options: realesrgan, none. ' ,
2022-08-29 19:12:14 +00:00
2022-08-26 07:15:42 +00:00
)
parser . add_argument (
' --gfpgan_bg_tile ' ,
type = int ,
default = 400 ,
2022-08-28 21:26:39 +00:00
help = ' Tile size for background sampler, 0 for no tile during testing. Default: 400. ' ,
2022-08-26 07:15:42 +00:00
)
parser . add_argument (
' --gfpgan_model_path ' ,
type = str ,
default = ' experiments/pretrained_models/GFPGANv1.3.pth ' ,
2022-08-29 00:34:55 +00:00
help = ' Indicates the path to the GFPGAN model, relative to --gfpgan_dir. ' ,
2022-08-26 07:15:42 +00:00
)
parser . add_argument (
' --gfpgan_dir ' ,
type = str ,
2022-09-11 16:47:26 +00:00
default = ' ./src/gfpgan ' ,
2022-08-29 00:34:55 +00:00
help = ' Indicates the directory containing the GFPGAN code. ' ,
2022-08-26 07:15:42 +00:00
)
2022-08-28 20:37:27 +00:00
parser . add_argument (
' --web ' ,
dest = ' web ' ,
action = ' store_true ' ,
2022-08-29 00:34:55 +00:00
help = ' Start in web server mode. ' ,
2022-08-26 07:15:42 +00:00
)
2022-08-31 18:20:28 +00:00
parser . add_argument (
2022-09-02 14:43:32 +00:00
' --host ' ,
type = str ,
default = ' 127.0.0.1 ' ,
2022-09-02 18:58:57 +00:00
help = ' Web server: Host or IP to listen on. Set to 0.0.0.0 to accept traffic from other devices on your network. '
2022-09-02 14:43:32 +00:00
)
parser . add_argument (
' --port ' ,
type = int ,
default = ' 9090 ' ,
help = ' Web server: Port to listen on '
)
2022-08-31 18:20:28 +00:00
parser . add_argument (
' --weights ' ,
default = ' model ' ,
help = ' Indicates the Stable Diffusion model to use. ' ,
)
2022-09-01 21:54:01 +00:00
parser . add_argument (
' --device ' ,
' -d ' ,
type = str ,
default = ' cuda ' ,
help = " device to run stable diffusion on. defaults to cuda `torch.cuda.current_device()` if available "
)
2022-09-01 18:04:31 +00:00
parser . add_argument (
' --model ' ,
default = ' stable-diffusion-1.4 ' ,
2022-09-03 15:36:04 +00:00
help = ' Indicates which diffusion model to load. (currently " stable-diffusion-1.4 " (default) or " laion400m " ) ' ,
)
parser . add_argument (
' --config ' ,
2022-09-11 19:47:12 +00:00
default = ' configs/models.yaml ' ,
help = ' Path to configuration file for alternate models. ' ,
2022-09-01 18:04:31 +00:00
)
2022-08-17 01:34:37 +00:00
return parser
2022-08-26 07:15:42 +00:00
2022-08-17 01:34:37 +00:00
def create_cmd_parser ( ) :
2022-08-26 07:15:42 +00:00
parser = argparse . ArgumentParser (
description = ' Example: dream> a fantastic alien landscape -W1024 -H960 -s100 -n12 '
)
2022-08-17 01:34:37 +00:00
parser . add_argument ( ' prompt ' )
2022-08-29 00:34:55 +00:00
parser . add_argument ( ' -s ' , ' --steps ' , type = int , help = ' Number of steps ' )
2022-08-26 07:15:42 +00:00
parser . add_argument (
' -S ' ,
' --seed ' ,
type = int ,
2022-08-29 00:34:55 +00:00
help = ' Image seed; a +ve integer, or use -1 for the previous seed, -2 for the one before that, etc ' ,
2022-08-26 07:15:42 +00:00
)
parser . add_argument (
' -n ' ,
' --iterations ' ,
type = int ,
default = 1 ,
2022-08-29 00:34:55 +00:00
help = ' Number of samplings to perform (slower, but will provide seeds for individual images) ' ,
2022-08-26 07:15:42 +00:00
)
parser . add_argument (
2022-08-29 00:34:55 +00:00
' -W ' , ' --width ' , type = int , help = ' Image width, multiple of 64 '
2022-08-26 07:15:42 +00:00
)
parser . add_argument (
2022-08-29 00:34:55 +00:00
' -H ' , ' --height ' , type = int , help = ' Image height, multiple of 64 '
2022-08-26 07:15:42 +00:00
)
parser . add_argument (
' -C ' ,
' --cfg_scale ' ,
default = 7.5 ,
type = float ,
2022-08-30 02:34:09 +00:00
help = ' Classifier free guidance (CFG) scale - higher numbers cause generator to " try " harder. ' ,
2022-08-26 07:15:42 +00:00
)
parser . add_argument (
' -g ' , ' --grid ' , action = ' store_true ' , help = ' generate a grid '
)
2022-08-28 19:54:12 +00:00
parser . add_argument (
' --outdir ' ,
' -o ' ,
type = str ,
default = None ,
2022-08-29 00:34:55 +00:00
help = ' Directory to save generated images and a log of prompts and seeds ' ,
2022-08-28 19:54:12 +00:00
)
2022-09-03 06:13:31 +00:00
parser . add_argument (
' --seamless ' ,
action = ' store_true ' ,
help = ' Change the model to seamless tiling (circular) mode ' ,
)
2022-08-26 07:15:42 +00:00
parser . add_argument (
' -i ' ,
' --individual ' ,
action = ' store_true ' ,
2022-08-29 00:34:55 +00:00
help = ' Generate individual files (default) ' ,
2022-08-26 07:15:42 +00:00
)
parser . add_argument (
' -I ' ,
' --init_img ' ,
type = str ,
2022-08-29 00:34:55 +00:00
help = ' Path to input image for img2img mode (supersedes width and height) ' ,
2022-08-26 07:15:42 +00:00
)
2022-09-06 00:40:10 +00:00
parser . add_argument (
' -M ' ,
2022-09-08 11:34:03 +00:00
' --init_mask ' ,
2022-09-06 00:40:10 +00:00
type = str ,
2022-09-08 11:34:03 +00:00
help = ' Path to input mask for inpainting mode (supersedes width and height) ' ,
2022-09-06 00:40:10 +00:00
)
2022-09-01 04:50:28 +00:00
parser . add_argument (
' -T ' ,
' -fit ' ,
' --fit ' ,
action = ' store_true ' ,
help = ' If specified, will resize the input image to fit within the dimensions of width x height (512x512 default) ' ,
)
2022-08-26 07:15:42 +00:00
parser . add_argument (
' -f ' ,
' --strength ' ,
default = 0.75 ,
type = float ,
2022-08-29 00:34:55 +00:00
help = ' Strength for noising/unnoising. 0.0 preserves image exactly, 1.0 replaces it completely ' ,
2022-08-26 07:15:42 +00:00
)
parser . add_argument (
' -G ' ,
' --gfpgan_strength ' ,
2022-08-28 20:14:29 +00:00
default = 0 ,
2022-08-26 07:15:42 +00:00
type = float ,
help = ' The strength at which to apply the GFPGAN model to the result, in order to improve faces. ' ,
)
2022-08-28 20:14:29 +00:00
parser . add_argument (
' -U ' ,
' --upscale ' ,
2022-08-28 21:26:39 +00:00
nargs = ' + ' ,
2022-08-28 20:14:29 +00:00
default = None ,
type = float ,
2022-08-28 21:26:39 +00:00
help = ' Scale factor (2, 4) for upscaling followed by upscaling strength (0-1.0). If strength not specified, defaults to 0.75 '
2022-08-28 20:14:29 +00:00
)
parser . add_argument (
' -save_orig ' ,
' --save_original ' ,
action = ' store_true ' ,
help = ' Save original. Use it when upscaling to save both versions. ' ,
)
2022-08-26 07:15:42 +00:00
# variants is going to be superseded by a generalized "prompt-morph" function
# parser.add_argument('-v','--variants',type=int,help="in img2img mode, the first generated image will get passed back to img2img to generate the requested number of variants")
parser . add_argument (
' -x ' ,
' --skip_normalize ' ,
action = ' store_true ' ,
2022-08-29 00:34:55 +00:00
help = ' Skip subprompt weight normalization ' ,
2022-08-26 07:15:42 +00:00
)
2022-08-28 04:05:00 +00:00
parser . add_argument (
2022-08-28 23:01:45 +00:00
' -A ' ,
2022-08-28 04:05:00 +00:00
' -m ' ,
2022-08-28 23:01:45 +00:00
' --sampler ' ,
dest = ' sampler_name ' ,
2022-08-28 04:05:00 +00:00
default = None ,
type = str ,
2022-08-29 00:34:55 +00:00
choices = SAMPLER_CHOICES ,
metavar = ' SAMPLER_NAME ' ,
help = f ' Switch to a different sampler. Supported samplers: { " , " . join ( SAMPLER_CHOICES ) } ' ,
2022-08-26 07:15:42 +00:00
)
2022-08-29 03:28:49 +00:00
parser . add_argument (
' -t ' ,
' --log_tokenization ' ,
action = ' store_true ' ,
help = ' shows how the prompt is split into tokens '
)
2022-09-01 02:31:52 +00:00
parser . add_argument (
' -v ' ,
' --variation_amount ' ,
default = 0.0 ,
type = float ,
help = ' If > 0, generates variations on the initial seed instead of random seeds per iteration. Must be between 0 and 1. Higher values will be more different. '
)
parser . add_argument (
' -V ' ,
' --with_variations ' ,
default = None ,
type = str ,
2022-09-03 06:36:44 +00:00
help = ' list of variations to apply, in the format `seed:weight,seed:weight,... '
2022-09-01 02:31:52 +00:00
)
2022-08-17 01:34:37 +00:00
return parser
2022-08-18 20:00:44 +00:00
2022-08-26 07:15:42 +00:00
if __name__ == ' __main__ ' :
2022-08-17 01:34:37 +00:00
main ( )