aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rwxr-xr-xfanfictioner11
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