| |
| """Generate a handwritten 1-8 digit image from a numeric prompt.""" |
|
|
| from __future__ import annotations |
|
|
| import argparse |
| from pathlib import Path |
|
|
| import torch |
| from PIL import Image |
|
|
| from tiny_digit_diffusion import ddim_sample, load_model |
|
|
| DEFAULT_REPO_ID = "shibatch/tinydigitdiffusion3m" |
|
|
|
|
| def parse_args() -> argparse.Namespace: |
| parser = argparse.ArgumentParser() |
| parser.add_argument("prompt", help="A numeric prompt containing 1-8 digits, for example 2026.") |
| parser.add_argument( |
| "--model-dir", |
| default=None, |
| help="Local model directory. If omitted, download the model from Hugging Face.", |
| ) |
| parser.add_argument("--repo-id", default=DEFAULT_REPO_ID) |
| parser.add_argument("--revision", default="main") |
| parser.add_argument("--output", default="generated_digits.png") |
| parser.add_argument("--steps", type=int, default=50) |
| parser.add_argument("--guidance-scale", type=float, default=1.0) |
| parser.add_argument("--seed", type=int, default=0) |
| parser.add_argument("--device", choices=["auto", "cpu", "cuda"], default="auto") |
| return parser.parse_args() |
|
|
|
|
| def resolve_model_dir( |
| model_dir: str | None, |
| repo_id: str, |
| revision: str, |
| ) -> Path: |
| if model_dir is not None: |
| return Path(model_dir).expanduser().resolve() |
|
|
| from huggingface_hub import snapshot_download |
|
|
| snapshot_dir = snapshot_download( |
| repo_id=repo_id, |
| revision=revision, |
| allow_patterns=["model/config.json", "model/model.safetensors"], |
| ) |
| return Path(snapshot_dir) / "model" |
|
|
|
|
| def main() -> None: |
| args = parse_args() |
| device = torch.device( |
| "cuda" if args.device == "auto" and torch.cuda.is_available() else |
| "cpu" if args.device == "auto" else args.device |
| ) |
| model_dir = resolve_model_dir(args.model_dir, args.repo_id, args.revision) |
| model = load_model(model_dir, device) |
| image = ddim_sample( |
| model, |
| [args.prompt], |
| device, |
| sampling_steps=args.steps, |
| guidance_scale=args.guidance_scale, |
| seed=args.seed, |
| )[0, 0] |
| pixels = ((image.cpu() + 1) * 127.5).round().clamp(0, 255).byte().numpy() |
| output = Path(args.output) |
| output.parent.mkdir(parents=True, exist_ok=True) |
| Image.fromarray(pixels, mode="L").save(output) |
| print(output.resolve()) |
|
|
|
|
| if __name__ == "__main__": |
| main() |
|
|