nextrec 0.4.27__py3-none-any.whl → 0.4.29__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.
- nextrec/__version__.py +1 -1
- nextrec/basic/loggers.py +1 -1
- nextrec/data/batch_utils.py +23 -3
- nextrec/data/dataloader.py +3 -8
- nextrec/models/multi_task/pepnet.py +13 -10
- {nextrec-0.4.27.dist-info → nextrec-0.4.29.dist-info}/METADATA +4 -4
- {nextrec-0.4.27.dist-info → nextrec-0.4.29.dist-info}/RECORD +10 -10
- {nextrec-0.4.27.dist-info → nextrec-0.4.29.dist-info}/WHEEL +0 -0
- {nextrec-0.4.27.dist-info → nextrec-0.4.29.dist-info}/entry_points.txt +0 -0
- {nextrec-0.4.27.dist-info → nextrec-0.4.29.dist-info}/licenses/LICENSE +0 -0
nextrec/__version__.py
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
__version__ = "0.4.
|
|
1
|
+
__version__ = "0.4.29"
|
nextrec/basic/loggers.py
CHANGED
|
@@ -111,7 +111,7 @@ def setup_logger(session_id: str | os.PathLike | None = None):
|
|
|
111
111
|
session = create_session(str(session_id) if session_id is not None else None)
|
|
112
112
|
log_dir = session.logs_dir
|
|
113
113
|
log_dir.mkdir(parents=True, exist_ok=True)
|
|
114
|
-
log_file = log_dir / "
|
|
114
|
+
log_file = log_dir / "runs_log.txt"
|
|
115
115
|
|
|
116
116
|
console_format = "%(message)s"
|
|
117
117
|
file_format = "%(asctime)s - %(levelname)s - %(message)s"
|
nextrec/data/batch_utils.py
CHANGED
|
@@ -5,13 +5,27 @@ Date: create on 03/12/2025
|
|
|
5
5
|
Author: Yang Zhou, zyaztec@gmail.com
|
|
6
6
|
"""
|
|
7
7
|
|
|
8
|
-
from typing import Any, Mapping
|
|
8
|
+
from typing import Any, Mapping, Literal
|
|
9
9
|
|
|
10
10
|
import numpy as np
|
|
11
11
|
import torch
|
|
12
12
|
|
|
13
13
|
|
|
14
|
-
def stack_section(batch: list[dict], section:
|
|
14
|
+
def stack_section(batch: list[dict], section: Literal["features", "labels", "ids"]):
|
|
15
|
+
"""
|
|
16
|
+
input example:
|
|
17
|
+
batch = [
|
|
18
|
+
{"features": {"f1": tensor1, "f2": tensor2}, "labels": {"label": tensor3}},
|
|
19
|
+
{"features": {"f1": tensor4, "f2": tensor5}, "labels": {"label": tensor6}},
|
|
20
|
+
...
|
|
21
|
+
]
|
|
22
|
+
output example:
|
|
23
|
+
{
|
|
24
|
+
"f1": torch.stack([tensor1, tensor4], dim=0),
|
|
25
|
+
"f2": torch.stack([tensor2, tensor5], dim=0),
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
"""
|
|
15
29
|
entries = [item.get(section) for item in batch if item.get(section) is not None]
|
|
16
30
|
if not entries:
|
|
17
31
|
return None
|
|
@@ -22,7 +36,13 @@ def stack_section(batch: list[dict], section: str):
|
|
|
22
36
|
for item in batch
|
|
23
37
|
if item.get(section) is not None and name in item[section]
|
|
24
38
|
]
|
|
25
|
-
|
|
39
|
+
tensor_sample = tensors[0]
|
|
40
|
+
if isinstance(tensor_sample, torch.Tensor):
|
|
41
|
+
merged[name] = torch.stack(tensors, dim=0)
|
|
42
|
+
elif isinstance(tensor_sample, np.ndarray):
|
|
43
|
+
merged[name] = np.stack(tensors, axis=0)
|
|
44
|
+
else:
|
|
45
|
+
merged[name] = tensors
|
|
26
46
|
return merged
|
|
27
47
|
|
|
28
48
|
|
nextrec/data/dataloader.py
CHANGED
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
Dataloader definitions
|
|
3
3
|
|
|
4
4
|
Date: create on 27/10/2025
|
|
5
|
-
Checkpoint: edit on
|
|
5
|
+
Checkpoint: edit on 01/01/2026
|
|
6
6
|
Author: Yang Zhou,zyaztec@gmail.com
|
|
7
7
|
"""
|
|
8
8
|
|
|
@@ -523,13 +523,8 @@ def build_tensors_from_data(
|
|
|
523
523
|
raise KeyError(
|
|
524
524
|
f"[RecDataLoader Error] ID column '{id_col}' not found in provided data."
|
|
525
525
|
)
|
|
526
|
-
|
|
527
|
-
|
|
528
|
-
except Exception as exc:
|
|
529
|
-
raise TypeError(
|
|
530
|
-
f"[RecDataLoader Error] ID column '{id_col}' must contain numeric values. Received dtype={np.asarray(column).dtype}, error: {exc}"
|
|
531
|
-
) from exc
|
|
532
|
-
id_tensors[id_col] = to_tensor(id_arr, dtype=torch.long)
|
|
526
|
+
# Normalize all id columns to strings for consistent downstream handling.
|
|
527
|
+
id_tensors[id_col] = np.asarray(column, dtype=str)
|
|
533
528
|
if not feature_tensors:
|
|
534
529
|
return None
|
|
535
530
|
return {"features": feature_tensors, "labels": label_tensors, "ids": id_tensors}
|
|
@@ -61,9 +61,9 @@ from nextrec.utils.model import select_features
|
|
|
61
61
|
from nextrec.utils.types import TaskTypeName
|
|
62
62
|
|
|
63
63
|
|
|
64
|
-
class
|
|
64
|
+
class PPNet(nn.Module):
|
|
65
65
|
"""
|
|
66
|
-
|
|
66
|
+
PPNet: per-task tower with layer-wise gates conditioned on task context.
|
|
67
67
|
"""
|
|
68
68
|
|
|
69
69
|
def __init__(
|
|
@@ -274,18 +274,21 @@ class PEPNet(BaseModel):
|
|
|
274
274
|
)
|
|
275
275
|
task_dim = domain_dim + user_dim + item_dim
|
|
276
276
|
|
|
277
|
-
|
|
277
|
+
# EPNet: shared feature-level gate (paper's EPNet).
|
|
278
|
+
self.epnet = GateMLP(
|
|
278
279
|
input_dim=input_dim + domain_dim,
|
|
279
280
|
hidden_dim=feature_gate_mlp_params["hidden_dim"],
|
|
280
281
|
output_dim=input_dim,
|
|
281
282
|
activation=feature_gate_mlp_params["activation"],
|
|
282
283
|
dropout=feature_gate_mlp_params["dropout"],
|
|
283
284
|
use_bn=feature_gate_mlp_params["use_bn"],
|
|
285
|
+
scale_factor=2.0,
|
|
284
286
|
)
|
|
285
287
|
|
|
286
|
-
|
|
288
|
+
# PPNet: per-task gated towers (paper's PPNet).
|
|
289
|
+
self.ppnet_blocks = nn.ModuleList(
|
|
287
290
|
[
|
|
288
|
-
|
|
291
|
+
PPNet(
|
|
289
292
|
input_dim=input_dim,
|
|
290
293
|
output_dim=1,
|
|
291
294
|
gate_input_dim=input_dim + task_dim,
|
|
@@ -300,9 +303,9 @@ class PEPNet(BaseModel):
|
|
|
300
303
|
self.prediction_layer = TaskHead(
|
|
301
304
|
task_type=self.task, task_dims=[1] * self.nums_task
|
|
302
305
|
)
|
|
303
|
-
self.grad_norm_shared_modules = ["embedding", "
|
|
306
|
+
self.grad_norm_shared_modules = ["embedding", "epnet"]
|
|
304
307
|
self.register_regularization_weights(
|
|
305
|
-
embedding_attr="embedding", include_modules=["
|
|
308
|
+
embedding_attr="embedding", include_modules=["epnet", "ppnet_blocks"]
|
|
306
309
|
)
|
|
307
310
|
|
|
308
311
|
def forward(self, x: dict[str, torch.Tensor]) -> torch.Tensor:
|
|
@@ -327,11 +330,11 @@ class PEPNet(BaseModel):
|
|
|
327
330
|
task_sf_emb = torch.cat(task_parts, dim=-1)
|
|
328
331
|
|
|
329
332
|
gate_input = torch.cat([dnn_input.detach(), domain_emb], dim=-1)
|
|
330
|
-
dnn_input = self.
|
|
333
|
+
dnn_input = self.epnet(gate_input) * dnn_input
|
|
331
334
|
|
|
332
335
|
task_logits = []
|
|
333
|
-
for block in self.
|
|
334
|
-
|
|
336
|
+
for block in self.ppnet_blocks:
|
|
337
|
+
task_logits.append(block(o_ep=dnn_input, o_prior=task_sf_emb))
|
|
335
338
|
|
|
336
339
|
y = torch.cat(task_logits, dim=1)
|
|
337
340
|
return self.prediction_layer(y)
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: nextrec
|
|
3
|
-
Version: 0.4.
|
|
3
|
+
Version: 0.4.29
|
|
4
4
|
Summary: A comprehensive recommendation library with match, ranking, and multi-task learning models
|
|
5
5
|
Project-URL: Homepage, https://github.com/zerolovesea/NextRec
|
|
6
6
|
Project-URL: Repository, https://github.com/zerolovesea/NextRec
|
|
@@ -69,7 +69,7 @@ Description-Content-Type: text/markdown
|
|
|
69
69
|

|
|
70
70
|

|
|
71
71
|

|
|
72
|
-

|
|
73
73
|
[](https://deepwiki.com/zerolovesea/NextRec)
|
|
74
74
|
|
|
75
75
|
中文文档 | [English Version](README_en.md)
|
|
@@ -254,11 +254,11 @@ nextrec --mode=predict --predict_config=path/to/predict_config.yaml
|
|
|
254
254
|
|
|
255
255
|
预测结果固定保存到 `{checkpoint_path}/predictions/{name}.{save_data_format}`。
|
|
256
256
|
|
|
257
|
-
> 截止当前版本0.4.
|
|
257
|
+
> 截止当前版本0.4.29,NextRec CLI支持单机训练,分布式训练相关功能尚在开发中。
|
|
258
258
|
|
|
259
259
|
## 兼容平台
|
|
260
260
|
|
|
261
|
-
当前最新版本为0.4.
|
|
261
|
+
当前最新版本为0.4.29,所有模型和测试代码均已在以下平台通过验证,如果开发者在使用中遇到兼容问题,请在issue区提出错误报告及系统版本:
|
|
262
262
|
|
|
263
263
|
| 平台 | 配置 |
|
|
264
264
|
|------|------|
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
nextrec/__init__.py,sha256=_M3oUqyuvQ5k8Th_3wId6hQ_caclh7M5ad51XN09m98,235
|
|
2
|
-
nextrec/__version__.py,sha256=
|
|
2
|
+
nextrec/__version__.py,sha256=LtSKwkqgueDQK6uLnhs8HgKylJHH36EMo48UDeHgv2Y,23
|
|
3
3
|
nextrec/cli.py,sha256=uOaXnlAM-ARrbxKOVWWkTE_rv-54px168kBhFUHtIAg,25073
|
|
4
4
|
nextrec/basic/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
5
5
|
nextrec/basic/activation.py,sha256=uekcJsOy8SiT0_NaDO2VNSStyYFzVikDFVLDk-VrjwQ,2949
|
|
@@ -8,16 +8,16 @@ nextrec/basic/callback.py,sha256=7geza5iMMlMojlrIKH5A7nzvCe4IYwgUaMRh_xpblWk,125
|
|
|
8
8
|
nextrec/basic/features.py,sha256=zLijBNkKwCXv9TKxSWwvmt7aVfWn2D5JvfwukeIRqec,9174
|
|
9
9
|
nextrec/basic/heads.py,sha256=BshykLxD41KxKuZaBxf4Fmy1Mc52b3ioJliN1BVaGlk,3374
|
|
10
10
|
nextrec/basic/layers.py,sha256=tr8XFOcTvUHEZ6T3zJwmtKMA-u_xfzHloIkItGs821U,40084
|
|
11
|
-
nextrec/basic/loggers.py,sha256=
|
|
11
|
+
nextrec/basic/loggers.py,sha256=LAfnhdSNEzHybrXaKxCWoAML1c2A-FJF6atpfrrm_Kw,13840
|
|
12
12
|
nextrec/basic/metrics.py,sha256=CPzENDcpO6QTDZLBtQlfAGKUYYQc0FT-eaMKJ4MURFo,23396
|
|
13
13
|
nextrec/basic/model.py,sha256=4vBp-vXAWC5Oiu_x4mtVaXTKJCcKDYT0IJ7UOyHD5lw,110162
|
|
14
14
|
nextrec/basic/session.py,sha256=mrIsjRJhmvcAfoO1pXX-KB3SK5CCgz89wH8XDoAiGEI,4475
|
|
15
15
|
nextrec/basic/summary.py,sha256=b6jLo70gqZj_bQ4eb5yb8SXmr2ilZlKNN293EyVnkyc,17759
|
|
16
16
|
nextrec/data/__init__.py,sha256=YZQjpty1pDCM7q_YNmiA2sa5kbujUw26ObLHWjMPjKY,1194
|
|
17
|
-
nextrec/data/batch_utils.py,sha256=
|
|
17
|
+
nextrec/data/batch_utils.py,sha256=vqlBvdfrhFEIUHmiWuUdXg1oY2jkyKOO1JO2l2KpJUU,3549
|
|
18
18
|
nextrec/data/data_processing.py,sha256=lhuwYxWp4Ts2bbuLGDt2LmuPrOy7pNcKczd2uVcQ4ss,6476
|
|
19
19
|
nextrec/data/data_utils.py,sha256=0Ls1cnG9lBz0ovtyedw5vwp7WegGK_iF-F8e_3DEddo,880
|
|
20
|
-
nextrec/data/dataloader.py,sha256=
|
|
20
|
+
nextrec/data/dataloader.py,sha256=2sXwoiWxupKE-V1QYeZlXjK1yJyxhDtlOhknAnJF8Wk,19727
|
|
21
21
|
nextrec/data/preprocessor.py,sha256=AD5bHNbkAZAnI_SbDfJJaAh57CRtRjoOQJ6aIBkgoQs,65251
|
|
22
22
|
nextrec/loss/__init__.py,sha256=rualGsY-IBvmM52q9eOBk0MyKcMkpkazcscOeDXi_SM,774
|
|
23
23
|
nextrec/loss/grad_norm.py,sha256=YoE_XSIN1HOUcNq1dpfkIlWtMaB5Pu-SEWDaNgtRw1M,8316
|
|
@@ -36,7 +36,7 @@ nextrec/models/multi_task/escm.py,sha256=Djk4SjLsZ8He3sZrKfZkHdH2istR9R71GVEJc6E
|
|
|
36
36
|
nextrec/models/multi_task/esmm.py,sha256=QRnNXV1IEArYorYJLOoBcLbxarMC_7azQLP79QTfAJ8,5273
|
|
37
37
|
nextrec/models/multi_task/hmoe.py,sha256=6mTzZxC5PfSQovrmnR0O2hdhDUG_8yNqMwCdkNRlHkY,7567
|
|
38
38
|
nextrec/models/multi_task/mmoe.py,sha256=Mplzstu-LYEMtiKiyiMEQZwY-xMkUeG-1FaDqqK5kws,7606
|
|
39
|
-
nextrec/models/multi_task/pepnet.py,sha256=
|
|
39
|
+
nextrec/models/multi_task/pepnet.py,sha256=ikCDu66TTPdfp94HU-4QzKCW5JOEvwAf5E0QEQ0SZzw,13510
|
|
40
40
|
nextrec/models/multi_task/ple.py,sha256=cO-NqEm-UZKRz2MznBjqsXL8ImH7WU1HRzXdWAtb7Kk,12089
|
|
41
41
|
nextrec/models/multi_task/poso.py,sha256=Xjw9JBAiGR9CGewp1uS4b1soA7fOvSWTsIT6pS9_o30,18215
|
|
42
42
|
nextrec/models/multi_task/share_bottom.py,sha256=BT-nu0NZTV4HlFkva_KnoKLSxB0-gYuJWPw7PRDGwC8,5172
|
|
@@ -83,8 +83,8 @@ nextrec/utils/loss.py,sha256=GBWQGpDaYkMJySpdG078XbeUNXUC34PVqFy0AqNS9N0,4578
|
|
|
83
83
|
nextrec/utils/model.py,sha256=PI9y8oWz1lhktgapZsiXb8rTr2NrFFlc80tr4yOFHik,5334
|
|
84
84
|
nextrec/utils/torch_utils.py,sha256=UQpWS7F3nITYqvx2KRBaQJc9oTowRkIvowhuQLt6NFM,11953
|
|
85
85
|
nextrec/utils/types.py,sha256=VhtLXUVvu0zAZVAUgRUML4FExRC-GH-ZmC1UiVSr3HE,1523
|
|
86
|
-
nextrec-0.4.
|
|
87
|
-
nextrec-0.4.
|
|
88
|
-
nextrec-0.4.
|
|
89
|
-
nextrec-0.4.
|
|
90
|
-
nextrec-0.4.
|
|
86
|
+
nextrec-0.4.29.dist-info/METADATA,sha256=07uY-tjvX77s4-doAM2zh5nCeptFxbzvBAv6BQdMvLU,23188
|
|
87
|
+
nextrec-0.4.29.dist-info/WHEEL,sha256=WLgqFyCfm_KASv4WHyYy0P3pM_m7J5L9k2skdKLirC8,87
|
|
88
|
+
nextrec-0.4.29.dist-info/entry_points.txt,sha256=NN-dNSdfMRTv86bNXM7d3ZEPW2BQC6bRi7QP7i9cIps,45
|
|
89
|
+
nextrec-0.4.29.dist-info/licenses/LICENSE,sha256=2fQfVKeafywkni7MYHyClC6RGGC3laLTXCNBx-ubtp0,1064
|
|
90
|
+
nextrec-0.4.29.dist-info/RECORD,,
|
|
File without changes
|
|
File without changes
|
|
File without changes
|