Why the tokenizer is the bottleneck
Most of the interesting variance in generative recommendation sits in how you build the codes, not in the model that consumes them. A tokenizer that collapses distinct items into the same code caps your ceiling before training starts. One that ignores behavior produces codes that are semantically tidy and commercially useless. This is the part of the stack we think is underbuilt, and it is where this product sits.How the codes are built
Encode content
Each item’s text and images go through frozen encoders, one per modality, concatenated into a single content vector. Nothing about interactions yet.
Quantize residually
An RQ-VAE assigns a code at level 1, takes the residual, assigns a code at level 2, and so on. Level 1 lands the item in a coarse neighborhood, later levels refine within it.
Fold in collaborative signal
Co-occurrence in real user sequences pulls on the quantizer, so items that get consumed together land near each other in code space. See below.
Resolve collisions
Items that quantize identically get a disambiguating suffix, so a semantic ID always maps to exactly one item.
Collaborative signal, and why not to fuse it directly
The obvious move is to concatenate a collaborative filtering embedding onto the content embedding before quantizing. It does not hold up. CF embeddings drift with popularity, so an item’s semantic ID would change as it trends, and a code that means something different this month is not an identifier. PLUM makes the better argument: use behavior as a training objective rather than an input feature. A co-occurrence contrastive loss on the quantizer pushes items that appear together in user sequences toward nearby codes, while the code itself stays a function of stable content. You get the collaborative structure without inheriting the drift. UTGRec arrives at a similar place from the transfer direction, using co-occurrence alignment and reconstruction so a single tokenizer generalizes across domains rather than being refit per catalog.Multi-resolution codebooks
Uniform codebooks give every level the same cardinality, which wastes capacity: by level 4 there is very little residual entropy left to encode, and a wide codebook there mostly sits empty. PLUM sizes the codebook as a function of depth,2048 / 2^(level-1):
Paired with progressive masking, where training randomly truncates to the first
r levels, this forces an actual hierarchy: the level-1 code has to be meaningful on its own, not just meaningful in combination with the levels below it. That property is what makes constrained beam search work well at decode time, because pruning on a prefix prunes a coherent region.
The API
Four endpoints. Fit a tokenizer, check on it, assign IDs, generate.Cold start
This is the property that tends to matter most in practice. A semantic ID is a function of content, so an item that went live sixty seconds ago and has zero interactions still gets a code in the right neighborhood, and the model can recommend it immediately. Pass a brand-new item toPOST /semantic-ids and it is assigned against the existing codebooks without refitting. The response flags it:
What we are still deciding
Writing this page is partly how we are working out the product. Open questions, and we would rather hear from you than guess:Should the tokenizer be per-tenant or universal?
Should the tokenizer be per-tenant or universal?
UTGRec argues for one tokenizer transferring across domains. A per-tenant fit is likely better on your catalog in isolation. The tradeoff is cold start quality on day one versus ceiling at maturity.
Do you want the codes, or the recommendations?
Do you want the codes, or the recommendations?
Some teams want
POST /generate and nothing else. Others want to export semantic IDs and feed them into a ranker they already own. These imply fairly different products.How much of the catalog do you actually have content for?
How much of the catalog do you actually have content for?
The whole approach assumes items carry real text or images. Catalogs where half the items are a bare SKU string change the design.
References
- PLUM: Adapting Pre-trained Language Models for Industrial-scale Generative Recommendations. SID-v2, co-occurrence contrastive collaborative signal, multi-resolution codebooks, progressive masking.
- Universal Item Tokenization for Transferable Generative Recommendation (UTGRec). Tree-structured codebooks, dual content decoders, cross-domain transfer.
- MiniOneRec. Open-source end to end pipeline: SID construction, supervised fine-tuning, then GRPO reinforcement learning with constrained beam search. Also hosts TS-Rec, implementing fine-grained semantics integration.

