NNSchemaParser
NNSchemaParser converts a PyTorch nn.Module into a serializable, inspectable
graph representation — the ModelBlockSchema — that keeps the original variable
names of the forward source and every sub-module (including MoE experts that a
single trace would never visit). The schema can then be executed by a built-in
schema interpreter that re-dispatches every recorded call to the real torch
callables, so the graph runs exactly like the model — and can optionally capture
the value of every intermediate tensor.
nn.Module ──parse──► ModelBlockSchema ──interpret──► outputs / captured values
(your code) (names + graph) (identical to model(x))
Why not torch.fx?
torch.fx.symbolic_trace |
NNSchemaParser | |
|---|---|---|
| Variable names | lost (_0, _1, …) |
kept (hidden_states, query, …) |
| Untaken branches (MoE experts) | missing | all present |
| Control flow | graph_module nodes only |
if / for / try as first-class instructions |
*args / **kwargs |
limited | supported in signatures and call sites |
| Comprehensions | unsupported | compiled to helper functions |
| Re-executable | via the FX machinery | via a small self-contained interpreter |
Quick start
import torch
from torch import nn
from nnschemaparser import NNParser, SchemaInterpreter, TraceRecorder, dump_schema
class MLP(nn.Module):
def __init__(self) -> None:
super().__init__()
self.fc1 = nn.Linear(784, 256)
self.fc2 = nn.Linear(256, 10)
def forward(self, x: torch.Tensor) -> torch.Tensor:
hidden = self.fc1(x)
activated = hidden.relu()
return self.fc2(activated)
model = MLP().eval()
x = torch.randn(2, 784)
# 1. Parse the model into a schema (resolves shapes and dtypes)
schema = NNParser.parse_model(
model=model,
inputs_tensors_shapes={"x": (2, 784)},
inputs_tensors_dtypes={"x": "torch.float32"},
inputs_tensors_values={"x": x},
)
# 2. Dump a readable view of the whole block tree
dump_schema(schema=schema, path="schema.txt")
# 3. Execute it with a tracer and compare with the real forward
tracer = TraceRecorder()
outputs = SchemaInterpreter(capture_values=True, listeners=[tracer]).run(
block=schema,
scope={"x": x.clone()},
)
tracer.save("trace.txt")
reference = model(x)
assert torch.equal(outputs[0], reference)
The schema dump of MLP reads exactly like the source — original variable
names, every sub-module, and the resolved shape of every step:
=== BLOCK MLP ===
inputs:
- x = torch.float32[2, 784]
outputs:
- torch.float32[2, 10]
weights:
(none)
sub-blocks:
- fc1(Linear)
- fc2(Linear)
body:
hidden = CALL fc1(x) -> torch.float32[2, 256]
$t1 = getattr(hidden, 'relu') -> builtin_function_or_method
activated = hidden.relu() -> torch.float32[2, 256]
$t2 = CALL fc2(activated) -> torch.float32[2, 10]
RETURN $t2
The tracer records the same execution chronologically, with the value of every intermediate tensor (one line per event, indented by the nesting depth) — this is what a WebUI consumes to display every intermediate value:
[00001] ENTER BLOCK MLP
[00002] in x = torch.float32[2, 784] abs_sum=1241.4496 min=-3.0303 max=3.3046
[00003] ENTER BLOCK Linear
[00004] in input = torch.float32[2, 784] abs_sum=1241.4496 min=-3.0303 max=3.3046
[00005] $t1 = F.linear(input, weight, bias) [torch.float32[2, 256] abs_sum=215.3293 ...]
[00006] EXIT BLOCK Linear -> (torch.float32[2, 256] abs_sum=215.3293 ...)
[00007] hidden = CALL fc1 [Linear] [torch.float32[2, 256] abs_sum=215.3293 ...]
Installation
pip install . # or: pip install -e .[research] for the harness extras
Requires Python ≥ 3.12 and PyTorch ≥ 2.0. The model classes must be importable
from a real file (the parser reads the forward source with
inspect.getsource, which fails for classes defined in a REPL or stdin).
Validation
A robustness sweep of 58 models — 48 Hugging Face hub checkpoints (text,
vision, audio, multimodal) plus 10 locally built architectures (MLP, RNN, CNN,
autoencoder, GAN, GNN) — runs each model through parse → interpret → compare
against the real forward. All 58 pass with maxdiff = 0.0 against the real
forward. See docs/DOCUMENTATION.md for the full model
matrix and the sweep CLI.
Documentation
- docs/API.md — the public API: parsing, executing, tracing, dumping and walking schemas.
- docs/DOCUMENTATION.md — full documentation: how the parser works, the schema and instruction reference, the interpreter, usage recipes, supported syntax, supported/unsupported models, and limitations.
- CHANGELOG.md — the release history.
tests/hf_sweep.py— the validation harness CLI (58 HuggingFace models).tests/test_new_syntax.py,tests/test_parser.py,tests/test_methods_and_scalars.py— the fixture test suite (pytest, no network needed), also runnable withpython -m tests.test_new_syntax.tests/test_speech_models.py— the espnet/torchaudio regression tests.
License
MIT — see LICENSE.
Metadata
Release files for nnschemaparser 0.1.0
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | Provenance | Actions |
|---|---|---|---|---|
| nnschemaparser-0.1.0.tar.gz | 68.9 kB | Without provenance | Details for nnschemaparser-0.1.0.tar.gz |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Actions Reset |
|---|---|---|---|---|
| nnschemaparser-0.1.0-py3-none-any.whl | Python 3 | none | any | Details for nnschemaparser-0.1.0-py3-none-any.whl |
Total release size: 145.5 kB
Release files / nnschemaparser-0.1.0.tar.gz
| Download URL | nnschemaparser-0.1.0.tar.gz |
|---|---|
| Size | 68.9 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
c8c5eb7e6cae86df435ea886a081d59157b15957d2e49b95c247da22ad0c2744
|
|
BLAKE2b-256 checksum How to use checksums |
135f5ad86ba3d3f43d0d03eb3ecf2fad72527cbd72af53a11fd3562745a843ba
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/7.0.0 CPython/3.12.0
|
Release files / nnschemaparser-0.1.0-py3-none-any.whl
| Download URL | nnschemaparser-0.1.0-py3-none-any.whl |
|---|---|
| Size | 76.6 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
3895f2551553265358307e721833e281d4742216667e938caddffe0698ec4cb8
|
|
BLAKE2b-256 checksum How to use checksums |
59abedc33c907f38f9d6b526216db8671f4cd47993dac85d1098432125f00658
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/7.0.0 CPython/3.12.0
|
Security for nnschemaparser 0.1.0
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
No provenance found
None of the files in this release were uploaded with provenance metadata.
A note on package security
PyPI is a repository for distributing packages, not a service for auditing them. While third-party security researchers and our staff do their best to detect and remove malicious packages, PyPI cannot guarantee the quality, security or suitability of any given package.
To learn more about protecting yourself from malicious actors, visit our package security documentation.