Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -151,6 +151,7 @@ The table below lists the recommendation models/algorithms featured in Cornac. E
| Year | Model and Paper | Type | Environment | Example |
| :--: | --------------- | :--: | :---------: | :-----: |
| 2025 | [Generating Long Semantic IDs in Parallel for Recommendation (RPG)](cornac/models/rpg), [docs](https://cornac.readthedocs.io/en/stable/api_ref/models.html#module-cornac.models.rpg.recom_rpg), [paper](https://arxiv.org/abs/2506.05781) | Next-Item / Content-Based | [requirements](cornac/models/rpg/requirements.txt), CPU / GPU | [quick-start](examples/rpg_example.py)
| | [Diffusion-based Generative Recommendation Model (DiffGRM)](cornac/models/diffgrm), [docs](https://cornac.readthedocs.io/en/stable/api_ref/models.html#module-cornac.models.diffgrm.recom_diffgrm), [paper](https://arxiv.org/abs/2510.21805) | Next-Item / Content-Based | [requirements](cornac/models/diffgrm/requirements.txt), CPU / GPU | [quick-start](examples/diffgrm_example.py)
| 2024 | [Comparative Aspects and Opinions Ranking for Recommendation Explanations (Companion)](cornac/models/companion), [docs](https://cornac.readthedocs.io/en/stable/api_ref/models.html#module-cornac.models.companion.recom_companion), [paper](https://lthoang.com/assets/publications/mlj24.pdf) | Hybrid / Sentiment / Explainable | CPU | [quick-start](examples/companion_example.py)
| | [Hypergraphs with Attention on Reviews (HypAR)](cornac/models/hypar), [docs](https://cornac.readthedocs.io/en/stable/api_ref/models.html#module-cornac.models.hypar.recom_hypar), [paper](https://doi.org/10.1007/978-3-031-56027-9_14)| Hybrid / Sentiment / Explainable | [requirements](cornac/models/hypar/requirements_cu118.txt), CPU / GPU | [quick-start](https://github.com/PreferredAI/HypAR)
| | [Learnable Item Tokenization for Generative Recommendation (LETTER)](cornac/models/letter), [docs](https://cornac.readthedocs.io/en/stable/api_ref/models.html#module-cornac.models.letter.recom_letter), [paper](https://arxiv.org/abs/2405.07314) | Next-Item / Content-Based | [requirements](cornac/models/letter/requirements.txt), CPU / GPU | [quick-start](examples/letter_example.py)
Expand Down
5 changes: 5 additions & 0 deletions docs/source/api_ref/models.rst
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,11 @@ Recommender (Generic Class)
.. automodule:: cornac.models.recommender
:members:

Diffusion-based Generative Recommendation Model (DiffGRM)
---------------------------------------------------------
.. automodule:: cornac.models.diffgrm.recom_diffgrm
:members:

Comparative Aspects and Opinions Ranking for Recommendation Explanations (Companion)
-------------------------------------------------------------------------
.. automodule:: cornac.models.companion.recom_companion
Expand Down
2 changes: 2 additions & 0 deletions examples/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -136,6 +136,8 @@

[rpg_example.py](rpg_example.py) - Parallel generation of long unordered semantic IDs (RPG): OPQ tokenizer + multi-token prediction + graph-guided decoding, with Diginetica dataset.

[diffgrm_example.py](diffgrm_example.py) - Masked-diffusion generation of PSE semantic IDs (DiffGRM) on Amazon Sports with Sentence-T5 item content embeddings, OCN training, and CPD decoding.

----

## Next-Basket Algorithms
Expand Down
94 changes: 94 additions & 0 deletions examples/diffgrm_example.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,94 @@
# Copyright 2026 The Cornac Authors. All Rights Reserved.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
# ============================================================================
"""DiffGRM (masked-diffusion Semantic IDs) on Amazon Sports (2014).

This example follows the DiffGRM Sports data path: per-user leave-last-out
splitting, item text containing title/price/brand/categories/description,
Sentence-T5 content embeddings, PSE tokenization, OCN training, and CPD
decoding. The model overrides the paper-style configuration's per-view loss
and paper decoder with the released pooled-token loss and released decoder
used by the release-fidelity study.

This is an end-to-end runnable reference, not an artifact-identical
reproduction. PCA and FAISS outputs depend on library versions; the controlled
study uses frozen ``item_sids``. Cornac's standard experiment output is also
item-expanded, whereas the paper and released evaluator report SID-level
metrics. See ``cornac/models/diffgrm/README.md`` for the controlled results and
limitations.

Requires ``sentence-transformers`` in addition to the packages in
``cornac/models/diffgrm/requirements.txt``. This is a paper-scale experiment;
training and beam evaluation are intended for a GPU.
"""

import torch
from sentence_transformers import SentenceTransformer

import cornac
from cornac.data import FeatureModality
from cornac.datasets import amazon_review
from cornac.eval_methods import NextItemEvaluation
from cornac.metrics import MRR, NDCG, Recall
from cornac.models import DiffGRM
from cornac.models.diffgrm import DIFFGRM_SPORTS_CONFIG

DEVICE = "cuda" if torch.cuda.is_available() else "cpu"
print(f"using device: {DEVICE}")

data = amazon_review.load_feedback(category="sports")
texts, item_ids = amazon_review.load_text(
category="sports",
include_description=True,
)

encoder = SentenceTransformer("sentence-t5-base", device=DEVICE)
features = encoder.encode(texts, batch_size=256, show_progress_bar=True)
del encoder # release encoder memory before fitting DiffGRM
if DEVICE == "cuda":
torch.cuda.empty_cache()

next_item_eval = NextItemEvaluation.leave_last_out(
data=data,
exclude_unknowns=True,
verbose=True,
item_feature=FeatureModality(features=features, ids=item_ids),
)

models = [
DiffGRM(
**{
**DIFFGRM_SPORTS_CONFIG,
"view_loss_reduction": "token_mean",
"scoring": "released",
"device": DEVICE,
"verbose": True,
"seed": 2024,
}
),
]

metrics = [
Recall(k=5),
Recall(k=10),
NDCG(k=5),
NDCG(k=10),
MRR(),
]

cornac.Experiment(
eval_method=next_item_eval,
models=models,
metrics=metrics,
).run()
Loading