feat(mflux_image_edit): Qwen-Image-Edit LoRA support
mflux-generate-qwen-edit already exposes --lora-paths/--lora-scales; wire them to params.loras (['multiple-angles=1.0', ...]). Names resolve by filename stem or fuzzy match across QWEN_LORA_DIRS (default ~/Documents/localmodels/QwenLora) so John can drop new .safetensors in and use them by short name. Misses log loudly instead of failing the job. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
parent
03deb589c1
commit
431aeb08ea
@ -1,9 +1,30 @@
|
|||||||
import argparse
|
import argparse
|
||||||
import json
|
import json
|
||||||
|
import os
|
||||||
import subprocess
|
import subprocess
|
||||||
import sys
|
import sys
|
||||||
from pathlib import Path
|
from pathlib import Path
|
||||||
|
|
||||||
|
# Qwen-Image-Edit LoRA search path (name → file). Drop .safetensors anywhere under these and they
|
||||||
|
# become usable as {"loras": ["multiple-angles=1.0", ...]}. Same UX as sd_local's LoRA list.
|
||||||
|
QWEN_LORA_DIRS = [Path(os.path.expanduser(d)) for d in os.environ.get(
|
||||||
|
"QWEN_LORA_DIRS", "~/Documents/localmodels/QwenLora").split(":")]
|
||||||
|
|
||||||
|
|
||||||
|
def find_lora(stem: str):
|
||||||
|
"""Match by exact filename stem, else the first file whose stem contains it (case-insensitive)."""
|
||||||
|
stem = stem.strip()
|
||||||
|
cands = [f for d in QWEN_LORA_DIRS if d.is_dir() for f in d.rglob("*.safetensors")]
|
||||||
|
for f in cands:
|
||||||
|
if f.stem == stem:
|
||||||
|
return f
|
||||||
|
low = stem.lower()
|
||||||
|
for f in cands:
|
||||||
|
if low in f.stem.lower() or low in f.parent.name.lower():
|
||||||
|
return f
|
||||||
|
return None
|
||||||
|
|
||||||
|
|
||||||
ap = argparse.ArgumentParser()
|
ap = argparse.ArgumentParser()
|
||||||
ap.add_argument("--input", action="append", default=[])
|
ap.add_argument("--input", action="append", default=[])
|
||||||
ap.add_argument("--outdir", required=True)
|
ap.add_argument("--outdir", required=True)
|
||||||
@ -34,6 +55,20 @@ cmd = [str(cli), "--image-paths", *[str(Path(x).resolve()) for x in a.input],
|
|||||||
"--guidance", str(p.get("guidance", 4.0)),
|
"--guidance", str(p.get("guidance", 4.0)),
|
||||||
"--output", str(out.resolve())]
|
"--output", str(out.resolve())]
|
||||||
|
|
||||||
|
# optional LoRAs: ["multiple-angles=1.0", "gymnastics-pose=0.8"] → --lora-paths/--lora-scales
|
||||||
|
paths, scales = [], []
|
||||||
|
for spec in (p.get("loras") or []):
|
||||||
|
name, _, w = str(spec).partition("=")
|
||||||
|
f = find_lora(name)
|
||||||
|
if not f:
|
||||||
|
print(f"LORA MISS '{name}' — searched {[str(d) for d in QWEN_LORA_DIRS]}", flush=True)
|
||||||
|
continue
|
||||||
|
paths.append(str(f))
|
||||||
|
scales.append(str(float(w or 1.0)))
|
||||||
|
if paths:
|
||||||
|
cmd += ["--lora-paths", *paths, "--lora-scales", *scales]
|
||||||
|
print(f"loras: {list(zip(paths, scales))}", flush=True)
|
||||||
|
|
||||||
print("+", " ".join(cmd), flush=True)
|
print("+", " ".join(cmd), flush=True)
|
||||||
print("(first run downloads Qwen-Image-Edit weights)", flush=True)
|
print("(first run downloads Qwen-Image-Edit weights)", flush=True)
|
||||||
res = subprocess.run(cmd, cwd=str(outdir), stdout=sys.stdout, stderr=subprocess.STDOUT)
|
res = subprocess.run(cmd, cwd=str(outdir), stdout=sys.stdout, stderr=subprocess.STDOUT)
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user