""" INFERENCE.py — run PixelModel from its model.safetensors weights. This is the standalone entry point for anyone who just wants to load the safetensors weights and generate an image, without needing model.png or the rest of this repo's training code. Usage: python INFERENCE.py "a red circle" python INFERENCE.py "a red circle" --model model.safetensors --out out.png --scale 8 """ import argparse import os import sys import numpy as np import torch from PIL import Image from safetensors.torch import load_file PROMPT_DIM = 32 OUT_SIZE = 32 def prompt_to_embedding(prompt: str) -> torch.Tensor: """Deterministic char-level embedding -> PROMPT_DIM vector.""" vec = torch.zeros(PROMPT_DIM) for i, ch in enumerate(prompt.lower()): idx = i % PROMPT_DIM vec[idx] += ord(ch) / 127.0 norm = vec.norm() if norm > 0: vec = vec / norm return vec def forward(weights: dict, prompt: str) -> torch.Tensor: emb = prompt_to_embedding(prompt) x = torch.tanh(weights["W1"] @ emb) x = torch.tanh(weights["W2"] @ x) x = torch.sigmoid(weights["W3"] @ x) return x.reshape(OUT_SIZE, OUT_SIZE, 3) def generate(prompt: str, model_path: str, out_path: str, scale: int = 8): if not os.path.exists(model_path): sys.exit( f"Model not found: {model_path}\n" f"Run: python convert_to_safetensors.py to create one from model.png first." ) weights = load_file(model_path) with torch.no_grad(): result = forward(weights, prompt) arr = (result.numpy() * 255).clip(0, 255).astype(np.uint8) img = Image.fromarray(arr, mode="RGB") if scale > 1: img = img.resize((OUT_SIZE * scale, OUT_SIZE * scale), Image.NEAREST) img.save(out_path) print(f"prompt : '{prompt}'") print(f"model : {model_path} ({os.path.getsize(model_path)} bytes, safetensors)") print(f"output : {out_path} ({OUT_SIZE * scale}x{OUT_SIZE * scale} px)") if __name__ == "__main__": p = argparse.ArgumentParser(description="PixelModel inference (safetensors)") p.add_argument("prompt", help="Text prompt") p.add_argument("--model", default="model.safetensors", help="Path to safetensors weights") p.add_argument("--out", default="out.png", help="Output image path") p.add_argument("--scale", type=int, default=8, help="Upscale factor for output (default 8 -> 256x256)") args = p.parse_args() generate(args.prompt, args.model, args.out, args.scale)