Model Card for CanvasVAE¶
This package ports CanvasVAE, a variational autoencoder for vector graphic documents, into a 🤗transformers-style package for training and layout generation. RICO full-run parity is confirmed: an independent, from-scratch held-out run in normal mode passed all five staged checks under calibrated limits, from static initialization through training outputs and optimizer updates to production-loader replay (S0–S4). The three-seed RICO evaluation comparison also passes all three primary metrics. Crello remains blocked and unclaimed.
The original and package each completed three 500-epoch RICO runs and pass the predeclared comparison rule on 5,623 test layouts for the reconstruction score (Sreconst, mean BLEU-1 across fields and test layouts), layout mIoU (mean class intersection-over-union on rasterized component maps), and generated-layout score (Sgen, mean histogram intersection for generated-layout field and element-count distributions against RICO); each Sgen value averages three evaluation seeds. TRAINING.md gives per-run results, the comparison rule, evaluation scope, calibration, and reproduction commands.
Model Details¶
Model Description¶
CanvasVAE encodes a layout, meaning a sequence of up to 50 UI elements, into a 256-dimensional latent code with a transformer encoder, and decodes a latent code back into the element count and every element field in one pass. Each RICO element has a position and size discretized into 64 bins over the canvas, a component label, an icon class, a text_button class, and a clickable flag. Sampling the latent code from a standard normal prior generates new layouts. The pipeline returns normalized center xywh boxes in [0, 1], component ids as labels, a valid-element mask, and id2label.
- Developed by: Kota Yamaguchi.
- Shared by: creative-graphic-design.
- Model type: content-agnostic; task: single-task; conditioning: unconditional.
- Language(s) (NLP): not applicable.
- License: Apache-2.0.
Model Sources¶
- Repository: CanvasVAE repository
- Paper: ICCV 2021 paper page
- Released weights: none; this package trains its own checkpoints.
Supported Checkpoints¶
| Checkpoint | Hub ID | Status |
|---|---|---|
| RICO | creative-graphic-design/canvas-vae-rico |
not-published |
RICO full-run parity is complete: an independent held-out normal-mode run passed the calibrated S0–S4 checks, and the three-seed S5 comparison passed all primary metrics. The corrected package checkpoints passed the final-epoch gate at epoch 499 and global step 22,500; all package outputs from before that correction are excluded. Model weights are not published. Crello remains blocked and unclaimed because it requires a separately trained image encoder. See TRAINING.md for the full evidence.
Uses¶
Direct Use¶
Use this package to train CanvasVAE on RICO, to generate UI layouts from the prior, and to reconstruct layouts through CanvasVAEModel.
condition_type |
Required inputs | Effect |
|---|---|---|
unconditional |
none | samples latent codes and decodes layouts |
label, label_size, completion, refinement, text, content_image, relation, hierarchical, retrieval |
not applicable | raises NotImplementedError |
Downstream Use¶
Generated layouts may feed UI prototyping, layout evaluation, or retrieval by latent code after task-specific validation.
Out-of-Scope Use¶
Do not treat generated layouts as accessibility annotations, semantic screen understanding, or license-cleared design assets without separate review.
Bias, Risks, and Limitations¶
The model learns from RICO Android screens collected in 2017; layouts of other platforms, languages, or design eras are outside its training distribution. Element geometry is quantized to 64 bins, so generated boxes snap to a coarse grid.
Recommendations¶
Rerun the agreement checks in REPRODUCING.md after changing the model, losses, optimizer, or data pipeline.
How to Get Started with the Model¶
Install the package directly from this repository. The command includes the shared laygen package because it is not published on PyPI.
pip install \
"laygen @ git+https://github.com/creative-graphic-design/design-generators.git#subdirectory=lib/laygen" \
"canvas-vae @ git+https://github.com/creative-graphic-design/design-generators.git#subdirectory=models/canvas-vae"
Clone this repository, install the workspace member, and prepare RICO and a checkpoint with REPRODUCING.md or TRAINING.md. The conversion step there creates .cache/canvas-vae/converted/initial. The snippet below loads those untrained starting weights as a wiring check, so its layouts are not meaningful; a trained checkpoint needs the full training run in TRAINING.md.
git clone https://github.com/creative-graphic-design/design-generators.git
cd design-generators
uv sync --package canvas-vae
uv run --package canvas-vae python
from canvas_vae import CanvasVAEPipeline
path = ".cache/canvas-vae/converted/initial"
# After Hub publication: from_pretrained("creative-graphic-design/canvas-vae-rico")
pipe = CanvasVAEPipeline.from_pretrained(path)
out = pipe(batch_size=4, seed=0)
print(out.bbox.shape)
print(out.labels.shape)
print(out.id2label[int(out.labels[out.mask][0])])
torch.Size([4, 49, 4])
torch.Size([4, 49])
Modal
Training Details¶
Training Data¶
| Dataset | Dataset ID | Notes |
|---|---|---|
| RICO | creative-graphic-design/Rico |
Training reads the original semantic-annotation archive because its content-hash split and textButtonClass field are not in the hosted configuration. |
Training Procedure¶
TRAINING.md documents the LightningCLI configs and the staged agreement evidence against the original trainer.
Preprocessing¶
scripts/prepare_rico.py deduplicates identical annotation files, flattens each view hierarchy in depth-first pre-order, drops screens with more than 50 elements, and assigns 10% validation and 10% test splits by an MD5 content hash. Lookup tables keep component values seen at least once and icon and text_button values seen at least 500 times.
Training Hyperparameters¶
- Training regime: fp32, batch size 1024, 500 epochs of 45 batches, Adam with learning rate 1e-3 and per-tensor gradient-norm clipping at 1.0, KL weight 16, and L2 weight 1e-6.
Speeds, Sizes, Times¶
The model has 1,558,435 trainable parameters. Full-run training time has not been measured yet.
Evaluation¶
Testing Data, Factors & Metrics¶
Testing Data¶
Agreement checks use data exported from the original trainer's RICO stream, with a different population per stage. S0's forward check, S1, and S2 use the first training batch of 1,024 layouts. S3 uses the first 50 training batches: the natural trajectory trains on all 50, and the synchronized diagnostic checks 49 steps. S4 compares all 45,222 / 5,584 / 5,623 train/validation/test records and replays 102 batches through the production loaders: 90 training, 6 validation, and 6 test batches. Generated references stay under .cache/canvas-vae/ and are not committed.
Factors¶
Results are reported per training-reproduction stage on RICO.
Metrics¶
Training agreement compares forward activations, losses, gradients, optimizer state, and parameters with float tolerances, and data records and stream order exactly. Layout quality uses the original reconstruction score, layout mIoU, and random-generation histogram score.
Parity Results¶
The table keeps reference and calibration-set maxima as historical measurements and adds the independent held-out normal-mode results. The held-out run used a fresh clone, initialized its submodule, downloaded and prepared RICO, and regenerated references on an Intel Xeon CPU at 2.20 GHz without AVX-512. All five S0–S4 commands passed; the documented full suite reported 10 passed and 3 warnings in 3,591.26 seconds (59 minutes 51 seconds). The read-back evidence bundle contained all 208 manifest entries. See the held-out evidence comment. A later documentation/comment-only update did not change executable checks or limits. The full-run reproduction claim covers RICO only; Crello remains blocked and unclaimed.
| Check | Cases | Criterion | Historical calibration maximum | Held-out normal-mode result |
|---|---|---|---|---|
| S0 static configuration and checkpoint key map | 1,558,435 trainable parameters; 71 original trainable-parameter name keys | Exact key-map equality | Reference and calibration reports retain equal topology. | Exact topology and key-map assertions passed. |
| S0 evaluation forward | 10 outputs from one batch of 1,024 layouts | Maximum relative-to-max difference (rtol=1e-5) |
1.266045e-6; reference run. | 1.139062e-6; limit 1e-5. |
| S1 activations and logits | One exact encoder-context tensor and 14 relative-to-max comparisons from one batch | Maximum relative-to-max difference (rtol=1e-5) |
2.916977e-6; independent rerun 1. | 2.087399e-6; limit 1e-5. |
| S1 per-field losses, KL, L2, and total loss | 12 scalars from one batch | Maximum relative-to-max difference (rtol=1e-6) |
1.684800e-7; independent rerun 3. | 1.617341e-7; limit 1e-6. |
| S2 gradients, clipped gradients, and Adam moments | 69 trainable tensors per family; two key-projection bias tensors checked separately | Direct relative L2 <= 3.5e-4 per family; float64 arbitration <= 4.1e-3 if direct bound exceeded |
Gradient 2.278771e-4, clipped gradient 2.277752e-4, first moment 2.277754e-4 (calibration run 1); second moment 2.301702e-4 (independent rerun 2); max arbitration error 2.696621e-3 (calibration run 1). |
Raw/clipped/first-moment/second-moment maxima 6.333509e-5 / 6.333466e-5 / 6.333450e-5 / 6.393008e-5; 276 direct, 0 arbitrated. |
| S2 optimizer update, excluded-bias gradient, and batch normalization | 69 updates per system; two excluded bias tensors × two systems; 256 moving-mean and moving-variance values | Adam-rule relative L2 <= 3.5e-4; well-conditioned update <= 1.6e-3; excluded-bias maximum absolute gradient <= 1e-6; moving-statistic relative-to-max difference <= 1e-5 |
Update-rule 2.829523e-5, well-conditioned update 2.623599e-5, excluded-bias gradient 6.600749e-8, moving statistics 2.608958e-7; historical maxima in Calibration Results. |
Update-rule 2.7879995e-5; well-conditioned update 6.479192e-6; excluded-bias gradient 7.178460e-8; moving-mean difference 1.553235e-7. The moving-variance gate also passed; its separate maximum was not included in the supplied summary. |
| S3 synchronized loss, gradients, and updates | 49 synchronized steps × 69 tensors = 3,381 gradient comparisons and per-tensor update checks | Loss <= 1.2e-6; direct routing 3.5e-4; shared float64 arbitration 4.1e-3; Adam rule 5.1e-4; well-conditioned update 6.1e-3; running variance 1e-5 |
Loss 7.353933e-7 (calibration run 3); arbitration 2.696621e-3 (calibration run 1); Adam rule 3.350313e-4 (independent rerun 3); well-conditioned update 4.037209e-3 (calibration run 1); running variance 8.221208e-8 (independent rerun 3). |
Loss 3.044964e-7; 3,268 direct and 113 arbitrated gradients, maximum arbitrated error 7.491022e-4; Adam rule 2.973134e-4; well-conditioned update 1.698453e-3; running variance 8.067037e-8. |
| S4 original records and production-loader stream replay | 45,222 / 5,584 / 5,623 train/validation/test records; record and stream gate counts recorded separately | Exact content-hash sets, vocabularies, lookups, sample IDs, encoded fields, masks, and padding widths | Calibration reports recorded exact equality. | Exact equality; 24 record gates and 427 stream gates passed. |
Reproducibility¶
See REPRODUCING.md for commands to prepare RICO, generate original-code references, run agreement checks, convert checkpoints, and smoke-test loading. TRAINING.md records the completed RICO S0–S4 held-out pass, historical calibration measurements, S5 results, and package-local LightningCLI training. Full-run reproduction is claimed for RICO only; Crello remains unclaimed.
Environmental Impact¶
The staged agreement checks run on CPU in minutes. Full-run GPU telemetry is report-only and does not affect the S5 decision.
Technical Specifications¶
Model Architecture and Objective¶
The encoder sums per-field embeddings with learned position embeddings, applies one pre-norm transformer block conditioned on the element-count embedding, pools valid elements, applies batch normalization, and predicts a diagonal Gaussian posterior. The decoder applies one conditioned transformer block to position embeddings and predicts every field with linear heads. Training minimizes per-field cross-entropy summed over elements, plus 16 times the KL divergence, plus an L2 penalty on dense and embedding weights.
Compute Infrastructure¶
Agreement checks run on CPU. Full RICO training used one A100 per training process, with training processes run sequentially per GPU.
Hardware¶
CPU is sufficient for inference, unit tests, and the staged agreement checks.
Software¶
Use uv run --package canvas-vae ... from the repository root. The training extra installs Lightning, and the vendor extra installs CUDA-enabled TensorFlow 2.15.1 and Apache Beam for original-code references. The separate convert extra installs CPU-only TensorFlow for original initial.ckpt and final.ckpt conversion. Package training keeps validation-best weights in best.ckpt; a separate unmonitored callback with save_top_k: 1 retains one rolling checkpoint under Lightning’s epoch/step name and updates last.ckpt at configured checkpoint events. The final-checkpoint gate requires epoch 499 and global step 22,500 before evaluation.
License¶
Repository wrapper code is Apache-2.0. The original implementation is released under the Apache-2.0 license.
Citation¶
@inproceedings{yamaguchi2021canvasvae,
title = {{CanvasVAE: Learning To Generate Vector Graphic Documents}},
author = {Kota Yamaguchi},
booktitle = {Proceedings of the IEEE/CVF International Conference on Computer Vision (ICCV)},
year = {2021},
pages = {5481-5489}
}
API Reference¶
Transformers-style CanvasVAE layout generation package.
CanvasVAEConfig ¶
Bases: PretrainedConfig
Configuration for a CanvasVAE model trained on RICO.
A layout has a document-level element count and eight categorical
per-element fields. Box coordinates and sizes are discretized into
num_bins bins over [0, 1]; component, icon, and
text_button use the lookup tables in vocabularies, whose index 0 is
the out-of-vocabulary token.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
vocabularies
|
Mapping[str, Sequence[str]] | None
|
Lookup tables for |
None
|
max_length
|
int
|
Maximum number of elements per layout. |
50
|
num_bins
|
int
|
Number of discretization bins for box coordinates and sizes. |
64
|
latent_dim
|
int
|
Hidden and latent dimension. |
256
|
num_blocks
|
int
|
Number of transformer blocks in the encoder and decoder. |
1
|
num_heads
|
int
|
Number of attention heads. |
8
|
dropout
|
float
|
Dropout rate of position embeddings and blocks. |
0.1
|
kl_weight
|
float
|
Weight of the KL divergence term. |
16.0
|
l2_weight
|
float
|
Weight of the squared-norm penalty on dense and embedding weights. |
1e-06
|
layer_norm_epsilon
|
float
|
Layer-normalization epsilon. |
0.001
|
batch_norm_epsilon
|
float
|
Batch-normalization epsilon. |
0.001
|
batch_norm_momentum
|
float
|
Batch-normalization moving-average momentum. |
0.99
|
**kwargs
|
str | float | bool | None
|
Extra |
{}
|
Examples:
>>> config = CanvasVAEConfig(
... vocabularies={
... "component": ["[UNK]", "", "Text"],
... "icon": ["[UNK]", ""],
... "text_button": ["[UNK]", ""],
... },
... latent_dim=16,
... num_heads=2,
... )
>>> config.field_sizes["component"], config.primary_label_id
(3, 1)
Source code in models/canvas-vae/src/canvas_vae/configuration_canvas_vae.py
41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 | |
field_sizes
property
¶
field_sizes: dict[str, int]
Return the number of classes of every per-element field.
Raises:
| Type | Description |
|---|---|
ValueError
|
If a required vocabulary is missing. |
primary_label_id
property
¶
primary_label_id: int
Return the component id of the empty label used as background.
__init__ ¶
__init__(
vocabularies: Mapping[str, Sequence[str]] | None = None,
max_length: int = 50,
num_bins: int = 64,
latent_dim: int = 256,
num_blocks: int = 1,
num_heads: int = 8,
dropout: float = 0.1,
kl_weight: float = 16.0,
l2_weight: float = 1e-06,
layer_norm_epsilon: float = 0.001,
batch_norm_epsilon: float = 0.001,
batch_norm_momentum: float = 0.99,
**kwargs: str | float | bool | None,
) -> None
Initialize the config; see the class docstring for arguments.
Source code in models/canvas-vae/src/canvas_vae/configuration_canvas_vae.py
85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 | |
CanvasVAEField ¶
Bases: StrEnum
Per-element fields of a CanvasVAE layout, in model column order.
Source code in models/canvas-vae/src/canvas_vae/configuration_canvas_vae.py
12 13 14 15 16 17 18 19 20 21 22 | |
CanvasVAEModel ¶
Bases: CanvasVAEPreTrainedModel
CanvasVAE variational autoencoder over layout element sequences.
Given layout ids, the model encodes them, takes a posterior sample in
training mode (or when posterior_noise is given) and the posterior mean
otherwise, and decodes with the ground-truth element mask in training mode
or the predicted element count in evaluation mode. Given only
latents, it decodes them with the predicted element count.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
config
|
CanvasVAEConfig
|
Model config with vocabularies. |
required |
Examples:
>>> config = CanvasVAEConfig(
... vocabularies={
... "component": ["[UNK]", "", "Text"],
... "icon": ["[UNK]", ""],
... "text_button": ["[UNK]", ""],
... },
... max_length=4,
... num_bins=8,
... latent_dim=16,
... num_heads=2,
... )
>>> model = CanvasVAEModel(config).eval()
>>> output = model(latents=torch.zeros(2, 16))
>>> output.length_logits.shape
torch.Size([2, 4])
Source code in models/canvas-vae/src/canvas_vae/modeling_canvas_vae.py
350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 411 412 413 414 415 416 417 418 419 420 421 422 423 424 425 426 427 428 429 430 431 432 433 434 435 436 437 438 439 440 441 442 443 444 445 446 447 448 449 450 451 452 453 454 455 456 457 458 459 460 461 | |
__init__ ¶
__init__(config: CanvasVAEConfig) -> None
Create the encoder and decoder.
Source code in models/canvas-vae/src/canvas_vae/modeling_canvas_vae.py
380 381 382 383 384 385 | |
forward ¶
forward(
num_elements: Int[Tensor, "batch"] | None = None,
element_ids: Int[Tensor, "batch elements fields"]
| None = None,
*,
latents: Float[Tensor, "batch dim"] | None = None,
posterior_noise: Float[Tensor, "batch dim"]
| None = None,
) -> CanvasVAEModelOutput
Encode and decode a layout batch, or decode latent codes.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
num_elements
|
Int[Tensor, 'batch'] | None
|
Element count of every layout. |
None
|
element_ids
|
Int[Tensor, 'batch elements fields'] | None
|
Field ids in :class: |
None
|
latents
|
Float[Tensor, 'batch dim'] | None
|
Latent codes to decode instead of encoding a layout. |
None
|
posterior_noise
|
Float[Tensor, 'batch dim'] | None
|
Standard-normal noise for the posterior sample. Drawn from the global generator in training mode when omitted. |
None
|
Returns:
| Type | Description |
|---|---|
CanvasVAEModelOutput
|
Model outputs; |
Raises:
| Type | Description |
|---|---|
ValueError
|
If neither a layout nor latent codes are given. |
Source code in models/canvas-vae/src/canvas_vae/modeling_canvas_vae.py
387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 411 412 413 414 415 416 417 418 419 420 421 422 423 424 425 426 427 428 429 430 431 432 433 434 435 436 437 438 439 440 441 442 443 444 445 446 447 448 449 450 451 452 453 454 455 456 457 458 459 460 461 | |
CanvasVAEModelOutput
dataclass
¶
Bases: ModelOutput
Outputs of :class:CanvasVAEModel.
Attributes:
| Name | Type | Description |
|---|---|---|
loss |
Float[Tensor, ''] | None
|
Reconstruction plus weighted KL loss; present when layout inputs are given and the model is in training mode. |
length_logits |
Float[Tensor, 'batch lengths'] | None
|
Logits over the zero-based element count. |
element_logits |
dict[str, Float[Tensor, 'batch elements classes']] | None
|
Logits of every per-element field, keyed by field name. |
mask |
Bool[Tensor, 'batch elements'] | None
|
Valid-element mask used by the decoder. |
latents |
Float[Tensor, 'batch latent'] | None
|
Latent codes fed to the decoder. |
z_mean |
Float[Tensor, 'batch latent'] | None
|
Posterior mean; present when layout inputs are given. |
z_log_var |
Float[Tensor, 'batch latent'] | None
|
Posterior log-variance; present when layout inputs are given. |
kl_divergence |
Float[Tensor, ''] | None
|
Unweighted KL divergence to the standard normal prior. |
reconstruction_losses |
dict[str, Float[Tensor, '']] | None
|
Per-field reconstruction losses, including
|
Source code in models/canvas-vae/src/canvas_vae/modeling_canvas_vae.py
20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 | |
CanvasVAEPipeline ¶
Bases: LayoutGenerationPipeline
Sample RICO layouts from the CanvasVAE prior.
Each call draws latent codes from the standard normal prior, decodes the
element count and every element field with argmax, and returns
normalized center xywh boxes clamped to [0, 1] with component
labels. intermediates holds the clickable, icon, and
text_button ids and the latent codes.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
model
|
CanvasVAEModel
|
CanvasVAE model. |
required |
Examples:
>>> from canvas_vae import CanvasVAEConfig
>>> config = CanvasVAEConfig(
... vocabularies={
... "component": ["[UNK]", "", "Text"],
... "icon": ["[UNK]", ""],
... "text_button": ["[UNK]", ""],
... },
... max_length=4,
... num_bins=8,
... latent_dim=16,
... num_heads=2,
... )
>>> pipe = CanvasVAEPipeline(model=CanvasVAEModel(config))
>>> out = pipe(batch_size=2, seed=0)
>>> out.bbox.shape[0], out.bbox.shape[-1]
(2, 4)
Source code in models/canvas-vae/src/canvas_vae/pipeline_canvas_vae.py
64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 | |
__init__ ¶
__init__(model: CanvasVAEModel) -> None
Wrap a model; the pipeline config is the model config.
Source code in models/canvas-vae/src/canvas_vae/pipeline_canvas_vae.py
100 101 102 103 | |
__call__ ¶
__call__(
*,
batch_size: int = 1,
seed: int | None = None,
generator: Generator | None = None,
condition_type: ConditionType
| str = ConditionType.unconditional,
labels: Shaped[Tensor, "..."]
| Shaped[ndarray, "..."]
| list[list[int]]
| None = None,
bbox: Shaped[Tensor, "..."]
| Shaped[ndarray, "..."]
| list[list[list[float]]]
| None = None,
mask: Shaped[Tensor, "..."]
| Shaped[ndarray, "..."]
| list[list[bool]]
| None = None,
num_elements: int
| list[int]
| Int[Tensor, "batch"]
| None = None,
box_format: Literal["xywh", "ltwh", "ltrb"] = "xywh",
normalized: bool = True,
canvas_size: tuple[int, int] | None = None,
num_inference_steps: int | None = None,
output_type: OutputType | str = OutputType.dataclass,
return_intermediates: bool = False,
) -> (
LayoutGenerationOutput
| dict[str, Shaped[torch.Tensor, "..."]]
)
Generate layouts from prior samples.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
batch_size
|
int
|
Number of layouts. |
1
|
seed
|
int | None
|
Seed for a local generator when |
None
|
generator
|
Generator | None
|
Generator for the prior samples; takes precedence over
|
None
|
condition_type
|
ConditionType | str
|
Only |
unconditional
|
labels
|
Shaped[Tensor, '...'] | Shaped[ndarray, '...'] | list[list[int]] | None
|
Unsupported; must be |
None
|
bbox
|
Shaped[Tensor, '...'] | Shaped[ndarray, '...'] | list[list[list[float]]] | None
|
Unsupported; must be |
None
|
mask
|
Shaped[Tensor, '...'] | Shaped[ndarray, '...'] | list[list[bool]] | None
|
Unsupported; must be |
None
|
num_elements
|
int | list[int] | Int[Tensor, 'batch'] | None
|
Unsupported; the model predicts the element count. |
None
|
box_format
|
Literal['xywh', 'ltwh', 'ltrb']
|
Only |
'xywh'
|
normalized
|
bool
|
Only normalized output is supported. |
True
|
canvas_size
|
tuple[int, int] | None
|
Unsupported; must be |
None
|
num_inference_steps
|
int | None
|
Unsupported; decoding is a single pass. |
None
|
output_type
|
OutputType | str
|
|
dataclass
|
return_intermediates
|
bool
|
Whether to fill |
False
|
Returns:
| Type | Description |
|---|---|
LayoutGenerationOutput | dict[str, Shaped[Tensor, '...']]
|
Generated layouts in the shared layout schema. |
Raises:
| Type | Description |
|---|---|
NotImplementedError
|
If a condition or layout input other than unconditional generation is requested. |
Source code in models/canvas-vae/src/canvas_vae/pipeline_canvas_vae.py
116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 | |
CanvasVAEProcessor ¶
Bases: ProcessorMixin
Encode flattened layouts into CanvasVAE model ids.
Coordinates and sizes in [0, 1] map to num_bins equal-width bins
whose float32 boundaries are linspace(0, 1, num_bins)[1:]; values at or
above a boundary fall in the next bin. Strings map through the lookup
tables with unknown values at id 0. Layouts are padded to the longest one
in the batch with zero geometry, clickable=0, and the id of the empty
string.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
vocabularies
|
Mapping[str, Sequence[str]]
|
Lookup tables for |
required |
num_bins
|
int
|
Number of geometry bins. |
64
|
Examples:
>>> processor = CanvasVAEProcessor(
... vocabularies={
... "component": ["[UNK]", "", "Text"],
... "icon": ["[UNK]", ""],
... "text_button": ["[UNK]", ""],
... },
... num_bins=4,
... )
>>> element = {"left": 0.5, "top": 0.0, "width": 1.0, "height": 0.2,
... "clickable": 1, "component": "Text", "icon": "", "text_button": ""}
>>> processor([[element]])["element_ids"].tolist()
[[[1, 0, 3, 0, 1, 2, 1, 1]]]
Source code in models/canvas-vae/src/canvas_vae/processing_canvas_vae.py
307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 411 412 413 414 415 416 417 | |
bin_boundaries
property
¶
bin_boundaries: Float[ndarray, 'boundaries']
Return the float32 geometry bin boundaries.
__init__ ¶
__init__(
vocabularies: Mapping[str, Sequence[str]],
num_bins: int = 64,
) -> None
Store lookup tables and the bin count.
Source code in models/canvas-vae/src/canvas_vae/processing_canvas_vae.py
337 338 339 340 341 342 343 344 345 346 347 | |
discretize ¶
discretize(
values: Float[ndarray, "*shape"],
) -> Int[np.ndarray, "*shape"]
Map normalized geometry values to bin ids.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
values
|
Float[ndarray, '*shape']
|
Normalized coordinates or sizes. |
required |
Returns:
| Type | Description |
|---|---|
Int[ndarray, '*shape']
|
Bin ids in |
Source code in models/canvas-vae/src/canvas_vae/processing_canvas_vae.py
354 355 356 357 358 359 360 361 362 363 364 365 366 367 | |
lookup ¶
lookup(field: str, value: str) -> int
Return the id of value in the field table, or 0 when unknown.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
field
|
str
|
Vocabulary field name. |
required |
value
|
str
|
String value. |
required |
Returns:
| Type | Description |
|---|---|
int
|
Lookup id. |
Source code in models/canvas-vae/src/canvas_vae/processing_canvas_vae.py
369 370 371 372 373 374 375 376 377 378 379 | |
__call__ ¶
__call__(
layouts: Sequence[Sequence[RicoElement]],
) -> BatchFeature
Encode a batch of flattened layouts.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
layouts
|
Sequence[Sequence[RicoElement]]
|
Element lists, each non-empty. |
required |
Returns:
| Type | Description |
|---|---|
BatchFeature
|
|
BatchFeature
|
shape |
Raises:
| Type | Description |
|---|---|
ValueError
|
If a layout has no elements. |
Source code in models/canvas-vae/src/canvas_vae/processing_canvas_vae.py
381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 411 412 413 414 415 416 417 | |
configuration_canvas_vae ¶
Configuration for CanvasVAE layout models.
CanvasVAEField ¶
Bases: StrEnum
Per-element fields of a CanvasVAE layout, in model column order.
Source code in models/canvas-vae/src/canvas_vae/configuration_canvas_vae.py
12 13 14 15 16 17 18 19 20 21 22 | |
CanvasVAEConfig ¶
Bases: PretrainedConfig
Configuration for a CanvasVAE model trained on RICO.
A layout has a document-level element count and eight categorical
per-element fields. Box coordinates and sizes are discretized into
num_bins bins over [0, 1]; component, icon, and
text_button use the lookup tables in vocabularies, whose index 0 is
the out-of-vocabulary token.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
vocabularies
|
Mapping[str, Sequence[str]] | None
|
Lookup tables for |
None
|
max_length
|
int
|
Maximum number of elements per layout. |
50
|
num_bins
|
int
|
Number of discretization bins for box coordinates and sizes. |
64
|
latent_dim
|
int
|
Hidden and latent dimension. |
256
|
num_blocks
|
int
|
Number of transformer blocks in the encoder and decoder. |
1
|
num_heads
|
int
|
Number of attention heads. |
8
|
dropout
|
float
|
Dropout rate of position embeddings and blocks. |
0.1
|
kl_weight
|
float
|
Weight of the KL divergence term. |
16.0
|
l2_weight
|
float
|
Weight of the squared-norm penalty on dense and embedding weights. |
1e-06
|
layer_norm_epsilon
|
float
|
Layer-normalization epsilon. |
0.001
|
batch_norm_epsilon
|
float
|
Batch-normalization epsilon. |
0.001
|
batch_norm_momentum
|
float
|
Batch-normalization moving-average momentum. |
0.99
|
**kwargs
|
str | float | bool | None
|
Extra |
{}
|
Examples:
>>> config = CanvasVAEConfig(
... vocabularies={
... "component": ["[UNK]", "", "Text"],
... "icon": ["[UNK]", ""],
... "text_button": ["[UNK]", ""],
... },
... latent_dim=16,
... num_heads=2,
... )
>>> config.field_sizes["component"], config.primary_label_id
(3, 1)
Source code in models/canvas-vae/src/canvas_vae/configuration_canvas_vae.py
41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 | |
field_sizes
property
¶
field_sizes: dict[str, int]
Return the number of classes of every per-element field.
Raises:
| Type | Description |
|---|---|
ValueError
|
If a required vocabulary is missing. |
primary_label_id
property
¶
primary_label_id: int
Return the component id of the empty label used as background.
__init__ ¶
__init__(
vocabularies: Mapping[str, Sequence[str]] | None = None,
max_length: int = 50,
num_bins: int = 64,
latent_dim: int = 256,
num_blocks: int = 1,
num_heads: int = 8,
dropout: float = 0.1,
kl_weight: float = 16.0,
l2_weight: float = 1e-06,
layer_norm_epsilon: float = 0.001,
batch_norm_epsilon: float = 0.001,
batch_norm_momentum: float = 0.99,
**kwargs: str | float | bool | None,
) -> None
Initialize the config; see the class docstring for arguments.
Source code in models/canvas-vae/src/canvas_vae/configuration_canvas_vae.py
85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 | |
conversion ¶
Checkpoint conversion for CanvasVAE.
TensorFlow checkpoints written by the original Keras trainer store variables
under object-graph keys such as
encoder/seq2seq/seq2seq_0/attn/dense_query/kernel/.ATTRIBUTES/VARIABLE_VALUE.
This module maps those keys to package state-dict keys, transposing Keras dense
kernels, and rejects missing or unexpected model variables. Lightning
checkpoints written by the package trainer store the model under model..
TensorFlowSource ¶
Bases: NamedTuple
Source variable of one package state-dict entry.
Source code in models/canvas-vae/src/canvas_vae/conversion.py
28 29 30 31 32 | |
tensorflow_key_map ¶
tensorflow_key_map(
config: CanvasVAEConfig,
) -> dict[str, TensorFlowSource]
Return the TensorFlow source of every package state-dict entry.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
config
|
CanvasVAEConfig
|
Model config. |
required |
Returns:
| Type | Description |
|---|---|
dict[str, TensorFlowSource]
|
Source keys without the |
Examples:
>>> config = CanvasVAEConfig(
... vocabularies={"component": ["[UNK]", ""], "icon": ["[UNK]"],
... "text_button": ["[UNK]"]}
... )
>>> tensorflow_key_map(config)["encoder.z_log_var.weight"]
TensorFlowSource(key='encoder/head/z_log_sigma/kernel', transpose=True)
Source code in models/canvas-vae/src/canvas_vae/conversion.py
64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 | |
convert_tensorflow_variables ¶
convert_tensorflow_variables(
variables: Mapping[str, Shaped[ndarray, ...]],
config: CanvasVAEConfig,
) -> dict[str, Float[torch.Tensor, ...]]
Convert TensorFlow checkpoint variables into a package state dict.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
variables
|
Mapping[str, Shaped[ndarray, ...]]
|
Checkpoint variables keyed by object-graph key, with or
without the |
required |
config
|
CanvasVAEConfig
|
Model config. |
required |
Returns:
| Type | Description |
|---|---|
dict[str, Float[Tensor, ...]]
|
Package state dict. |
Raises:
| Type | Description |
|---|---|
KeyError
|
If model variables are missing or unexpected. |
Source code in models/canvas-vae/src/canvas_vae/conversion.py
120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 | |
load_lightning_state_dict ¶
load_lightning_state_dict(
checkpoint: str | Path,
) -> dict[str, Float[torch.Tensor, ...]]
Load the model state dict from a package Lightning checkpoint.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
checkpoint
|
str | Path
|
Lightning |
required |
Returns:
| Type | Description |
|---|---|
dict[str, Float[Tensor, ...]]
|
Model state dict without the |
Source code in models/canvas-vae/src/canvas_vae/conversion.py
163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 | |
metrics ¶
Reconstruction and random-generation metrics for CanvasVAE layouts.
Reconstruction scores compare a decoded layout with its source layout per
document: a unigram BLEU score per element field, their mean (total), and
pixel accuracy and mean IoU of the component maps rasterized on the
num_bins x num_bins grid. Random-generation scores compare normalized
histograms of every field between a reference split and decoded prior samples
by histogram intersection.
bleu1 ¶
bleu1(
target_ids: Int[Tensor, "batch target_elements"],
target_mask: Bool[Tensor, "batch target_elements"],
predicted_ids: Int[Tensor, "batch predicted_elements"],
predicted_mask: Bool[
Tensor, "batch predicted_elements"
],
num_classes: int,
) -> Float[torch.Tensor, "batch"]
Return the unigram BLEU score of every document for one field.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
target_ids
|
Int[Tensor, 'batch target_elements']
|
Reference field ids. |
required |
target_mask
|
Bool[Tensor, 'batch target_elements']
|
Valid reference elements. |
required |
predicted_ids
|
Int[Tensor, 'batch predicted_elements']
|
Predicted field ids. |
required |
predicted_mask
|
Bool[Tensor, 'batch predicted_elements']
|
Valid predicted elements. |
required |
num_classes
|
int
|
Number of field classes. |
required |
Returns:
| Type | Description |
|---|---|
Float[Tensor, 'batch']
|
Brevity-penalized square root of unigram precision, clipped to |
Float[Tensor, 'batch']
|
|
Examples:
>>> ids = torch.tensor([[1, 2]])
>>> mask = torch.tensor([[True, True]])
>>> bleu1(ids, mask, ids, mask, 3)
tensor([1.])
Source code in models/canvas-vae/src/canvas_vae/metrics.py
24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 | |
reconstruction_scores ¶
reconstruction_scores(
target_ids: Int[Tensor, "batch target_elements fields"],
target_mask: Bool[Tensor, "batch target_elements"],
predicted_ids: Int[
Tensor, "batch predicted_elements fields"
],
predicted_mask: Bool[
Tensor, "batch predicted_elements"
],
field_sizes: Mapping[str, int],
) -> dict[str, Float[torch.Tensor, "batch"]]
Return per-document BLEU scores of every field and their mean.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
target_ids
|
Int[Tensor, 'batch target_elements fields']
|
Reference field ids in :class: |
required |
target_mask
|
Bool[Tensor, 'batch target_elements']
|
Valid reference elements. |
required |
predicted_ids
|
Int[Tensor, 'batch predicted_elements fields']
|
Predicted field ids in the same order. |
required |
predicted_mask
|
Bool[Tensor, 'batch predicted_elements']
|
Valid predicted elements. |
required |
field_sizes
|
Mapping[str, int]
|
Number of classes per field. |
required |
Returns:
| Type | Description |
|---|---|
dict[str, Float[Tensor, 'batch']]
|
Scores keyed by field name plus |
Source code in models/canvas-vae/src/canvas_vae/metrics.py
69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 | |
component_grid ¶
component_grid(
element_ids: Int[Tensor, "elements fields"],
*,
grid_size: int,
background_id: int,
) -> Int[torch.Tensor, "grid grid"]
Rasterize one layout's component ids on the bin grid.
Each element fills rows top..min(top + height, grid_size - 1) and
columns left..min(left + width, grid_size - 1) inclusively in element
order; elements with an empty span are skipped.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
element_ids
|
Int[Tensor, 'elements fields']
|
Valid elements of one layout in :class: |
required |
grid_size
|
int
|
Number of geometry bins. |
required |
background_id
|
int
|
|
required |
Returns:
| Type | Description |
|---|---|
Int[Tensor, 'grid grid']
|
Label grid indexed by row and column. |
Examples:
>>> element = torch.tensor([[0, 0, 1, 1, 0, 2, 0, 0]])
>>> component_grid(element, grid_size=3, background_id=1).tolist()
[[2, 2, 1], [2, 2, 1], [1, 1, 1]]
Source code in models/canvas-vae/src/canvas_vae/metrics.py
102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 | |
layout_scores ¶
layout_scores(
target_ids: Int[Tensor, "batch target_elements fields"],
target_mask: Bool[Tensor, "batch target_elements"],
predicted_ids: Int[
Tensor, "batch predicted_elements fields"
],
predicted_mask: Bool[
Tensor, "batch predicted_elements"
],
*,
grid_size: int,
num_labels: int,
background_id: int,
) -> dict[str, Float[torch.Tensor, "batch"]]
Return per-document pixel accuracy and mean IoU of component grids.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
target_ids
|
Int[Tensor, 'batch target_elements fields']
|
Reference field ids. |
required |
target_mask
|
Bool[Tensor, 'batch target_elements']
|
Valid reference elements. |
required |
predicted_ids
|
Int[Tensor, 'batch predicted_elements fields']
|
Predicted field ids. |
required |
predicted_mask
|
Bool[Tensor, 'batch predicted_elements']
|
Valid predicted elements. |
required |
grid_size
|
int
|
Number of geometry bins. |
required |
num_labels
|
int
|
Size of the |
required |
background_id
|
int
|
|
required |
Returns:
| Type | Description |
|---|---|
dict[str, Float[Tensor, 'batch']]
|
|
Source code in models/canvas-vae/src/canvas_vae/metrics.py
143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 | |
field_histograms ¶
field_histograms(
num_elements: Int[Tensor, "batch"],
element_ids: Int[Tensor, "batch elements fields"],
field_sizes: Mapping[str, int],
max_length: int,
) -> dict[str, Float[torch.Tensor, "classes"]]
Return normalized histograms of element counts and of every field.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
num_elements
|
Int[Tensor, 'batch']
|
Element count of every layout. |
required |
element_ids
|
Int[Tensor, 'batch elements fields']
|
Field ids in :class: |
required |
field_sizes
|
Mapping[str, int]
|
Number of classes per field. |
required |
max_length
|
int
|
Maximum element count. |
required |
Returns:
| Type | Description |
|---|---|
dict[str, Float[Tensor, 'classes']]
|
Histograms keyed by |
Examples:
>>> ids = torch.zeros(1, 2, 8, dtype=torch.long)
>>> sizes = {field: 2 for field in CanvasVAEField}
>>> field_histograms(torch.tensor([1]), ids, sizes, 3)["length"].tolist()
[1.0, 0.0, 0.0]
Source code in models/canvas-vae/src/canvas_vae/metrics.py
197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 | |
histogram_scores ¶
histogram_scores(
reference: Mapping[str, Float[Tensor, "classes"]],
generated: Mapping[str, Float[Tensor, "classes"]],
) -> dict[str, float]
Return histogram intersections per key and their mean.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
reference
|
Mapping[str, Float[Tensor, 'classes']]
|
Histograms of a reference split. |
required |
generated
|
Mapping[str, Float[Tensor, 'classes']]
|
Histograms of generated layouts. |
required |
Returns:
| Type | Description |
|---|---|
dict[str, float]
|
Intersection per key plus |
Examples:
>>> histogram_scores({"a": torch.tensor([0.5, 0.5])},
... {"a": torch.tensor([1.0, 0.0])})
{'a': 0.5, 'total': 0.5}
Source code in models/canvas-vae/src/canvas_vae/metrics.py
232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 | |
modeling_canvas_vae ¶
CanvasVAE encoder-decoder model.
CanvasVAEModelOutput
dataclass
¶
Bases: ModelOutput
Outputs of :class:CanvasVAEModel.
Attributes:
| Name | Type | Description |
|---|---|---|
loss |
Float[Tensor, ''] | None
|
Reconstruction plus weighted KL loss; present when layout inputs are given and the model is in training mode. |
length_logits |
Float[Tensor, 'batch lengths'] | None
|
Logits over the zero-based element count. |
element_logits |
dict[str, Float[Tensor, 'batch elements classes']] | None
|
Logits of every per-element field, keyed by field name. |
mask |
Bool[Tensor, 'batch elements'] | None
|
Valid-element mask used by the decoder. |
latents |
Float[Tensor, 'batch latent'] | None
|
Latent codes fed to the decoder. |
z_mean |
Float[Tensor, 'batch latent'] | None
|
Posterior mean; present when layout inputs are given. |
z_log_var |
Float[Tensor, 'batch latent'] | None
|
Posterior log-variance; present when layout inputs are given. |
kl_divergence |
Float[Tensor, ''] | None
|
Unweighted KL divergence to the standard normal prior. |
reconstruction_losses |
dict[str, Float[Tensor, '']] | None
|
Per-field reconstruction losses, including
|
Source code in models/canvas-vae/src/canvas_vae/modeling_canvas_vae.py
20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 | |
CanvasVAEBatchNorm ¶
Bases: Module
Batch normalization over latent features with population variance.
Training mode normalizes with the batch mean and the biased batch variance and moves both moving statistics toward them; evaluation mode uses the moving statistics.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
num_features
|
int
|
Feature dimension. |
required |
eps
|
float
|
Variance epsilon. |
required |
momentum
|
float
|
Moving-average momentum of the previous statistic. |
required |
Source code in models/canvas-vae/src/canvas_vae/modeling_canvas_vae.py
73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 | |
__init__ ¶
__init__(
num_features: int, eps: float, momentum: float
) -> None
Create parameters and moving statistics.
Source code in models/canvas-vae/src/canvas_vae/modeling_canvas_vae.py
89 90 91 92 93 94 95 96 97 | |
forward ¶
forward(
inputs: Float[Tensor, "batch features"],
) -> Float[torch.Tensor, "batch features"]
Normalize inputs.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
inputs
|
Float[Tensor, 'batch features']
|
Pooled features. |
required |
Returns:
| Type | Description |
|---|---|
Float[Tensor, 'batch features']
|
Normalized features. |
Source code in models/canvas-vae/src/canvas_vae/modeling_canvas_vae.py
99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 | |
CanvasVAEBlock ¶
Bases: Module
Pre-norm transformer block conditioned on a global vector.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
config
|
CanvasVAEConfig
|
Model config. |
required |
pooling
|
bool
|
Whether to return the masked mean of ReLU outputs. |
required |
Source code in models/canvas-vae/src/canvas_vae/modeling_canvas_vae.py
125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 | |
__init__ ¶
__init__(config: CanvasVAEConfig, *, pooling: bool) -> None
Create attention, conditioning, and feed-forward layers.
Source code in models/canvas-vae/src/canvas_vae/modeling_canvas_vae.py
133 134 135 136 137 138 139 140 141 142 143 144 145 146 | |
forward ¶
forward(
hidden_states: Float[Tensor, "batch elements dim"],
condition: Float[Tensor, "batch dim"],
mask: Bool[Tensor, "batch elements"],
) -> (
Float[torch.Tensor, "batch elements dim"]
| Float[torch.Tensor, "batch dim"]
)
Apply the block.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
hidden_states
|
Float[Tensor, 'batch elements dim']
|
Element sequence. |
required |
condition
|
Float[Tensor, 'batch dim']
|
Global conditioning vector. |
required |
mask
|
Bool[Tensor, 'batch elements']
|
Valid-element mask. |
required |
Returns:
| Type | Description |
|---|---|
Float[Tensor, 'batch elements dim'] | Float[Tensor, 'batch dim']
|
Updated sequence, or its masked mean when pooling. |
Source code in models/canvas-vae/src/canvas_vae/modeling_canvas_vae.py
148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 | |
CanvasVAEPositionEmbedding ¶
Bases: Module
Learned position embeddings with dropout.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
config
|
CanvasVAEConfig
|
Model config. |
required |
Source code in models/canvas-vae/src/canvas_vae/modeling_canvas_vae.py
178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 | |
__init__ ¶
__init__(config: CanvasVAEConfig) -> None
Create the embedding table.
Source code in models/canvas-vae/src/canvas_vae/modeling_canvas_vae.py
185 186 187 188 189 | |
forward ¶
forward(
mask: Bool[Tensor, "batch elements"],
) -> Float[torch.Tensor, "batch elements dim"]
Return dropout-applied position embeddings shaped like mask.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
mask
|
Bool[Tensor, 'batch elements']
|
Valid-element mask whose shape selects the output shape. |
required |
Returns:
| Type | Description |
|---|---|
Float[Tensor, 'batch elements dim']
|
Position embeddings tiled over the batch. |
Source code in models/canvas-vae/src/canvas_vae/modeling_canvas_vae.py
191 192 193 194 195 196 197 198 199 200 201 202 203 204 | |
CanvasVAEEncoder ¶
Bases: Module
Encode a layout into posterior statistics.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
config
|
CanvasVAEConfig
|
Model config. |
required |
Source code in models/canvas-vae/src/canvas_vae/modeling_canvas_vae.py
207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 | |
__init__ ¶
__init__(config: CanvasVAEConfig) -> None
Create input embeddings, blocks, normalization, and the head.
Source code in models/canvas-vae/src/canvas_vae/modeling_canvas_vae.py
214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 | |
forward ¶
forward(
length_ids: Int[Tensor, "batch"],
element_ids: Int[Tensor, "batch elements fields"],
) -> tuple[
Float[torch.Tensor, "batch dim"],
Float[torch.Tensor, "batch dim"],
]
Return the posterior mean and log-variance.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
length_ids
|
Int[Tensor, 'batch']
|
Zero-based element counts. |
required |
element_ids
|
Int[Tensor, 'batch elements fields']
|
Field ids in :class: |
required |
Returns:
| Type | Description |
|---|---|
tuple[Float[Tensor, 'batch dim'], Float[Tensor, 'batch dim']]
|
Posterior mean and log-variance. |
Source code in models/canvas-vae/src/canvas_vae/modeling_canvas_vae.py
233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 | |
CanvasVAEDecoder ¶
Bases: Module
Decode latent codes into per-element field logits in one pass.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
config
|
CanvasVAEConfig
|
Model config. |
required |
Source code in models/canvas-vae/src/canvas_vae/modeling_canvas_vae.py
260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 | |
__init__ ¶
__init__(config: CanvasVAEConfig) -> None
Create position embeddings, blocks, and output heads.
Source code in models/canvas-vae/src/canvas_vae/modeling_canvas_vae.py
267 268 269 270 271 272 273 274 275 276 277 278 | |
forward ¶
forward(
latents: Float[Tensor, "batch dim"],
mask: Bool[Tensor, "batch elements"] | None = None,
) -> tuple[
Float[torch.Tensor, "batch lengths"],
dict[
str, Float[torch.Tensor, "batch elements classes"]
],
Bool[torch.Tensor, "batch elements"],
]
Decode latent codes.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
latents
|
Float[Tensor, 'batch dim']
|
Latent codes. |
required |
mask
|
Bool[Tensor, 'batch elements'] | None
|
Element mask to decode with. Defaults to the mask of the predicted element counts. |
None
|
Returns:
| Type | Description |
|---|---|
tuple[Float[Tensor, 'batch lengths'], dict[str, Float[Tensor, 'batch elements classes']], Bool[Tensor, 'batch elements']]
|
Length logits, per-field logits, and the decoding mask. |
Source code in models/canvas-vae/src/canvas_vae/modeling_canvas_vae.py
280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 | |
CanvasVAEPreTrainedModel ¶
Bases: PreTrainedModel
Base class handling CanvasVAE weight initialization.
Source code in models/canvas-vae/src/canvas_vae/modeling_canvas_vae.py
322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 | |
CanvasVAEModel ¶
Bases: CanvasVAEPreTrainedModel
CanvasVAE variational autoencoder over layout element sequences.
Given layout ids, the model encodes them, takes a posterior sample in
training mode (or when posterior_noise is given) and the posterior mean
otherwise, and decodes with the ground-truth element mask in training mode
or the predicted element count in evaluation mode. Given only
latents, it decodes them with the predicted element count.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
config
|
CanvasVAEConfig
|
Model config with vocabularies. |
required |
Examples:
>>> config = CanvasVAEConfig(
... vocabularies={
... "component": ["[UNK]", "", "Text"],
... "icon": ["[UNK]", ""],
... "text_button": ["[UNK]", ""],
... },
... max_length=4,
... num_bins=8,
... latent_dim=16,
... num_heads=2,
... )
>>> model = CanvasVAEModel(config).eval()
>>> output = model(latents=torch.zeros(2, 16))
>>> output.length_logits.shape
torch.Size([2, 4])
Source code in models/canvas-vae/src/canvas_vae/modeling_canvas_vae.py
350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 411 412 413 414 415 416 417 418 419 420 421 422 423 424 425 426 427 428 429 430 431 432 433 434 435 436 437 438 439 440 441 442 443 444 445 446 447 448 449 450 451 452 453 454 455 456 457 458 459 460 461 | |
__init__ ¶
__init__(config: CanvasVAEConfig) -> None
Create the encoder and decoder.
Source code in models/canvas-vae/src/canvas_vae/modeling_canvas_vae.py
380 381 382 383 384 385 | |
forward ¶
forward(
num_elements: Int[Tensor, "batch"] | None = None,
element_ids: Int[Tensor, "batch elements fields"]
| None = None,
*,
latents: Float[Tensor, "batch dim"] | None = None,
posterior_noise: Float[Tensor, "batch dim"]
| None = None,
) -> CanvasVAEModelOutput
Encode and decode a layout batch, or decode latent codes.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
num_elements
|
Int[Tensor, 'batch'] | None
|
Element count of every layout. |
None
|
element_ids
|
Int[Tensor, 'batch elements fields'] | None
|
Field ids in :class: |
None
|
latents
|
Float[Tensor, 'batch dim'] | None
|
Latent codes to decode instead of encoding a layout. |
None
|
posterior_noise
|
Float[Tensor, 'batch dim'] | None
|
Standard-normal noise for the posterior sample. Drawn from the global generator in training mode when omitted. |
None
|
Returns:
| Type | Description |
|---|---|
CanvasVAEModelOutput
|
Model outputs; |
Raises:
| Type | Description |
|---|---|
ValueError
|
If neither a layout nor latent codes are given. |
Source code in models/canvas-vae/src/canvas_vae/modeling_canvas_vae.py
387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 411 412 413 414 415 416 417 418 419 420 421 422 423 424 425 426 427 428 429 430 431 432 433 434 435 436 437 438 439 440 441 442 443 444 445 446 447 448 449 450 451 452 453 454 455 456 457 458 459 460 461 | |
length_mask ¶
length_mask(
length_ids: Int[Tensor, "batch"],
max_elements: int | None = None,
) -> Bool[torch.Tensor, "batch elements"]
Build a valid-element mask from zero-based element-count ids.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
length_ids
|
Int[Tensor, 'batch']
|
Element count minus one for every layout. |
required |
max_elements
|
int | None
|
Mask width. Defaults to the longest layout in the batch. |
None
|
Returns:
| Type | Description |
|---|---|
Bool[Tensor, 'batch elements']
|
Mask where |
Examples:
>>> length_mask(torch.tensor([0, 2])).tolist()
[[True, False, False], [True, True, True]]
Source code in models/canvas-vae/src/canvas_vae/modeling_canvas_vae.py
51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 | |
pipeline_canvas_vae ¶
Unconditional layout generation pipeline for CanvasVAE.
OutputType ¶
Bases: StrEnum
Return container of :meth:CanvasVAEPipeline.__call__.
Source code in models/canvas-vae/src/canvas_vae/pipeline_canvas_vae.py
25 26 27 28 29 | |
CanvasVAEPipeline ¶
Bases: LayoutGenerationPipeline
Sample RICO layouts from the CanvasVAE prior.
Each call draws latent codes from the standard normal prior, decodes the
element count and every element field with argmax, and returns
normalized center xywh boxes clamped to [0, 1] with component
labels. intermediates holds the clickable, icon, and
text_button ids and the latent codes.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
model
|
CanvasVAEModel
|
CanvasVAE model. |
required |
Examples:
>>> from canvas_vae import CanvasVAEConfig
>>> config = CanvasVAEConfig(
... vocabularies={
... "component": ["[UNK]", "", "Text"],
... "icon": ["[UNK]", ""],
... "text_button": ["[UNK]", ""],
... },
... max_length=4,
... num_bins=8,
... latent_dim=16,
... num_heads=2,
... )
>>> pipe = CanvasVAEPipeline(model=CanvasVAEModel(config))
>>> out = pipe(batch_size=2, seed=0)
>>> out.bbox.shape[0], out.bbox.shape[-1]
(2, 4)
Source code in models/canvas-vae/src/canvas_vae/pipeline_canvas_vae.py
64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 | |
__init__ ¶
__init__(model: CanvasVAEModel) -> None
Wrap a model; the pipeline config is the model config.
Source code in models/canvas-vae/src/canvas_vae/pipeline_canvas_vae.py
100 101 102 103 | |
__call__ ¶
__call__(
*,
batch_size: int = 1,
seed: int | None = None,
generator: Generator | None = None,
condition_type: ConditionType
| str = ConditionType.unconditional,
labels: Shaped[Tensor, "..."]
| Shaped[ndarray, "..."]
| list[list[int]]
| None = None,
bbox: Shaped[Tensor, "..."]
| Shaped[ndarray, "..."]
| list[list[list[float]]]
| None = None,
mask: Shaped[Tensor, "..."]
| Shaped[ndarray, "..."]
| list[list[bool]]
| None = None,
num_elements: int
| list[int]
| Int[Tensor, "batch"]
| None = None,
box_format: Literal["xywh", "ltwh", "ltrb"] = "xywh",
normalized: bool = True,
canvas_size: tuple[int, int] | None = None,
num_inference_steps: int | None = None,
output_type: OutputType | str = OutputType.dataclass,
return_intermediates: bool = False,
) -> (
LayoutGenerationOutput
| dict[str, Shaped[torch.Tensor, "..."]]
)
Generate layouts from prior samples.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
batch_size
|
int
|
Number of layouts. |
1
|
seed
|
int | None
|
Seed for a local generator when |
None
|
generator
|
Generator | None
|
Generator for the prior samples; takes precedence over
|
None
|
condition_type
|
ConditionType | str
|
Only |
unconditional
|
labels
|
Shaped[Tensor, '...'] | Shaped[ndarray, '...'] | list[list[int]] | None
|
Unsupported; must be |
None
|
bbox
|
Shaped[Tensor, '...'] | Shaped[ndarray, '...'] | list[list[list[float]]] | None
|
Unsupported; must be |
None
|
mask
|
Shaped[Tensor, '...'] | Shaped[ndarray, '...'] | list[list[bool]] | None
|
Unsupported; must be |
None
|
num_elements
|
int | list[int] | Int[Tensor, 'batch'] | None
|
Unsupported; the model predicts the element count. |
None
|
box_format
|
Literal['xywh', 'ltwh', 'ltrb']
|
Only |
'xywh'
|
normalized
|
bool
|
Only normalized output is supported. |
True
|
canvas_size
|
tuple[int, int] | None
|
Unsupported; must be |
None
|
num_inference_steps
|
int | None
|
Unsupported; decoding is a single pass. |
None
|
output_type
|
OutputType | str
|
|
dataclass
|
return_intermediates
|
bool
|
Whether to fill |
False
|
Returns:
| Type | Description |
|---|---|
LayoutGenerationOutput | dict[str, Shaped[Tensor, '...']]
|
Generated layouts in the shared layout schema. |
Raises:
| Type | Description |
|---|---|
NotImplementedError
|
If a condition or layout input other than unconditional generation is requested. |
Source code in models/canvas-vae/src/canvas_vae/pipeline_canvas_vae.py
116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 | |
bins_to_ltwh ¶
bins_to_ltwh(
bins: Int[Tensor, "... 4"], num_bins: int
) -> Float[torch.Tensor, "... 4"]
Map left, top, width, and height bin ids to normalized values.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
bins
|
Int[Tensor, '... 4']
|
Bin ids in |
required |
num_bins
|
int
|
Number of bins. |
required |
Returns:
| Type | Description |
|---|---|
Float[Tensor, '... 4']
|
Values |
Examples:
>>> bins_to_ltwh(torch.tensor([0, 3, 1, 2]), 4).tolist()
[0.0, 1.0, 0.3333333432674408, 0.6666666865348816]
Source code in models/canvas-vae/src/canvas_vae/pipeline_canvas_vae.py
45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 | |
processing_canvas_vae ¶
RICO preparation and layout encoding for CanvasVAE.
RicoSplit ¶
Bases: StrEnum
Dataset splits assigned from the content hash.
Source code in models/canvas-vae/src/canvas_vae/processing_canvas_vae.py
53 54 55 56 57 58 | |
RicoDocument ¶
Bases: TypedDict
One deduplicated RICO screen flattened into elements.
Source code in models/canvas-vae/src/canvas_vae/processing_canvas_vae.py
61 62 63 64 65 66 67 | |
RicoNode ¶
Bases: TypedDict
Subset of a RICO semantic-annotation node read by the flattener.
Source code in models/canvas-vae/src/canvas_vae/processing_canvas_vae.py
70 71 72 73 74 75 76 77 78 | |
CanvasVAEProcessor ¶
Bases: ProcessorMixin
Encode flattened layouts into CanvasVAE model ids.
Coordinates and sizes in [0, 1] map to num_bins equal-width bins
whose float32 boundaries are linspace(0, 1, num_bins)[1:]; values at or
above a boundary fall in the next bin. Strings map through the lookup
tables with unknown values at id 0. Layouts are padded to the longest one
in the batch with zero geometry, clickable=0, and the id of the empty
string.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
vocabularies
|
Mapping[str, Sequence[str]]
|
Lookup tables for |
required |
num_bins
|
int
|
Number of geometry bins. |
64
|
Examples:
>>> processor = CanvasVAEProcessor(
... vocabularies={
... "component": ["[UNK]", "", "Text"],
... "icon": ["[UNK]", ""],
... "text_button": ["[UNK]", ""],
... },
... num_bins=4,
... )
>>> element = {"left": 0.5, "top": 0.0, "width": 1.0, "height": 0.2,
... "clickable": 1, "component": "Text", "icon": "", "text_button": ""}
>>> processor([[element]])["element_ids"].tolist()
[[[1, 0, 3, 0, 1, 2, 1, 1]]]
Source code in models/canvas-vae/src/canvas_vae/processing_canvas_vae.py
307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 411 412 413 414 415 416 417 | |
bin_boundaries
property
¶
bin_boundaries: Float[ndarray, 'boundaries']
Return the float32 geometry bin boundaries.
__init__ ¶
__init__(
vocabularies: Mapping[str, Sequence[str]],
num_bins: int = 64,
) -> None
Store lookup tables and the bin count.
Source code in models/canvas-vae/src/canvas_vae/processing_canvas_vae.py
337 338 339 340 341 342 343 344 345 346 347 | |
discretize ¶
discretize(
values: Float[ndarray, "*shape"],
) -> Int[np.ndarray, "*shape"]
Map normalized geometry values to bin ids.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
values
|
Float[ndarray, '*shape']
|
Normalized coordinates or sizes. |
required |
Returns:
| Type | Description |
|---|---|
Int[ndarray, '*shape']
|
Bin ids in |
Source code in models/canvas-vae/src/canvas_vae/processing_canvas_vae.py
354 355 356 357 358 359 360 361 362 363 364 365 366 367 | |
lookup ¶
lookup(field: str, value: str) -> int
Return the id of value in the field table, or 0 when unknown.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
field
|
str
|
Vocabulary field name. |
required |
value
|
str
|
String value. |
required |
Returns:
| Type | Description |
|---|---|
int
|
Lookup id. |
Source code in models/canvas-vae/src/canvas_vae/processing_canvas_vae.py
369 370 371 372 373 374 375 376 377 378 379 | |
__call__ ¶
__call__(
layouts: Sequence[Sequence[RicoElement]],
) -> BatchFeature
Encode a batch of flattened layouts.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
layouts
|
Sequence[Sequence[RicoElement]]
|
Element lists, each non-empty. |
required |
Returns:
| Type | Description |
|---|---|
BatchFeature
|
|
BatchFeature
|
shape |
Raises:
| Type | Description |
|---|---|
ValueError
|
If a layout has no elements. |
Source code in models/canvas-vae/src/canvas_vae/processing_canvas_vae.py
381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 411 412 413 414 415 416 417 | |
stable_hash ¶
stable_hash(content: bytes) -> int
Return the MD5 integer of the str form of raw JSON bytes.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
content
|
bytes
|
Raw annotation file bytes. |
required |
Returns:
| Type | Description |
|---|---|
int
|
Integer hash used for deduplication and split assignment. |
Examples:
>>> stable_hash(b"{}") % 10
6
Source code in models/canvas-vae/src/canvas_vae/processing_canvas_vae.py
81 82 83 84 85 86 87 88 89 90 91 92 93 94 | |
split_for_hash ¶
split_for_hash(content_hash: int) -> RicoSplit
Assign a split from a content hash: 0 is val, 1 is test, the rest train.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
content_hash
|
int
|
Value returned by :func: |
required |
Returns:
| Type | Description |
|---|---|
RicoSplit
|
Assigned split. |
Examples:
>>> split_for_hash(20), split_for_hash(31), split_for_hash(45)
(<RicoSplit.val: 'val'>, <RicoSplit.test: 'test'>, <RicoSplit.train: 'train'>)
Source code in models/canvas-vae/src/canvas_vae/processing_canvas_vae.py
97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 | |
flatten_rico_hierarchy ¶
flatten_rico_hierarchy(
node: RicoNode,
) -> Iterator[RicoElement]
Yield elements of a RICO view hierarchy in depth-first pre-order.
The root node is included. Coordinates are divided by the fixed 1440x2560 RICO canvas and rounded to float32.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
node
|
RicoNode
|
Root or child node of a semantic annotation. |
required |
Yields:
| Type | Description |
|---|---|
RicoElement
|
Flattened elements with absent attributes filled by empty values. |
Examples:
>>> root = {"bounds": [0, 0, 1440, 2560], "class": "View"}
>>> next(flatten_rico_hierarchy(root))["width"]
1.0
Source code in models/canvas-vae/src/canvas_vae/processing_canvas_vae.py
120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 | |
read_rico_archive ¶
read_rico_archive(
archive: str | Path,
*,
max_elements: int = RICO_MAX_ELEMENTS,
) -> list[RicoDocument]
Read, deduplicate, flatten, and split the RICO semantic annotations.
Files with identical bytes are kept once under the first file name in
archive order; screens with more than max_elements elements are dropped.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
archive
|
str | Path
|
Path to |
required |
max_elements
|
int
|
Maximum number of elements per screen. |
RICO_MAX_ELEMENTS
|
Returns:
| Type | Description |
|---|---|
list[RicoDocument]
|
Kept documents in archive order. |
Source code in models/canvas-vae/src/canvas_vae/processing_canvas_vae.py
153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 | |
count_values ¶
count_values(
documents: Sequence[RicoDocument],
) -> dict[str, dict[str, int]]
Count string field values over all documents.
Values are ordered by descending count, ties by ascending value.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
documents
|
Sequence[RicoDocument]
|
Documents of every split. |
required |
Returns:
| Type | Description |
|---|---|
dict[str, dict[str, int]]
|
Counts per field for |
dict[str, dict[str, int]]
|
|
Examples:
>>> element = {"class": "A", "component": "", "icon": "x", "text_button": ""}
>>> doc = {"id": 0, "content_hash": "", "split": "train", "elements": [element]}
>>> count_values([doc])["icon"]
{'x': 1}
Source code in models/canvas-vae/src/canvas_vae/processing_canvas_vae.py
197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 | |
build_vocabularies ¶
build_vocabularies(
counts: Mapping[str, Mapping[str, int]],
min_frequency: Mapping[str, int] = RICO_MIN_FREQUENCY,
) -> dict[str, list[str]]
Build lookup tables from value counts in their stored order.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
counts
|
Mapping[str, Mapping[str, int]]
|
Value counts per field, in lookup order. |
required |
min_frequency
|
Mapping[str, int]
|
Minimum count for a value to get its own id. |
RICO_MIN_FREQUENCY
|
Returns:
| Type | Description |
|---|---|
dict[str, list[str]]
|
Lookup tables starting with the out-of-vocabulary token. |
Examples:
>>> counts = {"component": {"": 3}, "icon": {"": 900, "x": 2}, "text_button": {}}
>>> build_vocabularies(counts)["icon"]
['[UNK]', '']
Source code in models/canvas-vae/src/canvas_vae/processing_canvas_vae.py
227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 | |
prepare_rico_cache ¶
prepare_rico_cache(
archive: str | Path, output_dir: str | Path
) -> dict[str, int]
Write split JSON-lines files, vocabulary.json, and count.json.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
archive
|
str | Path
|
Path to |
required |
output_dir
|
str | Path
|
Cache directory to write. |
required |
Returns:
| Type | Description |
|---|---|
dict[str, int]
|
Number of documents per split. |
Source code in models/canvas-vae/src/canvas_vae/processing_canvas_vae.py
252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 | |
load_rico_split ¶
load_rico_split(
data_dir: str | Path, split: RicoSplit | str
) -> list[RicoDocument]
Load one prepared split.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
data_dir
|
str | Path
|
Directory written by :func: |
required |
split
|
RicoSplit | str
|
Split name. |
required |
Returns:
| Type | Description |
|---|---|
list[RicoDocument]
|
Documents in stored order. |
Source code in models/canvas-vae/src/canvas_vae/processing_canvas_vae.py
279 280 281 282 283 284 285 286 287 288 289 290 291 | |
load_rico_vocabularies ¶
load_rico_vocabularies(
data_dir: str | Path,
) -> dict[str, list[str]]
Build lookup tables from a prepared vocabulary.json.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
data_dir
|
str | Path
|
Directory containing |
required |
Returns:
| Type | Description |
|---|---|
dict[str, list[str]]
|
Lookup tables for :class: |
Source code in models/canvas-vae/src/canvas_vae/processing_canvas_vae.py
294 295 296 297 298 299 300 301 302 303 304 | |
training ¶
Training utilities for CanvasVAE.
checkpoints ¶
Validate CanvasVAE Lightning checkpoints against the configured final epoch.
validate_final_checkpoint ¶
validate_final_checkpoint(
checkpoint_path: str | Path,
*,
max_epochs: int,
expected_global_step: int,
) -> tuple[int, int]
Require a Lightning checkpoint from the configured final epoch and step.
Source code in models/canvas-vae/src/canvas_vae/training/checkpoints.py
11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 | |
main ¶
main() -> int
Validate one checkpoint against its expected final training step.
Source code in models/canvas-vae/src/canvas_vae/training/checkpoints.py
54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 | |
datamodule ¶
Lightning data module for CanvasVAE on prepared RICO splits.
RicoLayoutDataset ¶
Bases: Dataset[list[RicoElement]]
Element lists of prepared RICO documents.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
documents
|
Sequence[RicoDocument]
|
Prepared documents. |
required |
Source code in models/canvas-vae/src/canvas_vae/training/datamodule.py
22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 | |
__init__ ¶
__init__(documents: Sequence[RicoDocument]) -> None
Store the documents.
Source code in models/canvas-vae/src/canvas_vae/training/datamodule.py
29 30 31 | |
__len__ ¶
__len__() -> int
Return the number of documents.
Source code in models/canvas-vae/src/canvas_vae/training/datamodule.py
33 34 35 | |
__getitem__ ¶
__getitem__(index: int) -> list[RicoElement]
Return the elements of one document.
Source code in models/canvas-vae/src/canvas_vae/training/datamodule.py
37 38 39 | |
CanvasVAEDataModule ¶
Bases: LightningDataModule
Serve RICO splits prepared by scripts/prepare_rico.py.
Training batches come from one endless stream of shuffled passes with
ceil(train_size / batch_size) full batches per epoch. Validation
scores the same number of full batches over a repeated ordered pass, and
testing scores one ordered pass. Every batch is padded to its longest
layout.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
data_dir
|
str
|
Prepared split directory. |
'.cache/canvas-vae/data/rico'
|
batch_size
|
int
|
Batch size. |
1024
|
num_workers
|
int
|
Data-loader worker processes. |
0
|
seed
|
int | None
|
Seed of the training stream. Defaults to the global Torch seed. |
None
|
Source code in models/canvas-vae/src/canvas_vae/training/datamodule.py
42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 | |
__init__ ¶
__init__(
data_dir: str = ".cache/canvas-vae/data/rico",
batch_size: int = 1024,
num_workers: int = 0,
seed: int | None = None,
) -> None
Store loader settings.
Source code in models/canvas-vae/src/canvas_vae/training/datamodule.py
58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 | |
setup ¶
setup(stage: str | None = None) -> None
Load splits and vocabularies once.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
stage
|
str | None
|
Lightning stage name. |
None
|
Source code in models/canvas-vae/src/canvas_vae/training/datamodule.py
75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 | |
train_dataloader ¶
train_dataloader() -> DataLoader[list[RicoElement]]
Return the cross-epoch training stream.
Source code in models/canvas-vae/src/canvas_vae/training/datamodule.py
110 111 112 | |
val_dataloader ¶
val_dataloader() -> DataLoader[list[RicoElement]]
Return full batches over a repeated ordered validation pass.
Source code in models/canvas-vae/src/canvas_vae/training/datamodule.py
114 115 116 117 | |
test_dataloader ¶
test_dataloader() -> DataLoader[list[RicoElement]]
Return one ordered test pass.
Source code in models/canvas-vae/src/canvas_vae/training/datamodule.py
119 120 121 122 | |
lightning_module ¶
Lightning training module for CanvasVAE.
CanvasVAETrainingModule ¶
Bases: LightningModule
Train a CanvasVAE model with its reconstruction, KL, and L2 losses.
The model config is built from the prepared vocabulary.json in
data_dir. Every gradient tensor is clipped to clip_norm on its own
before a :class:KerasAdam step; do not set Lightning's global
gradient_clip_val. Validation decodes with the posterior mean and
predicted element counts and logs per-document mean scores under val/,
including val/total_score.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
data_dir
|
str
|
Prepared split directory containing |
'.cache/canvas-vae/data/rico'
|
latent_dim
|
int
|
Hidden and latent dimension. |
256
|
num_blocks
|
int
|
Number of transformer blocks. |
1
|
num_heads
|
int
|
Number of attention heads. |
8
|
dropout
|
float
|
Dropout rate. |
0.1
|
kl_weight
|
float
|
KL divergence weight. |
16.0
|
l2_weight
|
float
|
Squared-norm penalty weight. |
1e-06
|
learning_rate
|
float
|
Adam learning rate. |
0.001
|
clip_norm
|
float
|
Maximum norm of each gradient tensor. |
1.0
|
Source code in models/canvas-vae/src/canvas_vae/training/lightning_module.py
19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 | |
__init__ ¶
__init__(
data_dir: str = ".cache/canvas-vae/data/rico",
latent_dim: int = 256,
num_blocks: int = 1,
num_heads: int = 8,
dropout: float = 0.1,
kl_weight: float = 16.0,
l2_weight: float = 1e-06,
learning_rate: float = 0.001,
clip_norm: float = 1.0,
) -> None
Build the model from the prepared vocabulary.
Source code in models/canvas-vae/src/canvas_vae/training/lightning_module.py
41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 | |
training_step ¶
training_step(
batch: Mapping[str, Int[Tensor, "..."]], batch_idx: int
) -> Float[torch.Tensor, ""]
Return reconstruction, weighted KL, and L2 losses summed.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
batch
|
Mapping[str, Int[Tensor, '...']]
|
Processor output. |
required |
batch_idx
|
int
|
Batch index. |
required |
Returns:
| Type | Description |
|---|---|
Float[Tensor, '']
|
Total loss. |
Source code in models/canvas-vae/src/canvas_vae/training/lightning_module.py
72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 | |
on_validation_epoch_start ¶
on_validation_epoch_start() -> None
Reset validation accumulators.
Source code in models/canvas-vae/src/canvas_vae/training/lightning_module.py
114 115 116 117 | |
validation_step ¶
validation_step(
batch: Mapping[str, Int[Tensor, "..."]], batch_idx: int
) -> None
Accumulate per-document reconstruction scores.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
batch
|
Mapping[str, Int[Tensor, '...']]
|
Processor output. |
required |
batch_idx
|
int
|
Batch index. |
required |
Source code in models/canvas-vae/src/canvas_vae/training/lightning_module.py
119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 | |
on_validation_epoch_end ¶
on_validation_epoch_end() -> None
Log per-document means of the accumulated scores.
Source code in models/canvas-vae/src/canvas_vae/training/lightning_module.py
160 161 162 163 164 165 166 167 168 169 170 171 172 | |
configure_optimizers ¶
configure_optimizers() -> Optimizer
Return :class:KerasAdam over the model parameters.
Source code in models/canvas-vae/src/canvas_vae/training/lightning_module.py
174 175 176 | |
configure_gradient_clipping ¶
configure_gradient_clipping(
optimizer: Optimizer,
gradient_clip_val: float | None = None,
gradient_clip_algorithm: str | None = None,
) -> None
Clip every gradient tensor to clip_norm independently.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
optimizer
|
Optimizer
|
Optimizer about to step. |
required |
gradient_clip_val
|
float | None
|
Must be unset; global clipping is not used. |
None
|
gradient_clip_algorithm
|
str | None
|
Ignored. |
None
|
Raises:
| Type | Description |
|---|---|
ValueError
|
If Lightning's global |
Source code in models/canvas-vae/src/canvas_vae/training/lightning_module.py
178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 | |
optim ¶
Optimizer, gradient clipping, and weight penalty for CanvasVAE training.
clip_gradients_by_norm ¶
clip_gradients_by_norm(
parameters: Iterable[Parameter], max_norm: float
) -> None
Rescale every gradient tensor whose own L2 norm exceeds max_norm.
Each gradient becomes g * max_norm / max(norm(g), max_norm); unlike
global-norm clipping, tensors are clipped independently.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
parameters
|
Iterable[Parameter]
|
Parameters whose gradients are clipped in place. |
required |
max_norm
|
float
|
Maximum norm of each gradient tensor. |
required |
Examples:
>>> weight = nn.Parameter(torch.zeros(2))
>>> weight.grad = torch.tensor([3.0, 4.0])
>>> clip_gradients_by_norm([weight], 1.0)
>>> weight.grad.tolist()
[0.6000000238418579, 0.800000011920929]
Source code in models/canvas-vae/src/canvas_vae/training/optim.py
13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 | |
l2_penalty ¶
l2_penalty(
model: Module, weight: float
) -> Float[torch.Tensor, ""]
Return weight * sum(w**2) over every dense and embedding parameter.
Normalization parameters and moving statistics are excluded.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
model
|
Module
|
Model whose |
required |
weight
|
float
|
Penalty weight. |
required |
Returns:
| Type | Description |
|---|---|
Float[Tensor, '']
|
Scalar penalty. |
Examples:
>>> l2_penalty(nn.Linear(1, 1, bias=False).requires_grad_(False), 0.0)
tensor(0.)
Source code in models/canvas-vae/src/canvas_vae/training/optim.py
39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 | |
sampling ¶
Batch index streams for CanvasVAE training and evaluation.
CrossEpochBatchSampler ¶
Bases: Sampler[list[int]]
Yield fixed-size batches from one endless stream of shuffled passes.
The stream concatenates independent permutations of the records, and each
epoch takes the next ceil(num_records / batch_size) batches from it, so
batches straddle pass boundaries and every batch is full.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
num_records
|
int
|
Number of training records. |
required |
batch_size
|
int
|
Batch size. |
required |
generator
|
Generator
|
Generator for the permutations. |
required |
ordered_indices
|
Sequence[int] | None
|
Optional finite sample-index stream for deterministic replay. Without it, the sampler keeps drawing shuffled passes. |
None
|
Examples:
>>> sampler = CrossEpochBatchSampler(5, 2, torch.Generator().manual_seed(0))
>>> [len(batch) for batch in sampler], len(sampler)
([2, 2, 2], 3)
Source code in models/canvas-vae/src/canvas_vae/training/sampling.py
13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 | |
__init__ ¶
__init__(
num_records: int,
batch_size: int,
generator: Generator,
*,
ordered_indices: Sequence[int] | None = None,
) -> None
Store the stream configuration.
Source code in models/canvas-vae/src/canvas_vae/training/sampling.py
33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 | |
__len__ ¶
__len__() -> int
Return the number of batches per epoch.
Source code in models/canvas-vae/src/canvas_vae/training/sampling.py
54 55 56 | |
__iter__ ¶
__iter__() -> Iterator[list[int]]
Yield the next epoch of batches from the stream.
Source code in models/canvas-vae/src/canvas_vae/training/sampling.py
58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 | |
wrapping_batches ¶
wrapping_batches(
num_records: int, batch_size: int
) -> list[list[int]]
Return ceil(num_records / batch_size) full batches of a repeated pass.
Records are taken in order and the last batch wraps to the first records, so some records are scored twice.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
num_records
|
int
|
Number of records. |
required |
batch_size
|
int
|
Batch size. |
required |
Returns:
| Type | Description |
|---|---|
list[list[int]]
|
Batches of record indices. |
Examples:
>>> wrapping_batches(3, 2)
[[0, 1], [2, 0]]
Source code in models/canvas-vae/src/canvas_vae/training/sampling.py
86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 | |
sequential_batches ¶
sequential_batches(
num_records: int, batch_size: int
) -> list[list[int]]
Return one ordered pass whose last batch may be smaller.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
num_records
|
int
|
Number of records. |
required |
batch_size
|
int
|
Batch size. |
required |
Returns:
| Type | Description |
|---|---|
list[list[int]]
|
Batches of record indices. |
Examples:
>>> sequential_batches(3, 2)
[[0, 1], [2]]
Source code in models/canvas-vae/src/canvas_vae/training/sampling.py
111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 | |