|
Download README.md from shibatch/tinydigitdiffusion3m: direct link, hf CLI and curl.
- Browser
- Download file 8.15 kB
-
https://huggingface.co/shibatch/tinydigitdiffusion3m/resolve/main/README.md
- Command line
-
hf download hf://shibatch/tinydigitdiffusion3m/README.md
-
curl -L -o README.md https://huggingface.co/shibatch/tinydigitdiffusion3m/resolve/main/README.md
8.15 kB
| library_name: pytorch | |
| pipeline_tag: text-to-image | |
| license: mit | |
| datasets: | |
| - ylecun/mnist | |
| tags: | |
| - diffusion | |
| - ddim | |
| - mnist | |
| - handwritten-digits | |
| - tiny-model | |
| # Tiny Digit Diffusion 3M | |
| Tiny Digit Diffusion 3M is a **2,767,529-parameter** conditional diffusion | |
| model that renders a prompt containing one to eight ASCII digits as a | |
| handwritten grayscale image. It was trained from scratch on dynamically | |
| composed MNIST digit strings and contains no weights from another generative | |
| model. | |
| This is a deliberately narrow tiny-model experiment, not a general-purpose | |
| text-to-image model. Its complete prompt language is a numeric string such as | |
| `7`, `2026`, or `31415926`. | |
|  | |
| ## Repository contents | |
| - `model/model.safetensors`: FP32 EMA inference weights | |
| - `model/config.json`: architecture and diffusion configuration | |
| - `tiny_digit_diffusion.py`: model, schedule, DDIM sampler, and weight loader | |
| - `generate_tiny_digits.py`: command-line generation example | |
| - `train_tiny_digit_diffusion.py`: training script | |
| - `artifact_metadata.json`: training settings and evaluation summary | |
| - `sample_grid.png`: generations from the final checkpoint | |
| Optimizer checkpoints, MNIST files, per-epoch samples, and the training log are | |
| not included in the distribution package. | |
| ## Quick start | |
| Create an environment and install the inference dependencies: | |
| ```bash | |
| python -m venv .venv | |
| source .venv/bin/activate | |
| pip install -r requirements.txt | |
| ``` | |
| Generate an eight-digit image: | |
| ```bash | |
| python generate_tiny_digits.py 31415926 --output 31415926.png | |
| ``` | |
| On the first run, the script downloads `model/config.json` and | |
| `model/model.safetensors` from `shibatch/tinydigitdiffusion3m` on Hugging | |
| Face. Later runs reuse the local Hugging Face cache. | |
| The script accepts the following useful options: | |
| ```bash | |
| python generate_tiny_digits.py 2026 \ | |
| --steps 50 \ | |
| --guidance-scale 1.0 \ | |
| --seed 0 \ | |
| --device auto \ | |
| --output 2026.png | |
| ``` | |
| Use a different Hub revision with `--revision`, or override the repository | |
| with `--repo-id`. To use model files already stored locally (including the | |
| `model/` directory included in this distribution package), pass | |
| `--model-dir`: | |
| ```bash | |
| python generate_tiny_digits.py 2026 --model-dir ./model --output 2026.png | |
| ``` | |
| The output is a fixed `32 x 256` grayscale PNG. Short prompts are centered on | |
| the eight available 32-pixel slots. | |
| ## Python example | |
| ```python | |
| import sys | |
| from pathlib import Path | |
| import torch | |
| from huggingface_hub import snapshot_download | |
| from PIL import Image | |
| repo_dir = Path(snapshot_download( | |
| repo_id="shibatch/tinydigitdiffusion3m", | |
| allow_patterns=[ | |
| "model/config.json", | |
| "model/model.safetensors", | |
| "tiny_digit_diffusion.py", | |
| ], | |
| )) | |
| sys.path.insert(0, str(repo_dir)) | |
| from tiny_digit_diffusion import ddim_sample, load_model | |
| device = torch.device("cuda" if torch.cuda.is_available() else "cpu") | |
| model = load_model(repo_dir / "model", device) | |
| image = ddim_sample( | |
| model, | |
| prompts=["31415926"], | |
| device=device, | |
| sampling_steps=50, | |
| guidance_scale=1.0, | |
| seed=0, | |
| )[0, 0] | |
| pixels = ((image.cpu() + 1) * 127.5).round().clamp(0, 255).byte().numpy() | |
| Image.fromarray(pixels, mode="L").save("31415926.png") | |
| ``` | |
| Prompts must contain only one to eight ASCII digits. Spaces, signs, decimal | |
| points, letters, and strings longer than eight digits are rejected. | |
| ## Recommended inference settings | |
| ```yaml | |
| sampling_method: deterministic DDIM | |
| sampling_steps: 50 | |
| guidance_scale: 1.0 | |
| output_size: 32 x 256 | |
| ``` | |
| Use `guidance_scale=1.0`. Larger classifier-free-guidance values are not | |
| helpful for this checkpoint. In particular, the original diagnostic setting | |
| of `3.0` over-amplifies the conditioning difference and creates digit-like | |
| artifacts in padding slots. At `1.0`, the sampler uses the conditional model | |
| directly and skips the unnecessary unconditional pass. | |
| ## Architecture | |
| ```yaml | |
| model: custom conditional diffusion U-Net | |
| parameter_count: 2,767,529 | |
| weight_dtype: float32 | |
| weight_file_size: approximately 11 MB | |
| image_channels: 1 | |
| image_height: 32 | |
| image_width: 256 | |
| maximum_digits: 8 | |
| slot_width: 32 | |
| base_channels: 48 | |
| channel_multipliers: [1, 1.5, 2, 2.6667] | |
| embedding_dim: 192 | |
| token_embedding_dim: 32 | |
| spatial_condition_channels: 8 | |
| attention_heads: 4 | |
| diffusion_steps: 400 | |
| ``` | |
| The denoiser has four resolution levels with residual blocks, skip | |
| connections, a bottleneck self-attention layer, sinusoidal timestep | |
| conditioning, global prompt conditioning, and slot-aligned spatial digit | |
| conditioning. Prompt tokens consist of digits `0` through `9`, a padding token, | |
| and a classifier-free null token. | |
| ## Training | |
| Each training example was assembled dynamically from MNIST: | |
| 1. Sample a prompt length uniformly from one to eight digits. | |
| 2. Sample an MNIST image independently for every digit. | |
| 3. Center the string on a `32 x 256` canvas. | |
| 4. Apply small horizontal and vertical offsets and an intensity variation. | |
| 5. Train the model to predict noise at a random cosine-schedule timestep. | |
| Training configuration: | |
| ```yaml | |
| dtype: float32 | |
| epochs: 30 | |
| steps: 28,110 | |
| batch_size: 64 | |
| samples_processed: 1,799,040 | |
| optimizer: AdamW | |
| learning_rate: 2.0e-4 | |
| warmup_steps: 500 | |
| minimum_learning_rate: 2.0e-5 | |
| weight_decay: 0.0 | |
| gradient_clip: 1.0 | |
| condition_dropout: 0.1 | |
| ema_decay: 0.999 | |
| final_recent_noise_mse: 0.015345 | |
| training_time: approximately 70 minutes | |
| ``` | |
| The distributed checkpoint is the EMA model, not the raw final optimizer | |
| weights. | |
| To train from scratch, install the additional dependencies and choose an output | |
| directory: | |
| ```bash | |
| pip install -r requirements-train.txt | |
| python train_tiny_digit_diffusion.py \ | |
| --output-dir runs/tiny_digit_diffusion_3m \ | |
| --data-dir data/mnist \ | |
| --epochs 30 \ | |
| --batch-size 64 \ | |
| --device cuda | |
| ``` | |
| ## Evaluation | |
| A separate small MNIST classifier was trained only for automated readability | |
| measurement. It reached 98.68% accuracy on the MNIST test split. The final | |
| generator was then evaluated on 240 random prompts: 30 prompts for every length | |
| from one through eight digits, using 50 DDIM steps and guidance 1.0. | |
| | Prompt length | Exact string | Per-digit accuracy | | |
| |---:|---:|---:| | |
| | 1 | 29/30 (96.7%) | 96.7% | | |
| | 2 | 26/30 (86.7%) | 91.7% | | |
| | 3 | 26/30 (86.7%) | 95.6% | | |
| | 4 | 22/30 (73.3%) | 93.3% | | |
| | 5 | 22/30 (73.3%) | 93.3% | | |
| | 6 | 14/30 (46.7%) | 88.9% | | |
| | 7 | 22/30 (73.3%) | 95.7% | | |
| | 8 | 13/30 (43.3%) | 90.4% | | |
| | **Overall** | **174/240 (72.5%)** | **92.6%** | | |
| These are OCR-proxy measurements, not human ratings. A generated digit can be | |
| legible to a person while being classified differently, and the classifier can | |
| also be confidently wrong. The samples should therefore be considered | |
| alongside the numeric results. | |
| ## Limitations | |
| - Longer strings compound individual digit errors; eight-digit exact match is | |
| substantially lower than single-digit accuracy. | |
| - Some handwritten `3`, `5`, `7`, `8`, and `9` shapes can be ambiguous. | |
| - The output canvas and maximum string length are fixed by the architecture. | |
| - The model supports only ASCII digits and does not render signs, punctuation, | |
| decimal values, mathematical expressions, or arbitrary text. | |
| - This checkpoint reproduces MNIST-like handwriting only. It is not suitable | |
| for OCR security testing, document generation, or realistic typography. | |
| - Results vary with the random seed even though each DDIM trajectory is | |
| deterministic for a fixed seed. | |
| ## Scope | |
| This checkpoint is intended for education, architecture experiments, tests, | |
| and demonstrations of a complete conditional image generator at a very small | |
| parameter count. It should not be interpreted as an official MNIST model or as | |
| an image-generation counterpart of any production diffusion system. | |
| ## License | |
| The source code and model checkpoint in this package are released under the | |
| MIT License. See `LICENSE` for the complete terms. | |
| The MNIST images are not redistributed in this package. Training used MNIST | |
| through `torchvision`; the [MNIST dataset card](https://huggingface.co/datasets/ylecun/mnist) | |
| identifies its license as MIT and credits Yann LeCun, Corinna Cortes, and | |
| Christopher J. C. Burges as the dataset curators. | |