Parsing YOLO models with the Hailo Dataflow Compiler tool

YOLO is a known and frequently used object detection model created by Ultralytics. It has many architecture versions - v3,v4,v5,v6,x,v7,v8,v9,10 and many sub-versions.
The yolo models are built with a backbone and a detection head, when it can be divided into two groups - anchor based models, such as yolov5 and yolov7, and anchor free models, such as yolov6, yolox, yolov8 etc.

In this post I’ll take to representative models to explain how to parse the YOLO models using Hailo’s Parser tool - yolov5 and yolov8.

Yolov5
Yolov5, as mentioned, is an anchor based YOLO model. The model detector head is composed of the detector neural ops and the postprocessing ops.
Hailo chip is a neural accelerator, and therefore is very good at running neural ops, but is less efficient in running post processing ops. This is way Hailo’s SW doesn’t support some postprocessing ops such as specific Reshape layer, Gather etc. that are not a neural op.
So, when coming to parse a yolov5 model with Hailo’s Parser (which is the first step of the Dataflow Compiler pipeline), we need to provide it with the relevant end nodes, meaning the last neural ops of the model, just before the postprocessing operations.
For example, in yolov5m, this would be an end node:

As it holds the bboxes and scores data of that branch, where after it comes only postprocessing ops.
In total, for yolov5 (and yolov7) we’ll have 3 output nodes when running the Hailo Parser.

Yolov8
Yolov8 is an anchor free model, so it’s architecture is a bit different than that of yolov5.
While yolov5 have 3 branches containing each (in one node)
In this case, instead of 3 branches with 1 node containing the bboxes and scores data of that branch, yolov8 have 3 branches, each containing two nodes - one for the bbox data of the branch and the other with the scores data of it.
So, while for yolov5 we’ll have 3 end nodes in Hailo, for yolov8 we’ll have 6. An example for yolov8 branch for parsing would look like this:

You can see that after it there are only postprocessing ops (for anyone checking, the convolution layer there after the Sofmax acts practically like a ReduceSum layer).

Of course, there are model with different number of end nodes for Hailo, but the rule of thumb is always the same - the end nodes would be the last neural ops, just before the postprocessing part of the model starts.

Ok, if I compile this model with the correct end nodes, do I have to include any model scripts for the post processing? Cause when the DFC compiles a har file it generates a model graph, and my question is that, can it generate the graph without the post processing steps?

Hi @shivatejasirimalla,
Yes, in case you want to add the Hailo NMS to your model (meaning that the bbox decoding, bbox extraction and NMS would executed by the Hailo SW but would run on the host machine), you need some model optimization commands for the specific model you are compiling.
You can find in instructions on how to do so in the Dataflow Compiler user guide from the Hailo website (Developer Zone → Documentation) and check those supported models in the Hailo Model Zoo config folder:

Regards,

hi, the yolov5 example is very help, but I have some question:
image
This picture is the rest of yolov5m model. but the post process model of yolov5 is like this:


I find this model from here:Hailo-Application-Code-Examples/runtime/python/hailo_onnxruntime at main · hailo-ai/Hailo-Application-Code-Examples · GitHub

If you have any suggestion please reply me, I am writting an open source course about pi + AI kit :GitHub - Seeed-Projects/Tutorial-of-AI-Kit-with-Raspberry-Pi-From-Zero-to-Hero: This repository provides a comprehensive step-by-step guide to building AI projects using the Raspberry Pi AI Kit..

The rest model of yolov5m is different from yolov5m post process, so how to change a rest of model to a post process model.

Hi @jiahao.li,
The difference between the model can be either because the ONNX you looked at is no simplified using onnx-simplifier, or it’s a different tag, meaning it’s the same model but with some structure changes for efficiency.

Regards,

I understand that this question is not directly related to Hailo.
However, in general terms, how do you find out where the end node should be?
Or how can I know which ones are post-processed?

1 Like

Thanks for your replay.

In most cases, the parser will give you a recommendation of which end-nodes to use. If that doesn’t happen, you can check which layer is problematic and parse until the one before it.

Another option for models that are already part of our ModelZoo collection, is to check which end-nodes the ModelZoo uses. This is available in the yaml cfg files, e.g. yolov8n.

You can use the netron.app to visualize models before and after parsing.