Skip to main content

Embed a Model Inside a Graph

FieldValue
DifficultyAdvanced
Estimated Read Time20-25 minutes
Labelsgraph, hybrid, model, mpk

Concept

Drop a model into a public Graph with graph.add(model). This is the bridge pattern when you need graph-level orchestration (routing, scheduling, extra inputs/outputs) around model execution without reaching into the internal runtime graph.

Many production systems need graph-level control while still using model execution as a reusable fragment. The public pattern is now:

model = pyneat.Model("/models/yolo_v8s.tar.gz")

graph = pyneat.Graph()
graph.add(pyneat.nodes.input("image"))
graph.add(model)
graph.add(pyneat.nodes.output("result"))

NEAT lowers the model fragment into the correct internal runtime execution plan at build time. Application code does not use StageModelExecutorOptions, node IDs, or pyneat.graph.

APIs introduced

  • pyneat.Model(path) — load a compiled model archive.
  • pyneat.Graph() — public composition surface.
  • graph.add(model) — append the model route as a reusable Graph fragment.
  • pyneat.nodes.input(name) / pyneat.nodes.output(name) — public named boundaries.

When to use this

  • Graph-level composition around model execution.
  • Deterministic behavior in CI/dev even when model assets differ across environments.
  • Safe migration path from simple stage graphs to model-backed hybrid graphs.

Prerequisites Chapter 001 (Model). Chapter 012 (Graph basics).

References

Learning Process

  1. Load a model archive.
  2. Add the model directly to a public Graph.
  3. Inspect the composed Graph without using low-level runtime graph node IDs.
  4. Use later tutorials for full model execution with real inputs and accuracy checks.

Run

Python:

python3 share/sima-neat/tutorials/013_embed_model_inside_graph/embed_model_inside_graph.py \
--model /tmp/yolo_v8s.tar.gz

C++ (prebuilt):

./lib/sima-neat/tutorials/tutorial_013_embed_model_inside_graph \
--model /tmp/yolo_v8s.tar.gz

C++ (build from source):

./build.sh --target tutorial_013_embed_model_inside_graph
./build/tutorials-standalone/tutorial_013_embed_model_inside_graph \
--model /tmp/yolo_v8s.tar.gz

To integrate this chapter's C++ source into your own project with a custom CMakeLists.txt (no extras folder required), see How to Run Tutorials on the landing page.

Code

tutorials/013_embed_model_inside_graph/embed_model_inside_graph.cpp
// Hybrid graph composition: a Model is added directly to a public Graph.
//
// Usage:
// tutorial_013_embed_model_inside_graph --model /path/to/model.tar.gz

#include "neat.h"

#include <iostream>
#include <string>

namespace {

bool get_arg(int argc, char** argv, const std::string& key, std::string& out) {
for (int i = 1; i + 1 < argc; ++i) {
if (key == argv[i]) {
out = argv[i + 1];
return true;
}
}
return false;
}

} // namespace

int main(int argc, char** argv) {
try {
std::string model_path;
if (!get_arg(argc, argv, "--model", model_path)) {
std::cerr << "Usage: tutorial_013_embed_model_inside_graph --model <path>\n";
return 1;
}

simaai::neat::Model model(model_path);

// CORE LOGIC
// Model is now a Graph-compatible object. `graph.add(model)` appends the
// model route fragment (preprocess/inference/postprocess as needed) without
// exposing the internal low-level runtime graph.
simaai::neat::Graph graph;
graph.add(simaai::neat::nodes::Input("image"));
graph.add(model);
graph.add(simaai::neat::nodes::Output("result"));

std::cout << graph.describe() << "\n";

const auto info = model.info();
std::cout << "model=" << (info.model_name.empty() ? "<unnamed>" : info.model_name)
<< " physical_outputs=" << info.output_topology.physical_outputs
<< " logical_outputs=" << info.output_topology.logical_outputs << "\n";
std::cout << "[OK] 013_embed_model_inside_graph\n";
return 0;
} catch (const std::exception& e) {
std::cerr << "[FAIL] " << e.what() << "\n";
return 1;
}
}

Source