nFlow

A node-based visual deep-learning model creator — design models as graphs, see live tensor shapes as you wire nodes, and design models, run real CPU inference, and export to PyTorch / ONNX. Built as a cross-platform Tauri v2 desktop app: Rust core (authoritative graph IR + shape-inference engine) + React/xyflow frontend.

Architecture & research docs live in the companion repo: krystv/nflow-architecture-spec (SRS, ENGINE, ONNX_BASELINE).

Status (implemented & verified)

Layer Crate / dir Verified
Graph IR (slotmap SSA, types, affine Dim algebra) crates/nflow-ir ✅ cargo test (6)
Inference (DimSolver unify/assume, broadcast) crates/nflow-infer ✅ cargo test (7)
Operators (Layer-0 prims + composites + Rhai custom ops) crates/nflow-ops ✅ cargo test (14)
Session (event-sourced undo/redo + live inference + view) crates/nflow-events ✅ cargo test (6)
Exporters (PyTorch + ONNX text & binary protobuf) crates/nflow-codegen ✅ cargo test (5)
Execution (Backend trait + CPU evaluator, real numeric inference) crates/nflow-exec ✅ cargo test (4)
Tauri v2 IPC backend (incl. export_code) src-tauri builds with Tauri toolchain
Frontend (3-pane pro UI, xyflow, dark design system) src/ ✅ npm run build

54 backend tests pass across 6 crates. The shape engine genuinely infers e.g. a ResNet stem Conv2D([B,3,224,224], [64,3,7,7], stride=2, pad=3) → [B,64,112,112] symbolically.

Verified ONNX interop ✅

nFlow exports a real binary .onnx (hand-encoded ModelProto, opset 21). Verified this session: the exported MatMul→Add→Relu model passes onnx.checker and runs in onnxruntime, matching the reference relu(x@w+b) numerically. Download via Export → .onnx.

Extensible custom ops (Rhai)

Researchers define a new op's shape logic in a Rhai script (fn infer(inputs)), loaded at runtime — no recompile (ENGINE §6.3). Verified with a double_last op.

Real execution (Simulate)

The Backend trait + a pure-Rust CPU evaluator actually compute the graph: x@w+b → relu with inputs returns the exact numeric tensor (verified in tests). A burn-wgpu backend implements the same trait for GPU — scaffolded behind the off-by-default wgpu feature (cargo test -p nflow-exec --features wgpu on a GPU host); the portable build/tests never depend on a GPU. This is the SRS §7.2 abstraction proven end-to-end.

Composite nodes (build new nodes from fundamentals)

nn.linear, nn.silu, nn.attention are composites defined purely as a decomposition into Layer-0 primitives (PyTorch-style). The inline pass materializes them, so inference, export, and (future) execution work with zero extra code — attention → transpose → matmul → softmax → matmul. New high-level nodes need only an expand() recipe. Export auto-inlines composites so they emit as primitives; double-click a Block node to "dive in" and edit its primitives.

Example: generated code

A 3-node graph x @ w + b -> relu exports (verified, AST-valid Python) to:

class Model(torch.nn.Module):
    def forward(self, x, w, b):
        v0 = torch.matmul(x, w)
        v1 = v0 + b
        v2 = F.relu(v1)
        return v2

and to ONNX text MatMul -> Add -> Relu carrying inferred symbolic shapes [s0, 4].

Revision highlights (robustness + UX)

  • Snapshot-based undo/redo — uniform across every edit (add/connect/disconnect/delete/attr/move/dive-in); eliminates the prior "undo not implemented" gaps. O(1) node-id index with a graph-scan fallback.
  • Edge-case guards: rejects self-connections, cycles (DAG-preserving), dtype-mismatched wires; delete cleans up orphaned edges; missing-node intents fail gracefully; inference surfaces shape errors as per-node diagnostics (never panics).
  • Cost model: real params + FLOPs per node and model totals (conv 3→64 7×7 = 9.4K params, verified), symbolic dims marked as estimates.
  • LLM-builder composites: nn.linear, nn.layernorm, nn.feedforward, nn.mha, nn.transformer_block (composite-of-composites) — drop one node, export a full transformer; all lower to primitives for ONNX/PyTorch.
  • UX: live cost HUD, model-totals + dive-in in the inspector, one-click Template (transformer), error toasts for rejected edits, a status bar (validity / node·edge counts / assumptions), Delete-key + edge-delete→disconnect.

Architecture (data-flow)

React/xyflow UI  --invoke(intent)-->  Tauri command  -->  Session.apply()
   ^                                                          |
   |  GraphView (nodes+edges+live shapes+assumptions)  <------ run_inference()

The Rust core is the single source of truth; the UI is a read-only projection. Every edit is a reversible event (undo/redo). Shapes are inferred in Rust and streamed to the UI.

Beta UI repair — declared input ports

Fixed a critical graph-model bug: node input handles are now rendered from the operator/composite declared port contract, not only from already-connected inputs. Newly added nodes like math.matmul show both a and b input ports immediately; composites like nn.linear show x, w, b before wiring. This is locked by regression tests.

Fixes this revision

  • Performance + draggable nodes: Canvas now uses xyflow local state (useNodesState/useEdgesState); syncs from the backend only on topology/shape changes and commits moves on drag-stop. Removed transition-all from nodes. No more full re-render on every mouse move.
  • Input / Output nodes: every model starts from an io.input (configurable shape/dtype) and ends at an io.output. New projects are seeded with Input → Output. Graph validity is enforced and shown in the status bar; ONNX export registers Input as a graph input / Output as the graph output (verified: passes onnx.checker + runs in onnxruntime).

Build & run

Workspace note: src-tauri is a workspace member (required so tauri dev / cargo metadata resolve). default-members points at the pure crates, so cargo test at the root is fast and needs no GPU/webkit; tauri dev builds src-tauri explicitly.

Prerequrisites: Rust (stable), Node 20+, and the Tauri v2 system deps (webkit2gtk etc. — see https://tauri.app/start/prerequisites/).

npm install
# Rust core tests (no GUI deps needed):
cargo test
# Dev (desktop app with hot-reload frontend):
npm run tauri dev
# Production bundle:
npm run tauri build
# Frontend-only preview (uses an in-browser mock of the Rust engine):
npm run dev

High-performance graph rendering (why these choices)

Heavy graphs must never hang the UI. Decisions:

  • xyflow (React Flow) with onlyRenderVisibleElements — viewport virtualization renders only on-screen nodes, so 1000+ node graphs stay smooth.
  • Backend does all heavy work. Shape inference, validation, and graph mutation run in Rust off the webview thread; the UI only renders the resulting GraphView. The webview main thread is never blocked by computation.
  • Move coalescing. Node drags commit to the core only on drag-stop (not every frame), keeping IPC traffic minimal (SRS §5.3).
  • memo-ised custom nodes + fine-grained zustand selectors → only changed nodes re-render.
  • Dotted canvas background + smoothstep edges are GPU-cheap; the minimap uses a flat node color function (no per-node React render).
  • Future: for >5k nodes, swap the xyflow renderer layer for a WebGL edge/node layer while keeping the same GraphView contract.

Repo layout

crates/         # Rust workspace: ir, infer, ops, events (pure, fully tested)
src-tauri/      # Tauri v2 desktop backend (IPC commands)
src/            # React 19 + xyflow + Tailwind v4 frontend
  bridge/       # the ONLY place that talks to Rust (typed invoke + dev mock)
  store/        # zustand read-only view projection
  editor/       # xyflow canvas + custom NFlowNode
  panels/       # Header, palette (SidebarLeft), inspector (SidebarRight)

License

Apache-2.0

Generated by ML Intern

This model repository was generated by ML Intern, an agent for machine learning research and development on the Hugging Face Hub.

Usage

from transformers import AutoModelForCausalLM, AutoTokenizer

model_id = 'krystv/nflow'
tokenizer = AutoTokenizer.from_pretrained(model_id)
model = AutoModelForCausalLM.from_pretrained(model_id)

For non-causal architectures, replace AutoModelForCausalLM with the appropriate AutoModel class.

Downloads last month

-

Downloads are not tracked for this model. How to track
Inference Providers NEW
This model isn't deployed by any Inference Provider. 🙋 Ask for provider support