mirror of https://github.com/vladmandic/automatic
parent
966eb3210a
commit
d8044136b9
27
TODO.md
27
TODO.md
|
|
@ -4,28 +4,23 @@ Main ToDo list can be found at [GitHub projects](https://github.com/users/vladma
|
|||
|
||||
## Current
|
||||
|
||||
- <https://github.com/KohakuBlueleaf/z-tipo-extension/pull/73>
|
||||
|
||||
## Future Candidates
|
||||
|
||||
- Redesign postprocessing
|
||||
- Flux NF4 loader: <https://github.com/huggingface/diffusers/issues/9996>
|
||||
- IPAdapter negative: <https://github.com/huggingface/diffusers/discussions/7167>
|
||||
- Control API enhance scripts compatibility
|
||||
- CogView4
|
||||
|
||||
## Code TODO
|
||||
|
||||
- flux: loader for civitai nf4 models (fixme)
|
||||
- hypertile: vae breaks when using non-standard sizes (fixme)
|
||||
- install: enable ROCm for windows when available (fixme)
|
||||
- lora make support quantized flux (fixme)
|
||||
- lora: add other quantization types (fixme)
|
||||
- model load: force-reloading entire model as loading transformers only leads to massive memory usage (fixme)
|
||||
- model loader: implement model in-memory caching (fixme)
|
||||
- modernui: monkey-patch for missing tabs.select event (fixme)
|
||||
- processing: remove duplicate mask params (fixme)
|
||||
- resize image: enable full VAE mode for resize-latent (fixme)
|
||||
- sana: fails when quantized (fixme)
|
||||
- support scripts via api (fixme)
|
||||
- transformer from-single-file with quant (fixme)
|
||||
- enable ROCm for windows when available
|
||||
- resize image: enable full VAE mode for resize-latent
|
||||
- infotext: handle using regex instead
|
||||
- processing: remove duplicate mask params
|
||||
- model loader: implement model in-memory caching
|
||||
- hypertile: vae breaks when using non-standard sizes
|
||||
- force-reloading entire model as loading transformers only leads to massive memory usage
|
||||
- add other quantization types
|
||||
- lora make support quantized flux
|
||||
- control: support scripts via api
|
||||
- modernui: monkey-patch for missing tabs.select event
|
||||
|
|
|
|||
|
|
@ -88,8 +88,6 @@ svg.feather.feather-image, .feather .feather-image { display: none }
|
|||
/* gradio elements overrides */
|
||||
#div.gradio-container { overflow-x: hidden; }
|
||||
#img2img_label_copy_to_img2img { font-weight: normal; }
|
||||
#txt2img_prompt, #txt2img_neg_prompt, #img2img_prompt, #img2img_neg_prompt { background-color: var(--background-color); box-shadow: 4px 4px 4px 0px #333333 !important; }
|
||||
#txt2img_prompt > label > textarea, #txt2img_neg_prompt > label > textarea, #img2img_prompt > label > textarea, #img2img_neg_prompt > label > textarea { font-size: 1.1rem; }
|
||||
#img2img_settings { min-width: calc(2 * var(--left-column)); max-width: calc(2 * var(--left-column)); background-color: #111111; padding-top: 16px; }
|
||||
#interrogate, #deepbooru { margin: 0 0px 10px 0px; max-width: 80px; max-height: 80px; font-weight: normal; font-size: 0.95em; }
|
||||
#quicksettings .gr-button-tool { font-size: 1.6rem; box-shadow: none; margin-left: -20px; margin-top: -2px; height: 2.4em; }
|
||||
|
|
|
|||
|
|
@ -103,11 +103,6 @@ svg.feather.feather-image, .feather .feather-image { display: none }
|
|||
/* gradio elements overrides */
|
||||
#div.gradio-container { overflow-x: hidden; }
|
||||
#img2img_label_copy_to_img2img { font-weight: normal; }
|
||||
|
||||
#txt2img_prompt, #txt2img_neg_prompt, #img2img_prompt, #img2img_neg_prompt, #control_prompt, #control_neg_prompt { background-color: var(--background-color); box-shadow: none !important; }
|
||||
#txt2img_prompt > label > textarea, #txt2img_neg_prompt > label > textarea, #img2img_prompt > label > textarea, #img2img_neg_prompt > label > textarea, #control_prompt > label > textarea, #control_neg_prompt > label > textarea { font-size: 1.0em; line-height: 1.4em; }
|
||||
#txt2img_styles, #img2img_styles, #control_styles { padding: 0; }
|
||||
#txt2img_styles_refresh, #img2img_styles_refresh, #control_styles_refresh { padding: 0; margin-top: 1em; }
|
||||
#img2img_settings { min-width: calc(2 * var(--left-column)); max-width: calc(2 * var(--left-column)); background-color: var(--primary-950); padding-top: 16px; }
|
||||
#interrogate, #deepbooru { margin: 0 0px 10px 0px; max-width: 80px; max-height: 80px; font-weight: normal; font-size: 0.95em; }
|
||||
#quicksettings .gr-button-tool { font-size: 1.6rem; box-shadow: none; margin-left: -20px; margin-top: -2px; height: 2.4em; }
|
||||
|
|
|
|||
|
|
@ -105,8 +105,6 @@ svg.feather.feather-image, .feather .feather-image { display: none }
|
|||
/* gradio elements overrides */
|
||||
#div.gradio-container { overflow-x: hidden; }
|
||||
#img2img_label_copy_to_img2img { font-weight: normal; }
|
||||
#txt2img_prompt, #txt2img_neg_prompt, #img2img_prompt, #img2img_neg_prompt { background-color: var(--background-color); box-shadow: 4px 4px 4px 0px #333333 !important; }
|
||||
#txt2img_prompt > label > textarea, #txt2img_neg_prompt > label > textarea, #img2img_prompt > label > textarea, #img2img_neg_prompt > label > textarea { font-size: 1.1rem; }
|
||||
#img2img_settings { min-width: calc(2 * var(--left-column)); max-width: calc(2 * var(--left-column)); background-color: #111111; padding-top: 16px; }
|
||||
#interrogate, #deepbooru { margin: 0 0px 10px 0px; max-width: 80px; max-height: 80px; font-weight: normal; font-size: 0.95em; }
|
||||
#quicksettings .gr-button-tool { font-size: 1.6rem; box-shadow: none; margin-left: -20px; margin-top: -2px; height: 2.4em; }
|
||||
|
|
|
|||
|
|
@ -142,11 +142,6 @@ svg.feather.feather-image, .feather .feather-image { display: none }
|
|||
/* gradio elements overrides */
|
||||
#div.gradio-container { overflow-x: hidden; }
|
||||
#img2img_label_copy_to_img2img { font-weight: normal; }
|
||||
|
||||
#txt2img_prompt, #txt2img_neg_prompt, #img2img_prompt, #img2img_neg_prompt, #control_prompt, #control_neg_prompt { background-color: var(--background-color); box-shadow: none !important; }
|
||||
#txt2img_prompt > label > textarea, #txt2img_neg_prompt > label > textarea, #img2img_prompt > label > textarea, #img2img_neg_prompt > label > textarea, #control_prompt > label > textarea, #control_neg_prompt > label > textarea { font-size: 1.0em; line-height: 1.4em; }
|
||||
#txt2img_styles, #img2img_styles, #control_styles { padding: 0; margin-top: 2px; }
|
||||
#txt2img_styles_refresh, #img2img_styles_refresh, #control_styles_refresh { padding: 0; margin-top: 1em; }
|
||||
#img2img_settings { min-width: calc(2 * var(--left-column)); max-width: calc(2 * var(--left-column)); background-color: var(--neutral-950); padding-top: 16px; }
|
||||
#interrogate, #deepbooru { margin: 0 0px 10px 0px; max-width: 80px; max-height: 80px; font-weight: normal; font-size: 0.95em; }
|
||||
#quicksettings .gr-button-tool { font-size: 1.6rem; box-shadow: none; margin-left: -20px; margin-top: -2px; height: 2.4em; }
|
||||
|
|
|
|||
|
|
@ -101,8 +101,6 @@ button.selected {background: var(--button-primary-background-fill);}
|
|||
/* gradio elements overrides */
|
||||
#div.gradio-container { overflow-x: hidden; }
|
||||
#img2img_label_copy_to_img2img { font-weight: normal; }
|
||||
#txt2img_prompt, #txt2img_neg_prompt, #img2img_prompt, #img2img_neg_prompt { background-color: var(--background-color); box-shadow: 4px 4px 4px 0px #333333 !important; }
|
||||
#txt2img_prompt > label > textarea, #txt2img_neg_prompt > label > textarea, #img2img_prompt > label > textarea, #img2img_neg_prompt > label > textarea { font-size: 1.1rem; }
|
||||
#img2img_settings { min-width: calc(2 * var(--left-column)); max-width: calc(2 * var(--left-column)); background-color: #111111; padding-top: 16px; }
|
||||
#interrogate, #deepbooru { margin: 0 0px 10px 0px; max-width: 80px; max-height: 80px; font-weight: normal; font-size: 0.95em; }
|
||||
#quicksettings .gr-button-tool { font-size: 1.6rem; box-shadow: none; margin-top: -2px; height: 2.4em; }
|
||||
|
|
|
|||
|
|
@ -101,8 +101,6 @@ button.selected {background: var(--button-primary-background-fill);}
|
|||
/* gradio elements overrides */
|
||||
#div.gradio-container { overflow-x: hidden; }
|
||||
#img2img_label_copy_to_img2img { font-weight: normal; }
|
||||
#txt2img_prompt, #txt2img_neg_prompt, #img2img_prompt, #img2img_neg_prompt { background-color: var(--background-color); box-shadow: 4px 4px 4px 0px #333333 !important; }
|
||||
#txt2img_prompt > label > textarea, #txt2img_neg_prompt > label > textarea, #img2img_prompt > label > textarea, #img2img_neg_prompt > label > textarea { font-size: 1.1rem; }
|
||||
#img2img_settings { min-width: calc(2 * var(--left-column)); max-width: calc(2 * var(--left-column)); background-color: #111111; padding-top: 16px; }
|
||||
#interrogate, #deepbooru { margin: 0 0px 10px 0px; max-width: 80px; max-height: 80px; font-weight: normal; font-size: 0.95em; }
|
||||
#quicksettings .gr-button-tool { font-size: 1.6rem; box-shadow: none; margin-top: -2px; height: 2.4em; }
|
||||
|
|
|
|||
|
|
@ -101,10 +101,6 @@ svg.feather.feather-image, .feather .feather-image { display: none }
|
|||
/* gradio elements overrides */
|
||||
#div.gradio-container { overflow-x: hidden; }
|
||||
#img2img_label_copy_to_img2img { font-weight: normal; }
|
||||
#txt2img_prompt, #txt2img_neg_prompt, #img2img_prompt, #img2img_neg_prompt, #control_prompt, #control_neg_prompt { background-color: var(--background-color); box-shadow: 4px 4px 4px 0px #333333 !important; }
|
||||
#txt2img_prompt > label > textarea, #txt2img_neg_prompt > label > textarea, #img2img_prompt > label > textarea, #img2img_neg_prompt > label > textarea, #control_prompt > label > textarea, #control_neg_prompt > label > textarea { font-size: 1.0em; line-height: 1.4em; }
|
||||
#txt2img_styles, #img2img_styles, #control_styles { padding: 0; }
|
||||
#txt2img_styles_refresh, #img2img_styles_refresh, #control_styles_refresh { padding: 0; margin-top: 1em; }
|
||||
#img2img_settings { min-width: calc(2 * var(--left-column)); max-width: calc(2 * var(--left-column)); background-color: #111111; padding-top: 16px; }
|
||||
#interrogate, #deepbooru { margin: 0 0px 10px 0px; max-width: 80px; max-height: 80px; font-weight: normal; font-size: 0.95em; }
|
||||
#quicksettings .gr-button-tool { font-size: 1.6rem; box-shadow: none; margin-left: -20px; margin-top: -2px; height: 2.4em; }
|
||||
|
|
|
|||
|
|
@ -94,8 +94,6 @@ svg.feather.feather-image, .feather .feather-image { display: none }
|
|||
/* gradio elements overrides */
|
||||
#div.gradio-container { overflow-x: hidden; }
|
||||
#img2img_label_copy_to_img2img { font-weight: normal; }
|
||||
#txt2img_prompt, #txt2img_neg_prompt, #img2img_prompt, #img2img_neg_prompt { background-color: var(--background-color); box-shadow: 4px 4px 4px 0px #333333 !important; }
|
||||
#txt2img_prompt > label > textarea, #txt2img_neg_prompt > label > textarea, #img2img_prompt > label > textarea, #img2img_neg_prompt > label > textarea { font-size: 1.1rem; }
|
||||
#img2img_settings { min-width: calc(2 * var(--left-column)); max-width: calc(2 * var(--left-column)); background-color: #111111; padding-top: 16px; }
|
||||
#interrogate, #deepbooru { margin: 0 0px 10px 0px; max-width: 80px; max-height: 80px; font-weight: normal; font-size: 0.95em; }
|
||||
#quicksettings .gr-button-tool { font-size: 1.6rem; box-shadow: none; margin-left: -20px; margin-top: -2px; height: 2.4em; }
|
||||
|
|
|
|||
|
|
@ -101,8 +101,6 @@ button.selected {background: var(--button-primary-background-fill);}
|
|||
/* gradio elements overrides */
|
||||
#div.gradio-container { overflow-x: hidden; }
|
||||
#img2img_label_copy_to_img2img { font-weight: normal; }
|
||||
#txt2img_prompt, #txt2img_neg_prompt, #img2img_prompt, #img2img_neg_prompt { background-color: var(--background-color); box-shadow: 4px 4px 4px 0px #333333 !important; }
|
||||
#txt2img_prompt > label > textarea, #txt2img_neg_prompt > label > textarea, #img2img_prompt > label > textarea, #img2img_neg_prompt > label > textarea { font-size: 1.1rem; }
|
||||
#img2img_settings { min-width: calc(2 * var(--left-column)); max-width: calc(2 * var(--left-column)); background-color: #111111; padding-top: 16px; }
|
||||
#interrogate, #deepbooru { margin: 0 0px 10px 0px; max-width: 80px; max-height: 80px; font-weight: normal; font-size: 0.95em; }
|
||||
#quicksettings .gr-button-tool { font-size: 1.6rem; box-shadow: none; margin-top: -2px; height: 2.4em; }
|
||||
|
|
|
|||
|
|
@ -99,20 +99,20 @@ button.custom-button { border-radius: var(--button-large-radius); padding: var(-
|
|||
#txt2img_gallery, #img2img_gallery { height: 50vh; }
|
||||
#control-result { background: var(--button-secondary-background-fill); padding: 0.2em; }
|
||||
#control-inputs { margin-top: 1em; }
|
||||
#txt2img_prompt_container, #img2img_prompt_container, #control_prompt_container { margin-right: var(--layout-gap) }
|
||||
#txt2img_prompt_container, #img2img_prompt_container, #control_prompt_container, #video_prompt_container { margin-right: var(--layout-gap) }
|
||||
#txt2img_footer, #img2img_footer, #control_footer { height: fit-content; display: none; }
|
||||
#txt2img_generate_box, #img2img_generate_box { gap: 0.5em; flex-wrap: unset; min-width: unset; width: 66.6%; }
|
||||
#control_generate_box { gap: 0.5em; flex-wrap: unset; min-width: unset; width: 100%; }
|
||||
#control_generate_box button:nth-child(1) { flex-grow: 2; }
|
||||
#control_generate_box button:nth-child(2) { flex-grow: 1; }
|
||||
#txt2img_actions_column, #img2img_actions_column, #control_actions_column { gap: 0.3em; height: fit-content; }
|
||||
#txt2img_generate_box>button, #img2img_generate_box>button, #control_generate_box>button, #txt2img_enqueue, #img2img_enqueue, #txt2img_enqueue>button, #img2img_enqueue>button { min-height: 44px !important; max-height: 44px !important; line-height: 1em; white-space: break-spaces; min-width: unset; }
|
||||
#txt2img_actions_column, #img2img_actions_column, #control_actions_column, #video_actions_column { gap: 0.3em; height: fit-content; }
|
||||
#txt2img_generate_box>button, #img2img_generate_box>button, #control_generate_box>button, #video_generate_box>button, #txt2img_enqueue, #img2img_enqueue, #txt2img_enqueue>button, #img2img_enqueue>button { min-height: 44px !important; max-height: 44px !important; line-height: 1em; white-space: break-spaces; min-width: unset; }
|
||||
#txt2img_enqueue_wrapper, #img2img_enqueue_wrapper, #control_enqueue_wrapper { min-width: unset !important; width: 31%; }
|
||||
#txt2img_generate_line2, #img2img_generate_line2, #txt2img_tools, #img2img_tools, #control_generate_line2, #control_tools { display: flex; }
|
||||
#txt2img_generate_line2>button, #img2img_generate_line2>button, #extras_generate_box>button, #control_generate_line2>button, #txt2img_tools>button, #img2img_tools>button, #control_tools>button { height: 2em; line-height: 0; font-size: var(--text-md);
|
||||
min-width: unset; display: block !important; }
|
||||
#txt2img_prompt, #txt2img_neg_prompt, #img2img_prompt, #img2img_neg_prompt, #control_prompt, #control_neg_prompt { display: contents; }
|
||||
#txt2img_actions_column, #img2img_actions_column, #control_actions { flex-flow: wrap; justify-content: space-between; }
|
||||
#txt2img_prompt, #txt2img_neg_prompt, #img2img_prompt, #img2img_neg_prompt, #control_prompt, #control_neg_prompt, #video_prompt, #video_neg_prompt { display: contents; }
|
||||
#txt2img_actions_column, #img2img_actions_column, #control_actions, #video_actions { flex-flow: wrap; justify-content: space-between; }
|
||||
|
||||
.interrogate { position: absolute; right: 2.8em; top: 0.2em; max-width: fit-content; background: none !important; z-index: 50; font-size: 1.5em !important; }
|
||||
.interrogate:hover { background: var(--button-primary-background-fill-hover) !important; }
|
||||
|
|
@ -140,6 +140,11 @@ div#extras_scale_to_tab div.form { flex-direction: row; }
|
|||
#txt2img_advanced_options, #img2img_advanced_options, #control_advanced_options { min-width: 100%; }
|
||||
#txt2img_advanced_options .gradio-checkbox, #img2img_advanced_options .gradio-checkbox, #control_advanced_options .gradio-checkbox { min-width: unset !important; max-width: fit-content; }
|
||||
|
||||
#txt2img_prompt, #txt2img_neg_prompt, #img2img_prompt, #img2img_neg_prompt, #control_prompt, #control_neg_prompt, #video_prompt, #video_neg_prompt { background-color: var(--background-color); box-shadow: none !important; }
|
||||
#txt2img_prompt > label > textarea, #txt2img_neg_prompt > label > textarea, #img2img_prompt > label > textarea, #img2img_neg_prompt > label > textarea, #control_prompt > label > textarea, #control_neg_prompt > label > textarea, #video_prompt > label > textarea, #video_neg_prompt > label > textarea { font-size: 1.0em; line-height: 1.4em; }
|
||||
#txt2img_styles, #img2img_styles, #control_styles, #video_styles { padding: 0; margin-top: 2px; }
|
||||
#txt2img_styles_refresh, #img2img_styles_refresh, #control_styles_refresh, #video_styles_refresh { padding: 0; margin-top: 1em; }
|
||||
|
||||
/* settings */
|
||||
#si-sparkline-memo, #si-sparkline-load { background-color: #111; }
|
||||
#quicksettings { width: fit-content; }
|
||||
|
|
@ -388,7 +393,7 @@ div:has(>#tab-gallery-folders) { flex-grow: 0 !important; background-color: var(
|
|||
#txt2img_results, #extras_results, #txt2im g_footer p { text-wrap: wrap; max-width: 100% !important; } /* maintain side by side split on larger mobile displays for from text */
|
||||
}
|
||||
#scripts_alwayson_txt2img div, #scripts_alwayson_img2img div { max-width: 100%; }
|
||||
#txt2img_prompt_container, #img2img_prompt_container, #control_prompt_container { resize: vertical !important; }
|
||||
#txt2img_prompt_container, #img2img_prompt_container, #control_prompt_container, #video_prompt_container { resize: vertical !important; }
|
||||
#txt2img_generate_box, #txt2img_enqueue_wrapper { min-width: 100% !important;} /* make generate and enqueue buttons take up the entire width of their rows. */
|
||||
#img2img_toprow>div.gradio-column { flex-grow: 1 !important;} /*make interrogate buttons take up appropriate space. */
|
||||
#img2img_actions_column { display: flex; min-width: fit-content !important; flex-direction: row;justify-content: space-evenly; align-items: center;}
|
||||
|
|
|
|||
|
|
@ -101,8 +101,6 @@ button.selected {background: var(--button-primary-background-fill);}
|
|||
/* gradio elements overrides */
|
||||
#div.gradio-container { overflow-x: hidden; }
|
||||
#img2img_label_copy_to_img2img { font-weight: normal; }
|
||||
#txt2img_prompt, #txt2img_neg_prompt, #img2img_prompt, #img2img_neg_prompt { background-color: var(--background-color); box-shadow: 4px 4px 4px 0px #333333 !important; }
|
||||
#txt2img_prompt > label > textarea, #txt2img_neg_prompt > label > textarea, #img2img_prompt > label > textarea, #img2img_neg_prompt > label > textarea { font-size: 1.1rem; }
|
||||
#img2img_settings { min-width: calc(2 * var(--left-column)); max-width: calc(2 * var(--left-column)); background-color: #111111; padding-top: 16px; }
|
||||
#interrogate, #deepbooru { margin: 0 0px 10px 0px; max-width: 80px; max-height: 80px; font-weight: normal; font-size: 0.95em; }
|
||||
#quicksettings .gr-button-tool { font-size: 1.6rem; box-shadow: none; margin-top: -2px; height: 2.4em; }
|
||||
|
|
|
|||
|
|
@ -240,6 +240,18 @@ function submit_control(...args) {
|
|||
return res;
|
||||
}
|
||||
|
||||
function submit_video(...args) {
|
||||
log('submitVideo');
|
||||
clearGallery('video');
|
||||
const id = randomId();
|
||||
requestProgress(id, null, gradioApp().getElementById('video_gallery'));
|
||||
const res = create_submit_args(args);
|
||||
res[0] = id;
|
||||
res[1] = window.submit_state;
|
||||
window.submit_state = '';
|
||||
return res;
|
||||
}
|
||||
|
||||
function submit_postprocessing(...args) {
|
||||
log('SubmitExtras');
|
||||
clearGallery('extras');
|
||||
|
|
|
|||
|
|
@ -146,6 +146,12 @@ def create_ui(startup_timer = None):
|
|||
ui_control.create_ui()
|
||||
timer.startup.record("ui-control")
|
||||
|
||||
with gr.Blocks(analytics_enabled=False) as video_interface:
|
||||
if shared.native and shared.cmd_opts.experimental:
|
||||
from modules import ui_video
|
||||
ui_video.create_ui()
|
||||
timer.startup.record("ui-video")
|
||||
|
||||
with gr.Blocks(analytics_enabled=False) as extras_interface:
|
||||
from modules import ui_postprocessing
|
||||
ui_postprocessing.create_ui()
|
||||
|
|
@ -398,7 +404,10 @@ def create_ui(startup_timer = None):
|
|||
interfaces = []
|
||||
interfaces += [(txt2img_interface, "Text", "txt2img")]
|
||||
interfaces += [(img2img_interface, "Image", "img2img")]
|
||||
interfaces += [(control_interface, "Control", "control")] if control_interface is not None else []
|
||||
if control_interface is not None:
|
||||
interfaces += [(control_interface, "Control", "control")]
|
||||
if video_interface is not None:
|
||||
interfaces += [(video_interface, "Video", "video")]
|
||||
interfaces += [(extras_interface, "Process", "process")]
|
||||
interfaces += [(caption_interface, "Caption", "caption")]
|
||||
interfaces += [(gallery_interface, "Gallery", "gallery")]
|
||||
|
|
|
|||
|
|
@ -237,8 +237,8 @@ def interrogate_booru(image): # legacy function
|
|||
return gr.update() if prompt is None else prompt
|
||||
|
||||
|
||||
def create_output_panel(tabname, preview=True, prompt=None, height=None):
|
||||
with gr.Column(variant='panel', elem_id=f"{tabname}_results"):
|
||||
def create_output_panel(tabname, preview=True, prompt=None, height=None, transfer=True, scale=1):
|
||||
with gr.Column(variant='panel', elem_id=f"{tabname}_results", scale=scale):
|
||||
with gr.Group(elem_id=f"{tabname}_gallery_container"):
|
||||
if tabname == "txt2img":
|
||||
gr.HTML(value="", elem_id="main_info", visible=False, elem_classes=["main-info"])
|
||||
|
|
@ -270,10 +270,13 @@ def create_output_panel(tabname, preview=True, prompt=None, height=None):
|
|||
clip_files.click(fn=None, _js='clip_gallery_urls', inputs=[result_gallery], outputs=[])
|
||||
save = gr.Button('Save', elem_id=f'save_{tabname}')
|
||||
delete = gr.Button('Delete', elem_id=f'delete_{tabname}')
|
||||
if not shared.native:
|
||||
buttons = generation_parameters_copypaste.create_buttons(["img2img", "inpaint", "extras"])
|
||||
if transfer:
|
||||
if not shared.native:
|
||||
buttons = generation_parameters_copypaste.create_buttons(["img2img", "inpaint", "extras"])
|
||||
else:
|
||||
buttons = generation_parameters_copypaste.create_buttons(["txt2img", "img2img", "control", "extras", "caption"])
|
||||
else:
|
||||
buttons = generation_parameters_copypaste.create_buttons(["txt2img", "img2img", "control", "extras", "caption"])
|
||||
buttons = None
|
||||
|
||||
download_files = gr.File(None, file_count="multiple", interactive=False, show_label=False, visible=False, elem_id=f'download_files_{tabname}')
|
||||
with gr.Group():
|
||||
|
|
@ -309,17 +312,18 @@ def create_output_panel(tabname, preview=True, prompt=None, height=None):
|
|||
else:
|
||||
paste_field_names = []
|
||||
debug(f'Paste field: tab={tabname} fields={paste_field_names}')
|
||||
for paste_tabname, paste_button in buttons.items():
|
||||
debug(f'Create output panel: source={tabname} target={paste_tabname} button={paste_button}')
|
||||
bindings = generation_parameters_copypaste.ParamBinding(
|
||||
paste_button=paste_button,
|
||||
tabname=paste_tabname,
|
||||
source_tabname=tabname,
|
||||
source_image_component=result_gallery,
|
||||
paste_field_names=paste_field_names,
|
||||
source_text_component=prompt or generation_info
|
||||
)
|
||||
generation_parameters_copypaste.register_paste_params_button(bindings)
|
||||
if buttons is not None:
|
||||
for paste_tabname, paste_button in buttons.items():
|
||||
debug(f'Create output panel: source={tabname} target={paste_tabname} button={paste_button}')
|
||||
bindings = generation_parameters_copypaste.ParamBinding(
|
||||
paste_button=paste_button,
|
||||
tabname=paste_tabname,
|
||||
source_tabname=tabname,
|
||||
source_image_component=result_gallery,
|
||||
paste_field_names=paste_field_names,
|
||||
source_text_component=prompt or generation_info
|
||||
)
|
||||
generation_parameters_copypaste.register_paste_params_button(bindings)
|
||||
return result_gallery, generation_info, html_info, html_info_formatted, html_log
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -4,7 +4,7 @@ from modules.ui_components import ToolButton
|
|||
from modules.interrogate import interrogate
|
||||
|
||||
|
||||
def create_toprow(is_img2img: bool = False, id_part: str = None):
|
||||
def create_toprow(is_img2img: bool = False, id_part: str = None, negative_visible: bool = True, reprocess_visible: bool = True):
|
||||
def apply_styles(prompt, prompt_neg, styles):
|
||||
prompt = shared.prompt_styles.apply_styles_to_prompt(prompt, styles, wildcards=not shared.opts.extra_networks_apply_unparsed)
|
||||
prompt_neg = shared.prompt_styles.apply_negative_styles_to_prompt(prompt_neg, styles, wildcards=not shared.opts.extra_networks_apply_unparsed)
|
||||
|
|
@ -21,19 +21,20 @@ def create_toprow(is_img2img: bool = False, id_part: str = None):
|
|||
with gr.Row():
|
||||
with gr.Column(scale=80):
|
||||
with gr.Row(elem_id=f"{id_part}_prompt_row"):
|
||||
prompt = gr.Textbox(elem_id=f"{id_part}_prompt", label="Prompt", show_label=False, lines=3, placeholder="Prompt", elem_classes=["prompt"])
|
||||
prompt = gr.Textbox(elem_id=f"{id_part}_prompt", label="Prompt", show_label=False, lines=3 if negative_visible else 5, placeholder="Prompt", elem_classes=["prompt"])
|
||||
with gr.Row():
|
||||
with gr.Column(scale=80):
|
||||
with gr.Row(elem_id=f"{id_part}_negative_row"):
|
||||
negative_prompt = gr.Textbox(elem_id=f"{id_part}_neg_prompt", label="Negative prompt", show_label=False, lines=3, placeholder="Negative prompt", elem_classes=["prompt"])
|
||||
negative_prompt = gr.Textbox(elem_id=f"{id_part}_neg_prompt", label="Negative prompt", show_label=False, lines=3, placeholder="Negative prompt", elem_classes=["prompt"], visible=negative_visible)
|
||||
with gr.Column(scale=1, elem_id=f"{id_part}_actions_column"):
|
||||
with gr.Row(elem_id=f"{id_part}_generate_box"):
|
||||
reprocess = []
|
||||
submit = gr.Button('Generate', elem_id=f"{id_part}_generate", variant='primary')
|
||||
reprocess.append(gr.Button('Reprocess', elem_id=f"{id_part}_reprocess", variant='primary', visible=True))
|
||||
reprocess.append(gr.Button('Reprocess decode', elem_id=f"{id_part}_reprocess_decode", variant='primary', visible=False))
|
||||
reprocess.append(gr.Button('Reprocess refine', elem_id=f"{id_part}_reprocess_refine", variant='primary', visible=False))
|
||||
reprocess.append(gr.Button('Reprocess face', elem_id=f"{id_part}_reprocess_detail", variant='primary', visible=False))
|
||||
if reprocess_visible:
|
||||
reprocess.append(gr.Button('Reprocess', elem_id=f"{id_part}_reprocess", variant='primary', visible=True))
|
||||
reprocess.append(gr.Button('Reprocess decode', elem_id=f"{id_part}_reprocess_decode", variant='primary', visible=False))
|
||||
reprocess.append(gr.Button('Reprocess refine', elem_id=f"{id_part}_reprocess_refine", variant='primary', visible=False))
|
||||
reprocess.append(gr.Button('Reprocess face', elem_id=f"{id_part}_reprocess_detail", variant='primary', visible=False))
|
||||
with gr.Row(elem_id=f"{id_part}_generate_line2"):
|
||||
interrupt = gr.Button('Stop', elem_id=f"{id_part}_interrupt")
|
||||
interrupt.click(fn=lambda: shared.state.interrupt(), _js="requestInterrupt", inputs=[], outputs=[])
|
||||
|
|
@ -79,9 +80,9 @@ def ar_change(ar, width, height):
|
|||
return gr.update(), gr.update()
|
||||
|
||||
|
||||
def create_resolution_inputs(tab):
|
||||
width = gr.Slider(minimum=64, maximum=4096, step=8, label="Width", value=1024, elem_id=f"{tab}_width")
|
||||
height = gr.Slider(minimum=64, maximum=4096, step=8, label="Height", value=1024, elem_id=f"{tab}_height")
|
||||
def create_resolution_inputs(tab, default_width=1024, default_height=1024):
|
||||
width = gr.Slider(minimum=64, maximum=4096, step=8, label="Width", value=default_width, elem_id=f"{tab}_width")
|
||||
height = gr.Slider(minimum=64, maximum=4096, step=8, label="Height", value=default_height, elem_id=f"{tab}_height")
|
||||
ar_list = ['AR'] + [x.strip() for x in shared.opts.aspect_ratios.split(',') if x.strip() != '']
|
||||
ar_dropdown = gr.Dropdown(show_label=False, interactive=True, choices=ar_list, value=ar_list[0], elem_id=f"{tab}_ar", elem_classes=["ar-dropdown"])
|
||||
for c in [ar_dropdown, width, height]:
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
import gradio as gr
|
||||
from modules.call_queue import wrap_gradio_gpu_call, wrap_queued_call
|
||||
from modules import timer, shared, ui_common, ui_sections, generation_parameters_copypaste, processing, processing_vae, devices
|
||||
from modules import timer, shared, ui_common, ui_sections, generation_parameters_copypaste, processing, processing_vae, devices, images
|
||||
from modules.ui_components import ToolButton # pylint: disable=unused-import
|
||||
|
||||
|
||||
|
|
@ -23,7 +23,7 @@ def create_ui():
|
|||
txt2img_prompt, txt2img_prompt_styles, txt2img_negative_prompt, txt2img_submit, txt2img_reprocess, txt2img_paste, txt2img_extra_networks_button, txt2img_token_counter, txt2img_token_button, txt2img_negative_token_counter, txt2img_negative_token_button = ui_sections.create_toprow(is_img2img=False, id_part="txt2img")
|
||||
|
||||
txt_prompt_img = gr.File(label="", elem_id="txt2img_prompt_image", file_count="single", type="binary", visible=False)
|
||||
txt_prompt_img.change(fn=modules.images.image_data, inputs=[txt_prompt_img], outputs=[txt2img_prompt, txt_prompt_img])
|
||||
txt_prompt_img.change(fn=images.image_data, inputs=[txt_prompt_img], outputs=[txt2img_prompt, txt_prompt_img])
|
||||
|
||||
with gr.Row(variant='compact', elem_id="txt2img_extra_networks", elem_classes=["extra_networks_root"], visible=False) as extra_networks_ui:
|
||||
from modules import ui_extra_networks
|
||||
|
|
|
|||
|
|
@ -0,0 +1,130 @@
|
|||
# TODO hunyuanvideo: seed, scheduler, scheduler_shift, guidance_scale=1.0, true_cfg_scale=6.0, num_inference_steps=30, prompt_template, vae, offloading
|
||||
# TODO modernui video tab
|
||||
|
||||
from dataclasses import dataclass
|
||||
import gradio as gr
|
||||
from modules import shared, images, ui_common, ui_sections, sd_models, call_queue, generation_parameters_copypaste
|
||||
from modules.video_models import hunyuan
|
||||
|
||||
|
||||
@dataclass
|
||||
class Model():
|
||||
name: str
|
||||
repo: str
|
||||
dit: str
|
||||
|
||||
|
||||
MODELS = {
|
||||
'None': [],
|
||||
'Hunyuan Video': [
|
||||
Model('None', None, None),
|
||||
Model('Hunyuan Video T2V', 'hunyuanvideo-community/HunyuanVideo', None),
|
||||
Model('Hunyuan Video I2V', 'hunyuanvideo-community/HunyuanVideo', 'hunyuanvideo-community/HunyuanVideo-I2V'), # https://github.com/huggingface/diffusers/pull/10983
|
||||
Model('SkyReels Hunyuan T2V', 'hunyuanvideo-community/HunyuanVideo', 'Skywork/SkyReels-V1-Hunyuan-T2V'), # https://github.com/huggingface/diffusers/pull/10837
|
||||
Model('SkyReels Hunyuan I2V', 'hunyuanvideo-community/HunyuanVideo', 'Skywork/SkyReels-V1-Hunyuan-I2V'),
|
||||
Model('Fast Hunyuan T2V', 'hunyuanvideo-community/HunyuanVideo', 'hunyuan-video-t2v-720p/transformers/mp_rank_00_model_states.pt'), # https://github.com/hao-ai-lab/FastVideo/blob/8a77cf22c9b9e7f931f42bc4b35d21fd91d24e45/fastvideo/models/hunyuan/inference.py#L213
|
||||
]
|
||||
}
|
||||
|
||||
|
||||
def engine_change(engine):
|
||||
models = [model.name for model in MODELS.get(engine, [])]
|
||||
return gr.update(choices=models, value=models[0] if len(models) > 0 else None)
|
||||
|
||||
|
||||
def model_change(engine, model):
|
||||
models = [model.name for model in MODELS.get(engine, [])]
|
||||
selected = [m for m in MODELS[engine] if m.name == model][0] if len(models) > 0 else None
|
||||
if selected:
|
||||
if 'None' in selected.name:
|
||||
sd_models.unload_model_weights()
|
||||
msg = 'Video model unloaded'
|
||||
elif 'Hunyuan' in selected.name:
|
||||
msg = hunyuan.load(selected)
|
||||
elif model != 'None':
|
||||
msg = f'Video model not found: engine={engine} model={model}'
|
||||
shared.log.error(msg)
|
||||
else:
|
||||
sd_models.unload_model_weights()
|
||||
msg = 'Video model unloaded'
|
||||
return [msg, gr.update(visible='I2V' in selected.name) if selected else gr.update(visible=False)]
|
||||
|
||||
|
||||
def run_video(*args):
|
||||
engine, model = args[2], args[3]
|
||||
models = [model.name for model in MODELS.get(engine, [])]
|
||||
selected = [m for m in MODELS[engine] if m.name == model][0] if len(models) > 0 else None
|
||||
if selected and 'Hunyuan' in selected.name:
|
||||
return hunyuan.generate(*args)
|
||||
shared.log.error(f'Video model not found: args={args}')
|
||||
return [], '', '', f'Video model not found: engine={engine} model={model}'
|
||||
|
||||
|
||||
def create_ui():
|
||||
shared.log.debug('UI initialize: txt2img')
|
||||
with gr.Blocks(analytics_enabled=False) as _video_interface:
|
||||
prompt, styles, _negative, generate, _reprocess, paste, _networks, _token_counter, _token_button, _token_counter_negative, _token_button_negative = ui_sections.create_toprow(is_img2img=False, id_part="video", negative_visible=False, reprocess_visible=False)
|
||||
prompt_image = gr.File(label="", elem_id="video_prompt_image", file_count="single", type="binary", visible=False)
|
||||
prompt_image.change(fn=images.image_data, inputs=[prompt_image], outputs=[prompt, prompt_image])
|
||||
|
||||
with gr.Row(elem_id="video_interface", equal_height=False):
|
||||
with gr.Column(variant='compact', elem_id="video_settings", scale=1):
|
||||
|
||||
with gr.Row():
|
||||
engine = gr.Dropdown(label='Engine', choices=list(MODELS), value='None')
|
||||
model = gr.Dropdown(label='Model', choices=[''], value=None)
|
||||
with gr.Row():
|
||||
width, height = ui_sections.create_resolution_inputs('video', default_width=720, default_height=480)
|
||||
with gr.Row():
|
||||
frames = gr.Slider(label='Frames', minimum=1, maximum=1024, step=1, value=15)
|
||||
with gr.Row():
|
||||
with gr.Group(visible=False) as image_group:
|
||||
gr.HTML("<br>  Init image")
|
||||
image = gr.Image(elem_id="video_image", show_label=False, source="upload", interactive=True, type="pil", tool="select", image_mode="RGB", height=512)
|
||||
with gr.Row():
|
||||
save_frames = gr.Checkbox(label='Save image frames', value=False)
|
||||
with gr.Row():
|
||||
cc, duration, loop, pad, interpolate = ui_sections.create_video_inputs(tab='video')
|
||||
override_settings = ui_common.create_override_inputs('video')
|
||||
|
||||
# output panel with gallery
|
||||
gallery, gen_info, html_info, _html_info_formatted, html_log = ui_common.create_output_panel("video", prompt=prompt, preview=False, transfer=False, scale=2)
|
||||
|
||||
# handle engine and model change
|
||||
engine.change(fn=engine_change, inputs=[engine], outputs=[model])
|
||||
model.change(fn=model_change, inputs=[engine, model], outputs=[html_log, image_group])
|
||||
# handle restore fields
|
||||
paste_fields = [
|
||||
(prompt, "Prompt"),
|
||||
# main
|
||||
(width, "Size-1"),
|
||||
(height, "Size-2"),
|
||||
(frames, "Frames"),
|
||||
]
|
||||
generation_parameters_copypaste.add_paste_fields("txt2img", None, paste_fields, override_settings)
|
||||
bindings = generation_parameters_copypaste.ParamBinding(paste_button=paste, tabname="video", source_text_component=prompt, source_image_component=None)
|
||||
generation_parameters_copypaste.register_paste_params_button(bindings)
|
||||
# hidden fields
|
||||
task_id = gr.Textbox(visible=False, value='')
|
||||
ui_state = gr.Textbox(visible=False, value='')
|
||||
# generate args
|
||||
video_args = [
|
||||
task_id, ui_state,
|
||||
engine, model,
|
||||
prompt, styles,
|
||||
width, height,
|
||||
frames,
|
||||
image,
|
||||
save_frames,
|
||||
cc, duration, loop, pad, interpolate,
|
||||
]
|
||||
# generate function
|
||||
video_dict = dict(
|
||||
fn=call_queue.wrap_gradio_gpu_call(run_video, extra_outputs=[None, '', ''], name='Video'),
|
||||
_js="submit_video",
|
||||
inputs=video_args,
|
||||
outputs=[gallery, gen_info, html_info, html_log],
|
||||
show_progress=False,
|
||||
)
|
||||
prompt.submit(**video_dict)
|
||||
generate.click(**video_dict)
|
||||
|
|
@ -0,0 +1,13 @@
|
|||
from modules import shared
|
||||
|
||||
|
||||
def load(selected):
|
||||
msg = f'Video load: model="{selected.name}" repo="{selected.repo}" dit="{selected.dit}"'
|
||||
shared.log.info(msg)
|
||||
return msg
|
||||
|
||||
|
||||
def generate(*args, **kwargs):
|
||||
# TODO hunyuanvideo: check if loaded
|
||||
shared.log.debug(f'Video generate: args={args} kwargs={kwargs}')
|
||||
return [], '', '', 'TBD'
|
||||
Loading…
Reference in New Issue