xpm-torch 0.1.0__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 (55) hide show
  1. xpm_torch-0.1.0/.git +1 -0
  2. xpm_torch-0.1.0/.github/workflows/pytest.yml +29 -0
  3. xpm_torch-0.1.0/.github/workflows/python-publish.yml +25 -0
  4. xpm_torch-0.1.0/.gitignore +105 -0
  5. xpm_torch-0.1.0/.pre-commit-config.yaml +36 -0
  6. xpm_torch-0.1.0/.readthedocs.yml +18 -0
  7. xpm_torch-0.1.0/PKG-INFO +65 -0
  8. xpm_torch-0.1.0/README.md +49 -0
  9. xpm_torch-0.1.0/docs/Makefile +12 -0
  10. xpm_torch-0.1.0/docs/source/conf.py +50 -0
  11. xpm_torch-0.1.0/docs/source/huggingface.rst +253 -0
  12. xpm_torch-0.1.0/docs/source/index.rst +19 -0
  13. xpm_torch-0.1.0/docs/source/module.rst +66 -0
  14. xpm_torch-0.1.0/docs/source/optimization.rst +44 -0
  15. xpm_torch-0.1.0/docs/source/overview.rst +158 -0
  16. xpm_torch-0.1.0/docs/source/training.rst +89 -0
  17. xpm_torch-0.1.0/pyproject.toml +48 -0
  18. xpm_torch-0.1.0/src/xpm_torch/__init__.py +3 -0
  19. xpm_torch-0.1.0/src/xpm_torch/actions.py +77 -0
  20. xpm_torch-0.1.0/src/xpm_torch/base.py +55 -0
  21. xpm_torch-0.1.0/src/xpm_torch/batchers.py +281 -0
  22. xpm_torch-0.1.0/src/xpm_torch/cli.py +8 -0
  23. xpm_torch-0.1.0/src/xpm_torch/configuration.py +95 -0
  24. xpm_torch-0.1.0/src/xpm_torch/context.py +52 -0
  25. xpm_torch-0.1.0/src/xpm_torch/datasets.py +351 -0
  26. xpm_torch-0.1.0/src/xpm_torch/experiments/__init__.py +2 -0
  27. xpm_torch-0.1.0/src/xpm_torch/experiments/configuration.py +132 -0
  28. xpm_torch-0.1.0/src/xpm_torch/experiments/helpers.py +21 -0
  29. xpm_torch-0.1.0/src/xpm_torch/experiments/services.py +108 -0
  30. xpm_torch-0.1.0/src/xpm_torch/huggingface.py +202 -0
  31. xpm_torch-0.1.0/src/xpm_torch/learner.py +431 -0
  32. xpm_torch-0.1.0/src/xpm_torch/losses/__init__.py +65 -0
  33. xpm_torch-0.1.0/src/xpm_torch/losses/batchwise.py +61 -0
  34. xpm_torch-0.1.0/src/xpm_torch/losses/pairwise.py +128 -0
  35. xpm_torch-0.1.0/src/xpm_torch/metrics.py +75 -0
  36. xpm_torch-0.1.0/src/xpm_torch/module.py +318 -0
  37. xpm_torch-0.1.0/src/xpm_torch/optim.py +488 -0
  38. xpm_torch-0.1.0/src/xpm_torch/parameters.py +349 -0
  39. xpm_torch-0.1.0/src/xpm_torch/results.py +24 -0
  40. xpm_torch-0.1.0/src/xpm_torch/schedulers.py +68 -0
  41. xpm_torch-0.1.0/src/xpm_torch/trainers/__init__.py +186 -0
  42. xpm_torch-0.1.0/src/xpm_torch/trainers/context.py +348 -0
  43. xpm_torch-0.1.0/src/xpm_torch/trainers/hooks.py +47 -0
  44. xpm_torch-0.1.0/src/xpm_torch/trainers/multiple.py +44 -0
  45. xpm_torch-0.1.0/src/xpm_torch/trainers/validation.py +172 -0
  46. xpm_torch-0.1.0/src/xpm_torch/utils/__init__.py +1 -0
  47. xpm_torch-0.1.0/src/xpm_torch/utils/iter.py +147 -0
  48. xpm_torch-0.1.0/src/xpm_torch/utils/logging.py +33 -0
  49. xpm_torch-0.1.0/src/xpm_torch/utils/utils.py +234 -0
  50. xpm_torch-0.1.0/src/xpm_torch/validation.py +26 -0
  51. xpm_torch-0.1.0/tests/__init__.py +0 -0
  52. xpm_torch-0.1.0/tests/test_documented.py +19 -0
  53. xpm_torch-0.1.0/tests/test_module.py +64 -0
  54. xpm_torch-0.1.0/tests/test_trainstate.py +96 -0
  55. xpm_torch-0.1.0/uv.lock +3170 -0
xpm_torch-0.1.0/.git ADDED
@@ -0,0 +1 @@
1
+ gitdir: ../.git/modules/xpm-torch
@@ -0,0 +1,29 @@
1
+ name: Python tests
2
+
3
+ on:
4
+ push:
5
+ branches: [main]
6
+ pull_request:
7
+ branches: [main]
8
+
9
+ jobs:
10
+ test:
11
+ runs-on: ubuntu-latest
12
+ strategy:
13
+ matrix:
14
+ python-version: ["3.10", "3.11", "3.12"]
15
+
16
+ steps:
17
+ - uses: actions/checkout@v4
18
+ - name: Install uv
19
+ uses: astral-sh/setup-uv@v4
20
+ with:
21
+ enable-cache: true
22
+ - name: Set up Python ${{ matrix.python-version }}
23
+ run: uv python install ${{ matrix.python-version }}
24
+ - name: Install dependencies
25
+ run: uv sync --group test --group dev
26
+ - name: Lint with ruff
27
+ run: uv run ruff check .
28
+ - name: Run tests
29
+ run: uv run pytest
@@ -0,0 +1,25 @@
1
+ name: Publish to PyPI
2
+
3
+ on:
4
+ release:
5
+ types: [created]
6
+
7
+ permissions:
8
+ contents: write
9
+ id-token: write
10
+
11
+ jobs:
12
+ publish:
13
+ runs-on: ubuntu-latest
14
+ steps:
15
+ - uses: actions/checkout@v4
16
+ - name: Set up Python
17
+ uses: actions/setup-python@v5
18
+ with:
19
+ python-version: "3.12"
20
+ - name: Install build tools
21
+ run: pip install hatch
22
+ - name: Build package
23
+ run: hatch build
24
+ - name: Publish to PyPI
25
+ uses: pypa/gh-action-pypi-publish@release/v1
@@ -0,0 +1,105 @@
1
+ # Byte-compiled / optimized / DLL files
2
+ __pycache__/
3
+ *.py[cod]
4
+ *$py.class
5
+
6
+ # C extensions
7
+ *.so
8
+
9
+ # Distribution / packaging
10
+ .Python
11
+ build/
12
+ develop-eggs/
13
+ dist/
14
+ downloads/
15
+ eggs/
16
+ .eggs/
17
+ lib/
18
+ lib64/
19
+ parts/
20
+ sdist/
21
+ var/
22
+ wheels/
23
+ *.egg-info/
24
+ .installed.cfg
25
+ *.egg
26
+ MANIFEST
27
+
28
+ # PyInstaller
29
+ # Usually these files are written by a python script from a template
30
+ # before PyInstaller builds the exe, so as to inject date/other infos into it.
31
+ *.manifest
32
+ *.spec
33
+
34
+ # Installer logs
35
+ pip-log.txt
36
+ pip-delete-this-directory.txt
37
+
38
+ # Unit test / coverage reports
39
+ htmlcov/
40
+ .tox/
41
+ .coverage
42
+ .coverage.*
43
+ .cache
44
+ nosetests.xml
45
+ coverage.xml
46
+ *.cover
47
+ .hypothesis/
48
+ .pytest_cache/
49
+
50
+ # Translations
51
+ *.mo
52
+ *.pot
53
+
54
+ # Django stuff:
55
+ *.log
56
+ local_settings.py
57
+ db.sqlite3
58
+
59
+ # Flask stuff:
60
+ instance/
61
+ .webassets-cache
62
+
63
+ # Scrapy stuff:
64
+ .scrapy
65
+
66
+ # Sphinx documentation
67
+ docs/_build/
68
+
69
+ # PyBuilder
70
+ target/
71
+
72
+ # Jupyter Notebook
73
+ .ipynb_checkpoints
74
+ .ipynb
75
+
76
+ # pyenv
77
+ .python-version
78
+
79
+ # celery beat schedule file
80
+ celerybeat-schedule
81
+
82
+ # SageMath parsed files
83
+ *.sage.py
84
+
85
+ # Environments
86
+ .env
87
+ .venv
88
+ env/
89
+ venv/
90
+ ENV/
91
+ env.bak/
92
+ venv.bak/
93
+
94
+ # Spyder project settings
95
+ .spyderproject
96
+ .spyproject
97
+
98
+ # Rope project settings
99
+ .ropeproject
100
+
101
+ # mypy
102
+ .mypy_cache/
103
+ .vscode/
104
+ src/xpmir/_version.py
105
+ .DS_Store
@@ -0,0 +1,36 @@
1
+ default_install_hook_types:
2
+ - pre-commit
3
+ - commit-msg
4
+
5
+ repos:
6
+ - hooks:
7
+ - id: check-yaml
8
+ - id: end-of-file-fixer
9
+ - id: trailing-whitespace
10
+ repo: https://github.com/pre-commit/pre-commit-hooks
11
+ rev: v6.0.0
12
+ # - hooks:
13
+ # - id: python-check-blanket-noqa
14
+ # - id: python-no-eval
15
+ # repo: https://github.com/pre-commit/pygrep-hooks
16
+ # rev: v1.10.0
17
+ - hooks:
18
+ - id: no-fixme-todo
19
+ name: No FIXME or TODO markers
20
+ entry: '(FIXME:|TODO:)'
21
+ language: pygrep
22
+ types: [python]
23
+ repo: local
24
+ - hooks:
25
+ - id: ruff
26
+ args: [--fix]
27
+ - id: ruff-format
28
+ exclude: ^src/experimaestro/webui/data
29
+ repo: https://github.com/astral-sh/ruff-pre-commit
30
+ rev: v0.14.10
31
+ - hooks:
32
+ - id: conventional-pre-commit
33
+ stages:
34
+ - commit-msg
35
+ repo: https://github.com/compilerla/conventional-pre-commit
36
+ rev: v4.3.0
@@ -0,0 +1,18 @@
1
+ # .readthedocs.yml
2
+ # Read the Docs configuration file
3
+ # See https://docs.readthedocs.io/en/stable/config-file/v2.html for details
4
+
5
+ version: 2
6
+
7
+ build:
8
+ os: ubuntu-22.04
9
+ tools:
10
+ python: "3.12"
11
+ commands:
12
+ - asdf plugin add uv
13
+ - asdf install uv latest
14
+ - asdf global uv latest
15
+ # Install only docs deps (experimaestro + sphinx), not the full project.
16
+ # conf.py adds src/ to sys.path and mocks heavy deps (torch, lightning, etc.)
17
+ - uv sync --only-group docs --no-install-project
18
+ - uv run python -m sphinx -b html docs/source $READTHEDOCS_OUTPUT/html
@@ -0,0 +1,65 @@
1
+ Metadata-Version: 2.4
2
+ Name: xpm-torch
3
+ Version: 0.1.0
4
+ Summary: Experimaestro module for Pytorch-based experiments
5
+ License: GPL-3
6
+ Keywords: PyTorch,experimaestro,experiments
7
+ Requires-Python: >=3.10
8
+ Requires-Dist: experimaestro>=2.3
9
+ Requires-Dist: huggingface-hub>0.17
10
+ Requires-Dist: lightning>=2.4
11
+ Requires-Dist: safetensors>=0.4
12
+ Requires-Dist: setuptools<82.0
13
+ Requires-Dist: tensorboard>=2.19.0
14
+ Requires-Dist: torchdata>=0.10
15
+ Description-Content-Type: text/markdown
16
+
17
+ # xpm-torch
18
+
19
+ PyTorch training framework built on [experimaestro](https://experimaestro-python.readthedocs.io/) and [Lightning Fabric](https://lightning.ai/docs/fabric/).
20
+
21
+ ## Features
22
+
23
+ - **Module system**: `Module` base class combining experimaestro `Config` with `torch.nn.Module`, with safetensors serialization
24
+ - **Training**: `Learner` task with checkpointing, validation listeners, and TensorBoard logging
25
+ - **HuggingFace Hub**: Upload/download models via `ExperimaestroHFHub` (from experimaestro)
26
+ - **Distributed training**: Lightning Fabric integration for multi-GPU/node training
27
+
28
+ ## Installation
29
+
30
+ ```bash
31
+ pip install xpm-torch
32
+ ```
33
+
34
+ ## Quick Start
35
+
36
+ ```python
37
+ from xpm_torch.module import Module
38
+ from experimaestro import Param
39
+ import torch
40
+ import torch.nn as nn
41
+
42
+ class MyModel(Module):
43
+ input_dim: Param[int]
44
+ hidden_dim: Param[int]
45
+
46
+ def __initialize__(self):
47
+ self.fc1 = nn.Linear(self.input_dim, self.hidden_dim)
48
+
49
+ def forward(self, x):
50
+ return self.fc1(x)
51
+
52
+ # Create config, then instance
53
+ cfg = MyModel.C(input_dim=50, hidden_dim=100)
54
+ model = cfg.instance()
55
+ model.initialize()
56
+
57
+ # Save/load with safetensors
58
+ from pathlib import Path
59
+ model.save_model(Path("checkpoint/model"))
60
+ model.load_model(Path("checkpoint/model"))
61
+ ```
62
+
63
+ ## License
64
+
65
+ GPL-3.0
@@ -0,0 +1,49 @@
1
+ # xpm-torch
2
+
3
+ PyTorch training framework built on [experimaestro](https://experimaestro-python.readthedocs.io/) and [Lightning Fabric](https://lightning.ai/docs/fabric/).
4
+
5
+ ## Features
6
+
7
+ - **Module system**: `Module` base class combining experimaestro `Config` with `torch.nn.Module`, with safetensors serialization
8
+ - **Training**: `Learner` task with checkpointing, validation listeners, and TensorBoard logging
9
+ - **HuggingFace Hub**: Upload/download models via `ExperimaestroHFHub` (from experimaestro)
10
+ - **Distributed training**: Lightning Fabric integration for multi-GPU/node training
11
+
12
+ ## Installation
13
+
14
+ ```bash
15
+ pip install xpm-torch
16
+ ```
17
+
18
+ ## Quick Start
19
+
20
+ ```python
21
+ from xpm_torch.module import Module
22
+ from experimaestro import Param
23
+ import torch
24
+ import torch.nn as nn
25
+
26
+ class MyModel(Module):
27
+ input_dim: Param[int]
28
+ hidden_dim: Param[int]
29
+
30
+ def __initialize__(self):
31
+ self.fc1 = nn.Linear(self.input_dim, self.hidden_dim)
32
+
33
+ def forward(self, x):
34
+ return self.fc1(x)
35
+
36
+ # Create config, then instance
37
+ cfg = MyModel.C(input_dim=50, hidden_dim=100)
38
+ model = cfg.instance()
39
+ model.initialize()
40
+
41
+ # Save/load with safetensors
42
+ from pathlib import Path
43
+ model.save_model(Path("checkpoint/model"))
44
+ model.load_model(Path("checkpoint/model"))
45
+ ```
46
+
47
+ ## License
48
+
49
+ GPL-3.0
@@ -0,0 +1,12 @@
1
+ SPHINXOPTS ?=
2
+ SPHINXBUILD ?= sphinx-build
3
+ SOURCEDIR = source
4
+ BUILDDIR = build
5
+
6
+ help:
7
+ @$(SPHINXBUILD) -M help "$(SOURCEDIR)" "$(BUILDDIR)" $(SPHINXOPTS) $(O)
8
+
9
+ .PHONY: help Makefile
10
+
11
+ %: Makefile
12
+ @$(SPHINXBUILD) -M $@ "$(SOURCEDIR)" "$(BUILDDIR)" $(SPHINXOPTS) $(O)
@@ -0,0 +1,50 @@
1
+ import sys
2
+ from pathlib import Path
3
+
4
+ # Add source directory so Sphinx can import xpm_torch without installing
5
+ # the full project (which would pull in torch, lightning, etc.)
6
+ sys.path.insert(0, str(Path(__file__).resolve().parents[2] / "src"))
7
+
8
+ project = "xpm-torch"
9
+ copyright = "2024, Benjamin Piwowarski"
10
+ author = "Benjamin Piwowarski"
11
+
12
+ extensions = [
13
+ # Experimaestro extension for documenting Config/Param classes
14
+ "experimaestro.sphinx",
15
+ "sphinx_rtd_theme",
16
+ "sphinx.ext.autodoc",
17
+ "sphinx.ext.autosummary",
18
+ "sphinx.ext.napoleon",
19
+ "sphinx.ext.viewcode",
20
+ # Link to other documentations
21
+ "sphinx.ext.intersphinx",
22
+ # Auto-link identifiers in code blocks to API docs
23
+ "sphinx_codeautolink",
24
+ ]
25
+
26
+ intersphinx_mapping = {
27
+ "experimaestro": (
28
+ "https://experimaestro-python.readthedocs.io/en/latest/",
29
+ None,
30
+ ),
31
+ }
32
+
33
+ # Mock heavy dependencies that are not needed to build the docs.
34
+ # experimaestro is NOT mocked — it's installed in the docs group
35
+ # and needed for experimaestro.sphinx and Config/Param introspection.
36
+ autodoc_mock_imports = [
37
+ "huggingface_hub",
38
+ "lightning",
39
+ "numpy",
40
+ "safetensors",
41
+ "tensorboard",
42
+ "torch",
43
+ "torchdata",
44
+ ]
45
+
46
+ templates_path = ["_templates"]
47
+ exclude_patterns = []
48
+ html_theme = "sphinx_rtd_theme"
49
+ html_static_path = ["_static"]
50
+ source_suffix = ".rst"
@@ -0,0 +1,253 @@
1
+ HuggingFace Hub Integration
2
+ ===========================
3
+
4
+ xpm-torch models can be pushed to and loaded from the
5
+ `HuggingFace Hub <https://huggingface.co/>`_ via
6
+ :class:`~xpm_torch.huggingface.TorchHFHub` (which extends experimaestro's
7
+ ``ExperimaestroHFHub``). The serialization preserves the full experimaestro
8
+ configuration graph, so a downloaded model can be used directly in further
9
+ experiments.
10
+
11
+ Exporting models via actions
12
+ ----------------------------
13
+
14
+ The recommended way to export trained models is through experimaestro's
15
+ **action system**. When a :class:`~xpm_torch.learner.Learner` is submitted,
16
+ it automatically registers :class:`~xpm_torch.actions.ExportAction` instances
17
+ for the last checkpoint and for each listener's best checkpoint. After the
18
+ experiment completes, these actions can be executed interactively via the
19
+ experimaestro CLI (``experimaestro experiments actions``).
20
+
21
+ :class:`~xpm_torch.actions.ExportAction` prompts the user to choose between
22
+ uploading to HuggingFace Hub or saving to a local directory, then delegates
23
+ to :class:`~xpm_torch.huggingface.TorchHFHub`.
24
+
25
+ How actions are registered
26
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~
27
+
28
+ Actions are registered during task submission via the ``add_action`` callback
29
+ provided by experimaestro:
30
+
31
+ .. code-block:: python
32
+
33
+ class Learner(Task):
34
+ def __submit__(self, dep, add_action):
35
+ loader = dep(self.model.loader_config(...))
36
+ # Register export action for the last checkpoint
37
+ add_action(self.model.export_action(loader, default_name="last"))
38
+ ...
39
+
40
+ :meth:`Module.export_action(loader, **kwargs) <xpm_torch.module.Module.export_action>`
41
+ returns an :class:`~xpm_torch.actions.ExportAction` config by default.
42
+ Subclasses override this method to return library-specific actions (e.g.
43
+ ``XPMIRExportAction`` adds xpmir README sections and metadata).
44
+
45
+ Customizing the export action
46
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
47
+
48
+ To customize what happens during export, subclass
49
+ :class:`~xpm_torch.actions.ExportAction` and override
50
+ :meth:`~xpm_torch.actions.ExportAction.get_hub` to return a
51
+ library-specific hub wrapper:
52
+
53
+ .. code-block:: python
54
+
55
+ from xpm_torch.actions import ExportAction
56
+
57
+ class MyExportAction(ExportAction):
58
+ def get_hub(self):
59
+ return MyCustomHFHub(self.loader)
60
+
61
+ Then override :meth:`~xpm_torch.module.Module.export_action` on your model
62
+ to return this action:
63
+
64
+ .. code-block:: python
65
+
66
+ class MyModel(Module):
67
+ def export_action(self, loader, **kwargs):
68
+ return MyExportAction.C(loader=loader, **kwargs)
69
+
70
+ Direct API usage
71
+ ~~~~~~~~~~~~~~~~
72
+
73
+ You can also use :class:`~xpm_torch.huggingface.TorchHFHub` directly:
74
+
75
+ .. code-block:: python
76
+
77
+ from xpm_torch.huggingface import TorchHFHub
78
+
79
+ # Push a ModuleLoader (from loader_config or validation output)
80
+ TorchHFHub(loader).push_to_hub("your-org/model-name")
81
+
82
+ # Or save locally first
83
+ TorchHFHub(loader).save_pretrained("/path/to/save")
84
+
85
+ :class:`~xpm_torch.huggingface.TorchHFHub` calls
86
+ :meth:`~xpm_torch.module.ModuleLoader.write_hub_extras` and
87
+ :meth:`~xpm_torch.module.ModuleLoader.hub_readme_sections` on the loader,
88
+ so format-specific files (e.g. sentence-transformers configs) and README
89
+ sections are generated automatically.
90
+
91
+ What gets uploaded
92
+ ~~~~~~~~~~~~~~~~~~
93
+
94
+ The serialized directory contains:
95
+
96
+ - ``experimaestro.json`` — the config definition (for reloading with xpmir)
97
+ - Model weight directories — named after the loader's ``DataPath`` fields
98
+ (or customized via ``__xpm_serialize__``)
99
+ - Format-specific configs written by ``write_hub_extras`` (e.g.
100
+ ``modules.json``, ``router_config.json`` for sentence-transformers)
101
+ - ``README.md`` — assembled from base + loader sections
102
+
103
+ Loading a model from the Hub
104
+ -----------------------------
105
+
106
+ Low-level (experimaestro):
107
+
108
+ .. code-block:: python
109
+
110
+ from experimaestro.huggingface import ExperimaestroHFHub
111
+
112
+ # Returns a deserialized config (e.g. ModuleLoader)
113
+ data = ExperimaestroHFHub.from_pretrained("your-org/model-name")
114
+
115
+ For xpmir models, use ``AutoModel`` which returns a
116
+ :class:`~xpm_torch.module.ModuleLoader` directly:
117
+
118
+ .. code-block:: python
119
+
120
+ from xpmir.models import AutoModel
121
+
122
+ # Returns a ModuleLoader — use as an init task in experiments
123
+ loader = AutoModel.load_from_hf_hub("your-org/model-name")
124
+ # loader.model is the model config
125
+
126
+ # Or load as a ready-to-use instance for direct inference
127
+ model = AutoModel.load_from_hf_hub("your-org/model-name", as_instance=True)
128
+
129
+ Customizing the HF checkpoint format
130
+ -------------------------------------
131
+
132
+ There are three extension points for customizing what gets written during
133
+ Hub export:
134
+
135
+ - :meth:`Module.loader_config(path) <xpm_torch.module.Module.loader_config>` —
136
+ on the model, controls which ``ModuleLoader`` subclass is returned
137
+ - :meth:`ModuleLoader.write_hub_extras(save_directory) <xpm_torch.module.ModuleLoader.write_hub_extras>` —
138
+ on the loader, writes additional files (e.g. ST configs)
139
+ - :meth:`ModuleLoader.hub_readme_sections() <xpm_torch.module.ModuleLoader.hub_readme_sections>` —
140
+ on the loader, provides named README sections with positioning
141
+
142
+ The hooks are on :class:`~xpm_torch.module.ModuleLoader` (not on
143
+ :class:`~xpm_torch.module.Module`) because the loader is the object that
144
+ gets serialized for Hub export and holds the ``DataPath`` references to
145
+ model weights. ``Module`` configs are data-less.
146
+
147
+ :meth:`~xpm_torch.module.Module.loader_config`
148
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
149
+
150
+ When a model is serialized for the Hub, experimaestro serializes the
151
+ :class:`~xpm_torch.module.ModuleLoader` returned by
152
+ :meth:`~xpm_torch.module.Module.loader_config`. Subclasses override this
153
+ method to return a custom loader with different ``DataPath`` fields:
154
+
155
+ .. code-block:: python
156
+
157
+ from xpm_torch.module import Module, SimpleModuleLoader
158
+
159
+ class MyModel(Module):
160
+ def loader_config(self, path):
161
+ # Default: single path DataPath
162
+ return SimpleModuleLoader.C(value=self, path=path)
163
+
164
+ Loaders can also override ``__xpm_serialize__`` to control the directory
165
+ names used during serialization (e.g. mapping field names to
166
+ sentence-transformers conventions).
167
+
168
+ :meth:`~xpm_torch.module.Module.save_model` / :meth:`~xpm_torch.module.Module.load_model`
169
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
170
+
171
+ These methods on :class:`~xpm_torch.module.Module` control how model
172
+ weights are written to and read from a directory. Override them to change
173
+ the on-disk format:
174
+
175
+ .. code-block:: python
176
+
177
+ class DualEncoderModel(Module):
178
+ encoder: Param[Module]
179
+ query_encoder: Param[Optional[Module]]
180
+
181
+ def save_model(self, path):
182
+ path.mkdir(parents=True, exist_ok=True)
183
+ self.encoder.save_model(path / "encoder")
184
+ if self.query_encoder is not None:
185
+ self.query_encoder.save_model(path / "query_encoder")
186
+
187
+ def load_model(self, path):
188
+ self.encoder.load_model(path / "encoder")
189
+ if (path / "query_encoder").exists():
190
+ self.query_encoder.load_model(path / "query_encoder")
191
+
192
+ :meth:`~xpm_torch.module.ModuleLoader.write_hub_extras` and :meth:`~xpm_torch.module.ModuleLoader.hub_readme_sections`
193
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
194
+
195
+ To write additional files alongside the model weights during Hub export
196
+ (e.g. sentence-transformers compatibility configs), create a custom
197
+ :class:`~xpm_torch.module.ModuleLoader` subclass and override
198
+ :meth:`~xpm_torch.module.ModuleLoader.write_hub_extras`.
199
+
200
+ To add sections to the README, override
201
+ :meth:`~xpm_torch.module.ModuleLoader.hub_readme_sections` and return a
202
+ list of :class:`~xpm_torch.module.ReadmeSection`. Each section has a
203
+ ``key``, ``content``, and optional ``before``/``after`` constraints for
204
+ positioning relative to the base sections (``frontmatter``,
205
+ ``description``, ``usage``, ``results``):
206
+
207
+ .. code-block:: python
208
+
209
+ from xpm_torch.module import ModuleLoader, ReadmeSection
210
+
211
+ class MyCustomLoader(ModuleLoader):
212
+ def write_hub_extras(self, save_directory):
213
+ (save_directory / "my_config.json").write_text('{"format": "custom"}')
214
+
215
+ def hub_readme_sections(self):
216
+ return [
217
+ ReadmeSection(
218
+ key="quick_loading",
219
+ content="## Quick loading\n\n```python\nmodel = MyLib.load(...)\n```",
220
+ before="usage", # appears before the XPMIR usage section
221
+ ),
222
+ ]
223
+
224
+ These hooks are only called during Hub export (by
225
+ :class:`~xpm_torch.huggingface.TorchHFHub`), not during checkpoint saving.
226
+ Then override :meth:`~xpm_torch.module.Module.loader_config` on your model
227
+ to return this loader:
228
+
229
+ .. code-block:: python
230
+
231
+ class MyModel(Module):
232
+ def loader_config(self, path):
233
+ return MyCustomLoader.C(value=self, path=path)
234
+
235
+ Class hierarchy
236
+ ~~~~~~~~~~~~~~~
237
+
238
+ - :class:`~experimaestro.huggingface.ExperimaestroHFHub` — base serialization
239
+ (experimaestro)
240
+ - :class:`~xpm_torch.huggingface.TorchHFHub` — calls ``write_hub_extras``
241
+ and ``hub_readme_sections`` on the loader (xpm-torch)
242
+ - ``XPMIRHFHub`` — adds xpmir README sections (frontmatter, usage, results)
243
+ and TensorBoard logs (xpmir)
244
+
245
+ Utility functions
246
+ -----------------
247
+
248
+ Helper functions for working with HuggingFace Hub (cache checks,
249
+ downloads, config retrieval):
250
+
251
+ .. automodule:: xpm_torch.huggingface
252
+ :members:
253
+ :exclude-members: TorchHFHub
@@ -0,0 +1,19 @@
1
+ xpm-torch documentation
2
+ ========================
3
+
4
+ .. toctree::
5
+ :maxdepth: 2
6
+ :caption: Contents:
7
+
8
+ overview
9
+ module
10
+ training
11
+ optimization
12
+ huggingface
13
+
14
+ Indices and tables
15
+ ==================
16
+
17
+ * :ref:`genindex`
18
+ * :ref:`modindex`
19
+ * :ref:`search`