nextrec 0.4.16__py3-none-any.whl → 0.4.18__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (37) hide show
  1. nextrec/__version__.py +1 -1
  2. nextrec/basic/heads.py +99 -0
  3. nextrec/basic/loggers.py +5 -5
  4. nextrec/basic/model.py +217 -88
  5. nextrec/cli.py +1 -1
  6. nextrec/data/dataloader.py +93 -95
  7. nextrec/data/preprocessor.py +108 -46
  8. nextrec/loss/grad_norm.py +13 -13
  9. nextrec/models/multi_task/esmm.py +10 -11
  10. nextrec/models/multi_task/mmoe.py +20 -19
  11. nextrec/models/multi_task/ple.py +35 -34
  12. nextrec/models/multi_task/poso.py +23 -21
  13. nextrec/models/multi_task/share_bottom.py +18 -17
  14. nextrec/models/ranking/afm.py +4 -3
  15. nextrec/models/ranking/autoint.py +4 -3
  16. nextrec/models/ranking/dcn.py +4 -3
  17. nextrec/models/ranking/dcn_v2.py +4 -3
  18. nextrec/models/ranking/deepfm.py +4 -3
  19. nextrec/models/ranking/dien.py +2 -2
  20. nextrec/models/ranking/din.py +2 -2
  21. nextrec/models/ranking/eulernet.py +4 -3
  22. nextrec/models/ranking/ffm.py +4 -3
  23. nextrec/models/ranking/fibinet.py +2 -2
  24. nextrec/models/ranking/fm.py +4 -3
  25. nextrec/models/ranking/lr.py +4 -3
  26. nextrec/models/ranking/masknet.py +4 -5
  27. nextrec/models/ranking/pnn.py +5 -4
  28. nextrec/models/ranking/widedeep.py +8 -8
  29. nextrec/models/ranking/xdeepfm.py +5 -4
  30. nextrec/utils/console.py +20 -6
  31. nextrec/utils/data.py +154 -32
  32. nextrec/utils/model.py +86 -1
  33. {nextrec-0.4.16.dist-info → nextrec-0.4.18.dist-info}/METADATA +5 -6
  34. {nextrec-0.4.16.dist-info → nextrec-0.4.18.dist-info}/RECORD +37 -36
  35. {nextrec-0.4.16.dist-info → nextrec-0.4.18.dist-info}/WHEEL +0 -0
  36. {nextrec-0.4.16.dist-info → nextrec-0.4.18.dist-info}/entry_points.txt +0 -0
  37. {nextrec-0.4.16.dist-info → nextrec-0.4.18.dist-info}/licenses/LICENSE +0 -0
nextrec/__version__.py CHANGED
@@ -1 +1 @@
1
- __version__ = "0.4.16"
1
+ __version__ = "0.4.18"
nextrec/basic/heads.py ADDED
@@ -0,0 +1,99 @@
1
+ """
2
+ Task head implementations for NextRec models.
3
+
4
+ Date: create on 23/12/2025
5
+ Author: Yang Zhou, zyaztec@gmail.com
6
+ """
7
+
8
+ from __future__ import annotations
9
+
10
+ from typing import Literal
11
+
12
+ import torch
13
+ import torch.nn as nn
14
+ import torch.nn.functional as F
15
+
16
+ from nextrec.basic.layers import PredictionLayer
17
+
18
+
19
+ class TaskHead(nn.Module):
20
+ """
21
+ Unified task head for ranking/regression/multi-task outputs.
22
+
23
+ This wraps PredictionLayer so models can depend on a "Head" abstraction
24
+ without changing their existing forward signatures.
25
+ """
26
+
27
+ def __init__(
28
+ self,
29
+ task_type: str | list[str] = "binary",
30
+ task_dims: int | list[int] | None = None,
31
+ use_bias: bool = True,
32
+ return_logits: bool = False,
33
+ ) -> None:
34
+ super().__init__()
35
+ self.prediction = PredictionLayer(
36
+ task_type=task_type,
37
+ task_dims=task_dims,
38
+ use_bias=use_bias,
39
+ return_logits=return_logits,
40
+ )
41
+ # Expose commonly used attributes for compatibility with PredictionLayer.
42
+ self.task_types = self.prediction.task_types
43
+ self.task_dims = self.prediction.task_dims
44
+ self.task_slices = self.prediction.task_slices
45
+ self.total_dim = self.prediction.total_dim
46
+
47
+ def forward(self, x: torch.Tensor) -> torch.Tensor:
48
+ return self.prediction(x)
49
+
50
+
51
+ class RetrievalHead(nn.Module):
52
+ """
53
+ Retrieval head for two-tower models.
54
+
55
+ It computes similarity for pointwise training/inference, and returns
56
+ raw embeddings for in-batch negative sampling in pairwise/listwise modes.
57
+ """
58
+
59
+ def __init__(
60
+ self,
61
+ similarity_metric: Literal["dot", "cosine", "euclidean"] = "dot",
62
+ temperature: float = 1.0,
63
+ training_mode: Literal["pointwise", "pairwise", "listwise"] = "pointwise",
64
+ apply_sigmoid: bool = True,
65
+ ) -> None:
66
+ super().__init__()
67
+ self.similarity_metric = similarity_metric
68
+ self.temperature = temperature
69
+ self.training_mode = training_mode
70
+ self.apply_sigmoid = apply_sigmoid
71
+
72
+ def forward(
73
+ self,
74
+ user_emb: torch.Tensor,
75
+ item_emb: torch.Tensor,
76
+ similarity_fn=None,
77
+ ) -> torch.Tensor | tuple[torch.Tensor, torch.Tensor]:
78
+ if self.training and self.training_mode in {"pairwise", "listwise"}:
79
+ return user_emb, item_emb
80
+
81
+ if similarity_fn is not None:
82
+ similarity = similarity_fn(user_emb, item_emb)
83
+ else:
84
+ if user_emb.dim() == 2 and item_emb.dim() == 3:
85
+ user_emb = user_emb.unsqueeze(1)
86
+
87
+ if self.similarity_metric == "dot":
88
+ similarity = torch.sum(user_emb * item_emb, dim=-1)
89
+ elif self.similarity_metric == "cosine":
90
+ similarity = F.cosine_similarity(user_emb, item_emb, dim=-1)
91
+ elif self.similarity_metric == "euclidean":
92
+ similarity = -torch.sum((user_emb - item_emb) ** 2, dim=-1)
93
+ else:
94
+ raise ValueError(f"Unknown similarity metric: {self.similarity_metric}")
95
+
96
+ similarity = similarity / self.temperature
97
+ if self.training_mode == "pointwise" and self.apply_sigmoid:
98
+ return torch.sigmoid(similarity)
99
+ return similarity
nextrec/basic/loggers.py CHANGED
@@ -2,7 +2,7 @@
2
2
  NextRec Basic Loggers
3
3
 
4
4
  Date: create on 27/10/2025
5
- Checkpoint: edit on 20/12/2025
5
+ Checkpoint: edit on 24/12/2025
6
6
  Author: Yang Zhou, zyaztec@gmail.com
7
7
  """
8
8
 
@@ -148,18 +148,18 @@ class TrainingLogger:
148
148
  def __init__(
149
149
  self,
150
150
  session: Session,
151
- enable_tensorboard: bool,
151
+ use_tensorboard: bool,
152
152
  log_name: str = "training_metrics.jsonl",
153
153
  ) -> None:
154
154
  self.session = session
155
- self.enable_tensorboard = enable_tensorboard
155
+ self.use_tensorboard = use_tensorboard
156
156
  self.log_path = session.metrics_dir / log_name
157
157
  self.log_path.parent.mkdir(parents=True, exist_ok=True)
158
158
 
159
159
  self.tb_writer = None
160
160
  self.tb_dir = None
161
161
 
162
- if self.enable_tensorboard:
162
+ if self.use_tensorboard:
163
163
  self._init_tensorboard()
164
164
 
165
165
  def _init_tensorboard(self) -> None:
@@ -169,7 +169,7 @@ class TrainingLogger:
169
169
  logging.warning(
170
170
  "[TrainingLogger] tensorboard not installed, disable tensorboard logging."
171
171
  )
172
- self.enable_tensorboard = False
172
+ self.use_tensorboard = False
173
173
  return
174
174
  tb_dir = self.session.logs_dir / "tensorboard"
175
175
  tb_dir.mkdir(parents=True, exist_ok=True)