nneditor 1.0.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.
- nneditor-1.0.0/.gitignore +42 -0
- nneditor-1.0.0/PKG-INFO +318 -0
- nneditor-1.0.0/README.md +293 -0
- nneditor-1.0.0/pyproject.toml +113 -0
- nneditor-1.0.0/src/nneditor/__init__.py +5 -0
- nneditor-1.0.0/src/nneditor/__main__.py +12 -0
- nneditor-1.0.0/src/nneditor/adapters/__init__.py +6 -0
- nneditor-1.0.0/src/nneditor/adapters/detect.py +91 -0
- nneditor-1.0.0/src/nneditor/adapters/jax/__init__.py +23 -0
- nneditor-1.0.0/src/nneditor/adapters/jax/checkpoint.py +158 -0
- nneditor-1.0.0/src/nneditor/adapters/jax/mlir_text.py +614 -0
- nneditor-1.0.0/src/nneditor/adapters/jax/stablehlo.py +309 -0
- nneditor-1.0.0/src/nneditor/adapters/onnx/__init__.py +56 -0
- nneditor-1.0.0/src/nneditor/adapters/onnx/dtypes.py +85 -0
- nneditor-1.0.0/src/nneditor/adapters/onnx/exporter.py +1081 -0
- nneditor-1.0.0/src/nneditor/adapters/onnx/index.py +280 -0
- nneditor-1.0.0/src/nneditor/adapters/onnx/indexer.py +1269 -0
- nneditor-1.0.0/src/nneditor/adapters/onnx/numerical.py +319 -0
- nneditor-1.0.0/src/nneditor/adapters/onnx/smoke_worker.py +118 -0
- nneditor-1.0.0/src/nneditor/adapters/onnx/splice.py +197 -0
- nneditor-1.0.0/src/nneditor/adapters/onnx/to_ir.py +411 -0
- nneditor-1.0.0/src/nneditor/adapters/onnx/typed_data.py +279 -0
- nneditor-1.0.0/src/nneditor/adapters/onnx/wire.py +297 -0
- nneditor-1.0.0/src/nneditor/adapters/pytorch/__init__.py +27 -0
- nneditor-1.0.0/src/nneditor/adapters/pytorch/checkpoint.py +292 -0
- nneditor-1.0.0/src/nneditor/adapters/pytorch/fx.py +296 -0
- nneditor-1.0.0/src/nneditor/adapters/pytorch/pickle_scan.py +413 -0
- nneditor-1.0.0/src/nneditor/adapters/pytorch/pt2.py +635 -0
- nneditor-1.0.0/src/nneditor/adapters/pytorch/safetensors.py +371 -0
- nneditor-1.0.0/src/nneditor/adapters/pytorch/scalar_types.py +103 -0
- nneditor-1.0.0/src/nneditor/adapters/pytorch/zip_store.py +148 -0
- nneditor-1.0.0/src/nneditor/adapters/registry.py +185 -0
- nneditor-1.0.0/src/nneditor/analysis/__init__.py +6 -0
- nneditor-1.0.0/src/nneditor/analysis/detectors.py +766 -0
- nneditor-1.0.0/src/nneditor/analysis/hierarchy.py +367 -0
- nneditor-1.0.0/src/nneditor/analysis/layout.py +306 -0
- nneditor-1.0.0/src/nneditor/analysis/lod.py +505 -0
- nneditor-1.0.0/src/nneditor/analysis/statistics.py +337 -0
- nneditor-1.0.0/src/nneditor/application/__init__.py +7 -0
- nneditor-1.0.0/src/nneditor/application/editing.py +318 -0
- nneditor-1.0.0/src/nneditor/application/edits_store.py +164 -0
- nneditor-1.0.0/src/nneditor/application/hierarchy.py +618 -0
- nneditor-1.0.0/src/nneditor/application/jobs.py +218 -0
- nneditor-1.0.0/src/nneditor/application/navigation.py +228 -0
- nneditor-1.0.0/src/nneditor/application/persistence.py +163 -0
- nneditor-1.0.0/src/nneditor/application/session.py +1253 -0
- nneditor-1.0.0/src/nneditor/application/slices.py +284 -0
- nneditor-1.0.0/src/nneditor/application/statistics_store.py +89 -0
- nneditor-1.0.0/src/nneditor/artifact_formats.py +35 -0
- nneditor-1.0.0/src/nneditor/assets/favicon.png +0 -0
- nneditor-1.0.0/src/nneditor/assets/icons/apple-touch-icon-192.png +0 -0
- nneditor-1.0.0/src/nneditor/assets/icons/icon-192.png +0 -0
- nneditor-1.0.0/src/nneditor/assets/icons/icon-512.png +0 -0
- nneditor-1.0.0/src/nneditor/assets/icons/icon-maskable-192.png +0 -0
- nneditor-1.0.0/src/nneditor/assets/icons/icon-maskable-512.png +0 -0
- nneditor-1.0.0/src/nneditor/assets/manifest.json +35 -0
- nneditor-1.0.0/src/nneditor/assets/nneditor.ico +0 -0
- nneditor-1.0.0/src/nneditor/assets/nneditor.png +0 -0
- nneditor-1.0.0/src/nneditor/cancellation.py +44 -0
- nneditor-1.0.0/src/nneditor/desktop/__init__.py +21 -0
- nneditor-1.0.0/src/nneditor/desktop/windows_associations.py +252 -0
- nneditor-1.0.0/src/nneditor/diagnostics.py +526 -0
- nneditor-1.0.0/src/nneditor/editing/__init__.py +12 -0
- nneditor-1.0.0/src/nneditor/editing/commands.py +1259 -0
- nneditor-1.0.0/src/nneditor/editing/cow.py +182 -0
- nneditor-1.0.0/src/nneditor/editing/diff.py +219 -0
- nneditor-1.0.0/src/nneditor/editing/revisions.py +572 -0
- nneditor-1.0.0/src/nneditor/editing/validation.py +868 -0
- nneditor-1.0.0/src/nneditor/input_generation.py +464 -0
- nneditor-1.0.0/src/nneditor/ir/__init__.py +6 -0
- nneditor-1.0.0/src/nneditor/ir/capabilities.py +595 -0
- nneditor-1.0.0/src/nneditor/ir/core.py +644 -0
- nneditor-1.0.0/src/nneditor/ir/identity.py +201 -0
- nneditor-1.0.0/src/nneditor/ir/schema.py +189 -0
- nneditor-1.0.0/src/nneditor/ir/serialize.py +518 -0
- nneditor-1.0.0/src/nneditor/py.typed +0 -0
- nneditor-1.0.0/src/nneditor/rendering/__init__.py +34 -0
- nneditor-1.0.0/src/nneditor/rendering/contract.py +121 -0
- nneditor-1.0.0/src/nneditor/rendering/flet_canvas.py +210 -0
- nneditor-1.0.0/src/nneditor/rendering/flet_canvas_managed.py +341 -0
- nneditor-1.0.0/src/nneditor/rendering/flet_shapes.py +278 -0
- nneditor-1.0.0/src/nneditor/rendering/hit_testing.py +63 -0
- nneditor-1.0.0/src/nneditor/rendering/scene.py +362 -0
- nneditor-1.0.0/src/nneditor/rendering/spatial.py +170 -0
- nneditor-1.0.0/src/nneditor/rendering/synthetic.py +202 -0
- nneditor-1.0.0/src/nneditor/storage/__init__.py +6 -0
- nneditor-1.0.0/src/nneditor/storage/cache.py +191 -0
- nneditor-1.0.0/src/nneditor/storage/paths.py +53 -0
- nneditor-1.0.0/src/nneditor/storage/reader.py +376 -0
- nneditor-1.0.0/src/nneditor/storage/store.py +451 -0
- nneditor-1.0.0/src/nneditor/tracing/__init__.py +117 -0
- nneditor-1.0.0/src/nneditor/tracing/comparison.py +244 -0
- nneditor-1.0.0/src/nneditor/tracing/contracts.py +453 -0
- nneditor-1.0.0/src/nneditor/tracing/inputs.py +433 -0
- nneditor-1.0.0/src/nneditor/tracing/runner.py +220 -0
- nneditor-1.0.0/src/nneditor/tracing/store.py +408 -0
- nneditor-1.0.0/src/nneditor/tracing/trace_worker.py +271 -0
- nneditor-1.0.0/src/nneditor/tracing/visualization.py +253 -0
- nneditor-1.0.0/src/nneditor/transformations/__init__.py +59 -0
- nneditor-1.0.0/src/nneditor/transformations/calibration.py +118 -0
- nneditor-1.0.0/src/nneditor/transformations/engine.py +942 -0
- nneditor-1.0.0/src/nneditor/transformations/schema.py +308 -0
- nneditor-1.0.0/src/nneditor/ui/__init__.py +1 -0
- nneditor-1.0.0/src/nneditor/ui/app.py +4982 -0
- nneditor-1.0.0/src/nneditor/ui/input_workspace.py +934 -0
- nneditor-1.0.0/src/nneditor/ui/overview.py +478 -0
- nneditor-1.0.0/src/nneditor/ui/shell_layout.py +353 -0
- nneditor-1.0.0/src/nneditor/ui/tensor_tools.py +130 -0
- nneditor-1.0.0/src/nneditor/ui/trace_graph.py +253 -0
- nneditor-1.0.0/src/nneditor/ui/viewmodel.py +437 -0
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
# Python
|
|
2
|
+
__pycache__/
|
|
3
|
+
*.py[cod]
|
|
4
|
+
.mypy_cache/
|
|
5
|
+
.pytest_cache/
|
|
6
|
+
.ruff_cache/
|
|
7
|
+
.coverage
|
|
8
|
+
htmlcov/
|
|
9
|
+
|
|
10
|
+
# Internal planning and assistant state
|
|
11
|
+
.claude/
|
|
12
|
+
.codex/
|
|
13
|
+
*.md
|
|
14
|
+
!/README.md
|
|
15
|
+
|
|
16
|
+
# Environments and builds
|
|
17
|
+
.venv/
|
|
18
|
+
.package-venv/
|
|
19
|
+
build/
|
|
20
|
+
dist/
|
|
21
|
+
*.egg-info/
|
|
22
|
+
|
|
23
|
+
# Flet
|
|
24
|
+
.flet/
|
|
25
|
+
|
|
26
|
+
# Editors and operating systems
|
|
27
|
+
.idea/
|
|
28
|
+
.vscode/
|
|
29
|
+
.DS_Store
|
|
30
|
+
Thumbs.db
|
|
31
|
+
|
|
32
|
+
# NNEditor local state and model artifacts
|
|
33
|
+
.nneditor/
|
|
34
|
+
*.onnx
|
|
35
|
+
*.onnx.data
|
|
36
|
+
*.safetensors
|
|
37
|
+
|
|
38
|
+
# Generated benchmark artifacts
|
|
39
|
+
benchmarks/results/
|
|
40
|
+
|
|
41
|
+
# Documentation generator is not part of the release source tree.
|
|
42
|
+
tools/render_docs.py
|
nneditor-1.0.0/PKG-INFO
ADDED
|
@@ -0,0 +1,318 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: nneditor
|
|
3
|
+
Version: 1.0.0
|
|
4
|
+
Summary: A scalable, capability-aware neural-network viewer and editor.
|
|
5
|
+
Author-email: Imed Bouazizi <ibouazizi@gmail.com>
|
|
6
|
+
Keywords: flet,jax,machine-learning,model-editor,neural-network,onnx,pruning,pytorch,quantization,visualization
|
|
7
|
+
Classifier: Development Status :: 5 - Production/Stable
|
|
8
|
+
Classifier: Intended Audience :: Developers
|
|
9
|
+
Classifier: Intended Audience :: Science/Research
|
|
10
|
+
Classifier: Operating System :: OS Independent
|
|
11
|
+
Classifier: Programming Language :: Python :: 3
|
|
12
|
+
Classifier: Programming Language :: Python :: 3 :: Only
|
|
13
|
+
Classifier: Programming Language :: Python :: 3.12
|
|
14
|
+
Classifier: Programming Language :: Python :: 3.13
|
|
15
|
+
Classifier: Programming Language :: Python :: 3.14
|
|
16
|
+
Classifier: Topic :: Scientific/Engineering :: Artificial Intelligence
|
|
17
|
+
Classifier: Topic :: Software Development :: User Interfaces
|
|
18
|
+
Classifier: Typing :: Typed
|
|
19
|
+
Requires-Python: <3.15,>=3.12
|
|
20
|
+
Requires-Dist: flet[all]==0.86.4
|
|
21
|
+
Requires-Dist: numpy<3,>=1.26
|
|
22
|
+
Requires-Dist: onnx<2,>=1.22
|
|
23
|
+
Requires-Dist: pillow<13,>=10
|
|
24
|
+
Description-Content-Type: text/markdown
|
|
25
|
+
|
|
26
|
+
<p align="center">
|
|
27
|
+
<img src="assets/icons/nneditor.png" alt="NNEditor icon" width="128">
|
|
28
|
+
</p>
|
|
29
|
+
|
|
30
|
+
<h1 align="center">NNEditor</h1>
|
|
31
|
+
|
|
32
|
+
<p align="center">
|
|
33
|
+
Inspect, understand, edit, optimize, and trace neural-network artifacts
|
|
34
|
+
without loading an entire model into memory or executing artifact-provided
|
|
35
|
+
code.
|
|
36
|
+
</p>
|
|
37
|
+
|
|
38
|
+
NNEditor 1.0 is a capability-aware neural-network workspace for ONNX, PyTorch,
|
|
39
|
+
safetensors, and textual StableHLO artifacts. It combines semantic graph
|
|
40
|
+
navigation, lazy tensor access, reversible editing, validated export, and
|
|
41
|
+
desktop activation tracing in one application.
|
|
42
|
+
|
|
43
|
+
## NNEditor in action
|
|
44
|
+
|
|
45
|
+
These screenshots come from a real desktop session with the 2,364-operator
|
|
46
|
+
`detr-resnet-50.onnx` model. The trace used the included fox image tensor and an
|
|
47
|
+
automatically generated all-valid pixel mask. It reached the approved 256 MiB
|
|
48
|
+
capture bound, so NNEditor reported an honest partial result while retaining
|
|
49
|
+
2,364 readable activations.
|
|
50
|
+
|
|
51
|
+
### Navigate a model by architecture
|
|
52
|
+
|
|
53
|
+

|
|
54
|
+
|
|
55
|
+
### Run a bounded activation trace
|
|
56
|
+
|
|
57
|
+

|
|
58
|
+
|
|
59
|
+
### Open activation data in a large view
|
|
60
|
+
|
|
61
|
+

|
|
62
|
+
|
|
63
|
+
## Highlights
|
|
64
|
+
|
|
65
|
+
- Navigate large graphs through architecture, block, layer, and operator views.
|
|
66
|
+
- Detect attention, feed-forward, convolutional, repeated, and structural
|
|
67
|
+
regions with retained evidence and explanations.
|
|
68
|
+
- Read embedded and external tensors lazily through bounded byte ranges.
|
|
69
|
+
- Inspect tensor metadata, decoded previews, heatmaps, streaming statistics,
|
|
70
|
+
and paged hexadecimal data.
|
|
71
|
+
- Apply reversible graph and tensor changes without modifying the source
|
|
72
|
+
artifact.
|
|
73
|
+
- Save only when needed through a dirty-aware top-bar action, or close the
|
|
74
|
+
current model without quitting the application.
|
|
75
|
+
- Generate safe `.npy` test inputs from images, masks, CSV data, synthetic
|
|
76
|
+
time series, or generic tensor patterns, then assign them to model inputs.
|
|
77
|
+
- Preview quantization and pruning before committing them.
|
|
78
|
+
- Export validated ONNX revisions or clearly labelled weights-only artifacts.
|
|
79
|
+
- Trace ONNX activations in an isolated desktop worker and inspect values by
|
|
80
|
+
clicking nodes, blocks, connections, inputs, or outputs.
|
|
81
|
+
- Explain every unavailable action through an explicit artifact capability
|
|
82
|
+
contract.
|
|
83
|
+
|
|
84
|
+
## Supported artifacts
|
|
85
|
+
|
|
86
|
+
NNEditor identifies artifacts by their contents, not only by their extension.
|
|
87
|
+
The table describes the built-in readers and the strongest release-level
|
|
88
|
+
workflow available for each artifact.
|
|
89
|
+
|
|
90
|
+
| Artifact | Inspection | Editing | Export | Activation tracing |
|
|
91
|
+
|:--|:--|:--|:--|:--|
|
|
92
|
+
| ONNX model, including external data | Graphs, weights, metadata | Validated graph and tensor subset | ONNX with validation and provenance | Available on desktop |
|
|
93
|
+
| PyTorch exported program | Graph, parameters, buffers, constraints | Parameter and buffer bytes | Weights-only safetensors | Unavailable |
|
|
94
|
+
| PyTorch state dictionary | Weights and tensor metadata | Tensor-level changes | Weights-only artifact | Unavailable |
|
|
95
|
+
| PyTorch FX graph module | Partial topology and metadata | Unavailable | Unavailable | Unavailable |
|
|
96
|
+
| Safetensors | Weights and header metadata | Tensor-level changes | Safetensors | Unavailable |
|
|
97
|
+
| Flax or Orbax checkpoint | Weights and tensor metadata | Tensor-level changes | Weights-only artifact | Unavailable |
|
|
98
|
+
| Textual StableHLO | Functions, regions, operations, attributes | Inspection only | Unavailable | Unavailable |
|
|
99
|
+
|
|
100
|
+
Support is intentionally capability-specific. For example, opening a checkpoint
|
|
101
|
+
does not imply that NNEditor can reconstruct a model graph, and reading
|
|
102
|
+
StableHLO does not imply that NNEditor can write the dialect back. Unavailable
|
|
103
|
+
actions explain the format-specific reason directly in the interface.
|
|
104
|
+
|
|
105
|
+
## Installation
|
|
106
|
+
|
|
107
|
+
NNEditor requires Python 3.12, 3.13, or 3.14.
|
|
108
|
+
|
|
109
|
+
```bash
|
|
110
|
+
python -m pip install nneditor==1.0.0
|
|
111
|
+
```
|
|
112
|
+
|
|
113
|
+
Start the desktop application with either command:
|
|
114
|
+
|
|
115
|
+
```bash
|
|
116
|
+
nneditor
|
|
117
|
+
```
|
|
118
|
+
|
|
119
|
+
```bash
|
|
120
|
+
python -m nneditor
|
|
121
|
+
```
|
|
122
|
+
|
|
123
|
+
Open a model directly from the command line:
|
|
124
|
+
|
|
125
|
+
```bash
|
|
126
|
+
nneditor path/to/model.onnx
|
|
127
|
+
```
|
|
128
|
+
|
|
129
|
+
On Windows, select **File types** in the top bar to register NNEditor for
|
|
130
|
+
`.onnx`, `.pb`, `.pt2`, `.pt`, `.pth`, `.ckpt`, `.bin`, `.safetensors`,
|
|
131
|
+
`.mlir`, and `.stablehlo` files. NNEditor then opens Windows Default apps,
|
|
132
|
+
where you choose which extensions should launch it. Registration is per-user
|
|
133
|
+
and never replaces a protected Windows default without that explicit choice.
|
|
134
|
+
|
|
135
|
+
## First run
|
|
136
|
+
|
|
137
|
+
1. Select **Open model** and choose a supported artifact. NNEditor detects its
|
|
138
|
+
format from the file contents.
|
|
139
|
+
2. Start in the architecture view, then open a block or change the detail level
|
|
140
|
+
to move through blocks, layers, and operators.
|
|
141
|
+
3. Select a node to inspect its ports, attributes, weights, and capability
|
|
142
|
+
information.
|
|
143
|
+
4. Use search, breadcrumbs, the hierarchy explorer, keyboard navigation, and
|
|
144
|
+
the minimap to move around large models.
|
|
145
|
+
5. Prepare edits or transformations in the left panel. NNEditor validates a
|
|
146
|
+
preview before enabling **Commit**.
|
|
147
|
+
6. After a commit, **Save changes…** appears in the top bar. Select it to
|
|
148
|
+
export the current revision to a new destination; it disappears after a
|
|
149
|
+
successful save and returns after another change.
|
|
150
|
+
7. Select **Close model** to release the current artifact and return to the
|
|
151
|
+
start screen without quitting NNEditor.
|
|
152
|
+
|
|
153
|
+
The opened source remains unchanged throughout this workflow. A recovered
|
|
154
|
+
sidecar revision is treated as unsaved and offers **Save changes…** immediately.
|
|
155
|
+
|
|
156
|
+
Large imports, statistics, exports, and traces run as cancellable background
|
|
157
|
+
jobs. The interface reports partial or unavailable data instead of presenting
|
|
158
|
+
it as complete.
|
|
159
|
+
|
|
160
|
+
## Activation tracing
|
|
161
|
+
|
|
162
|
+
Desktop tracing is available for ONNX models:
|
|
163
|
+
|
|
164
|
+
1. Open **Generate test input** to resize an image, create a mask, convert
|
|
165
|
+
numeric CSV/time-series data, synthesize a signal, or create a generic
|
|
166
|
+
tensor. Select a model input and use **Generate, save & assign** to return
|
|
167
|
+
directly to that input node. You can also click the tensor-picker button
|
|
168
|
+
inside an input node and choose an existing safe NumPy `.npy` tensor.
|
|
169
|
+
Required `*_mask` inputs left unchanged use an automatically generated
|
|
170
|
+
all-valid mask; other inputs use deterministic random data.
|
|
171
|
+
2. Open **Trace activations**, review the input specification and the
|
|
172
|
+
wall-clock, memory, capture, and chunk limits.
|
|
173
|
+
3. Select **Approve & run trace**. This click creates an approval bound to the
|
|
174
|
+
current model, inputs, and limits for that run only.
|
|
175
|
+
4. Click any operator, semantic block, visible connection, model input, or model
|
|
176
|
+
output. NNEditor automatically builds the corresponding bounded activation
|
|
177
|
+
views and shows them in the inspector.
|
|
178
|
+
5. Select **Open large view** on an activation card for a scrollable overlay
|
|
179
|
+
containing its histogram, line view, heatmap, feature-map grid, or attention
|
|
180
|
+
view, as applicable.
|
|
181
|
+
|
|
182
|
+
Ready-made image and time-series tensors are available in
|
|
183
|
+
[examples/trace-inputs](examples/trace-inputs).
|
|
184
|
+
|
|
185
|
+
Input tensors are checked against the model's declared dtype and shape.
|
|
186
|
+
Approval is created only when **Approve & run trace** is selected, so a changed
|
|
187
|
+
input or limit cannot reuse stale consent. The UI captures graph inputs and
|
|
188
|
+
operator outputs by default so inspection does not depend on the selection that
|
|
189
|
+
was active when the trace began.
|
|
190
|
+
|
|
191
|
+
Tracing uses the ONNX reference evaluator in a separate, resource-limited
|
|
192
|
+
process. A failed or cancelled run publishes no trace. Desktop subprocess
|
|
193
|
+
isolation is not a multi-tenant security boundary, so tracing is disabled in
|
|
194
|
+
the browser application until a dedicated worker service is available.
|
|
195
|
+
|
|
196
|
+
## Editing and optimization
|
|
197
|
+
|
|
198
|
+
### Validated ONNX editing
|
|
199
|
+
|
|
200
|
+
The 1.0 release supports a deliberately bounded entry-graph edit surface:
|
|
201
|
+
|
|
202
|
+
- rename nodes;
|
|
203
|
+
- edit supported scalar and list attributes;
|
|
204
|
+
- replace compatible operators;
|
|
205
|
+
- insert or remove validated unary operators;
|
|
206
|
+
- reconnect compatible inputs; and
|
|
207
|
+
- replace same-length tensor byte ranges.
|
|
208
|
+
|
|
209
|
+
Every change is prepared as a transaction, checked against the graph and ONNX
|
|
210
|
+
schema, and committed as a reversible revision. Undo, redo, recovery, diff
|
|
211
|
+
previews, and export provenance use the same revision chain.
|
|
212
|
+
|
|
213
|
+
### Quantization and pruning
|
|
214
|
+
|
|
215
|
+
NNEditor can preview and commit:
|
|
216
|
+
|
|
217
|
+
- 8-bit signed or unsigned, symmetric or asymmetric weight conversion;
|
|
218
|
+
- per-tensor and per-channel quantization;
|
|
219
|
+
- portable ONNX QuantizeLinear/DequantizeLinear insertion;
|
|
220
|
+
- threshold, mask, and exact `N:M` logical pruning; and
|
|
221
|
+
- a shape-proven terminal `MatMul` channel-pruning pattern.
|
|
222
|
+
|
|
223
|
+
The UI distinguishes a mathematical conversion from storage reduction or
|
|
224
|
+
runtime acceleration. Logical sparsity alone is never advertised as a smaller
|
|
225
|
+
or faster model.
|
|
226
|
+
|
|
227
|
+
## Safety and data integrity
|
|
228
|
+
|
|
229
|
+
NNEditor is safe-artifact-first:
|
|
230
|
+
|
|
231
|
+
- Import parses artifact bytes without importing or executing Python stored in
|
|
232
|
+
the artifact.
|
|
233
|
+
- Pickle-based PyTorch containers are inspected through a restricted,
|
|
234
|
+
non-executing reader.
|
|
235
|
+
- Source artifacts are immutable and identified by cryptographic content
|
|
236
|
+
hashes.
|
|
237
|
+
- External tensor files are verified before their bytes are used.
|
|
238
|
+
- Tensor reads, caches, statistics, capture storage, and writes are bounded.
|
|
239
|
+
- Unsupported or ambiguous edits are rejected rather than approximated.
|
|
240
|
+
- Exports are staged, validated, and published as new artifacts.
|
|
241
|
+
- Inference requires explicit per-run approval and enforced resource limits.
|
|
242
|
+
|
|
243
|
+
## Large-model design
|
|
244
|
+
|
|
245
|
+
NNEditor avoids eager model materialization during normal inspection. Its ONNX
|
|
246
|
+
reader indexes protobuf wire ranges directly, tensor storage uses range reads
|
|
247
|
+
and bounded caches, and semantic graph levels keep the visible working set
|
|
248
|
+
manageable. The renderer is behind a toolkit-neutral contract and uses culling,
|
|
249
|
+
persistent shapes, and deterministic aggregation.
|
|
250
|
+
|
|
251
|
+
These choices make ordinary navigation responsive without pretending that an
|
|
252
|
+
unaggregated view containing tens of thousands of visible operators is cheap.
|
|
253
|
+
|
|
254
|
+
## Platform support
|
|
255
|
+
|
|
256
|
+
The desktop application targets:
|
|
257
|
+
|
|
258
|
+
- 64-bit Windows 10 and 11;
|
|
259
|
+
- macOS 12 or newer; and
|
|
260
|
+
- Debian 10–12 and Ubuntu 20.04, 22.04, and 24.04 LTS.
|
|
261
|
+
|
|
262
|
+
CI exercises Python 3.12, 3.13, and 3.14 on Linux and Python 3.14 on Windows.
|
|
263
|
+
The dynamic Flet browser application supports model inspection and editing, but
|
|
264
|
+
desktop-only tracing and browser multi-file export packaging remain unavailable.
|
|
265
|
+
Mobile packaging is outside the 1.0 release.
|
|
266
|
+
|
|
267
|
+
## Known boundaries
|
|
268
|
+
|
|
269
|
+
- Structural editing is limited to validated ONNX entry-graph cases.
|
|
270
|
+
- Custom or unknown operator schemas may be inspected but are not guessed
|
|
271
|
+
during editing or tracing.
|
|
272
|
+
- PyTorch graph re-serialization and ONNX conversion are not included.
|
|
273
|
+
- Textual StableHLO is inspection-only.
|
|
274
|
+
- Weights-only exports do not contain executable topology.
|
|
275
|
+
- Browser tracing is disabled pending multi-user worker isolation.
|
|
276
|
+
- The original Python, module definitions, and training code cannot be
|
|
277
|
+
reconstructed from serialized artifacts.
|
|
278
|
+
|
|
279
|
+
## Development
|
|
280
|
+
|
|
281
|
+
The development environment is managed with
|
|
282
|
+
[uv](https://docs.astral.sh/uv/):
|
|
283
|
+
|
|
284
|
+
```bash
|
|
285
|
+
uv sync --locked --group dev
|
|
286
|
+
```
|
|
287
|
+
|
|
288
|
+
Run the desktop application:
|
|
289
|
+
|
|
290
|
+
```bash
|
|
291
|
+
uv run flet run src/main.py
|
|
292
|
+
```
|
|
293
|
+
|
|
294
|
+
Run the browser application:
|
|
295
|
+
|
|
296
|
+
```bash
|
|
297
|
+
uv run flet run --web src/main.py
|
|
298
|
+
```
|
|
299
|
+
|
|
300
|
+
Run the release quality gates:
|
|
301
|
+
|
|
302
|
+
```bash
|
|
303
|
+
uv run ruff format --check .
|
|
304
|
+
uv run ruff check .
|
|
305
|
+
uv run mypy
|
|
306
|
+
uv run pytest -m "not performance" \
|
|
307
|
+
--cov=nneditor \
|
|
308
|
+
--cov-report=term-missing \
|
|
309
|
+
--cov-fail-under=90
|
|
310
|
+
uv run pytest -m performance tests/performance
|
|
311
|
+
```
|
|
312
|
+
|
|
313
|
+
Build and validate the distributions:
|
|
314
|
+
|
|
315
|
+
```bash
|
|
316
|
+
uv build --clear
|
|
317
|
+
uvx twine check --strict dist/*
|
|
318
|
+
```
|
nneditor-1.0.0/README.md
ADDED
|
@@ -0,0 +1,293 @@
|
|
|
1
|
+
<p align="center">
|
|
2
|
+
<img src="assets/icons/nneditor.png" alt="NNEditor icon" width="128">
|
|
3
|
+
</p>
|
|
4
|
+
|
|
5
|
+
<h1 align="center">NNEditor</h1>
|
|
6
|
+
|
|
7
|
+
<p align="center">
|
|
8
|
+
Inspect, understand, edit, optimize, and trace neural-network artifacts
|
|
9
|
+
without loading an entire model into memory or executing artifact-provided
|
|
10
|
+
code.
|
|
11
|
+
</p>
|
|
12
|
+
|
|
13
|
+
NNEditor 1.0 is a capability-aware neural-network workspace for ONNX, PyTorch,
|
|
14
|
+
safetensors, and textual StableHLO artifacts. It combines semantic graph
|
|
15
|
+
navigation, lazy tensor access, reversible editing, validated export, and
|
|
16
|
+
desktop activation tracing in one application.
|
|
17
|
+
|
|
18
|
+
## NNEditor in action
|
|
19
|
+
|
|
20
|
+
These screenshots come from a real desktop session with the 2,364-operator
|
|
21
|
+
`detr-resnet-50.onnx` model. The trace used the included fox image tensor and an
|
|
22
|
+
automatically generated all-valid pixel mask. It reached the approved 256 MiB
|
|
23
|
+
capture bound, so NNEditor reported an honest partial result while retaining
|
|
24
|
+
2,364 readable activations.
|
|
25
|
+
|
|
26
|
+
### Navigate a model by architecture
|
|
27
|
+
|
|
28
|
+

|
|
29
|
+
|
|
30
|
+
### Run a bounded activation trace
|
|
31
|
+
|
|
32
|
+

|
|
33
|
+
|
|
34
|
+
### Open activation data in a large view
|
|
35
|
+
|
|
36
|
+

|
|
37
|
+
|
|
38
|
+
## Highlights
|
|
39
|
+
|
|
40
|
+
- Navigate large graphs through architecture, block, layer, and operator views.
|
|
41
|
+
- Detect attention, feed-forward, convolutional, repeated, and structural
|
|
42
|
+
regions with retained evidence and explanations.
|
|
43
|
+
- Read embedded and external tensors lazily through bounded byte ranges.
|
|
44
|
+
- Inspect tensor metadata, decoded previews, heatmaps, streaming statistics,
|
|
45
|
+
and paged hexadecimal data.
|
|
46
|
+
- Apply reversible graph and tensor changes without modifying the source
|
|
47
|
+
artifact.
|
|
48
|
+
- Save only when needed through a dirty-aware top-bar action, or close the
|
|
49
|
+
current model without quitting the application.
|
|
50
|
+
- Generate safe `.npy` test inputs from images, masks, CSV data, synthetic
|
|
51
|
+
time series, or generic tensor patterns, then assign them to model inputs.
|
|
52
|
+
- Preview quantization and pruning before committing them.
|
|
53
|
+
- Export validated ONNX revisions or clearly labelled weights-only artifacts.
|
|
54
|
+
- Trace ONNX activations in an isolated desktop worker and inspect values by
|
|
55
|
+
clicking nodes, blocks, connections, inputs, or outputs.
|
|
56
|
+
- Explain every unavailable action through an explicit artifact capability
|
|
57
|
+
contract.
|
|
58
|
+
|
|
59
|
+
## Supported artifacts
|
|
60
|
+
|
|
61
|
+
NNEditor identifies artifacts by their contents, not only by their extension.
|
|
62
|
+
The table describes the built-in readers and the strongest release-level
|
|
63
|
+
workflow available for each artifact.
|
|
64
|
+
|
|
65
|
+
| Artifact | Inspection | Editing | Export | Activation tracing |
|
|
66
|
+
|:--|:--|:--|:--|:--|
|
|
67
|
+
| ONNX model, including external data | Graphs, weights, metadata | Validated graph and tensor subset | ONNX with validation and provenance | Available on desktop |
|
|
68
|
+
| PyTorch exported program | Graph, parameters, buffers, constraints | Parameter and buffer bytes | Weights-only safetensors | Unavailable |
|
|
69
|
+
| PyTorch state dictionary | Weights and tensor metadata | Tensor-level changes | Weights-only artifact | Unavailable |
|
|
70
|
+
| PyTorch FX graph module | Partial topology and metadata | Unavailable | Unavailable | Unavailable |
|
|
71
|
+
| Safetensors | Weights and header metadata | Tensor-level changes | Safetensors | Unavailable |
|
|
72
|
+
| Flax or Orbax checkpoint | Weights and tensor metadata | Tensor-level changes | Weights-only artifact | Unavailable |
|
|
73
|
+
| Textual StableHLO | Functions, regions, operations, attributes | Inspection only | Unavailable | Unavailable |
|
|
74
|
+
|
|
75
|
+
Support is intentionally capability-specific. For example, opening a checkpoint
|
|
76
|
+
does not imply that NNEditor can reconstruct a model graph, and reading
|
|
77
|
+
StableHLO does not imply that NNEditor can write the dialect back. Unavailable
|
|
78
|
+
actions explain the format-specific reason directly in the interface.
|
|
79
|
+
|
|
80
|
+
## Installation
|
|
81
|
+
|
|
82
|
+
NNEditor requires Python 3.12, 3.13, or 3.14.
|
|
83
|
+
|
|
84
|
+
```bash
|
|
85
|
+
python -m pip install nneditor==1.0.0
|
|
86
|
+
```
|
|
87
|
+
|
|
88
|
+
Start the desktop application with either command:
|
|
89
|
+
|
|
90
|
+
```bash
|
|
91
|
+
nneditor
|
|
92
|
+
```
|
|
93
|
+
|
|
94
|
+
```bash
|
|
95
|
+
python -m nneditor
|
|
96
|
+
```
|
|
97
|
+
|
|
98
|
+
Open a model directly from the command line:
|
|
99
|
+
|
|
100
|
+
```bash
|
|
101
|
+
nneditor path/to/model.onnx
|
|
102
|
+
```
|
|
103
|
+
|
|
104
|
+
On Windows, select **File types** in the top bar to register NNEditor for
|
|
105
|
+
`.onnx`, `.pb`, `.pt2`, `.pt`, `.pth`, `.ckpt`, `.bin`, `.safetensors`,
|
|
106
|
+
`.mlir`, and `.stablehlo` files. NNEditor then opens Windows Default apps,
|
|
107
|
+
where you choose which extensions should launch it. Registration is per-user
|
|
108
|
+
and never replaces a protected Windows default without that explicit choice.
|
|
109
|
+
|
|
110
|
+
## First run
|
|
111
|
+
|
|
112
|
+
1. Select **Open model** and choose a supported artifact. NNEditor detects its
|
|
113
|
+
format from the file contents.
|
|
114
|
+
2. Start in the architecture view, then open a block or change the detail level
|
|
115
|
+
to move through blocks, layers, and operators.
|
|
116
|
+
3. Select a node to inspect its ports, attributes, weights, and capability
|
|
117
|
+
information.
|
|
118
|
+
4. Use search, breadcrumbs, the hierarchy explorer, keyboard navigation, and
|
|
119
|
+
the minimap to move around large models.
|
|
120
|
+
5. Prepare edits or transformations in the left panel. NNEditor validates a
|
|
121
|
+
preview before enabling **Commit**.
|
|
122
|
+
6. After a commit, **Save changes…** appears in the top bar. Select it to
|
|
123
|
+
export the current revision to a new destination; it disappears after a
|
|
124
|
+
successful save and returns after another change.
|
|
125
|
+
7. Select **Close model** to release the current artifact and return to the
|
|
126
|
+
start screen without quitting NNEditor.
|
|
127
|
+
|
|
128
|
+
The opened source remains unchanged throughout this workflow. A recovered
|
|
129
|
+
sidecar revision is treated as unsaved and offers **Save changes…** immediately.
|
|
130
|
+
|
|
131
|
+
Large imports, statistics, exports, and traces run as cancellable background
|
|
132
|
+
jobs. The interface reports partial or unavailable data instead of presenting
|
|
133
|
+
it as complete.
|
|
134
|
+
|
|
135
|
+
## Activation tracing
|
|
136
|
+
|
|
137
|
+
Desktop tracing is available for ONNX models:
|
|
138
|
+
|
|
139
|
+
1. Open **Generate test input** to resize an image, create a mask, convert
|
|
140
|
+
numeric CSV/time-series data, synthesize a signal, or create a generic
|
|
141
|
+
tensor. Select a model input and use **Generate, save & assign** to return
|
|
142
|
+
directly to that input node. You can also click the tensor-picker button
|
|
143
|
+
inside an input node and choose an existing safe NumPy `.npy` tensor.
|
|
144
|
+
Required `*_mask` inputs left unchanged use an automatically generated
|
|
145
|
+
all-valid mask; other inputs use deterministic random data.
|
|
146
|
+
2. Open **Trace activations**, review the input specification and the
|
|
147
|
+
wall-clock, memory, capture, and chunk limits.
|
|
148
|
+
3. Select **Approve & run trace**. This click creates an approval bound to the
|
|
149
|
+
current model, inputs, and limits for that run only.
|
|
150
|
+
4. Click any operator, semantic block, visible connection, model input, or model
|
|
151
|
+
output. NNEditor automatically builds the corresponding bounded activation
|
|
152
|
+
views and shows them in the inspector.
|
|
153
|
+
5. Select **Open large view** on an activation card for a scrollable overlay
|
|
154
|
+
containing its histogram, line view, heatmap, feature-map grid, or attention
|
|
155
|
+
view, as applicable.
|
|
156
|
+
|
|
157
|
+
Ready-made image and time-series tensors are available in
|
|
158
|
+
[examples/trace-inputs](examples/trace-inputs).
|
|
159
|
+
|
|
160
|
+
Input tensors are checked against the model's declared dtype and shape.
|
|
161
|
+
Approval is created only when **Approve & run trace** is selected, so a changed
|
|
162
|
+
input or limit cannot reuse stale consent. The UI captures graph inputs and
|
|
163
|
+
operator outputs by default so inspection does not depend on the selection that
|
|
164
|
+
was active when the trace began.
|
|
165
|
+
|
|
166
|
+
Tracing uses the ONNX reference evaluator in a separate, resource-limited
|
|
167
|
+
process. A failed or cancelled run publishes no trace. Desktop subprocess
|
|
168
|
+
isolation is not a multi-tenant security boundary, so tracing is disabled in
|
|
169
|
+
the browser application until a dedicated worker service is available.
|
|
170
|
+
|
|
171
|
+
## Editing and optimization
|
|
172
|
+
|
|
173
|
+
### Validated ONNX editing
|
|
174
|
+
|
|
175
|
+
The 1.0 release supports a deliberately bounded entry-graph edit surface:
|
|
176
|
+
|
|
177
|
+
- rename nodes;
|
|
178
|
+
- edit supported scalar and list attributes;
|
|
179
|
+
- replace compatible operators;
|
|
180
|
+
- insert or remove validated unary operators;
|
|
181
|
+
- reconnect compatible inputs; and
|
|
182
|
+
- replace same-length tensor byte ranges.
|
|
183
|
+
|
|
184
|
+
Every change is prepared as a transaction, checked against the graph and ONNX
|
|
185
|
+
schema, and committed as a reversible revision. Undo, redo, recovery, diff
|
|
186
|
+
previews, and export provenance use the same revision chain.
|
|
187
|
+
|
|
188
|
+
### Quantization and pruning
|
|
189
|
+
|
|
190
|
+
NNEditor can preview and commit:
|
|
191
|
+
|
|
192
|
+
- 8-bit signed or unsigned, symmetric or asymmetric weight conversion;
|
|
193
|
+
- per-tensor and per-channel quantization;
|
|
194
|
+
- portable ONNX QuantizeLinear/DequantizeLinear insertion;
|
|
195
|
+
- threshold, mask, and exact `N:M` logical pruning; and
|
|
196
|
+
- a shape-proven terminal `MatMul` channel-pruning pattern.
|
|
197
|
+
|
|
198
|
+
The UI distinguishes a mathematical conversion from storage reduction or
|
|
199
|
+
runtime acceleration. Logical sparsity alone is never advertised as a smaller
|
|
200
|
+
or faster model.
|
|
201
|
+
|
|
202
|
+
## Safety and data integrity
|
|
203
|
+
|
|
204
|
+
NNEditor is safe-artifact-first:
|
|
205
|
+
|
|
206
|
+
- Import parses artifact bytes without importing or executing Python stored in
|
|
207
|
+
the artifact.
|
|
208
|
+
- Pickle-based PyTorch containers are inspected through a restricted,
|
|
209
|
+
non-executing reader.
|
|
210
|
+
- Source artifacts are immutable and identified by cryptographic content
|
|
211
|
+
hashes.
|
|
212
|
+
- External tensor files are verified before their bytes are used.
|
|
213
|
+
- Tensor reads, caches, statistics, capture storage, and writes are bounded.
|
|
214
|
+
- Unsupported or ambiguous edits are rejected rather than approximated.
|
|
215
|
+
- Exports are staged, validated, and published as new artifacts.
|
|
216
|
+
- Inference requires explicit per-run approval and enforced resource limits.
|
|
217
|
+
|
|
218
|
+
## Large-model design
|
|
219
|
+
|
|
220
|
+
NNEditor avoids eager model materialization during normal inspection. Its ONNX
|
|
221
|
+
reader indexes protobuf wire ranges directly, tensor storage uses range reads
|
|
222
|
+
and bounded caches, and semantic graph levels keep the visible working set
|
|
223
|
+
manageable. The renderer is behind a toolkit-neutral contract and uses culling,
|
|
224
|
+
persistent shapes, and deterministic aggregation.
|
|
225
|
+
|
|
226
|
+
These choices make ordinary navigation responsive without pretending that an
|
|
227
|
+
unaggregated view containing tens of thousands of visible operators is cheap.
|
|
228
|
+
|
|
229
|
+
## Platform support
|
|
230
|
+
|
|
231
|
+
The desktop application targets:
|
|
232
|
+
|
|
233
|
+
- 64-bit Windows 10 and 11;
|
|
234
|
+
- macOS 12 or newer; and
|
|
235
|
+
- Debian 10–12 and Ubuntu 20.04, 22.04, and 24.04 LTS.
|
|
236
|
+
|
|
237
|
+
CI exercises Python 3.12, 3.13, and 3.14 on Linux and Python 3.14 on Windows.
|
|
238
|
+
The dynamic Flet browser application supports model inspection and editing, but
|
|
239
|
+
desktop-only tracing and browser multi-file export packaging remain unavailable.
|
|
240
|
+
Mobile packaging is outside the 1.0 release.
|
|
241
|
+
|
|
242
|
+
## Known boundaries
|
|
243
|
+
|
|
244
|
+
- Structural editing is limited to validated ONNX entry-graph cases.
|
|
245
|
+
- Custom or unknown operator schemas may be inspected but are not guessed
|
|
246
|
+
during editing or tracing.
|
|
247
|
+
- PyTorch graph re-serialization and ONNX conversion are not included.
|
|
248
|
+
- Textual StableHLO is inspection-only.
|
|
249
|
+
- Weights-only exports do not contain executable topology.
|
|
250
|
+
- Browser tracing is disabled pending multi-user worker isolation.
|
|
251
|
+
- The original Python, module definitions, and training code cannot be
|
|
252
|
+
reconstructed from serialized artifacts.
|
|
253
|
+
|
|
254
|
+
## Development
|
|
255
|
+
|
|
256
|
+
The development environment is managed with
|
|
257
|
+
[uv](https://docs.astral.sh/uv/):
|
|
258
|
+
|
|
259
|
+
```bash
|
|
260
|
+
uv sync --locked --group dev
|
|
261
|
+
```
|
|
262
|
+
|
|
263
|
+
Run the desktop application:
|
|
264
|
+
|
|
265
|
+
```bash
|
|
266
|
+
uv run flet run src/main.py
|
|
267
|
+
```
|
|
268
|
+
|
|
269
|
+
Run the browser application:
|
|
270
|
+
|
|
271
|
+
```bash
|
|
272
|
+
uv run flet run --web src/main.py
|
|
273
|
+
```
|
|
274
|
+
|
|
275
|
+
Run the release quality gates:
|
|
276
|
+
|
|
277
|
+
```bash
|
|
278
|
+
uv run ruff format --check .
|
|
279
|
+
uv run ruff check .
|
|
280
|
+
uv run mypy
|
|
281
|
+
uv run pytest -m "not performance" \
|
|
282
|
+
--cov=nneditor \
|
|
283
|
+
--cov-report=term-missing \
|
|
284
|
+
--cov-fail-under=90
|
|
285
|
+
uv run pytest -m performance tests/performance
|
|
286
|
+
```
|
|
287
|
+
|
|
288
|
+
Build and validate the distributions:
|
|
289
|
+
|
|
290
|
+
```bash
|
|
291
|
+
uv build --clear
|
|
292
|
+
uvx twine check --strict dist/*
|
|
293
|
+
```
|