OneHot operator

Hello. https://hailo.ai/developer-zone/documentation/dataflow-compiler-v3-31-0/?sp_referrer=sdk/translating_tf_models.html says that OneHot is a quantizable operation, but the following code throws with
hailo_sdk_common.hailo_nn.exceptions.InvalidHNError: The original node name /OneHot in end_node_names is missing in the HN.

# OneHot.py
def minimal_example():
    import os
    import tempfile
    from pathlib import Path

    import onnx
    import torch
    import torch.nn.functional as F
    from hailo_sdk_client import ClientRunner


    class JustOneHot(torch.nn.Module):
        def __init__(self, num_classes: int):
            super().__init__()
            self.num_classes = num_classes

        def forward(
            self,
            x: torch.Tensor,
        ) -> torch.Tensor:
            return F.one_hot(x, num_classes=self.num_classes)


    os.chdir(tempfile.mkdtemp(dir=Path(__file__).parent.resolve()))
    ONNX_PATH = f"{__file__.removesuffix('.py')}.onnx"
    OPSET_VERSION = 15
    IN_SHAPE = (16, 1, 1)  # B
    N_CLASSES = 8

    torch_input = torch.randint(0, N_CLASSES, IN_SHAPE)
    model = JustOneHot(num_classes=N_CLASSES)
    # =============== Convert to .ONNX =================
    with torch.no_grad():
        torch.onnx.export(
            model,
            args = (torch_input,),
            f=ONNX_PATH,
            verbose=False,
            do_constant_folding=False,
            opset_version=OPSET_VERSION,  # Use the appropriate ONNX opset version
        )
    # onnx_model, _ = onnxsim.simplify(ONNX_PATH)
    # onnx.checker.check_model(onnx_model, full_check=True)
    # onnx.save_model(onnx_model, ONNX_PATH)
    onnx_model = onnx.load(ONNX_PATH)
    onnx.checker.check_model(onnx_model, full_check=True)
    print(f"Saved ONNX model to {ONNX_PATH}")

    # ============== Parse the model (.onnx -> .hef) ===============
    print(f"{onnx.__version__ = }")
    print(f"{torch.__version__ = }")
    print(f"{__import__('hailo_sdk_client').__version__ = }")
    runner = ClientRunner(hw_arch="hailo8l")
    runner.translate_onnx_model(ONNX_PATH)



if __name__ == "__main__":
    minimal_example()

Full output

onnx.__version__ = '1.16.0'
torch.__version__ = '2.7.0+cu126'
__import__('hailo_sdk_client').__version__ = '3.31.0'
[info] Translation started on ONNX model model
[info] Restored ONNX model model (completion time: 00:00:00.00)
[info] Extracted ONNXRuntime meta-data for Hailo model (completion time: 00:00:00.01)
[info] Simplified ONNX model for a parsing retry attempt (completion time: 00:00:00.02)
Traceback (most recent call last):
  File "/local/workspace/hailo_virtualenv/lib/python3.10/site-packages/hailo_sdk_client/sdk_backend/parser/parser.py", line 239, 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 320, 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 372, in parse_model_to_hn
    hailo_nn = fuser.convert_model()
               └ <hailo_sdk_client.model_translator.fuser.fuser.HailoNNFuser object at 0x7f76195fcbb0>
  File "/local/workspace/hailo_virtualenv/lib/python3.10/site-packages/hailo_sdk_client/model_translator/fuser/fuser.py", line 114, in convert_model
    self._finalize_fused_model()
    └ <hailo_sdk_client.model_translator.fuser.fuser.HailoNNFuser object at 0x7f76195fcbb0>
  File "/local/workspace/hailo_virtualenv/lib/python3.10/site-packages/hailo_sdk_client/model_translator/fuser/fuser.py", line 476, in _finalize_fused_model
    self._output_graph.update_output_layers_order(self._end_node_names)
    │                                             └ <hailo_sdk_client.model_translator.fuser.fuser.HailoNNFuser object at 0x7f76195fcbb0>
    └ <hailo_sdk_client.model_translator.fuser.fuser.HailoNNFuser object at 0x7f76195fcbb0>
  File "/local/workspace/hailo_virtualenv/lib/python3.10/site-packages/hailo_sdk_common/hailo_nn/hailo_nn.py", line 928, in update_output_layers_order
    raise InvalidHNError(
hailo_sdk_common.hailo_nn.exceptions.InvalidHNError: The original node name /OneHot in end_node_names is missing in the HN.

During handling of the above exception, another exception occurred:

Traceback (most recent call last):
  File "/mnt/eagle-core/test_onehot.py", line 63, in <module>
    minimal_example()
    └ <function minimal_example at 0x7f77b5bc3d90>
  File "/mnt/eagle-core/test_onehot.py", line 58, in minimal_example
    runner.translate_onnx_model(ONNX_PATH)
    │                           └ '/mnt/eagle-core/test_onehot.onnx'
    └ <hailo_sdk_client.runner.client_runner.ClientRunner object at 0x7f77b5692470>
  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)
           │    │      │       └ {}
           │    │      └ ('/mnt/eagle-core/test_onehot.onnx',)
           │    └ <hailo_sdk_client.runner.client_runner.ClientRunner object at 0x7f77b5692470>
           └ <function ClientRunner.translate_onnx_model at 0x7f761a9b7490>
  File "/local/workspace/hailo_virtualenv/lib/python3.10/site-packages/hailo_sdk_client/runner/client_runner.py", line 1187, 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 280, 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 320, 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 372, in parse_model_to_hn
    hailo_nn = fuser.convert_model()
               └ <hailo_sdk_client.model_translator.fuser.fuser.HailoNNFuser object at 0x7f7619600520>
  File "/local/workspace/hailo_virtualenv/lib/python3.10/site-packages/hailo_sdk_client/model_translator/fuser/fuser.py", line 114, in convert_model
    self._finalize_fused_model()
    └ <hailo_sdk_client.model_translator.fuser.fuser.HailoNNFuser object at 0x7f7619600520>
  File "/local/workspace/hailo_virtualenv/lib/python3.10/site-packages/hailo_sdk_client/model_translator/fuser/fuser.py", line 476, in _finalize_fused_model
    self._output_graph.update_output_layers_order(self._end_node_names)
    │                                             └ <hailo_sdk_client.model_translator.fuser.fuser.HailoNNFuser object at 0x7f7619600520>
    └ <hailo_sdk_client.model_translator.fuser.fuser.HailoNNFuser object at 0x7f7619600520>
  File "/local/workspace/hailo_virtualenv/lib/python3.10/site-packages/hailo_sdk_common/hailo_nn/hailo_nn.py", line 928, in update_output_layers_order
    raise InvalidHNError(
hailo_sdk_common.hailo_nn.exceptions.InvalidHNError: The original node name /OneHot in end_node_names is missing in the HN.

Hey @Kamil_Ciebiera,

Welcome to the Hailo Community!

You’re right — DFC 3.31.0 does mention support for the OneHot operator, but it’s preview-level and comes with key limitations:

:white_check_mark: Only supported for axis = -1
:warning: PyTorch and ONNX only
:prohibited: Not fully stable for all graph positions


Why You’re Getting This Error:

InvalidHNError: The original node name /OneHot in end_node_names is missing in the HN.

This usually means the OneHot node got dropped during parsing. Likely causes:

  1. axis isn’t -1 — DFC skips it if it’s not.
  2. Output type is int64, which Hailo doesn’t support directly.
  3. It’s the last node, and DFC optimizes it away.

How to Fix It:

  1. Force axis = -1 in PyTorch:

    F.one_hot(x, num_classes=self.num_classes).to(torch.float32)
    
  2. Cast to float before exporting. Hailo prefers floating-point outputs.

  3. Don’t use OneHot as your final output node
    → Add a dummy op after it (e.g., Add + 0 or Identity) and point your end_node_names there.