Compare commits

...

24 commits

Author SHA1 Message Date
oobabooga cf90312960 Update docs 2025-12-02 09:55:07 -08:00
oobabooga 2842f20639 Revert "Update docs"
This reverts commit 594ccf5235.
2025-12-02 09:54:42 -08:00
oobabooga 594ccf5235 Update docs 2025-12-02 09:54:27 -08:00
oobabooga cd80d0f62d Update README, add a tutorial 2025-12-02 09:52:03 -08:00
oobabooga 26b49b176c Add diffusers and optimum-quanto to requirements 2025-12-02 09:16:16 -08:00
oobabooga 5297a874db Revert "Use dtype instead of torch_dtype"
This reverts commit f4b27a39af.
2025-12-02 07:28:29 -08:00
oobabooga 86f0a77b8a Better scrollbar for Image AI > Gallery (2nd attempt) 2025-12-02 07:18:04 -08:00
oobabooga 4d2f151260 Revert "Better scrollbar for Image AI > Gallery"
This reverts commit c3bd1c901d.
2025-12-02 07:15:45 -08:00
oobabooga e7a15a0361 Clear the torch cache before generating 2025-12-02 06:41:08 -08:00
oobabooga f4b27a39af Use dtype instead of torch_dtype 2025-12-02 06:35:06 -08:00
oobabooga 5382fe2d1b Improve the Gallery startup 2025-12-02 06:26:04 -08:00
oobabooga 6b3ff64724 Fix a minor UI glitch 2025-12-02 06:23:36 -08:00
oobabooga e328748bc8 Make --image-model load the model on startup 2025-12-02 06:15:21 -08:00
oobabooga 977d08de14 Make it possible to upload images to the UI to see settings 2025-12-02 06:11:08 -08:00
oobabooga f41e558e00 Improve a log message 2025-12-02 06:07:18 -08:00
oobabooga 180e1f0cbf Make it possible to interrupt a generation 2025-12-02 06:06:07 -08:00
oobabooga c3bd1c901d Better scrollbar for Image AI > Gallery 2025-12-02 05:51:30 -08:00
oobabooga b70011aeea Lint 2025-12-02 05:41:13 -08:00
oobabooga 0c4bdb19c8 Add exception handling while generating images 2025-12-02 05:39:40 -08:00
oobabooga 62cf5aa51c Don't assume CUDA GPU 2025-12-02 05:36:01 -08:00
oobabooga 29bdcc0be1 Several small bug fixes 2025-12-02 05:09:46 -08:00
oobabooga 83af6864d5 More precise pipeline type discovery 2025-12-02 04:50:33 -08:00
oobabooga 07754f9f29 Declare image_pipeline_type in shared.py 2025-12-02 04:44:38 -08:00
oobabooga c81c052f4e Add a missing import 2025-12-02 04:41:16 -08:00
17 changed files with 244 additions and 91 deletions

View file

@ -28,6 +28,8 @@ A Gradio web UI for Large Language Models.
- 100% offline and private, with zero telemetry, external resources, or remote update requests.
- **File attachments**: Upload text files, PDF documents, and .docx documents to talk about their contents.
- **Vision (multimodal models)**: Attach images to messages for visual understanding ([tutorial](https://github.com/oobabooga/text-generation-webui/wiki/Multimodal-Tutorial)).
Image generation: A dedicated tab for diffusers models like Z-Image-Turbo and Qwen-Image. Features 4-bit/8-bit quantization and a persistent gallery with metadata (tutorial).
- **Image generation**: A dedicated tab for `diffusers` models like **Z-Image-Turbo** and **Qwen-Image**. Features 4-bit/8-bit quantization and a persistent gallery with metadata ([tutorial](https://github.com/oobabooga/text-generation-webui/wiki/Image-Generation-Tutorial)).
- **Web search**: Optionally search the internet with LLM-generated queries to add context to the conversation.
- Aesthetic UI with dark and light themes.
- Syntax highlighting for code blocks and LaTeX rendering for mathematical expressions.

View file

@ -244,37 +244,46 @@ button {
font-size: 100% !important;
}
.pretty_scrollbar::-webkit-scrollbar {
.pretty_scrollbar::-webkit-scrollbar,
#image-history-gallery > :nth-child(2)::-webkit-scrollbar {
width: 8px;
height: 8px;
}
.pretty_scrollbar::-webkit-scrollbar-track {
.pretty_scrollbar::-webkit-scrollbar-track,
#image-history-gallery > :nth-child(2)::-webkit-scrollbar-track {
background: transparent;
}
.pretty_scrollbar::-webkit-scrollbar-thumb,
.pretty_scrollbar::-webkit-scrollbar-thumb:hover {
.pretty_scrollbar::-webkit-scrollbar-thumb:hover,
#image-history-gallery > :nth-child(2)::-webkit-scrollbar-thumb,
#image-history-gallery > :nth-child(2)::-webkit-scrollbar-thumb:hover {
background: var(--neutral-300);
border-radius: 30px;
}
.dark .pretty_scrollbar::-webkit-scrollbar-thumb,
.dark .pretty_scrollbar::-webkit-scrollbar-thumb:hover {
.dark .pretty_scrollbar::-webkit-scrollbar-thumb:hover,
.dark #image-history-gallery > :nth-child(2)::-webkit-scrollbar-thumb,
.dark #image-history-gallery > :nth-child(2)::-webkit-scrollbar-thumb:hover {
background: rgb(255 255 255 / 6.25%);
border-radius: 10px;
}
.pretty_scrollbar::-webkit-resizer {
.pretty_scrollbar::-webkit-resizer,
#image-history-gallery > :nth-child(2)::-webkit-resizer {
background: #c5c5d2;
}
.dark .pretty_scrollbar::-webkit-resizer {
.dark .pretty_scrollbar::-webkit-resizer,
.dark #image-history-gallery > :nth-child(2)::-webkit-resizer {
background: #ccc;
border-radius: 10px;
}
.pretty_scrollbar::-webkit-scrollbar-corner {
.pretty_scrollbar::-webkit-scrollbar-corner,
#image-history-gallery > :nth-child(2)::-webkit-scrollbar-corner {
background: transparent;
}
@ -1737,3 +1746,9 @@ button#swap-height-width {
padding: 8px;
background: var(--background-fill-secondary);
}
/* Fix a gr.Markdown UI glitch when clicking Next in the
* Image AI > Gallery tab */
.min.svelte-1yrv54 {
min-height: 0;
}

View file

@ -0,0 +1,20 @@
# Image Generation Tutorial
This feature allows you to generate images using high-speed models like Z-Image-Turbo directly within the web UI.
## How to use
1. Click on the **Image AI** tab at the top of the interface.
2. Select the **Model** sub-tab.
3. Copy and paste the following link into the **Download model** box:
```
https://huggingface.co/Tongyi-MAI/Z-Image-Turbo
```
4. Click the **Download** button and wait for the confirmation message.
5. In the **Model** dropdown menu, select the model you just downloaded (if you don't see it, click the 🔄 refresh button).
6. Click **Load**.
7. Go to the **Generate** sub-tab, type a prompt, and click **GENERATE**.
> **Note for Z-Image-Turbo:** For the best results with this specific model, keep the **CFG Scale** slider at **0**.

View file

@ -83,9 +83,9 @@ def get_pipeline_type(pipe):
str: 'zimage', 'qwenimage', or 'unknown'
"""
class_name = pipe.__class__.__name__
if 'ZImage' in class_name:
if class_name == 'ZImagePipeline':
return 'zimage'
elif 'QwenImage' in class_name:
elif class_name == 'QwenImagePipeline':
return 'qwenimage'
else:
return 'unknown'

View file

@ -23,6 +23,7 @@ lora_names = []
# Image model variables
image_model = None
image_model_name = 'None'
image_pipeline_type = None
# Generation variables
stop_everything = False
@ -364,7 +365,6 @@ def apply_image_model_cli_overrides():
settings['image_quant'] = args.image_quant
def fix_loader_name(name):
if not name:
return name

View file

@ -11,8 +11,14 @@ from PIL import Image
from PIL.PngImagePlugin import PngInfo
from modules import shared, ui, utils
from modules.image_models import load_image_model, unload_image_model
from modules.image_models import (
get_pipeline_type,
load_image_model,
unload_image_model
)
from modules.logging_colors import logger
from modules.text_generation import stop_everything_event
from modules.torch_utils import get_device
from modules.utils import gradio
ASPECT_RATIOS = {
@ -241,6 +247,12 @@ def get_paginated_images(page=0, force_refresh=False):
return page_images, page, total_pages, total_images
def get_initial_page_info():
"""Get page info string for initial load."""
_, page, total_pages, total_images = get_paginated_images(0)
return f"Page {page + 1} of {total_pages} ({total_images} total images)"
def refresh_gallery(current_page=0):
"""Refresh gallery with current page."""
images, page, total_pages, total_images = get_paginated_images(current_page, force_refresh=True)
@ -324,6 +336,15 @@ def send_to_generate(selected_image_path):
return updates + [status]
def read_dropped_image_metadata(image_path):
"""Read metadata from a dropped/uploaded image."""
if not image_path:
return "Drop an image to view its generation settings."
metadata = read_image_metadata(image_path)
return format_metadata_for_display(metadata)
def create_ui():
if shared.settings['image_model_menu'] != 'None':
shared.image_model_name = shared.settings['image_model_menu']
@ -349,7 +370,7 @@ def create_ui():
)
shared.gradio['image_generate_btn'] = gr.Button("Generate", variant="primary", size="lg")
shared.gradio['image_generating_btn'] = gr.Button("Generating...", size="lg", visible=False, interactive=False)
shared.gradio['image_stop_btn'] = gr.Button("Stop", size="lg", visible=False)
gr.HTML("<hr style='border-top: 1px solid #444; margin: 20px 0;'>")
gr.Markdown("### Dimensions")
@ -374,7 +395,7 @@ def create_ui():
shared.gradio['image_steps'] = gr.Slider(1, 100, value=shared.settings['image_steps'], step=1, label="Steps")
shared.gradio['image_cfg_scale'] = gr.Slider(
0.0, 10.0,
value=0.0,
value=shared.settings['image_cfg_scale'],
step=0.1,
label="CFG Scale",
info="Z-Image Turbo: 0.0 | Qwen: 4.0"
@ -396,7 +417,7 @@ def create_ui():
with gr.Row():
shared.gradio['image_refresh_history'] = gr.Button("🔄 Refresh", elem_classes="refresh-button")
shared.gradio['image_prev_page'] = gr.Button("◀ Prev", elem_classes="refresh-button")
shared.gradio['image_page_info'] = gr.Markdown("Loading...", elem_id="image-page-info")
shared.gradio['image_page_info'] = gr.Markdown(value=get_initial_page_info, elem_id="image-page-info")
shared.gradio['image_next_page'] = gr.Button("Next ▶", elem_classes="refresh-button")
shared.gradio['image_page_input'] = gr.Number(value=1, label="Page", precision=0, minimum=1, scale=0, min_width=80)
shared.gradio['image_go_to_page'] = gr.Button("Go", elem_classes="refresh-button", scale=0, min_width=50)
@ -423,6 +444,13 @@ def create_ui():
shared.gradio['image_send_to_generate'] = gr.Button("Send to Generate", variant="primary")
shared.gradio['image_gallery_status'] = gr.Markdown("")
gr.Markdown("### Import Image")
shared.gradio['image_drop_upload'] = gr.Image(
label="Drop image here to view settings",
type="filepath",
height=150
)
# TAB 3: MODEL
with gr.TabItem("Model"):
with gr.Row():
@ -517,22 +545,26 @@ def create_event_handlers():
# Generation
shared.gradio['image_generate_btn'].click(
ui.gather_interface_values, gradio(shared.input_elements), gradio('interface_state')).then(
lambda: [gr.update(visible=True), gr.update(visible=False)], None, gradio('image_generating_btn', 'image_generate_btn')).then(
lambda: [gr.update(visible=True), gr.update(visible=False)], None, gradio('image_stop_btn', 'image_generate_btn')).then(
generate, gradio('interface_state'), gradio('image_output_gallery'), show_progress=False).then(
lambda: [gr.update(visible=False), gr.update(visible=True)], None, gradio('image_generating_btn', 'image_generate_btn'))
lambda: [gr.update(visible=False), gr.update(visible=True)], None, gradio('image_stop_btn', 'image_generate_btn'))
shared.gradio['image_prompt'].submit(
ui.gather_interface_values, gradio(shared.input_elements), gradio('interface_state')).then(
lambda: [gr.update(visible=True), gr.update(visible=False)], None, gradio('image_generating_btn', 'image_generate_btn')).then(
lambda: [gr.update(visible=True), gr.update(visible=False)], None, gradio('image_stop_btn', 'image_generate_btn')).then(
generate, gradio('interface_state'), gradio('image_output_gallery'), show_progress=False).then(
lambda: [gr.update(visible=False), gr.update(visible=True)], None, gradio('image_generating_btn', 'image_generate_btn'))
lambda: [gr.update(visible=False), gr.update(visible=True)], None, gradio('image_stop_btn', 'image_generate_btn'))
shared.gradio['image_neg_prompt'].submit(
ui.gather_interface_values, gradio(shared.input_elements), gradio('interface_state')).then(
lambda: [gr.update(visible=True), gr.update(visible=False)], None, gradio('image_generating_btn', 'image_generate_btn')).then(
lambda: [gr.update(visible=True), gr.update(visible=False)], None, gradio('image_stop_btn', 'image_generate_btn')).then(
generate, gradio('interface_state'), gradio('image_output_gallery'), show_progress=False).then(
lambda: [gr.update(visible=False), gr.update(visible=True)], None, gradio('image_generating_btn', 'image_generate_btn'))
lambda: [gr.update(visible=False), gr.update(visible=True)], None, gradio('image_stop_btn', 'image_generate_btn'))
# Stop button
shared.gradio['image_stop_btn'].click(
stop_everything_event, None, None, show_progress=False
)
# Model management
shared.gradio['image_refresh_models'].click(
@ -620,6 +652,13 @@ def create_event_handlers():
show_progress=False
)
shared.gradio['image_drop_upload'].change(
read_dropped_image_metadata,
gradio('image_drop_upload'),
gradio('image_settings_display'),
show_progress=False
)
def generate(state):
"""
@ -627,83 +666,113 @@ def generate(state):
Automatically adjusts parameters based on pipeline type.
"""
import torch
import numpy as np
model_name = state['image_model_menu']
from modules.torch_utils import clear_torch_cache
if not model_name or model_name == 'None':
logger.error("No image model selected. Go to the Model tab and select a model.")
return []
clear_torch_cache()
if shared.image_model is None:
result = load_image_model(
model_name,
dtype=state['image_dtype'],
attn_backend=state['image_attn_backend'],
cpu_offload=state['image_cpu_offload'],
compile_model=state['image_compile'],
quant_method=state['image_quant']
)
if result is None:
logger.error(f"Failed to load model `{model_name}`.")
try:
model_name = state['image_model_menu']
if not model_name or model_name == 'None':
logger.error("No image model selected. Go to the Model tab and select a model.")
return []
shared.image_model_name = model_name
if shared.image_model is None:
result = load_image_model(
model_name,
dtype=state['image_dtype'],
attn_backend=state['image_attn_backend'],
cpu_offload=state['image_cpu_offload'],
compile_model=state['image_compile'],
quant_method=state['image_quant']
)
if result is None:
logger.error(f"Failed to load model `{model_name}`.")
return []
seed = state['image_seed']
if seed == -1:
seed = np.random.randint(0, 2**32 - 1)
shared.image_model_name = model_name
generator = torch.Generator("cuda").manual_seed(int(seed))
all_images = []
seed = state['image_seed']
if seed == -1:
seed = np.random.randint(0, 2**32 - 1)
# Get pipeline type for parameter adjustment
pipeline_type = getattr(shared, 'image_pipeline_type', None)
if pipeline_type is None:
pipeline_type = get_pipeline_type(shared.image_model)
device = get_device()
if device is None:
device = "cpu"
generator = torch.Generator(device).manual_seed(int(seed))
# Process Prompt
prompt = state['image_prompt']
all_images = []
# Apply "Positive Magic" for Qwen models only
if pipeline_type == 'qwenimage':
magic_suffix = ", Ultra HD, 4K, cinematic composition"
# Avoid duplication if user already added it
if magic_suffix.strip(", ") not in prompt:
prompt += magic_suffix
# Get pipeline type for parameter adjustment
pipeline_type = getattr(shared, 'image_pipeline_type', None)
if pipeline_type is None:
pipeline_type = get_pipeline_type(shared.image_model)
# Build generation kwargs
gen_kwargs = {
"prompt": prompt,
"negative_prompt": state['image_neg_prompt'],
"height": int(state['image_height']),
"width": int(state['image_width']),
"num_inference_steps": int(state['image_steps']),
"num_images_per_prompt": int(state['image_batch_size']),
"generator": generator,
}
# Process Prompt
prompt = state['image_prompt']
# Add pipeline-specific parameters for CFG
cfg_val = state.get('image_cfg_scale', 0.0)
# Apply "Positive Magic" for Qwen models only
if pipeline_type == 'qwenimage':
magic_suffix = ", Ultra HD, 4K, cinematic composition"
# Avoid duplication if user already added it
if magic_suffix.strip(", ") not in prompt:
prompt += magic_suffix
if pipeline_type == 'qwenimage':
# Qwen-Image uses true_cfg_scale (typically 4.0)
gen_kwargs["true_cfg_scale"] = cfg_val
else:
# Z-Image and others use guidance_scale (typically 0.0 for Turbo)
gen_kwargs["guidance_scale"] = cfg_val
# Reset stop flag at start
shared.stop_everything = False
t0 = time.time()
for i in range(int(state['image_batch_count'])):
generator.manual_seed(int(seed + i))
batch_results = shared.image_model(**gen_kwargs).images
all_images.extend(batch_results)
# Callback to check for interruption during diffusion steps
def interrupt_callback(pipe, step_index, timestep, callback_kwargs):
if shared.stop_everything:
pipe._interrupt = True
t1 = time.time()
save_generated_images(all_images, state, seed)
return callback_kwargs
logger.info(f'Images generated in {(t1-t0):.2f} seconds ({state["image_steps"]/(t1-t0):.2f} steps/s, seed {seed})')
return all_images
# Build generation kwargs
gen_kwargs = {
"prompt": prompt,
"negative_prompt": state['image_neg_prompt'],
"height": int(state['image_height']),
"width": int(state['image_width']),
"num_inference_steps": int(state['image_steps']),
"num_images_per_prompt": int(state['image_batch_size']),
"generator": generator,
"callback_on_step_end": interrupt_callback,
}
# Add pipeline-specific parameters for CFG
cfg_val = state.get('image_cfg_scale', 0.0)
if pipeline_type == 'qwenimage':
# Qwen-Image uses true_cfg_scale (typically 4.0)
gen_kwargs["true_cfg_scale"] = cfg_val
else:
# Z-Image and others use guidance_scale (typically 0.0 for Turbo)
gen_kwargs["guidance_scale"] = cfg_val
t0 = time.time()
for i in range(int(state['image_batch_count'])):
if shared.stop_everything:
break
generator.manual_seed(int(seed + i))
batch_results = shared.image_model(**gen_kwargs).images
all_images.extend(batch_results)
t1 = time.time()
save_generated_images(all_images, state, seed)
total_images = int(state['image_batch_count']) * int(state['image_batch_size'])
total_steps = state["image_steps"] * int(state['image_batch_count'])
logger.info(f'Generated {total_images} {"image" if total_images == 1 else "images"} in {(t1 - t0):.2f} seconds ({total_steps / (t1 - t0):.2f} steps/s, seed {seed})')
return all_images
except Exception as e:
logger.error(f"Image generation failed: {e}")
traceback.print_exc()
return []
def load_image_model_wrapper(model_name, dtype, attn_backend, cpu_offload, compile_model, quant_method):
@ -734,9 +803,10 @@ def load_image_model_wrapper(model_name, dtype, attn_backend, cpu_offload, compi
def unload_image_model_wrapper():
previous_name = shared.image_model_name
unload_image_model()
if shared.image_model_name != 'None':
return f"Model: **{shared.image_model_name}** (not loaded)"
if previous_name != 'None':
return f"Model: **{previous_name}** (unloaded)"
return "No model loaded"

View file

@ -157,14 +157,7 @@ def get_available_models():
def get_available_image_models():
model_dir = Path(shared.args.image_model_dir)
# Find directories with safetensors files
dirs_with_safetensors = set()
for item in os.listdir(model_dir):
item_path = model_dir / item
if item_path.is_dir():
if any(file.lower().endswith(('.safetensors', '.pt')) for file in os.listdir(item_path) if (item_path / file).is_file()):
dirs_with_safetensors.add(item)
model_dir.mkdir(parents=True, exist_ok=True)
# Find valid model directories
model_dirs = []

View file

@ -11,6 +11,7 @@ huggingface-hub==0.36.0
jinja2==3.1.6
markdown
numpy==2.2.*
optimum-quanto==0.2.7
pandas
peft==0.18.*
Pillow>=9.5.0
@ -34,6 +35,9 @@ wandb
gradio==4.37.*
https://github.com/oobabooga/gradio/releases/download/custom-build/gradio_client-1.0.2+custom.1-py3-none-any.whl
# Diffusers
diffusers @ git+https://github.com/huggingface/diffusers.git@edf36f5128abf3e6ecf92b5145115514363c58e6
# API
flask_cloudflared==0.0.14
sse-starlette==1.6.5

View file

@ -9,6 +9,7 @@ huggingface-hub==0.36.0
jinja2==3.1.6
markdown
numpy==2.2.*
optimum-quanto==0.2.7
pandas
peft==0.18.*
Pillow>=9.5.0
@ -32,6 +33,9 @@ wandb
gradio==4.37.*
https://github.com/oobabooga/gradio/releases/download/custom-build/gradio_client-1.0.2+custom.1-py3-none-any.whl
# Diffusers
diffusers @ git+https://github.com/huggingface/diffusers.git@edf36f5128abf3e6ecf92b5145115514363c58e6
# API
flask_cloudflared==0.0.14
sse-starlette==1.6.5

View file

@ -9,6 +9,7 @@ huggingface-hub==0.36.0
jinja2==3.1.6
markdown
numpy==2.2.*
optimum-quanto==0.2.7
pandas
peft==0.18.*
Pillow>=9.5.0
@ -32,6 +33,9 @@ wandb
gradio==4.37.*
https://github.com/oobabooga/gradio/releases/download/custom-build/gradio_client-1.0.2+custom.1-py3-none-any.whl
# Diffusers
diffusers @ git+https://github.com/huggingface/diffusers.git@edf36f5128abf3e6ecf92b5145115514363c58e6
# API
flask_cloudflared==0.0.14
sse-starlette==1.6.5

View file

@ -9,6 +9,7 @@ huggingface-hub==0.36.0
jinja2==3.1.6
markdown
numpy==2.2.*
optimum-quanto==0.2.7
pandas
peft==0.18.*
Pillow>=9.5.0
@ -32,6 +33,9 @@ wandb
gradio==4.37.*
https://github.com/oobabooga/gradio/releases/download/custom-build/gradio_client-1.0.2+custom.1-py3-none-any.whl
# Diffusers
diffusers @ git+https://github.com/huggingface/diffusers.git@edf36f5128abf3e6ecf92b5145115514363c58e6
# API
flask_cloudflared==0.0.14
sse-starlette==1.6.5

View file

@ -9,6 +9,7 @@ huggingface-hub==0.36.0
jinja2==3.1.6
markdown
numpy==2.2.*
optimum-quanto==0.2.7
pandas
peft==0.18.*
Pillow>=9.5.0
@ -32,6 +33,9 @@ wandb
gradio==4.37.*
https://github.com/oobabooga/gradio/releases/download/custom-build/gradio_client-1.0.2+custom.1-py3-none-any.whl
# Diffusers
diffusers @ git+https://github.com/huggingface/diffusers.git@edf36f5128abf3e6ecf92b5145115514363c58e6
# API
flask_cloudflared==0.0.14
sse-starlette==1.6.5

View file

@ -9,6 +9,7 @@ huggingface-hub==0.36.0
jinja2==3.1.6
markdown
numpy==2.2.*
optimum-quanto==0.2.7
pandas
peft==0.18.*
Pillow>=9.5.0
@ -32,6 +33,9 @@ wandb
gradio==4.37.*
https://github.com/oobabooga/gradio/releases/download/custom-build/gradio_client-1.0.2+custom.1-py3-none-any.whl
# Diffusers
diffusers @ git+https://github.com/huggingface/diffusers.git@edf36f5128abf3e6ecf92b5145115514363c58e6
# API
flask_cloudflared==0.0.14
sse-starlette==1.6.5

View file

@ -9,6 +9,7 @@ huggingface-hub==0.36.0
jinja2==3.1.6
markdown
numpy==2.2.*
optimum-quanto==0.2.7
pandas
peft==0.18.*
Pillow>=9.5.0
@ -32,6 +33,9 @@ wandb
gradio==4.37.*
https://github.com/oobabooga/gradio/releases/download/custom-build/gradio_client-1.0.2+custom.1-py3-none-any.whl
# Diffusers
diffusers @ git+https://github.com/huggingface/diffusers.git@edf36f5128abf3e6ecf92b5145115514363c58e6
# API
flask_cloudflared==0.0.14
sse-starlette==1.6.5

View file

@ -11,6 +11,7 @@ huggingface-hub==0.36.0
jinja2==3.1.6
markdown
numpy==2.2.*
optimum-quanto==0.2.7
pandas
peft==0.18.*
Pillow>=9.5.0
@ -34,6 +35,9 @@ wandb
gradio==4.37.*
https://github.com/oobabooga/gradio/releases/download/custom-build/gradio_client-1.0.2+custom.1-py3-none-any.whl
# Diffusers
diffusers @ git+https://github.com/huggingface/diffusers.git@edf36f5128abf3e6ecf92b5145115514363c58e6
# API
flask_cloudflared==0.0.14
sse-starlette==1.6.5

View file

@ -9,6 +9,7 @@ huggingface-hub==0.36.0
jinja2==3.1.6
markdown
numpy==2.2.*
optimum-quanto==0.2.7
pandas
peft==0.18.*
Pillow>=9.5.0
@ -32,6 +33,9 @@ wandb
gradio==4.37.*
https://github.com/oobabooga/gradio/releases/download/custom-build/gradio_client-1.0.2+custom.1-py3-none-any.whl
# Diffusers
diffusers @ git+https://github.com/huggingface/diffusers.git@edf36f5128abf3e6ecf92b5145115514363c58e6
# API
flask_cloudflared==0.0.14
sse-starlette==1.6.5

View file

@ -5,6 +5,7 @@ from pathlib import Path
from modules import shared
from modules.block_requests import OpenMonkeyPatch, RequestBlocker
from modules.image_models import load_image_model
from modules.logging_colors import logger
from modules.prompts import load_prompt
@ -320,6 +321,22 @@ if __name__ == "__main__":
if shared.args.lora:
add_lora_to_model(shared.args.lora)
# Load image model if specified via CLI
if shared.args.image_model:
logger.info(f"Loading image model: {shared.args.image_model}")
result = load_image_model(
shared.args.image_model,
dtype=shared.settings.get('image_dtype', 'bfloat16'),
attn_backend=shared.settings.get('image_attn_backend', 'sdpa'),
cpu_offload=shared.settings.get('image_cpu_offload', False),
compile_model=shared.settings.get('image_compile', False),
quant_method=shared.settings.get('image_quant', 'none')
)
if result is not None:
shared.image_model_name = shared.args.image_model
else:
logger.error(f"Failed to load image model: {shared.args.image_model}")
shared.generation_lock = Lock()
if shared.args.idle_timeout > 0: