nextrec 0.4.13__tar.gz → 0.4.15__tar.gz

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 (171) hide show
  1. nextrec-0.4.15/.github/workflows/publish.yml +107 -0
  2. {nextrec-0.4.13 → nextrec-0.4.15}/PKG-INFO +9 -5
  3. {nextrec-0.4.13 → nextrec-0.4.15}/README.md +8 -4
  4. {nextrec-0.4.13 → nextrec-0.4.15}/README_en.md +7 -4
  5. {nextrec-0.4.13 → nextrec-0.4.15}/docs/rtd/conf.py +1 -1
  6. nextrec-0.4.15/nextrec/__version__.py +1 -0
  7. {nextrec-0.4.13 → nextrec-0.4.15}/nextrec/basic/model.py +25 -6
  8. {nextrec-0.4.13 → nextrec-0.4.15}/nextrec/cli.py +12 -0
  9. {nextrec-0.4.13 → nextrec-0.4.15}/nextrec/data/dataloader.py +17 -0
  10. {nextrec-0.4.13 → nextrec-0.4.15}/nextrec/utils/config.py +8 -8
  11. {nextrec-0.4.13 → nextrec-0.4.15}/pyproject.toml +1 -1
  12. nextrec-0.4.13/.github/workflows/publish.yml +0 -65
  13. nextrec-0.4.13/nextrec/__version__.py +0 -1
  14. {nextrec-0.4.13 → nextrec-0.4.15}/.github/workflows/tests.yml +0 -0
  15. {nextrec-0.4.13 → nextrec-0.4.15}/.gitignore +0 -0
  16. {nextrec-0.4.13 → nextrec-0.4.15}/.readthedocs.yaml +0 -0
  17. {nextrec-0.4.13 → nextrec-0.4.15}/CODE_OF_CONDUCT.md +0 -0
  18. {nextrec-0.4.13 → nextrec-0.4.15}/CONTRIBUTING.md +0 -0
  19. {nextrec-0.4.13 → nextrec-0.4.15}/LICENSE +0 -0
  20. {nextrec-0.4.13 → nextrec-0.4.15}/MANIFEST.in +0 -0
  21. {nextrec-0.4.13 → nextrec-0.4.15}/assets/Feature Configuration.png +0 -0
  22. {nextrec-0.4.13 → nextrec-0.4.15}/assets/Model Parameters.png +0 -0
  23. {nextrec-0.4.13 → nextrec-0.4.15}/assets/Training Configuration.png +0 -0
  24. {nextrec-0.4.13 → nextrec-0.4.15}/assets/Training logs.png +0 -0
  25. {nextrec-0.4.13 → nextrec-0.4.15}/assets/logo.png +0 -0
  26. {nextrec-0.4.13 → nextrec-0.4.15}/assets/mmoe_tutorial.png +0 -0
  27. {nextrec-0.4.13 → nextrec-0.4.15}/assets/nextrec_diagram.png +0 -0
  28. {nextrec-0.4.13 → nextrec-0.4.15}/assets/test data.png +0 -0
  29. {nextrec-0.4.13 → nextrec-0.4.15}/dataset/ctcvr_task.csv +0 -0
  30. {nextrec-0.4.13 → nextrec-0.4.15}/dataset/ecommerce_task.csv +0 -0
  31. {nextrec-0.4.13 → nextrec-0.4.15}/dataset/match_task.csv +0 -0
  32. {nextrec-0.4.13 → nextrec-0.4.15}/dataset/movielens_100k.csv +0 -0
  33. {nextrec-0.4.13 → nextrec-0.4.15}/dataset/multitask_task.csv +0 -0
  34. {nextrec-0.4.13 → nextrec-0.4.15}/dataset/ranking_task.csv +0 -0
  35. {nextrec-0.4.13 → nextrec-0.4.15}/docs/en/Getting started guide.md +0 -0
  36. {nextrec-0.4.13 → nextrec-0.4.15}/docs/rtd/Makefile +0 -0
  37. {nextrec-0.4.13 → nextrec-0.4.15}/docs/rtd/index.md +0 -0
  38. {nextrec-0.4.13 → nextrec-0.4.15}/docs/rtd/make.bat +0 -0
  39. {nextrec-0.4.13 → nextrec-0.4.15}/docs/rtd/modules.rst +0 -0
  40. {nextrec-0.4.13 → nextrec-0.4.15}/docs/rtd/nextrec.basic.rst +0 -0
  41. {nextrec-0.4.13 → nextrec-0.4.15}/docs/rtd/nextrec.data.rst +0 -0
  42. {nextrec-0.4.13 → nextrec-0.4.15}/docs/rtd/nextrec.loss.rst +0 -0
  43. {nextrec-0.4.13 → nextrec-0.4.15}/docs/rtd/nextrec.rst +0 -0
  44. {nextrec-0.4.13 → nextrec-0.4.15}/docs/rtd/nextrec.utils.rst +0 -0
  45. {nextrec-0.4.13 → nextrec-0.4.15}/docs/rtd/requirements.txt +0 -0
  46. {nextrec-0.4.13 → nextrec-0.4.15}/docs/zh//345/277/253/351/200/237/344/270/212/346/211/213.md" +0 -0
  47. {nextrec-0.4.13 → nextrec-0.4.15}/nextrec/__init__.py +0 -0
  48. {nextrec-0.4.13 → nextrec-0.4.15}/nextrec/basic/__init__.py +0 -0
  49. {nextrec-0.4.13 → nextrec-0.4.15}/nextrec/basic/activation.py +0 -0
  50. {nextrec-0.4.13 → nextrec-0.4.15}/nextrec/basic/callback.py +0 -0
  51. {nextrec-0.4.13 → nextrec-0.4.15}/nextrec/basic/features.py +0 -0
  52. {nextrec-0.4.13 → nextrec-0.4.15}/nextrec/basic/layers.py +0 -0
  53. {nextrec-0.4.13 → nextrec-0.4.15}/nextrec/basic/loggers.py +0 -0
  54. {nextrec-0.4.13 → nextrec-0.4.15}/nextrec/basic/metrics.py +0 -0
  55. {nextrec-0.4.13 → nextrec-0.4.15}/nextrec/basic/session.py +0 -0
  56. {nextrec-0.4.13 → nextrec-0.4.15}/nextrec/data/__init__.py +0 -0
  57. {nextrec-0.4.13 → nextrec-0.4.15}/nextrec/data/batch_utils.py +0 -0
  58. {nextrec-0.4.13 → nextrec-0.4.15}/nextrec/data/data_processing.py +0 -0
  59. {nextrec-0.4.13 → nextrec-0.4.15}/nextrec/data/data_utils.py +0 -0
  60. {nextrec-0.4.13 → nextrec-0.4.15}/nextrec/data/preprocessor.py +0 -0
  61. {nextrec-0.4.13 → nextrec-0.4.15}/nextrec/loss/__init__.py +0 -0
  62. {nextrec-0.4.13 → nextrec-0.4.15}/nextrec/loss/grad_norm.py +0 -0
  63. {nextrec-0.4.13 → nextrec-0.4.15}/nextrec/loss/listwise.py +0 -0
  64. {nextrec-0.4.13 → nextrec-0.4.15}/nextrec/loss/loss_utils.py +0 -0
  65. {nextrec-0.4.13 → nextrec-0.4.15}/nextrec/loss/pairwise.py +0 -0
  66. {nextrec-0.4.13 → nextrec-0.4.15}/nextrec/loss/pointwise.py +0 -0
  67. {nextrec-0.4.13 → nextrec-0.4.15}/nextrec/models/generative/__init__.py +0 -0
  68. {nextrec-0.4.13 → nextrec-0.4.15}/nextrec/models/generative/tiger.py +0 -0
  69. {nextrec-0.4.13 → nextrec-0.4.15}/nextrec/models/multi_task/__init__.py +0 -0
  70. {nextrec-0.4.13 → nextrec-0.4.15}/nextrec/models/multi_task/esmm.py +0 -0
  71. {nextrec-0.4.13 → nextrec-0.4.15}/nextrec/models/multi_task/mmoe.py +0 -0
  72. {nextrec-0.4.13 → nextrec-0.4.15}/nextrec/models/multi_task/ple.py +0 -0
  73. {nextrec-0.4.13 → nextrec-0.4.15}/nextrec/models/multi_task/poso.py +0 -0
  74. {nextrec-0.4.13 → nextrec-0.4.15}/nextrec/models/multi_task/share_bottom.py +0 -0
  75. {nextrec-0.4.13 → nextrec-0.4.15}/nextrec/models/ranking/__init__.py +0 -0
  76. {nextrec-0.4.13 → nextrec-0.4.15}/nextrec/models/ranking/afm.py +0 -0
  77. {nextrec-0.4.13 → nextrec-0.4.15}/nextrec/models/ranking/autoint.py +0 -0
  78. {nextrec-0.4.13 → nextrec-0.4.15}/nextrec/models/ranking/dcn.py +0 -0
  79. {nextrec-0.4.13 → nextrec-0.4.15}/nextrec/models/ranking/dcn_v2.py +0 -0
  80. {nextrec-0.4.13 → nextrec-0.4.15}/nextrec/models/ranking/deepfm.py +0 -0
  81. {nextrec-0.4.13 → nextrec-0.4.15}/nextrec/models/ranking/dien.py +0 -0
  82. {nextrec-0.4.13 → nextrec-0.4.15}/nextrec/models/ranking/din.py +0 -0
  83. {nextrec-0.4.13 → nextrec-0.4.15}/nextrec/models/ranking/eulernet.py +0 -0
  84. {nextrec-0.4.13 → nextrec-0.4.15}/nextrec/models/ranking/ffm.py +0 -0
  85. {nextrec-0.4.13 → nextrec-0.4.15}/nextrec/models/ranking/fibinet.py +0 -0
  86. {nextrec-0.4.13 → nextrec-0.4.15}/nextrec/models/ranking/fm.py +0 -0
  87. {nextrec-0.4.13 → nextrec-0.4.15}/nextrec/models/ranking/lr.py +0 -0
  88. {nextrec-0.4.13 → nextrec-0.4.15}/nextrec/models/ranking/masknet.py +0 -0
  89. {nextrec-0.4.13 → nextrec-0.4.15}/nextrec/models/ranking/pnn.py +0 -0
  90. {nextrec-0.4.13 → nextrec-0.4.15}/nextrec/models/ranking/widedeep.py +0 -0
  91. {nextrec-0.4.13 → nextrec-0.4.15}/nextrec/models/ranking/xdeepfm.py +0 -0
  92. {nextrec-0.4.13 → nextrec-0.4.15}/nextrec/models/representation/__init__.py +0 -0
  93. {nextrec-0.4.13 → nextrec-0.4.15}/nextrec/models/representation/autorec.py +0 -0
  94. {nextrec-0.4.13 → nextrec-0.4.15}/nextrec/models/representation/bpr.py +0 -0
  95. {nextrec-0.4.13 → nextrec-0.4.15}/nextrec/models/representation/cl4srec.py +0 -0
  96. {nextrec-0.4.13 → nextrec-0.4.15}/nextrec/models/representation/lightgcn.py +0 -0
  97. {nextrec-0.4.13 → nextrec-0.4.15}/nextrec/models/representation/mf.py +0 -0
  98. {nextrec-0.4.13 → nextrec-0.4.15}/nextrec/models/representation/rqvae.py +0 -0
  99. {nextrec-0.4.13 → nextrec-0.4.15}/nextrec/models/representation/s3rec.py +0 -0
  100. {nextrec-0.4.13 → nextrec-0.4.15}/nextrec/models/retrieval/__init__.py +0 -0
  101. {nextrec-0.4.13 → nextrec-0.4.15}/nextrec/models/retrieval/dssm.py +0 -0
  102. {nextrec-0.4.13 → nextrec-0.4.15}/nextrec/models/retrieval/dssm_v2.py +0 -0
  103. {nextrec-0.4.13 → nextrec-0.4.15}/nextrec/models/retrieval/mind.py +0 -0
  104. {nextrec-0.4.13 → nextrec-0.4.15}/nextrec/models/retrieval/sdm.py +0 -0
  105. {nextrec-0.4.13 → nextrec-0.4.15}/nextrec/models/retrieval/youtube_dnn.py +0 -0
  106. {nextrec-0.4.13 → nextrec-0.4.15}/nextrec/models/sequential/hstu.py +0 -0
  107. {nextrec-0.4.13 → nextrec-0.4.15}/nextrec/models/sequential/sasrec.py +0 -0
  108. {nextrec-0.4.13 → nextrec-0.4.15}/nextrec/utils/__init__.py +0 -0
  109. {nextrec-0.4.13 → nextrec-0.4.15}/nextrec/utils/console.py +0 -0
  110. {nextrec-0.4.13 → nextrec-0.4.15}/nextrec/utils/data.py +0 -0
  111. {nextrec-0.4.13 → nextrec-0.4.15}/nextrec/utils/embedding.py +0 -0
  112. {nextrec-0.4.13 → nextrec-0.4.15}/nextrec/utils/feature.py +0 -0
  113. {nextrec-0.4.13 → nextrec-0.4.15}/nextrec/utils/model.py +0 -0
  114. {nextrec-0.4.13 → nextrec-0.4.15}/nextrec/utils/torch_utils.py +0 -0
  115. {nextrec-0.4.13 → nextrec-0.4.15}/nextrec_cli_preset/NextRec-CLI.md +0 -0
  116. {nextrec-0.4.13 → nextrec-0.4.15}/nextrec_cli_preset/NextRec-CLI_zh.md +0 -0
  117. {nextrec-0.4.13 → nextrec-0.4.15}/nextrec_cli_preset/feature_config.yaml +0 -0
  118. {nextrec-0.4.13 → nextrec-0.4.15}/nextrec_cli_preset/model_configs/afm.yaml +0 -0
  119. {nextrec-0.4.13 → nextrec-0.4.15}/nextrec_cli_preset/model_configs/autoint.yaml +0 -0
  120. {nextrec-0.4.13 → nextrec-0.4.15}/nextrec_cli_preset/model_configs/dcn.yaml +0 -0
  121. {nextrec-0.4.13 → nextrec-0.4.15}/nextrec_cli_preset/model_configs/deepfm.yaml +0 -0
  122. {nextrec-0.4.13 → nextrec-0.4.15}/nextrec_cli_preset/model_configs/din.yaml +0 -0
  123. {nextrec-0.4.13 → nextrec-0.4.15}/nextrec_cli_preset/model_configs/esmm.yaml +0 -0
  124. {nextrec-0.4.13 → nextrec-0.4.15}/nextrec_cli_preset/model_configs/fibinet.yaml +0 -0
  125. {nextrec-0.4.13 → nextrec-0.4.15}/nextrec_cli_preset/model_configs/fm.yaml +0 -0
  126. {nextrec-0.4.13 → nextrec-0.4.15}/nextrec_cli_preset/model_configs/masknet.yaml +0 -0
  127. {nextrec-0.4.13 → nextrec-0.4.15}/nextrec_cli_preset/model_configs/mmoe.yaml +0 -0
  128. {nextrec-0.4.13 → nextrec-0.4.15}/nextrec_cli_preset/model_configs/ple.yaml +0 -0
  129. {nextrec-0.4.13 → nextrec-0.4.15}/nextrec_cli_preset/model_configs/pnn.yaml +0 -0
  130. {nextrec-0.4.13 → nextrec-0.4.15}/nextrec_cli_preset/model_configs/poso.yaml +0 -0
  131. {nextrec-0.4.13 → nextrec-0.4.15}/nextrec_cli_preset/model_configs/share_bottom.yaml +0 -0
  132. {nextrec-0.4.13 → nextrec-0.4.15}/nextrec_cli_preset/model_configs/widedeep.yaml +0 -0
  133. {nextrec-0.4.13 → nextrec-0.4.15}/nextrec_cli_preset/model_configs/xdeepfm.yaml +0 -0
  134. {nextrec-0.4.13 → nextrec-0.4.15}/nextrec_cli_preset/predict_config.yaml +0 -0
  135. {nextrec-0.4.13 → nextrec-0.4.15}/nextrec_cli_preset/predict_config_template.yaml +0 -0
  136. {nextrec-0.4.13 → nextrec-0.4.15}/nextrec_cli_preset/train_config.yaml +0 -0
  137. {nextrec-0.4.13 → nextrec-0.4.15}/nextrec_cli_preset/train_config_template.yaml +0 -0
  138. {nextrec-0.4.13 → nextrec-0.4.15}/pytest.ini +0 -0
  139. {nextrec-0.4.13 → nextrec-0.4.15}/requirements.txt +0 -0
  140. {nextrec-0.4.13 → nextrec-0.4.15}/scripts/format_code.py +0 -0
  141. {nextrec-0.4.13 → nextrec-0.4.15}/test/__init__.py +0 -0
  142. {nextrec-0.4.13 → nextrec-0.4.15}/test/conftest.py +0 -0
  143. {nextrec-0.4.13 → nextrec-0.4.15}/test/helpers.py +0 -0
  144. {nextrec-0.4.13 → nextrec-0.4.15}/test/run_tests.py +0 -0
  145. {nextrec-0.4.13 → nextrec-0.4.15}/test/test_base_model_regularization.py +0 -0
  146. {nextrec-0.4.13 → nextrec-0.4.15}/test/test_generative_models.py +0 -0
  147. {nextrec-0.4.13 → nextrec-0.4.15}/test/test_layers.py +0 -0
  148. {nextrec-0.4.13 → nextrec-0.4.15}/test/test_losses.py +0 -0
  149. {nextrec-0.4.13 → nextrec-0.4.15}/test/test_match_models.py +0 -0
  150. {nextrec-0.4.13 → nextrec-0.4.15}/test/test_multitask_models.py +0 -0
  151. {nextrec-0.4.13 → nextrec-0.4.15}/test/test_preprocessor.py +0 -0
  152. {nextrec-0.4.13 → nextrec-0.4.15}/test/test_ranking_models.py +0 -0
  153. {nextrec-0.4.13 → nextrec-0.4.15}/test/test_utils_console.py +0 -0
  154. {nextrec-0.4.13 → nextrec-0.4.15}/test/test_utils_data.py +0 -0
  155. {nextrec-0.4.13 → nextrec-0.4.15}/test/test_utils_embedding.py +0 -0
  156. {nextrec-0.4.13 → nextrec-0.4.15}/test_requirements.txt +0 -0
  157. {nextrec-0.4.13 → nextrec-0.4.15}/tutorials/distributed/example_distributed_training.py +0 -0
  158. {nextrec-0.4.13 → nextrec-0.4.15}/tutorials/distributed/example_distributed_training_large_dataset.py +0 -0
  159. {nextrec-0.4.13 → nextrec-0.4.15}/tutorials/example_multitask.py +0 -0
  160. {nextrec-0.4.13 → nextrec-0.4.15}/tutorials/example_ranking_din.py +0 -0
  161. {nextrec-0.4.13 → nextrec-0.4.15}/tutorials/movielen_match_dssm.py +0 -0
  162. {nextrec-0.4.13 → nextrec-0.4.15}/tutorials/movielen_ranking_deepfm.py +0 -0
  163. {nextrec-0.4.13 → nextrec-0.4.15}/tutorials/notebooks/en/Build semantic ID with RQ-VAE.ipynb +0 -0
  164. {nextrec-0.4.13 → nextrec-0.4.15}/tutorials/notebooks/en/Hands on dataprocessor.ipynb +0 -0
  165. {nextrec-0.4.13 → nextrec-0.4.15}/tutorials/notebooks/en/Hands on nextrec.ipynb +0 -0
  166. {nextrec-0.4.13 → nextrec-0.4.15}/tutorials/notebooks/zh//344/275/277/347/224/250RQ-VAE/346/236/204/345/273/272/350/257/255/344/271/211ID.ipynb" +0 -0
  167. {nextrec-0.4.13 → nextrec-0.4.15}/tutorials/notebooks/zh//345/246/202/344/275/225/344/275/277/347/224/250DataProcessor/350/277/233/350/241/214/351/242/204/345/244/204/347/220/206.ipynb" +0 -0
  168. {nextrec-0.4.13 → nextrec-0.4.15}/tutorials/notebooks/zh//345/277/253/351/200/237/345/205/245/351/227/250nextrec.ipynb" +0 -0
  169. {nextrec-0.4.13 → nextrec-0.4.15}/tutorials/run_all_match_models.py +0 -0
  170. {nextrec-0.4.13 → nextrec-0.4.15}/tutorials/run_all_multitask_models.py +0 -0
  171. {nextrec-0.4.13 → nextrec-0.4.15}/tutorials/run_all_ranking_models.py +0 -0
@@ -0,0 +1,107 @@
1
+ name: Publish to PyPI
2
+
3
+ on:
4
+ push:
5
+ branches:
6
+ - main
7
+ - dev
8
+ workflow_dispatch:
9
+
10
+ jobs:
11
+ check-version:
12
+ runs-on: ubuntu-latest
13
+ outputs:
14
+ changed: ${{ steps.version.outputs.changed }}
15
+ steps:
16
+ - name: Checkout code
17
+ uses: actions/checkout@v4
18
+ with:
19
+ fetch-depth: 0
20
+
21
+ - name: Compare project version
22
+ id: version
23
+ run: |
24
+ before="${{ github.event.before }}"
25
+ after="${{ github.sha }}"
26
+ zero_sha="0000000000000000000000000000000000000000"
27
+
28
+ if [ -z "$before" ] || [ "$before" = "$zero_sha" ]; then
29
+ echo "changed=true" >> "$GITHUB_OUTPUT"
30
+ exit 0
31
+ fi
32
+
33
+ get_version() {
34
+ git show "$1:pyproject.toml" | grep -m 1 '^version[[:space:]]*=' | sed -E 's/.*"([^"]+)".*/\1/'
35
+ }
36
+
37
+ before_version="$(get_version "$before" || true)"
38
+ after_version="$(get_version "$after" || true)"
39
+
40
+ if [ -z "$before_version" ] || [ -z "$after_version" ]; then
41
+ echo "changed=true" >> "$GITHUB_OUTPUT"
42
+ exit 0
43
+ fi
44
+
45
+ if [ "$before_version" = "$after_version" ]; then
46
+ echo "changed=false" >> "$GITHUB_OUTPUT"
47
+ else
48
+ echo "changed=true" >> "$GITHUB_OUTPUT"
49
+ fi
50
+
51
+ # dev -> TestPyPI
52
+ publish-to-testpypi:
53
+ needs: check-version
54
+ if: needs.check-version.outputs.changed == 'true' && github.ref == 'refs/heads/dev'
55
+ runs-on: ubuntu-latest
56
+ steps:
57
+ - name: Checkout code
58
+ uses: actions/checkout@v4
59
+
60
+ - name: Set up Python
61
+ uses: actions/setup-python@v5
62
+ with:
63
+ python-version: '3.10'
64
+
65
+ - name: Install build tools
66
+ run: |
67
+ pip install build twine
68
+
69
+ - name: Build package
70
+ run: |
71
+ python -m build
72
+
73
+ - name: Publish to TestPyPI
74
+ env:
75
+ TWINE_USERNAME: ${{ secrets.TEST_PYPI_USERNAME }}
76
+ TWINE_PASSWORD: ${{ secrets.TEST_PYPI_PASSWORD }}
77
+ run: |
78
+ twine upload --verbose --repository testpypi dist/*
79
+
80
+ # main -> PyPI
81
+ publish-to-pypi:
82
+ needs: check-version
83
+ if: needs.check-version.outputs.changed == 'true' && github.ref == 'refs/heads/main'
84
+ runs-on: ubuntu-latest
85
+ steps:
86
+ - name: Checkout code
87
+ uses: actions/checkout@v4
88
+
89
+ - name: Set up Python
90
+ uses: actions/setup-python@v5
91
+ with:
92
+ python-version: '3.10'
93
+
94
+ - name: Install build tools
95
+ run: |
96
+ pip install build twine
97
+
98
+ - name: Build package
99
+ run: |
100
+ python -m build
101
+
102
+ - name: Publish to PyPI
103
+ env:
104
+ TWINE_USERNAME: ${{ secrets.PYPI_USERNAME }}
105
+ TWINE_PASSWORD: ${{ secrets.PYPI_PASSWORD }}
106
+ run: |
107
+ twine upload --verbose dist/*
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: nextrec
3
- Version: 0.4.13
3
+ Version: 0.4.15
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
@@ -63,10 +63,13 @@ Description-Content-Type: text/markdown
63
63
 
64
64
  <div align="center">
65
65
 
66
+ [![PyPI Downloads](https://static.pepy.tech/personalized-badge/nextrec?period=total&units=NONE&left_color=BLACK&right_color=GREEN&left_text=PyPI-downloads)](https://pepy.tech/projects/nextrec)
66
67
  ![Python](https://img.shields.io/badge/Python-3.10+-blue.svg)
67
68
  ![PyTorch](https://img.shields.io/badge/PyTorch-1.10+-ee4c2c.svg)
69
+
68
70
  ![License](https://img.shields.io/badge/License-Apache%202.0-green.svg)
69
- ![Version](https://img.shields.io/badge/Version-0.4.13-orange.svg)
71
+ ![Version](https://img.shields.io/badge/Version-0.4.15-orange.svg)
72
+
70
73
 
71
74
  中文文档 | [English Version](README_en.md)
72
75
 
@@ -99,7 +102,8 @@ NextRec是一个基于PyTorch的现代推荐系统框架,旨在为研究工程
99
102
 
100
103
  ## NextRec近期进展
101
104
 
102
- - **12/12/2025** 在v0.4.13中加入了[RQ-VAE](/nextrec/models/representation/rqvae.py)模块。配套的[数据集](/dataset/ecommerce_task.csv)和[代码](tutorials/notebooks/zh/使用RQ-VAE构建语义ID.ipynb)已经同步在仓库中
105
+ - **21/12/2025** 在v0.4.15中加入了对[GradNorm](/nextrec/loss/grad_norm.py)的支持,通过compile的`loss_weight='grad_norm'`进行配置
106
+ - **12/12/2025** 在v0.4.9中加入了[RQ-VAE](/nextrec/models/representation/rqvae.py)模块。配套的[数据集](/dataset/ecommerce_task.csv)和[代码](tutorials/notebooks/zh/使用RQ-VAE构建语义ID.ipynb)已经同步在仓库中
103
107
  - **07/12/2025** 发布了NextRec CLI命令行工具,它允许用户根据配置文件进行一键训练和推理,我们提供了相关的[教程](/nextrec_cli_preset/NextRec-CLI_zh.md)和[教学代码](/nextrec_cli_preset)
104
108
  - **03/12/2025** NextRec获得了100颗🌟!感谢大家的支持
105
109
  - **06/12/2025** 在v0.4.1中支持了单机多卡的分布式DDP训练,并且提供了配套的[代码](tutorials/distributed)
@@ -240,11 +244,11 @@ nextrec --mode=train --train_config=path/to/train_config.yaml
240
244
  nextrec --mode=predict --predict_config=path/to/predict_config.yaml
241
245
  ```
242
246
 
243
- > 截止当前版本0.4.13,NextRec CLI支持单机训练,分布式训练相关功能尚在开发中。
247
+ > 截止当前版本0.4.15,NextRec CLI支持单机训练,分布式训练相关功能尚在开发中。
244
248
 
245
249
  ## 兼容平台
246
250
 
247
- 当前最新版本为0.4.13,所有模型和测试代码均已在以下平台通过验证,如果开发者在使用中遇到兼容问题,请在issue区提出错误报告及系统版本:
251
+ 当前最新版本为0.4.15,所有模型和测试代码均已在以下平台通过验证,如果开发者在使用中遇到兼容问题,请在issue区提出错误报告及系统版本:
248
252
 
249
253
  | 平台 | 配置 |
250
254
  |------|------|
@@ -4,10 +4,13 @@
4
4
 
5
5
  <div align="center">
6
6
 
7
+ [![PyPI Downloads](https://static.pepy.tech/personalized-badge/nextrec?period=total&units=NONE&left_color=BLACK&right_color=GREEN&left_text=PyPI-downloads)](https://pepy.tech/projects/nextrec)
7
8
  ![Python](https://img.shields.io/badge/Python-3.10+-blue.svg)
8
9
  ![PyTorch](https://img.shields.io/badge/PyTorch-1.10+-ee4c2c.svg)
10
+
9
11
  ![License](https://img.shields.io/badge/License-Apache%202.0-green.svg)
10
- ![Version](https://img.shields.io/badge/Version-0.4.13-orange.svg)
12
+ ![Version](https://img.shields.io/badge/Version-0.4.15-orange.svg)
13
+
11
14
 
12
15
  中文文档 | [English Version](README_en.md)
13
16
 
@@ -40,7 +43,8 @@ NextRec是一个基于PyTorch的现代推荐系统框架,旨在为研究工程
40
43
 
41
44
  ## NextRec近期进展
42
45
 
43
- - **12/12/2025** 在v0.4.13中加入了[RQ-VAE](/nextrec/models/representation/rqvae.py)模块。配套的[数据集](/dataset/ecommerce_task.csv)和[代码](tutorials/notebooks/zh/使用RQ-VAE构建语义ID.ipynb)已经同步在仓库中
46
+ - **21/12/2025** 在v0.4.15中加入了对[GradNorm](/nextrec/loss/grad_norm.py)的支持,通过compile的`loss_weight='grad_norm'`进行配置
47
+ - **12/12/2025** 在v0.4.9中加入了[RQ-VAE](/nextrec/models/representation/rqvae.py)模块。配套的[数据集](/dataset/ecommerce_task.csv)和[代码](tutorials/notebooks/zh/使用RQ-VAE构建语义ID.ipynb)已经同步在仓库中
44
48
  - **07/12/2025** 发布了NextRec CLI命令行工具,它允许用户根据配置文件进行一键训练和推理,我们提供了相关的[教程](/nextrec_cli_preset/NextRec-CLI_zh.md)和[教学代码](/nextrec_cli_preset)
45
49
  - **03/12/2025** NextRec获得了100颗🌟!感谢大家的支持
46
50
  - **06/12/2025** 在v0.4.1中支持了单机多卡的分布式DDP训练,并且提供了配套的[代码](tutorials/distributed)
@@ -181,11 +185,11 @@ nextrec --mode=train --train_config=path/to/train_config.yaml
181
185
  nextrec --mode=predict --predict_config=path/to/predict_config.yaml
182
186
  ```
183
187
 
184
- > 截止当前版本0.4.13,NextRec CLI支持单机训练,分布式训练相关功能尚在开发中。
188
+ > 截止当前版本0.4.15,NextRec CLI支持单机训练,分布式训练相关功能尚在开发中。
185
189
 
186
190
  ## 兼容平台
187
191
 
188
- 当前最新版本为0.4.13,所有模型和测试代码均已在以下平台通过验证,如果开发者在使用中遇到兼容问题,请在issue区提出错误报告及系统版本:
192
+ 当前最新版本为0.4.15,所有模型和测试代码均已在以下平台通过验证,如果开发者在使用中遇到兼容问题,请在issue区提出错误报告及系统版本:
189
193
 
190
194
  | 平台 | 配置 |
191
195
  |------|------|
@@ -4,10 +4,12 @@
4
4
 
5
5
  <div align="center">
6
6
 
7
+ [![PyPI Downloads](https://static.pepy.tech/personalized-badge/nextrec?period=total&units=NONE&left_color=BLACK&right_color=GREEN&left_text=PyPI-downloads)](https://pepy.tech/projects/nextrec)
7
8
  ![Python](https://img.shields.io/badge/Python-3.10+-blue.svg)
8
9
  ![PyTorch](https://img.shields.io/badge/PyTorch-1.10+-ee4c2c.svg)
10
+
9
11
  ![License](https://img.shields.io/badge/License-Apache%202.0-green.svg)
10
- ![Version](https://img.shields.io/badge/Version-0.4.13-orange.svg)
12
+ ![Version](https://img.shields.io/badge/Version-0.4.15-orange.svg)
11
13
 
12
14
  English | [中文文档](README.md)
13
15
 
@@ -42,7 +44,8 @@ NextRec is a modern recommendation framework built on PyTorch, delivering a unif
42
44
 
43
45
  ## NextRec Progress
44
46
 
45
- - **12/12/2025** Added [RQ-VAE](/nextrec/models/representation/rqvae.py), a common module for generative retrieval. Paired [dataset](/dataset/ecommerce_task.csv) and [notebook code](tutorials/notebooks/en/Build%20semantic%20ID%20with%20RQ-VAE.ipynb) are available.
47
+ - **21/12/2025** Added support for [GradNorm](/nextrec/loss/grad_norm.py) in v0.4.15, configurable via `loss_weight='grad_norm'` in the compile method
48
+ - **12/12/2025** Added [RQ-VAE](/nextrec/models/representation/rqvae.py), a common module for generative retrieval in v0.4.9. Paired [dataset](/dataset/ecommerce_task.csv) and [notebook code](tutorials/notebooks/en/Build%20semantic%20ID%20with%20RQ-VAE.ipynb) are available.
46
49
  - **07/12/2025** Released the NextRec CLI tool to run training/inference from configs. See the [guide](/nextrec_cli_preset/NextRec-CLI.md) and [reference code](/nextrec_cli_preset).
47
50
  - **03/12/2025** NextRec reached 100 ⭐—thanks for the support!
48
51
  - **06/12/2025** Added single-machine multi-GPU DDP training in v0.4.1 with supporting [code](tutorials/distributed).
@@ -185,11 +188,11 @@ nextrec --mode=train --train_config=path/to/train_config.yaml
185
188
  nextrec --mode=predict --predict_config=path/to/predict_config.yaml
186
189
  ```
187
190
 
188
- > As of version 0.4.13, NextRec CLI supports single-machine training; distributed training features are currently under development.
191
+ > As of version 0.4.15, NextRec CLI supports single-machine training; distributed training features are currently under development.
189
192
 
190
193
  ## Platform Compatibility
191
194
 
192
- The current version is 0.4.13. All models and test code have been validated on the following platforms. If you encounter compatibility issues, please report them in the issue tracker with your system version:
195
+ The current version is 0.4.15. All models and test code have been validated on the following platforms. If you encounter compatibility issues, please report them in the issue tracker with your system version:
193
196
 
194
197
  | Platform | Configuration |
195
198
  |----------|---------------|
@@ -11,7 +11,7 @@ sys.path.insert(0, str(PROJECT_ROOT / "nextrec"))
11
11
  project = "NextRec"
12
12
  copyright = "2025, Yang Zhou"
13
13
  author = "Yang Zhou"
14
- release = "0.4.13"
14
+ release = "0.4.15"
15
15
 
16
16
  extensions = [
17
17
  "myst_parser",
@@ -0,0 +1 @@
1
+ __version__ = "0.4.15"
@@ -341,7 +341,7 @@ class BaseModel(FeatureSet, nn.Module):
341
341
  )
342
342
  else:
343
343
  raise TypeError(
344
- f"[BaseModel-validation Error] train_data must be a pandas DataFrame or a dict, got {type(train_data)}"
344
+ f"[BaseModel-validation Error] If you want to use validation_split, train_data must be a pandas DataFrame or a dict instead of {type(train_data)}"
345
345
  )
346
346
  rng = np.random.default_rng(42)
347
347
  indices = rng.permutation(total_length)
@@ -481,7 +481,7 @@ class BaseModel(FeatureSet, nn.Module):
481
481
  "[BaseModel-compile Error] loss_weights list must have exactly one element for single-task setup."
482
482
  )
483
483
  loss_weights = loss_weights[0]
484
- self.loss_weights = [float(loss_weights)]
484
+ self.loss_weights = [float(loss_weights)] # type: ignore
485
485
  else:
486
486
  if isinstance(loss_weights, (int, float)):
487
487
  weights = [float(loss_weights)] * self.nums_task
@@ -555,13 +555,13 @@ class BaseModel(FeatureSet, nn.Module):
555
555
 
556
556
  def prepare_data_loader(
557
557
  self,
558
- data: dict | pd.DataFrame | DataLoader,
558
+ data,
559
559
  batch_size: int = 32,
560
560
  shuffle: bool = True,
561
561
  num_workers: int = 0,
562
562
  sampler=None,
563
563
  return_dataset: bool = False,
564
- ) -> DataLoader | tuple[DataLoader, TensorDictDataset | None]:
564
+ ):
565
565
  """
566
566
  Prepare a DataLoader from input data. Only used when input data is not a DataLoader.
567
567
  """
@@ -591,8 +591,8 @@ class BaseModel(FeatureSet, nn.Module):
591
591
 
592
592
  def fit(
593
593
  self,
594
- train_data: dict | pd.DataFrame | DataLoader,
595
- valid_data: dict | pd.DataFrame | DataLoader | None = None,
594
+ train_data = None,
595
+ valid_data = None,
596
596
  metrics: (
597
597
  list[str] | dict[str, list[str]] | None
598
598
  ) = None, # ['auc', 'logloss'] or {'target1': ['auc', 'logloss'], 'target2': ['mse']}
@@ -1420,6 +1420,11 @@ class BaseModel(FeatureSet, nn.Module):
1420
1420
  # Create DataLoader based on data type
1421
1421
  if isinstance(data, DataLoader):
1422
1422
  data_loader = data
1423
+ if num_workers != 0:
1424
+ logging.warning(
1425
+ "[Predict Warning] num_workers parameter is ignored when data is already a DataLoader. "
1426
+ "The DataLoader's existing num_workers configuration will be used."
1427
+ )
1423
1428
  elif isinstance(data, (str, os.PathLike)):
1424
1429
  rec_loader = RecDataLoader(
1425
1430
  dense_features=self.dense_features,
@@ -1578,6 +1583,14 @@ class BaseModel(FeatureSet, nn.Module):
1578
1583
  else:
1579
1584
  data_loader = data
1580
1585
 
1586
+ if hasattr(data_loader, 'num_workers') and data_loader.num_workers > 0:
1587
+ if hasattr(data_loader.dataset, '__class__') and 'Streaming' in data_loader.dataset.__class__.__name__:
1588
+ logging.warning(
1589
+ f"[Predict Streaming Warning] Detected DataLoader with num_workers={data_loader.num_workers} "
1590
+ "and streaming dataset. This may cause data duplication! "
1591
+ "When using streaming mode, set num_workers=0 to avoid reading data multiple times."
1592
+ )
1593
+
1581
1594
  suffix = ".csv" if save_format == "csv" else ".parquet"
1582
1595
  target_path = resolve_save_path(
1583
1596
  path=save_path,
@@ -1943,6 +1956,12 @@ class BaseModel(FeatureSet, nn.Module):
1943
1956
  logger.info(f"Loss Function: {self.loss_config}")
1944
1957
  if hasattr(self, "loss_weights"):
1945
1958
  logger.info(f"Loss Weights: {self.loss_weights}")
1959
+ if hasattr(self, "grad_norm"):
1960
+ logger.info(f"GradNorm Enabled: {self.grad_norm is not None}")
1961
+ if self.grad_norm is not None:
1962
+ grad_lr = self.grad_norm.optimizer.param_groups[0].get("lr")
1963
+ logger.info(f" GradNorm alpha: {self.grad_norm.alpha}")
1964
+ logger.info(f" GradNorm lr: {grad_lr}")
1946
1965
 
1947
1966
  logger.info("Regularization:")
1948
1967
  logger.info(f" Embedding L1: {self.embedding_l1_reg}")
@@ -21,6 +21,7 @@ Author: Yang Zhou, zyaztec@gmail.com
21
21
  import argparse
22
22
  import logging
23
23
  import pickle
24
+ import resource
24
25
  import sys
25
26
  import time
26
27
  from pathlib import Path
@@ -625,6 +626,17 @@ def predict_model(predict_config_path: str) -> None:
625
626
  def main() -> None:
626
627
  """Parse CLI arguments and dispatch to train or predict mode."""
627
628
 
629
+ # Increase file descriptor limit to avoid "Too many open files" error
630
+ # when using DataLoader with multiple workers
631
+ try:
632
+ soft, hard = resource.getrlimit(resource.RLIMIT_NOFILE)
633
+ target_limit = 65535
634
+ if soft < target_limit:
635
+ resource.setrlimit(resource.RLIMIT_NOFILE, (min(target_limit, hard), hard))
636
+ except (ValueError, OSError):
637
+ # If we can't set the limit, continue anyway
638
+ pass
639
+
628
640
  root = logging.getLogger()
629
641
  if not root.handlers:
630
642
  handler = logging.StreamHandler(sys.stdout)
@@ -186,6 +186,7 @@ class RecDataLoader(FeatureSet):
186
186
  | list[str]
187
187
  | list[os.PathLike]
188
188
  | DataLoader
189
+ | None
189
190
  ),
190
191
  batch_size: int = 32,
191
192
  shuffle: bool = True,
@@ -209,6 +210,15 @@ class RecDataLoader(FeatureSet):
209
210
  DataLoader instance.
210
211
  """
211
212
 
213
+ # Enforce num_workers=0 for streaming mode to prevent data duplication
214
+ if streaming and num_workers > 0:
215
+ logging.warning(
216
+ f"[RecDataLoader Warning] num_workers={num_workers} is not compatible with streaming=True. "
217
+ "Each worker would create its own data stream, causing data duplication. "
218
+ "Forcing num_workers=0."
219
+ )
220
+ num_workers = 0
221
+
212
222
  if isinstance(data, DataLoader):
213
223
  return data
214
224
  elif isinstance(data, (str, os.PathLike)):
@@ -362,6 +372,13 @@ class RecDataLoader(FeatureSet):
362
372
  logging.info(
363
373
  "[RecDataLoader Info] Streaming mode enforces batch_size=1; tune chunk_size to control memory/throughput."
364
374
  )
375
+ if num_workers > 0:
376
+ logging.warning(
377
+ f"[RecDataLoader Warning] num_workers={num_workers} is not compatible with streaming mode. "
378
+ "Each worker would create its own data stream, causing data duplication. "
379
+ "Forcing num_workers=0."
380
+ )
381
+ num_workers = 0
365
382
  dataset = FileDataset(
366
383
  file_paths=file_paths,
367
384
  dense_features=self.dense_features,
@@ -28,19 +28,19 @@ if TYPE_CHECKING:
28
28
  from nextrec.data.preprocessor import DataProcessor
29
29
 
30
30
 
31
- def resolve_path(path_str: str | Path, base_dir: Path) -> Path:
31
+ def resolve_path(path_str: str | Path | None = None, base_dir: Path | None = None) -> Path:
32
+ if path_str is None:
33
+ return Path.cwd()
32
34
  path = Path(path_str).expanduser()
33
35
  if path.is_absolute():
34
36
  return path
35
37
  # Prefer resolving relative to current working directory when the path (or its parent)
36
38
  # already exists there; otherwise fall back to the config file's directory.
37
- cwd_path = (Path.cwd() / path).resolve()
38
- if cwd_path.exists() or cwd_path.parent.exists():
39
- return cwd_path
40
- base_dir_path = (base_dir / path).resolve()
41
- if base_dir_path.exists() or base_dir_path.parent.exists():
42
- return base_dir_path
43
- return cwd_path
39
+ candidates = ((Path.cwd() / path).resolve(), ((base_dir or Path.cwd()) / path).resolve())
40
+ return next(
41
+ (candidate for candidate in candidates if candidate.exists() or candidate.parent.exists()),
42
+ candidates[0],
43
+ )
44
44
 
45
45
 
46
46
  def select_features(
@@ -1,6 +1,6 @@
1
1
  [project]
2
2
  name = "nextrec"
3
- version = "0.4.13"
3
+ version = "0.4.15"
4
4
  description = "A comprehensive recommendation library with match, ranking, and multi-task learning models"
5
5
  readme = "README.md"
6
6
  requires-python = ">=3.10"
@@ -1,65 +0,0 @@
1
- name: Publish to PyPI
2
-
3
- on:
4
- push:
5
- branches:
6
- - main
7
- - dev
8
- workflow_dispatch:
9
-
10
- jobs:
11
- # dev -> TestPyPI
12
- publish-to-testpypi:
13
- if: github.ref == 'refs/heads/dev'
14
- runs-on: ubuntu-latest
15
- steps:
16
- - name: Checkout code
17
- uses: actions/checkout@v4
18
-
19
- - name: Set up Python
20
- uses: actions/setup-python@v5
21
- with:
22
- python-version: '3.10'
23
-
24
- - name: Install build tools
25
- run: |
26
- pip install build twine
27
-
28
- - name: Build package
29
- run: |
30
- python -m build
31
-
32
- - name: Publish to TestPyPI
33
- env:
34
- TWINE_USERNAME: ${{ secrets.TEST_PYPI_USERNAME }}
35
- TWINE_PASSWORD: ${{ secrets.TEST_PYPI_PASSWORD }}
36
- run: |
37
- twine upload --verbose --repository testpypi dist/*
38
-
39
- # main -> PyPI
40
- publish-to-pypi:
41
- if: github.ref == 'refs/heads/main'
42
- runs-on: ubuntu-latest
43
- steps:
44
- - name: Checkout code
45
- uses: actions/checkout@v4
46
-
47
- - name: Set up Python
48
- uses: actions/setup-python@v5
49
- with:
50
- python-version: '3.10'
51
-
52
- - name: Install build tools
53
- run: |
54
- pip install build twine
55
-
56
- - name: Build package
57
- run: |
58
- python -m build
59
-
60
- - name: Publish to PyPI
61
- env:
62
- TWINE_USERNAME: ${{ secrets.PYPI_USERNAME }}
63
- TWINE_PASSWORD: ${{ secrets.PYPI_PASSWORD }}
64
- run: |
65
- twine upload --verbose dist/*
@@ -1 +0,0 @@
1
- __version__ = "0.4.13"
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes