Tarul commited on
Commit
181c7ca
·
verified ·
1 Parent(s): eb61853

Upload cli.py with huggingface_hub

Browse files
Files changed (1) hide show
  1. cli.py +123 -0
cli.py ADDED
@@ -0,0 +1,123 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ #!/usr/bin/env python3
2
+ """PXG-Tiny CLI (offline, NumPy-only).
3
+
4
+ python3 cli.py "a golden sword" -o sword.png
5
+ python3 cli.py "a golden sword" --variations 4 --sheet row.png
6
+ python3 cli.py --ask "can you draw a photo of a cat"
7
+ python3 cli.py --sheet-from-prompts prompts.txt --outdir sprites/
8
+ """
9
+ import argparse
10
+ import json
11
+ import sys
12
+ from pathlib import Path
13
+
14
+ ROOT = Path(__file__).resolve().parents[0]
15
+ sys.path.insert(0, str(ROOT / "src"))
16
+
17
+ from PIL import Image # noqa: E402
18
+
19
+ from pxg_tiny import config as C # noqa: E402
20
+ from pxg_tiny.pipeline import PXGPipeline # noqa: E402
21
+
22
+
23
+ def sheet(grids, path, scale=8):
24
+ n = len(grids)
25
+ im = Image.new("RGBA", (n * (16 * scale + 4) + 4, 16 * scale + 8),
26
+ (24, 24, 30, 255))
27
+ from pxg_tiny.render import grid_to_rgba
28
+ for i, g in enumerate(grids):
29
+ tile = Image.fromarray(grid_to_rgba(g), "RGBA").resize(
30
+ (16 * scale, 16 * scale), Image.NEAREST)
31
+ im.paste(tile, (4 + i * (16 * scale + 4), 4), tile)
32
+ im.save(path)
33
+
34
+
35
+ def main():
36
+ ap = argparse.ArgumentParser(prog="pxg-tiny")
37
+ ap.add_argument("prompt", nargs="?")
38
+ ap.add_argument("-o", "--out", default=None)
39
+ ap.add_argument("--seed", type=int, default=0)
40
+ ap.add_argument("--temperature", type=float, default=None)
41
+ ap.add_argument("--top-k", type=int, default=None)
42
+ ap.add_argument("--variations", type=int, default=1)
43
+ ap.add_argument("--sheet", action="store_true",
44
+ help="save a variations sheet next to the png")
45
+ ap.add_argument("--sheet-from-prompts", default=None,
46
+ help="path to a text file with one prompt per line; "
47
+ "renders every prompt into --outdir")
48
+ ap.add_argument("--outdir", default=None,
49
+ help="output directory for --sheet-from-prompts")
50
+ ap.add_argument("--ask", action="store_true",
51
+ help="ask-first mode: clarify/refuse instead of drawing")
52
+ ap.add_argument("--bundle", default=str(ROOT / "weights"))
53
+ ap.add_argument("--no-quality", action="store_true",
54
+ help="disable the grounding auto-retry gate")
55
+ args = ap.parse_args()
56
+
57
+ if args.sheet_from_prompts:
58
+ outdir = Path(args.outdir or "pxg_batch_out")
59
+ outdir.mkdir(parents=True, exist_ok=True)
60
+ lines = [l.strip() for l in Path(args.sheet_from_prompts)
61
+ .read_text().splitlines() if l.strip()]
62
+ pipe = PXGPipeline(args.bundle)
63
+ grids = []
64
+ results = []
65
+ for i, p in enumerate(lines):
66
+ g, m = pipe.generate_pixels(p, seed=args.seed,
67
+ enforce_quality=not args.no_quality,
68
+ temperature=args.temperature,
69
+ top_k=args.top_k)
70
+ results.append({"prompt": p, "gate": m.get("gate")})
71
+ if g is None:
72
+ print(json.dumps({"i": i, "prompt": p, **m}, indent=2))
73
+ continue
74
+ from pxg_tiny.render import save_png
75
+ f = outdir / f"{i+1:02d}_{p.replace(' ', '_')[:24]}.png"
76
+ save_png(g, f, scale=8)
77
+ grids.append(g)
78
+ results[-1]["file"] = str(f)
79
+ if grids:
80
+ sheet(grids, outdir / "sheet.png")
81
+ print(json.dumps({"n_prompts": len(lines), "n_rendered": len(grids),
82
+ "outdir": str(outdir), "results": results}, indent=2))
83
+ return
84
+
85
+ if not args.prompt:
86
+ ap.error("give me a prompt, e.g. pxg-tiny \"a gold sword\"")
87
+
88
+ pipe = PXGPipeline(args.bundle)
89
+
90
+ if args.ask:
91
+ label, msg = pipe.should_ask(args.prompt)
92
+ print(json.dumps({"label": label, "message": msg}, indent=2))
93
+ return
94
+
95
+ out = Path(args.out) if args.out else Path(
96
+ args.prompt.replace(" ", "_")[:24].replace("/", "_") + ".png")
97
+ out.parent.mkdir(parents=True, exist_ok=True)
98
+
99
+ grids, metas = [], []
100
+ if args.variations > 1:
101
+ res = pipe.variations(args.prompt, k=args.variations,
102
+ start_seed=args.seed,
103
+ enforce_quality=not args.no_quality,
104
+ temperature=args.temperature, top_k=args.top_k)
105
+ grids = [g for g, _ in res if g is not None]
106
+ metas = [m for _, m in res]
107
+ else:
108
+ g, m = pipe.generate_pixels(args.prompt, seed=args.seed,
109
+ temperature=args.temperature,
110
+ top_k=args.top_k,
111
+ enforce_quality=not args.no_quality)
112
+ if g is None:
113
+ print(json.dumps(m, indent=2))
114
+ return
115
+ grids, metas = [g], [m]
116
+
117
+ sheet(grids, out)
118
+ print(json.dumps({"prompt": args.prompt, "out": str(out),
119
+ "n": len(grids), "meta": metas[0]}, indent=2))
120
+
121
+
122
+ if __name__ == "__main__":
123
+ main()