Embed a Model Inside a Graph
| Field | Value |
|---|---|
| Difficulty | Advanced |
| Estimated Read Time | 20-25 minutes |
| Labels | graph, 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
- Load a model archive.
- Add the model directly to a public Graph.
- Inspect the composed Graph without using low-level runtime graph node IDs.
- 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
// 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;
}
}