diff options
| -rwxr-xr-x | fanfictioner | 11 |
1 files changed, 10 insertions, 1 deletions
diff --git a/fanfictioner b/fanfictioner index 9917540..db801bc 100755 --- a/fanfictioner +++ b/fanfictioner @@ -436,7 +436,9 @@ def run_sd(args, log, preview=None): print() if viewer: viewer.terminate() - if proc.returncode or "[ERROR" in Path(log).read_text(errors="replace"): + out = Path(log).read_text(errors="replace") + # sd-cli also logs [ERROR for steps it recovers from (Qwen prefix caching): every image saved wins. + if proc.returncode or ("[ERROR" in out and not re.search(r"\b(\d+)/\1 images saved", out)): return f"sd-cli failed (exit {proc.returncode})" return None @@ -484,6 +486,11 @@ def generate(d, profile, prompt, size, refs=()): preview.unlink(missing_ok=True) args += ["--preview", "proj", "--preview-path", str(preview)] err = run_sd(args, log, preview) + if err and "cannot make enough memory" in log.read_text(errors="replace"): + # ponytail: fixed 5 GB budget, fits a Qwen edit beside the desktop but streams weights, + # ~12 min per candidate; closing VRAM-heavy apps avoids this path. + print("out of VRAM, retrying with a 5 GB budget (slow) ...", flush=True) + err = run_sd(args + ["--max-vram", "vulkan0=5"], log, preview) files = [d / f"{seed}_{i}.png" for i in (1, 2, 3)] if not err and not all(f.exists() for f in files): err = "sd-cli wrote no output" @@ -901,6 +908,8 @@ def selftest(): assert run_sd(["true"], t / "ok.log") is None assert (t / "ok.log").read_text().startswith("true") assert run_sd(["sh", "-c", "echo '[ERROR] boom'"], t / "e.log") == "sd-cli failed (exit 0)" + assert run_sd(["sh", "-c", "echo '[ERROR] boom'; echo '3/3 images saved'"], t / "r.log") is None + assert run_sd(["sh", "-c", "echo '[ERROR] boom'; echo '1/3 images saved'"], t / "p.log") assert run_sd(["false"], t / "f.log") == "sd-cli failed (exit 1)" assert run_sd(["/nonexistent-sd-cli"], t / "n.log").startswith("cannot run /nonexistent-sd-cli") global LOG |
