{
"cells": [
{
"cell_type": "markdown",
"metadata": {},
"source": [
"Copyright (c) Recommenders contributors. \n",
"\n",
"Licensed under the MIT License. "
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"# Sequential Recommender Quick Start\n",
"\n",
"### Example: A2SVD : Adaptive User Modeling with Long and Short-Term Preferences for Personailzed Recommendation\n",
"Unlike a general recommender such as Matrix Factorization or xDeepFM (in the repo) which doesn't consider the order of the user's activities, sequential recommender systems take the sequence of the user behaviors as context and the goal is to predict the items that the user will interact in a short time (in an extreme case, the item that the user will interact next).\n",
"\n",
"This notebook aims to give you a quick example of how to train a sequential model based on a public Amazon dataset. Currently, we can support NextItNet \\[4\\], GRU \\[2\\], Caser \\[3\\], A2SVD \\[1\\], and SUM \\[5\\]. Without loss of generality, this notebook takes the [A2SVD model](https://www.microsoft.com/en-us/research/uploads/prod/2019/07/IJCAI19-ready_v1.pdf) for example.\n",
"A2SVD \\[1\\] is a deep learning-based model that captures long-term user preferences: it adopts an attentive \"Asymmetric-SVD\" paradigm, summarizing the user's whole behavior history into a long-term representation with an attention mechanism.\n",
"\n",
"In this notebook, we test A2SVD on a subset of the public dataset: [Amazon_reviews](http://snap.stanford.edu/data/amazon/productGraph/categoryFiles/reviews_Movies_and_TV_5.json.gz) and [Amazon_metadata](http://snap.stanford.edu/data/amazon/productGraph/categoryFiles/meta_Movies_and_TV.json.gz)\n",
"\n",
"This notebook is tested under TF 2.6. **Note:** SLi_Rec \\[1\\], the time-aware model from the same paper, has moved to its own PyTorch notebook: [slirec_amazon.ipynb](slirec_amazon.ipynb). "
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## 0. Global Settings and Imports"
]
},
{
"cell_type": "code",
"execution_count": 1,
"metadata": {
"execution": {
"iopub.execute_input": "2026-07-21T14:56:44.734809Z",
"iopub.status.busy": "2026-07-21T14:56:44.734033Z",
"iopub.status.idle": "2026-07-21T14:56:52.405362Z",
"shell.execute_reply": "2026-07-21T14:56:52.401172Z"
}
},
"outputs": [
{
"name": "stderr",
"output_type": "stream",
"text": [
"2026-07-21 16:56:45.348592: I tensorflow/core/util/port.cc:113] oneDNN custom operations are on. You may see slightly different numerical results due to floating-point round-off errors from different computation orders. To turn them off, set the environment variable `TF_ENABLE_ONEDNN_OPTS=0`.\n",
"2026-07-21 16:56:45.448916: E external/local_xla/xla/stream_executor/cuda/cuda_dnn.cc:9261] Unable to register cuDNN factory: Attempting to register factory for plugin cuDNN when one has already been registered\n",
"2026-07-21 16:56:45.448993: E external/local_xla/xla/stream_executor/cuda/cuda_fft.cc:607] Unable to register cuFFT factory: Attempting to register factory for plugin cuFFT when one has already been registered\n",
"2026-07-21 16:56:45.451479: E external/local_xla/xla/stream_executor/cuda/cuda_blas.cc:1515] Unable to register cuBLAS factory: Attempting to register factory for plugin cuBLAS when one has already been registered\n",
"2026-07-21 16:56:45.466224: I tensorflow/core/platform/cpu_feature_guard.cc:182] This TensorFlow binary is optimized to use available CPU instructions in performance-critical operations.\n",
"To enable the following instructions: AVX2 AVX512F AVX512_VNNI AVX512_BF16 AVX_VNNI FMA, in other operations, rebuild TensorFlow with the appropriate compiler flags.\n"
]
},
{
"name": "stderr",
"output_type": "stream",
"text": [
"2026-07-21 16:56:46.896794: W tensorflow/compiler/tf2tensorrt/utils/py_utils.cc:38] TF-TRT Warning: Could not find TensorRT\n"
]
},
{
"name": "stdout",
"output_type": "stream",
"text": [
"System version: 3.11.14 (main, Jan 14 2026, 19:35:32) [Clang 21.1.4 ]\n",
"Tensorflow version: 2.15.1\n"
]
}
],
"source": [
"import os\n",
"import sys\n",
"import tensorflow.compat.v1 as tf\n",
"tf.get_logger().setLevel('ERROR') # only show error messages\n",
"\n",
"from recommenders.utils.timer import Timer\n",
"from recommenders.utils.constants import SEED\n",
"from recommenders.models.deeprec.deeprec_utils import (\n",
" prepare_hparams\n",
")\n",
"from recommenders.datasets.amazon_reviews import download_and_extract, data_preprocessing\n",
"from recommenders.models.deeprec.models.sequential.asvd import A2SVDModel as SeqModel\n",
"#### SLi-Rec now has its own PyTorch notebook (slirec_amazon.ipynb); to use another model, use one of these:\n",
"# from recommenders.models.deeprec.models.sequential.caser import CaserModel as SeqModel\n",
"# from recommenders.models.deeprec.models.sequential.gru import GRUModel as SeqModel\n",
"# from recommenders.models.deeprec.models.sequential.sum import SUMModel as SeqModel\n",
"#from recommenders.models.deeprec.models.sequential.nextitnet import NextItNetModel\n",
"from recommenders.models.deeprec.io.sequential_iterator import SequentialIterator\n",
"#from recommenders.models.deeprec.io.nextitnet_iterator import NextItNetIterator\n",
"from recommenders.utils.notebook_utils import store_metadata\n",
"\n",
"print(f\"System version: {sys.version}\")\n",
"print(f\"Tensorflow version: {tf.__version__}\")\n",
"\n"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"#### Parameters"
]
},
{
"cell_type": "code",
"execution_count": 2,
"metadata": {
"execution": {
"iopub.execute_input": "2026-07-21T14:56:52.410074Z",
"iopub.status.busy": "2026-07-21T14:56:52.409402Z",
"iopub.status.idle": "2026-07-21T14:56:52.418906Z",
"shell.execute_reply": "2026-07-21T14:56:52.415532Z"
},
"tags": [
"parameters"
]
},
"outputs": [],
"source": [
"EPOCHS = 10\n",
"BATCH_SIZE = 400\n",
"RANDOM_SEED = SEED # Set None for non-deterministic result\n",
"\n",
"data_path = os.path.join(\"..\", \"..\", \"tests\", \"resources\", \"deeprec\", \"slirec\")\n",
"\n",
"## ATTENTION: change to the corresponding config file, e.g., caser.yaml for CaserModel, sum.yaml for SUMModel\n",
"yaml_file = '../../recommenders/models/deeprec/config/asvd.yaml' "
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## 1. Input data format\n",
"The input data contains 8 columns, i.e., ` ` columns are seperated by `\"\\t\"`. item_id and category_id denote the target item and category, which means that for this instance, we want to guess whether user user_id will interact with item_id at timestamp. `` columns record the user behavior list up to ``, elements are separated by commas. `` is a binary value with 1 for positive instances and 0 for negative instances. One example for an instance is: \n",
"\n",
"`1 A1QQ86H5M2LVW2 B0059XTU1S Movies 1377561600 B002ZG97WE,B004IK30PA,B000BNX3AU,B0017ANB08,B005LAIHW2 Movies,Movies,Movies,Movies,Movies 1304294400,1304812800,1315785600,1316304000,1356998400` \n",
"\n",
"In data preprocessing stage, we have a script to generate some ID mapping dictionaries, so user_id, item_id and category_id will be mapped into interager index starting from 1. And you need to tell the input iterator where is the ID mapping files are. (For example, in the next section, we have some mapping files like user_vocab, item_vocab, and cate_vocab). The data preprocessing script is at [recommenders/dataset/amazon_reviews.py](../../recommenders/dataset/amazon_reviews.py), you need to call the `_create_vocab(train_file, user_vocab, item_vocab, cate_vocab)` function. Note that ID vocabulary only creates from the train_file, so the new IDs in valid_file or test_file will be regarded as unknown IDs and assigned with a defualt 0 index.\n",
"\n",
"The models in this notebook are not time-aware (only the [SLi_Rec model](slirec_amazon.ipynb) is), so you can just pad some meaningless timestamp in the data files to fill up the format, the models will ignore these columns.\n",
"\n",
"We use Softmax to the loss function. In training and evalution stage, we group 1 positive instance with `num_ngs` negative instances. Pair-wise ranking can be regarded as a special case of softmax ranking, where `num_ngs` is set to 1. \n",
"\n",
"More specifically, for training and evalation, you need to organize the data file such that each one positive instance is followed by `num_ngs` negative instances. Our program will take `1+num_ngs` lines as a unit for Softmax calculation. `num_ngs` is a parameter you need to pass to the `prepare_hparams`, `fit` and `run_eval` function. `train_num_ngs` in `prepare_hparams` denotes the number of negative instances for training, where a recommended number is 4. `valid_num_ngs` and `num_ngs` in `fit` and `run_eval` denote the number in evalution. In evaluation, the model calculates metrics among the `1+num_ngs` instances. For the `predict` function, since we only need to calcuate a score for each individual instance, there is no need for `num_ngs` setting. More details and examples will be provided in the following sections.\n",
"\n",
"For training stage, if you don't want to prepare negative instances, you can just provide positive instances and set the parameter `need_sample=True, train_num_ngs=train_num_ngs` for function `prepare_hparams`, our model will dynamicly sample `train_num_ngs` instances as negative samples in each mini batch.\n",
"\n",
"### Amazon dataset\n",
"Now let's start with a public dataset containing product reviews and metadata from Amazon, which is widely used as a benchmark dataset in recommemdation systems field."
]
},
{
"cell_type": "code",
"execution_count": 3,
"metadata": {
"execution": {
"iopub.execute_input": "2026-07-21T14:56:52.423549Z",
"iopub.status.busy": "2026-07-21T14:56:52.423223Z",
"iopub.status.idle": "2026-07-21T14:56:52.433711Z",
"shell.execute_reply": "2026-07-21T14:56:52.430789Z"
},
"scrolled": false
},
"outputs": [],
"source": [
"\n",
"# for test\n",
"train_file = os.path.join(data_path, r'train_data')\n",
"valid_file = os.path.join(data_path, r'valid_data')\n",
"test_file = os.path.join(data_path, r'test_data')\n",
"user_vocab = os.path.join(data_path, r'user_vocab.pkl')\n",
"item_vocab = os.path.join(data_path, r'item_vocab.pkl')\n",
"cate_vocab = os.path.join(data_path, r'category_vocab.pkl')\n",
"output_file = os.path.join(data_path, r'output.txt')\n",
"\n",
"reviews_name = 'reviews_Movies_and_TV_5.json'\n",
"meta_name = 'meta_Movies_and_TV.json'\n",
"reviews_file = os.path.join(data_path, reviews_name)\n",
"meta_file = os.path.join(data_path, meta_name)\n",
"train_num_ngs = 4 # number of negative instances with a positive instance for training\n",
"valid_num_ngs = 4 # number of negative instances with a positive instance for validation\n",
"test_num_ngs = 9 # number of negative instances with a positive instance for testing\n",
"sample_rate = 0.01 # sample a small item set for training and testing here for fast example\n",
"\n",
"input_files = [reviews_file, meta_file, train_file, valid_file, test_file, user_vocab, item_vocab, cate_vocab]\n",
"\n",
"if not os.path.exists(train_file):\n",
" download_and_extract(reviews_name, reviews_file)\n",
" download_and_extract(meta_name, meta_file)\n",
" data_preprocessing(*input_files, sample_rate=sample_rate, valid_num_ngs=valid_num_ngs, test_num_ngs=test_num_ngs)\n",
" #### uncomment this for the NextItNet model, because it does not need to unfold the user history\n",
" # data_preprocessing(*input_files, sample_rate=sample_rate, valid_num_ngs=valid_num_ngs, test_num_ngs=test_num_ngs, is_history_expanding=False)\n"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"#### 1.1 Prepare hyper-parameters\n",
"prepare_hparams() will create a full set of hyper-parameters for model training, such as learning rate, feature number, and dropout ratio. We can put those parameters in a yaml file (a complete list of parameters can be found under our config folder) , or pass parameters as the function's parameters (which will overwrite yaml settings).\n",
"\n",
"Parameters hints: \n",
"`need_sample` controls whether to perform dynamic negative sampling in mini-batch. \n",
"`train_num_ngs` indicates how many negative instances followed by one positive instances. \n",
"Examples: \n",
"(1) `need_sample=True and train_num_ngs=4`: There are only positive instances in your training file. Our model will dynamically sample 4 negative instances for each positive instances in mini-batch. Note that if need_sample is set to True, train_num_ngs should be greater than zero. \n",
"(2) `need_sample=False and train_num_ngs=4`: In your training file, each one positive line is followed by 4 negative lines. Note that if need_sample is set to False, you must provide a traiing file with negative instances, and train_num_ngs should match the number of negative number in your training file."
]
},
{
"cell_type": "code",
"execution_count": 4,
"metadata": {
"execution": {
"iopub.execute_input": "2026-07-21T14:56:52.437454Z",
"iopub.status.busy": "2026-07-21T14:56:52.437081Z",
"iopub.status.idle": "2026-07-21T14:56:52.452844Z",
"shell.execute_reply": "2026-07-21T14:56:52.448786Z"
},
"scrolled": true
},
"outputs": [],
"source": [
"### NOTE: \n",
"### remember to use `_create_vocab(train_file, user_vocab, item_vocab, cate_vocab)` to generate the user_vocab, item_vocab and cate_vocab files, if you are using your own dataset rather than using our demo Amazon dataset.\n",
"hparams = prepare_hparams(yaml_file, \n",
" embed_l2=0., \n",
" layer_l2=0., \n",
" learning_rate=0.001, # set to 0.01 if batch normalization is disable\n",
" epochs=EPOCHS,\n",
" batch_size=BATCH_SIZE,\n",
" show_step=20,\n",
" MODEL_DIR=os.path.join(data_path, \"model/\"),\n",
" SUMMARIES_DIR=os.path.join(data_path, \"summary/\"),\n",
" user_vocab=user_vocab,\n",
" item_vocab=item_vocab,\n",
" cate_vocab=cate_vocab,\n",
" need_sample=True,\n",
" train_num_ngs=train_num_ngs, # provides the number of negative instances for each positive instance for loss computation.\n",
" )"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"#### 1.2 Create data loader\n",
"Designate a data iterator for the model. All our sequential models use SequentialIterator. \n",
"data format is introduced aboved. \n",
"\n",
" Validation and testing data are files after negative sampling offline with the number of `` and ``."
]
},
{
"cell_type": "code",
"execution_count": 5,
"metadata": {
"execution": {
"iopub.execute_input": "2026-07-21T14:56:52.456860Z",
"iopub.status.busy": "2026-07-21T14:56:52.456509Z",
"iopub.status.idle": "2026-07-21T14:56:52.463500Z",
"shell.execute_reply": "2026-07-21T14:56:52.461068Z"
}
},
"outputs": [],
"source": [
"input_creator = SequentialIterator\n",
"#### uncomment this for the NextItNet model, because it needs a special data iterator for training\n",
"#input_creator = NextItNetIterator"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## 2. Create model\n",
"When both hyper-parameters and data iterator are ready, we can create a model:"
]
},
{
"cell_type": "code",
"execution_count": 6,
"metadata": {
"execution": {
"iopub.execute_input": "2026-07-21T14:56:52.467650Z",
"iopub.status.busy": "2026-07-21T14:56:52.467331Z",
"iopub.status.idle": "2026-07-21T14:56:59.407022Z",
"shell.execute_reply": "2026-07-21T14:56:59.403165Z"
},
"scrolled": true
},
"outputs": [
{
"name": "stderr",
"output_type": "stream",
"text": [
"/home/u/run3x/wt-slirec-pytorch/recommenders/models/deeprec/models/base_model.py:701: UserWarning: `tf.layers.batch_normalization` is deprecated and will be removed in a future version. Please use `tf.keras.layers.BatchNormalization` instead. In particular, `tf.control_dependencies(tf.GraphKeys.UPDATE_OPS)` should not be used (consult the `tf.keras.layers.BatchNormalization` documentation).\n",
" curr_hidden_nn_layer = tf.compat.v1.layers.batch_normalization(\n",
"2026-07-21 16:56:54.456084: I external/local_xla/xla/stream_executor/cuda/cuda_executor.cc:887] could not open file to read NUMA node: /sys/bus/pci/devices/0000:64:00.0/numa_node\n",
"Your kernel may have been built without NUMA support.\n"
]
},
{
"name": "stderr",
"output_type": "stream",
"text": [
"2026-07-21 16:56:54.601724: I external/local_xla/xla/stream_executor/cuda/cuda_executor.cc:887] could not open file to read NUMA node: /sys/bus/pci/devices/0000:64:00.0/numa_node\n",
"Your kernel may have been built without NUMA support.\n",
"2026-07-21 16:56:54.601874: I external/local_xla/xla/stream_executor/cuda/cuda_executor.cc:887] could not open file to read NUMA node: /sys/bus/pci/devices/0000:64:00.0/numa_node\n",
"Your kernel may have been built without NUMA support.\n",
"2026-07-21 16:56:54.601892: W tensorflow/core/common_runtime/gpu/gpu_device.cc:2348] TensorFlow was not built with CUDA kernel binaries compatible with compute capability 12.0. CUDA kernels will be jit-compiled from PTX, which could take 30 minutes or longer.\n",
"2026-07-21 16:56:54.614459: I external/local_xla/xla/stream_executor/cuda/cuda_executor.cc:887] could not open file to read NUMA node: /sys/bus/pci/devices/0000:64:00.0/numa_node\n",
"Your kernel may have been built without NUMA support.\n",
"2026-07-21 16:56:54.614666: I external/local_xla/xla/stream_executor/cuda/cuda_executor.cc:887] could not open file to read NUMA node: /sys/bus/pci/devices/0000:64:00.0/numa_node\n",
"Your kernel may have been built without NUMA support.\n",
"2026-07-21 16:56:54.614715: I external/local_xla/xla/stream_executor/cuda/cuda_executor.cc:887] could not open file to read NUMA node: /sys/bus/pci/devices/0000:64:00.0/numa_node\n",
"Your kernel may have been built without NUMA support.\n",
"2026-07-21 16:56:54.614728: W tensorflow/core/common_runtime/gpu/gpu_device.cc:2348] TensorFlow was not built with CUDA kernel binaries compatible with compute capability 12.0. CUDA kernels will be jit-compiled from PTX, which could take 30 minutes or longer.\n",
"2026-07-21 16:56:55.307536: I external/local_xla/xla/stream_executor/cuda/cuda_executor.cc:887] could not open file to read NUMA node: /sys/bus/pci/devices/0000:64:00.0/numa_node\n",
"Your kernel may have been built without NUMA support.\n",
"2026-07-21 16:56:55.307662: I external/local_xla/xla/stream_executor/cuda/cuda_executor.cc:887] could not open file to read NUMA node: /sys/bus/pci/devices/0000:64:00.0/numa_node\n",
"Your kernel may have been built without NUMA support.\n",
"2026-07-21 16:56:55.307676: I tensorflow/core/common_runtime/gpu/gpu_device.cc:2022] Could not identify NUMA node of platform GPU id 0, defaulting to 0. Your kernel may not have been built with NUMA support.\n",
"2026-07-21 16:56:55.307730: I external/local_xla/xla/stream_executor/cuda/cuda_executor.cc:887] could not open file to read NUMA node: /sys/bus/pci/devices/0000:64:00.0/numa_node\n",
"Your kernel may have been built without NUMA support.\n",
"2026-07-21 16:56:55.307778: I tensorflow/core/common_runtime/gpu/gpu_device.cc:1929] Created device /job:localhost/replica:0/task:0/device:GPU:0 with 21233 MB memory: -> device: 0, name: NVIDIA GeForce RTX 5090 Laptop GPU, pci bus id: 0000:64:00.0, compute capability: 12.0\n"
]
},
{
"name": "stderr",
"output_type": "stream",
"text": [
"2026-07-21 16:56:56.472709: I external/local_xla/xla/stream_executor/cuda/cuda_executor.cc:887] could not open file to read NUMA node: /sys/bus/pci/devices/0000:64:00.0/numa_node\n",
"Your kernel may have been built without NUMA support.\n",
"2026-07-21 16:56:56.472909: I external/local_xla/xla/stream_executor/cuda/cuda_executor.cc:887] could not open file to read NUMA node: /sys/bus/pci/devices/0000:64:00.0/numa_node\n",
"Your kernel may have been built without NUMA support.\n",
"2026-07-21 16:56:56.472959: I external/local_xla/xla/stream_executor/cuda/cuda_executor.cc:887] could not open file to read NUMA node: /sys/bus/pci/devices/0000:64:00.0/numa_node\n",
"Your kernel may have been built without NUMA support.\n",
"2026-07-21 16:56:56.472970: W tensorflow/core/common_runtime/gpu/gpu_device.cc:2348] TensorFlow was not built with CUDA kernel binaries compatible with compute capability 12.0. CUDA kernels will be jit-compiled from PTX, which could take 30 minutes or longer.\n",
"2026-07-21 16:56:56.473706: I external/local_xla/xla/stream_executor/cuda/cuda_executor.cc:887] could not open file to read NUMA node: /sys/bus/pci/devices/0000:64:00.0/numa_node\n",
"Your kernel may have been built without NUMA support.\n",
"2026-07-21 16:56:56.473789: I tensorflow/core/common_runtime/gpu/gpu_device.cc:2022] Could not identify NUMA node of platform GPU id 0, defaulting to 0. Your kernel may not have been built with NUMA support.\n",
"2026-07-21 16:56:56.473849: I external/local_xla/xla/stream_executor/cuda/cuda_executor.cc:887] could not open file to read NUMA node: /sys/bus/pci/devices/0000:64:00.0/numa_node\n",
"Your kernel may have been built without NUMA support.\n",
"2026-07-21 16:56:56.473907: I tensorflow/core/common_runtime/gpu/gpu_device.cc:1929] Created device /job:localhost/replica:0/task:0/device:GPU:0 with 21233 MB memory: -> device: 0, name: NVIDIA GeForce RTX 5090 Laptop GPU, pci bus id: 0000:64:00.0, compute capability: 12.0\n",
"2026-07-21 16:56:56.522492: I tensorflow/compiler/mlir/mlir_graph_optimization_pass.cc:388] MLIR V1 optimization pass is not enabled\n"
]
}
],
"source": [
"model = SeqModel(hparams, input_creator, seed=RANDOM_SEED)\n",
"\n",
"## sometimes we don't want to train a model from scratch\n",
"## then we can load a pre-trained model like this: \n",
"#model.load_model(r'your_model_path')"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"Now let's see what is the model's performance at this point (without starting training):"
]
},
{
"cell_type": "code",
"execution_count": 7,
"metadata": {
"execution": {
"iopub.execute_input": "2026-07-21T14:56:59.412789Z",
"iopub.status.busy": "2026-07-21T14:56:59.412213Z",
"iopub.status.idle": "2026-07-21T14:57:48.116605Z",
"shell.execute_reply": "2026-07-21T14:57:48.112683Z"
}
},
"outputs": [
{
"name": "stderr",
"output_type": "stream",
"text": [
"2026-07-21 16:57:04.330171: I external/local_tsl/tsl/platform/default/subprocess.cc:304] Start cannot spawn child process: No such file or directory\n",
"2026-07-21 16:57:04.356633: W external/local_xla/xla/stream_executor/gpu/asm_compiler.cc:225] Falling back to the CUDA driver for PTX compilation; ptxas does not support CC 12.0\n",
"2026-07-21 16:57:04.356730: W external/local_xla/xla/stream_executor/gpu/asm_compiler.cc:228] Used ptxas at /home/u/.venvs/tfcompat-recommenders/lib/python3.11/site-packages/nvidia/cuda_nvcc/bin/ptxas\n",
"2026-07-21 16:57:04.356870: W tensorflow/compiler/mlir/tools/kernel_gen/transforms/gpu_kernel_to_blob_pass.cc:191] Failed to compile generated PTX with ptxas. Falling back to compilation by driver.\n"
]
},
{
"name": "stderr",
"output_type": "stream",
"text": [
"2026-07-21 16:57:04.534962: W tensorflow/compiler/mlir/tools/kernel_gen/transforms/gpu_kernel_to_blob_pass.cc:191] Failed to compile generated PTX with ptxas. Falling back to compilation by driver.\n",
"2026-07-21 16:57:04.535204: W tensorflow/compiler/mlir/tools/kernel_gen/transforms/gpu_kernel_to_blob_pass.cc:191] Failed to compile generated PTX with ptxas. Falling back to compilation by driver.\n",
"2026-07-21 16:57:04.535281: W tensorflow/compiler/mlir/tools/kernel_gen/transforms/gpu_kernel_to_blob_pass.cc:191] Failed to compile generated PTX with ptxas. Falling back to compilation by driver.\n",
"2026-07-21 16:57:04.540989: W tensorflow/compiler/mlir/tools/kernel_gen/transforms/gpu_kernel_to_blob_pass.cc:191] Failed to compile generated PTX with ptxas. Falling back to compilation by driver.\n",
"2026-07-21 16:57:04.541134: W tensorflow/compiler/mlir/tools/kernel_gen/transforms/gpu_kernel_to_blob_pass.cc:191] Failed to compile generated PTX with ptxas. Falling back to compilation by driver.\n",
"2026-07-21 16:57:04.544134: W tensorflow/compiler/mlir/tools/kernel_gen/transforms/gpu_kernel_to_blob_pass.cc:191] Failed to compile generated PTX with ptxas. Falling back to compilation by driver.\n",
"2026-07-21 16:57:04.544371: W tensorflow/compiler/mlir/tools/kernel_gen/transforms/gpu_kernel_to_blob_pass.cc:191] Failed to compile generated PTX with ptxas. Falling back to compilation by driver.\n",
"2026-07-21 16:57:04.544709: W tensorflow/compiler/mlir/tools/kernel_gen/transforms/gpu_kernel_to_blob_pass.cc:191] Failed to compile generated PTX with ptxas. Falling back to compilation by driver.\n"
]
},
{
"name": "stderr",
"output_type": "stream",
"text": [
"2026-07-21 16:57:05.126178: W tensorflow/compiler/mlir/tools/kernel_gen/transforms/gpu_kernel_to_blob_pass.cc:191] Failed to compile generated PTX with ptxas. Falling back to compilation by driver.\n",
"2026-07-21 16:57:05.127077: W tensorflow/compiler/mlir/tools/kernel_gen/transforms/gpu_kernel_to_blob_pass.cc:191] Failed to compile generated PTX with ptxas. Falling back to compilation by driver.\n",
"2026-07-21 16:57:05.131249: W tensorflow/compiler/mlir/tools/kernel_gen/transforms/gpu_kernel_to_blob_pass.cc:191] Failed to compile generated PTX with ptxas. Falling back to compilation by driver.\n",
"2026-07-21 16:57:05.131460: W tensorflow/compiler/mlir/tools/kernel_gen/transforms/gpu_kernel_to_blob_pass.cc:191] Failed to compile generated PTX with ptxas. Falling back to compilation by driver.\n",
"2026-07-21 16:57:05.131580: W tensorflow/compiler/mlir/tools/kernel_gen/transforms/gpu_kernel_to_blob_pass.cc:191] Failed to compile generated PTX with ptxas. Falling back to compilation by driver.\n",
"2026-07-21 16:57:05.134578: W tensorflow/compiler/mlir/tools/kernel_gen/transforms/gpu_kernel_to_blob_pass.cc:191] Failed to compile generated PTX with ptxas. Falling back to compilation by driver.\n",
"2026-07-21 16:57:05.135687: W tensorflow/compiler/mlir/tools/kernel_gen/transforms/gpu_kernel_to_blob_pass.cc:191] Failed to compile generated PTX with ptxas. Falling back to compilation by driver.\n",
"2026-07-21 16:57:05.138293: W tensorflow/compiler/mlir/tools/kernel_gen/transforms/gpu_kernel_to_blob_pass.cc:191] Failed to compile generated PTX with ptxas. Falling back to compilation by driver.\n",
"2026-07-21 16:57:05.138444: W tensorflow/compiler/mlir/tools/kernel_gen/transforms/gpu_kernel_to_blob_pass.cc:191] Failed to compile generated PTX with ptxas. Falling back to compilation by driver.\n"
]
},
{
"name": "stderr",
"output_type": "stream",
"text": [
"2026-07-21 16:57:05.820749: W tensorflow/compiler/mlir/tools/kernel_gen/transforms/gpu_kernel_to_blob_pass.cc:191] Failed to compile generated PTX with ptxas. Falling back to compilation by driver.\n",
"2026-07-21 16:57:05.930308: W tensorflow/compiler/mlir/tools/kernel_gen/transforms/gpu_kernel_to_blob_pass.cc:191] Failed to compile generated PTX with ptxas. Falling back to compilation by driver.\n"
]
},
{
"name": "stdout",
"output_type": "stream",
"text": [
"{'auc': 0.4846, 'logloss': 0.6931, 'mean_mrr': 0.2755, 'ndcg@2': 0.135, 'ndcg@4': 0.2283, 'ndcg@6': 0.3027, 'group_auc': 0.4851}\n"
]
}
],
"source": [
"# test_num_ngs is the number of negative lines after each positive line in your test_file\n",
"print(model.run_eval(test_file, num_ngs=test_num_ngs)) "
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"AUC=0.5 is a state of random guess. We can see that before training, the model behaves like random guessing.\n",
"\n",
"#### 2.1 Train model\n",
"Next we want to train the model on a training set, and check the performance on a validation dataset. Training the model is as simple as a function call:"
]
},
{
"cell_type": "code",
"execution_count": 8,
"metadata": {
"execution": {
"iopub.execute_input": "2026-07-21T14:57:48.122652Z",
"iopub.status.busy": "2026-07-21T14:57:48.121992Z",
"iopub.status.idle": "2026-07-21T15:02:01.501011Z",
"shell.execute_reply": "2026-07-21T15:02:01.497395Z"
},
"scrolled": true
},
"outputs": [
{
"name": "stderr",
"output_type": "stream",
"text": [
"2026-07-21 16:57:49.411624: W tensorflow/compiler/mlir/tools/kernel_gen/transforms/gpu_kernel_to_blob_pass.cc:191] Failed to compile generated PTX with ptxas. Falling back to compilation by driver.\n",
"2026-07-21 16:57:49.424419: W tensorflow/compiler/mlir/tools/kernel_gen/transforms/gpu_kernel_to_blob_pass.cc:191] Failed to compile generated PTX with ptxas. Falling back to compilation by driver.\n"
]
},
{
"name": "stderr",
"output_type": "stream",
"text": [
"2026-07-21 16:57:52.003513: W tensorflow/compiler/mlir/tools/kernel_gen/transforms/gpu_kernel_to_blob_pass.cc:191] Failed to compile generated PTX with ptxas. Falling back to compilation by driver.\n",
"2026-07-21 16:57:52.019509: W tensorflow/compiler/mlir/tools/kernel_gen/transforms/gpu_kernel_to_blob_pass.cc:191] Failed to compile generated PTX with ptxas. Falling back to compilation by driver.\n",
"2026-07-21 16:57:52.058711: W tensorflow/compiler/mlir/tools/kernel_gen/transforms/gpu_kernel_to_blob_pass.cc:191] Failed to compile generated PTX with ptxas. Falling back to compilation by driver.\n"
]
},
{
"name": "stderr",
"output_type": "stream",
"text": [
"2026-07-21 16:57:53.471420: W tensorflow/compiler/mlir/tools/kernel_gen/transforms/gpu_kernel_to_blob_pass.cc:191] Failed to compile generated PTX with ptxas. Falling back to compilation by driver.\n",
"2026-07-21 16:57:53.557219: W tensorflow/compiler/mlir/tools/kernel_gen/transforms/gpu_kernel_to_blob_pass.cc:191] Failed to compile generated PTX with ptxas. Falling back to compilation by driver.\n"
]
},
{
"name": "stderr",
"output_type": "stream",
"text": [
"2026-07-21 16:57:53.703431: W tensorflow/compiler/mlir/tools/kernel_gen/transforms/gpu_kernel_to_blob_pass.cc:191] Failed to compile generated PTX with ptxas. Falling back to compilation by driver.\n"
]
},
{
"name": "stdout",
"output_type": "stream",
"text": [
"step 20 , total_loss: 1.6092, data_loss: 1.6092\n"
]
},
{
"name": "stdout",
"output_type": "stream",
"text": [
"step 40 , total_loss: 1.6080, data_loss: 1.6080\n"
]
},
{
"name": "stdout",
"output_type": "stream",
"text": [
"eval valid at epoch 1: auc:0.499,logloss:0.6938,mean_mrr:0.4521,ndcg@2:0.3212,ndcg@4:0.5079,ndcg@6:0.5862,group_auc:0.4959\n"
]
},
{
"name": "stdout",
"output_type": "stream",
"text": [
"step 20 , total_loss: 1.6008, data_loss: 1.6008\n"
]
},
{
"name": "stdout",
"output_type": "stream",
"text": [
"step 40 , total_loss: 1.5456, data_loss: 1.5456\n"
]
},
{
"name": "stdout",
"output_type": "stream",
"text": [
"eval valid at epoch 2: auc:0.5858,logloss:0.6988,mean_mrr:0.5146,ndcg@2:0.4092,ndcg@4:0.5813,ndcg@6:0.6344,group_auc:0.5787\n"
]
},
{
"name": "stdout",
"output_type": "stream",
"text": [
"step 20 , total_loss: 1.4455, data_loss: 1.4455\n"
]
},
{
"name": "stdout",
"output_type": "stream",
"text": [
"step 40 , total_loss: 1.4152, data_loss: 1.4152\n"
]
},
{
"name": "stdout",
"output_type": "stream",
"text": [
"eval valid at epoch 3: auc:0.6787,logloss:0.7519,mean_mrr:0.5958,ndcg@2:0.527,ndcg@4:0.6663,ndcg@6:0.6966,group_auc:0.6773\n"
]
},
{
"name": "stdout",
"output_type": "stream",
"text": [
"step 20 , total_loss: 1.3308, data_loss: 1.3308\n"
]
},
{
"name": "stdout",
"output_type": "stream",
"text": [
"step 40 , total_loss: 1.2829, data_loss: 1.2829\n"
]
},
{
"name": "stdout",
"output_type": "stream",
"text": [
"eval valid at epoch 4: auc:0.7193,logloss:0.6908,mean_mrr:0.6324,ndcg@2:0.5711,ndcg@4:0.6983,ndcg@6:0.7242,group_auc:0.7092\n"
]
},
{
"name": "stdout",
"output_type": "stream",
"text": [
"step 20 , total_loss: 1.2815, data_loss: 1.2815\n"
]
},
{
"name": "stdout",
"output_type": "stream",
"text": [
"step 40 , total_loss: 1.2032, data_loss: 1.2032\n"
]
},
{
"name": "stdout",
"output_type": "stream",
"text": [
"eval valid at epoch 5: auc:0.7276,logloss:0.6762,mean_mrr:0.6411,ndcg@2:0.5823,ndcg@4:0.7061,ndcg@6:0.7307,group_auc:0.7168\n"
]
},
{
"name": "stdout",
"output_type": "stream",
"text": [
"step 20 , total_loss: 1.2450, data_loss: 1.2450\n"
]
},
{
"name": "stdout",
"output_type": "stream",
"text": [
"step 40 , total_loss: 1.1787, data_loss: 1.1787\n"
]
},
{
"name": "stdout",
"output_type": "stream",
"text": [
"eval valid at epoch 6: auc:0.7352,logloss:0.6439,mean_mrr:0.6465,ndcg@2:0.5902,ndcg@4:0.7099,ndcg@6:0.7348,group_auc:0.7206\n"
]
},
{
"name": "stdout",
"output_type": "stream",
"text": [
"step 20 , total_loss: 1.2197, data_loss: 1.2197\n"
]
},
{
"name": "stdout",
"output_type": "stream",
"text": [
"step 40 , total_loss: 1.2064, data_loss: 1.2064\n"
]
},
{
"name": "stdout",
"output_type": "stream",
"text": [
"eval valid at epoch 7: auc:0.7337,logloss:0.6364,mean_mrr:0.6509,ndcg@2:0.5958,ndcg@4:0.7123,ndcg@6:0.7381,group_auc:0.723\n"
]
},
{
"name": "stdout",
"output_type": "stream",
"text": [
"step 20 , total_loss: 1.2178, data_loss: 1.2178\n"
]
},
{
"name": "stdout",
"output_type": "stream",
"text": [
"step 40 , total_loss: 1.1709, data_loss: 1.1709\n"
]
},
{
"name": "stdout",
"output_type": "stream",
"text": [
"eval valid at epoch 8: auc:0.7322,logloss:0.6487,mean_mrr:0.6495,ndcg@2:0.592,ndcg@4:0.7108,ndcg@6:0.737,group_auc:0.7213\n"
]
},
{
"name": "stdout",
"output_type": "stream",
"text": [
"step 20 , total_loss: 1.1724, data_loss: 1.1724\n"
]
},
{
"name": "stdout",
"output_type": "stream",
"text": [
"step 40 , total_loss: 1.2365, data_loss: 1.2365\n"
]
},
{
"name": "stdout",
"output_type": "stream",
"text": [
"eval valid at epoch 9: auc:0.7329,logloss:0.6506,mean_mrr:0.6527,ndcg@2:0.596,ndcg@4:0.7139,ndcg@6:0.7393,group_auc:0.7235\n"
]
},
{
"name": "stdout",
"output_type": "stream",
"text": [
"step 20 , total_loss: 1.1408, data_loss: 1.1408\n"
]
},
{
"name": "stdout",
"output_type": "stream",
"text": [
"step 40 , total_loss: 1.2092, data_loss: 1.2092\n"
]
},
{
"name": "stdout",
"output_type": "stream",
"text": [
"eval valid at epoch 10: auc:0.734,logloss:0.6502,mean_mrr:0.6536,ndcg@2:0.5956,ndcg@4:0.7137,ndcg@6:0.74,group_auc:0.7243\n",
"[(1, {'auc': 0.499, 'logloss': 0.6938, 'mean_mrr': 0.4521, 'ndcg@2': 0.3212, 'ndcg@4': 0.5079, 'ndcg@6': 0.5862, 'group_auc': 0.4959}), (2, {'auc': 0.5858, 'logloss': 0.6988, 'mean_mrr': 0.5146, 'ndcg@2': 0.4092, 'ndcg@4': 0.5813, 'ndcg@6': 0.6344, 'group_auc': 0.5787}), (3, {'auc': 0.6787, 'logloss': 0.7519, 'mean_mrr': 0.5958, 'ndcg@2': 0.527, 'ndcg@4': 0.6663, 'ndcg@6': 0.6966, 'group_auc': 0.6773}), (4, {'auc': 0.7193, 'logloss': 0.6908, 'mean_mrr': 0.6324, 'ndcg@2': 0.5711, 'ndcg@4': 0.6983, 'ndcg@6': 0.7242, 'group_auc': 0.7092}), (5, {'auc': 0.7276, 'logloss': 0.6762, 'mean_mrr': 0.6411, 'ndcg@2': 0.5823, 'ndcg@4': 0.7061, 'ndcg@6': 0.7307, 'group_auc': 0.7168}), (6, {'auc': 0.7352, 'logloss': 0.6439, 'mean_mrr': 0.6465, 'ndcg@2': 0.5902, 'ndcg@4': 0.7099, 'ndcg@6': 0.7348, 'group_auc': 0.7206}), (7, {'auc': 0.7337, 'logloss': 0.6364, 'mean_mrr': 0.6509, 'ndcg@2': 0.5958, 'ndcg@4': 0.7123, 'ndcg@6': 0.7381, 'group_auc': 0.723}), (8, {'auc': 0.7322, 'logloss': 0.6487, 'mean_mrr': 0.6495, 'ndcg@2': 0.592, 'ndcg@4': 0.7108, 'ndcg@6': 0.737, 'group_auc': 0.7213}), (9, {'auc': 0.7329, 'logloss': 0.6506, 'mean_mrr': 0.6527, 'ndcg@2': 0.596, 'ndcg@4': 0.7139, 'ndcg@6': 0.7393, 'group_auc': 0.7235}), (10, {'auc': 0.734, 'logloss': 0.6502, 'mean_mrr': 0.6536, 'ndcg@2': 0.5956, 'ndcg@4': 0.7137, 'ndcg@6': 0.74, 'group_auc': 0.7243})]\n",
"best epoch: 10\n",
"Time cost for training is 4.54 mins\n"
]
}
],
"source": [
"with Timer() as train_time:\n",
" model = model.fit(train_file, valid_file, valid_num_ngs=valid_num_ngs) \n",
"\n",
"# valid_num_ngs is the number of negative lines after each positive line in your valid_file \n",
"# we will evaluate the performance of model on valid_file every epoch\n",
"print('Time cost for training is {0:.2f} mins'.format(train_time.interval/60.0))"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"#### 2.2 Evaluate model\n",
"\n",
"Again, let's see what is the model's performance now (after training):"
]
},
{
"cell_type": "code",
"execution_count": 9,
"metadata": {
"execution": {
"iopub.execute_input": "2026-07-21T15:02:01.506933Z",
"iopub.status.busy": "2026-07-21T15:02:01.506141Z",
"iopub.status.idle": "2026-07-21T15:02:47.806488Z",
"shell.execute_reply": "2026-07-21T15:02:47.803082Z"
}
},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"{'auc': 0.7075, 'logloss': 0.6789, 'mean_mrr': 0.4747, 'ndcg@2': 0.3824, 'ndcg@4': 0.4868, 'ndcg@6': 0.5394, 'group_auc': 0.6954}\n"
]
}
],
"source": [
"res_syn = model.run_eval(test_file, num_ngs=test_num_ngs)\n",
"print(res_syn)\n"
]
},
{
"cell_type": "code",
"execution_count": 10,
"metadata": {
"execution": {
"iopub.execute_input": "2026-07-21T15:02:47.811292Z",
"iopub.status.busy": "2026-07-21T15:02:47.810889Z",
"iopub.status.idle": "2026-07-21T15:02:47.839044Z",
"shell.execute_reply": "2026-07-21T15:02:47.835438Z"
}
},
"outputs": [
{
"data": {
"application/notebook_utils.json+json": {
"data": 0.7075,
"encoder": "json",
"name": "auc"
}
},
"metadata": {
"notebook_utils": {
"data": true,
"display": false,
"name": "auc"
}
},
"output_type": "display_data"
},
{
"data": {
"application/notebook_utils.json+json": {
"data": 0.6789,
"encoder": "json",
"name": "logloss"
}
},
"metadata": {
"notebook_utils": {
"data": true,
"display": false,
"name": "logloss"
}
},
"output_type": "display_data"
},
{
"data": {
"application/notebook_utils.json+json": {
"data": 0.4747,
"encoder": "json",
"name": "mean_mrr"
}
},
"metadata": {
"notebook_utils": {
"data": true,
"display": false,
"name": "mean_mrr"
}
},
"output_type": "display_data"
},
{
"data": {
"application/notebook_utils.json+json": {
"data": 0.3824,
"encoder": "json",
"name": "ndcg@2"
}
},
"metadata": {
"notebook_utils": {
"data": true,
"display": false,
"name": "ndcg@2"
}
},
"output_type": "display_data"
},
{
"data": {
"application/notebook_utils.json+json": {
"data": 0.4868,
"encoder": "json",
"name": "ndcg@4"
}
},
"metadata": {
"notebook_utils": {
"data": true,
"display": false,
"name": "ndcg@4"
}
},
"output_type": "display_data"
},
{
"data": {
"application/notebook_utils.json+json": {
"data": 0.5394,
"encoder": "json",
"name": "ndcg@6"
}
},
"metadata": {
"notebook_utils": {
"data": true,
"display": false,
"name": "ndcg@6"
}
},
"output_type": "display_data"
},
{
"data": {
"application/notebook_utils.json+json": {
"data": 0.6954,
"encoder": "json",
"name": "group_auc"
}
},
"metadata": {
"notebook_utils": {
"data": true,
"display": false,
"name": "group_auc"
}
},
"output_type": "display_data"
}
],
"source": [
"# Record results for tests - ignore this cell\n",
"store_metadata(\"auc\", res_syn[\"auc\"])\n",
"store_metadata(\"logloss\", res_syn[\"logloss\"])\n",
"store_metadata(\"mean_mrr\", res_syn[\"mean_mrr\"])\n",
"store_metadata(\"ndcg@2\", res_syn[\"ndcg@2\"])\n",
"store_metadata(\"ndcg@4\", res_syn[\"ndcg@4\"])\n",
"store_metadata(\"ndcg@6\", res_syn[\"ndcg@6\"])\n",
"store_metadata(\"group_auc\", res_syn[\"group_auc\"])\n"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"If we want to get the full prediction scores rather than evaluation metrics, we can do this:"
]
},
{
"cell_type": "code",
"execution_count": 11,
"metadata": {
"execution": {
"iopub.execute_input": "2026-07-21T15:02:47.844140Z",
"iopub.status.busy": "2026-07-21T15:02:47.843555Z",
"iopub.status.idle": "2026-07-21T15:02:56.680254Z",
"shell.execute_reply": "2026-07-21T15:02:56.676380Z"
}
},
"outputs": [],
"source": [
"model = model.predict(test_file, output_file)"
]
},
{
"cell_type": "code",
"execution_count": 12,
"metadata": {
"execution": {
"iopub.execute_input": "2026-07-21T15:02:56.685481Z",
"iopub.status.busy": "2026-07-21T15:02:56.685023Z",
"iopub.status.idle": "2026-07-21T15:02:56.693642Z",
"shell.execute_reply": "2026-07-21T15:02:56.689438Z"
}
},
"outputs": [],
"source": [
"# The data was downloaded in tmpdir folder. You can delete them manually if you do not need them any more."
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"#### 2.3 Running models with large dataset\n",
"Here are performances using the whole amazon dataset among popular sequential models with 1,697,533 positive instances.\n",
" Settings for reproducing the results:\n",
" `learning_rate=0.001, dropout=0.3, item_embedding_dim=32, cate_embedding_dim=8, l2_norm=0, batch_size=400, \n",
"train_num_ngs=4, valid_num_ngs=4, test_num_ngs=49`\n",
"\n",
"\n",
"We compare the running time with CPU only and with GPU on the larger dataset. It appears that GPU can significantly accelerate the training. Hardware specification for running the large dataset: \n",
" GPU: Tesla P100-PCIE-16GB\n",
" CPU: 6 cores Intel(R) Xeon(R) CPU E5-2690 v4 @ 2.60GHz\n",
" \n",
"| Models | AUC | g-AUC | NDCG@2 | NDCG@10 | seconds per epoch on GPU | seconds per epoch on CPU| config |\n",
"| :------| :------: | :------: | :------: | :------: | :------: | :------: | :------ |\n",
"| A2SVD | 0.8251 | 0.8178 | 0.2922 | 0.4264 | 249.5 | 440.0 | N/A |\n",
"| GRU | 0.8411 | 0.8332 | 0.3213 | 0.4547 | 439.0 | 4285.0 | max_seq_length=50, hidden_size=40|\n",
"| Caser | 0.8244 | 0.8171 | 0.283 | 0.4194 | 314.3 | 5369.9 | T=1, n_v=128, n_h=128, L=3, min_seq_length=5|\n",
"| NextItNet* | 0.6793 | 0.6769 | 0.0602 | 0.1733 | 112.0 | 214.5 | min_seq_length=3, dilations=\\[1,2,4,1,2,4\\], kernel_size=3 |\n",
"| SUM | 0.8481 | 0.8406 | 0.3394 | 0.4774 | 1005.0 | 9427.0 | hidden_size=40, slots=4, dropout=0|\n",
"\n",
" Note 1: The five models are grid searched with a coarse granularity and the results are for reference only.\n",
" Note 2: NextItNet model requires a dataset with strong sequence property, but the Amazon dataset used in this notebook does not meet that requirement, so NextItNet Model may not performance good. If you wish to use other datasets with strong sequence property, NextItNet is recommended.\n",
" Note 3: Time cost of NextItNet Model is significantly shorter than other models because it doesn't need a history expanding of training data.\n",
" Note 4: The results of the time-aware SLi_Rec model on this dataset are reported in its own notebook: [slirec_amazon.ipynb](slirec_amazon.ipynb)."
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## 3. Loading Trained Models\n",
"In this section, we provide a simple example to illustrate how we can use the trained model to serve for production demand.\n",
"\n",
"Suppose we are in a new session. First let's load a previous trained model:"
]
},
{
"cell_type": "code",
"execution_count": 13,
"metadata": {
"execution": {
"iopub.execute_input": "2026-07-21T15:02:56.698303Z",
"iopub.status.busy": "2026-07-21T15:02:56.697696Z",
"iopub.status.idle": "2026-07-21T15:02:58.342239Z",
"shell.execute_reply": "2026-07-21T15:02:58.339236Z"
}
},
"outputs": [
{
"name": "stderr",
"output_type": "stream",
"text": [
"/home/u/run3x/wt-slirec-pytorch/recommenders/models/deeprec/models/base_model.py:701: UserWarning: `tf.layers.batch_normalization` is deprecated and will be removed in a future version. Please use `tf.keras.layers.BatchNormalization` instead. In particular, `tf.control_dependencies(tf.GraphKeys.UPDATE_OPS)` should not be used (consult the `tf.keras.layers.BatchNormalization` documentation).\n",
" curr_hidden_nn_layer = tf.compat.v1.layers.batch_normalization(\n"
]
},
{
"name": "stderr",
"output_type": "stream",
"text": [
"2026-07-21 17:02:58.066296: I external/local_xla/xla/stream_executor/cuda/cuda_executor.cc:887] could not open file to read NUMA node: /sys/bus/pci/devices/0000:64:00.0/numa_node\n",
"Your kernel may have been built without NUMA support.\n",
"2026-07-21 17:02:58.066488: I external/local_xla/xla/stream_executor/cuda/cuda_executor.cc:887] could not open file to read NUMA node: /sys/bus/pci/devices/0000:64:00.0/numa_node\n",
"Your kernel may have been built without NUMA support.\n",
"2026-07-21 17:02:58.066540: I external/local_xla/xla/stream_executor/cuda/cuda_executor.cc:887] could not open file to read NUMA node: /sys/bus/pci/devices/0000:64:00.0/numa_node\n",
"Your kernel may have been built without NUMA support.\n",
"2026-07-21 17:02:58.066551: W tensorflow/core/common_runtime/gpu/gpu_device.cc:2348] TensorFlow was not built with CUDA kernel binaries compatible with compute capability 12.0. CUDA kernels will be jit-compiled from PTX, which could take 30 minutes or longer.\n",
"2026-07-21 17:02:58.066987: I external/local_xla/xla/stream_executor/cuda/cuda_executor.cc:887] could not open file to read NUMA node: /sys/bus/pci/devices/0000:64:00.0/numa_node\n",
"Your kernel may have been built without NUMA support.\n",
"2026-07-21 17:02:58.067026: I tensorflow/core/common_runtime/gpu/gpu_device.cc:2022] Could not identify NUMA node of platform GPU id 0, defaulting to 0. Your kernel may not have been built with NUMA support.\n",
"2026-07-21 17:02:58.067075: I external/local_xla/xla/stream_executor/cuda/cuda_executor.cc:887] could not open file to read NUMA node: /sys/bus/pci/devices/0000:64:00.0/numa_node\n",
"Your kernel may have been built without NUMA support.\n",
"2026-07-21 17:02:58.067098: I tensorflow/core/common_runtime/gpu/gpu_device.cc:1929] Created device /job:localhost/replica:0/task:0/device:GPU:0 with 21233 MB memory: -> device: 0, name: NVIDIA GeForce RTX 5090 Laptop GPU, pci bus id: 0000:64:00.0, compute capability: 12.0\n"
]
},
{
"name": "stdout",
"output_type": "stream",
"text": [
"loading saved model in ../../tests/resources/deeprec/slirec/model/best_model\n"
]
}
],
"source": [
"model_best_trained = SeqModel(hparams, input_creator, seed=RANDOM_SEED)\n",
"path_best_trained = os.path.join(hparams.MODEL_DIR, \"best_model\")\n",
"print('loading saved model in {0}'.format(path_best_trained))\n",
"model_best_trained.load_model(path_best_trained)\n"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"Let's see if we load the model correctly. The testing metrics should be close to the numbers we have in the training stage."
]
},
{
"cell_type": "code",
"execution_count": 14,
"metadata": {
"execution": {
"iopub.execute_input": "2026-07-21T15:02:58.349039Z",
"iopub.status.busy": "2026-07-21T15:02:58.347850Z",
"iopub.status.idle": "2026-07-21T15:03:47.815336Z",
"shell.execute_reply": "2026-07-21T15:03:47.811431Z"
}
},
"outputs": [
{
"name": "stderr",
"output_type": "stream",
"text": [
"2026-07-21 17:03:02.587161: W tensorflow/compiler/mlir/tools/kernel_gen/transforms/gpu_kernel_to_blob_pass.cc:191] Failed to compile generated PTX with ptxas. Falling back to compilation by driver.\n",
"2026-07-21 17:03:02.724437: W tensorflow/compiler/mlir/tools/kernel_gen/transforms/gpu_kernel_to_blob_pass.cc:191] Failed to compile generated PTX with ptxas. Falling back to compilation by driver.\n",
"2026-07-21 17:03:02.725036: W tensorflow/compiler/mlir/tools/kernel_gen/transforms/gpu_kernel_to_blob_pass.cc:191] Failed to compile generated PTX with ptxas. Falling back to compilation by driver.\n",
"2026-07-21 17:03:02.727824: W tensorflow/compiler/mlir/tools/kernel_gen/transforms/gpu_kernel_to_blob_pass.cc:191] Failed to compile generated PTX with ptxas. Falling back to compilation by driver.\n",
"2026-07-21 17:03:02.728008: W tensorflow/compiler/mlir/tools/kernel_gen/transforms/gpu_kernel_to_blob_pass.cc:191] Failed to compile generated PTX with ptxas. Falling back to compilation by driver.\n",
"2026-07-21 17:03:02.729149: W tensorflow/compiler/mlir/tools/kernel_gen/transforms/gpu_kernel_to_blob_pass.cc:191] Failed to compile generated PTX with ptxas. Falling back to compilation by driver.\n",
"2026-07-21 17:03:02.732904: W tensorflow/compiler/mlir/tools/kernel_gen/transforms/gpu_kernel_to_blob_pass.cc:191] Failed to compile generated PTX with ptxas. Falling back to compilation by driver.\n",
"2026-07-21 17:03:02.733426: W tensorflow/compiler/mlir/tools/kernel_gen/transforms/gpu_kernel_to_blob_pass.cc:191] Failed to compile generated PTX with ptxas. Falling back to compilation by driver.\n",
"2026-07-21 17:03:02.734877: W tensorflow/compiler/mlir/tools/kernel_gen/transforms/gpu_kernel_to_blob_pass.cc:191] Failed to compile generated PTX with ptxas. Falling back to compilation by driver.\n"
]
},
{
"name": "stderr",
"output_type": "stream",
"text": [
"2026-07-21 17:03:02.933420: W tensorflow/compiler/mlir/tools/kernel_gen/transforms/gpu_kernel_to_blob_pass.cc:191] Failed to compile generated PTX with ptxas. Falling back to compilation by driver.\n",
"2026-07-21 17:03:02.934843: W tensorflow/compiler/mlir/tools/kernel_gen/transforms/gpu_kernel_to_blob_pass.cc:191] Failed to compile generated PTX with ptxas. Falling back to compilation by driver.\n",
"2026-07-21 17:03:02.935273: W tensorflow/compiler/mlir/tools/kernel_gen/transforms/gpu_kernel_to_blob_pass.cc:191] Failed to compile generated PTX with ptxas. Falling back to compilation by driver.\n",
"2026-07-21 17:03:02.935619: W tensorflow/compiler/mlir/tools/kernel_gen/transforms/gpu_kernel_to_blob_pass.cc:191] Failed to compile generated PTX with ptxas. Falling back to compilation by driver.\n",
"2026-07-21 17:03:02.939273: W tensorflow/compiler/mlir/tools/kernel_gen/transforms/gpu_kernel_to_blob_pass.cc:191] Failed to compile generated PTX with ptxas. Falling back to compilation by driver.\n",
"2026-07-21 17:03:02.939521: W tensorflow/compiler/mlir/tools/kernel_gen/transforms/gpu_kernel_to_blob_pass.cc:191] Failed to compile generated PTX with ptxas. Falling back to compilation by driver.\n",
"2026-07-21 17:03:02.942790: W tensorflow/compiler/mlir/tools/kernel_gen/transforms/gpu_kernel_to_blob_pass.cc:191] Failed to compile generated PTX with ptxas. Falling back to compilation by driver.\n",
"2026-07-21 17:03:02.943042: W tensorflow/compiler/mlir/tools/kernel_gen/transforms/gpu_kernel_to_blob_pass.cc:191] Failed to compile generated PTX with ptxas. Falling back to compilation by driver.\n",
"2026-07-21 17:03:02.945740: W tensorflow/compiler/mlir/tools/kernel_gen/transforms/gpu_kernel_to_blob_pass.cc:191] Failed to compile generated PTX with ptxas. Falling back to compilation by driver.\n"
]
},
{
"name": "stderr",
"output_type": "stream",
"text": [
"2026-07-21 17:03:03.658967: W tensorflow/compiler/mlir/tools/kernel_gen/transforms/gpu_kernel_to_blob_pass.cc:191] Failed to compile generated PTX with ptxas. Falling back to compilation by driver.\n",
"2026-07-21 17:03:03.753376: W tensorflow/compiler/mlir/tools/kernel_gen/transforms/gpu_kernel_to_blob_pass.cc:191] Failed to compile generated PTX with ptxas. Falling back to compilation by driver.\n"
]
},
{
"data": {
"text/plain": [
"{'auc': 0.7075,\n",
" 'logloss': 0.6789,\n",
" 'mean_mrr': 0.4747,\n",
" 'ndcg@2': 0.3824,\n",
" 'ndcg@4': 0.4868,\n",
" 'ndcg@6': 0.5394,\n",
" 'group_auc': 0.6954}"
]
},
"execution_count": 14,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"model_best_trained.run_eval(test_file, num_ngs=test_num_ngs)"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"And we make predictions using this model. In the next step, we will make predictions using a serving model. Then we can check if the two result files are consistent."
]
},
{
"cell_type": "code",
"execution_count": 15,
"metadata": {
"execution": {
"iopub.execute_input": "2026-07-21T15:03:47.819538Z",
"iopub.status.busy": "2026-07-21T15:03:47.819152Z",
"iopub.status.idle": "2026-07-21T15:03:55.982455Z",
"shell.execute_reply": "2026-07-21T15:03:55.977771Z"
}
},
"outputs": [
{
"data": {
"text/plain": [
""
]
},
"execution_count": 15,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"model_best_trained.predict(test_file, output_file)"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## References\n",
"\\[1\\] Zeping Yu, Jianxun Lian, Ahmad Mahmoody, Gongshen Liu, Xing Xie. Adaptive User Modeling with Long and Short-Term Preferences for Personailzed Recommendation. In Proceedings of the 28th International Joint Conferences on Artificial Intelligence, IJCAI’19, Pages 4213-4219. AAAI Press, 2019.\n",
"\n",
"\\[2\\] Kyunghyun Cho, Bart van Merrienboer, Caglar Gulcehre, Dzmitry Bahdanau, Fethi Bougares, Holger Schwenk, and Yoshua Bengio. Learning Phrase Representations using RNN Encoder-Decoder for Statistical Machine Translation. arXiv preprint arXiv:1406.1078. 2014.\n",
"\n",
"\\[3\\] Tang, Jiaxi, and Ke Wang. Personalized top-n sequential recommendation via convolutional sequence embedding. Proceedings of the Eleventh ACM International Conference on Web Search and Data Mining. ACM, 2018.\n",
"\n",
"\\[4\\] Yuan, F., Karatzoglou, A., Arapakis, I., Jose, J. M., & He, X. A Simple Convolutional Generative Network for Next Item Recommendation. WSDM, 2019.\n",
"\n",
"\\[5\\] Lian, J., Batal, I., Liu, Z., Soni, A., Kang, E. Y., Wang, Y., & Xie, X. Multi-Interest-Aware User Modeling for Large-Scale Sequential Recommendations. arXiv preprint arXiv:2102.09211. 2021."
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": []
}
],
"metadata": {
"celltoolbar": "Tags",
"interpreter": {
"hash": "3a9a0c422ff9f08d62211b9648017c63b0a26d2c935edc37ebb8453675d13bb5"
},
"kernelspec": {
"display_name": "Python 3.7.11 64-bit ('tf2': conda)",
"language": "python",
"name": "python3"
},
"language_info": {
"codemirror_mode": {
"name": "ipython",
"version": 3
},
"file_extension": ".py",
"mimetype": "text/x-python",
"name": "python",
"nbconvert_exporter": "python",
"pygments_lexer": "ipython3",
"version": "3.11.14"
}
},
"nbformat": 4,
"nbformat_minor": 2
}