YOLOv8-seg compilation error on Hailo-8: concat18 mapping failed. What is solution?

Hello,

I’m working with a Raspberry Pi 5 + Hailo-8 AI HAT setup. After successfully installing and running the example code, I’m now trying to use my custom-trained YOLOv8s-seg model.

My Progress:

Successfully converted: PT → ONNX → HAR

Compilation to HEF fails with the following error:

Error Message:[error] Mapping Failed (allocation time: 5s) No successful assignments: concat18 errors: Agent infeasible [error] Failed to produce compiled graph [error] BackendAllocatorException: Compilation failed: No successful assignments: concat18 errors: Agent infeasible

From my searching result, it appears this error occurs because my model is trained with YOLOv8-seg (Segmentation) rather than YOLOv8-detect (Detection).Does Hailo-8 not support YOLOv8 Segmentation models?

So is retraining with yolov8s-detect the only solution?

Hey @HyeonSeung_Je,

Welcome to the Hailo Community!

Hailo-8 definitely supports YOLOv8 segmentation models, so no need to retrain. That concat18 error is just a compiler mapping issue, not a hardware limitation.

The problem is that YOLOv8-seg has extra outputs (mask coefficients, proto layers, etc.), and the compiler needs explicit guidance on which nodes to use as endpoints. The cleanest way to handle this is using the Dataflow Compiler (DFC) directly.

Step 1: Find your end nodes

Run the DFC parser on your ONNX model:

hailo parser onnx your_model.onnx --hw-arch hailo8

It’ll detect the YOLOv8 structure and print out something like:

[info] NMS structure of yolov8 was detected.
[info] In order to use HailoRT post-processing capabilities, these end node names should be used:
  /model.22/cv2.0/cv2.0.2/Conv
  /model.22/cv3.0/cv3.0.2/Conv
  /model.22/cv2.1/cv2.1.2/Conv
  /model.22/cv3.1/cv3.1.2/Conv
  /model.22/cv2.2/cv2.2.2/Conv
  /model.22/cv3.2/cv3.2.2/Conv

Copy all of these—they’re critical for segmentation to work properly. Since you’re using seg, make sure all detection heads and segmentation outputs are included.

Step 2: Use DFC to translate, optimize, and compile

Create a Python script to run the full DFC pipeline:

from hailo_sdk_client import ClientRunner

# Initialize the runner for Hailo-8
runner = ClientRunner(hw_arch='hailo8')

# Step 1: Translate ONNX to HAR with your end nodes
runner.translate_onnx_model(
    "your_model.onnx",
    start_nodes=None,  # defaults to model input
    end_nodes=[
        "/model.22/cv2.0/cv2.0.2/Conv",
        "/model.22/cv3.0/cv3.0.2/Conv",
        "/model.22/cv2.1/cv2.1.2/Conv",
        "/model.22/cv3.1/cv3.1.2/Conv",
        "/model.22/cv2.2/cv2.2.2/Conv",
        "/model.22/cv3.2/cv3.2.2/Conv",
    ],
)

# Step 2: Optimize (quantize) with your calibration images
runner.optimize(
    calib_dataset="/path/to/calib/images"
)

# Step 3: Compile to HEF
hef = runner.compile()

# Save the compiled model
with open("yolov8s_seg.hailo8.hef", "wb") as f:
    f.write(hef)

print("Compilation successful!")

That’s it. The DFC handles all three stages automatically: translation → optimization → compilation.

Quick tips:

  • Replace those end node names with the exact ones from your parser output.
  • Make sure your calibration dataset path points to real images (ideally similar to your use case).
  • If parsing doesn’t print end nodes, try running it again—sometimes it needs a second pass to detect the YOLOv8 structure.

If it still fails, share the exact output from hailo parser onnx and we can troubleshoot from there. But this approach usually solves the mapping issue right away for YOLOv8-seg.

Let me know how it goes!

YOLOv8-seg compilation error at Step 2: TypeError with start_nodes argument

Hi,

Thanks for the previous guidance! I successfully completed Step 1 (parsing) and generated the HAR file using:

hailo parser onnx best.onnx --hw-arch hailo8

Output:
[info] Translation started on ONNX model best
[info] Restored ONNX model best (completion time: 00:00:00.19)
[info] End nodes mapped from original model: ‘/model.22/proto/cv3/act/Mul’, ‘/model.22/Concat’, ‘/model.22/Concat_4’.
[info] Translation completed on ONNX model best (completion time: 00:00:01.46)
[info] Saved HAR to: /local/shared_with_docker/yolo_conversion/best.har

:white_check_mark: best.har file created successfully


However, when I try to run the full compilation script as suggested:

from hailo_sdk_client import ClientRunner

runner = ClientRunner(hw_arch=‘hailo8’)

runner.translate_onnx_model(
“best.onnx”,
start_nodes=None,
end_nodes=[
“/model.22/proto/cv3/act/Mul”,
“/model.22/Concat”,
“/model.22/Concat_4”,
],
)

runner.optimize(
calib_dataset=“../calib_images/parking_robot_tire_detection”
)

hef = runner.compile()

with open(“yolov8s_seg_tire.hef”, “wb”) as f:
f.write(hef)

I get the following errors:

Error 1: Model name issue
[info] Translation started on ONNX model model
(It recognizes as “model” instead of “best”)

Error 2: TypeError
TypeError: Parser.parse_model_to_hn() got an unexpected keyword argument ‘start_nodes’

Error 3: Parsing error
UnsupportedShuffleLayerError in op /model.22/dfl/Reshape: Failed to determine type of layer to create in node /model.22/dfl/Reshape
Please try to parse the model again, using these end node names: /model.22/Concat_4, /model.22/proto/cv3/act/Mul, /model.22/Concat


Full error traceback:

[info] No GPU chosen and no suitable GPU found, falling back to CPU.
[info] Translation started on ONNX model model
[info] Restored ONNX model model (completion time: 00:00:00.13)
[info] Extracted ONNXRuntime meta-data for Hailo model (completion time: 00:00:00.69)
[info] Simplified ONNX model for a parsing retry attempt (completion time: 00:00:01.68)
Traceback (most recent call last):
File “/local/workspace/hailo_virtualenv/lib/python3.10/site-packages/hailo_sdk_client/sdk_backend/parser/parser.py”, line 235, in translate_onnx_model
parsing_results = self._parse_onnx_model_to_hn(
File “/local/workspace/hailo_virtualenv/lib/python3.10/site-packages/hailo_sdk_client/sdk_backend/parser/parser.py”, line 316, in _parse_onnx_model_to_hn
return self.parse_model_to_hn(
File “/local/workspace/hailo_virtualenv/lib/python3.10/site-packages/hailo_sdk_client/sdk_backend/parser/parser.py”, line 359, in parse_model_to_hn
fuser = HailoNNFuser(converter.convert_model(), net_name, converter.end_node_names)
File “/local/workspace/hailo_virtualenv/lib/python3.10/site-packages/hailo_sdk_client/model_translator/translator.py”, line 82, in convert_model
self._create_layers()
File “/local/workspace/hailo_virtualenv/lib/python3.10/site-packages/hailo_sdk_client/model_translator/edge_nn_translator.py”, line 39, in _create_layers
self._add_direct_layers()
File “/local/workspace/hailo_virtualenv/lib/python3.10/site-packages/hailo_sdk_client/model_translator/edge_nn_translator.py”, line 162, in _add_direct_layers
raise ParsingWithRecommendationException(
hailo_sdk_client.model_translator.exceptions.ParsingWithRecommendationException: Parsing failed. The errors found in the graph are:
UnsupportedShuffleLayerError in op /model.22/dfl/Reshape: Failed to determine type of layer to create in node /model.22/dfl/Reshape
Please try to parse the model again, using these end node names: /model.22/Concat_4, /model.22/proto/cv3/act/Mul, /model.22/Concat
During handling of the above exception, another exception occurred:
Traceback (most recent call last):
File “/local/shared_with_docker/yolo_conversion/compile_yolov8_seg.py”, line 7, in
runner.translate_onnx_model(
File “/local/workspace/hailo_virtualenv/lib/python3.10/site-packages/hailo_sdk_common/states/states.py”, line 16, in wrapped_func
return func(self, *args, **kwargs)
File “/local/workspace/hailo_virtualenv/lib/python3.10/site-packages/hailo_sdk_client/runner/client_runner.py”, line 1192, in translate_onnx_model
parser.translate_onnx_model(
File “/local/workspace/hailo_virtualenv/lib/python3.10/site-packages/hailo_sdk_client/sdk_backend/parser/parser.py”, line 276, in translate_onnx_model
parsing_results = self._parse_onnx_model_to_hn(
File “/local/workspace/hailo_virtualenv/lib/python3.10/site-packages/hailo_sdk_client/sdk_backend/parser/parser.py”, line 316, in _parse_onnx_model_to_hn
return self.parse_model_to_hn(
TypeError: Parser.parse_model_to_hn() got an unexpected keyword argument ‘start_nodes’


Questions:

  1. Since I already have best.har from Step 1, can I skip the translation step and proceed directly with:

runner = ClientRunner(hw_arch=‘hailo8’, har=‘best.har’)
runner.optimize(calib_dataset=‘…’)
hef = runner.compile()

  1. Is the start_nodes argument causing compatibility issues with my DFC version (3.33.0)?

  2. Should I use a different approach to specify the ONNX model path?

Environment:

  • Compilation platform: Ubuntu 22.04 with Docker (hailo_ai_sw_suite_2025-10-docker)
  • Hailo DFC: 3.33.0
  • HailoRT: 4.23.0
  • Model: YOLOv8s-seg (4 classes, custom trained for tire detection)
  • Target deployment device: Raspberry Pi 5 with Hailo-8
  • Working directory: /local/shared_with_docker/yolo_conversion

Additional question:

Once I successfully compile the HEF file, what’s the correct way to run it on Raspberry Pi 5?

Should I use the instance_segmentation.py example like this:

python basic_pipelines/instance_segmentation.py --hef-path custom_model/best.hef --input /dev/video0

Or do I need additional configuration files (like yolov8s_seg.json) for the GStreamerInstanceSegmentationApp to recognize the YOLOv8-seg HEF properly?

Any guidance would be appreciated!

Hey @HyeonSeung_Je,

There’s no need to re-parse your ONNX model. You can work directly from your existing best.har file. Let me break down what’s happening and how to resolve it.

Understanding Your Errors

The primary issue is with parameter naming. The API expects start_node_names and end_node_names, but your code is using start_nodes and end_nodes, which is causing the TypeError you’re encountering. Additionally, the parser identified some YOLO post-processing layers that it can’t handle directly. However, this isn’t actually a blocker—you already worked around this successfully when you generated best.har on the CLI, so we’ve moved past that hurdle. Finally, if you didn’t explicitly set net_name="best", the system defaults to "model". This is minor, but you can specify it if you’d like consistency.

The Solution

Skip the translate_onnx_model step entirely and proceed directly to optimization and compilation:

from hailo_sdk_client import ClientRunner
runner = ClientRunner(hw_arch='hailo8')
runner.load_har('best.har')
runner.optimize(calib_dataset='/path/to/calib_images')
hef = runner.compile()
with open('yolov8s_seg_tire.hef', 'wb') as f:
    f.write(hef)

For RPi5 Deployment

If you’re planning to deploy on Raspberry Pi 5 using Hailo-apps-infra, you would need to add a JSON configuration and may need to adjust the post-processing steps slightly. We’re here to help with that—simply run hailortclio parse-hef {model} and we can guide you through setting up those components.

Hope this helps!

Hi,

Thanks for the guidance! However, I’m getting a TypeError when trying to use the optimize method:

Code I’m using (exactly as suggested):

from hailo_sdk_client import ClientRunner

runner = ClientRunner(hw_arch=‘hailo8’)
runner.load_har(‘best.har’)
runner.optimize(calib_dataset=‘/local/shared_with_docker/calib_images/’)
hef = runner.compile()

with open(‘yolov8s_seg_tire.hef’, ‘wb’) as f:
f.write(hef)

Error:

[info] No GPU chosen and no suitable GPU found, falling back to CPU.
Traceback (most recent call last):
File “/local/shared_with_docker/yolo_conversion/compile_from_har.py”, line 5, in
runner.optimize(calib_dataset=‘/local/shared_with_docker/calib_images/parking_robot_tire_detection’)
File “/local/workspace/hailo_virtualenv/lib/python3.10/site-packages/hailo_sdk_common/states/states.py”, line 16, in wrapped_func
return func(self, *args, **kwargs)
TypeError: ClientRunner.optimize() got an unexpected keyword argument ‘calib_dataset’

Environment:

  • Hailo DFC: 3.33.0
  • HailoRT: 4.23.0
  • Docker: hailo_ai_sw_suite_2025-10-docker

Is the parameter name different in this version? What’s the correct syntax for ClientRunner.optimize()?


Additional context:

Previously, I successfully compiled this model using hailomz (Hailo Model Zoo CLI):

hailomz compile yolov8s_seg \
–ckpt best.onnx \
–hw-arch hailo8 \
–calib-path calib_images/parking_robot_tire_detection \
–classes 4

This worked and generated a HEF file. However, when I tried to run it on Raspberry Pi 5 with the instance_segmentation.py example:

python basic_pipelines/instance_segmentation.py \
–hef-path custom_model/best.hef \
–input /dev/video0

I got this error:

ValueError: HEF version not supported; please provide a compatible segmentation HEF or config file.

That’s why I’m now trying to compile using the ClientRunner API directly (as you suggested) to ensure proper compatibility.

Questions:

  1. Was the HEF file compiled via hailomz compile correct, or does it need the ClientRunner approach for proper segmentation support?

  2. If I can get the ClientRunner.optimize() working, what are the specific steps for RPi5 deployment you mentioned? You said:
    “If you’re planning to deploy on Raspberry Pi 5 using Hailo-apps-infra, you would need to add a JSON configuration and may need to adjust the post-processing steps slightly.”

    Could you provide more details on:

    • What JSON configuration format is needed?
    • How to run hailortcli parse-hef and use its output?
    • What post-processing adjustments are required for YOLOv8-seg?

I’m ready to follow the complete workflow if you can guide me through these steps!

Thank you so much for your continued support and detailed explanations. I really appreciate your help!

Hey @HyeonSeung_Je,

Let me clarify both points for you.


1. Model Zoo vs. Direct DFC and Segmentation Support

Both approaches support segmentation; you may use either the Model Zoo or the direct DFC workflow. The Model Zoo is effective when your model aligns with the pre-configured YAML files, but for a custom model, the direct DFC workflow is likely the better choice—especially if you prefer not to use the Python API.

Regarding the ClientRunner.optimize() issue you encountered, here is the correct syntax:

from hailo_sdk_client import ClientRunner, CalibrationDataType

runner = ClientRunner(har='best.har')
runner.optimize(
    calib_data='/local/shared_with_docker/calib_images/',
    data_type=CalibrationDataType.npy_dir  # or allow auto-detection
)
hef = runner.compile()
with open('yolov8s_seg_tire.hef', 'wb') as f:
    f.write(hef)

Alternatively, you can simply use
runner.optimize('/local/shared_with_docker/calib_images/')
to rely on automatic data-type detection.


2. RPi5 Post-Processing Setup

To obtain your model’s input and output nodes on the Raspberry Pi, run:

hailortcli parse-hef {model}

This command displays the node structure and simplifies the development of your post-processing code. For guidance on implementing post-processing, refer to our developer guide:
writing-postprocess

You may also consult existing segmentation JSON files as templates. If you encounter any difficulties while setting them up, feel free to reach out—we are happy to assist.

Hi,

Thanks for all the previous guidance! I’ve been working on deploying a custom YOLOv8-seg model for tire detection on Raspberry Pi 5 with Hailo-8. After overcoming several challenges during the compilation phase, I successfully generated an HEF file using hailomz. However, I’m now stuck at the deployment stage with the instance_segmentation pipeline.

I wanted to provide a comprehensive overview of the entire process, including the issues I faced and how I resolved them, to help identify what might be going wrong with the Raspberry Pi deployment.


Background & Journey

**Goal:** Deploy a custom YOLOv8s-seg model trained on 4 tire classes (front_left_tire, front_right_tire, rear_left_tire, rear_right_tire) on Raspberry Pi 5 with Hailo-8 for real-time instance segmentation.

**Initial Attempt:** Following the standard DFC workflow with ClientRunner API as suggested in earlier discussions. This led to multiple challenges that I’ll detail below.

**Current Status:** HEF file successfully compiled with hailomz, but encountering “HEF version not supported” error when trying to run it with GStreamerInstanceSegmentationApp on Raspberry Pi 5.


Compilation Journey (Ubuntu Docker Environment)

Initial Setup

**HEF File Information:**
Successfully compiled using hailomz:
```
hailomz compile yolov8s_seg \
–ckpt best.onnx \
–hw-arch hailo8 \
–calib-path calib_images/parking_robot_tire_detection \
–classes 4
```

**Compilation Attempts:**

**Attempt 1: Direct DFC compilation (FAILED)**
Following your initial guidance, I tried compiling using ClientRunner:

```python
from hailo_sdk_client import ClientRunner, CalibrationDataType

runner = ClientRunner(har=‘best.har’)
runner.optimize(
calib_data=‘/local/shared_with_docker/yolo_conversion/calib_images/parking_robot_tire_detection’,
data_type=CalibrationDataType.image_dir
)
hef = runner.compile()
```

**First issue - CalibrationDataType error:**
```
AttributeError: image_dir
```

Tried with automatic detection:
```python
runner.optimize(‘/local/shared_with_docker/yolo_conversion/calib_images/parking_robot_tire_detection’)
```

**Second issue - Data type detection failed:**
```
[info] Found model with 3 input channels, using real RGB images for calibration
[info] Starting Model Optimization

ValueError: Couldn’t detect CalibrationDataType
```

Despite having 445 JPG images in the directory, the optimizer couldn’t detect the data type.

**Solution: Converted images to NPY format**
```python
import cv2
import numpy as np
from pathlib import Path

image_dir = Path(‘calib_images/parking_robot_tire_detection’)
output_dir = Path(‘calib_npy’)
output_dir.mkdir(exist_ok=True)

image_files = sorted(list(image_dir.glob(‘*.jpg’)))
for i, img_path in enumerate(image_files):
img = cv2.imread(str(img_path))
if img is not None:
img = cv2.resize(img, (640, 640))
img = cv2.cvtColor(img, cv2.COLOR_BGR2RGB)
img = img.astype(np.float32) / 255.0 # Normalize to 0-1
np.save(output_dir / f’calib_{i:04d}.npy’, img)
```

Then used NPY directory:
```python
runner.optimize(
calib_data=‘/local/shared_with_docker/yolo_conversion/calib_npy’,
data_type=CalibrationDataType.npy_dir
)
```

**Optimization succeeded** with warnings:
```
[warning] Reducing optimization level to 0 (the accuracy won’t be optimized and compression won’t be used) because there’s less data than the recommended amount (1024), and there’s no available GPU
[info] Using dataset with 64 entries for calibration
Calibration: 100%|█████████████| 64/64 [00:18<00:00, 3.38entries/s]
[info] Model Optimization is done
```

**Compilation FAILED** with concat18 error:
```
[error] Mapping Failed (allocation time: 6s)
No successful assignments: concat18 errors:
Agent infeasible
[error] Failed to produce compiled graph
[error] BackendAllocatorException: Compilation failed
```

This is the same concat18 error we encountered initially when trying to parse the ONNX without proper end nodes.

**Attempt 2: hailomz compilation (SUCCESS)**
Switched to hailomz which succeeded without the concat18 error and generated an 18MB HEF file. This suggests hailomz handles YOLOv8-seg’s layer structure better than direct ClientRunner compilation.

**Key difference:** hailomz appears to have YOLOv8-seg specific optimizations that avoid the concat18 memory mapping issue.


Deployment Attempt (Raspberry Pi 5 Environment)

After successfully compiling the HEF with hailomz, I transferred it to Raspberry Pi 5 and attempted to run it with the existing instance_segmentation pipeline. This is where I’m currently stuck.

**HEF Parse Output:**
```
hailortcli parse-hef best.hef

Architecture HEF was compiled for: HAILO8
Network group name: yolov8s_seg, Multi Context - Number of contexts: 2
Network name: yolov8s_seg/yolov8s_seg
VStream infos:
Input yolov8s_seg/input_layer1 UINT8, NHWC(640x640x3)
Output yolov8s_seg/conv73 UINT8, NHWC(20x20x64)
Output yolov8s_seg/conv74 UINT8, NHWC(20x20x4)
Output yolov8s_seg/conv75 UINT8, NHWC(20x20x32)
Output yolov8s_seg/conv60 UINT8, FCR(40x40x64)
Output yolov8s_seg/conv61 UINT8, NHWC(40x40x4)
Output yolov8s_seg/conv62 UINT8, FCR(40x40x32)
Output yolov8s_seg/conv44 UINT8, FCR(80x80x64)
Output yolov8s_seg/conv45 UINT8, NHWC(80x80x4)
Output yolov8s_seg/conv46 UINT8, FCR(80x80x32)
Output yolov8s_seg/conv48 UINT8, FCR(160x160x32)
```


Configuration Files

**1. .env file:**
```bash
host_arch=arm
hailo_arch=hailo8
resources_path=resources
tappas_postproc_path=/usr/lib/aarch64-linux-gnu/hailo/tappas/post_processes
model_zoo_version=v2.14.0
hailort_version=4.20.0-1
tappas_version=3.31.0
virtual_env_name=venv_hailo_rpi_examples
server_url=http://dev-public.hailo.ai/2025_01
tappas_variant=hailo-tappas-core

===== Custom HEF Configuration =====

HEF_PATH=/home/argoon/hailo-rpi5-examples/custom_model/best.hef
LABELS_JSON=/home/argoon/hailo-rpi5-examples/local_resources/yolov8s_seg_custom.json
NETWORK_WIDTH=640
NETWORK_HEIGHT=640

====================================

```

**2. yolov8s_seg_custom.json (created based on parse-hef output):**
```json
{
“iou_threshold”: 0.45,
“score_threshold”: 0.3,
“max_detections”: 300,
“image_dims”: [640, 640],
“regression_length”: 64,
“classes”: 4,
“labels”: [
“front_left_tire”,
“front_right_tire”,
“rear_left_tire”,
“rear_right_tire”
],
“anchors”: ,
“meta_arch”: “yolov8_seg”,
“output_format_type”: “HAILO_FORMAT_TYPE_UINT8”,
“outputs_name”: [
“yolov8s_seg/conv73”,
“yolov8s_seg/conv74”,
“yolov8s_seg/conv75”,
“yolov8s_seg/conv60”,
“yolov8s_seg/conv61”,
“yolov8s_seg/conv62”,
“yolov8s_seg/conv44”,
“yolov8s_seg/conv45”,
“yolov8s_seg/conv46”,
“yolov8s_seg/conv48”
],
“outputs_size”: [20, 40, 80],
“strides”: [32, 16, 8],
“mask_threshold”: 0.5
}
```

**3. Modified instance_segmentation_tire.py:**
```python

Key modifications from original instance_segmentation.py:

Changed detection filter from “person” to tire classes

TIRE_COLORS = {
“front_left_tire”: (255, 0, 0), # Red
“front_right_tire”: (0, 255, 0), # Green
“rear_left_tire”: (0, 0, 255), # Blue
“rear_right_tire”: (255, 255, 0), # Cyan
}

In app_callback function:

if label in TIRE_COLORS: # Changed from: if label == “person”
# … process tire detections

At the end of file:

if _name_ == “_main_”:
import sys

project_root = Path(\__file_\_).resolve().parent.parent
env_file = project_root / ".env"
env_path_str = str(env_file)
os.environ\["HAILO_ENV_FILE"\] = env_path_str

# Attempted to force config file loading
config_file = project_root / "local_resources" / "yolov8s_seg_custom.json"
if config_file.exists():
    os.environ\["LABELS_JSON"\] = str(config_file)
    print(f"Using config file: {config_file}")
else:
    print(f"WARNING: Config file not found: {config_file}")

user_data = user_app_callback_class()
app = GStreamerInstanceSegmentationApp(app_callback, user_data)
app.run()

```


Error

When running:
```bash
cd ~/hailo-rpi5-examples
source setup_env.sh
python basic_pipelines/instance_segmentation_tire.py \
–hef-path custom_model/best.hef \
–input /dev/video0
```

**Output:**
```
Using config file: /home/argoon/hailo-rpi5-examples/local_resources/yolov8s_seg_custom.json
Loading environment variables from /home/argoon/hailo-rpi5-examples/.env…
All required environment variables loaded.
Auto-detected Hailo architecture: hailo8
Traceback (most recent call last):
File “/home/argoon/hailo-rpi5-examples/basic_pipelines/instance_segmentation_tire.py”, line 124, in
app = GStreamerInstanceSegmentationApp(app_callback, user_data)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File “/home/argoon/hailo-rpi5-examples/venv_hailo_rpi_examples/lib/python3.11/site-packages/hailo_apps/hailo_app_python/apps/instance_segmentation/instance_segmentation_pipeline.py”, line 60, in _init_
raise ValueError(“HEF version not supported; please provide a compatible segmentation HEF or config file.”)
ValueError: HEF version not supported; please provide a compatible segmentation HEF or config file.
```



Critical Discovery: Post-Processing Library Missing

After deploying to Raspberry Pi 5, I discovered the root cause:

**YOLOv8-seg post-processing library does not exist!**

```bash
ls /usr/local/hailo/resources/so/*seg*
/usr/local/hailo/resources/so/libyolov5seg_postprocess.so # Only YOLOv5!
```

The pipeline automatically uses:
```
so-path=/usr/local/hailo/resources/so/libyolov5seg_postprocess.so
config-path=/usr/local/hailo/resources/json/yolov5m_seg.json
```

**JSON Schema Incompatibility:**

When I tried using a YOLOv8-format JSON based on parse-hef outputs, I got:
```
Input JSON is invalid
Invalid schema: #
Invalid keyword: required
json config file doesn’t follow schema rules
```

**YOLOv5 vs YOLOv8 Structure:**

  • YOLOv5: 4 outputs (3 detection + 1 proto), anchor-based, uses “input_shape”
  • YOLOv8: 10 outputs (9 detection + 1 proto), anchor-free, uses “image_dims”

The YOLOv5 post-processing library cannot handle YOLOv8’s architecture.


Additional Attempts After Initial Question

**Attempt 1: Understanding the automatic HEF-JSON matching**

Initially tried various methods to pass config file:

  • Setting `LABELS_JSON` in .env file
  • Setting `os.environ[“LABELS_JSON”]` in Python script
  • Using `–config-file` argument (not supported)
  • Using `–labels-json` argument (not recognized)

All failed with “unrecognized arguments” errors.

**Then analyzed the source code to understand why:**

```python

Checked GStreamerInstanceSegmentationApp internals

python3 << ‘EOF’
import inspect
from hailo_apps.hailo_app_python.apps.instance_segmentation.instance_segmentation_pipeline import GStreamerInstanceSegmentationApp

init_source = inspect.getsource(GStreamerInstanceSegmentationApp._init_)
print(init_source)
EOF
```

**Critical discovery - automatic pattern matching:**
```python

The pipeline automatically matches HEF filename to JSON config!

hef_name = Path(self.hef_path).name

if INSTANCE_SEGMENTATION_MODEL_NAME_H8 in hef_name: # Checks if “yolov5m_seg” in filename
self.config_file = get_resource_path(…, “yolov5m_seg.json”) # Hardcoded JSON name!
elif INSTANCE_SEGMENTATION_MODEL_NAME_H8L in hef_name: # Checks if “yolov5n_seg” in filename
self.config_file = get_resource_path(…, “yolov5n_seg.json”)
else:
raise ValueError(“HEF version not supported…”)
```

**Key insight:** The config file is **NOT passed as argument** - it’s **automatically selected based on HEF filename pattern!**

Confirmed the pattern strings:
```python
INSTANCE_SEGMENTATION_MODEL_NAME_H8: “yolov5m_seg”
INSTANCE_SEGMENTATION_MODEL_NAME_H8L: “yolov5n_seg”
```

**This explained why:**

  • `best.hef` → Error: “HEF version not supported” (no pattern match)
  • `yolov5m_seg_custom.hef` → Success: matches “yolov5m_seg” pattern, loads `yolov5m_seg.json`

Based on this automatic matching behavior, I renamed:
```bash
mv best.hef yolov5m_seg_custom.hef
```

This successfully bypassed the “HEF version not supported” error and the pipeline started!

**Result:**
```
Using config file: /usr/local/hailo/resources/json/yolov5m_seg.json
v4l2src device=/dev/video0 … [pipeline created successfully]
```

**Attempt 2: Replacing JSON with YOLOv8-format config**

Created yolov5m_seg.json with YOLOv8 output structure:
```bash
sudo cp yolov5m_seg.json.backup yolov5m_seg.json.backup # Backed up original
sudo cp yolov8s_seg_custom.json /usr/local/hailo/resources/json/yolov5m_seg.json
```

**Result: FAILED with schema validation error**
```
Input JSON is invalid
Invalid schema: #
Invalid keyword: required
Invalid document: #
terminate called after throwing an instance of ‘std::runtime_error’
what(): json config file doesn’t follow schema rules
```

The YOLOv5 post-processing library (libyolov5seg_postprocess.so) expects YOLOv5-format JSON and cannot parse YOLOv8’s different structure.

**Confirmed: No YOLOv8-seg support**
```bash
ls /usr/local/hailo/resources/so/*seg*
/usr/local/hailo/resources/so/libyolov5seg_postprocess.so # Only this exists
```


Questions

  1. **Why couldn’t ClientRunner detect JPG calibration images automatically?** The directory had 445 valid JPG files, but I got “Couldn’t detect CalibrationDataType” error. Is NPY format required, or is there a way to use JPG directly?

  2. **Why does ClientRunner compilation fail with concat18 error while hailomz succeeds?** Is there a fundamental difference in how they handle YOLOv8-seg layer mapping?

  3. **Is there a YOLOv8-seg post-processing library available?** Or is YOLOv8-seg simply not supported yet on Raspberry Pi 5 despite being compilable with hailomz?

  4. **What’s the recommended approach for deploying YOLOv8-seg on Raspberry Pi 5?**

    • Option A: Write custom post-processing in C++ following the guide?
    • Option B: Use Python callback post-processing?
    • Option C: Wait for official YOLOv8-seg library support?

    Note: YOLOv8-seg is required for our use case - we cannot use Detection-only or older architectures.

  5. **If custom post-processing is needed, can you provide guidance on:**

    • How to parse the 10 output tensors from YOLOv8-seg HEF?
    • How to decode the proto masks (conv48)?
    • How to integrate it with GStreamerInstanceSegmentationApp?
  6. **Is the hailomz-compiled YOLOv8-seg HEF fundamentally compatible with Raspberry Pi deployment?** Or does hailomz compilation create HEFs that require different runtime support than what’s available on RPi5?

  7. **Can the existing libyolov5seg_postprocess.so be modified or extended to support YOLOv8-seg?** Or is a completely new post-processing library required due to the architectural differences?

  8. **Please verify our analysis:** Did we correctly understand the pipeline’s behavior?

    • Is it true that config file selection is purely based on HEF filename pattern matching?
    • Is it correct that there’s no way to override the hardcoded “yolov5m_seg.json” selection?
    • Did we miss any configuration options or environment variables that could help?

    We want to make sure we didn’t overlook something obvious before pursuing custom post-processing development.


Environment

**Compilation Environment:**

  • Platform: Ubuntu 22.04 with Docker (hailo_ai_sw_suite_2025-10-docker)
  • Hailo DFC: 3.33.0
  • Calibration images: 445 images (64 used for optimization)

**Deployment Environment:**

  • Platform: Raspberry Pi 5 with Hailo-8
  • HailoRT: 4.20.0-1
  • Tappas: 3.31.0
  • Model Zoo: v2.14.0

**Model Details:**

  • Architecture: YOLOv8s-seg
  • Classes: 4 custom classes (tire detection: front_left_tire, front_right_tire, rear_left_tire, rear_right_tire)
  • Input size: 640x640x3
  • HEF size: 18MB
  • Compiled with: hailomz (after ClientRunner failed with concat18 error)

Any guidance on how to properly configure and run YOLOv8-seg on Raspberry Pi 5 would be greatly appreciated!

Thank you for your continued support!


UPDATE - SOLVED ✓

Problem Summary:

  • YOLOv8-seg custom model (tire detection, 4 classes)
  • GStreamerInstanceSegmentationApp only supports YOLOv5-seg
  • Missing post-processing library for YOLOv8-seg

Solution: DeGirum PySDK

The Hailo community guide pointed me to DeGirum PySDK, which has native YOLOv8-seg support.

What I did:

  1. HEF compilation (hailomz) - ✓ No issues
  2. Install DeGirum: pip install degirum
  3. Create Model Zoo directory with:
    • best.hef (compiled model)
    • config.json (model configuration + Checksum required!)
    • labels.json (class names)
  4. Run inference with simple Python code

Results:

  • ✓ Real-time webcam: ~10 FPS (Raspberry Pi 5 + Hailo-8)

Key Points:

  • DeGirum handles YOLOv8-seg post-processing internally
  • No need to write custom .so files
  • JSON configuration is straightforward
  • Webcam requires GStreamer backend (not V4L2)

Resources:

Big thanks to the Hailo team and community for the excellent support!

I’ll be back if I run into any new issues during development! :+1:

1 Like

Hi @HyeonSeung_Je

The 10FPS looks low. If you are willing to share the code, we can take a look and see how to boost the FPS. You can run hailortclion the hef file to see expected performance.

Thanks for the feedback!

Actually, I’m getting around ~10 FPS based on this simple FPS counter in my code:

import time

fps_start = time.time()
fps_count = 0
fps = 0

while True:
    ret, frame = cap.read()
    result = model(frame)  # DeGirum inference
    
    # FPS calculation
    fps_count += 1
    if fps_count >= 10:
        fps = fps_count / (time.time() - fps_start)
        fps_start = time.time()
        fps_count = 0
    
    # Display with FPS
    display = result.image_overlay
    cv2.putText(display, f"FPS: {fps:.1f}", (10, 30),
                cv2.FONT_HERSHEY_SIMPLEX, 1, (0, 255, 0), 2)
    cv2.imshow('Live', display)

Model: YOLOv8s-seg (640x640, 4 classes)
Input: 640x480 webcam via GStreamer
Hardware: Raspberry Pi 5 + Hailo-8

I’ll run hailortcli on the HEF to check the expected performance. If the development progresses further from here, I’ll optimize the code based on the benchmark results and test again.

Thanks for the suggestion!

Hi @HyeonSeung_Je

Thanks for sharing. This is referred to as synchronous inference and generally leads to poor performance as successive frames are not pipelined. Please see Videos | Hailo | DeGirum Docs on how to run on video streams. You will hopefully see 30FPS (camera limit).