aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDanilo M. <danix@danix.xyz>2026-10-05 09:36:42 +0200
committerDanilo M. <danix@danix.xyz>2026-10-05 09:36:42 +0200
commit04cae51db97e20e24a53e1183dc18d5ea993f873 (patch)
tree04bcbc595f4c1918edeab725656882b4e7026482
parent5a757cd11c43c1225af03c6ad6c56531dac986e2 (diff)
downloadfanfictioner-04cae51db97e20e24a53e1183dc18d5ea993f873.tar.gz
fanfictioner-04cae51db97e20e24a53e1183dc18d5ea993f873.zip
Add model profiles and sd-cli argument building
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
-rwxr-xr-xfanfictioner57
1 files changed, 57 insertions, 0 deletions
diff --git a/fanfictioner b/fanfictioner
index 888d06e..8f5764b 100755
--- a/fanfictioner
+++ b/fanfictioner
@@ -34,6 +34,32 @@ LLM_MODEL = "Gemma4-12B-qat-mtp"
SD_DIR = Path("/data/LLM-models/SD")
CONF = Path.home() / ".config/book-reader.conf"
+# Settings verified by hand on 2026-10-04 (Krea2 re-checked against upstream on 2026-10-05).
+# Model paths are relative to SD_DIR. All profiles run at cfg 1.0, so no negative prompts.
+PROFILES = {
+ "zimage": ["--diffusion-model", "z_image_turbo-Q8_0.gguf",
+ "--vae", "vae/flux1-ae.safetensors",
+ "--llm", "Qwen3-4B-Instruct-2507-Q8_0.gguf",
+ "--cfg-scale", "1.0", "--steps", "8", "--diffusion-fa", "--offload-to-cpu"],
+ "krea2": ["--diffusion-model", "Krea-2-Turbo-Q6_K.gguf",
+ "--vae", "vae/wan_2.1_vae.safetensors",
+ "--llm", "Qwen3VL-4B-Instruct-Q8_0.gguf",
+ "--cfg-scale", "1.0", "--steps", "8", "--diffusion-fa", "--offload-to-cpu"],
+ # te=cpu alone puts diffusion on the iGPU and crashes: always name all three backends.
+ # --offload-to-cpu here OOM-killed the desktop: never add it.
+ "qwen_edit": ["--diffusion-model", "Qwen-Image-2.1-viggle-turbo-v0.3-6step-Q8_0.gguf",
+ "--vae", "vae/qwen_image_2.1_vae_bf16.safetensors",
+ "--llm", "Qwen3VL-8B-Instruct-Q8_0.gguf",
+ "--llm_vision", "mmproj-Qwen3VL-8B-Instruct-F16.gguf",
+ "--cfg-scale", "1.0", "--steps", "6",
+ "--sigmas", "1.0,0.9375,0.875,0.75,0.5,0.25,0.0", "--sampling-method", "euler",
+ "--fa", "--backend", "te=cpu,diffusion=vulkan0,vae=vulkan0", "--mmap", "--vae-tiling"],
+}
+MODEL_FLAGS = {"--diffusion-model", "--vae", "--llm", "--llm_vision"}
+SIZES = {"portrait": (832, 1216), "landscape": (1216, 832), "turnaround": (1216, 832)}
+# Edit inputs are shrunk first: full-size refs blow past 12 GB VRAM.
+SHRINK = {"portrait": "576x832", "landscape": "832x576", "ref": "560x384"}
+
def load_conf(path=CONF):
conf = {}
@@ -178,6 +204,20 @@ def check_json(pj, plan):
return errs
+def sd_args(profile, prompt, out, size, seed, refs=()):
+ args = ["sd-cli"]
+ it = iter(PROFILES[profile])
+ for x in it:
+ args.append(x)
+ if x in MODEL_FLAGS:
+ args.append(str(SD_DIR / next(it)))
+ args += ["-p", prompt, "-W", str(size[0]), "-H", str(size[1]), "-s", str(seed),
+ "-b", "3", "-o", str(out), "--output-begin-idx", "1"]
+ for r in refs:
+ args += ["-r", str(r)]
+ return args
+
+
def selftest():
plan = parse_plan(SAMPLE_PLAN)
assert (plan["title"], plan["series"], plan["book"]) == ("Rooftop", "Test Series", "Book One"), plan
@@ -222,6 +262,23 @@ def selftest():
short = json.loads(json.dumps(good))
del short["characters"][2], short["pages"][1]
assert check_json(short, plan) == ["characters differ from plan.md", "pages differ from plan.md"]
+ q = sd_args("qwen_edit", "edit it", Path("c/7_%d.png"), (832, 1216), 7,
+ [Path("in1.png"), Path("mara.png")])
+ assert q[0] == "sd-cli"
+ assert q[q.index("--diffusion-model") + 1] == str(SD_DIR / "Qwen-Image-2.1-viggle-turbo-v0.3-6step-Q8_0.gguf")
+ assert q[q.index("--llm_vision") + 1] == str(SD_DIR / "mmproj-Qwen3VL-8B-Instruct-F16.gguf")
+ assert q[q.index("--backend") + 1] == "te=cpu,diffusion=vulkan0,vae=vulkan0"
+ assert "--offload-to-cpu" not in q
+ assert q[q.index("-r") + 1] == "in1.png" and q.count("-r") == 2
+ for flag, val in (("-p", "edit it"), ("-W", "832"), ("-H", "1216"), ("-s", "7"), ("-b", "3"),
+ ("-o", "c/7_%d.png"), ("--output-begin-idx", "1"), ("--steps", "6")):
+ assert q[q.index(flag) + 1] == val, (flag, q)
+ z = sd_args("zimage", "x", Path("o_%d.png"), SIZES["turnaround"], 1)
+ assert "--offload-to-cpu" in z and "-r" not in z
+ assert z[z.index("--vae") + 1] == str(SD_DIR / "vae/flux1-ae.safetensors")
+ k = sd_args("krea2", "x", Path("o_%d.png"), SIZES["portrait"], 1)
+ assert k[k.index("--llm") + 1] == str(SD_DIR / "Qwen3VL-4B-Instruct-Q8_0.gguf")
+ assert k[k.index("--steps") + 1] == "8" and k[k.index("--cfg-scale") + 1] == "1.0"
with tempfile.TemporaryDirectory() as t:
t = Path(t)
(t / "c.conf").write_text('# comment\nLIBRARY="/data/my lib"\nPORT=8642\n')