Skip to main content
Version: 0.9.x [Latest Beta]

Core concepts

The main building blocks

Pipeline

A Pipeline is the graph that executes your complete inference workflow. You either:

  • load it from a .denkflow file, or
  • build it manually from .denkmodel files and utility nodes

A pipeline can be modified only before initialization.

# Load from export
pipeline = Pipeline.from_denkflow("model.denkflow", pat="YOUR-PAT")

# Or build manually
pipeline = Pipeline()
pipeline.add_image_resize_node(...)

Node

A Node is one processing step inside the pipeline, such as:

  • image resize
  • object detection
  • classification
  • OCR
  • segmentation
  • anomaly detection

Topic

A Topic is the connection name used to move tensors between producers and consumers.

Topic strings follow this format:

[{node_name}]/{port_name}[?timeout={ms}]
  • Node outputs and internal connections use {node_name}/{port_name} — for example image-resize/resized_image or bb-filter/filtered_bounding_boxes.
  • Pipeline inputs and constants use an empty node name: /port_name — for example /image for the external image input, or /target_size for a fixed resize dimension.
  • Optional timeout — append ?timeout=500 to set a per-topic receive timeout in milliseconds.

Constant topic values

Instead of dedicated constant nodes, you set fixed tensor values on topics before initialize(). Constant topics must use the /port_name form (empty node name).

pipeline.set_constant_value("/target_size", np.array([1088, 1280], dtype=np.int64))
defaults = pipeline.get_constant_values() # before initialize()
pipeline.remove_constant_value("/target_size")

Runtime parameters on exported pipelines

When you load a .denkflow file, graph constants from the export are applied automatically (for example /iou_threshold or /image_size). To supply different values on each run:

  1. Discover constant topics and their default values with get_constant_values() before initialize()
  2. Call remove_constant_value(topic) for each parameter you intend to override
  3. Publish your own values before every run()

See Runtime parameters on exported pipelines for a full walkthrough.

Inspecting topics with TopicDescription

After initialize(), call get_topics() to list every topic in the pipeline. Each entry is a TopicDescription with:

  • topic_name — the topic string
  • topic_typeExternalInput, ExternalOutput, or InternalConnection
  • tensor_type — e.g. ImageTensor, BoundingBoxTensor
  • is_constanttrue when the topic has a fixed initializer value
pipeline.initialize()
for topic in pipeline.get_topics():
if topic.topic_type.name == "ExternalInput" and not topic.is_constant:
print("Publish to:", topic.topic_name)
if topic.topic_type.name == "ExternalOutput":
print("Subscribe to:", topic.topic_name)

Tensor

A Tensor is a payload flowing through the graph. Common tensor types include:

  • ImageTensor
  • BoundingBoxTensor
  • ScalarTensor
  • OcrTensor
  • SegmentationMaskTensor
  • InstanceSegmentationMaskTensor

Receiver

A Receiver subscribes to a topic and lets you wait for output data. This is how you collect inference results after calling run().

receiver = pipeline.subscribe("filter/output")
# Then use the typed receive method that matches the topic's tensor type:
# receiver.receive_bounding_box_tensor()

Typical evaluation workflow

Most inference scripts follow this shape:

  1. Create or load a pipeline
  2. Initialize the pipeline
  3. Subscribe to one or more output topics
  4. Publish input tensors
  5. Call run()
  6. Receive and decode the result
pipeline = Pipeline.from_denkflow("model.denkflow", pat="PAT")
pipeline.initialize()

# Discover topics (see Topic section above)
input_topics = [
t.topic_name for t in pipeline.get_topics()
if t.topic_type.name == "ExternalInput" and not t.is_constant
]
output_topics = [
t.topic_name for t in pipeline.get_topics()
if t.topic_type.name == "ExternalOutput"
]

receiver = pipeline.subscribe(output_topics[0])
pipeline.publish_image_tensor("/image", ImageTensor.from_file("image.jpg"))
pipeline.run()

objects = receiver.receive_bounding_box_tensor().to_objects(0.5)

.denkflow versus .denkmodel

.denkflow

Use .denkflow when:

  • you want the simplest deployment path
  • you want export-target-specific runtime configuration
  • you want quantized deployment artifacts

.denkmodel

Use .denkmodel when:

  • you want to assemble the graph yourself
  • you want to choose or force runtime strings like cuda, tensorrt, directml, or openvino from Python or C/C++
  • you want to combine multiple models in one hand-built pipeline

Execution providers and device IDs

Each inference node runs on an execution provider (cpu, cuda, tensorrt, directml, or openvino). Custom pipelines select it via execution_provider= (Python) or the C-API equivalent; exported .denkflow files carry the runtime intent chosen at export time and can be redirected per node before initialization.

For the full provider list, device-id semantics (e.g. OpenVINO -1/-2/>=0), and override rules, see Runtime and Device Selection.

  1. Export a .denkflow file from the Vision AI Hub
  2. Install the SDK for the target runtime and language
  3. Keep the SDK data directory persistent (default paths are in Configuration; in Docker, mount a host volume at that default path or at the path DENKFLOW_DATA_DIRECTORY points to)
  4. Deploy and benchmark on the actual target hardware