Nodes/ComfyUI CV/CV DNN Forward All
ComfyUI Node

CV DNN Forward All

Every output at once, and how to drive a two-frame model

By bmad4ever·Created 3 months ago·Updated 14 days ago· 1
CV DNN Forward All
  • blob
  • outputs
  • output_names
  • count
◄model▾►
◄output_layers►
◄backendauto (default backend)►
◄targetauto (default target)►
◄engineauto (default engine)►
◄input_names►

CV DNN Forward All loads a model and runs a forward pass that returns all of its unconnected outputs at once. It's the CV DNN Forward sibling for models that don't have a single answer.

Which models are those? Multi-head detection nets - a YOLO segmentation export gives you a detection tensor and a mask-prototype map, and you need both. Optical flow nets that return one field per direction. Anything where the "default output" your other node would return is only half the story.

It also handles .tflite files, picking the loader from the file extension (.onnx → readNetFromONNX, .tflite → readNetFromTFLite).

How it works

Same pipeline position as CV DNN Forward - CV DNN Blob From Image before it, CV DNN Pick Output and a decoder after it, and the forward pass runs in the pack's interruptible DNN worker so it can be cancelled. The difference is what comes back: leave output_layers blank and you get every unconnected output; give it a comma-separated list of names and you get exactly those, in the order you asked.

Outputs are outputs (a list of raw arrays, aligned with the names), output_names (newline-separated, feed Preview as Text), and count.

The multi-input trick, and its limits

The interesting part of this node is input_names, which is how you drive a model that takes two frames - an optical flow net, a change-detection net. Give it a comma-separated list of the network's input names and the blob's batch dimension N is split into K equal groups, one per name.

So if you run a two-frame IMAGE batch through CV DNN Blob From Image and set input_names to 0,1 - the opencv-zoo RAFT export's naming - you're feeding frame group one to input zero and group two to input one. Other exports use image0,image1 or left,right; check the model. N must be a multiple of K.

Two sharp edges here, both spelled out by the author:

  • The groups are contiguous, not interleaved. A batch of pairs is laid out as [all first frames][all second frames]. That's fine if you build the batch that way and wrong if you assumed alternating.
  • Batching may not work at all, and that's the model's fault, not the node's. Many two-input exports freeze batch 1 into their constants. Feed a two-pair blob to one of those and it dies in a Concat layer with "Inconsistent shape". Feed one pair per execution and loop. The tooltip names opencv-zoo RAFT as exactly this case, and adds another gem: on the graph engine that export returns an all-NaN field for some input pairs whatever the engine widget says - the pack's dense-flow node recovers most of them by re-running with input_names reversed and negating the flow. Good luck deducing that from a NaN.

All groups share one blob's preprocessing, so this only fits models whose inputs are images of the same size and scaling. A model mixing an image with a differently-shaped input is out of reach.

Inputs and outputs

Required: blob (NCHW, from CV DNN Blob From Image) and model (.onnx or .tflite from ComfyUI/models/onnx).

Optional: output_layers (blank = all unconnected outputs), input_names (blank = one unnamed input, right for the usual case), and the backend / target / engine trio. On this build, the first two do nothing - the graph engine ignores them, OpenCV 5.1 removed the classic engine that honoured them, and this wheel has no CUDA, no OpenVINO and no OpenCL. The engine choice still matters for loading; ONNX Runtime needs a build with WITH_ONNXRUNTIME=ON, and auto is the only meaningful choice on 5.1.

Install

Part of comfyui_cv (bmad4ever/comfyui_cv). Search "ComfyUI CV" in ComfyUI Manager, or:

cd ComfyUI/custom_nodes
git clone https://github.com/bmad4ever/comfyui_cv
pip install "opencv-contrib-python-headless~=5.0.0.93"

Then restart ComfyUI. Python ≥ 3.12 and a recent V3-API ComfyUI. Models aren't bundled - put them in ComfyUI/models/onnx and consult model_sources.txt for download URLs and licences. Note the licence warning in the README before you republish anything: yolo26n-seg.onnx is AGPL-3.0 with a network clause, and one of the LLM/VLM models isn't redistributable at all.

Common issues

  • "Inconsistent shape" in a Concat layer. A two-input model being fed more than one pair. One pair per execution, loop for the rest.
  • The output list order surprises you. It matches output_names - read that output rather than assuming index 0 is the detection head.
  • The blob's batch doesn't divide by the number of input names. N must be a multiple of K exactly.
  • Shapes are wrong and you're guessing. Inspect CV Data on each output before you wire a decoder. Detection heads come in at least four different layouts, which is precisely why CV YOLO Detect Decode has four named modes.
  • You're tempted by backend/target anyway. They're listed because the build exposes the options, not because they work. If a model is too slow, the fix is a smaller model or the CPU budget, not a compute backend.
Categoryimage/CV/dnn

Inputs (7)

NameTypeDefaultDescription
blobNPARRAY(N, C, H, W) NCHW input blob from 'CV DNN Blob From Image'.
modelCOMBOModel file from ComfyUI/models/onnx (.onnx or .tflite; the loader is picked from the extension).
output_layersoptSTRINGComma-separated output layer names to fetch. Blank = every unconnected output layer (right for most models).
backendoptCOMBOauto (default backend)Compute backend (cv2.dnn.setPreferableBackend). 'auto' leaves the net on its default and is right for almost every model. Listed is not usable: this wheel has no CUDA and no OpenVINO, so those two raise on the classic engine. The GRAPH engine ignores the setting entirely, and OpenCV 5.1 removed the classic engine that honoured it - so on this build the widget has no effect.
targetoptCOMBOauto (default target)Compute target / device (cv2.dnn.setPreferableTarget). 'auto' leaves the net on its default (CPU). Honoured on the CLASSIC engine only, which OpenCV 5.1 removed, and this build reports haveOpenCL() == False - so the widget currently does nothing. HISTORICAL (5.0 classic engine): OpenCL was usually SLOWER - squeezenet 3.6x faster, but yolo26n-seg 0.73x, EAST 0.68x, RAFT 0.26x, YuNet 0.07x.
engineoptCOMBOauto (default engine)DNN engine for ONNX models (cv2.dnn.readNetFromONNX). Ignored for .tflite files. 'auto' lets OpenCV pick. The options depend on the build: OpenCV 5.1 merged 'classic' and 'new graph' into one engine, so 'auto' is the only meaningful choice there, and 'ONNX Runtime' falls back to it unless the build has WITH_ONNXRUNTIME=ON. NOTE for two-frame models: the opencv-zoo RAFT export returns an all-NaN field for some input pairs on the graph engine, whatever this widget says - 'CV Dense Flow (DNN Model)' recovers most of them by re-running with input_names reversed and negating the flow.
input_namesoptSTRINGComma-separated NETWORK INPUT names for a multi-input model. Blank = one unnamed setInput (right for the usual single-input model). With K names the blob's batch dimension N is split into K equal groups, one fed to each named input - so a 2-frame IMAGE batch through 'DNN Blob From Image' drives a two-frame model with input_names = '0,1' (opencv-zoo RAFT), or 'image0,image1' / 'left,right' for other exports. N must be a multiple of K. The groups are CONTIGUOUS, so a batch of pairs is laid out [all first frames][all second frames], NOT interleaved. Whether a batch works at all is the MODEL's business: many two-input exports (opencv-zoo RAFT among them) freeze batch 1 into their constants, and a 2-pair blob then dies in a Concat layer with 'Inconsistent shape' - feed one pair per execution and loop for more. All groups share the one blob's preprocessing, so this fits models whose inputs are images of the SAME size and scaling; a model mixing images with a differently-shaped input is out of reach here.

Outputs (3)

NameTypeDescription
outputsNPARRAYList of raw output arrays, one per fetched layer, in the same order as output_names. Feed 'CV DNN Pick Output' to select one, or 'Inspect CV Data'.
output_namesSTRINGNewline-separated names of the fetched layers, aligned with 'outputs'. Feed 'Preview as Text'.
countINTNumber of output layers fetched.