Relational batches
RelationalBatch is the stable contract shared by every backend and by RelativeDB’s
native engine. Integer tensors describe topology, value tensors carry already encoded
model inputs, and two boolean masks mark padding and targets.
Fields
Field |
Shape |
Purpose |
|---|---|---|
|
|
Row/node identity for each cell |
|
|
Foreign-key parent node identities, |
|
|
Column vocabulary identity |
|
|
Table vocabulary identity |
|
|
|
|
|
|
|
|
|
|
|
Normalized numeric channel |
|
|
Normalized timestamp channel |
|
|
Boolean channel as floats |
|
|
User-encoded text values |
|
|
User-encoded column descriptions |
Node identities can be production-scale integers such as primary keys; the model compares
them for equality and never uses them as array indices. Column and table identities are
per-batch vocabulary IDs, so first-seen numbering within each batch is fine. A cell with
up to five foreign-key parents lists their node identities in f2p_nbr_idxs and pads the
rest with -1.
Cells stay in the order you provide them. Backends may reorder internally for speed, but
token_scores and embeddings always come back in caller order.
How the Model Reads a Batch
Each cell’s input state starts from its encoded column name. The value channel selected
by sem_types is added for regular cells. Target cells receive a learned mask embedding
for their semantic type, and their value channel is ignored. Attention then flows along
three relations derived from the index fields: cells of the same node or its parents,
cells whose key is a foreign-key parent of the query’s node, and cells sharing a column
within a table. Padding is excluded from all three.
Constructing a Batch
The constructor accepts numpy arrays, torch tensors, or nested lists and canonicalizes
them: index fields become int64, masks become bool (so uint8 inputs work), value
channels become floating point, and [B, S] scalar channels gain the trailing axis.
Validation runs immediately and raises ValueError naming the first offending field.
from_mapping builds a batch from a dictionary and accepts RelativeDB’s short aliases:
from relational_transformers import RelationalBatch
batch = RelationalBatch.from_mapping({
"node_idxs": node_idxs,
"f2p": f2p, # alias of f2p_nbr_idxs
"col_idxs": col_idxs, # alias of col_name_idxs
"table_idxs": table_idxs, # alias of table_name_idxs
"is_padding": is_padding,
"sem_types": sem_types,
"is_target": is_target, # alias of is_targets
"number_v": number_v, # alias of number_values
"datetime_v": datetime_v,
"boolean_v": boolean_v,
"text_v": text_v,
"col_name_v": col_name_v,
})
as_dict() returns the canonical fields under their full names, so a batch round-trips
through from_mapping(batch.as_dict()). numpy() produces the same dictionary as CPU
numpy arrays, which is what the Triton backend consumes.
Validation rules
Construction rejects a batch when:
node_idxsis not two-dimensional, or any per-cell field disagrees with its[B, S]shape;f2p_nbr_idxsis not[B, S, 5];a scalar channel is not
[B, S, 1]after canonicalization;col_name_valuesandtext_valuesdiffer in shape;any
sem_typesvalue falls outside[0, 3];a cell is both padding and a target;
any value channel contains NaN or infinity.
Encode a missing value as 0.0 with the correct semantic type; NaN fails validation.
All-text Convenience Batches
from_text_cells builds a single-row batch from [cells, 2*d_text] arrays where each
row is a column embedding followed by a value embedding. Optional keywords supply node
identities, foreign-key parents, and table IDs. Everything is typed as text, so use it
for prototypes and text-only contexts, and build the full batch when scalar channels
matter.
batch = RelationalBatch.from_text_cells(
cells,
target=0,
node_idxs=[7, 7, 8],
parents={2: [7]},
)
Device Movement and Ablation
batch.to(device) returns a copy on the target device, with an optional dtype for the
floating-point channels. batch.ablate(positions) pads out the selected cells while
positions and node identities stay stable; the Ablation page builds on it.