mirror of
https://github.com/vladmandic/automatic
synced 2026-09-19 17:24:32 +02:00
+21
-6
@@ -1,16 +1,31 @@
|
||||
# Change Log for SD.Next
|
||||
|
||||
## Update for 2025-05-12
|
||||
## Update for 2025-05-15
|
||||
|
||||
Curious how your system is performing?
|
||||
*Curious how your system is performing?*
|
||||
Run a built-in benchmark and compare to over 15k unique results world-wide: (Benchmark data)[https://vladmandic.github.io/sd-extension-system-info/pages/benchmark.html]!
|
||||
From slowest 0.02 it/s running on 6th gen CPU without acceleration up to 275 it/s running on tuned GH100 system!
|
||||
From slowest 0.02 it/s running on 6th gen CPU without acceleration up to 275+ it/s running on tuned GH100 system!
|
||||
|
||||
Also, since quantization is becoming a necessity for almost all new models, see comparison of different quantization methods available in SD.Next: [Quantization](https://vladmandic.github.io/sdnext-docs/Quantization/)
|
||||
*Hint*: Even if you may not need quantization for your current model, it may be worth trying it out as it can significantly improve performance!
|
||||
|
||||
For ZLUDA users, this update adds [compatibility](https://github.com/vladmandic/sdnext/issues/3918) with with latest AMD Adrenaline drivers
|
||||
|
||||
Btw, last few releases have been smaller, but more regular so do check posts about previous releases as features do quickly add up!
|
||||
|
||||
- **Wiki**
|
||||
- Updates for: *WSL, ZLUDA, ROCm*
|
||||
- Updates for: *Quantization, NNCF, WSL, ZLUDA, ROCm*
|
||||
- **Compute**
|
||||
- ZLUDA: update to `zluda==3.9.5` with `torch==2.7.0`
|
||||
*Note*: delete `.zluda` folder so that newest zluda will be installed if you are using the latest AMD Adrenaline driver
|
||||
- NNCF: added experimental support for direct INT8 MatMul
|
||||
|
||||
- **Feature**
|
||||
- Prompt Enhance: option to allow/disallow NSFW content
|
||||
- **Fixes**
|
||||
- OpenVINO: force cpu device
|
||||
- Gradio: major cleanup and fixing defaults and ranges
|
||||
- Pydantic: update to api types
|
||||
- UI defaults: match correct prompt components
|
||||
|
||||
## Update for 2025-05-12
|
||||
|
||||
@@ -973,7 +988,7 @@ Commit hash: `master: #dcfc9f3` `dev: #935cac6`
|
||||
- optimizations: full offload, quantization and tiling support
|
||||
- [TeaCache](https://github.com/ali-vilab/TeaCache/blob/main/TeaCache4LTX-Video/README.md) integration
|
||||
- **VAE**:
|
||||
- tiling granular options in *settings -> variable auto encoder*
|
||||
- tiling granular options in *settings -> Variational Auto Encoder*
|
||||
- **UI**:
|
||||
- live preview optimizations and error handling
|
||||
- live preview high quality output, thanks @Disty0
|
||||
|
||||
@@ -4,20 +4,31 @@ Main ToDo list can be found at [GitHub projects](https://github.com/users/vladma
|
||||
|
||||
## Current
|
||||
|
||||
- [Diffusers guiders](https://github.com/huggingface/diffusers/pull/11311)
|
||||
- [Nunchaku PulID](https://github.com/mit-han-lab/nunchaku/pull/274)
|
||||
- Video: API support
|
||||
|
||||
### Issues/Limitations
|
||||
|
||||
N/A
|
||||
- Control: API enhance scripts compatibility
|
||||
- Video: API support
|
||||
|
||||
## Future Candidates
|
||||
|
||||
- Control: API enhance scripts compatibility
|
||||
- IPAdapter: negative guidance: <https://github.com/huggingface/diffusers/discussions/7167>
|
||||
- Video: STG: <https://github.com/huggingface/diffusers/blob/main/examples/community/README.md#spatiotemporal-skip-guidance>
|
||||
- Video: SmoothCache: https://github.com/huggingface/diffusers/issues/11135
|
||||
- [IPAdapter negative guidance](https://github.com/huggingface/diffusers/discussions/7167)
|
||||
- [STG](https://github.com/huggingface/diffusers/blob/main/examples/community/README.md#spatiotemporal-skip-guidance)
|
||||
- [LBM](https://github.com/gojasper/LBM)
|
||||
- [SmoothCache](https://github.com/huggingface/diffusers/issues/11135)
|
||||
- [Magi](https://github.com/SandAI-org/MAGI-1)
|
||||
- [SkyReels-v2](https://github.com/huggingface/diffusers/pull/11518)
|
||||
- [WanAI-2.1 VACE](https://huggingface.co/Wan-AI/Wan2.1-VACE-14B)
|
||||
- [LTXVideo-0.9.7](https://github.com/huggingface/diffusers/pull/11516)
|
||||
- [VisualClose](https://github.com/huggingface/diffusers/pull/11377)
|
||||
- [SEVA](https://github.com/huggingface/diffusers/pull/11440)
|
||||
- [CausVid-Plus](https://github.com/goatWu/CausVid-Plus/)
|
||||
- [Index-AniSora](https://github.com/bilibili/Index-anisora)
|
||||
- [HiDream GGUF](https://github.com/huggingface/diffusers/pull/11550)
|
||||
- [JoyCaption-Beta-One](https://huggingface.co/fancyfeast/llama-joycaption-beta-one-hf-llava)
|
||||
- [Diffusers guiders](https://github.com/huggingface/diffusers/pull/11311)
|
||||
- [Nunchaku PulID](https://github.com/mit-han-lab/nunchaku/pull/274)
|
||||
- [Dream0](https://huggingface.co/ByteDance/DreamO)
|
||||
- [Pydantic changes](https://github.com/Cschlaefli/automatic)
|
||||
|
||||
## Code TODO
|
||||
|
||||
@@ -31,14 +42,13 @@ N/A
|
||||
- loader: load receipe
|
||||
- loader: save receipe
|
||||
- lora: add other quantization types
|
||||
- lora: add t5 key support for sd35/f1
|
||||
- lora: maybe force imediate quantization
|
||||
- lora: add t5 key support for sd35/f16
|
||||
- lora: support pre-quantized flux
|
||||
- model load: force-reloading entire model as loading transformers only leads to massive memory usage
|
||||
- model loader: implement model in-memory caching
|
||||
- modernui: monkey-patch for missing tabs.select event
|
||||
- modules/lora/lora_extract.py:185:9: W0511: TODO: lora: support pre-quantized flux
|
||||
- nunchaku: batch support
|
||||
- nunchaku: cache-dir for transformer and t5 loader
|
||||
- processing: remove duplicate mask params
|
||||
- resize image: enable full VAE mode for resize-latent
|
||||
|
||||
@@ -53,6 +53,7 @@ def enhance(args): # pylint: disable=redefined-outer-name
|
||||
'prompt': str(args.prompt),
|
||||
'seed': int(args.seed),
|
||||
'type': str(args.type),
|
||||
'nsfw': bool(args.nsfw),
|
||||
}
|
||||
if args.model:
|
||||
options['model'] = str(args.model)
|
||||
@@ -69,6 +70,7 @@ if __name__ == "__main__":
|
||||
parser.add_argument('--type', type=str, default='text', choices=['text', 'image', 'video'], required=False, help='enhance type')
|
||||
parser.add_argument('--model', type=str, default=None, required=False, help='model name')
|
||||
parser.add_argument('--image', type=str, default=None, required=False, help='optional input image')
|
||||
parser.add_argument('--nsfw', type=bool, action=argparse.BooleanOptionalAction, required=False, help='nsfw allowed')
|
||||
args = parser.parse_args()
|
||||
log.info(f'api-upscale: {args}')
|
||||
result = enhance(args)
|
||||
|
||||
Submodule extensions-builtin/sd-extension-system-info updated: ce373b9c27...539625f289
+1
-1
@@ -1402,7 +1402,7 @@
|
||||
},
|
||||
{
|
||||
"id": "",
|
||||
"label": "Variable Auto Encoder",
|
||||
"label": "Variational Auto Encoder",
|
||||
"localized": "Variabler Auto-Encoder",
|
||||
"hint": "Einstellungen bezüglich variablem Auto-Encoder und Bilddekodierungsprozess während der Generierung"
|
||||
},
|
||||
|
||||
+2
-2
@@ -59,7 +59,7 @@
|
||||
{"id":"","label":"Hypernetwork","localized":"","hint":"Small trained neural network that modifies behavior of the loaded model"},
|
||||
{"id":"","label":"VLM Caption","localized":"","hint":"Analyze image using vision langugage model"},
|
||||
{"id":"","label":"CLiP Interrogate","localized":"","hint":"Analyze image using CLiP model"},
|
||||
{"id":"","label":"VAE","localized":"","hint":"Variable Auto Encoder: model used to run image decode at the end of generate"},
|
||||
{"id":"","label":"VAE","localized":"","hint":"Variational Auto Encoder: model used to run image decode at the end of generate"},
|
||||
{"id":"","label":"History","localized":"","hint":"List of previous generations that can be further reprocessed"},
|
||||
{"id":"","label":"UI disable variable aspect ratio","localized":"","hint":"When disabled, all thumbnails appear as squared images"},
|
||||
{"id":"","label":"Build info on first access","localized":"","hint":"Prevents server from building EN page on server startup and instead build it when requested"},
|
||||
@@ -247,7 +247,7 @@
|
||||
{"id":"","label":"Unload model","localized":"","hint":"Unload currently loaded model"},
|
||||
{"id":"","label":"Reload model","localized":"","hint":"Reload currently selected model"},
|
||||
{"id":"","label":"Models & Loading","localized":"","hint":"Settings related to base models, primary backend and model load behavior"},
|
||||
{"id":"","label":"Variable Auto Encoder","localized":"","hint":"Settings related to variable auto encoder and image decoding process during generate"},
|
||||
{"id":"","label":"Variational Auto Encoder","localized":"","hint":"Settings related to Variational Auto Encoder and image decoding process during generate"},
|
||||
{"id":"","label":"Text encoder","localized":"","hint":"Settings related to text encoder and prompt encoding processing during generate"},
|
||||
{"id":"","label":"Compute Settings","localized":"","hint":"Settings related to compute precision, cross attention, and optimizations for computing platforms"},
|
||||
{"id":"","label":"Backend Settings","localized":"","hint":"Settings related to compute backends: torch, onnx and olive"},
|
||||
|
||||
+2
-2
@@ -324,7 +324,7 @@
|
||||
"id": "",
|
||||
"label": "VAE",
|
||||
"localized": "VAE",
|
||||
"hint": "Variable Auto Encoder: modelo usado para ejecutar la decodificación de la imagen al final de la generación"
|
||||
"hint": "Variational Auto Encoder: modelo usado para ejecutar la decodificación de la imagen al final de la generación"
|
||||
},
|
||||
{
|
||||
"id": "",
|
||||
@@ -1402,7 +1402,7 @@
|
||||
},
|
||||
{
|
||||
"id": "",
|
||||
"label": "Variable Auto Encoder",
|
||||
"label": "Variational Auto Encoder",
|
||||
"localized": "Autoencoder Variable",
|
||||
"hint": "Configuración relacionada con el autoencoder variable y el proceso de decodificación de imágenes durante la generación"
|
||||
},
|
||||
|
||||
+2
-2
@@ -324,7 +324,7 @@
|
||||
"id": "",
|
||||
"label": "VAE",
|
||||
"localized": "VAE",
|
||||
"hint": "Variable Auto Encoder : modèle utilisé pour exécuter le décodage d'image à la fin de la génération"
|
||||
"hint": "Variational Auto Encoder : modèle utilisé pour exécuter le décodage d'image à la fin de la génération"
|
||||
},
|
||||
{
|
||||
"id": "",
|
||||
@@ -1402,7 +1402,7 @@
|
||||
},
|
||||
{
|
||||
"id": "",
|
||||
"label": "Variable Auto Encoder",
|
||||
"label": "Variational Auto Encoder",
|
||||
"localized": "Encodeur automatique variable",
|
||||
"hint": "Paramètres liés à l'encodeur automatique variable et au processus de décodage d'image pendant la génération"
|
||||
},
|
||||
|
||||
+2
-2
@@ -324,7 +324,7 @@
|
||||
"id": "",
|
||||
"label": "VAE",
|
||||
"localized": "VAE",
|
||||
"hint": "Variable Auto Encoder: model koji se koristi za pokretanje dekodiranja slike na kraju generiranja"
|
||||
"hint": "Variational Auto Encoder: model koji se koristi za pokretanje dekodiranja slike na kraju generiranja"
|
||||
},
|
||||
{
|
||||
"id": "",
|
||||
@@ -1402,7 +1402,7 @@
|
||||
},
|
||||
{
|
||||
"id": "",
|
||||
"label": "Variable Auto Encoder",
|
||||
"label": "Variational Auto Encoder",
|
||||
"localized": "Varijabilni Auto Encoder",
|
||||
"hint": "Postavke vezane uz varijabilni auto encoder i proces dekodiranja slike tijekom generiranja"
|
||||
},
|
||||
|
||||
+4
-4
@@ -324,7 +324,7 @@
|
||||
"id": "",
|
||||
"label": "VAE",
|
||||
"localized": "VAE",
|
||||
"hint": "Variable Auto Encoder: modello utilizzato per eseguire la decodifica dell'immagine alla fine della generazione"
|
||||
"hint": "Variational Auto Encoder: modello utilizzato per eseguire la decodifica dell'immagine alla fine della generazione"
|
||||
},
|
||||
{
|
||||
"id": "",
|
||||
@@ -1402,9 +1402,9 @@
|
||||
},
|
||||
{
|
||||
"id": "",
|
||||
"label": "Variable Auto Encoder",
|
||||
"localized": "Variable Auto Encoder",
|
||||
"hint": "Impostazioni relative al variable auto encoder e al processo di decodifica delle immagini durante la generazione"
|
||||
"label": "Variational Auto Encoder",
|
||||
"localized": "Variational Auto Encoder",
|
||||
"hint": "Impostazioni relative al Variational Auto Encoder e al processo di decodifica delle immagini durante la generazione"
|
||||
},
|
||||
{
|
||||
"id": "",
|
||||
|
||||
+2
-2
@@ -324,7 +324,7 @@
|
||||
"id": "",
|
||||
"label": "VAE",
|
||||
"localized": "VAE",
|
||||
"hint": "Variable Auto Encoder:生成の最後にイメージデコードを実行するために使用されるモデル"
|
||||
"hint": "Variational Auto Encoder:生成の最後にイメージデコードを実行するために使用されるモデル"
|
||||
},
|
||||
{
|
||||
"id": "",
|
||||
@@ -1402,7 +1402,7 @@
|
||||
},
|
||||
{
|
||||
"id": "",
|
||||
"label": "Variable Auto Encoder",
|
||||
"label": "Variational Auto Encoder",
|
||||
"localized": "可変オートエンコーダー",
|
||||
"hint": "生成時の可変オートエンコーダーと画像デコードプロセスに関する設定。"
|
||||
},
|
||||
|
||||
+3
-3
@@ -324,7 +324,7 @@
|
||||
"id": "",
|
||||
"label": "VAE",
|
||||
"localized": "VAE",
|
||||
"hint": "Variable Auto Encoder: 생성 종료 시 이미지 디코드를 실행하는 데 사용되는 모델"
|
||||
"hint": "Variational Auto Encoder: 생성 종료 시 이미지 디코드를 실행하는 데 사용되는 모델"
|
||||
},
|
||||
{
|
||||
"id": "",
|
||||
@@ -1402,8 +1402,8 @@
|
||||
},
|
||||
{
|
||||
"id": "",
|
||||
"label": "Variable Auto Encoder",
|
||||
"localized": "Variable Auto Encoder",
|
||||
"label": "Variational Auto Encoder",
|
||||
"localized": "Variational Auto Encoder",
|
||||
"hint": "가변 자동 인코더 및 생성 중 이미지 디코딩 프로세스와 관련된 설정입니다."
|
||||
},
|
||||
{
|
||||
|
||||
+2
-2
@@ -324,7 +324,7 @@
|
||||
"id": "",
|
||||
"label": "VAE",
|
||||
"localized": "VAE",
|
||||
"hint": "Variable Auto Encoder: modelo usado para executar a decodificação da imagem no final da geração"
|
||||
"hint": "Variational Auto Encoder: modelo usado para executar a decodificação da imagem no final da geração"
|
||||
},
|
||||
{
|
||||
"id": "",
|
||||
@@ -1402,7 +1402,7 @@
|
||||
},
|
||||
{
|
||||
"id": "",
|
||||
"label": "Variable Auto Encoder",
|
||||
"label": "Variational Auto Encoder",
|
||||
"localized": "Auto Encoder Variável",
|
||||
"hint": "Configurações relacionadas ao auto encoder variável e ao processo de decodificação de imagem durante a geração"
|
||||
},
|
||||
|
||||
+2
-2
@@ -324,7 +324,7 @@
|
||||
"id": "",
|
||||
"label": "VAE",
|
||||
"localized": "VAE",
|
||||
"hint": "Variable Auto Encoder: модель, используемая для запуска декодирования изображения в конце генерации"
|
||||
"hint": "Variational Auto Encoder: модель, используемая для запуска декодирования изображения в конце генерации"
|
||||
},
|
||||
{
|
||||
"id": "",
|
||||
@@ -1402,7 +1402,7 @@
|
||||
},
|
||||
{
|
||||
"id": "",
|
||||
"label": "Variable Auto Encoder",
|
||||
"label": "Variational Auto Encoder",
|
||||
"localized": "Вариативный автоэнкодер",
|
||||
"hint": "Настройки, связанные с вариативным автоэнкодером и процессом декодирования изображений во время генерации"
|
||||
},
|
||||
|
||||
+1
-1
@@ -1402,7 +1402,7 @@
|
||||
},
|
||||
{
|
||||
"id": "",
|
||||
"label": "Variable Auto Encoder",
|
||||
"label": "Variational Auto Encoder",
|
||||
"localized": "可变自动编码器",
|
||||
"hint": "与可变自动编码器和生成过程中图像解码过程相关的设置"
|
||||
},
|
||||
|
||||
File diff suppressed because one or more lines are too long
+2
-2
@@ -546,7 +546,7 @@ def check_diffusers():
|
||||
t_start = time.time()
|
||||
if args.skip_all or args.skip_git or args.experimental:
|
||||
return
|
||||
sha = '0ba1f76d4dde6d25b33dbdca73b6aa21bb682c56' # diffusers commit hash
|
||||
sha = '20379d9d1395b8e95977faf80facff43065ba75f' # diffusers commit hash
|
||||
pkg = pkg_resources.working_set.by_key.get('diffusers', None)
|
||||
minor = int(pkg.version.split('.')[1] if pkg is not None else 0)
|
||||
cur = opts.get('diffusers_version', '') if minor > 0 else ''
|
||||
@@ -655,7 +655,7 @@ def install_rocm_zluda():
|
||||
if error is None:
|
||||
try:
|
||||
zluda_installer.load()
|
||||
torch_command = os.environ.get('TORCH_COMMAND', 'torch==2.6.0 torchvision --index-url https://download.pytorch.org/whl/cu118')
|
||||
torch_command = os.environ.get('TORCH_COMMAND', 'torch==2.7.0 torchvision --index-url https://download.pytorch.org/whl/cu118')
|
||||
except Exception as e:
|
||||
error = e
|
||||
log.warning(f'Failed to load ZLUDA: {e}')
|
||||
|
||||
@@ -23,7 +23,7 @@ ReqControl = models.create_model_from_signature(
|
||||
model_name = "StableDiffusionProcessingControl",
|
||||
additional_fields = [
|
||||
{"key": "sampler_name", "type": str, "default": "UniPC"},
|
||||
{"key": "script_name", "type": str, "default": None},
|
||||
{"key": "script_name", "type": Optional[str], "default": None},
|
||||
{"key": "script_args", "type": list, "default": []},
|
||||
{"key": "send_images", "type": bool, "default": True},
|
||||
{"key": "save_images", "type": bool, "default": False},
|
||||
|
||||
+24
-19
@@ -67,8 +67,11 @@ class PydanticModelGenerator:
|
||||
def generate_model(self):
|
||||
model_fields = { d.field: (d.field_type, Field(default=d.field_value, alias=d.field_alias, exclude=d.field_exclude)) for d in self._model_def }
|
||||
DynamicModel = create_model(self._model_name, **model_fields)
|
||||
DynamicModel.__config__.allow_population_by_field_name = True
|
||||
DynamicModel.__config__.allow_mutation = True
|
||||
try:
|
||||
DynamicModel.__config__.allow_population_by_field_name = True
|
||||
DynamicModel.__config__.allow_mutation = True
|
||||
except Exception:
|
||||
pass
|
||||
return DynamicModel
|
||||
|
||||
### item classes
|
||||
@@ -182,7 +185,7 @@ class ItemScript(BaseModel):
|
||||
class ItemExtension(BaseModel):
|
||||
name: str = Field(title="Name", description="Extension name")
|
||||
remote: str = Field(title="Remote", description="Extension Repository URL")
|
||||
branch: str = Field(title="Branch", description="Extension Repository Branch")
|
||||
branch: str = Field(default="uknnown", title="Branch", description="Extension Repository Branch")
|
||||
commit_hash: str = Field(title="Commit Hash", description="Extension Repository Commit Hash")
|
||||
version: str = Field(title="Version", description="Extension Version")
|
||||
commit_date: str = Field(title="Commit Date", description="Extension Repository Commit Date")
|
||||
@@ -197,7 +200,7 @@ ReqTxt2Img = PydanticModelGenerator(
|
||||
{"key": "sampler_index", "type": Union[int, str], "default": 0},
|
||||
{"key": "sampler_name", "type": str, "default": "UniPC"},
|
||||
{"key": "hr_sampler_name", "type": str, "default": "Same as primary"},
|
||||
{"key": "script_name", "type": str, "default": "none"},
|
||||
{"key": "script_name", "type": Optional[str], "default": "none"},
|
||||
{"key": "script_args", "type": list, "default": []},
|
||||
{"key": "send_images", "type": bool, "default": True},
|
||||
{"key": "save_images", "type": bool, "default": False},
|
||||
@@ -221,13 +224,11 @@ ReqImg2Img = PydanticModelGenerator(
|
||||
{"key": "sampler_index", "type": Union[int, str], "default": 0},
|
||||
{"key": "sampler_name", "type": str, "default": "UniPC"},
|
||||
{"key": "hr_sampler_name", "type": str, "default": "Same as primary"},
|
||||
{"key": "script_name", "type": str, "default": "none"},
|
||||
{"key": "script_args", "type": list, "default": []},
|
||||
{"key": "init_images", "type": list, "default": None},
|
||||
{"key": "denoising_strength", "type": float, "default": 0.5},
|
||||
{"key": "mask", "type": str, "default": None},
|
||||
{"key": "mask", "type": Optional[str], "default": None},
|
||||
{"key": "include_init_images", "type": bool, "default": False, "exclude": True},
|
||||
{"key": "script_name", "type": str, "default": None},
|
||||
{"key": "script_name", "type": Optional[str], "default": "none"},
|
||||
{"key": "script_args", "type": list, "default": []},
|
||||
{"key": "send_images", "type": bool, "default": True},
|
||||
{"key": "save_images", "type": bool, "default": False},
|
||||
@@ -274,6 +275,7 @@ class ReqPromptEnhance(BaseModel):
|
||||
system_prompt: Optional[str] = Field(title="System prompt", default=None, description="Model system prompt")
|
||||
image: Optional[str] = Field(title="Image", default=None, description="Image to work on, must be a Base64 string containing the image's data.")
|
||||
seed: int = Field(title="Seed", default=-1, description="Seed used to generate the prompt")
|
||||
nsfw: bool = Field(title="NSFW", default=True, description="Should NSFW content be allowed?")
|
||||
|
||||
class ResPromptEnhance(BaseModel):
|
||||
prompt: str = Field(title="Prompt", description="Enhanced prompt")
|
||||
@@ -305,9 +307,9 @@ class ReqGetLog(BaseModel):
|
||||
|
||||
|
||||
class ReqPostLog(BaseModel):
|
||||
message: Optional[str] = Field(title="Message", description="The info message to log")
|
||||
debug: Optional[str] = Field(title="Debug message", description="The debug message to log")
|
||||
error: Optional[str] = Field(title="Error message", description="The error message to log")
|
||||
message: Optional[str] = Field(default=None, title="Message", description="The info message to log")
|
||||
debug: Optional[str] = Field(default=None, title="Debug message", description="The debug message to log")
|
||||
error: Optional[str] = Field(default=None, title="Error message", description="The error message to log")
|
||||
|
||||
class ReqHistory(BaseModel):
|
||||
id: str = Field(default=None, title="Task ID", description="Task ID")
|
||||
@@ -320,8 +322,8 @@ class ResProgress(BaseModel):
|
||||
progress: float = Field(title="Progress", description="The progress with a range of 0 to 1")
|
||||
eta_relative: float = Field(title="ETA in secs")
|
||||
state: dict = Field(title="State", description="The current state snapshot")
|
||||
current_image: str = Field(default=None, title="Current image", description="The current image in base64 format. opts.show_progress_every_n_steps is required for this to work.")
|
||||
textinfo: str = Field(default=None, title="Info text", description="Info text used by WebUI.")
|
||||
current_image: Optional[str] = Field(default=None, title="Current image", description="The current image in base64 format. opts.show_progress_every_n_steps is required for this to work.")
|
||||
textinfo: Optional[str] = Field(default=None, title="Info text", description="Info text used by WebUI.")
|
||||
|
||||
class ResHistory(BaseModel):
|
||||
id: str = Field(title="ID", description="Task ID")
|
||||
@@ -344,9 +346,9 @@ class ResStatus(BaseModel):
|
||||
steps: int = Field(title="Steps", description="Total steps")
|
||||
queued: int = Field(title="Queued", description="Number of queued tasks")
|
||||
uptime: int = Field(title="Uptime", description="Uptime of the server")
|
||||
elapsed: Optional[float] = Field(title="Elapsed time")
|
||||
eta: Optional[float] = Field(title="ETA in secs")
|
||||
progress: Optional[float] = Field(title="Progress", description="The progress with a range of 0 to 1")
|
||||
elapsed: Optional[float] = Field(default=None, title="Elapsed time")
|
||||
eta: Optional[float] = Field(default=None, title="ETA in secs")
|
||||
progress: Optional[float] = Field(default=None, title="Progress", description="The progress with a range of 0 to 1")
|
||||
|
||||
|
||||
class ReqInterrogate(BaseModel):
|
||||
@@ -403,7 +405,7 @@ _options = vars(shared.parser)['_option_string_actions']
|
||||
for key in _options:
|
||||
if _options[key].dest != 'help':
|
||||
flag = _options[key]
|
||||
_type = str
|
||||
_type = Optional[str]
|
||||
if _options[key].default is not None:
|
||||
_type = type(_options[key].default)
|
||||
flags.update({flag.dest: (_type, Field(default=flag.default, description=flag.help))})
|
||||
@@ -481,6 +483,9 @@ def create_model_from_signature(func: Callable, model_name: str, base_model: Typ
|
||||
__base__=base_model,
|
||||
__config__=config,
|
||||
)
|
||||
model.__config__.allow_population_by_field_name = True
|
||||
model.__config__.allow_mutation = True
|
||||
try:
|
||||
model.__config__.allow_population_by_field_name = True
|
||||
model.__config__.allow_mutation = True
|
||||
except Exception:
|
||||
pass
|
||||
return model
|
||||
|
||||
@@ -146,6 +146,7 @@ class APIProcess():
|
||||
prompt=req.prompt,
|
||||
system=req.system_prompt,
|
||||
seed=seed,
|
||||
nsfw=req.nsfw,
|
||||
)
|
||||
elif req.type == 'image':
|
||||
from modules.scripts import scripts_txt2img
|
||||
@@ -157,6 +158,7 @@ class APIProcess():
|
||||
system=req.system_prompt,
|
||||
image=decode_base64_to_image(req.image),
|
||||
seed=seed,
|
||||
nsfw=req.nsfw,
|
||||
)
|
||||
elif req.type == 'video':
|
||||
from modules.ui_video_vlm import enhance_prompt
|
||||
@@ -167,6 +169,7 @@ class APIProcess():
|
||||
prompt=req.prompt,
|
||||
model=model,
|
||||
system_prompt=req.system_prompt,
|
||||
nsfw=req.nsfw,
|
||||
)
|
||||
else:
|
||||
raise HTTPException(status_code=400, detail="prompt enhancement: invalid type")
|
||||
|
||||
@@ -69,7 +69,7 @@ class Extension:
|
||||
if repo.active_branch:
|
||||
self.branch = repo.active_branch.name
|
||||
except Exception:
|
||||
pass
|
||||
self.branch = 'unknown'
|
||||
self.commit_hash = head.hexsha
|
||||
self.version = f"<p>{self.commit_hash[:8]}</p><p>{datetime.fromtimestamp(self.commit_date).strftime('%a %b%d %Y %H:%M')}</p>"
|
||||
except Exception as ex:
|
||||
|
||||
@@ -92,12 +92,12 @@ class Script(scripts.Script):
|
||||
gr.HTML('<a href="https://photo-maker.github.io/" target="_blank">  Tenecent ARC Lab PhotoMaker</a><br>')
|
||||
with gr.Row():
|
||||
pm_model = gr.Dropdown(label='PhotoMaker Model', choices=['PhotoMaker v1', 'PhotoMaker v2'], value='PhotoMaker v2')
|
||||
pm_trigger = gr.Text(label='Trigger word', placeholder="enter one word in prompt")
|
||||
pm_trigger = gr.Textbox(label='Trigger word', placeholder="enter one word in prompt")
|
||||
with gr.Row():
|
||||
pm_strength = gr.Slider(label='Strength', minimum=0.0, maximum=2.0, step=0.01, value=1.0)
|
||||
pm_start = gr.Slider(label='Start', minimum=0.0, maximum=1.0, step=0.01, value=0.5)
|
||||
with gr.Row():
|
||||
files = gr.File(label='Input images', file_count='multiple', file_types=['image'], type='file', interactive=True, height=100)
|
||||
files = gr.File(label='Input images', file_count='multiple', file_types=['image'], interactive=True, height=100)
|
||||
with gr.Row():
|
||||
gallery = gr.Gallery(show_label=False, value=[])
|
||||
files.change(fn=self.load_images, inputs=[files], outputs=[gallery])
|
||||
|
||||
+34
-2
@@ -84,14 +84,46 @@ def Blocks_get_config_file(self, *args, **kwargs):
|
||||
return config
|
||||
|
||||
|
||||
def patch_gradio():
|
||||
def wrap_gradio_js(fn):
|
||||
def wrapper(*args, js=None, _js=None, **kwargs):
|
||||
if _js is not None:
|
||||
js = _js
|
||||
return fn(*args, js=js, **kwargs)
|
||||
return wrapper
|
||||
|
||||
gradio.components.Button.click = wrap_gradio_js(gradio.components.Button.click)
|
||||
gradio.components.Textbox.submit = wrap_gradio_js(gradio.components.Textbox.submit)
|
||||
gradio.components.Image.clear = wrap_gradio_js(gradio.components.Image.clear)
|
||||
gradio.components.Image.change = wrap_gradio_js(gradio.components.Image.change)
|
||||
gradio.components.Image.upload = wrap_gradio_js(gradio.components.Image.upload)
|
||||
gradio.components.Video.change = wrap_gradio_js(gradio.components.Video.change)
|
||||
gradio.components.Video.clear = wrap_gradio_js(gradio.components.Video.clear)
|
||||
gradio.components.Slider.change = wrap_gradio_js(gradio.components.Slider.change)
|
||||
gradio.components.Dropdown.change = wrap_gradio_js(gradio.components.Dropdown.change)
|
||||
gradio.components.File.change = wrap_gradio_js(gradio.components.File.change)
|
||||
gradio.components.File.clear = wrap_gradio_js(gradio.components.File.clear)
|
||||
gradio.components.Number.change = wrap_gradio_js(gradio.components.Number.change)
|
||||
gradio.components.Textbox.change = wrap_gradio_js(gradio.components.Textbox.change)
|
||||
gradio.components.Radio.change = wrap_gradio_js(gradio.components.Radio.change)
|
||||
gradio.components.Checkbox.change = wrap_gradio_js(gradio.components.Checkbox.change)
|
||||
gradio.components.CheckboxGroup.change = wrap_gradio_js(gradio.components.CheckboxGroup.change)
|
||||
gradio.components.ColorPicker.change = wrap_gradio_js(gradio.components.ColorPicker.change)
|
||||
gradio.layouts.Tab.select = wrap_gradio_js(gradio.layouts.Tab.select)
|
||||
gradio.components.Image.edit = lambda *args, **kwargs: None
|
||||
# gradio.components.image.Image.__init__ missing tool, brush_radius, mask_opacity, edit()
|
||||
|
||||
def init():
|
||||
global hijacked, original_IOComponent_init, original_Block_get_config, original_BlockContext_init, original_Blocks_get_config_file # pylint: disable=global-statement
|
||||
if hijacked:
|
||||
return
|
||||
gr.components.Image.preprocess = gr_image_preprocess
|
||||
gr.components.IOComponent.pil_to_temp_file = gr_tempdir.pil_to_temp_file
|
||||
original_IOComponent_init = patches.patch(__name__, obj=gr.components.IOComponent, field="__init__", replacement=IOComponent_init)
|
||||
if hasattr(gr.components, 'IOComponent'):
|
||||
gr.components.IOComponent.pil_to_temp_file = gr_tempdir.pil_to_temp_file
|
||||
original_IOComponent_init = patches.patch(__name__, obj=gr.components.IOComponent, field="__init__", replacement=IOComponent_init)
|
||||
original_Block_get_config = patches.patch(__name__, obj=gr.blocks.Block, field="get_config", replacement=Block_get_config)
|
||||
original_BlockContext_init = patches.patch(__name__, obj=gr.blocks.BlockContext, field="__init__", replacement=BlockContext_init)
|
||||
original_Blocks_get_config_file = patches.patch(__name__, obj=gr.blocks.Blocks, field="get_config_file", replacement=Blocks_get_config_file)
|
||||
if not gr.__version__.startswith('3.43'):
|
||||
patch_gradio()
|
||||
hijacked = True
|
||||
|
||||
@@ -151,7 +151,7 @@ def network_add_weights(self: Union[torch.nn.Conv2d, torch.nn.Linear, torch.nn.G
|
||||
new_weight = dequant_weight.to(devices.device, dtype=torch.float32) + lora_weights.to(devices.device, dtype=torch.float32)
|
||||
self.weight = torch.nn.Parameter(new_weight, requires_grad=False)
|
||||
self.pre_ops.pop("0")
|
||||
self._custom_forward_fn = None
|
||||
self._custom_forward_fn = None # pylint: disable=protected-access
|
||||
self = nncf_compress_layer(self, num_bits, is_asym_mode, torch_dtype=devices.dtype, quant_conv=shared.opts.nncf_quantize_conv_layers, group_size=shared.opts.nncf_compress_weights_group_size, use_int8_matmul=shared.opts.nncf_decompress_int8_matmul)
|
||||
self = self.to(device)
|
||||
del dequant_weight
|
||||
|
||||
@@ -111,7 +111,6 @@ def create_nncf_config(kwargs = None, allow_nncf: bool = True, module: str = 'Mo
|
||||
load_nncf(silent=True)
|
||||
if intel_nncf is None:
|
||||
return kwargs
|
||||
|
||||
from modules.model_quant_nncf import NNCFQuantizer, NNCFConfig
|
||||
diffusers.quantizers.auto.AUTO_QUANTIZER_MAPPING["nncf"] = NNCFQuantizer
|
||||
transformers.quantizers.auto.AUTO_QUANTIZER_MAPPING["nncf"] = NNCFQuantizer
|
||||
@@ -269,12 +268,12 @@ def load_nncf(msg='', silent=False):
|
||||
log.warning('Quantization: nncf installed please restart')
|
||||
install('jstyleson', quiet=True)
|
||||
install('texttable', quiet=True)
|
||||
install('tabulate', quiet=True)
|
||||
try:
|
||||
import nncf
|
||||
intel_nncf = nncf
|
||||
try:
|
||||
# silence the pytorch version warning
|
||||
nncf.common.logging.logger.warn_bkc_version_mismatch = lambda *args, **kwargs: None
|
||||
nncf.common.logging.logger.warn_bkc_version_mismatch = lambda *args, **kwargs: None # silence the pytorch version warning
|
||||
except Exception:
|
||||
pass
|
||||
fn = f'{sys._getframe(2).f_code.co_name}:{sys._getframe(1).f_code.co_name}' # pylint: disable=protected-access
|
||||
@@ -328,7 +327,8 @@ def apply_layerwise(sd_model, quiet:bool=False):
|
||||
m.quantization_method = quantization_config.QuantizationMethod.LAYERWISE # pylint: disable=no-member
|
||||
log.quiet(quiet, f'Quantization: type=layerwise module={module} cls={cls} storage={storage_dtype} compute={devices.dtype} blocking={not non_blocking}')
|
||||
except Exception as e:
|
||||
log.error(f'Quantization: type=layerwise {e}')
|
||||
if 'Hook with name' not in str(e):
|
||||
log.error(f'Quantization: type=layerwise {e}')
|
||||
|
||||
|
||||
def nncf_compress_model(model, op=None, sd_model=None, do_gc=True):
|
||||
|
||||
+50
-81
@@ -1,28 +1,25 @@
|
||||
# pylint: disable=redefined-builtin,no-member
|
||||
|
||||
from typing import Any, Dict, List, Tuple, Optional, Union
|
||||
from dataclasses import dataclass
|
||||
from enum import Enum
|
||||
|
||||
import os
|
||||
import torch
|
||||
from diffusers.quantizers.base import DiffusersQuantizer
|
||||
from diffusers.quantizers.quantization_config import QuantizationConfigMixin
|
||||
from diffusers.utils import get_module_from_name
|
||||
|
||||
from accelerate import init_empty_weights
|
||||
from accelerate.utils import CustomDtype
|
||||
|
||||
from modules import devices, shared
|
||||
|
||||
|
||||
debug = os.environ.get('SD_QUANT_DEBUG', None) is not None
|
||||
|
||||
torch_dtype_dict = {
|
||||
"int8": torch.int8,
|
||||
"uint8": torch.uint8,
|
||||
"int4": CustomDtype.INT4,
|
||||
"uint4": CustomDtype.INT4,
|
||||
}
|
||||
|
||||
weights_dtype_dict = {
|
||||
"int8_asym": "uint8",
|
||||
"int8_sym": "int8",
|
||||
@@ -31,21 +28,20 @@ weights_dtype_dict = {
|
||||
"int8": "uint8",
|
||||
"int4": "uint4",
|
||||
}
|
||||
|
||||
linear_types = ["NNCFLinear", "Linear"]
|
||||
conv_types = ["NNCFConv1d", "NNCFConv2d", "NNCFConv3d", "Conv1d", "Conv2d", "Conv3d"]
|
||||
conv_transpose_types = ["NNCFConvTranspose1d", "NNCFConvTranspose2d", "NNCFConvTranspose3d", "ConvTranspose1d", "ConvTranspose2d", "ConvTranspose3d"]
|
||||
|
||||
allowed_types = []
|
||||
allowed_types.extend(linear_types)
|
||||
allowed_types.extend(conv_types)
|
||||
allowed_types.extend(conv_transpose_types)
|
||||
|
||||
|
||||
class QuantizationMethod(str, Enum):
|
||||
NNCF = "nncf"
|
||||
|
||||
|
||||
def nncf_compress_layer(layer, num_bits, is_asym_mode, torch_dtype=None, quant_conv=False, group_size=0, use_int8_matmul=False, param_name=None):
|
||||
def nncf_compress_layer(layer, num_bits, is_asym_mode, torch_dtype=None, quant_conv=False, group_size=0, use_int8_matmul=False, param_name=None): # pylint: disable=unused-argument
|
||||
if layer.__class__.__name__ in allowed_types:
|
||||
if torch_dtype is None:
|
||||
torch_dtype = devices.dtype
|
||||
@@ -64,7 +60,7 @@ def nncf_compress_layer(layer, num_bits, is_asym_mode, torch_dtype=None, quant_c
|
||||
else:
|
||||
reduction_axes = -1
|
||||
channel_size = layer.weight.shape[-1]
|
||||
use_int8_matmul = use_int8_matmul and not is_asym_mode and channel_size >= 1024 and layer.weight.shape[0] >= 1024
|
||||
use_int8_matmul = use_int8_matmul and not is_asym_mode and channel_size >= 32 and layer.weight.shape[0] >= 32
|
||||
|
||||
if not use_int8_matmul and (group_size > 0 or (num_bits == 4 and group_size != -1)):
|
||||
if group_size == 0:
|
||||
@@ -110,12 +106,12 @@ def nncf_compress_layer(layer, num_bits, is_asym_mode, torch_dtype=None, quant_c
|
||||
zero_point = zero_point.to(torch_dtype)
|
||||
|
||||
if use_int8_matmul:
|
||||
layer._custom_forward_fn = linear_forward_int8_matmul
|
||||
layer._custom_forward_fn = linear_forward_int8_matmul # pylint: disable=protected-access
|
||||
scale = scale.squeeze(-1)
|
||||
if num_bits == 8:
|
||||
compressed_weight = compressed_weight.transpose(0,1)
|
||||
else:
|
||||
layer._custom_forward_fn = None
|
||||
layer._custom_forward_fn = None # pylint: disable=protected-access
|
||||
|
||||
if num_bits == 4:
|
||||
if is_asym_mode:
|
||||
@@ -125,7 +121,6 @@ def nncf_compress_layer(layer, num_bits, is_asym_mode, torch_dtype=None, quant_c
|
||||
compressed_weight_shape=compressed_weight.shape,
|
||||
result_dtype=torch_dtype,
|
||||
result_shape=result_shape,
|
||||
use_int8_matmul=use_int8_matmul,
|
||||
)
|
||||
else:
|
||||
decompressor = INT4SymmetricWeightsDecompressor(
|
||||
@@ -142,7 +137,6 @@ def nncf_compress_layer(layer, num_bits, is_asym_mode, torch_dtype=None, quant_c
|
||||
zero_point=zero_point.data,
|
||||
result_dtype=torch_dtype,
|
||||
result_shape=result_shape,
|
||||
use_int8_matmul=use_int8_matmul,
|
||||
)
|
||||
else:
|
||||
decompressor = INT8SymmetricWeightsDecompressor(
|
||||
@@ -152,12 +146,9 @@ def nncf_compress_layer(layer, num_bits, is_asym_mode, torch_dtype=None, quant_c
|
||||
use_int8_matmul=use_int8_matmul,
|
||||
)
|
||||
|
||||
compressed_weight = decompressor.pack_weight(compressed_weight)
|
||||
compressed_weight = compressed_weight.to(return_device)
|
||||
|
||||
compressed_weight = decompressor.pack_weight(compressed_weight).to(return_device)
|
||||
decompressor = decompressor.to(return_device)
|
||||
layer.register_pre_forward_operation(decompressor)
|
||||
|
||||
layer.weight.requires_grad = False
|
||||
layer.weight.data = compressed_weight
|
||||
return layer
|
||||
@@ -201,8 +192,9 @@ class NNCFQuantizer(DiffusersQuantizer):
|
||||
use_keep_in_fp32_modules = True
|
||||
requires_calibration = False
|
||||
required_packages = ["nncf"]
|
||||
torch_dtype = None
|
||||
|
||||
def __init__(self, quantization_config, **kwargs):
|
||||
def __init__(self, quantization_config, **kwargs): # pylint: disable=useless-parent-delegation
|
||||
super().__init__(quantization_config, **kwargs)
|
||||
|
||||
def check_if_quantized_param(
|
||||
@@ -213,7 +205,7 @@ class NNCFQuantizer(DiffusersQuantizer):
|
||||
state_dict: Dict[str, Any],
|
||||
**kwargs,
|
||||
):
|
||||
module, tensor_name = get_module_from_name(model, param_name)
|
||||
module, _ = get_module_from_name(model, param_name)
|
||||
return module.__class__.__name__.startswith("NNCF") and param_name.endswith(".weight")
|
||||
|
||||
def check_quantized_param(self, *args, **kwargs) -> bool:
|
||||
@@ -222,19 +214,19 @@ class NNCFQuantizer(DiffusersQuantizer):
|
||||
"""
|
||||
return self.check_if_quantized_param(*args, **kwargs)
|
||||
|
||||
def create_quantized_param(
|
||||
def create_quantized_param( # pylint: disable=arguments-differ
|
||||
self,
|
||||
model,
|
||||
param_value: "torch.Tensor",
|
||||
param_name: str,
|
||||
target_device: "torch.device",
|
||||
state_dict: Dict[str, Any],
|
||||
unexpected_keys: List[str],
|
||||
state_dict: Dict[str, Any], # pylint: disable=unused-argument
|
||||
unexpected_keys: List[str], # pylint: disable=unused-argument
|
||||
**kwargs,
|
||||
):
|
||||
# load the model params to target_device first
|
||||
layer, tensor_name = get_module_from_name(model, param_name)
|
||||
layer._parameters[tensor_name] = torch.nn.Parameter(param_value).to(device=target_device)
|
||||
layer._parameters[tensor_name] = torch.nn.Parameter(param_value).to(device=target_device) # pylint: disable=protected-access
|
||||
|
||||
split_param_name = param_name.split(".")
|
||||
if param_name not in self.modules_to_not_convert and not any(param in split_param_name for param in self.modules_to_not_convert):
|
||||
@@ -252,7 +244,7 @@ class NNCFQuantizer(DiffusersQuantizer):
|
||||
max_memory = {key: val * 0.70 for key, val in max_memory.items()}
|
||||
return max_memory
|
||||
|
||||
def adjust_target_dtype(self, target_dtype: "torch.dtype") -> "torch.dtype":
|
||||
def adjust_target_dtype(self, target_dtype: "torch.dtype") -> "torch.dtype": # pylint: disable=unused-argument,arguments-renamed
|
||||
return torch_dtype_dict[self.quantization_config.weights_dtype]
|
||||
|
||||
def update_torch_dtype(self, torch_dtype: "torch.dtype" = None) -> "torch.dtype":
|
||||
@@ -261,10 +253,10 @@ class NNCFQuantizer(DiffusersQuantizer):
|
||||
self.torch_dtype = torch_dtype
|
||||
return torch_dtype
|
||||
|
||||
def _process_model_before_weight_loading(
|
||||
def _process_model_before_weight_loading( # pylint: disable=arguments-differ
|
||||
self,
|
||||
model,
|
||||
device_map,
|
||||
device_map, # pylint: disable=unused-argument
|
||||
keep_in_fp32_modules: List[str] = [],
|
||||
**kwargs,
|
||||
):
|
||||
@@ -289,19 +281,19 @@ class NNCFQuantizer(DiffusersQuantizer):
|
||||
"""
|
||||
return config
|
||||
|
||||
def update_unexpected_keys(self, model, unexpected_keys: List[str], prefix: str) -> List[str]:
|
||||
def update_unexpected_keys(self, model, unexpected_keys: List[str], prefix: str) -> List[str]: # pylint: disable=unused-argument
|
||||
"""
|
||||
needed for transformers compatibilty, no-op function
|
||||
"""
|
||||
return unexpected_keys
|
||||
|
||||
def update_missing_keys_after_loading(self, model, missing_keys: List[str], prefix: str) -> List[str]:
|
||||
def update_missing_keys_after_loading(self, model, missing_keys: List[str], prefix: str) -> List[str]: # pylint: disable=unused-argument
|
||||
"""
|
||||
needed for transformers compatibilty, no-op function
|
||||
"""
|
||||
return missing_keys
|
||||
|
||||
def update_expected_keys(self, model, expected_keys: List[str], loaded_keys: List[str]) -> List[str]:
|
||||
def update_expected_keys(self, model, expected_keys: List[str], loaded_keys: List[str]) -> List[str]: # pylint: disable=unused-argument
|
||||
"""
|
||||
needed for transformers compatibilty, no-op function
|
||||
"""
|
||||
@@ -330,16 +322,18 @@ class NNCFConfig(QuantizationConfigMixin):
|
||||
modules left in their original precision (e.g. Whisper encoder, Llava encoder, Mixtral gate layers).
|
||||
"""
|
||||
|
||||
def __init__(
|
||||
def __init__( # pylint: disable=super-init-not-called
|
||||
self,
|
||||
weights_dtype: str = "int8_sym",
|
||||
group_size: int = 0,
|
||||
use_int8_matmul: bool = False,
|
||||
modules_to_not_convert: Optional[List[str]] = None,
|
||||
**kwargs,
|
||||
**kwargs, # pylint: disable=unused-argument
|
||||
):
|
||||
self.quant_method = QuantizationMethod.NNCF
|
||||
self.weights_dtype = weights_dtype_dict[weights_dtype.lower()]
|
||||
self.group_size = group_size
|
||||
self.use_int8_matmul = use_int8_matmul
|
||||
self.modules_to_not_convert = modules_to_not_convert
|
||||
|
||||
self.post_init()
|
||||
@@ -347,8 +341,6 @@ class NNCFConfig(QuantizationConfigMixin):
|
||||
self.num_bits = 8 if self.weights_dtype in {"int8", "uint8"} else 4
|
||||
self.is_asym_mode = self.weights_dtype in {"uint8", "uint4"}
|
||||
self.is_integer = True
|
||||
self.group_size = group_size
|
||||
self.use_int8_matmul = use_int8_matmul
|
||||
|
||||
def post_init(self):
|
||||
r"""
|
||||
@@ -380,16 +372,11 @@ class NNCF_T5DenseGatedActDense(torch.nn.Module): # forward can't find what self
|
||||
|
||||
|
||||
def get_int_scale_asymmetric(weight: torch.FloatTensor, reduction_axes: List[int], num_bits: int) -> Tuple[torch.FloatTensor, torch.FloatTensor]:
|
||||
level_low = 0
|
||||
level_high = 2**num_bits
|
||||
|
||||
min_values = torch.amin(weight, dim=reduction_axes, keepdims=True)
|
||||
zero_point = torch.amin(weight, dim=reduction_axes, keepdims=True)
|
||||
max_values = torch.amax(weight, dim=reduction_axes, keepdims=True)
|
||||
scale = ((max_values - min_values) / (level_high - 1))
|
||||
|
||||
scale = (max_values - zero_point) / (2**num_bits - 1)
|
||||
eps = torch.finfo(scale.dtype).eps # prevent divison by 0
|
||||
scale = torch.where(torch.abs(scale) < eps, eps, scale)
|
||||
zero_point = (level_low - (min_values / scale))
|
||||
return scale, zero_point
|
||||
|
||||
|
||||
@@ -397,7 +384,6 @@ def get_int_scale_symmetric(weight: torch.FloatTensor, reduction_axes: List[int]
|
||||
w_abs_min = torch.abs(torch.amin(weight, dim=reduction_axes, keepdims=True))
|
||||
w_max = torch.amax(weight, dim=reduction_axes, keepdims=True)
|
||||
scale = torch.where(w_abs_min >= w_max, w_abs_min, -w_max) / (2 ** (num_bits - 1))
|
||||
|
||||
eps = torch.finfo(scale.dtype).eps # prevent divison by 0
|
||||
scale = torch.where(torch.abs(scale) < eps, eps, scale)
|
||||
return scale
|
||||
@@ -407,26 +393,25 @@ def quantize_int(weight: torch.FloatTensor, scale: torch.FloatTensor, zero_point
|
||||
dtype = torch.uint8 if is_asym_mode else torch.int8
|
||||
level_low = 0 if is_asym_mode else -(2 ** (num_bits - 1))
|
||||
level_high = 2**num_bits - 1 if is_asym_mode else 2 ** (num_bits - 1) - 1
|
||||
|
||||
compressed_weight = weight / scale
|
||||
if zero_point is not None:
|
||||
compressed_weight += zero_point
|
||||
|
||||
compressed_weight = torch.round(compressed_weight).clamp_(level_low, level_high).to(dtype)
|
||||
compressed_weight = torch.sub(weight, zero_point).div_(scale)
|
||||
else:
|
||||
compressed_weight = torch.div(weight, scale)
|
||||
compressed_weight = compressed_weight.round_().clamp_(level_low, level_high).to(dtype)
|
||||
if flatten:
|
||||
compressed_weight = compressed_weight.flatten(0,-2)
|
||||
return compressed_weight
|
||||
|
||||
|
||||
def decompress_asymmetric(input: torch.Tensor, scale: torch.Tensor, zero_point: torch.Tensor, dtype: torch.dtype, result_shape: torch.Size) -> torch.Tensor:
|
||||
result = torch.mul(torch.sub(input.to(dtype=scale.dtype), zero_point), scale).to(dtype=dtype)
|
||||
result = torch.addcmul(zero_point, input.to(dtype=scale.dtype), scale).to(dtype=dtype)
|
||||
if result_shape is not None:
|
||||
result = result.reshape(result_shape)
|
||||
return result
|
||||
|
||||
|
||||
def decompress_symmetric(input: torch.Tensor, scale: torch.Tensor, dtype: torch.dtype, result_shape: torch.Size) -> torch.Tensor:
|
||||
result = torch.mul(input.to(dtype=scale.dtype), scale).to(dtype=dtype)
|
||||
result = input.to(dtype=scale.dtype).mul_(scale).to(dtype=dtype)
|
||||
if result_shape is not None:
|
||||
result = result.reshape(result_shape)
|
||||
return result
|
||||
@@ -463,7 +448,7 @@ def unpack_uint4(packed_tensor: torch.Tensor, shape: torch.Size, transpose: Opti
|
||||
|
||||
|
||||
def unpack_int4(packed_tensor: torch.Tensor, shape: torch.Size, dtype: Optional[torch.dtype] = torch.int8, transpose: Optional[bool] = False) -> torch.Tensor:
|
||||
result = unpack_uint4(packed_tensor, shape).to(dtype=dtype) - 8
|
||||
result = unpack_uint4(packed_tensor, shape).to(dtype=dtype).sub_(8)
|
||||
if transpose:
|
||||
result = result.transpose(0,1)
|
||||
return result
|
||||
@@ -472,9 +457,7 @@ def unpack_int4(packed_tensor: torch.Tensor, shape: torch.Size, dtype: Optional[
|
||||
def quantize_int8_matmul_input(input: torch.FloatTensor, scale: torch.FloatTensor) -> Tuple[torch.ByteTensor, torch.FloatTensor]:
|
||||
input_scale = torch.div(input.abs().max(), 127)
|
||||
input = torch.div(input, input_scale).round_().clamp_(-128, 127).to(torch.int8).flatten(0,-2)
|
||||
|
||||
scale_dtype = torch.float32 if input.dtype == torch.float16 else torch.bfloat16
|
||||
scale = torch.mul(input_scale.to(dtype=scale_dtype), scale.to(dtype=scale_dtype))
|
||||
scale = torch.mul(input_scale, scale)
|
||||
return input, scale
|
||||
|
||||
|
||||
@@ -483,31 +466,23 @@ def int8_matmul(
|
||||
weight: torch.Tensor,
|
||||
scale: torch.Tensor,
|
||||
compressed_weight_shape: torch.Size,
|
||||
num_bits: int,
|
||||
):
|
||||
if num_bits == 4:
|
||||
if compressed_weight_shape is not None:
|
||||
weight = unpack_int4_compiled(weight, compressed_weight_shape, transpose=True)
|
||||
|
||||
return_dtype = input.dtype
|
||||
output_shape = list(input.shape)
|
||||
output_shape[-1] = weight.shape[-1]
|
||||
|
||||
input, scale = quantize_int8_matmul_input_compiled(input, scale)
|
||||
return decompress_symmetric_compiled(torch._int_mm(input, weight), scale, return_dtype, output_shape)
|
||||
return decompress_symmetric_compiled(torch._int_mm(input, weight), scale, return_dtype, output_shape) # pylint: disable=protected-access
|
||||
|
||||
|
||||
class linear_forward_int8_matmul():
|
||||
def __func__(self, input) -> torch.FloatTensor:
|
||||
if self.pre_ops["0"].skip_int8_matmul:
|
||||
return torch.nn.Linear.forward(self, input)
|
||||
|
||||
num_bits = self.pre_ops["0"].num_bits
|
||||
scale = self.pre_ops["0"].scale
|
||||
compressed_weight_shape = self.pre_ops["0"].compressed_weight_shape if num_bits == 4 else None
|
||||
result = int8_matmul(input, self.weight, scale, compressed_weight_shape, num_bits)
|
||||
|
||||
result = int8_matmul(input, self.weight, self.pre_ops["0"].scale, getattr(self.pre_ops["0"], "compressed_weight_shape", None))
|
||||
if self.bias is not None:
|
||||
result = result + self.bias
|
||||
result.add_(self.bias)
|
||||
return result
|
||||
|
||||
|
||||
@@ -518,12 +493,10 @@ class INT8AsymmetricWeightsDecompressor(torch.nn.Module):
|
||||
zero_point: torch.Tensor,
|
||||
result_dtype: torch.dtype,
|
||||
result_shape: torch.Size,
|
||||
use_int8_matmul: bool,
|
||||
):
|
||||
super().__init__()
|
||||
self.num_bits = 8
|
||||
self.quantization_mode = "asymmetric"
|
||||
|
||||
self.scale = scale
|
||||
self.zero_point = zero_point
|
||||
self.result_dtype = result_dtype
|
||||
@@ -535,7 +508,7 @@ class INT8AsymmetricWeightsDecompressor(torch.nn.Module):
|
||||
raise ValueError("Weight values are not in [0, 255].")
|
||||
return weight.to(dtype=torch.uint8)
|
||||
|
||||
def forward(self, x, input=None, *args, return_decompressed_only=False):
|
||||
def forward(self, x, input=None, *args, return_decompressed_only=False): # pylint: disable=keyword-arg-before-vararg,unused-argument
|
||||
result = decompress_asymmetric_compiled(x.weight, self.scale, self.zero_point, self.result_dtype, self.result_shape)
|
||||
if return_decompressed_only:
|
||||
return result
|
||||
@@ -554,11 +527,9 @@ class INT8SymmetricWeightsDecompressor(torch.nn.Module):
|
||||
super().__init__()
|
||||
self.num_bits = 8
|
||||
self.quantization_mode = "symmetric"
|
||||
|
||||
self.scale = scale
|
||||
self.result_dtype = result_dtype
|
||||
self.result_shape = result_shape
|
||||
|
||||
self.use_int8_matmul = use_int8_matmul
|
||||
self.skip_int8_matmul = False
|
||||
self.input_scale = None
|
||||
@@ -569,7 +540,7 @@ class INT8SymmetricWeightsDecompressor(torch.nn.Module):
|
||||
raise ValueError("Weight values are not in [-128, 127].")
|
||||
return weight.to(dtype=torch.int8)
|
||||
|
||||
def forward(self, x, input=None, *args, return_decompressed_only=False):
|
||||
def forward(self, x, input=None, *args, return_decompressed_only=False): # pylint: disable=unused-argument,keyword-arg-before-vararg
|
||||
if self.use_int8_matmul:
|
||||
if input is not None:
|
||||
if torch.numel(input[0]) / input[0].shape[-1] < 32:
|
||||
@@ -594,12 +565,10 @@ class INT4AsymmetricWeightsDecompressor(torch.nn.Module):
|
||||
compressed_weight_shape: torch.Size,
|
||||
result_dtype: torch.dtype,
|
||||
result_shape: torch.Size,
|
||||
use_int8_matmul: bool,
|
||||
):
|
||||
super().__init__()
|
||||
self.num_bits = 4
|
||||
self.quantization_mode = "asymmetric"
|
||||
|
||||
self.scale = scale
|
||||
self.zero_point = zero_point
|
||||
self.compressed_weight_shape = compressed_weight_shape
|
||||
@@ -612,7 +581,7 @@ class INT4AsymmetricWeightsDecompressor(torch.nn.Module):
|
||||
raise ValueError("Weight values are not in [0, 15].")
|
||||
return pack_uint4(weight.to(dtype=torch.uint8))
|
||||
|
||||
def forward(self, x, input=None, *args, return_decompressed_only=False):
|
||||
def forward(self, x, input=None, *args, return_decompressed_only=False): # pylint: disable=unused-argument,keyword-arg-before-vararg
|
||||
result = decompress_int4_asymmetric_compiled(x.weight, self.scale, self.zero_point, self.compressed_weight_shape, self.result_dtype, self.result_shape)
|
||||
if return_decompressed_only:
|
||||
return result
|
||||
@@ -632,12 +601,10 @@ class INT4SymmetricWeightsDecompressor(torch.nn.Module):
|
||||
super().__init__()
|
||||
self.num_bits = 4
|
||||
self.quantization_mode = "symmetric"
|
||||
|
||||
self.scale = scale
|
||||
self.compressed_weight_shape = compressed_weight_shape
|
||||
self.result_dtype = result_dtype
|
||||
self.result_shape = result_shape
|
||||
|
||||
self.use_int8_matmul = use_int8_matmul
|
||||
self.skip_int8_matmul = False
|
||||
self.input_scale = None
|
||||
@@ -648,7 +615,7 @@ class INT4SymmetricWeightsDecompressor(torch.nn.Module):
|
||||
raise ValueError("Tensor values are not in [-8, 7].")
|
||||
return pack_int4(weight.to(dtype=torch.int8))
|
||||
|
||||
def forward(self, x, input=None, *arg, return_decompressed_only=False):
|
||||
def forward(self, x, input=None, *arg, return_decompressed_only=False): # pylint: disable=keyword-arg-before-vararg,unused-argument
|
||||
if self.use_int8_matmul:
|
||||
if input is not None:
|
||||
if torch.numel(input[0]) / input[0].shape[-1] < 32:
|
||||
@@ -672,16 +639,19 @@ if shared.opts.nncf_decompress_compile:
|
||||
decompress_symmetric_compiled = torch.compile(decompress_symmetric, fullgraph=True)
|
||||
decompress_int4_asymmetric_compiled = torch.compile(decompress_int4_asymmetric, fullgraph=True)
|
||||
decompress_int4_symmetric_compiled = torch.compile(decompress_int4_symmetric, fullgraph=True)
|
||||
|
||||
quantize_int8_matmul_input_compiled = torch.compile(quantize_int8_matmul_input, fullgraph=True)
|
||||
unpack_int4_compiled = torch.compile(unpack_int4, fullgraph=True)
|
||||
if devices.backend != "ipex": # pytorch uses the cpu device in torch._int_mm op with ipex + torch.compile
|
||||
quantize_int8_matmul_input_compiled = quantize_int8_matmul_input
|
||||
unpack_int4_compiled = unpack_int4
|
||||
int8_matmul = torch.compile(int8_matmul, fullgraph=True)
|
||||
else:
|
||||
quantize_int8_matmul_input_compiled = torch.compile(quantize_int8_matmul_input, fullgraph=True)
|
||||
unpack_int4_compiled = torch.compile(unpack_int4, fullgraph=True)
|
||||
except Exception as e:
|
||||
shared.log.warning(f"Quantization: type=nncf Decompress using torch.compile is not available: {e}")
|
||||
decompress_asymmetric_compiled = decompress_asymmetric
|
||||
decompress_symmetric_compiled = decompress_symmetric
|
||||
decompress_int4_asymmetric_compiled = decompress_int4_asymmetric
|
||||
decompress_int4_symmetric_compiled = decompress_int4_symmetric
|
||||
|
||||
quantize_int8_matmul_input_compiled = quantize_int8_matmul_input
|
||||
unpack_int4_compiled = unpack_int4
|
||||
else:
|
||||
@@ -689,6 +659,5 @@ else:
|
||||
decompress_symmetric_compiled = decompress_symmetric
|
||||
decompress_int4_asymmetric_compiled = decompress_int4_asymmetric
|
||||
decompress_int4_symmetric_compiled = decompress_int4_symmetric
|
||||
|
||||
quantize_int8_matmul_input_compiled = quantize_int8_matmul_input
|
||||
unpack_int4_compiled = unpack_int4
|
||||
|
||||
@@ -68,7 +68,7 @@ def create_ui():
|
||||
with gr.Row():
|
||||
cache_list_optimized_headers = ["height", "width"]
|
||||
cache_list_optimized_types = ["str", "str"]
|
||||
cache_list_optimized = gr.Dataframe(None, label="Optimized caches", show_label=True, overflow_row_behaviour='paginate', interactive=False, max_rows=10, headers=cache_list_optimized_headers, datatype=cache_list_optimized_types, type="array")
|
||||
cache_list_optimized = gr.Dataframe(None, label="Optimized caches", show_label=True, interactive=False, headers=cache_list_optimized_headers, datatype=cache_list_optimized_types, type="array")
|
||||
cache_list_optimized.select(fn=select_cache_optimized, inputs=[cache_list_optimized,], outputs=[cache_optimized_selected,])
|
||||
cache_remove_optimized = gr.Button(value="Remove selected cache", visible=False)
|
||||
cache_remove_optimized.click(fn=remove_cache_optimized, inputs=[cache_state_dirname, cache_optimized_selected,])
|
||||
|
||||
@@ -367,10 +367,10 @@ class YoloRestorer(Detailer):
|
||||
with gr.Row():
|
||||
negative = gr.Textbox(label="Detailer negative prompt", value='', placeholder='Detailer negative prompt', lines=2, elem_id=f"{tab}_detailer_negative")
|
||||
with gr.Row():
|
||||
steps = gr.Slider(label="Detailer steps", elem_id=f"{tab}_detailer_steps", value=10, min=0, max=99, step=1)
|
||||
steps = gr.Slider(label="Detailer steps", elem_id=f"{tab}_detailer_steps", value=10, minimum=0, maximum=99, step=1)
|
||||
strength = gr.Slider(label="Detailer strength", elem_id=f"{tab}_detailer_strength", value=0.3, minimum=0, maximum=1, step=0.01)
|
||||
with gr.Row():
|
||||
max_detected = gr.Slider(label="Max detected", elem_id=f"{tab}_detailer_max", value=shared.opts.detailer_max, min=1, maximum=10, step=1)
|
||||
max_detected = gr.Slider(label="Max detected", elem_id=f"{tab}_detailer_max", value=shared.opts.detailer_max, minimum=1, maximum=10, step=1)
|
||||
with gr.Row():
|
||||
padding = gr.Slider(label="Edge padding", elem_id=f"{tab}_detailer_padding", value=shared.opts.detailer_padding, minimum=0, maximum=100, step=1)
|
||||
blur = gr.Slider(label="Edge blur", elem_id=f"{tab}_detailer_blur", value=shared.opts.detailer_blur, minimum=0, maximum=100, step=1)
|
||||
|
||||
+8
-3
@@ -412,9 +412,14 @@ class ScriptRunner:
|
||||
api_args = []
|
||||
for control in controls:
|
||||
debug(f'Script control: parent={script.parent} script="{script.name}" label="{control.label}" type={control} id={control.elem_id}')
|
||||
if not isinstance(control, gr.components.IOComponent):
|
||||
errors.log.error(f'Invalid script control: "{script.filename}" control={control}')
|
||||
continue
|
||||
if hasattr(gr.components, 'IOComponent'):
|
||||
if not isinstance(control, gr.components.IOComponent):
|
||||
errors.log.error(f'Invalid script control: "{script.filename}" control={control}')
|
||||
continue
|
||||
else:
|
||||
if not isinstance(control, gr.components.Component):
|
||||
errors.log.error(f'Invalid script control: "{script.filename}" control={control}')
|
||||
continue
|
||||
control.custom_script_source = os.path.basename(script.filename)
|
||||
arg_info = api_models.ScriptArg(label=control.label or "")
|
||||
for field in ("value", "minimum", "maximum", "step", "choices"):
|
||||
|
||||
+15
-15
@@ -423,7 +423,7 @@ options_templates.update(options_section(('model_options', "Models Options"), {
|
||||
"model_h1_llama_repo": OptionInfo("Default", "HiDream: LLama repo", gr.Textbox),
|
||||
}))
|
||||
|
||||
options_templates.update(options_section(('vae_encoder', "Variable Auto Encoder"), {
|
||||
options_templates.update(options_section(('vae_encoder', "Variational Auto Encoder"), {
|
||||
"sd_vae": OptionInfo("Automatic", "VAE model", gr.Dropdown, lambda: {"choices": shared_items.sd_vae_items()}, refresh=shared_items.refresh_vae_list),
|
||||
"diffusers_vae_upcast": OptionInfo("default", "VAE upcasting", gr.Radio, {"choices": ['default', 'true', 'false']}),
|
||||
"no_half_vae": OptionInfo(False if not cmd_opts.use_openvino else True, "Full precision (--no-half-vae)"),
|
||||
@@ -525,6 +525,20 @@ options_templates.update(options_section(('quantization', "Quantization Settings
|
||||
"bnb_quantization_type": OptionInfo("nf4", "Quantization type", gr.Dropdown, {"choices": ['nf4', 'fp8', 'fp4'], "visible": native}),
|
||||
"bnb_quantization_storage": OptionInfo("uint8", "Backend storage", gr.Dropdown, {"choices": ["float16", "float32", "int8", "uint8", "float64", "bfloat16"], "visible": native}),
|
||||
|
||||
"nncf_compress_sep": OptionInfo("<h2>NNCF: Neural Network Compression Framework</h2>", "", gr.HTML),
|
||||
"nncf_compress_weights": OptionInfo([], "Quantization enabled", gr.CheckboxGroup, {"choices": ["Model", "Transformer", "VAE", "TE", "Video", "LLM", "ControlNet"], "visible": native}),
|
||||
"nncf_compress_mode": OptionInfo("post", "Quantization mode", gr.Dropdown, {"choices": ['pre', 'post'], "visible": native and not cmd_opts.use_openvino}),
|
||||
"nncf_compress_weights_mode": OptionInfo("INT8_SYM", "Quantization type", gr.Dropdown, {"choices": ['INT8', 'INT8_SYM', 'INT4_ASYM', 'INT4_SYM', 'NF4'] if cmd_opts.use_openvino else ['INT8', 'INT8_SYM', 'INT4', 'INT4_SYM']}),
|
||||
"nncf_compress_weights_raito": OptionInfo(0, "Compress ratio", gr.Slider, {"minimum": 0, "maximum": 1, "step": 0.01, "visible": cmd_opts.use_openvino}),
|
||||
"nncf_compress_weights_group_size": OptionInfo(0, "Group size", gr.Slider, {"minimum": -1, "maximum": 4096, "step": 1, "visible": native}),
|
||||
"nncf_quantize": OptionInfo([], "OpenVINO enabled", gr.CheckboxGroup, {"choices": ["Model", "VAE", "TE"], "visible": cmd_opts.use_openvino}),
|
||||
"nncf_quantize_mode": OptionInfo("INT8", "OpenVINO activations mode", gr.Dropdown, {"choices": ['INT8', 'FP8_E4M3', 'FP8_E5M2'], "visible": cmd_opts.use_openvino}),
|
||||
"nncf_quantize_conv_layers": OptionInfo(False, "Quantize the convolutional layers", gr.Checkbox, {"visible": native and not cmd_opts.use_openvino}),
|
||||
"nncf_decompress_fp32": OptionInfo(False, "Decompress using full precision", gr.Checkbox, {"visible": native and not cmd_opts.use_openvino}),
|
||||
"nncf_decompress_compile": OptionInfo(devices.has_triton(), "Decompress using torch.compile", gr.Checkbox, {"visible": native and not cmd_opts.use_openvino}),
|
||||
"nncf_decompress_int8_matmul": OptionInfo(False, "Use direct INT8 MatMul", gr.Checkbox, {"visible": native and not cmd_opts.use_openvino}),
|
||||
"nncf_quantize_shuffle_weights": OptionInfo(False, "Shuffle weights in post mode", gr.Checkbox, {"visible": native and not cmd_opts.use_openvino}),
|
||||
|
||||
"quanto_quantization_sep": OptionInfo("<h2>Optimum Quanto</h2>", "", gr.HTML),
|
||||
"quanto_quantization": OptionInfo([], "Quantization enabled", gr.CheckboxGroup, {"choices": ["Model", "Transformer", "VAE", "TE", "Video", "LLM", "ControlNet"], "visible": native}),
|
||||
"quanto_quantization_type": OptionInfo("int8", "Quantization weights type", gr.Dropdown, {"choices": ["float8", "int8", "int4", "int2"], "visible": native}),
|
||||
@@ -540,20 +554,6 @@ options_templates.update(options_section(('quantization', "Quantization Settings
|
||||
"torchao_quantization_mode": OptionInfo("pre", "Quantization mode", gr.Dropdown, {"choices": ['pre', 'post'], "visible": native}),
|
||||
"torchao_quantization_type": OptionInfo("int8_weight_only", "Quantization type", gr.Dropdown, {"choices": ['int4_weight_only', 'int8_dynamic_activation_int4_weight', 'int8_weight_only', 'int8_dynamic_activation_int8_weight', 'float8_weight_only', 'float8_dynamic_activation_float8_weight', 'float8_static_activation_float8_weight'], "visible": native}),
|
||||
|
||||
"nncf_compress_sep": OptionInfo("<h2>NNCF: Neural Network Compression Framework</h2>", "", gr.HTML),
|
||||
"nncf_compress_weights": OptionInfo([], "Quantization enabled", gr.CheckboxGroup, {"choices": ["Model", "Transformer", "VAE", "TE", "Video", "LLM", "ControlNet"], "visible": native}),
|
||||
"nncf_compress_mode": OptionInfo("post", "Quantization mode", gr.Dropdown, {"choices": ['pre', 'post'], "visible": native and not cmd_opts.use_openvino}),
|
||||
"nncf_compress_weights_mode": OptionInfo("INT8_SYM", "Quantization type", gr.Dropdown, {"choices": ['INT8', 'INT8_SYM', 'INT4_ASYM', 'INT4_SYM', 'NF4'] if cmd_opts.use_openvino else ['INT8', 'INT8_SYM', 'INT4', 'INT4_SYM']}),
|
||||
"nncf_compress_weights_raito": OptionInfo(0, "Compress ratio", gr.Slider, {"minimum": 0, "maximum": 1, "step": 0.01, "visible": cmd_opts.use_openvino}),
|
||||
"nncf_compress_weights_group_size": OptionInfo(0, "Group size", gr.Slider, {"minimum": -1, "maximum": 4096, "step": 1, "visible": native}),
|
||||
"nncf_quantize": OptionInfo([], "OpenVINO enabled", gr.CheckboxGroup, {"choices": ["Model", "VAE", "TE"], "visible": cmd_opts.use_openvino}),
|
||||
"nncf_quantize_mode": OptionInfo("INT8", "OpenVINO activations mode", gr.Dropdown, {"choices": ['INT8', 'FP8_E4M3', 'FP8_E5M2'], "visible": cmd_opts.use_openvino}),
|
||||
"nncf_quantize_conv_layers": OptionInfo(False, "Quantize the convolutional layers", gr.Checkbox, {"visible": native and not cmd_opts.use_openvino}),
|
||||
"nncf_decompress_fp32": OptionInfo(False, "Decompress using full precision", gr.Checkbox, {"visible": native and not cmd_opts.use_openvino}),
|
||||
"nncf_decompress_compile": OptionInfo(devices.has_triton(), "Decompress using torch.compile", gr.Checkbox, {"visible": native and not cmd_opts.use_openvino}),
|
||||
"nncf_decompress_int8_matmul": OptionInfo(False, "Use direct INT8 MatMul", gr.Checkbox, {"visible": native and not cmd_opts.use_openvino}),
|
||||
"nncf_quantize_shuffle_weights": OptionInfo(False, "Shuffle weights in post mode", gr.Checkbox, {"visible": native and not cmd_opts.use_openvino}),
|
||||
|
||||
"layerwise_quantization_sep": OptionInfo("<h2>Layerwise Casting</h2>", "", gr.HTML),
|
||||
"layerwise_quantization": OptionInfo([], "Layerwise casting enabled", gr.CheckboxGroup, {"choices": ["Model", "Transformer", "TE"], "visible": native}),
|
||||
"layerwise_quantization_storage": OptionInfo("float8_e4m3fn", "Layerwise casting storage", gr.Dropdown, {"choices": ["float8_e4m3fn", "float8_e5m2"], "visible": native}),
|
||||
|
||||
@@ -61,11 +61,11 @@ def create_ui():
|
||||
vlm_top_p.change(fn=update_vlm_params, inputs=[vlm_max_tokens, vlm_num_beams, vlm_temperature, vlm_do_sample, vlm_top_k, vlm_top_p], outputs=[])
|
||||
with gr.Accordion(label='Batch caption', open=False, visible=True):
|
||||
with gr.Row():
|
||||
vlm_batch_files = gr.File(label="Files", show_label=True, file_count='multiple', file_types=['image'], type='file', interactive=True, height=100, elem_id='vlm_batch_files')
|
||||
vlm_batch_files = gr.File(label="Files", show_label=True, file_count='multiple', file_types=['image'], interactive=True, height=100, elem_id='vlm_batch_files')
|
||||
with gr.Row():
|
||||
vlm_batch_folder = gr.File(label="Folder", show_label=True, file_count='directory', file_types=['image'], type='file', interactive=True, height=100, elem_id='vlm_batch_folder')
|
||||
vlm_batch_folder = gr.File(label="Folder", show_label=True, file_count='directory', file_types=['image'], interactive=True, height=100, elem_id='vlm_batch_folder')
|
||||
with gr.Row():
|
||||
vlm_batch_str = gr.Text(label="Folder", value="", interactive=True, elem_id='vlm_batch_str')
|
||||
vlm_batch_str = gr.Textbox(label="Folder", value="", interactive=True, elem_id='vlm_batch_str')
|
||||
with gr.Row():
|
||||
vlm_save_output = gr.Checkbox(label='Save caption files', value=True, elem_id="vlm_save_output")
|
||||
vlm_save_append = gr.Checkbox(label='Append caption files', value=False, elem_id="vlm_save_append")
|
||||
@@ -100,11 +100,11 @@ def create_ui():
|
||||
clip_num_beams.change(fn=update_clip_params, inputs=[clip_min_length, clip_max_length, clip_chunk_size, clip_min_flavors, clip_max_flavors, clip_flavor_count, clip_num_beams], outputs=[])
|
||||
with gr.Accordion(label='Batch interogate', open=False, visible=True):
|
||||
with gr.Row():
|
||||
clip_batch_files = gr.File(label="Files", show_label=True, file_count='multiple', file_types=['image'], type='file', interactive=True, height=100, elem_id='clip_batch_files')
|
||||
clip_batch_files = gr.File(label="Files", show_label=True, file_count='multiple', file_types=['image'], interactive=True, height=100, elem_id='clip_batch_files')
|
||||
with gr.Row():
|
||||
clip_batch_folder = gr.File(label="Folder", show_label=True, file_count='directory', file_types=['image'], type='file', interactive=True, height=100, elem_id='clip_batch_folder')
|
||||
clip_batch_folder = gr.File(label="Folder", show_label=True, file_count='directory', file_types=['image'], interactive=True, height=100, elem_id='clip_batch_folder')
|
||||
with gr.Row():
|
||||
clip_batch_str = gr.Text(label="Folder", value="", interactive=True, elem_id='clip_batch_str')
|
||||
clip_batch_str = gr.Textbox(label="Folder", value="", interactive=True, elem_id='clip_batch_str')
|
||||
with gr.Row():
|
||||
clip_save_output = gr.Checkbox(label='Save caption files', value=True, elem_id="clip_save_output")
|
||||
clip_save_append = gr.Checkbox(label='Append caption files', value=False, elem_id="clip_save_append")
|
||||
|
||||
+15
-15
@@ -129,7 +129,7 @@ def create_ui(_blocks: gr.Blocks=None):
|
||||
txt_prompt_img = gr.File(label="", elem_id="control_prompt_image", file_count="single", type="binary", visible=False)
|
||||
txt_prompt_img.change(fn=images.image_data, inputs=[txt_prompt_img], outputs=[prompt, txt_prompt_img])
|
||||
|
||||
with gr.Group(elem_id="control_interface", equal_height=False):
|
||||
with gr.Group(elem_id="control_interface"):
|
||||
|
||||
with gr.Row(elem_id='control_status'):
|
||||
result_txt = gr.HTML(elem_classes=['control-result'], elem_id='control-result')
|
||||
@@ -193,29 +193,29 @@ def create_ui(_blocks: gr.Blocks=None):
|
||||
with gr.Tabs(elem_classes=['control-tabs'], elem_id='control-tab-input'):
|
||||
with gr.Tab('Image', id='in-image') as tab_image:
|
||||
input_mode = gr.Label(value='select', visible=False)
|
||||
input_image = gr.Image(label="Input", show_label=False, type="pil", source="upload", interactive=True, tool="editor", height=gr_height, visible=True, image_mode='RGB', elem_id='control_input_select', elem_classes=['control-image'])
|
||||
input_resize = gr.Image(label="Input", show_label=False, type="pil", source="upload", interactive=True, tool="select", height=gr_height, visible=False, image_mode='RGB', elem_id='control_input_resize', elem_classes=['control-image'])
|
||||
input_inpaint = gr.Image(label="Input", show_label=False, type="pil", source="upload", interactive=True, tool="sketch", height=gr_height, visible=False, image_mode='RGB', elem_id='control_input_inpaint', brush_radius=32, mask_opacity=0.6, elem_classes=['control-image'])
|
||||
input_image = gr.Image(label="Input", show_label=False, type="pil", interactive=True, tool="editor", height=gr_height, visible=True, image_mode='RGB', elem_id='control_input_select', elem_classes=['control-image'])
|
||||
input_resize = gr.Image(label="Input", show_label=False, type="pil", interactive=True, tool="select", height=gr_height, visible=False, image_mode='RGB', elem_id='control_input_resize', elem_classes=['control-image'])
|
||||
input_inpaint = gr.Image(label="Input", show_label=False, type="pil", interactive=True, tool="sketch", height=gr_height, visible=False, image_mode='RGB', elem_id='control_input_inpaint', brush_radius=32, mask_opacity=0.6, elem_classes=['control-image'])
|
||||
btn_interrogate = ui_sections.create_interrogate_button('control')
|
||||
with gr.Row():
|
||||
input_buttons = [gr.Button('Select', visible=True, interactive=False), gr.Button('Inpaint', visible=True, interactive=True), gr.Button('Outpaint', visible=True, interactive=True)]
|
||||
with gr.Tab('Video', id='in-video') as tab_video:
|
||||
input_video = gr.Video(label="Input", show_label=False, interactive=True, height=gr_height, elem_classes=['control-image'])
|
||||
with gr.Tab('Batch', id='in-batch') as tab_batch:
|
||||
input_batch = gr.File(label="Input", show_label=False, file_count='multiple', file_types=['image'], type='file', interactive=True, height=gr_height)
|
||||
input_batch = gr.File(label="Input", show_label=False, file_count='multiple', file_types=['image'], interactive=True, height=gr_height)
|
||||
with gr.Tab('Folder', id='in-folder') as tab_folder:
|
||||
input_folder = gr.File(label="Input", show_label=False, file_count='directory', file_types=['image'], type='file', interactive=True, height=gr_height)
|
||||
input_folder = gr.File(label="Input", show_label=False, file_count='directory', file_types=['image'], interactive=True, height=gr_height)
|
||||
with gr.Column(scale=9, elem_id='control-init-column', visible=False) as column_init:
|
||||
gr.HTML('<span id="control-init-button">Init input</p>')
|
||||
with gr.Tabs(elem_classes=['control-tabs'], elem_id='control-tab-init'):
|
||||
with gr.Tab('Image', id='init-image') as tab_image_init:
|
||||
init_image = gr.Image(label="Input", show_label=False, type="pil", source="upload", interactive=True, tool="editor", height=gr_height, elem_classes=['control-image'])
|
||||
init_image = gr.Image(label="Input", show_label=False, type="pil", interactive=True, tool="editor", height=gr_height, elem_classes=['control-image'])
|
||||
with gr.Tab('Video', id='init-video') as tab_video_init:
|
||||
init_video = gr.Video(label="Input", show_label=False, interactive=True, height=gr_height, elem_classes=['control-image'])
|
||||
with gr.Tab('Batch', id='init-batch') as tab_batch_init:
|
||||
init_batch = gr.File(label="Input", show_label=False, file_count='multiple', file_types=['image'], type='file', interactive=True, height=gr_height, elem_classes=['control-image'])
|
||||
init_batch = gr.File(label="Input", show_label=False, file_count='multiple', file_types=['image'], interactive=True, height=gr_height, elem_classes=['control-image'])
|
||||
with gr.Tab('Folder', id='init-folder') as tab_folder_init:
|
||||
init_folder = gr.File(label="Input", show_label=False, file_count='directory', file_types=['image'], type='file', interactive=True, height=gr_height, elem_classes=['control-image'])
|
||||
init_folder = gr.File(label="Input", show_label=False, file_count='directory', file_types=['image'], interactive=True, height=gr_height, elem_classes=['control-image'])
|
||||
with gr.Column(scale=9, elem_id='control-output-column', visible=True) as _column_output:
|
||||
gr.HTML('<span id="control-output-button">Output</p>')
|
||||
with gr.Tabs(elem_classes=['control-tabs'], elem_id='control-tab-output') as output_tabs:
|
||||
@@ -229,7 +229,7 @@ def create_ui(_blocks: gr.Blocks=None):
|
||||
gr.HTML('<span id="control-preview-button">Preview</p>')
|
||||
with gr.Tabs(elem_classes=['control-tabs'], elem_id='control-tab-preview'):
|
||||
with gr.Tab('Preview', id='preview-image') as _tab_preview:
|
||||
preview_process = gr.Image(label="Preview", show_label=False, type="pil", source="upload", interactive=False, height=gr_height, visible=True, elem_id='control_preview', elem_classes=['control-image'])
|
||||
preview_process = gr.Image(label="Preview", show_label=False, type="pil", interactive=False, height=gr_height, visible=True, elem_id='control_preview', elem_classes=['control-image'])
|
||||
|
||||
with gr.Accordion('Control elements', open=False, elem_id="control_elements"):
|
||||
with gr.Tabs(elem_id='control-tabs') as _tabs_control_type:
|
||||
@@ -259,7 +259,7 @@ def create_ui(_blocks: gr.Blocks=None):
|
||||
image_upload = gr.UploadButton(label=ui_symbols.upload, file_types=['image'], elem_classes=['form', 'gradio-button', 'tool'])
|
||||
image_reuse= ui_components.ToolButton(value=ui_symbols.reuse)
|
||||
process_btn= ui_components.ToolButton(value=ui_symbols.preview)
|
||||
image_preview = gr.Image(label="Input", type="pil", source="upload", height=128, width=128, visible=False, interactive=True, show_label=False, show_download_button=False, container=False, elem_id=f'control_unit-{i}-override')
|
||||
image_preview = gr.Image(label="Input", type="pil", height=128, width=128, visible=False, interactive=True, show_label=False, show_download_button=False, container=False, elem_id=f'control_unit-{i}-override')
|
||||
controlnet_ui_units.append(unit_ui)
|
||||
units.append(unit.Unit(
|
||||
unit_type = 'controlnet',
|
||||
@@ -308,7 +308,7 @@ def create_ui(_blocks: gr.Blocks=None):
|
||||
image_upload = gr.UploadButton(label=ui_symbols.upload, file_types=['image'], elem_classes=['form', 'gradio-button', 'tool'])
|
||||
image_reuse= ui_components.ToolButton(value=ui_symbols.reuse)
|
||||
process_btn= ui_components.ToolButton(value=ui_symbols.preview)
|
||||
image_preview = gr.Image(label="Input", show_label=False, type="pil", source="upload", interactive=False, height=128, width=128, visible=False, elem_id=f'control_unit-{i}-override')
|
||||
image_preview = gr.Image(label="Input", show_label=False, type="pil", interactive=False, height=128, width=128, visible=False, elem_id=f'control_unit-{i}-override')
|
||||
adapter_ui_units.append(unit_ui)
|
||||
units.append(unit.Unit(
|
||||
unit_type = 't2i adapter',
|
||||
@@ -355,7 +355,7 @@ def create_ui(_blocks: gr.Blocks=None):
|
||||
image_upload = gr.UploadButton(label=ui_symbols.upload, file_types=['image'], elem_classes=['form', 'gradio-button', 'tool'])
|
||||
image_reuse= ui_components.ToolButton(value=ui_symbols.reuse)
|
||||
process_btn= ui_components.ToolButton(value=ui_symbols.preview)
|
||||
image_preview = gr.Image(label="Input", show_label=False, type="pil", source="upload", interactive=False, height=128, width=128, visible=False, elem_id=f'control_unit-{i}-override')
|
||||
image_preview = gr.Image(label="Input", show_label=False, type="pil", interactive=False, height=128, width=128, visible=False, elem_id=f'control_unit-{i}-override')
|
||||
controlnetxs_ui_units.append(unit_ui)
|
||||
units.append(unit.Unit(
|
||||
unit_type = 'xs',
|
||||
@@ -400,7 +400,7 @@ def create_ui(_blocks: gr.Blocks=None):
|
||||
reset_btn = ui_components.ToolButton(value=ui_symbols.reset)
|
||||
image_upload = gr.UploadButton(label=ui_symbols.upload, file_types=['image'], elem_classes=['form', 'gradio-button', 'tool'])
|
||||
image_reuse= ui_components.ToolButton(value=ui_symbols.reuse)
|
||||
image_preview = gr.Image(label="Input", show_label=False, type="pil", source="upload", interactive=False, height=128, width=128, visible=False, elem_id=f'control_unit-{i}-override')
|
||||
image_preview = gr.Image(label="Input", show_label=False, type="pil", interactive=False, height=128, width=128, visible=False, elem_id=f'control_unit-{i}-override')
|
||||
process_btn= ui_components.ToolButton(value=ui_symbols.preview)
|
||||
lite_ui_units.append(unit_ui)
|
||||
units.append(unit.Unit(
|
||||
@@ -444,7 +444,7 @@ def create_ui(_blocks: gr.Blocks=None):
|
||||
reset_btn = ui_components.ToolButton(value=ui_symbols.reset)
|
||||
image_upload = gr.UploadButton(label=ui_symbols.upload, file_types=['image'], elem_classes=['form', 'gradio-button', 'tool'])
|
||||
image_reuse= ui_components.ToolButton(value=ui_symbols.reuse)
|
||||
image_preview = gr.Image(label="Input", show_label=False, type="pil", source="upload", interactive=False, height=128, width=128, visible=False, elem_id=f'control_unit-{i}-override')
|
||||
image_preview = gr.Image(label="Input", show_label=False, type="pil", interactive=False, height=128, width=128, visible=False, elem_id=f'control_unit-{i}-override')
|
||||
process_btn= ui_components.ToolButton(value=ui_symbols.preview)
|
||||
units.append(unit.Unit(
|
||||
unit_type = 'reference',
|
||||
|
||||
+1
-1
@@ -59,7 +59,7 @@ def create_ui_wiki():
|
||||
gr.HTML('<a href="https://github.com/vladmandic/sdnext/wiki" style="color: #AAA" target="_blank">  Open GitHub Wiki</a>')
|
||||
with gr.Row():
|
||||
wiki_search = gr.Textbox(label="Search Wiki Pages", elem_id="wiki_search")
|
||||
wiki_search_btn = ui_components.ToolButton(value=ui_symbols.search, label="Search", elem_id="wiki_search_btn")
|
||||
wiki_search_btn = ui_components.ToolButton(value=ui_symbols.search, elem_id="wiki_search_btn")
|
||||
with gr.Row():
|
||||
wiki_result = gr.HTML(elem_id="wiki_result", value='')
|
||||
wiki_search.submit(_js="wikiSearch", fn=search_github, inputs=[wiki_search], outputs=[wiki_result])
|
||||
|
||||
@@ -438,17 +438,17 @@ def create_html(search_text, sort_column):
|
||||
|
||||
def create_ui():
|
||||
extensions_disable_all = gr.Radio(label="Disable all extensions", choices=["none", "user", "all"], value=shared.opts.disable_all_extensions, elem_id="extensions_disable_all", visible=False)
|
||||
extensions_disabled_list = gr.Text(elem_id="extensions_disabled_list", visible=False, container=False)
|
||||
extensions_update_list = gr.Text(elem_id="extensions_update_list", visible=False, container=False)
|
||||
extensions_disabled_list = gr.Textbox(elem_id="extensions_disabled_list", visible=False, container=False)
|
||||
extensions_update_list = gr.Textbox(elem_id="extensions_update_list", visible=False, container=False)
|
||||
with gr.Tabs(elem_id="tabs_extensions"):
|
||||
with gr.TabItem("Manage extensions", id="manage"):
|
||||
with gr.Row(elem_id="extensions_installed_top"):
|
||||
extension_to_install = gr.Text(elem_id="extension_to_install", visible=False)
|
||||
extension_to_install = gr.Textbox(elem_id="extension_to_install", visible=False)
|
||||
install_extension_button = gr.Button(elem_id="install_extension_button", visible=False)
|
||||
uninstall_extension_button = gr.Button(elem_id="uninstall_extension_button", visible=False)
|
||||
update_extension_button = gr.Button(elem_id="update_extension_button", visible=False)
|
||||
with gr.Column(scale=4):
|
||||
search_text = gr.Text(label="Search")
|
||||
search_text = gr.Textbox(label="Search")
|
||||
with gr.Column(scale=1):
|
||||
sort_column = gr.Dropdown(value="default", label="Sort by", choices=list(sort_ordering.keys()), multiselect=False)
|
||||
with gr.Column(scale=1):
|
||||
@@ -508,9 +508,9 @@ def create_ui():
|
||||
outputs=[extensions_table, info],
|
||||
)
|
||||
with gr.TabItem("Manual install", id="install_from_url"):
|
||||
install_url = gr.Text(label="Extension GIT repository URL")
|
||||
install_branch = gr.Text(label="Specific branch name", placeholder="Leave empty for default main branch")
|
||||
install_dirname = gr.Text(label="Local directory name", placeholder="Leave empty for auto")
|
||||
install_url = gr.Textbox(label="Extension GIT repository URL")
|
||||
install_branch = gr.Textbox(label="Specific branch name", placeholder="Leave empty for default main branch")
|
||||
install_dirname = gr.Textbox(label="Local directory name", placeholder="Leave empty for auto")
|
||||
install_button = gr.Button(value="Install", variant="primary")
|
||||
info = gr.HTML(elem_id="extension_info")
|
||||
install_button.click(
|
||||
|
||||
@@ -603,7 +603,7 @@ def create_ui(container, button_parent, tabname, skip_indexing = False):
|
||||
text = gr.HTML('<div>title</div>')
|
||||
ui.details_components.append(text)
|
||||
with gr.Column(scale=1):
|
||||
img = gr.Image(value=None, show_label=False, interactive=False, container=False, show_download_button=False, show_info=False, elem_id=f"{tabname}_extra_details_img", elem_classes=['extra-details-img'])
|
||||
img = gr.Image(value=None, show_label=False, interactive=False, container=False, show_download_button=False, elem_id=f"{tabname}_extra_details_img", elem_classes=['extra-details-img'])
|
||||
ui.details_components.append(img)
|
||||
with gr.Row():
|
||||
btn_save_img = gr.Button('Replace', elem_classes=['small-button'])
|
||||
|
||||
@@ -43,14 +43,14 @@ def create_ui():
|
||||
with gr.Blocks() as tab:
|
||||
with gr.Row(elem_id='tab-gallery-sort-buttons'):
|
||||
sort_buttons = []
|
||||
sort_buttons.append(ToolButton(value=ui_symbols.sort_alpha_asc, show_label=False, elem_classes=['gallery-sort']))
|
||||
sort_buttons.append(ToolButton(value=ui_symbols.sort_alpha_dsc, show_label=False, elem_classes=['gallery-sort']))
|
||||
sort_buttons.append(ToolButton(value=ui_symbols.sort_size_asc, show_label=False, elem_classes=['gallery-sort']))
|
||||
sort_buttons.append(ToolButton(value=ui_symbols.sort_size_dsc, show_label=False, elem_classes=['gallery-sort']))
|
||||
sort_buttons.append(ToolButton(value=ui_symbols.sort_num_asc, show_label=False, elem_classes=['gallery-sort']))
|
||||
sort_buttons.append(ToolButton(value=ui_symbols.sort_num_dsc, show_label=False, elem_classes=['gallery-sort']))
|
||||
sort_buttons.append(ToolButton(value=ui_symbols.sort_time_asc, show_label=False, elem_classes=['gallery-sort']))
|
||||
sort_buttons.append(ToolButton(value=ui_symbols.sort_time_dsc, show_label=False, elem_classes=['gallery-sort']))
|
||||
sort_buttons.append(ToolButton(value=ui_symbols.sort_alpha_asc, elem_classes=['gallery-sort']))
|
||||
sort_buttons.append(ToolButton(value=ui_symbols.sort_alpha_dsc, elem_classes=['gallery-sort']))
|
||||
sort_buttons.append(ToolButton(value=ui_symbols.sort_size_asc, elem_classes=['gallery-sort']))
|
||||
sort_buttons.append(ToolButton(value=ui_symbols.sort_size_dsc, elem_classes=['gallery-sort']))
|
||||
sort_buttons.append(ToolButton(value=ui_symbols.sort_num_asc, elem_classes=['gallery-sort']))
|
||||
sort_buttons.append(ToolButton(value=ui_symbols.sort_num_dsc, elem_classes=['gallery-sort']))
|
||||
sort_buttons.append(ToolButton(value=ui_symbols.sort_time_asc, elem_classes=['gallery-sort']))
|
||||
sort_buttons.append(ToolButton(value=ui_symbols.sort_time_dsc, elem_classes=['gallery-sort']))
|
||||
gr.Textbox(show_label=False, placeholder='Search', elem_id='tab-gallery-search')
|
||||
gr.HTML('', elem_id='tab-gallery-status')
|
||||
for btn in sort_buttons:
|
||||
|
||||
@@ -47,8 +47,6 @@ def create_ui():
|
||||
show_label=True,
|
||||
interactive=False,
|
||||
wrap=True,
|
||||
overflow_row_behaviour='paginate',
|
||||
max_rows=50,
|
||||
elem_id='history_table',
|
||||
)
|
||||
with gr.Row():
|
||||
|
||||
@@ -68,20 +68,20 @@ def create_ui():
|
||||
img2img_selected_tab = gr.State(0) # pylint: disable=abstract-class-instantiated
|
||||
state = gr.Textbox(value='', visible=False)
|
||||
with gr.TabItem('Image', id='img2img_image', elem_id="img2img_image_tab") as tab_img2img:
|
||||
img_init = gr.Image(label="", elem_id="img2img_image", show_label=False, source="upload", interactive=True, type="pil", tool="editor", image_mode="RGBA", height=512)
|
||||
img_init = gr.Image(label="", elem_id="img2img_image", show_label=False, interactive=True, type="pil", tool="editor", image_mode="RGBA", height=512)
|
||||
interrogate_btn = ui_sections.create_interrogate_button(tab='img2img')
|
||||
add_copy_image_controls('img2img', img_init)
|
||||
|
||||
with gr.TabItem('Inpaint', id='img2img_inpaint', elem_id="img2img_inpaint_tab") as tab_inpaint:
|
||||
img_inpaint = gr.Image(label="", elem_id="img2img_inpaint", show_label=False, source="upload", interactive=True, type="pil", tool="sketch", image_mode="RGBA", height=512)
|
||||
img_inpaint = gr.Image(label="", elem_id="img2img_inpaint", show_label=False, interactive=True, type="pil", tool="sketch", image_mode="RGBA", height=512)
|
||||
add_copy_image_controls('inpaint', img_inpaint)
|
||||
|
||||
with gr.TabItem('Sketch', id='img2img_sketch', elem_id="img2img_sketch_tab") as tab_sketch:
|
||||
img_sketch = gr.Image(label="", elem_id="img2img_sketch", show_label=False, source="upload", interactive=True, type="pil", tool="color-sketch", image_mode="RGBA", height=512)
|
||||
img_sketch = gr.Image(label="", elem_id="img2img_sketch", show_label=False, interactive=True, type="pil", tool="color-sketch", image_mode="RGBA", height=512)
|
||||
add_copy_image_controls('sketch', img_sketch)
|
||||
|
||||
with gr.TabItem('Composite', id='img2img_composite', elem_id="img2img_composite_tab") as tab_inpaint_color:
|
||||
img_composite = gr.Image(label="", show_label=False, elem_id="img2img_composite", source="upload", interactive=True, type="pil", tool="color-sketch", image_mode="RGBA", height=512)
|
||||
img_composite = gr.Image(label="", show_label=False, elem_id="img2img_composite", interactive=True, type="pil", tool="color-sketch", image_mode="RGBA", height=512)
|
||||
img_composite_orig = gr.State(None) # pylint: disable=abstract-class-instantiated
|
||||
img_composite_orig_update = False
|
||||
|
||||
@@ -99,8 +99,8 @@ def create_ui():
|
||||
add_copy_image_controls('composite', img_composite)
|
||||
|
||||
with gr.TabItem('Upload', id='inpaint_upload', elem_id="img2img_inpaint_upload_tab") as tab_inpaint_upload:
|
||||
init_img_inpaint = gr.Image(label="Image for img2img", show_label=False, source="upload", interactive=True, type="pil", elem_id="img_inpaint_base")
|
||||
init_mask_inpaint = gr.Image(label="Mask", source="upload", interactive=True, type="pil", elem_id="img_inpaint_mask")
|
||||
init_img_inpaint = gr.Image(label="Image for img2img", show_label=False, interactive=True, type="pil", elem_id="img_inpaint_base")
|
||||
init_mask_inpaint = gr.Image(label="Mask", interactive=True, type="pil", elem_id="img_inpaint_mask")
|
||||
|
||||
with gr.TabItem('Batch', id='batch', elem_id="img2img_batch_tab") as tab_batch:
|
||||
gr.HTML("<p style='padding-bottom: 1em;' class=\"text-gray-500\">Run image processing on upload images or files in a folder<br>If masks are provided will run inpaint</p>")
|
||||
|
||||
@@ -26,7 +26,9 @@ class UiLoadsave:
|
||||
|
||||
def apply_field(obj, field, condition=None, init_field=None):
|
||||
key = f"{path}/{field}"
|
||||
if getattr(obj, 'custom_script_source', None) is not None:
|
||||
if hasattr(obj, 'use_original'):
|
||||
pass
|
||||
elif getattr(obj, 'custom_script_source', None) is not None:
|
||||
key = f"customscript/{obj.custom_script_source}/{key}"
|
||||
if getattr(obj, 'do_not_save_to_config', False):
|
||||
return
|
||||
@@ -45,7 +47,9 @@ class UiLoadsave:
|
||||
init_field(saved_value)
|
||||
if debug_ui and key in self.component_mapping and not key.startswith('customscript'):
|
||||
errors.log.warning(f'UI duplicate: key="{key}" id={getattr(obj, "elem_id", None)} class={getattr(obj, "elem_classes", None)}')
|
||||
if field == 'value' and key not in self.component_mapping:
|
||||
if hasattr(obj, 'skip'):
|
||||
print('HERE', key)
|
||||
if (field == 'value') and (key not in self.component_mapping):
|
||||
self.component_mapping[key] = x
|
||||
if field == 'open' and key not in self.component_mapping:
|
||||
self.component_open[key] = x
|
||||
|
||||
+12
-24
@@ -23,11 +23,11 @@ def create_ui():
|
||||
dummy_component = gr.Label(visible=False)
|
||||
with gr.Row(elem_id="models_tab"):
|
||||
with gr.Column(elem_id='models_output_container', scale=1):
|
||||
# models_output = gr.Text(elem_id="models_output", value="", show_label=False)
|
||||
# models_output = gr.Textbox(elem_id="models_output", value="", show_label=False)
|
||||
gr.HTML(elem_id="models_progress", value="")
|
||||
models_image = gr.Image(elem_id="models_image", show_label=False, interactive=False, type='pil')
|
||||
models_outcome = gr.HTML(elem_id="models_error", value="")
|
||||
models_file = gr.File(label='', type='file', help='', visible=False)
|
||||
models_file = gr.File(label='', visible=False)
|
||||
|
||||
with gr.Column(elem_id='models_input_container', scale=3):
|
||||
|
||||
@@ -327,7 +327,7 @@ def create_ui():
|
||||
with gr.Row():
|
||||
precision = gr.Dropdown(label="Model precision", choices=["fp32", "fp16", "bf16"], value="fp16")
|
||||
comp_scheduler = gr.Dropdown(label="Sampler", choices=[s.name for s in sd_samplers.samplers if s.constructor is not None])
|
||||
comp_prediction = gr.Dropdown(Label="Prediction type", choices=["epsilon", "v"], value="epsilon")
|
||||
comp_prediction = gr.Dropdown(label="Prediction type", choices=["epsilon", "v"], value="epsilon")
|
||||
with gr.Row():
|
||||
with gr.Column(scale=3):
|
||||
gr.HTML('Merge LoRA<br>')
|
||||
@@ -349,7 +349,7 @@ def create_ui():
|
||||
meta_desc = gr.Textbox(placeholder="Model description", lines=3, show_label=False)
|
||||
meta_hint = gr.Textbox(placeholder="Model hint", lines=3, show_label=False)
|
||||
with gr.Column(scale=3):
|
||||
meta_thumbnail = gr.Image(label="Thumbnail", type='pil', source='upload')
|
||||
meta_thumbnail = gr.Image(label="Thumbnail", type='pil')
|
||||
with gr.Row():
|
||||
gr.HTML('Note: Save is optional as you can merge in-memory and use newly created model immediately')
|
||||
with gr.Row():
|
||||
@@ -357,7 +357,7 @@ def create_ui():
|
||||
create_safetensors = gr.Checkbox(label="Save safetensors", value=True)
|
||||
debug = gr.Checkbox(label="Debug info", value=False)
|
||||
|
||||
model_modules_btn = gr.Button(label="Modules", variant='primary')
|
||||
model_modules_btn = gr.Button(value="Modules", variant='primary')
|
||||
model_modules_btn.click(
|
||||
fn=extras.run_model_modules,
|
||||
inputs=[
|
||||
@@ -389,8 +389,6 @@ def create_ui():
|
||||
show_label=True,
|
||||
interactive=False,
|
||||
wrap=True,
|
||||
overflow_row_behaviour='paginate',
|
||||
max_rows=50,
|
||||
)
|
||||
|
||||
def list_models():
|
||||
@@ -452,7 +450,7 @@ def create_ui():
|
||||
gr.HTML('<h2> Download model from huggingface<br></h2>')
|
||||
with gr.Row():
|
||||
hf_search_text = gr.Textbox('', label='Search models', placeholder='search huggingface models')
|
||||
hf_search_btn = ToolButton(value=ui_symbols.search, label="Search")
|
||||
hf_search_btn = ToolButton(value=ui_symbols.search)
|
||||
with gr.Row():
|
||||
with gr.Column(scale=2):
|
||||
with gr.Row():
|
||||
@@ -472,7 +470,7 @@ def create_ui():
|
||||
with gr.Row():
|
||||
hf_headers = ['Name', 'Pipeline', 'Tags', 'Downloads', 'Updated', 'URL']
|
||||
hf_types = ['str', 'str', 'str', 'number', 'date', 'markdown']
|
||||
hf_results = gr.DataFrame(None, label='Search results', show_label=True, interactive=False, wrap=True, overflow_row_behaviour='paginate', max_rows=10, headers=hf_headers, datatype=hf_types, type='array')
|
||||
hf_results = gr.DataFrame(None, label='Search results', show_label=True, interactive=False, wrap=True, headers=hf_headers, datatype=hf_types, type='array')
|
||||
|
||||
hf_search_text.submit(fn=hf_search, inputs=[hf_search_text], outputs=[hf_results])
|
||||
hf_search_btn.click(fn=hf_search, inputs=[hf_search_text], outputs=[hf_results])
|
||||
@@ -684,7 +682,7 @@ def create_ui():
|
||||
with gr.Row():
|
||||
civit_search_text = gr.Textbox('', label='Search models', placeholder='keyword')
|
||||
civit_search_tag = gr.Textbox('', label='', placeholder='tags')
|
||||
civit_search_btn = ToolButton(value=ui_symbols.search, label="Search", interactive=True)
|
||||
civit_search_btn = ToolButton(value=ui_symbols.search, interactive=True)
|
||||
with gr.Row():
|
||||
civit_search_res = gr.HTML('')
|
||||
with gr.Row():
|
||||
@@ -704,25 +702,16 @@ def create_ui():
|
||||
with gr.Row():
|
||||
civit_headers1 = ['ID', 'Name', 'Tags', 'Downloads', 'Rating']
|
||||
civit_types1 = ['number', 'str', 'str', 'number', 'number']
|
||||
civit_results1 = gr.DataFrame(value=None, label=None, show_label=False, interactive=False,
|
||||
wrap=True, overflow_row_behaviour='paginate', max_rows=10,
|
||||
headers=civit_headers1, datatype=civit_types1, type='array',
|
||||
visible=False)
|
||||
civit_results1 = gr.DataFrame(value=None, label=None, show_label=False, interactive=False, wrap=True, headers=civit_headers1, datatype=civit_types1, type='array', visible=False)
|
||||
with gr.Row():
|
||||
with gr.Column():
|
||||
civit_headers2 = ['ID', 'ModelID', 'Name', 'Base', 'Created', 'Preview']
|
||||
civit_types2 = ['number', 'number', 'str', 'str', 'date', 'str']
|
||||
civit_results2 = gr.DataFrame(value=None, label='Model versions', show_label=True,
|
||||
interactive=False, wrap=True, overflow_row_behaviour='paginate',
|
||||
max_rows=10, headers=civit_headers2, datatype=civit_types2,
|
||||
type='array', visible=False)
|
||||
civit_results2 = gr.DataFrame(value=None, label='Model versions', show_label=True, interactive=False, wrap=True, headers=civit_headers2, datatype=civit_types2, type='array', visible=False)
|
||||
with gr.Column():
|
||||
civit_headers3 = ['Name', 'Size', 'Metadata', 'URL']
|
||||
civit_types3 = ['str', 'number', 'str', 'str']
|
||||
civit_results3 = gr.DataFrame(value=None, label='Model variants', show_label=True,
|
||||
interactive=False, wrap=True, overflow_row_behaviour='paginate',
|
||||
max_rows=10, headers=civit_headers3, datatype=civit_types3,
|
||||
type='array', visible=False)
|
||||
civit_results3 = gr.DataFrame(value=None, label='Model variants', show_label=True, interactive=False, wrap=True, headers=civit_headers3, datatype=civit_types3, type='array', visible=False)
|
||||
|
||||
def is_visible(component):
|
||||
visible = len(component) > 0 if component is not None else False
|
||||
@@ -751,8 +740,7 @@ def create_ui():
|
||||
civit_headers4 = ['ID', 'File', 'Name', 'Versions', 'Current', 'Latest', 'Update']
|
||||
civit_types4 = ['number', 'str', 'str', 'number', 'str', 'str', 'str']
|
||||
civit_widths4 = ['10%', '25%', '25%', '5%', '10%', '10%', '15%']
|
||||
civit_results4 = gr.DataFrame(value=None, label=None, show_label=False, interactive=False, wrap=True, overflow_row_behaviour='paginate',
|
||||
row_count=20, max_rows=100, headers=civit_headers4, datatype=civit_types4, type='array', column_widths=civit_widths4)
|
||||
civit_results4 = gr.DataFrame(value=None, label=None, show_label=False, interactive=False, wrap=True, row_count=20, headers=civit_headers4, datatype=civit_types4, type='array', column_widths=civit_widths4)
|
||||
with gr.Row():
|
||||
gr.HTML('<h3>Select model from the list and download update if available</h3>')
|
||||
with gr.Row():
|
||||
|
||||
@@ -284,7 +284,7 @@ def create_ui(gr_status, gr_file):
|
||||
cls = gr.Textbox(label="Model class", placeholder="Class name", interactive=False)
|
||||
with gr.Row():
|
||||
repo = gr.Textbox(label="Model repo", placeholder="Repo name", interactive=True)
|
||||
link = gr.HTML(value="", interactive=False)
|
||||
link = gr.HTML(value="")
|
||||
with gr.Row():
|
||||
headers = ['ID', 'Name', 'Loadable', 'Default', 'Class', 'Local', 'Remote', 'Dtype', 'Quant']
|
||||
datatype = ['number', 'str', 'bool', 'str', 'str', 'str', 'str', 'str', 'bool']
|
||||
@@ -296,8 +296,6 @@ def create_ui(gr_status, gr_file):
|
||||
wrap=True,
|
||||
headers=headers,
|
||||
datatype=datatype,
|
||||
max_rows=None,
|
||||
max_cols=None,
|
||||
type='array',
|
||||
elem_id="model_loader_df",
|
||||
)
|
||||
|
||||
@@ -22,7 +22,7 @@ def create_ui():
|
||||
with gr.Tabs(elem_id="mode_extras"):
|
||||
with gr.Tab('Process Image', id="single_image", elem_id="extras_single_tab") as tab_single:
|
||||
with gr.Row():
|
||||
extras_image = gr.Image(label="Source", source="upload", interactive=True, type="pil", elem_id="extras_image")
|
||||
extras_image = gr.Image(label="Source", interactive=True, type="pil", elem_id="extras_image")
|
||||
with gr.Tab('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.Tab('Process Folder', id="batch_from_directory", elem_id="extras_batch_directory_tab") as tab_batch_dir:
|
||||
@@ -44,7 +44,7 @@ def create_ui():
|
||||
result_images, generation_info, html_info, html_info_formatted, html_log = ui_common.create_output_panel("extras")
|
||||
gr.HTML('File metadata')
|
||||
exif_info = gr.HTML(elem_id="pnginfo_html_info")
|
||||
gen_info = gr.Text(elem_id="pnginfo_gen_info", visible=False)
|
||||
gen_info = gr.Textbox(elem_id="pnginfo_gen_info", visible=False)
|
||||
with gr.Row(elem_id='copy_buttons_process'):
|
||||
copy_process_buttons = generation_parameters_copypaste.create_buttons(["txt2img", "img2img", "control", "caption"])
|
||||
|
||||
|
||||
@@ -87,7 +87,7 @@ def create_resolution_inputs(tab, default_width=1024, default_height=1024):
|
||||
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]:
|
||||
c.change(fn=ar_change, inputs=[ar_dropdown, width, height], outputs=[width, height], show_progress=False)
|
||||
res_switch_btn = ToolButton(value=ui_symbols.switch, elem_id=f"{tab}_res_switch_btn", label="Switch dims")
|
||||
res_switch_btn = ToolButton(value=ui_symbols.switch, elem_id=f"{tab}_res_switch_btn")
|
||||
res_switch_btn.click(lambda w, h: (h, w), inputs=[width, height], outputs=[width, height], show_progress=False)
|
||||
return width, height
|
||||
|
||||
@@ -125,8 +125,8 @@ def create_seed_inputs(tab, reuse_visible=True, accordion=True, subseed_visible=
|
||||
with gr.Accordion(open=False, label="Seed", elem_id=f"{tab}_seed_group", elem_classes=["small-accordion"]) if accordion else gr.Group():
|
||||
with gr.Row(elem_id=f"{tab}_seed_row", variant="compact"):
|
||||
seed = gr.Number(label='Initial seed', value=-1, elem_id=f"{tab}_seed", container=True)
|
||||
random_seed = ToolButton(ui_symbols.random, elem_id=f"{tab}_random_seed", label='Random seed')
|
||||
reuse_seed = ToolButton(ui_symbols.reuse, elem_id=f"{tab}_reuse_seed", label='Reuse seed', visible=reuse_visible)
|
||||
random_seed = ToolButton(ui_symbols.random, elem_id=f"{tab}_random_seed")
|
||||
reuse_seed = ToolButton(ui_symbols.reuse, elem_id=f"{tab}_reuse_seed", visible=reuse_visible)
|
||||
with gr.Row(elem_id=f"{tab}_subseed_row", variant="compact", visible=subseed_visible):
|
||||
subseed = gr.Number(label='Variation', value=-1, elem_id=f"{tab}_subseed", container=True)
|
||||
random_subseed = ToolButton(ui_symbols.random, elem_id=f"{tab}_random_subseed")
|
||||
|
||||
@@ -97,7 +97,10 @@ def create_setting_component(key, is_quicksettings=False):
|
||||
res = None
|
||||
|
||||
if res is not None and not is_quicksettings:
|
||||
res.change(fn=None, inputs=res, _js=f'(val) => markIfModified("{key}", val)')
|
||||
try:
|
||||
res.change(fn=None, inputs=res, _js=f'(val) => markIfModified("{key}", val)')
|
||||
except Exception as e:
|
||||
shared.log.error(f'Quicksetting: component={res} {e}')
|
||||
if dirty_indicator is not None:
|
||||
dirty_indicator.click(fn=lambda: shared.opts.get_default(key), outputs=[res], show_progress=False)
|
||||
dirtyable_setting.__exit__()
|
||||
@@ -186,7 +189,7 @@ def create_ui():
|
||||
preview_theme = gr.Button(value="Preview theme", variant='primary', elem_id="settings_preview_theme")
|
||||
defaults_submit = gr.Button(value="Restore defaults", variant='primary', elem_id="defaults_submit")
|
||||
with gr.Row():
|
||||
_settings_search = gr.Text(label="Search", elem_id="settings_search")
|
||||
_settings_search = gr.Textbox(label="Search", elem_id="settings_search")
|
||||
|
||||
result = gr.HTML(elem_id="settings_result")
|
||||
script_callbacks.ui_settings_callback() # let extensions create settings
|
||||
|
||||
+3
-3
@@ -92,7 +92,7 @@ def create_ui():
|
||||
with gr.Row():
|
||||
engine = gr.Dropdown(label='Engine', choices=list(models_def.models), value='None', elem_id="video_engine")
|
||||
model = gr.Dropdown(label='Model', choices=[''], value=None, elem_id="video_model")
|
||||
btn_load = ToolButton(ui_symbols.loading, elem_id="video_model_load", label='Load model')
|
||||
btn_load = ToolButton(ui_symbols.loading, elem_id="video_model_load")
|
||||
with gr.Row():
|
||||
url = gr.HTML(label='Model URL', elem_id='video_model_url', value='<br><br>')
|
||||
with gr.Accordion(open=True, label="Size", elem_id='video_size_accordion'):
|
||||
@@ -101,8 +101,8 @@ def create_ui():
|
||||
with gr.Row():
|
||||
frames = gr.Slider(label='Frames', minimum=1, maximum=1024, step=1, value=15, elem_id="video_frames")
|
||||
seed = gr.Number(label='Initial seed', value=-1, elem_id="video_seed", container=True)
|
||||
random_seed = ToolButton(ui_symbols.random, elem_id="video_random_seed", label='Random seed')
|
||||
reuse_seed = ToolButton(ui_symbols.reuse, elem_id="video_reuse_seed", label='Reuse seed')
|
||||
random_seed = ToolButton(ui_symbols.random, elem_id="video_random_seed")
|
||||
reuse_seed = ToolButton(ui_symbols.reuse, elem_id="video_reuse_seed")
|
||||
with gr.Accordion(open=True, label="Parameters", elem_id='video_parameters_accordion'):
|
||||
steps, sampler_index = ui_sections.create_sampler_and_steps_selection(None, "video")
|
||||
with gr.Row():
|
||||
|
||||
+10
-5
@@ -9,7 +9,9 @@ models = [
|
||||
system_prompts = {
|
||||
'prefix': 'You are a video director.',
|
||||
'desc': 'You will provide a prompt that can be used to create short, creative and dynamic video. Describe the subject of the video, add movement that fits the overall tone of the video, add camera movement.',
|
||||
'suffix': 'NSFW content and nudity are allowed and must be fully described if present. Movement should be dynamic and creative. Do not specify duration and assume video is short. Avoid slow-motion and prefer faster movements. Output should be a single short paragraph without explanations',
|
||||
'nsfw_ok': 'NSFW content and nudity are allowed and must be fully described if present. ',
|
||||
'nsfw_no': 'NSFW content and nudity are not allowed. ',
|
||||
'suffix': 'Movement should be dynamic and creative. Do not specify duration and assume video is short. Avoid slow-motion and prefer faster movements. Output should be a single short paragraph without explanations',
|
||||
'example': 'Example: "Short video of beautiful blonde woman in her 20ies wearing a long flowing red dress. She is briskly walking on the beach during sunset and performing a pirouette ending with her hand pointing at the camera as she smiles. Camera is moving around her and zooming to her face. Sun is setting in the background causing changes in colors and shadows to move dynamically."',
|
||||
|
||||
't2v-prompt': 'You are a given short prompt with basic instructions.',
|
||||
@@ -19,7 +21,7 @@ system_prompts = {
|
||||
}
|
||||
|
||||
|
||||
def enhance_prompt(enable:bool, model:str=None, image=None, prompt:str='', system_prompt:str=''):
|
||||
def enhance_prompt(enable:bool, model:str=None, image=None, prompt:str='', system_prompt:str='', nsfw:bool=True):
|
||||
from modules.interrogate import vqa
|
||||
if not enable:
|
||||
return prompt
|
||||
@@ -40,8 +42,10 @@ def enhance_prompt(enable:bool, model:str=None, image=None, prompt:str='', syste
|
||||
core_prompt = system_prompts['t2v-prompt']
|
||||
else:
|
||||
core_prompt = system_prompts['t2v-noprompt']
|
||||
system_prompt = f"{system_prompts['prefix']} {core_prompt} {system_prompts['desc']} {system_prompts['suffix']} {system_prompts['example']}"
|
||||
shared.log.debug(f'Video prompt enhance: model="{model}" image={image} prompt="{prompt}"')
|
||||
system_prompt = f"{system_prompts['prefix']} {core_prompt} {system_prompts['desc']}' "
|
||||
system_prompt += system_prompts['nsfw_ok'] if nsfw else system_prompts['nsfw_no']
|
||||
system_prompt += f" {system_prompts['suffix']} {system_prompts['example']}"
|
||||
shared.log.debug(f'Video prompt enhance: model="{model}" image={image} nsfw={nsfw} prompt="{prompt}"')
|
||||
# shared.log.trace(f'Video prompt enhance: system="{system_prompt}"')
|
||||
answer = vqa.interrogate(question='', prompt=prompt, system_prompt=system_prompt, image=image, model_name=model, quiet=False)
|
||||
shared.log.debug(f'Video prompt enhance: answer="{answer}"')
|
||||
@@ -52,6 +56,7 @@ def create_ui(prompt_element:gr.Textbox, image_element:gr.Image):
|
||||
with gr.Accordion('Prompt enhance', open=False):
|
||||
with gr.Row():
|
||||
enable = gr.Checkbox(label='Enable', value=False)
|
||||
nsfw = gr.Checkbox(label='NSFW allowed', value=True)
|
||||
btn_enhance = gr.Button(value='Enhance now', elem_id='btn_enhance')
|
||||
with gr.Row():
|
||||
model = gr.Dropdown(label='Model', choices=models, value=models[0])
|
||||
@@ -59,7 +64,7 @@ def create_ui(prompt_element:gr.Textbox, image_element:gr.Image):
|
||||
system_prompt = gr.Textbox(label='System prompt', placeholder='override system prompt with user-provided prompt', lines=3)
|
||||
btn_enhance.click(
|
||||
fn=enhance_prompt,
|
||||
inputs=[enable, model, image_element, prompt_element, system_prompt],
|
||||
inputs=[enable, model, image_element, prompt_element, system_prompt, nsfw],
|
||||
outputs=prompt_element,
|
||||
show_progress=True,
|
||||
)
|
||||
|
||||
@@ -78,7 +78,7 @@ def install():
|
||||
return
|
||||
|
||||
platform = "windows"
|
||||
commit = os.environ.get("ZLUDA_HASH", "8d2128caf460b853b165cab0b4d8826b6b734ae7")
|
||||
commit = os.environ.get("ZLUDA_HASH", "5e717459179dc272b7d7d23391f0fad66c7459cf")
|
||||
if os.environ.get("ZLUDA_NIGHTLY", "0") == "1":
|
||||
log.warning("Environment variable 'ZLUDA_NIGHTLY' will be removed. Please use command-line argument '--use-nightly' instead.")
|
||||
args.use_nightly = True
|
||||
|
||||
+1
-1
@@ -45,7 +45,7 @@ accelerate==1.6.0
|
||||
opencv-contrib-python-headless==4.9.0.80
|
||||
einops==0.4.1
|
||||
gradio==3.43.2
|
||||
huggingface_hub==0.31.1
|
||||
huggingface_hub==0.31.2
|
||||
numexpr==2.10.2
|
||||
numpy==1.26.4
|
||||
numba==0.61.2
|
||||
|
||||
+2
-2
@@ -42,8 +42,8 @@ class Script(scripts.Script):
|
||||
override = gr.Checkbox(label='Override resolution', value=True)
|
||||
with gr.Accordion('Optional init image or video', open=False):
|
||||
with gr.Row():
|
||||
image = gr.Image(value=None, label='Image', type='pil', source='upload', width=256, height=256)
|
||||
video = gr.Video(value=None, label='Video', source='upload', width=256, height=256)
|
||||
image = gr.Image(value=None, label='Image', type='pil', width=256, height=256)
|
||||
video = gr.Video(value=None, label='Video', width=256, height=256)
|
||||
with gr.Row():
|
||||
from modules.ui_sections import create_video_inputs
|
||||
video_type, duration, loop, pad, interpolate = create_video_inputs(tab='img2img' if is_img2img else 'txt2img')
|
||||
|
||||
+4
-4
@@ -17,20 +17,20 @@ class Script(scripts.Script):
|
||||
gr.HTML('<a href="https://github.com/genforce/ctrl-x">  Ctrl-X: Controlling Structure and Appearance</a><br>')
|
||||
with gr.Accordion(label='Structure', open=True):
|
||||
with gr.Row():
|
||||
struct_prompt = gr.Textbox(label='Prompt', value='', rows=1)
|
||||
struct_prompt = gr.Textbox(label='Prompt', value='')
|
||||
with gr.Row():
|
||||
struct_strength = gr.Slider(label='Strength', value=0.5, minimum=0.0, maximum=1.0, step=0.05)
|
||||
struct_guidance = gr.Slider(label='Guidance', value=5.0, minimum=0.0, maximum=14.0, step=0.05)
|
||||
with gr.Row():
|
||||
struct_image = gr.Image(label='Image', source='upload', type='pil')
|
||||
struct_image = gr.Image(label='Image', type='pil')
|
||||
with gr.Accordion(label='Appearance', open=True):
|
||||
with gr.Row():
|
||||
appear_prompt = gr.Textbox(label='Prompt', value='', rows=1)
|
||||
appear_prompt = gr.Textbox(label='Prompt', value='')
|
||||
with gr.Row():
|
||||
appear_strength = gr.Slider(label='Strength', value=0.5, minimum=0.0, maximum=1.0, step=0.05)
|
||||
appear_guidance = gr.Slider(label='Guidance', value=5.0, minimum=0.0, maximum=14.0, step=0.05)
|
||||
with gr.Row():
|
||||
appear_image = gr.Image(label='Image', source='upload', type='pil')
|
||||
appear_image = gr.Image(label='Image', type='pil')
|
||||
return struct_prompt, struct_strength, struct_guidance, struct_image, appear_prompt, appear_strength, appear_guidance, appear_image
|
||||
|
||||
def restore(self):
|
||||
|
||||
@@ -1872,7 +1872,7 @@ class Script(scripts.Script):
|
||||
strength = gr.Slider(minimum=0.0, maximum=2.0, value=1.0, label='Mask strength')
|
||||
model = gr.Dropdown(label='Model', choices=['None', 'DPT Tiny', 'DPT Hybrid', 'DPT Large'], value='None')
|
||||
with gr.Row():
|
||||
image = gr.Image(label="Image map", show_label=False, type="pil", source="upload", interactive=True, tool="editor", visible=True, image_mode='RGB')
|
||||
image = gr.Image(label="Image map", show_label=False, type="pil", interactive=True, tool="editor", visible=True, image_mode='RGB')
|
||||
return enabled, strength, invert, model, image
|
||||
|
||||
def depthmap(self, image_init: Image.Image, image_map: Image.Image, model: str, strength: float, invert: bool):
|
||||
|
||||
@@ -73,13 +73,13 @@ class Script(scripts.Script):
|
||||
def ui(self, _is_img2img):
|
||||
with gr.Row():
|
||||
self.button = gr.Button(value='Enhance prompt')
|
||||
self.auto_apply = gr.Checkbox(label='Auto apply', default=False)
|
||||
self.auto_apply = gr.Checkbox(label='Auto apply', value=False)
|
||||
with gr.Row():
|
||||
self.max_length = gr.Slider(label='Length', minimum=64, maximum=512, step=1, value=128)
|
||||
self.temperature = gr.Slider(label='Temperature', minimum=0.1, maximum=2.0, step=0.05, value=0.7)
|
||||
self.repetition_penalty = gr.Slider(label='Penalty', minimum=0.1, maximum=2.0, step=0.05, value=1.2)
|
||||
with gr.Row():
|
||||
self.table = gr.DataFrame(self.prompts, label='', show_label=False, interactive=False, wrap=True, datatype="str", col_count=1, max_rows=num_return_sequences, headers=['Prompts'])
|
||||
self.table = gr.DataFrame(self.prompts, label='', show_label=False, interactive=False, wrap=True, datatype="str", col_count=1, headers=['Prompts'])
|
||||
|
||||
if self.prompt is not None:
|
||||
self.button.click(fn=self.enhance, inputs=[self.prompt, self.auto_apply, self.temperature, self.repetition_penalty, self.max_length], outputs=[self.table])
|
||||
@@ -100,3 +100,4 @@ class Script(scripts.Script):
|
||||
def after_component(self, component, **kwargs): # searching for actual ui prompt components
|
||||
if getattr(component, 'elem_id', '') in ['txt2img_prompt', 'img2img_prompt', 'control_prompt', 'video_prompt']:
|
||||
self.prompt = component
|
||||
self.prompt.use_original = True
|
||||
|
||||
@@ -66,25 +66,25 @@ class Script(scripts.Script):
|
||||
ui_common.create_refresh_button(adapter, ipadapter.get_adapters)
|
||||
with gr.Row():
|
||||
scales.append(gr.Slider(label='Strength', minimum=0.0, maximum=1.0, step=0.01, value=0.5))
|
||||
crops.append(gr.Checkbox(label='Crop to portrait', default=False, interactive=True))
|
||||
crops.append(gr.Checkbox(label='Crop to portrait', value=False, interactive=True))
|
||||
with gr.Row():
|
||||
starts.append(gr.Slider(label='Start', minimum=0.0, maximum=1.0, step=0.1, value=0))
|
||||
ends.append(gr.Slider(label='End', minimum=0.0, maximum=1.0, step=0.1, value=1))
|
||||
with gr.Row():
|
||||
files.append(gr.File(label='Input images', file_count='multiple', file_types=['image'], type='file', interactive=True, height=100))
|
||||
files.append(gr.File(label='Input images', file_count='multiple', file_types=['image'], interactive=True, height=100))
|
||||
with gr.Row():
|
||||
image_galleries.append(gr.Gallery(show_label=False, value=[], visible=False, container=False, rows=1))
|
||||
with gr.Row():
|
||||
masks.append(gr.File(label='Input masks', file_count='multiple', file_types=['image'], type='file', interactive=True, height=100))
|
||||
masks.append(gr.File(label='Input masks', file_count='multiple', file_types=['image'], interactive=True, height=100))
|
||||
with gr.Row():
|
||||
mask_galleries.append(gr.Gallery(show_label=False, value=[], visible=False))
|
||||
files[i].change(fn=self.load_images, inputs=[files[i]], outputs=[image_galleries[i]])
|
||||
masks[i].change(fn=self.load_images, inputs=[masks[i]], outputs=[mask_galleries[i]])
|
||||
units.append(unit)
|
||||
num_adapters.change(fn=self.display_units, inputs=[num_adapters], outputs=units)
|
||||
layers_active = gr.Checkbox(label='Layer options', default=False, interactive=True)
|
||||
layers_active = gr.Checkbox(label='Layer options', value=False, interactive=True)
|
||||
layers_label = gr.HTML('<a href="https://huggingface.co/docs/diffusers/main/en/using-diffusers/ip_adapter#style--layout-control" target="_blank">InstantStyle: advanced layer activation</a>', visible=False)
|
||||
layers = gr.Text(label='Layer scales', placeholder='{\n"down": {"block_2": [0.0, 1.0]},\n"up": {"block_0": [0.0, 1.0, 0.0]}\n}', rows=1, type='text', interactive=True, lines=5, visible=False, show_label=False)
|
||||
layers = gr.Textbox(label='Layer scales', placeholder='{\n"down": {"block_2": [0.0, 1.0]},\n"up": {"block_0": [0.0, 1.0, 0.0]}\n}', type='text', interactive=True, lines=5, visible=False, show_label=False)
|
||||
layers_active.change(fn=self.display_advanced, inputs=[layers_active], outputs=[layers_label, layers])
|
||||
return [num_adapters] + [unload_adapter] + adapters + scales + files + crops + starts + ends + masks + [layers_active] + [layers]
|
||||
|
||||
|
||||
@@ -45,7 +45,7 @@ class Script(scripts.Script):
|
||||
with gr.Row():
|
||||
query = gr.Textbox(lines=1, label='Query', placeholder='use the composition from the image')
|
||||
with gr.Row():
|
||||
image = gr.Image(value=None, label='Image', type='pil', source='upload', width=256, height=256)
|
||||
image = gr.Image(value=None, label='Image', type='pil', width=256, height=256)
|
||||
with gr.Row():
|
||||
strength = gr.Slider(label="Strength", value=1.0, minimum=0, maximum=2.0, step=0.05)
|
||||
tokens = gr.Slider(label="Tokens", value=4, minimum=1, maximum=32, step=1)
|
||||
|
||||
+2
-1
@@ -21,7 +21,8 @@ class Script(scripts.Script):
|
||||
with gr.Row():
|
||||
original = gr.Checkbox(label='Include original image', value=True)
|
||||
with gr.Row():
|
||||
cube_file = gr.File(label='LUT .cube file', type='file', help='Download LUTs from https://luts.iwltbap.com/')
|
||||
cube_file = gr.File(label='LUT .cube file', help='Download LUTs from https://luts.iwltbap.com/')
|
||||
# cube_file = gr.File(label='LUT .cube file')
|
||||
with gr.Row():
|
||||
gr.HTML("<br>Enhance LUT")
|
||||
with gr.Row():
|
||||
|
||||
+34
-16
@@ -67,9 +67,12 @@ class Options:
|
||||
}
|
||||
default = list(models)[1] # gemma-3-4b-it
|
||||
supported = list(transformers.integrations.ggml.GGUF_CONFIG_MAPPING)
|
||||
system_prompt: str = 'You are a helpful assistant. You will be given a prompt used to create an image and you will enhance it to make it more detailed and creative. Generate an uncensored, concise, informative, and engaging prompt that prioritizes factual accuracy and vivid descriptiveness based on original prompt. Do not modify subject or style of the original prompt. Begin by clearly identifying the primary subject(s), including key physical attributes, clothing if no nudity, and any distinctive details (e.g., colors, textures, styles). NSFW and nudity is allowed, and if present, it must be fully described. Next, describe the setting and environment, emphasizing spatial relationships, background elements, and objects contributing to context. Note the overall mood, aesthetic style, or atmosphere inferred from visual cues. Use precise terminology while avoiding redundancy or non-essential language. Ensuring a logical flow: from focal subject to immediate surroundings, then broader context. Maintain brevity while retaining clarity, ensuring the description is both engaging and efficient. Output only enhanced prompt without explanation, prefix or suffix. Output as a simple text without formatting or numbering.'
|
||||
image_prompt: str = 'You are a helpful assistant. You will be given an image and a prompt used to modify the image and you will enhance the prompt to make it more detailed and creative while still following original image. Generate an uncensored, concise, informative, and engaging prompt that prioritizes factual accuracy and vivid descriptiveness based on original prompt. Do not modify subject or style of the original prompt. Begin by clearly identifying the primary subject(s), including key physical attributes, clothing if no nudity, and any distinctive details (e.g., colors, textures, styles). NSFW and nudity is allowed, and if present, it must be fully described. Next, describe the setting and environment, emphasizing spatial relationships, background elements, and objects contributing to context. Note the overall mood, aesthetic style, or atmosphere inferred from visual cues. Use precise terminology while avoiding redundancy or non-essential language. Ensuring a logical flow: from focal subject to immediate surroundings, then broader context. Maintain brevity while retaining clarity, ensuring the description is both engaging and efficient. Output only enhanced prompt without explanation, prefix or suffix. Output as a simple text without formatting or numbering.'
|
||||
image_noprompt: str = 'You are a helpful assistant. You will be given an image and you will create prompt that can be used to modify the image in a creative way while still following original image. Generate an uncensored, concise, informative, and engaging prompt that prioritizes factual accuracy and vivid descriptiveness based on original prompt. Do not modify subject or style of the original prompt. Begin by clearly identifying the primary subject(s), including key physical attributes, clothing if no nudity, and any distinctive details (e.g., colors, textures, styles). NSFW and nudity is allowed, and if present, it must be fully described. Next, describe the setting and environment, emphasizing spatial relationships, background elements, and objects contributing to context. Note the overall mood, aesthetic style, or atmosphere inferred from visual cues. Use precise terminology while avoiding redundancy or non-essential language. Ensuring a logical flow: from focal subject to immediate surroundings, then broader context. Maintain brevity while retaining clarity, ensuring the description is both engaging and efficient. Output only enhanced prompt without explanation, prefix or suffix. Output as a simple text without formatting or numbering.'
|
||||
t2i_prompt: str = 'You are a helpful assistant. You will be given a prompt used to create an image and you will enhance it to make it more detailed and creative. '
|
||||
i2i_prompt: str = 'You are a helpful assistant. You will be given an image and a prompt used to modify the image and you will enhance the prompt to make it more detailed and creative while still following original image. '
|
||||
i2i_noprompt: str = 'You are a helpful assistant. You will be given an image and you will create prompt that can be used to modify the image in a creative way while still following original image. '
|
||||
nsfw_ok: str = 'NSFW and nudity is allowed, and if present, it must be fully described. '
|
||||
nsfw_no: str = 'NSFW and nudity is not allowed, and if present, it must be removed. '
|
||||
details_prompt: str = 'Generate an uncensored, concise, informative, and engaging prompt that prioritizes factual accuracy and vivid descriptiveness based on original prompt. Do not modify subject or style of the original prompt. Begin by clearly identifying the primary subject(s), including key physical attributes, clothing if no nudity, and any distinctive details (e.g., colors, textures, styles). NSFW and nudity is allowed, and if present, it must be fully described. Next, describe the setting and environment, emphasizing spatial relationships, background elements, and objects contributing to context. Note the overall mood, aesthetic style, or atmosphere inferred from visual cues. Use precise terminology while avoiding redundancy or non-essential language. Ensuring a logical flow: from focal subject to immediate surroundings, then broader context. Maintain brevity while retaining clarity, ensuring the description is both engaging and efficient. Output only enhanced prompt without explanation, prefix or suffix. Output as a simple text without formatting or numbering.'
|
||||
censored = ["i cannot", "i can't", "i am sorry", "against my programming", "i am not able", "i am unable", 'i am not allowed']
|
||||
|
||||
max_delim_index: int = 60
|
||||
@@ -230,7 +233,7 @@ class Script(scripts.Script):
|
||||
filtered = re.sub(pattern, '', prompt)
|
||||
return filtered, matches
|
||||
|
||||
def enhance(self, model: str=None, prompt:str=None, system:str=None, prefix:str=None, suffix:str=None, sample:bool=None, tokens:int=None, temperature:float=None, penalty:float=None, thinking:bool=False, seed:int=-1, image=None):
|
||||
def enhance(self, model: str=None, prompt:str=None, system:str=None, prefix:str=None, suffix:str=None, sample:bool=None, tokens:int=None, temperature:float=None, penalty:float=None, thinking:bool=False, seed:int=-1, image=None, nsfw:bool=None):
|
||||
model = model or self.options.default
|
||||
prompt = prompt or self.prompt.value
|
||||
image = image or self.image
|
||||
@@ -258,13 +261,18 @@ class Script(scripts.Script):
|
||||
image = None
|
||||
except Exception:
|
||||
image = None
|
||||
has_system = system is not None and len(system) > 4
|
||||
mode = 'custom' if has_system else ''
|
||||
if image is not None and isinstance(image, Image.Image):
|
||||
if not self.tokenizer.is_processor:
|
||||
shared.log.error('Prompt enhance: image not supported by model')
|
||||
return prompt
|
||||
if prompt is not None and len(prompt) > 0:
|
||||
mode = 'i2i+p'
|
||||
system = system or self.options.image_prompt
|
||||
if not has_system:
|
||||
mode = 'i2i-prompt'
|
||||
system = self.options.i2i_prompt
|
||||
system += self.options.nsfw_ok if nsfw else self.options.nsfw_no
|
||||
system += self.options.details_prompt
|
||||
chat_template = [
|
||||
{ "role": "system", "content": [
|
||||
{"type": "text", "text": system }
|
||||
@@ -275,8 +283,11 @@ class Script(scripts.Script):
|
||||
] },
|
||||
]
|
||||
else:
|
||||
mode = 'i2i-p'
|
||||
system = system or self.options.image_noprompt
|
||||
if not has_system:
|
||||
mode = 'i2i-noprompt'
|
||||
system = self.options.i2i_noprompt
|
||||
system += self.options.nsfw_ok if nsfw else self.options.nsfw_no
|
||||
system += self.options.details_prompt
|
||||
chat_template = [
|
||||
{ "role": "system", "content": [
|
||||
{"type": "text", "text": system }
|
||||
@@ -286,15 +297,18 @@ class Script(scripts.Script):
|
||||
] },
|
||||
]
|
||||
else:
|
||||
system = system or self.options.system_prompt
|
||||
if not has_system:
|
||||
system = self.options.t2i_prompt
|
||||
system += self.options.nsfw_ok if nsfw else self.options.nsfw_no
|
||||
system += self.options.details_prompt
|
||||
if not self.tokenizer.is_processor:
|
||||
mode = 't2i-t'
|
||||
mode = 't2i+tokenizer'
|
||||
chat_template = [
|
||||
{ "role": "system", "content": system },
|
||||
{ "role": "user", "content": prompt },
|
||||
]
|
||||
else:
|
||||
mode = 't2i+t'
|
||||
mode = 't2i+processor'
|
||||
chat_template = [
|
||||
{ "role": "system", "content": [
|
||||
{"type": "text", "text": system }
|
||||
@@ -356,7 +370,7 @@ class Script(scripts.Script):
|
||||
if not is_censored:
|
||||
response = self.clean(response)
|
||||
response = self.post(response, prefix, suffix, networks)
|
||||
shared.log.info(f'Prompt enhance: model="{model}" mode="{mode}" time={t1-t0:.2f} inputs={input_len} outputs={outputs.shape[-1]} prompt={len(prompt)} response={len(response)}')
|
||||
shared.log.info(f'Prompt enhance: model="{model}" mode="{mode}" nsfw={nsfw} time={t1-t0:.2f} inputs={input_len} outputs={outputs.shape[-1]} prompt={len(prompt)} response={len(response)}')
|
||||
if debug_enabled:
|
||||
shared.log.trace(f'Prompt enhance: sample={sample} tokens={tokens} temperature={temperature} penalty={penalty} thinking={thinking}')
|
||||
shared.log.trace(f'Prompt enhance: prompt="{prompt}"')
|
||||
@@ -430,6 +444,7 @@ class Script(scripts.Script):
|
||||
temperature = gr.Slider(label='Temperature', value=self.options.temperature, minimum=0.0, maximum=1.0, step=0.01, interactive=True)
|
||||
repetition_penalty = gr.Slider(label='Repetition penalty', value=self.options.repetition_penalty, minimum=0.0, maximum=2.0, step=0.01, interactive=True)
|
||||
with gr.Row():
|
||||
nsfw_mode = gr.Checkbox(label='NSFW allowed', value=True, interactive=True)
|
||||
thinking_mode = gr.Checkbox(label='Thinking mode', value=False, interactive=True)
|
||||
gr.HTML('<br>')
|
||||
with gr.Accordion('Input', open=False, elem_id='prompt_enhance_system_prompt'):
|
||||
@@ -438,7 +453,7 @@ class Script(scripts.Script):
|
||||
with gr.Row():
|
||||
prompt_suffix = gr.Textbox(label='Prompt suffix', value='', placeholder='Optional prompt suffix', interactive=True, lines=2, elem_id='prompt_enhance_suffix')
|
||||
with gr.Row():
|
||||
prompt_system = gr.Textbox(label='System prompt', value=self.options.system_prompt, interactive=True, lines=4, elem_id='prompt_enhance_system')
|
||||
prompt_system = gr.Textbox(label='System prompt', value='', interactive=True, lines=4, elem_id='prompt_enhance_system')
|
||||
with gr.Accordion('Output', open=True, elem_id='prompt_enhance_system_prompt'):
|
||||
with gr.Row():
|
||||
prompt_output = gr.Textbox(label='Enhanced prompt', value='', interactive=True, lines=4)
|
||||
@@ -449,17 +464,19 @@ class Script(scripts.Script):
|
||||
copy_btn.click(fn=lambda x: x, inputs=[prompt_output], outputs=[self.prompt])
|
||||
if self.image is None:
|
||||
self.image = gr.Image(type='pil', interactive=False, visible=False, width=64, height=64) # dummy image
|
||||
apply_btn.click(fn=self.apply, inputs=[self.prompt, self.image, apply_prompt, llm_model, prompt_system, prompt_prefix, prompt_suffix, max_tokens, do_sample, temperature, repetition_penalty, thinking_mode], outputs=[prompt_output, self.prompt])
|
||||
return [self.prompt, self.image, apply_auto, llm_model, prompt_system, prompt_prefix, prompt_suffix, max_tokens, do_sample, temperature, repetition_penalty, thinking_mode]
|
||||
apply_btn.click(fn=self.apply, inputs=[self.prompt, self.image, apply_prompt, llm_model, prompt_system, prompt_prefix, prompt_suffix, max_tokens, do_sample, temperature, repetition_penalty, thinking_mode, nsfw_mode], outputs=[prompt_output, self.prompt])
|
||||
return [self.prompt, self.image, apply_auto, llm_model, prompt_system, prompt_prefix, prompt_suffix, max_tokens, do_sample, temperature, repetition_penalty, thinking_mode, nsfw_mode]
|
||||
|
||||
def after_component(self, component, **kwargs): # searching for actual ui prompt components
|
||||
if getattr(component, 'elem_id', '') in ['txt2img_prompt', 'img2img_prompt', 'control_prompt', 'video_prompt']:
|
||||
self.prompt = component
|
||||
self.prompt.use_original = True
|
||||
if getattr(component, 'elem_id', '') in ['img2img_image', 'control_input_select']:
|
||||
self.image = component
|
||||
self.image.use_original = True
|
||||
|
||||
def before_process(self, p: processing.StableDiffusionProcessing, *args, **kwargs): # pylint: disable=unused-argument
|
||||
_self_prompt, self_image, apply_auto, llm_model, prompt_system, prompt_prefix, prompt_suffix, max_tokens, do_sample, temperature, repetition_penalty, thinking_mode = args
|
||||
_self_prompt, self_image, apply_auto, llm_model, prompt_system, prompt_prefix, prompt_suffix, max_tokens, do_sample, temperature, repetition_penalty, thinking_mode, nsfw_mode = args
|
||||
if not apply_auto and not p.enhance_prompt:
|
||||
return
|
||||
if shared.state.skipped or shared.state.interrupted:
|
||||
@@ -481,6 +498,7 @@ class Script(scripts.Script):
|
||||
temperature=temperature,
|
||||
penalty=repetition_penalty,
|
||||
thinking=thinking_mode,
|
||||
nsfw=nsfw_mode,
|
||||
)
|
||||
p.extra_generation_params['LLM'] = llm_model
|
||||
shared.state.end()
|
||||
|
||||
@@ -86,8 +86,8 @@ class Script(scripts.Script):
|
||||
with gr.Row():
|
||||
gr.HTML('<a href="https://github.com/ToTheBeginning/PuLID">  PuLID: Pure and Lightning ID Customization</a><br>')
|
||||
with gr.Row():
|
||||
strength = gr.Slider(label = 'Strength', value = 0.8, mininimum = 0, maximum = 1, step = 0.01)
|
||||
zero = gr.Slider(label = 'Zero', value = 20, mininimum = 0, maximum = 80, step = 1)
|
||||
strength = gr.Slider(label = 'Strength', value = 0.8, minimum = 0, maximum = 1, step = 0.01)
|
||||
zero = gr.Slider(label = 'Zero', value = 20, minimum = 0, maximum = 80, step = 1)
|
||||
with gr.Row():
|
||||
sampler = gr.Dropdown(label="Sampler", value='dpmpp_sde', choices=['dpmpp_2m', 'dpmpp_2m_sde', 'dpmpp_2s_ancestral', 'dpmpp_3m_sde', 'dpmpp_sde', 'euler', 'euler_ancestral'])
|
||||
ortho = gr.Dropdown(label="Ortho", choices=['off', 'v1', 'v2'], value='v2')
|
||||
@@ -97,7 +97,7 @@ class Script(scripts.Script):
|
||||
restore = gr.Checkbox(label='Restore pipe on end', value=False)
|
||||
offload = gr.Checkbox(label='Offload face module', value=True)
|
||||
with gr.Row():
|
||||
files = gr.File(label='Input images', file_count='multiple', file_types=['image'], type='file', interactive=True, height=100)
|
||||
files = gr.File(label='Input images', file_count='multiple', file_types=['image'], interactive=True, height=100)
|
||||
with gr.Row():
|
||||
gallery = gr.Gallery(show_label=False, value=[], visible=False, container=False, rows=1)
|
||||
files.change(fn=self.load_images, inputs=[files], outputs=[gallery])
|
||||
|
||||
@@ -38,8 +38,8 @@ class Script(scripts.Script):
|
||||
mode = gr.Radio(label='Mode', choices=['None', 'Prompt', 'Prompt EX', 'Columns', 'Rows'], value='None')
|
||||
with gr.Row():
|
||||
power = gr.Slider(label='Power', minimum=0, maximum=1, value=1.0, step=0.01)
|
||||
threshold = gr.Textbox('', label='Prompt thresholds:', default='', visible=False)
|
||||
grid = gr.Text('', label='Grid sections:', default='', visible=False)
|
||||
threshold = gr.Textbox('', label='Prompt thresholds', visible=False)
|
||||
grid = gr.Textbox('', label='Grid sections', visible=False)
|
||||
mode.change(fn=self.change, inputs=[mode], outputs=[grid, threshold])
|
||||
return mode, grid, power, threshold
|
||||
|
||||
|
||||
@@ -51,7 +51,7 @@ class Script(scripts.Script):
|
||||
with gr.Row():
|
||||
prompt = gr.Textbox(lines=1, label='Optional image description', placeholder='use the style from the image')
|
||||
with gr.Row():
|
||||
image = gr.Image(label='Optional image', source='upload', type='pil')
|
||||
image = gr.Image(label='Optional image', type='pil')
|
||||
|
||||
image.change(self.reset)
|
||||
preset.change(self.preset, inputs=[preset], outputs=[shared_opts, shared_score_scale, shared_score_shift, only_self_level])
|
||||
|
||||
+1
-1
Submodule wiki updated: 12dbff5ca4...6192bb85f1
Reference in New Issue
Block a user