| """PixelModel v3 inference from model.safetensors (standalone). |
| |
| Needs only: model.safetensors, model.py, vocab.json, torch. No model.png, |
| no config.json - the architecture config is read from the safetensors header. |
| Produces output identical to main.py for the same prompt and resolution. |
| |
| python convert_to_safetensors.py |
| python INFERENCE.py "a red double decker bus" --out bus.png |
| """ |
|
|
| from __future__ import annotations |
|
|
| import argparse |
| import json |
|
|
| import numpy as np |
| import torch |
| from PIL import Image |
| from safetensors import safe_open |
|
|
| from model import ( |
| ModelConfig, PixelModelV3, load_vocab, encode_caption, make_coord_grid, |
| ) |
|
|
|
|
| def load_from_safetensors(path, device): |
| with safe_open(path, framework="pt", device="cpu") as f: |
| meta = f.metadata() or {} |
| cfg = ModelConfig.from_json(json.loads(meta["config"])) |
| model = PixelModelV3(cfg) |
| state = {k: f.get_tensor(k) for k in f.keys()} |
| model.load_state_dict(state) |
| model.to(device).eval() |
| return model, cfg |
|
|
|
|
| def main(): |
| ap = argparse.ArgumentParser() |
| ap.add_argument("prompt") |
| ap.add_argument("--out", default="out.png") |
| ap.add_argument("--res", type=int, default=128) |
| ap.add_argument("--safetensors", default="model.safetensors") |
| ap.add_argument("--vocab", default="vocab.json") |
| ap.add_argument("--device", default="cpu") |
| args = ap.parse_args() |
|
|
| model, cfg = load_from_safetensors(args.safetensors, args.device) |
| vocab = load_vocab(args.vocab) |
|
|
| tokens = encode_caption(args.prompt, vocab, cfg.max_tokens) |
| tokens = torch.from_numpy(tokens).long().unsqueeze(0).to(args.device) |
| coords = make_coord_grid(args.res, args.res, device=args.device, |
| dtype=torch.float32).unsqueeze(0) |
| with torch.no_grad(): |
| rgb = model(tokens, coords) |
| img = (rgb.clamp(0, 1).reshape(args.res, args.res, 3).cpu().numpy() * 255.0 |
| ).round().astype(np.uint8) |
| Image.fromarray(img, "RGB").save(args.out) |
| print(f'[inference] "{args.prompt}" @ {args.res}x{args.res} -> {args.out}') |
|
|
|
|
| if __name__ == "__main__": |
| main() |
|
|