diffract-core 0.2.1__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.
- diffract/__init__.py +52 -0
- diffract/configs/fast_speed_without_disk.ini +48 -0
- diffract/configs/hybrid.ini +74 -0
- diffract/configs/sqlite.ini +62 -0
- diffract/containers.py +405 -0
- diffract/core/__init__.py +23 -0
- diffract/core/cache/__init__.py +24 -0
- diffract/core/cache/containers.py +93 -0
- diffract/core/cache/interface.py +117 -0
- diffract/core/cache/redis_manager.py +464 -0
- diffract/core/cache/simple_manager.py +478 -0
- diffract/core/compute/__init__.py +46 -0
- diffract/core/compute/config.py +48 -0
- diffract/core/compute/containers.py +81 -0
- diffract/core/compute/decorator.py +125 -0
- diffract/core/compute/exceptions.py +31 -0
- diffract/core/compute/execution/__init__.py +14 -0
- diffract/core/compute/execution/_types.py +70 -0
- diffract/core/compute/execution/aggregation.py +74 -0
- diffract/core/compute/execution/aggregation_runner.py +362 -0
- diffract/core/compute/execution/enums.py +38 -0
- diffract/core/compute/execution/executor.py +125 -0
- diffract/core/compute/execution/parameter_runner.py +125 -0
- diffract/core/compute/execution/restrictions.py +61 -0
- diffract/core/compute/execution/strategy.py +118 -0
- diffract/core/compute/execution/utils.py +112 -0
- diffract/core/compute/extensions/__init__.py +0 -0
- diffract/core/compute/extensions/power_law.py +1051 -0
- diffract/core/compute/extensions/rmt.py +150 -0
- diffract/core/compute/extensions/utils.py +36 -0
- diffract/core/compute/field_signature.py +183 -0
- diffract/core/compute/kernels/__init__.py +48 -0
- diffract/core/compute/kernels/alignment.py +106 -0
- diffract/core/compute/kernels/heavy_tailed.py +394 -0
- diffract/core/compute/kernels/marchenko_pastur.py +99 -0
- diffract/core/compute/kernels/mat_decomposition.py +101 -0
- diffract/core/compute/kernels/mat_properties.py +53 -0
- diffract/core/compute/kernels/model_quality.py +27 -0
- diffract/core/compute/kernels/norms.py +88 -0
- diffract/core/compute/kernels/ranks.py +35 -0
- diffract/core/compute/kernels/tracy_widom.py +36 -0
- diffract/core/compute/metadata.py +67 -0
- diffract/core/compute/registry.py +485 -0
- diffract/core/constants.py +147 -0
- diffract/core/data/__init__.py +32 -0
- diffract/core/data/interface.py +304 -0
- diffract/core/data/metadata/__init__.py +15 -0
- diffract/core/data/metadata/containers.py +60 -0
- diffract/core/data/metadata/interface.py +208 -0
- diffract/core/data/metadata/sqlite_index.py +604 -0
- diffract/core/data/nn/__init__.py +43 -0
- diffract/core/data/nn/aggregates/__init__.py +35 -0
- diffract/core/data/nn/aggregates/metadata.py +96 -0
- diffract/core/data/nn/aggregates/proxy.py +57 -0
- diffract/core/data/nn/aggregates/repository.py +87 -0
- diffract/core/data/nn/aggregates/view.py +307 -0
- diffract/core/data/nn/containers.py +86 -0
- diffract/core/data/nn/extractors/__init__.py +49 -0
- diffract/core/data/nn/extractors/base.py +300 -0
- diffract/core/data/nn/extractors/factory.py +234 -0
- diffract/core/data/nn/extractors/flax.py +112 -0
- diffract/core/data/nn/extractors/handlers/__init__.py +39 -0
- diffract/core/data/nn/extractors/handlers/base.py +110 -0
- diffract/core/data/nn/extractors/handlers/flax_handlers.py +71 -0
- diffract/core/data/nn/extractors/handlers/numpy_handlers.py +63 -0
- diffract/core/data/nn/extractors/handlers/onnx_handlers.py +67 -0
- diffract/core/data/nn/extractors/handlers/tensorflow_handlers.py +82 -0
- diffract/core/data/nn/extractors/handlers/torch_handlers.py +124 -0
- diffract/core/data/nn/extractors/interface.py +56 -0
- diffract/core/data/nn/extractors/numpy.py +94 -0
- diffract/core/data/nn/extractors/onnx.py +108 -0
- diffract/core/data/nn/extractors/tensorflow.py +99 -0
- diffract/core/data/nn/extractors/torch.py +204 -0
- diffract/core/data/nn/params/__init__.py +27 -0
- diffract/core/data/nn/params/interface.py +402 -0
- diffract/core/data/nn/params/metadata.py +110 -0
- diffract/core/data/nn/params/proxy.py +93 -0
- diffract/core/data/nn/params/repository.py +45 -0
- diffract/core/data/nn/params/schema.py +82 -0
- diffract/core/data/nn/params/view.py +393 -0
- diffract/core/data/proxy.py +246 -0
- diffract/core/data/repository.py +227 -0
- diffract/core/data/utils.py +33 -0
- diffract/core/data/view.py +389 -0
- diffract/core/export/__init__.py +27 -0
- diffract/core/export/containers.py +47 -0
- diffract/core/export/exporters.py +191 -0
- diffract/core/export/formatters/__init__.py +23 -0
- diffract/core/export/formatters/base.py +68 -0
- diffract/core/export/formatters/dict_formatter.py +38 -0
- diffract/core/export/formatters/json_formatter.py +58 -0
- diffract/core/export/formatters/list_formatter.py +41 -0
- diffract/core/export/formatters/pandas_formatter.py +86 -0
- diffract/core/export/formatters/polars_formatter.py +86 -0
- diffract/core/export/formatters/registry.py +84 -0
- diffract/core/export/interface.py +105 -0
- diffract/core/parallel/__init__.py +21 -0
- diffract/core/parallel/containers.py +57 -0
- diffract/core/parallel/execution.py +91 -0
- diffract/core/parallel/runtime.py +91 -0
- diffract/core/storage/__init__.py +35 -0
- diffract/core/storage/base_manager.py +330 -0
- diffract/core/storage/containers.py +122 -0
- diffract/core/storage/hdf5_manager.py +856 -0
- diffract/core/storage/hybrid_manager.py +218 -0
- diffract/core/storage/interface.py +222 -0
- diffract/core/storage/metadata.py +89 -0
- diffract/core/storage/ram_manager.py +159 -0
- diffract/core/storage/sqlite_manager.py +1062 -0
- diffract/core/storage/zarr_manager.py +992 -0
- diffract/core/utils/__init__.py +45 -0
- diffract/core/utils/build.py +46 -0
- diffract/core/utils/exceptions.py +11 -0
- diffract/core/utils/hashing.py +90 -0
- diffract/core/utils/imports.py +292 -0
- diffract/core/utils/math.py +15 -0
- diffract/py.typed +0 -0
- diffract/session/__init__.py +24 -0
- diffract/session/errors.py +17 -0
- diffract/session/field_cache.py +216 -0
- diffract/session/namespaces/__init__.py +15 -0
- diffract/session/namespaces/compute/__init__.py +219 -0
- diffract/session/namespaces/models/__init__.py +282 -0
- diffract/session/namespaces/models/parameters/__init__.py +133 -0
- diffract/session/namespaces/models/parameters/meta_patcher.py +167 -0
- diffract/session/namespaces/results/__init__.py +378 -0
- diffract/session/namespaces/results/eraser.py +129 -0
- diffract/session/namespaces/results/injester.py +249 -0
- diffract/session/namespaces/utils/__init__.py +141 -0
- diffract/session/namespaces/utils/merger.py +295 -0
- diffract/session/namespaces/viz/__init__.py +91 -0
- diffract/session/namespaces/viz/_utils.py +14 -0
- diffract/session/namespaces/viz/box.py +207 -0
- diffract/session/namespaces/viz/grid.py +160 -0
- diffract/session/namespaces/viz/heatmap.py +164 -0
- diffract/session/namespaces/viz/scatter.py +202 -0
- diffract/session/namespaces/viz/sparkline.py +270 -0
- diffract/session/namespaces/viz/violin.py +212 -0
- diffract/session/session.py +260 -0
- diffract/session/utils.py +81 -0
- diffract/viz/__init__.py +42 -0
- diffract/viz/data/__init__.py +34 -0
- diffract/viz/data/detection.py +57 -0
- diffract/viz/data/extraction.py +117 -0
- diffract/viz/data/filtering.py +57 -0
- diffract/viz/data/ordering.py +129 -0
- diffract/viz/data/provider.py +99 -0
- diffract/viz/data/types.py +98 -0
- diffract/viz/plots/__init__.py +37 -0
- diffract/viz/plots/base/__init__.py +20 -0
- diffract/viz/plots/base/axis.py +219 -0
- diffract/viz/plots/base/coloraxis.py +133 -0
- diffract/viz/plots/base/configurator.py +18 -0
- diffract/viz/plots/base/jitter.py +368 -0
- diffract/viz/plots/base/line.py +197 -0
- diffract/viz/plots/base/marker.py +278 -0
- diffract/viz/plots/base/overlay.py +14 -0
- diffract/viz/plots/base/plot.py +110 -0
- diffract/viz/plots/base/update.py +50 -0
- diffract/viz/plots/boxplot.py +283 -0
- diffract/viz/plots/cluster.py +374 -0
- diffract/viz/plots/heatmap.py +168 -0
- diffract/viz/plots/scatter.py +233 -0
- diffract/viz/plots/sparkline.py +405 -0
- diffract/viz/plots/subplots/__init__.py +32 -0
- diffract/viz/plots/subplots/coloraxis.py +339 -0
- diffract/viz/plots/subplots/factory.py +713 -0
- diffract/viz/plots/subplots/grid.py +214 -0
- diffract/viz/plots/subplots/layout.py +370 -0
- diffract/viz/plots/subplots/spec.py +39 -0
- diffract/viz/plots/violin.py +298 -0
- diffract/viz/renderer.py +513 -0
- diffract/viz/styling/__init__.py +78 -0
- diffract/viz/styling/palettes/__init__.py +20 -0
- diffract/viz/styling/palettes/bundle.py +16 -0
- diffract/viz/styling/palettes/color.py +83 -0
- diffract/viz/styling/palettes/dashes.py +27 -0
- diffract/viz/styling/palettes/symbols.py +42 -0
- diffract/viz/styling/resolvers/__init__.py +11 -0
- diffract/viz/styling/resolvers/categorical.py +68 -0
- diffract/viz/styling/resolvers/color.py +77 -0
- diffract/viz/styling/resolvers/numeric.py +108 -0
- diffract/viz/styling/sources.py +27 -0
- diffract/viz/styling/theme/__init__.py +29 -0
- diffract/viz/styling/theme/applier.py +114 -0
- diffract/viz/styling/theme/components.py +66 -0
- diffract/viz/styling/theme/presets.py +58 -0
- diffract/viz/styling/theme/theme.py +36 -0
- diffract_core-0.2.1.dist-info/METADATA +530 -0
- diffract_core-0.2.1.dist-info/RECORD +193 -0
- diffract_core-0.2.1.dist-info/WHEEL +4 -0
- diffract_core-0.2.1.dist-info/licenses/LICENSE +201 -0
- diffract_core-0.2.1.dist-info/licenses/NOTICE +2 -0
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
from __future__ import annotations
|
|
2
|
+
|
|
3
|
+
from diffract.viz.styling.palettes import PaletteBundle
|
|
4
|
+
from diffract.viz.styling.palettes.color import DarkColorPalette
|
|
5
|
+
|
|
6
|
+
from .components import (
|
|
7
|
+
AxesStyle,
|
|
8
|
+
BackgroundStyle,
|
|
9
|
+
LayoutStyle,
|
|
10
|
+
LegendStyle,
|
|
11
|
+
TypographyStyle,
|
|
12
|
+
)
|
|
13
|
+
from .theme import Theme
|
|
14
|
+
|
|
15
|
+
DEFAULT_THEME = Theme()
|
|
16
|
+
|
|
17
|
+
|
|
18
|
+
DARK_THEME = Theme(
|
|
19
|
+
background=BackgroundStyle(
|
|
20
|
+
plot_bgcolor="#1e1e1e",
|
|
21
|
+
paper_bgcolor="#2d2d2d",
|
|
22
|
+
),
|
|
23
|
+
axes=AxesStyle(
|
|
24
|
+
grid_color="#444444",
|
|
25
|
+
line_color="#666666",
|
|
26
|
+
mirror=False,
|
|
27
|
+
),
|
|
28
|
+
legend=LegendStyle(
|
|
29
|
+
bgcolor="rgba(45,45,45,0.9)",
|
|
30
|
+
border_color="#666666",
|
|
31
|
+
),
|
|
32
|
+
palettes=PaletteBundle(
|
|
33
|
+
color=DarkColorPalette(),
|
|
34
|
+
),
|
|
35
|
+
)
|
|
36
|
+
|
|
37
|
+
|
|
38
|
+
MINIMAL_THEME = Theme(
|
|
39
|
+
layout=LayoutStyle(
|
|
40
|
+
margin={"l": 50, "r": 20, "t": 40, "b": 50},
|
|
41
|
+
),
|
|
42
|
+
typography=TypographyStyle(
|
|
43
|
+
font_family="Arial",
|
|
44
|
+
title_font_size=14,
|
|
45
|
+
label_font_size=12,
|
|
46
|
+
tick_font_size=10,
|
|
47
|
+
),
|
|
48
|
+
axes=AxesStyle(
|
|
49
|
+
show_grid=False,
|
|
50
|
+
show_line=False,
|
|
51
|
+
mirror=False,
|
|
52
|
+
),
|
|
53
|
+
legend=LegendStyle(
|
|
54
|
+
bgcolor="rgba(255,255,255,0)",
|
|
55
|
+
border_color="rgba(0,0,0,0)",
|
|
56
|
+
border_width=0,
|
|
57
|
+
),
|
|
58
|
+
)
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
from __future__ import annotations
|
|
2
|
+
|
|
3
|
+
from dataclasses import dataclass, field
|
|
4
|
+
|
|
5
|
+
from diffract.viz.styling.palettes import PaletteBundle
|
|
6
|
+
|
|
7
|
+
from .components import (
|
|
8
|
+
AxesStyle,
|
|
9
|
+
BackgroundStyle,
|
|
10
|
+
ColorbarStyle,
|
|
11
|
+
LayoutStyle,
|
|
12
|
+
LegendStyle,
|
|
13
|
+
TypographyStyle,
|
|
14
|
+
)
|
|
15
|
+
|
|
16
|
+
|
|
17
|
+
@dataclass
|
|
18
|
+
class Theme:
|
|
19
|
+
"""Complete theme configuration with composition.
|
|
20
|
+
|
|
21
|
+
Theme provides figure-level styling and palette configuration.
|
|
22
|
+
Explicit user settings on Plot/Configurator fields take precedence.
|
|
23
|
+
|
|
24
|
+
Example:
|
|
25
|
+
>>> from diffract.viz.styling.theme import Theme, DARK_THEME
|
|
26
|
+
>>> plot = BoxPlot(x=FieldRef("model"), y=FieldRef("accuracy"))
|
|
27
|
+
>>> fig = plot.render(session, theme=DARK_THEME)
|
|
28
|
+
"""
|
|
29
|
+
|
|
30
|
+
layout: LayoutStyle = field(default_factory=LayoutStyle)
|
|
31
|
+
typography: TypographyStyle = field(default_factory=TypographyStyle)
|
|
32
|
+
background: BackgroundStyle = field(default_factory=BackgroundStyle)
|
|
33
|
+
axes: AxesStyle = field(default_factory=AxesStyle)
|
|
34
|
+
legend: LegendStyle = field(default_factory=LegendStyle)
|
|
35
|
+
colorbar: ColorbarStyle = field(default_factory=ColorbarStyle)
|
|
36
|
+
palettes: PaletteBundle = field(default_factory=PaletteBundle)
|
|
@@ -0,0 +1,530 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: diffract-core
|
|
3
|
+
Version: 0.2.1
|
|
4
|
+
Summary: Spectral analysis of neural network weights and their evolution over training
|
|
5
|
+
Project-URL: Homepage, https://github.com/Risk-AI-Research/diffract
|
|
6
|
+
Project-URL: Documentation, https://risk-ai-research.github.io/diffract/
|
|
7
|
+
Project-URL: Repository, https://github.com/Risk-AI-Research/diffract
|
|
8
|
+
Project-URL: Issues, https://github.com/Risk-AI-Research/diffract/issues
|
|
9
|
+
Project-URL: Changelog, https://github.com/Risk-AI-Research/diffract/blob/main/CHANGELOG.md
|
|
10
|
+
Project-URL: Paper, https://openreview.net/forum?id=XBUHoiAGDE
|
|
11
|
+
Author: Risk AI Research
|
|
12
|
+
Maintainer-email: Nikita Borodin <borodinik.s@gmail.com>
|
|
13
|
+
License-Expression: Apache-2.0
|
|
14
|
+
License-File: LICENSE
|
|
15
|
+
License-File: NOTICE
|
|
16
|
+
Keywords: deep-learning,llm,neural-networks,random-matrix-theory,spectral-analysis
|
|
17
|
+
Classifier: Development Status :: 3 - Alpha
|
|
18
|
+
Classifier: Intended Audience :: Science/Research
|
|
19
|
+
Classifier: Programming Language :: Python :: 3.12
|
|
20
|
+
Classifier: Topic :: Scientific/Engineering :: Artificial Intelligence
|
|
21
|
+
Classifier: Topic :: Software Development :: Libraries :: Python Modules
|
|
22
|
+
Classifier: Typing :: Typed
|
|
23
|
+
Requires-Python: <3.13,>=3.12
|
|
24
|
+
Requires-Dist: dependency-injector>=4.44.0
|
|
25
|
+
Requires-Dist: h5py>=3.9.0
|
|
26
|
+
Requires-Dist: numpy<3,>=1.26
|
|
27
|
+
Requires-Dist: ordered-set>=4.1.0
|
|
28
|
+
Requires-Dist: powerlaw<2,>=1.5.0
|
|
29
|
+
Requires-Dist: rootutils<2,>=1.0.7
|
|
30
|
+
Requires-Dist: scipy>=1.12.0
|
|
31
|
+
Requires-Dist: tqdm>=4.65.0
|
|
32
|
+
Requires-Dist: typing-extensions>=4.8.0
|
|
33
|
+
Provides-Extra: all
|
|
34
|
+
Requires-Dist: hydra-core>=1.3.0; extra == 'all'
|
|
35
|
+
Requires-Dist: kaleido>=0.2.1; extra == 'all'
|
|
36
|
+
Requires-Dist: omegaconf>=2.3.0; extra == 'all'
|
|
37
|
+
Requires-Dist: pandas>=2.1.0; extra == 'all'
|
|
38
|
+
Requires-Dist: plotly>=6.0.0; extra == 'all'
|
|
39
|
+
Requires-Dist: polars>=0.20.0; extra == 'all'
|
|
40
|
+
Requires-Dist: pyyaml>=6.0.1; extra == 'all'
|
|
41
|
+
Requires-Dist: taichi>=1.7.3; extra == 'all'
|
|
42
|
+
Requires-Dist: torch>=2.7.0; extra == 'all'
|
|
43
|
+
Provides-Extra: common
|
|
44
|
+
Requires-Dist: hydra-core>=1.3.0; extra == 'common'
|
|
45
|
+
Requires-Dist: kaleido>=0.2.1; extra == 'common'
|
|
46
|
+
Requires-Dist: omegaconf>=2.3.0; extra == 'common'
|
|
47
|
+
Requires-Dist: pandas>=2.1.0; extra == 'common'
|
|
48
|
+
Requires-Dist: plotly>=6.0.0; extra == 'common'
|
|
49
|
+
Requires-Dist: polars>=0.20.0; extra == 'common'
|
|
50
|
+
Requires-Dist: pyyaml>=6.0.1; extra == 'common'
|
|
51
|
+
Provides-Extra: dev
|
|
52
|
+
Requires-Dist: bandit[toml]>=1.7.5; extra == 'dev'
|
|
53
|
+
Requires-Dist: fsspec>=2024.2.0; extra == 'dev'
|
|
54
|
+
Requires-Dist: hydra-core>=1.3.0; extra == 'dev'
|
|
55
|
+
Requires-Dist: interrogate>=1.7.0; extra == 'dev'
|
|
56
|
+
Requires-Dist: kaleido>=0.2.1; extra == 'dev'
|
|
57
|
+
Requires-Dist: mypy>=1.10.1; extra == 'dev'
|
|
58
|
+
Requires-Dist: omegaconf>=2.3.0; extra == 'dev'
|
|
59
|
+
Requires-Dist: pandas>=2.1.0; extra == 'dev'
|
|
60
|
+
Requires-Dist: plotly>=6.0.0; extra == 'dev'
|
|
61
|
+
Requires-Dist: polars>=0.20.0; extra == 'dev'
|
|
62
|
+
Requires-Dist: pre-commit>=3.6.0; extra == 'dev'
|
|
63
|
+
Requires-Dist: pytest-cov>=4.0.0; extra == 'dev'
|
|
64
|
+
Requires-Dist: pytest-mock>=3.12.0; extra == 'dev'
|
|
65
|
+
Requires-Dist: pytest-timeout>=2.4.0; extra == 'dev'
|
|
66
|
+
Requires-Dist: pytest-watch>=4.2.0; extra == 'dev'
|
|
67
|
+
Requires-Dist: pytest-xdist>=3.3.0; extra == 'dev'
|
|
68
|
+
Requires-Dist: pytest>=7.4.0; extra == 'dev'
|
|
69
|
+
Requires-Dist: pyyaml>=6.0.1; extra == 'dev'
|
|
70
|
+
Requires-Dist: ruff>=0.9.0; extra == 'dev'
|
|
71
|
+
Requires-Dist: sybil>=6.0.0; extra == 'dev'
|
|
72
|
+
Requires-Dist: types-pyyaml>=6.0.0; extra == 'dev'
|
|
73
|
+
Requires-Dist: types-requests>=2.31.0; extra == 'dev'
|
|
74
|
+
Requires-Dist: zarr>=2.18.0; extra == 'dev'
|
|
75
|
+
Provides-Extra: docs
|
|
76
|
+
Requires-Dist: furo>=2024.8.0; extra == 'docs'
|
|
77
|
+
Requires-Dist: myst-parser>=2.0.0; extra == 'docs'
|
|
78
|
+
Requires-Dist: sphinx-autobuild>=2024.10.0; extra == 'docs'
|
|
79
|
+
Requires-Dist: sphinx-autodoc-typehints>=1.25.0; extra == 'docs'
|
|
80
|
+
Requires-Dist: sphinx-copybutton>=0.5.0; extra == 'docs'
|
|
81
|
+
Requires-Dist: sphinx-design>=0.6.0; extra == 'docs'
|
|
82
|
+
Requires-Dist: sphinx>=7.0.0; extra == 'docs'
|
|
83
|
+
Requires-Dist: sphinxext-opengraph>=0.9.0; extra == 'docs'
|
|
84
|
+
Provides-Extra: flax
|
|
85
|
+
Requires-Dist: flax>=0.10.0; extra == 'flax'
|
|
86
|
+
Provides-Extra: frameworks
|
|
87
|
+
Requires-Dist: flax>=0.10.0; extra == 'frameworks'
|
|
88
|
+
Requires-Dist: onnx>=1.16.0; extra == 'frameworks'
|
|
89
|
+
Requires-Dist: tensorflow>=2.16.0; extra == 'frameworks'
|
|
90
|
+
Provides-Extra: notebooks
|
|
91
|
+
Requires-Dist: einops>=0.7.0; extra == 'notebooks'
|
|
92
|
+
Requires-Dist: ipywidgets>=8.1.0; extra == 'notebooks'
|
|
93
|
+
Requires-Dist: jupyter>=1.0.0; extra == 'notebooks'
|
|
94
|
+
Requires-Dist: matplotlib>=3.8.0; extra == 'notebooks'
|
|
95
|
+
Requires-Dist: safetensors>=0.4.0; extra == 'notebooks'
|
|
96
|
+
Provides-Extra: onnx
|
|
97
|
+
Requires-Dist: onnx>=1.16.0; extra == 'onnx'
|
|
98
|
+
Provides-Extra: pandas
|
|
99
|
+
Requires-Dist: pandas>=2.1.0; extra == 'pandas'
|
|
100
|
+
Provides-Extra: polars
|
|
101
|
+
Requires-Dist: polars>=0.20.0; extra == 'polars'
|
|
102
|
+
Provides-Extra: redis
|
|
103
|
+
Requires-Dist: redis>=5.1.0; extra == 'redis'
|
|
104
|
+
Provides-Extra: taichi
|
|
105
|
+
Requires-Dist: taichi>=1.7.3; extra == 'taichi'
|
|
106
|
+
Provides-Extra: tensorflow
|
|
107
|
+
Requires-Dist: tensorflow>=2.16.0; extra == 'tensorflow'
|
|
108
|
+
Provides-Extra: torch
|
|
109
|
+
Requires-Dist: torch>=2.7.0; extra == 'torch'
|
|
110
|
+
Provides-Extra: viz
|
|
111
|
+
Requires-Dist: hydra-core>=1.3.0; extra == 'viz'
|
|
112
|
+
Requires-Dist: kaleido>=0.2.1; extra == 'viz'
|
|
113
|
+
Requires-Dist: omegaconf>=2.3.0; extra == 'viz'
|
|
114
|
+
Requires-Dist: plotly>=6.0.0; extra == 'viz'
|
|
115
|
+
Requires-Dist: pyyaml>=6.0.1; extra == 'viz'
|
|
116
|
+
Provides-Extra: zarr
|
|
117
|
+
Requires-Dist: fsspec>=2024.2.0; extra == 'zarr'
|
|
118
|
+
Requires-Dist: s3fs>=2024.2.0; extra == 'zarr'
|
|
119
|
+
Requires-Dist: zarr>=3.0.0; extra == 'zarr'
|
|
120
|
+
Description-Content-Type: text/markdown
|
|
121
|
+
|
|
122
|
+
# Diffract: Deep Neural Network Weight Analysis Library
|
|
123
|
+
|
|
124
|
+
[](https://github.com/Risk-AI-Research/diffract/actions/workflows/ci.yml)
|
|
125
|
+
[](https://pypi.org/project/diffract-core/)
|
|
126
|
+
[](https://pypi.org/project/diffract-core/)
|
|
127
|
+
[](https://risk-ai-research.github.io/diffract/)
|
|
128
|
+
[](https://opensource.org/licenses/Apache-2.0)
|
|
129
|
+
|
|
130
|
+
Official library of ["Diffract: Spectral View of LLM Domain Adaptation"](https://openreview.net/forum?id=XBUHoiAGDE)
|
|
131
|
+
(**ICML 2026 Oral**).
|
|
132
|
+
|
|
133
|
+
Diffract is a Python package for analyzing deep neural network weights and tracking
|
|
134
|
+
their evolution over the course of training.
|
|
135
|
+
|
|
136
|
+
With a straightforward API and a functional design centered on reusable _kernels_,
|
|
137
|
+
Diffract automatically resolves dependencies, builds computation graphs, and schedules
|
|
138
|
+
calculations. Parameters and results are persisted across sessions.
|
|
139
|
+
|
|
140
|
+
It accepts models from PyTorch, TensorFlow, Flax, and ONNX, as well as plain
|
|
141
|
+
dictionaries of NumPy weight matrices.
|
|
142
|
+
|
|
143
|
+
<br>
|
|
144
|
+
|
|
145
|
+
## 🚀 Quick Start
|
|
146
|
+
|
|
147
|
+
Diffract requires Python 3.12. The core package installs without any deep
|
|
148
|
+
learning framework; heavy dependencies are opt-in extras:
|
|
149
|
+
|
|
150
|
+
```bash
|
|
151
|
+
pip install diffract-core # core: extraction, spectral metrics, storage
|
|
152
|
+
pip install "diffract-core[torch]" # + PyTorch model loading (CUDA wheels on Linux, ~2-3 GB)
|
|
153
|
+
pip install "diffract-core[viz]" # + Plotly visualization and YAML plot configs
|
|
154
|
+
pip install "diffract-core[taichi]" # + accelerated heavy-tailed fits and p-value kernels
|
|
155
|
+
pip install "diffract-core[all]" # torch + viz + taichi + pandas/polars exports
|
|
156
|
+
```
|
|
157
|
+
|
|
158
|
+
Further extras: `frameworks` (TensorFlow, Flax, ONNX), `pandas` / `polars`
|
|
159
|
+
(DataFrame exports), `zarr` (cloud storage), `redis` (shared cache),
|
|
160
|
+
`notebooks` (tooling for the example notebooks). The quotes around
|
|
161
|
+
`"diffract-core[...]"` matter in zsh.
|
|
162
|
+
|
|
163
|
+
### Development Install
|
|
164
|
+
|
|
165
|
+
```bash
|
|
166
|
+
# Install uv if you haven't already
|
|
167
|
+
curl -LsSf https://astral.sh/uv/install.sh | sh
|
|
168
|
+
|
|
169
|
+
# Clone and install (uv provisions Python 3.12 automatically)
|
|
170
|
+
git clone https://github.com/Risk-AI-Research/diffract.git
|
|
171
|
+
cd diffract
|
|
172
|
+
uv sync --extra dev --extra torch
|
|
173
|
+
```
|
|
174
|
+
|
|
175
|
+
Then use it in your code:
|
|
176
|
+
|
|
177
|
+
```python
|
|
178
|
+
from diffract import Session
|
|
179
|
+
|
|
180
|
+
# Quick experiments (in-memory, no persistence)
|
|
181
|
+
session = Session(profile="ram")
|
|
182
|
+
|
|
183
|
+
# Persistent local storage (SQLite in .diffract/)
|
|
184
|
+
session = Session(profile="local")
|
|
185
|
+
|
|
186
|
+
with session:
|
|
187
|
+
session.models.add(torch_model, model_id="bert-base")
|
|
188
|
+
session.compute.apply("frob_norm", "stable_rank", "log_norm")
|
|
189
|
+
# per-parameter metrics
|
|
190
|
+
metrics_df = session.results.export_metrics(
|
|
191
|
+
"frob_norm", "stable_rank", export_format="pandas"
|
|
192
|
+
)
|
|
193
|
+
# model-level aggregates
|
|
194
|
+
aggregates_df = session.results.export_aggregates(
|
|
195
|
+
"log_norm", export_format="pandas"
|
|
196
|
+
)
|
|
197
|
+
```
|
|
198
|
+
|
|
199
|
+
Check out
|
|
200
|
+
[example notebooks](https://github.com/Risk-AI-Research/diffract/tree/main/examples) and
|
|
201
|
+
[plot configurations](https://github.com/Risk-AI-Research/diffract/tree/main/examples/configs)
|
|
202
|
+
for more examples. The
|
|
203
|
+
[notebooks](https://github.com/Risk-AI-Research/diffract/tree/main/notebooks) directory
|
|
204
|
+
contains `compare_two_checkpoints.ipynb`, an end-to-end walkthrough.
|
|
205
|
+
|
|
206
|
+
<br>
|
|
207
|
+
|
|
208
|
+
## 🤔 Why Diffract?
|
|
209
|
+
|
|
210
|
+
Neural networks often feel like black boxes. Diffract provides tools to analyze their
|
|
211
|
+
internal structure:
|
|
212
|
+
|
|
213
|
+
- **Training Insights**: Track how weights evolve across training epochs.
|
|
214
|
+
- **Architecture Analysis**: Compare different model architectures objectively.
|
|
215
|
+
- **Initialization Studies**: Evaluate the impact of initialization methods.
|
|
216
|
+
- **Spectral Analysis**: Compute empirical spectral distributions, ranks, and norms.
|
|
217
|
+
- **Heavy-Tailed Distributions**: Detect power-law and exponential tails in weight
|
|
218
|
+
spectra.
|
|
219
|
+
|
|
220
|
+
<br>
|
|
221
|
+
|
|
222
|
+
## 🔑 Key Features
|
|
223
|
+
|
|
224
|
+
- **Session-based API**: Simple `models.add`, `compute.apply`, and
|
|
225
|
+
`results.export_metrics` workflow.
|
|
226
|
+
|
|
227
|
+
- **Kernels**: Reusable functions that compute model characteristics—ranks, norms,
|
|
228
|
+
spectral properties—stored as named _fields_ on each parameter. Dependencies are
|
|
229
|
+
resolved automatically.
|
|
230
|
+
|
|
231
|
+
- **Persistent Storage**: Parameters and results survive between sessions. Supports
|
|
232
|
+
HDF5, SQLite, Zarr, and hybrid backends.
|
|
233
|
+
|
|
234
|
+
- **Kernel Apply Levels**: Kernels can work at multiple levels:
|
|
235
|
+
- **PARAMETER** - Operate on individual weight matrices.
|
|
236
|
+
- **IN_MODEL** - Aggregate within a single model.
|
|
237
|
+
- **CROSS_MODEL** - Compare or aggregate across models.
|
|
238
|
+
|
|
239
|
+
- **Built-in Visualization**: Publication-ready Plotly plots with theming support.
|
|
240
|
+
|
|
241
|
+
- **Export Formats**: Get results as `pandas`, `polars`, `dict`, `json`, or `list`.
|
|
242
|
+
|
|
243
|
+
<br>
|
|
244
|
+
|
|
245
|
+
## ✨ Core Functionality
|
|
246
|
+
|
|
247
|
+
### Adding Models
|
|
248
|
+
|
|
249
|
+
Add models from various frameworks to a session:
|
|
250
|
+
|
|
251
|
+
<!-- skip: next -->
|
|
252
|
+
|
|
253
|
+
```python
|
|
254
|
+
from diffract import Session
|
|
255
|
+
|
|
256
|
+
session = Session()
|
|
257
|
+
|
|
258
|
+
with session:
|
|
259
|
+
session.models.add(torch_model) # torch.nn.Module
|
|
260
|
+
session.models.add(torch_state_dict, model_id="checkpoint") # Dict[str, torch.Tensor]
|
|
261
|
+
session.models.add(numpy_weights, model_id="raw-weights") # Dict[str, np.ndarray]
|
|
262
|
+
session.models.add(onnx_model, model_id="onnx-model") # onnx.ModelProto
|
|
263
|
+
session.models.add(flax_model, model_id="flax-model") # flax.linen.Module
|
|
264
|
+
session.models.add(tf_model, model_id="tf-model") # TensorFlow model
|
|
265
|
+
```
|
|
266
|
+
|
|
267
|
+
### Computing Metrics
|
|
268
|
+
|
|
269
|
+
Dependencies are resolved automatically:
|
|
270
|
+
|
|
271
|
+
```python
|
|
272
|
+
session.compute.apply("frob_norm", "stable_rank")
|
|
273
|
+
session.compute.apply("pl_ks") # has many dependencies—all resolved automatically
|
|
274
|
+
```
|
|
275
|
+
|
|
276
|
+
### Filtering Parameters
|
|
277
|
+
|
|
278
|
+
Filter computations by model, parameter type, or name:
|
|
279
|
+
|
|
280
|
+
```python
|
|
281
|
+
from diffract import ParameterOverrides, ParameterType, Session
|
|
282
|
+
|
|
283
|
+
session = Session()
|
|
284
|
+
|
|
285
|
+
# Assign custom types and names during extraction
|
|
286
|
+
overrides = {
|
|
287
|
+
"model.layers.0.attn.q_proj.weight": ParameterOverrides(name="q", ptype="attn"),
|
|
288
|
+
"model.layers.0.attn.k_proj.weight": ParameterOverrides(name="k", ptype="attn"),
|
|
289
|
+
"model.layers.0.mlp.fc1.weight": ParameterOverrides(ptype="mlp"),
|
|
290
|
+
}
|
|
291
|
+
|
|
292
|
+
with session:
|
|
293
|
+
session.models.add(model, model_id="gpt", parameter_overrides=overrides)
|
|
294
|
+
session.compute.apply("frob_norm")
|
|
295
|
+
|
|
296
|
+
# Scope work to a subset with session.filter(...)
|
|
297
|
+
gpt = session.filter(model_ids=["gpt"])
|
|
298
|
+
with gpt:
|
|
299
|
+
gpt.compute.apply("frob_norm")
|
|
300
|
+
|
|
301
|
+
attn = session.filter(param_types=[ParameterType.from_string("attn")])
|
|
302
|
+
with attn:
|
|
303
|
+
attn.results.export_metrics("frob_norm")
|
|
304
|
+
```
|
|
305
|
+
|
|
306
|
+
### Retrieving Results
|
|
307
|
+
|
|
308
|
+
Export results in various formats (`pandas`, `polars`, `dict`, `json`, or `list`):
|
|
309
|
+
|
|
310
|
+
```python
|
|
311
|
+
scalars_df = session.results.export_metrics("stable_rank", export_format="pandas")
|
|
312
|
+
aggregates_df = session.results.export_aggregates(
|
|
313
|
+
"stable_rank", export_format="pandas"
|
|
314
|
+
)
|
|
315
|
+
|
|
316
|
+
# Other formats work the same way
|
|
317
|
+
results = session.results.export_metrics("stable_rank", export_format="polars")
|
|
318
|
+
results = session.results.export_metrics("stable_rank", export_format="dict")
|
|
319
|
+
results = session.results.export_metrics("stable_rank", export_format="json")
|
|
320
|
+
results = session.results.export_metrics("stable_rank", export_format="list")
|
|
321
|
+
```
|
|
322
|
+
|
|
323
|
+
### Visualization
|
|
324
|
+
|
|
325
|
+
Create publication-ready Plotly plots:
|
|
326
|
+
|
|
327
|
+
<!-- skip: next -->
|
|
328
|
+
|
|
329
|
+
```python
|
|
330
|
+
from diffract.viz import DEFAULT_THEME
|
|
331
|
+
|
|
332
|
+
# Ergonomic helpers on session.viz accept field names directly
|
|
333
|
+
session.viz.box(y="stable_rank", x="model_id", theme=DEFAULT_THEME).show()
|
|
334
|
+
session.viz.scatter(x="frob_norm", y="stable_rank").show()
|
|
335
|
+
```
|
|
336
|
+
|
|
337
|
+
### YAML-Driven Plotting
|
|
338
|
+
|
|
339
|
+
Define complex visualizations via Hydra configs:
|
|
340
|
+
|
|
341
|
+
<!-- skip: next -->
|
|
342
|
+
|
|
343
|
+
```python
|
|
344
|
+
session.viz.draw(config_path="examples/configs/boxplot_stable_rank.yaml").show()
|
|
345
|
+
```
|
|
346
|
+
|
|
347
|
+
### Kernel Configuration
|
|
348
|
+
|
|
349
|
+
List and configure kernels at runtime:
|
|
350
|
+
|
|
351
|
+
```python
|
|
352
|
+
session.compute.list_available_kernels(verbose=True)
|
|
353
|
+
session.compute.list_available_metrics(verbose=True)
|
|
354
|
+
session.compute.configure_kernel("hard_rank", threshold=1e-6)
|
|
355
|
+
```
|
|
356
|
+
|
|
357
|
+
### Session Management
|
|
358
|
+
|
|
359
|
+
Parameters and results stay available whenever the session is reopened. `Session()`
|
|
360
|
+
defaults to the in-memory `ram` profile; pick a persistent profile such as `local` or
|
|
361
|
+
`hybrid` to keep data across separate runs:
|
|
362
|
+
|
|
363
|
+
```python
|
|
364
|
+
from diffract import Session
|
|
365
|
+
|
|
366
|
+
session = Session() # in-memory; use profile="local" to persist across runs
|
|
367
|
+
|
|
368
|
+
# Add models and compute
|
|
369
|
+
with session:
|
|
370
|
+
session.models.add(model, model_id="my-model")
|
|
371
|
+
session.compute.apply("frob_norm")
|
|
372
|
+
|
|
373
|
+
# Reopen the session: earlier results are still there
|
|
374
|
+
with session:
|
|
375
|
+
results = session.results.export_metrics("frob_norm", export_format="pandas")
|
|
376
|
+
session.models.list()
|
|
377
|
+
session.models.erase("my-model")
|
|
378
|
+
```
|
|
379
|
+
|
|
380
|
+
### Custom Kernels
|
|
381
|
+
|
|
382
|
+
Implement your own research metrics using the session kernel decorator:
|
|
383
|
+
|
|
384
|
+
```python
|
|
385
|
+
from diffract import Session
|
|
386
|
+
|
|
387
|
+
session = Session()
|
|
388
|
+
|
|
389
|
+
with session:
|
|
390
|
+
# Define and register a custom kernel
|
|
391
|
+
@session.compute.kernel()
|
|
392
|
+
def my_custom_metric(frob_norm: float, *, scaling_factor: float = 1.0) -> float:
|
|
393
|
+
"""Custom metric that scales the Frobenius norm."""
|
|
394
|
+
return frob_norm * scaling_factor
|
|
395
|
+
|
|
396
|
+
session.models.add(my_model)
|
|
397
|
+
session.compute.configure_kernel("my_custom_metric", scaling_factor=2.0)
|
|
398
|
+
session.compute.apply("my_custom_metric")
|
|
399
|
+
```
|
|
400
|
+
|
|
401
|
+
You can also override the registered name and output fields:
|
|
402
|
+
|
|
403
|
+
```python
|
|
404
|
+
with session:
|
|
405
|
+
@session.compute.kernel(name="scaled_metric", produce_fields=["scaled_result"])
|
|
406
|
+
def custom_analysis(frob_norm: float, stable_rank: float, *, weight: float = 0.5) -> float:
|
|
407
|
+
"""Custom analysis combining multiple metrics."""
|
|
408
|
+
return weight * frob_norm + (1 - weight) * stable_rank
|
|
409
|
+
```
|
|
410
|
+
|
|
411
|
+
### Available Kernels
|
|
412
|
+
|
|
413
|
+
Diffract includes kernels for norms, ranks, spectral analysis, heavy-tailed fits, and
|
|
414
|
+
more. Run `session.compute.list_available_kernels(verbose=True)` to list them all.
|
|
415
|
+
|
|
416
|
+
### Merging Sessions
|
|
417
|
+
|
|
418
|
+
Merge parameters and results from another session:
|
|
419
|
+
|
|
420
|
+
<!-- skip: next -->
|
|
421
|
+
|
|
422
|
+
```python
|
|
423
|
+
from diffract import Session
|
|
424
|
+
|
|
425
|
+
session1 = Session(config_path="config1.ini")
|
|
426
|
+
session2 = Session(config_path="config2.ini")
|
|
427
|
+
|
|
428
|
+
with session1:
|
|
429
|
+
session1.models.add(model1, model_id="model-a")
|
|
430
|
+
session1.compute.apply("frob_norm")
|
|
431
|
+
|
|
432
|
+
with session2:
|
|
433
|
+
session2.models.add(model2, model_id="model-b")
|
|
434
|
+
session2.utils.merge_other_session(session1, fields=["frob_norm"])
|
|
435
|
+
```
|
|
436
|
+
|
|
437
|
+
### Configuration
|
|
438
|
+
|
|
439
|
+
Diffract offers built-in **profiles** for common setups:
|
|
440
|
+
|
|
441
|
+
| Profile | Storage | Cache | Use case |
|
|
442
|
+
| -------- | ------------- | ---------- | --------------------------------- |
|
|
443
|
+
| `ram` | RAM | None | Quick experiments, no persistence |
|
|
444
|
+
| `local` | SQLite | Simple LRU | Local development, persistent |
|
|
445
|
+
| `hybrid` | SQLite + HDF5 | Simple LRU | Large models, optimized arrays |
|
|
446
|
+
|
|
447
|
+
```python
|
|
448
|
+
from diffract import Session
|
|
449
|
+
|
|
450
|
+
# Use a profile (recommended for most users)
|
|
451
|
+
session = Session(profile="ram") # fast, temporary
|
|
452
|
+
session = Session(profile="local") # persistent, simple
|
|
453
|
+
session = Session(profile="hybrid") # persistent, optimized for large arrays
|
|
454
|
+
|
|
455
|
+
# Or use a custom config file for full control
|
|
456
|
+
session = Session(config_path="my_config.ini")
|
|
457
|
+
```
|
|
458
|
+
|
|
459
|
+
**Tip**: Start with a profile, then switch to a config file when you need
|
|
460
|
+
reproducibility or custom settings.
|
|
461
|
+
|
|
462
|
+
#### Advanced Configuration
|
|
463
|
+
|
|
464
|
+
For production or reproducible experiments, use INI config files. See
|
|
465
|
+
`src/diffract/configs/` for examples:
|
|
466
|
+
|
|
467
|
+
```ini
|
|
468
|
+
[storage]
|
|
469
|
+
backend = "sqlite"
|
|
470
|
+
|
|
471
|
+
[storage.sqlite]
|
|
472
|
+
path = "data/diffract.db"
|
|
473
|
+
|
|
474
|
+
[cache]
|
|
475
|
+
backend = "simple"
|
|
476
|
+
|
|
477
|
+
[parallel.thread_pool]
|
|
478
|
+
max_workers = 4
|
|
479
|
+
```
|
|
480
|
+
|
|
481
|
+
#### Storage Backends
|
|
482
|
+
|
|
483
|
+
- **RAM**: In-memory (no persistence)
|
|
484
|
+
- **SQLite**: Lightweight database for metadata and arrays
|
|
485
|
+
- **HDF5**: Optimized for large numerical arrays with compression
|
|
486
|
+
- **Zarr**: Cloud-optimized array storage for large-scale data
|
|
487
|
+
- **Hybrid**: SQLite (metadata) + HDF5/Zarr (arrays)
|
|
488
|
+
|
|
489
|
+
#### Cache Backends
|
|
490
|
+
|
|
491
|
+
- **Simple**: In-memory LRU cache
|
|
492
|
+
- **Redis**: Distributed caching (requires `redis` extra)
|
|
493
|
+
- **None**: Disable caching
|
|
494
|
+
|
|
495
|
+
<br>
|
|
496
|
+
|
|
497
|
+
## 📚 Documentation
|
|
498
|
+
|
|
499
|
+
The documentation site is sourced from `docs/` and built with Sphinx + MyST. Install the
|
|
500
|
+
tooling via `uv sync --extra docs` and run `make docs` to render the HTML locally.
|
|
501
|
+
|
|
502
|
+
<br>
|
|
503
|
+
|
|
504
|
+
## 📝 Citation
|
|
505
|
+
|
|
506
|
+
If you use Diffract or build on the paper, please cite:
|
|
507
|
+
|
|
508
|
+
```bibtex
|
|
509
|
+
@inproceedings{borodin2026diffract,
|
|
510
|
+
title = {Diffract: Spectral View of {LLM} Domain Adaptation},
|
|
511
|
+
author = {Nikita Borodin and Maria Krylova and Artem Zabolotnyi and Dmitry Aspisov and Egor Shikov and Nikita Tyuplyaev and Oleg Travkin and Roman Alferov and Dmitry Vinichenko},
|
|
512
|
+
booktitle = {Forty-third International Conference on Machine Learning},
|
|
513
|
+
year = {2026},
|
|
514
|
+
url = {https://openreview.net/forum?id=XBUHoiAGDE}
|
|
515
|
+
}
|
|
516
|
+
```
|
|
517
|
+
|
|
518
|
+
<br>
|
|
519
|
+
|
|
520
|
+
## ❤️ Contributions
|
|
521
|
+
|
|
522
|
+
Contributions are welcome! Fork the repo, create a feature branch, and submit a PR. Use
|
|
523
|
+
`make lint` and `make test` to validate your changes.
|
|
524
|
+
|
|
525
|
+
<br>
|
|
526
|
+
|
|
527
|
+
## 📄 License
|
|
528
|
+
|
|
529
|
+
Licensed under the Apache License 2.0 — see [LICENSE](LICENSE). Copyright 2026 Risk AI
|
|
530
|
+
Research.
|