The dataloader consumes saved PRAGMA Parquet shards produced by PRAGMADataset.write_kv; it does not refit or modify the tokenizer. It groups rows by entity, separates profile/lifelong state from events, applies load-time limits, packs variable-length events, and emits batches for PyTorch or fastai.
PRAGMADataset creates the saved preprocessing contract: tokenizer.json plus entity-sharded Parquet. write_kv fits the tokenizer if needed, tokenizes profile and event sources, and writes the shards. The dataloader starts only after this step.
out = Path('data/ml100k_pragma')ds = PRAGMADataset(profile=users_src, events=[ratings_src], entity_col='user_id', out_path=out)ds.show_summary()
Reload with Tokenizer.load(out/'tokenizer.json') and discover shards with sorted(out.glob('shard_*.parquet')). Each row is one token. event_idx=-1 identifies profile/lifelong rows; non-negative event_idx identifies event rows. The loader operates entirely on these saved artifacts.
tok = Tokenizer.load(out/'tokenizer.json')shard = pl.read_parquet(out/'shard_0.parquet')shard.shape, shard.columns, shard.head()
The loader represents each token as (key_id, val_id, val_pos) with a separate logsec value. Profile and lifelong sequences are padded per batch. Event tokens remain packed flat, with offsets and user indices preserving event boundaries. Limits are applied during loading, not tokenization.
Convert one entity into a record
user_rec converts one entity’s rows into profile tokens, lifelong tokens, event-token tensors, event times, and calendar features. prep_shard applies the independent limits for profile tokens, lifelong tokens, retained events, and tokens per event before record construction.
pack_batch pads profile and lifelong tensors, concatenates event tokens into one flat tensor, and returns event_offsets, event_user, event_time, cal, history_offsets, and uids. uids are retained for joins and traceability; model structure is represented by the batch-local offset/index tensors.
detailed plan
The current fitting convention is:
PRAGMADataset.write_kv(...) is the preprocessing/fitting stage.
It fits or loads the tokenizer, tokenizes profile and event sources, assigns each entity to a shard, and writes saved parquet shards plus tokenizer.json.
The dataloader does not refit anything. It only consumes the saved files.
mask_batch performs event-value MLM masking using token-, event-, and user-local key-level probabilities. pragma_dl returns a PyTorch DataLoader; PRAGMADataLoader.from_path reloads a tokenizer and shard directory. The loader supports token-budget batching, optional shuffling, masking, and worker-based shard splitting.
MLM masking assumptions
We mask only event value tokens, not profile or lifelong tokens.
For each user record, selected mask positions come from the union of three sources:
Token-level masking: each event token is selected independently with probability p_tok.
Event-level masking: each event is selected independently with probability p_event, and all value tokens in that event are selected.
Semantic key-level masking: keys are selected independently per user with probability p_key, and all event values for those keys are selected for that user.
After positions are selected:
selected positions become MLM targets using their original val_id
most selected input values are replaced with [MASK]
a small fraction are replaced with [UNK]
[UNK] positions are excluded from the loss by setting their label to -100
So the effective target mask is:
This follows the paper’s intent while treating key-level masking as sample-local: selected keys affect only the user record where they were sampled, not other users in the same batch.