Text-to-Image
English
numpy
machine-learning
deep-learning
generative-ai
text-2-image
image-generation
open-weights
model-weights
ai-art
pixel-art
game-development
gamedev
game-assets
asset-generator
sprite-generator
offline
tiny-model
numpy-runtime
int8-quantization
self-supervised
procedural-data
gpt
english-prompts
awesome-ai
Upload pxg_tiny/config.py with huggingface_hub
Browse files- pxg_tiny/config.py +121 -0
pxg_tiny/config.py
ADDED
|
@@ -0,0 +1,121 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
"""PXG-Tiny shared configuration: master palette, tokenizer, classes, model dims.
|
| 2 |
+
|
| 3 |
+
Single source of truth imported by both the training pipeline and the
|
| 4 |
+
inference runtime. All sprites are represented as 16x16 grids of *master
|
| 5 |
+
palette indices* (0 = fully transparent alpha, 1..31 = opaque colors).
|
| 6 |
+
This makes reconstruction byte-exact by construction and keeps the
|
| 7 |
+
generation vocabulary tiny (32 visual symbols).
|
| 8 |
+
"""
|
| 9 |
+
|
| 10 |
+
IMG = 16 # sprite resolution (16x16, even, inside the 8..256 schema band)
|
| 11 |
+
N_COLORS = 32 # visual vocabulary size: index 0 = transparent, 1..31 colors
|
| 12 |
+
|
| 13 |
+
# ---------------------------------------------------------------------------
|
| 14 |
+
# Master palette (index -> RGBA). Hand-crafted to span the classic
|
| 15 |
+
# warm_fantasy / nes / cool_sci_fi flavor families while staying <= 31 opaque
|
| 16 |
+
# colors so a single byte encodes any pixel.
|
| 17 |
+
# ---------------------------------------------------------------------------
|
| 18 |
+
PALETTE = {
|
| 19 |
+
1: (248, 248, 248), # white / specular
|
| 20 |
+
2: (217, 221, 230), # pale gray
|
| 21 |
+
3: (183, 191, 204), # silver
|
| 22 |
+
4: (120, 129, 142), # gray
|
| 23 |
+
5: (69, 76, 87), # charcoal
|
| 24 |
+
6: (23, 23, 31), # ink (outline black)
|
| 25 |
+
7: (212, 61, 51), # red
|
| 26 |
+
8: (140, 35, 32), # maroon
|
| 27 |
+
9: (232, 137, 46), # orange / terracotta
|
| 28 |
+
10: (242, 193, 46), # gold
|
| 29 |
+
11: (255, 232, 107), # lemon (gold highlight)
|
| 30 |
+
12: (127, 201, 79), # lime
|
| 31 |
+
13: (76, 154, 68), # green mid
|
| 32 |
+
14: (44, 106, 53), # forest dark
|
| 33 |
+
15: (55, 179, 171), # teal
|
| 34 |
+
16: (159, 223, 240), # ice / cyan highlight
|
| 35 |
+
17: (79, 147, 220), # sky blue
|
| 36 |
+
18: (45, 71, 127), # navy deep
|
| 37 |
+
19: (124, 80, 173), # purple
|
| 38 |
+
20: (180, 140, 224), # light violet
|
| 39 |
+
21: (168, 123, 35), # bronze (dark gold)
|
| 40 |
+
22: (242, 203, 160), # peach
|
| 41 |
+
23: (221, 182, 113), # sand
|
| 42 |
+
24: (244, 230, 192), # cream ivory
|
| 43 |
+
25: (165, 116, 74), # tan wood
|
| 44 |
+
26: (122, 78, 42), # brown mid
|
| 45 |
+
27: (76, 48, 26), # dark wood
|
| 46 |
+
28: (111, 117, 57), # moss olive
|
| 47 |
+
29: (185, 230, 197), # mint pale (slime)
|
| 48 |
+
30: (93, 114, 136), # steel blue-gray
|
| 49 |
+
31: (238, 173, 174), # blush soft pink
|
| 50 |
+
}
|
| 51 |
+
|
| 52 |
+
# ---------------------------------------------------------------------------
|
| 53 |
+
# Text tokenizer (char-level with byte-fallback buckets).
|
| 54 |
+
# id 0 = <pad>, 1 = <bos>, 2 = <sep>, 3..6 punctuation, 7..32 a-z,
|
| 55 |
+
# 33..62 byte-fallback buckets (ord % 30 + 33), 63 spare.
|
| 56 |
+
# Deterministic, lossless round-trip on the supported charset; any other
|
| 57 |
+
# Unicode character folds into its byte-fallback bucket (documented lossy
|
| 58 |
+
# fold for exotic input, mirrors the "byte fallback" philosophy of the big
|
| 59 |
+
# sibling project).
|
| 60 |
+
# ---------------------------------------------------------------------------
|
| 61 |
+
CHARSET = "abcdefghijklmnopqrstuvwxyz ,:-:'"
|
| 62 |
+
PAD_ID, BOS_ID, SEP_ID = 0, 1, 2
|
| 63 |
+
_TEXT_VOCAB = 64 # total text-side embedding width
|
| 64 |
+
CAP_LEN = 32 # fixed padded caption slot count (incl. <pad>)
|
| 65 |
+
PREFIX_LEN = 8 # intent-encoder output prefix vectors fed to decoder
|
| 66 |
+
|
| 67 |
+
|
| 68 |
+
def encode_char(c: str) -> int:
|
| 69 |
+
if c == " ": return 3
|
| 70 |
+
if c == ",": return 4
|
| 71 |
+
if c == "-": return 5
|
| 72 |
+
if c == ":": return 6
|
| 73 |
+
if "a" <= c <= "z":
|
| 74 |
+
return 7 + ord(c) - ord("a")
|
| 75 |
+
if c == "'": return 39
|
| 76 |
+
# byte fallback bucket for anything else (digits, unicode, etc.)
|
| 77 |
+
fb = c.encode("utf-8", "replace")[0] # first UTF-8 byte as int
|
| 78 |
+
return 33 + (fb % 30)
|
| 79 |
+
|
| 80 |
+
|
| 81 |
+
def decode_char(i: int):
|
| 82 |
+
if i == 3: return " "
|
| 83 |
+
if i == 4: return ","
|
| 84 |
+
if i == 5: return "-"
|
| 85 |
+
if i == 6: return ":"
|
| 86 |
+
if 7 <= i <= 32: return chr(ord("a") + i - 7)
|
| 87 |
+
if i == 39: return "'"
|
| 88 |
+
if 33 <= i <= 38 or 40 <= i <= 62: return "?" # fallback bucket: unknown glyph
|
| 89 |
+
return None # control specials
|
| 90 |
+
|
| 91 |
+
|
| 92 |
+
def encode_caption(text: str):
|
| 93 |
+
"""text -> list of CAP_LEN ids, left-padded slot layout:
|
| 94 |
+
[<pad>...]<chars>. No <bos>/<sep> needed: the prefix encoder consumes the
|
| 95 |
+
whole 32-slot window positionally."""
|
| 96 |
+
ids = [encode_char(c) for c in text.lower()][:CAP_LEN]
|
| 97 |
+
return [PAD_ID] * (CAP_LEN - len(ids)) + ids
|
| 98 |
+
|
| 99 |
+
|
| 100 |
+
def decode_caption(ids) -> str:
|
| 101 |
+
out = []
|
| 102 |
+
for i in ids:
|
| 103 |
+
c = decode_char(int(i))
|
| 104 |
+
if c is not None:
|
| 105 |
+
out.append(c)
|
| 106 |
+
return "".join(out).strip()
|
| 107 |
+
|
| 108 |
+
|
| 109 |
+
# ---------------------------------------------------------------------------
|
| 110 |
+
# Generation model geometry (extremely tiny on purpose).
|
| 111 |
+
# ---------------------------------------------------------------------------
|
| 112 |
+
D_MODEL = 96
|
| 113 |
+
N_LAYERS = 4
|
| 114 |
+
N_HEADS = 4 # 24-dim heads
|
| 115 |
+
FF_HIDDEN = 256 # ffn_mult ~= 2.7 (lean by design)
|
| 116 |
+
SEQ_VIS = IMG * IMG # 256 autoregressive visual positions
|
| 117 |
+
POS_TOTAL = PREFIX_LEN + SEQ_VIS # 264 learned positions
|
| 118 |
+
|
| 119 |
+
SAMPLING = {"temperature": 0.85, "top_k": 10}
|
| 120 |
+
|
| 121 |
+
APPROX_PARAMS = 483_040 # exact: encoder + 4-block decoder + heads
|