Online Vocabulary
Category, Set, and Cluster learn a mapping from observed labels to model slots during training. Users supply the labels directly; a separate integer encoding step is unnecessary. Each field has its own growing vocabulary, preserved with the model’s learned state.
The Vocabulary and OOV proofs exercise unknown inputs and targets, vocabulary growth, set membership, and checkpoint/continued-training behavior. They distinguish learned fallback from information that a frozen evaluation vocabulary cannot represent.
A Vocabulary Belongs To A Field
One customer observation might contain:
orders:
- merchant: grocery
tags:
- food
- in_store
- merchant: bookstore
tags:
- gift
- online
preferred_channel: emailimport relflow as rf
model = rf.Model.sm(
orders=rf.Branch(
length=64,
merchant=rf.Category,
tags=rf.Set,
),
preferred_channel=rf.Category(mask=True),
)All orders share /orders/merchant, so that field learns one merchant vocabulary across customers and order positions. Tags and preferred channels have separate mappings. Matching labels in different fields do not imply shared slots or embeddings. Use one repeated field when roles should share a vocabulary; Preprocessing shows that reshaping.
Keep labels in one compatible Arrow type family and normalize spelling, case, and label types upstream. A null is a separate value state and consumes no vocabulary slot. Set members are labels; the entire set is not one vocabulary entry.
When Labels Are Learned
| Stage | Vocabulary behavior |
|---|---|
| Training | Admit new labels before the batch’s forward pass, growing storage as needed. |
| Validation and test | Reuse the existing mapping; unseen labels remain unknown. |
| Prediction and serving | Reuse the loaded mapping; requests do not teach new labels. |
| Fine-tuning or resumed training | Continue from the saved mapping, admitting new labels and growing storage as needed. |
Learning observes the pristine values retained by the schema, after preprocessing and query/overflow selection but before input masking and p_unavailable perturbations. An always-hidden target such as preferred_channel therefore learns its label vocabulary too. Masking does not prevent vocabulary learning.
Training-stage encoding, including model.encode(..., strata="train"), can update this state even without an optimizer step. Validation or prediction on a newly constructed model starts with empty vocabularies; load a trained artifact to reuse its mappings.
Automatic Storage Growth
Category, Set, and Cluster manage vocabulary storage automatically. Neither size nor capacity is a field option, and there is no configured maximum. When a training batch introduces more labels than fit, storage grows geometrically until it can hold them. Users do not need to estimate the number of labels before training. Cluster’s bounds controls latent clusters, not vocabulary storage.
Growth preserves existing label IDs, learned embedding and decoder rows, exposure counters, partial gradients, and optimizer history: Adam/AdamW moments and step counters, or SGD momentum. New parameter rows receive standard initialization and zeroed optimizer moments or momentum. Cluster preserves its unavailable assignment while growing per-label rows; its configured cluster bounds are unchanged. Checkpoints preserve the mapping and grown tensor sizes, so resumed training can continue from that allocation. Vocabulary storage is runtime state, not schema configuration; growing it does not change the schema.
Labels append in encounter order without evicting or renumbering existing ones. With DDP, each batch’s labels are gathered in rank order, preserving encounter order within each rank. Record order, shuffling, and rank layout can change the assigned IDs, but early rare labels do not exclude later common labels. P057 checks admission and learning across encounter orders.
Automatic growth still consumes memory and increases decoder cost. In particular, Set membership and decoder outputs span the current allocation. Spare rows are not labels: reconstruction objectives and written probabilities use only discovered labels. Actual new labels can change the learning objective; additional storage alone does not add classes.
Use Hash for identifier equality without a persistent vocabulary. Cluster shares latent representations between labels but still keeps growing per-label state.
Unknown Values And Prediction
At evaluation, a label outside the learned mapping remains valued; it does not become null. Its content representation depends on the datatype:
| Type | Unknown content |
|---|---|
| Category | Zero categorical input content plus its value-state embedding. Unavailable reconstruction targets supply no categorical gradient; coverage and all-target accuracy report their exclusion from conditional quality metrics. |
| Set | Known membership bits plus distinct unavailable-member counts. A learned unavailable-input contribution can distinguish unknown from empty sets; it cannot recover unknown identities. |
| Cluster | A shared unavailable assignment. Unknown targets do not drive label reconstruction or balancing; coverage reports their exclusion. |
These types default to p_unavailable=0.01, which simulates unavailable content during training. All three perturb inputs only, preserving the original reconstruction answers. This changes input content, not membership in the learned vocabulary or pristine exposure counts. See the datatype pages for their respective loss and coverage definitions: a Set counts memberships, where Category and Cluster count scalar targets.
Predictions name only populated vocabulary entries. Category and Cluster label probabilities are normalized over those entries; Set emits their independent membership probabilities. None can name an unseen label. A high probability does not establish that a request belongs to the known vocabulary. Evaluate unknown-label coverage alongside content accuracy, which excludes unknown targets for Category and Cluster.
Cold input identities
Simulated unavailable inputs teach prediction from the context that remains. They cannot teach the identity-specific effect of an unseen arbitrary ID. A model can legitimately remain confident when other fields are decisive; there is no universal OOV confidence cap. Use entity-disjoint or time-respecting validation to assess the actual cold-start population, not just a stratified row split. Evaluate proper scores such as NLL or Brier score separately for known and unseen input groups.
p_unavailable is an explicit input-augmentation policy, not an estimate of how often a category will be missing at deployment. Increasing it can improve the fallback while weakening use of known identity. Select it on a separate development split; do not learn a vocabulary from validation to conceal OOVs. P061 measures both regimes and includes decisive-context controls. Its synthetic missing-ID population does not establish robustness to arbitrary new-population effects.
Vocabulary admission activates an unused or newly allocated representation. It does not train that representation and can change predictions immediately. Keep serving vocabularies frozen, and evaluate a separately continued-training artifact before promotion. Counts measure exposures, not representation competence.
At the start of each Lightning validation, test, or prediction loop, RelFlow logs one warning per field if any populated vocabulary entry has fewer than 10 training observations. This includes validation and sanity checks during fitting. The warning reports the field address, affected-entry count, vocabulary size, and lowest exposure count without logging label values. Empty vocabularies, unused slots, and the counter’s smoothing prior are excluded. Evaluation does not add observations; the warning does not change predictions or losses. This is a loop-start diagnostic, not a check on every batch or direct model.predict(...) call. Ten exposures are a warning threshold, not a guarantee that a representation has been learned.
P066 isolates this failure across successive training cohorts: input admission can change reconstruction NLL even with fixed masks, fixed output labels, and complete target coverage. Zero-content and gated-content candidates remove that jump but regress other learning proofs; they have not replaced the current implementation. For pretraining targets, see coverage-aware evaluation.
Workers And Distributed Training
Data workers encode immutable dictionaries local to each batch. The training process binds those dictionaries to the model’s current vocabulary before forward, admits the new labels, and remaps inputs, targets, and exposure counts. Prefetched batches remain valid across growth because their local IDs are resolved when consumed. Labels are available to their first training batch, including with multiple workers.
Under DDP, every rank gathers that batch’s dictionaries and applies the same ordered admission. When parameters grow, RelFlow replaces the DDP wrapper during the current fit, before the affected batch enters forward, and migrates optimizer state to the grown parameters.
Growth also happens before the affected batch during gradient accumulation (accumulate_grad_batches > 1). Before replacing the DDP wrapper, RelFlow synchronizes which parameters have gradients and their partial gradients across ranks. Resizing preserves these gradients, including contributions from parameters used only in earlier microbatches, and accumulation continues.
Automatic growth supports single-device training and standard eager Lightning DDP with automatic optimization and static_graph=False; DDP growth during accumulation requires dense gradients. FSDP, DeepSpeed, other sharded backends, compiled DDP, and DDP configurations with native mixed precision, custom communication hooks, or delayed all-reduce are unsupported for growth.
Checkpoints record the model’s admitted vocabulary and allocated rows. Prefetching alone does not admit labels or record training exposures. Integer slots are local to a trained model; preserve its artifact and inspect its mapping when reusing it.
Inspect And Reuse The Mapping
After training the example model:
merchant_labels = rf.Category.vocabulary(model, rf.Address("orders", "merchant"))
merchant_counts = rf.Category.counts(model, rf.Address("orders", "merchant"))
tag_labels = rf.Set.vocabulary(model, rf.Address("orders", "tags"))
merchant_label_count = len(merchant_labels)Vocabulary accessors return immutable tuples in slot order. Category counts are pristine training exposures for populated labels, excluding the smoothing prior and unavailable values. Repeated epochs count again; these are not unique-record counts. DDP exposure counts synchronize at epoch end and before the evaluation-loop warning checks. New training labels are counted from their first consumed batch. rf.Cluster.vocabulary(model, address) provides the same mapping inspection for Cluster fields.
Preprocessors can inspect established mappings through encoding_context. Training preprocessing runs before vocabulary admission: filtering new labels against that snapshot would prevent them from being learned. Normalize labels there, and reserve vocabulary-based filtering for an explicit application policy. See Preprocessing.
Save/load preserves the mapping and associated model state. Fine-tuning continues learning from it; freezing parameter gradients alone does not freeze vocabulary admission. Use prediction stages for a fixed vocabulary.
Cluster also has an explicit assignment API that can add labels and grow storage on an idle model outside training.
Automatic growth needs no schema update. Resetting a field discards its learned vocabulary and runtime state. Review Schema Mutation before explicitly rebuilding a trained field.