# TIGER (Semantic ID Generative Retrieval)

> NeurIPS 2023 - retrieval as sequence generation: the model DECODES the next item id code by code, so the catalogue never appears as a softmax over millions of rows.

Pick when the catalogue is too large for a dot-product retrieval head, or when cold-start items need to be reachable through their content. Pair with the RQ-VAE tokenizer.

- Category: Recommendation
- Paper: Rajput et al. (2023). Recommender Systems with Generative Retrieval. NeurIPS 2023 (https://arxiv.org/abs/2305.05065)
- Layers: 14
- Parameters: 1.05M
- Input shape (batchless): 1 × 200
- Output shape: 1 × 4 × 1024
- Verifier verdict: pass
- Graph JSON: https://neurarch.com/templates/tiger/model.json
- Open on the canvas: https://neurarch.com/?template=tiger

## Structure

| # | Layer | Type | Parameters | Output shape |
| --- | --- | --- | --- | --- |
| 1 | History semantic IDs (50 items x 4 codes) | Input | shape=[1, 200] | 1 × 200 |
| 2 | Code Embed (4 x 256 codebooks) | Embedding | vocabSize=1024 | 1 × 200 × 128 |
| 3 | Pos Encoding | Positional Encoding | maxLen=256 | 1 × 200 × 128 |
| 4 | Encoder Block 1 | Transformer Block | numHeads=4, numLayers=1 | 1 × 200 × 128 |
| 5 | Encoder Block 2 | Transformer Block | numHeads=4, numLayers=1 | 1 × 200 × 128 |
| 6 | Decoded codes so far | Input | shape=[1, 4] | 1 × 4 |
| 7 | Code Embed (shared) | Embedding | vocabSize=1024 | 1 × 4 × 128 |
| 8 | Pos Encoding | Positional Encoding | maxLen=8 | 1 × 4 × 128 |
| 9 | Masked Self-Attention | Causal Attention | embedDim=128, numHeads=4 | 1 × 4 × 128 |
| 10 | Cross-Attention to history | Cross-Attention | embedDim=128, numHeads=4 | 1 × 4 × 128 |
| 11 | Decoder FFN | Feed Forward | embedDim=128, ffDim=512 | 1 × 4 × 128 |
| 12 | LayerNorm | LayerNorm | normalizedShape=128 | 1 × 4 × 128 |
| 13 | Codebook Head (1024 codes) | LM Head | hiddenSize=128, vocabSize=1024 | 1 × 4 × 1024 |
| 14 | next code logits | Output |  | 1 × 4 × 1024 |

## Verifier findings

No finding. Shapes propagate end to end and no advisory rule fires.

## Exported PyTorch (first 46 lines)

```python
# Architecture designed with Neurarch: https://neurarch.com
# PyTorch: compatible with Python 3.8+ and torch>=1.12
# Colab: pip install torch torchvision  (usually pre-installed)

import torch
import torch.nn as nn
import torch.nn.functional as F
from typing import Tuple

class TIGERSemanticIDGenerativeRetrieval(nn.Module):
    def __init__(self):
        super().__init__()

        self.embedding_1 = nn.Embedding(1024, 128)
        self.transformerBlock_1 = nn.TransformerEncoderLayer(d_model=128, nhead=4, dim_feedforward=512, batch_first=True)
        self.transformerBlock_2 = nn.TransformerEncoderLayer(d_model=128, nhead=4, dim_feedforward=512, batch_first=True)
        self.embedding_2 = nn.Embedding(1024, 128)
        self.causalAttention_1 = nn.MultiheadAttention(embed_dim=128, num_heads=4, batch_first=True)
        self.crossAttention_1 = nn.MultiheadAttention(embed_dim=128, num_heads=4, batch_first=True)
        self.feedForward_1 = nn.Sequential(
            nn.Linear(128, 512),
            nn.ReLU(),
            nn.Linear(512, 128)
        )
        self.layerNorm_1 = nn.LayerNorm(128)
        self.lmHead_1 = nn.Linear(128, 1024, bias=False)

    def forward(self, src, tgt=None):
        # History semantic IDs (50 items x 4 codes) shape: [1,200]
        # Decoded codes so far shape: [1,4]
        embedding_nc_emb = self.embedding_1(src)
        # positionalEncoding: add positional encoding externally (e.g. sinusoidal or learned PE)
        transformer_block_enc1 = self.transformerBlock_1(embedding_nc_emb)
        transformer_block_enc2 = self.transformerBlock_2(transformer_block_enc1)
        embedding_ec_emb = self.embedding_2(tgt)
        # positionalEncoding: add positional encoding externally (e.g. sinusoidal or learned PE)
        causal_attention_c_self = self.causalAttention_1(embedding_ec_emb, embedding_ec_emb, embedding_ec_emb)[0]
        cross_attention_xattn = self.crossAttention_1(causal_attention_c_self, transformer_block_enc2, transformer_block_enc2)[0]
        feed_forward_dec_ff = self.feedForward_1(cross_attention_xattn)
        layer_norm_c_norm = self.layerNorm_1(feed_forward_dec_ff)
        lm_head_head = self.lmHead_1(layer_norm_c_norm)
        # Output
        return lm_head_head


if __name__ == '__main__':
```

## Machine access

- Every architecture: https://neurarch.com/a/index.json
- Verify a graph of your own: `POST https://www.neurarch.com/api/v1/check` (see https://neurarch.com/developer.html)
- MCP server, so an agent edits the graph with the checks in the loop: https://neurarch.com/docs/mcp.md
