UH-OH

It looks like you don’t have access to that feature yet

Contact sales to get upgraded to the full DevStudio experience.

UH-OH

It looks like you don't have access to that feature yet.

to select
to navigate
escto close
Introduction to the Chimera SDK
Chimera SDK Quick Start Guide
Chimera SDK Command Line Interface (CLI)
Tutorial: Using SDK as a Library
Tutorials & Model Demos
Model Demos
Model Demo: Llama-2 15M (Baby Llama-2)
Model Demo: QWEN3 8B End-to-End CGC and ISS Execution
Model Demo: QWEN3 Prefill All Decoders
Model Demo: DeepSeek-R1-Distill-Qwen-1.5B End-to-End CGC and ISS Execution
Model Demo: QWEN3 Single Decoder
Model Demo: Qwen2.5-0.5B INT8 Quantization Pipeline
Model Demo: ConvNeXt Detection
Model Demo: QWEN3 Prefill Decoder Validation
Model Demo: ConvNeXt Segmentation
Model Demo: Classifiers Zoo
Model Demo: Detectors Zoo - MMDetection
Model Demo: Segmentors Zoo - MMSegmentation
Model Demo: Pose Estimators Zoo - MMPose
Model Demo: Detectors3D Zoo - MMDetection3D
MODEL Demo: Optical Character Recognition (OCR) Zoo - MMOCR
Model Demo: YOLOv3 Object Detection
Model Demo: YOLOv4 Object Detection
Model Demo: YOLOv5 Detection
Model Demo: YOLOv5 Detection and Segmentation
Model Demo: YOLOR Detection
Model Demo: YOLOX End-to-End Detection
Model Demo: YOLOv7 Detection
Model Demo: YOLOv8 Detection
Model Demo: YOLOv8 Pose Estimation
Model Demo: YOLOP Detection and Segmentation
Model Demo: QAT Vision Transformer (ViT)
Model Demo: QAT Swin Transformer
Model Demo: Mediapipe Face Pipeline
Demo: DOOM Renderer on Chimera GPNPU
Model Demo: Mediapipe Hand Pipeline
Model Demo: Whisper Tiny (Encoder + Decoder)
Model Demo: L2CS Fine-Grained Gaze Estimation
Model Demo: ASVspoof2021 LA Anti-Spoofing (LFCC-LCNN-BiLSTM)
Model Demo: UNET Tumor Segmentation
Model Demo: DETR Encoder
Model Demo: FFNet Segmentation
Model Demo: Centernet Detection
Model Demo: RetinaNet End-to-End Detection
Model Demo: Blazepose Pose Estimation
Model Demo: Pose Resnet Human Pose Estimation
Model Demo: MaskRCNN Detection and Segmentation
Model Demo: Keypoint R-CNN
Model Demo: Faster R-CNN Detection
Model Demo: FCOS Detection
Model Demo: DDRNet Classificationls
Model Demo: PI0.5 End-to-End VLA Inference
Model Demo: BEVFormer End-to-End 3D Detection
Multicore Demo
Chimera LLVM C++ Compiler
Chimera SDK Licensing Policy Documentation
Glossary
Chimera Software User GuideTutorials & Model DemosModel DemosModel Demo: Mediapipe Hand Pipeline

Model Demo: Mediapipe Hand Pipeline


NOTE: The Jupyter Notebook below is included in the Chimera SDK and can be run interactively by running the following CLI command:

$ quadric sdk notebook

From the Jupyter Notebook window in your browser, select the notebook named /quadric/sdk-cli/examples/models/mediapipe/hand/MediapipeHand.ipynb.


TFLITE Mediapipe Hand Solution

MediaPipe Hands is a high-fidelity hand and finger tracking solution. It employs machine learning (ML) to infer 21 landmarks of a hand from just a single frame. Whereas current state-of-the-art approaches rely primarily on powerful desktop environments for inference, this method achieves real-time performance on a mobile phone, and even scales to multiple hands.

Hand Pipeline

MediaPipe Hands utilizes an ML pipeline consisting of multiple models working together: A palm detection model that operates on the full image and returns an oriented hand bounding box. A hand landmark model that operates on the cropped image region defined by the palm detector and returns 3D hand keypoints. This strategy is similar to that employed in MediaPipe Face solution, which uses a face detector together with a face landmark model.

Providing the accurately cropped hand image to the hand landmark model drastically reduces the need for data augmentation (e.g. rotations, translation and scale) and instead allows the network to dedicate most of its capacity towards coordinate prediction accuracy.

The following figure shows a hand solution example. When the palm detector model takes an original image in the left as an input, it detects a palm like the middle image.

The hand landmark model takes the detected palm as an input, and infers hand landmakrs as shown in the right.

Demo

Now, we are going to use actual Mediapipe models to infer palm positions and hand (finger) landmarks.

  • Models
    • Palm Detection Model
      • In this notebook, palm_detection_lite is presented.
    • Hand Landmark Model
      • In this notebook, hand_landmark_lite is presented.

Convert TFLITE to ONNX

We are going to convert TFLITE files to ONNX files.

The following packages are installed for this conversion.

  • tensorflow
  • onnxconverter-common
  • tensorflow-onnx
!pip3 install -r ../../../requirements.txt -q
WARNING: Running pip as the 'root' user can result in broken permissions and conflicting behaviour with the system package manager. It is recommended to use a virtual environment instead: https://pip.pypa.io/warnings/venv

import os
import sys
from pathlib import Path

FILE_PATH = Path(os.path.abspath(""))
sys.path.append(f"{FILE_PATH.parent}")

from examples.models.zoo.zoo_utils import download_and_extract_zip

github_list = [
    (
        "https://github.com/microsoft/onnxconverter-common/archive/refs/tags/v%s.zip",
        "1.15.0",
    ),
    ("https://github.com/onnx/tensorflow-onnx/archive/refs/tags/v%s.zip", "1.16.1"),
]

for url, version in github_list:
    url = url % (version)
    basename = url.split("/")[-5]
    filename = Path(url).name
    if not Path(basename).exists():
        download_and_extract_zip(url, filename)
        Path(f"{basename}-{version}").rename(basename)
        Path(filename).unlink(missing_ok=True)

    print(f"{basename} is setup.")
onnxconverter-common is setup.
tensorflow-onnx is setup.

The following TFLITE files are converted to ONNX files.

  • palm_detection_lite.tflite
  • hand_landmark_lite.tflite
from pathlib import Path
from mputils.convert_utils import create_onnx_from_tflite

tf_file_list = ["palm_detection_lite.tflite", "hand_landmark_lite.tflite"]

for tf_file in tf_file_list:
    file = create_onnx_from_tflite(tf_file)
    file = Path(file)
    new_file = f"{file.stem}_float32{file.suffix}".replace("-convert", "")
    os.rename(file, new_file)
    print(f"onnx is renamed to {new_file}")
Generate onnx as palm_detection_lite-convert.onnx
onnx is renamed to palm_detection_lite_float32.onnx
Generate onnx as hand_landmark_lite-convert.onnx
onnx is renamed to hand_landmark_lite_float32.onnx

Compilation of each network

At first, those two models are compiled with ChimeraJob().

from pathlib import Path
import subprocess

import tvm.contrib.epu.chimera_job.core as core
from tvm.contrib.epu.chimera_job.hw_config import DEFAULT_8_ARRAY_SIZE
from tvm.contrib.epu.chimera_job.quantize import quadric_quantize
from tvm.contrib.epu.chimera_job.chimera_job import ChimeraJob
from sdk_cli.utils import model_helpers


def get_cgc_job(
    onnx_model, input_size, calibration_folder="images", hw_config=DEFAULT_8_ARRAY_SIZE
):
    dataset_input_size = (input_size, input_size)  # an (W, H) tuple
    dataset_mean = [0, 0, 0]
    dataset_std = [1, 1, 1]

    # include quadric's cli helpers and instantiate a module to help
    mh = model_helpers.ModelHelper(dataset_input_size, dataset_mean, dataset_std)

    print("Start quantizing %s" % (onnx_model))
    quantize_result = quadric_quantize(
        onnx_model, 100, mh, calibration_folder, asymmetric_activation=True
    )

    print("Define chimerajob with %s" % (quantize_result.qmodel_path))
    cgc_job = ChimeraJob(
        model_p=quantize_result.qmodel_path,
        **hw_config.to_dict(),
    )

    print("Start network compilation")
    cgc_job.compile(quiet=True)

    return cgc_job, quantize_result.qmodel_path, mh

palm_detection_lite

To detect initial hand locations, a single-shot detector model optimized for mobile real-time is designed. Detecting hands is a decidedly complex task: lite model and full model have to work across a variety of hand sizes with a large scale span (~20x) relative to the image frame and be able to detect occluded and self-occluded hands. Whereas faces have high contrast patterns, e.g., in the eye and mouth region, the lack of such features in hands makes it comparatively difficult to detect them reliably from their visual features alone. Instead, providing additional context, like arm, body, or person features, aids accurate hand localization.

onnx_file = "palm_detection_lite_float32.onnx"
palm_detection_lite_cgc, qmodel_path, mh_detector_lite = get_cgc_job(
    onnx_file,
    input_size=192,
    calibration_folder="../../../common/calibration/face",
)

print(palm_detection_lite_cgc)
/tmp/ipykernel_98286/3325241689.py:19: DeprecationWarning: Call to deprecated class ModelHelper. ('ModelHelper' class is being deprecated. Quadric APIs have been updated to use PyTorch datasets and transforms instead.) -- Deprecated since version 24.01.
  mh = model_helpers.ModelHelper(dataset_input_size, dataset_mean, dataset_std)


Start quantizing palm_detection_lite_float32.onnx


2026-06-19 04:08 - INFO - epu - quantize - Collecting calibration data
2026-06-19 04:08 - INFO - epu - quantize - Optimized model to opset
2026-06-19 04:08 - INFO - epu - quantize - Saved optimized model to palm_detection_lite_float32_float32_opt.onnx
2026-06-19 04:08 - INFO - epu - quantize - Input shapes: [1, 3, 192, 192]. Input names: inputs0
2026-06-19 04:08 - INFO - epu - quantize - Output shapes: [[1, 2016, 18], [1, 2016, 1]]. Output names: ['outputs0', 'outputs1']
2026-06-19 04:08 - INFO - epu - quantize - applying calibration data to input: inputs0
2026-06-19 04:08 - INFO - epu - quantize - calibration set size: 8
2026-06-19 04:08 - INFO - epu - quantize - Running real quantization on this input: inputs0 with input shape: [1, 3, 192, 192]
2026-06-19 04:08 - DEBUG - epu - quantize - Full exclusion set for quantization: ['Softmax', 'Sigmoid', 'QuadricCustomOp']
2026-06-19 04:08 - DEBUG - epu - quantize - excl_nodes []
2026-06-19 04:08 - INFO - epu - quantize - Quantization started...
WARNING:root:Please use QuantFormat.QDQ for activation type QInt8 and weight type QInt8. Or it will lead to bad performance on x64.
2026-06-19 04:08 - INFO - epu - quantize - Quantization done succesfully!
2026-06-19 04:08 - INFO - epu - quantize - ONNX full precision model size: 3.72 MB
2026-06-19 04:08 - INFO - epu - quantize - ONNX quantized model size: 1.11 MB
2026-06-19 04:08 - INFO - epu - quantize - Saved quantized model to /quadric/sdk-cli/examples/models/mediapipe/hand/palm_detection_lite_opt_asym_int8_q.onnx
2026-06-19 04:08 - INFO - epu - quantize - Saved shape inferenced model to /quadric/sdk-cli/examples/models/mediapipe/hand/palm_detection_lite_opt_asym_int8_q.onnx
2026-06-19 04:08 - INFO - epu - quantize - Checking for remaining FLOAT/FLOAT16 types.
2026-06-19 04:08 - INFO - epu - quantize - Model still has FLOAT/FLOAT16 types. Creating ranges for floating point tensors using calibration data
2026-06-19 04:08 - INFO - epu - quantize - Saved tensor ranges to /quadric/sdk-cli/examples/models/mediapipe/hand/palm_detection_lite_opt_asym_int8_q.onnx.tranges


Define chimerajob with /quadric/sdk-cli/examples/models/mediapipe/hand/palm_detection_lite_opt_asym_int8_q.onnx


/tmp/ipykernel_98286/3325241689.py:27: DeprecationWarning: Specifying hardware configuration through individual parameters is deprecated. Please use hw_config parameter instead. Example: hw_cfg = HWConfig(product='QC-U', ocm_size='16MB'); ChimeraJob('model.onnx', hw_config=hw_cfg)
  cgc_job = ChimeraJob(


Start network compilation

╒═════════════════════╤══════════════════════════════════════════════════════════════════════════════════════════╕
 Module Name          palm_detection_lite_opt_asym_int8_q_QC_N_1d7_8MB_4kB_128GBps_128GBps_16_OFF_x1_x1        
├─────────────────────┼──────────────────────────────────────────────────────────────────────────────────────────┤
 ONNX File            /quadric/sdk-cli/examples/models/mediapipe/hand/palm_detection_lite_opt_asym_int8_q.onnx 
├─────────────────────┼──────────────────────────────────────────────────────────────────────────────────────────┤
 Product Target       QC-N                                                                                     
├─────────────────────┼──────────────────────────────────────────────────────────────────────────────────────────┤
 Number of Cores      1                                                                                        
├─────────────────────┼──────────────────────────────────────────────────────────────────────────────────────────┤
 ISS Clock Frequency  1.700                                                                                    
├─────────────────────┼──────────────────────────────────────────────────────────────────────────────────────────┤
 L2M Size             8MB                                                                                      
├─────────────────────┼──────────────────────────────────────────────────────────────────────────────────────────┤
 LRM Size             4kB                                                                                      
├─────────────────────┼──────────────────────────────────────────────────────────────────────────────────────────┤
 External Read BW     128GBps                                                                                  
├─────────────────────┼──────────────────────────────────────────────────────────────────────────────────────────┤
 External Write BW    128GBps                                                                                  
├─────────────────────┼──────────────────────────────────────────────────────────────────────────────────────────┤
 MACS per PE          16                                                                                       
├─────────────────────┼──────────────────────────────────────────────────────────────────────────────────────────┤
 Max L2M              0.728MB                                                                                  
├─────────────────────┼──────────────────────────────────────────────────────────────────────────────────────────┤
 Max LRM              1.500kB                                                                                  
├─────────────────────┼──────────────────────────────────────────────────────────────────────────────────────────┤
 Max Temp Ext Bytes   0.000MB                                                                                  
├─────────────────────┼──────────────────────────────────────────────────────────────────────────────────────────┤
 Network GMACs        0.283                                                                                    
╘═════════════════════╧══════════════════════════════════════════════════════════════════════════════════════════╛

╒════╤════════╤══════════╤══════════════════╤══════════════════════════╤═══════╕
     Type    Name      shape             type                      mse   
╞════╪════════╪══════════╪══════════════════╪══════════════════════════╪═══════╡
  0  Input   inputs0   [1, 3, 192, 192]  tensor[FixedPoint32<27>]  n/a   
├────┼────────┼──────────┼──────────────────┼──────────────────────────┼───────┤
  1  Output  outputs0  [1, 2016, 18]     tensor[FixedPoint32<23>]  n/a   
├────┼────────┼──────────┼──────────────────┼──────────────────────────┼───────┤
  2  Output  outputs1  [1, 2016, 1]      tensor[FixedPoint32<26>]  n/a   
╘════╧════════╧══════════╧══════════════════╧══════════════════════════╧═══════╛

As can be seen in the above figure, this model can run on less than 1MB L2M memory.

hand_landmark_lite

After the palm detection over the whole image, the subsequent hand landmark model performs precise keypoint localization of hand-knuckle coordinates inside the detected hand regions via regression, that is direct coordinate prediction. The model learns a consistent internal hand pose representation and is robust even to partially visible hands and self-occlusions.

onnx_file = "hand_landmark_lite_float32.onnx"
hand_landmark_lite_cgc, qmodel_path, mh_regressor_lite = get_cgc_job(
    onnx_file,
    input_size=224,
    calibration_folder="../images/fingers",
)

print(hand_landmark_lite_cgc)
Start quantizing hand_landmark_lite_float32.onnx


2026-06-19 04:09 - INFO - epu - quantize - Collecting calibration data
2026-06-19 04:09 - INFO - epu - quantize - Optimized model to opset
2026-06-19 04:09 - INFO - epu - quantize - Saved optimized model to hand_landmark_lite_float32_float32_opt.onnx
2026-06-19 04:09 - INFO - epu - quantize - Input shapes: [1, 3, 224, 224]. Input names: inputs0
2026-06-19 04:09 - INFO - epu - quantize - Output shapes: [[1, 63], [1, 1], [1, 1], [1, 63]]. Output names: ['outputs0', 'outputs1', 'outputs2', 'outputs3']
2026-06-19 04:09 - INFO - epu - quantize - applying calibration data to input: inputs0
2026-06-19 04:09 - INFO - epu - quantize - calibration set size: 11
2026-06-19 04:09 - INFO - epu - quantize - Running real quantization on this input: inputs0 with input shape: [1, 3, 224, 224]
2026-06-19 04:09 - INFO - epu - quantize - Quantization started...
WARNING:root:Please use QuantFormat.QDQ for activation type QInt8 and weight type QInt8. Or it will lead to bad performance on x64.
2026-06-19 04:09 - INFO - epu - quantize - Quantization done succesfully!
2026-06-19 04:09 - INFO - epu - quantize - ONNX full precision model size: 3.91 MB
2026-06-19 04:09 - INFO - epu - quantize - ONNX quantized model size: 1.11 MB
2026-06-19 04:09 - INFO - epu - quantize - Saved quantized model to /quadric/sdk-cli/examples/models/mediapipe/hand/hand_landmark_lite_opt_asym_int8_q.onnx
2026-06-19 04:09 - INFO - epu - quantize - Saved shape inferenced model to /quadric/sdk-cli/examples/models/mediapipe/hand/hand_landmark_lite_opt_asym_int8_q.onnx
2026-06-19 04:09 - INFO - epu - quantize - Checking for remaining FLOAT/FLOAT16 types.
2026-06-19 04:09 - INFO - epu - quantize - Model still has FLOAT/FLOAT16 types. Creating ranges for floating point tensors using calibration data
2026-06-19 04:09 - INFO - epu - quantize - Saved tensor ranges to /quadric/sdk-cli/examples/models/mediapipe/hand/hand_landmark_lite_opt_asym_int8_q.onnx.tranges


Define chimerajob with /quadric/sdk-cli/examples/models/mediapipe/hand/hand_landmark_lite_opt_asym_int8_q.onnx


/tmp/ipykernel_98286/3325241689.py:27: DeprecationWarning: Specifying hardware configuration through individual parameters is deprecated. Please use hw_config parameter instead. Example: hw_cfg = HWConfig(product='QC-U', ocm_size='16MB'); ChimeraJob('model.onnx', hw_config=hw_cfg)
  cgc_job = ChimeraJob(


Start network compilation

╒═════════════════════╤═════════════════════════════════════════════════════════════════════════════════════════╕
│ Module Name         │ hand_landmark_lite_opt_asym_int8_q_QC_N_1d7_8MB_4kB_128GBps_128GBps_16_OFF_x1_x1        │
├─────────────────────┼─────────────────────────────────────────────────────────────────────────────────────────┤
│ ONNX File           │ /quadric/sdk-cli/examples/models/mediapipe/hand/hand_landmark_lite_opt_asym_int8_q.onnx │
├─────────────────────┼─────────────────────────────────────────────────────────────────────────────────────────┤
│ Product Target      │ QC-N                                                                                    │
├─────────────────────┼─────────────────────────────────────────────────────────────────────────────────────────┤
│ Number of Cores     │ 1                                                                                       │
├─────────────────────┼─────────────────────────────────────────────────────────────────────────────────────────┤
│ ISS Clock Frequency │ 1.700                                                                                   │
├─────────────────────┼─────────────────────────────────────────────────────────────────────────────────────────┤
│ L2M Size            │ 8MB                                                                                     │
├─────────────────────┼─────────────────────────────────────────────────────────────────────────────────────────┤
│ LRM Size            │ 4kB                                                                                     │
├─────────────────────┼─────────────────────────────────────────────────────────────────────────────────────────┤
│ External Read BW    │ 128GBps                                                                                 │
├─────────────────────┼─────────────────────────────────────────────────────────────────────────────────────────┤
│ External Write BW   │ 128GBps                                                                                 │
├─────────────────────┼─────────────────────────────────────────────────────────────────────────────────────────┤
│ MACS per PE         │ 16                                                                                      │
├─────────────────────┼─────────────────────────────────────────────────────────────────────────────────────────┤
│ Max L2M             │ 1.160MB                                                                                 │
├─────────────────────┼─────────────────────────────────────────────────────────────────────────────────────────┤
│ Max LRM             │ 1.875kB                                                                                 │
├─────────────────────┼─────────────────────────────────────────────────────────────────────────────────────────┤
│ Max Temp Ext Bytes  │ 0.000MB                                                                                 │
├─────────────────────┼─────────────────────────────────────────────────────────────────────────────────────────┤
│ Network GMACs       │ 0.146                                                                                   │
╘═════════════════════╧═════════════════════════════════════════════════════════════════════════════════════════╛

╒════╤════════╤══════════╤══════════════════╤══════════════════════════╤═══════╕
│    │ Type   │ Name     │ shape            │ type                     │ mse   │
╞════╪════════╪══════════╪══════════════════╪══════════════════════════╪═══════╡
│  0 │ Input  │ inputs0  │ [1, 3, 224, 224] │ tensor[FixedPoint32<27>] │ n/a   │
├────┼────────┼──────────┼──────────────────┼──────────────────────────┼───────┤
│  1 │ Output │ outputs0 │ [1, 63]          │ tensor[FixedPoint32<23>] │ n/a   │
├────┼────────┼──────────┼──────────────────┼──────────────────────────┼───────┤
│  2 │ Output │ outputs1 │ [1, 1]           │ tensor[FixedPoint32<31>] │ n/a   │
├────┼────────┼──────────┼──────────────────┼──────────────────────────┼───────┤
│  3 │ Output │ outputs2 │ [1, 1]           │ tensor[FixedPoint32<31>] │ n/a   │
├────┼────────┼──────────┼──────────────────┼──────────────────────────┼───────┤
│  4 │ Output │ outputs3 │ [1, 63]          │ tensor[FixedPoint32<31>] │ n/a   │
╘════╧════════╧══════════╧══════════════════╧══════════════════════════╧═══════╛

As can be seen in the above figure, this model can run less than 2MB L2M memory.

Inference

Palm Detection

By using the palm detection model (palm_detection_lite), palm positions are detected from input images with the following patterns.

  • Int8 Quantized ONNX: palm_detection_lite_cgc
  • ISS: palm_detection_lite_cgc
import os
import sys
from pathlib import Path
from typing import Tuple

import onnx
import matplotlib.pyplot as plt
import numpy as np
import torch
import cv2
import glob

from sdk_cli.node_builtins.classical.normalize import normalize
from sdk_cli.node_builtins.classical.object_detector_postprocessing import (
    MEDIAPIPE_FULL_RANGE_HAND_DETECTOR_PARAMETERS,
    ObjectDetectorParameters,
    object_detector_postprocessing,
)
from sdk_cli.node_builtins.classical.resize_pad import resize_pad
from sdk_cli.node_builtins.inputs.image import load_image

FILE_PATH = Path(os.path.abspath(""))
sys.path.append(f"{FILE_PATH.parent}")

from sdk_cli.lib.inference import InferenceEngine

all_images = ["../../../common/calibration/face/nigel_daniel.jpg"]
NUM_IMAGES = len(all_images)
THREADS = min(NUM_IMAGES, 6)

hand_detector_parameters: ObjectDetectorParameters = MEDIAPIPE_FULL_RANGE_HAND_DETECTOR_PARAMETERS

engines = {
    InferenceEngine.CHIMERA_ORT_INT8: palm_detection_lite_cgc,
    InferenceEngine.CHIMERA_ISS_INT8: palm_detection_lite_cgc,
}


def preprocess_detector(image_path: str, input_image_size: Tuple[int, int]):
    """Preprocess stuff."""
    original_image = load_image(image_path)
    input_image, scale, pad = resize_pad(original_image, input_image_size)
    # input_image is channels first, usually channels last here
    input_image = normalize(input_image, np.array([0.0, 0.0, 0.0]), np.array([1.0, 1.0, 1.0]))
    # input_image is channels first and has a batch dimension

    assert input_image.shape[1] == 3, "Assertion failed"
    assert input_image.shape[2] == input_image_size[1], "Assertion failed"
    assert input_image.shape[3] == input_image_size[0], "Assertion failed"

    return original_image, input_image.astype(np.float32), scale, pad


def postprocess_detector(
    original_image: np.ndarray,
    out0: np.ndarray,
    out1: np.ndarray,
    scale: float,
    pad: Tuple[int, int],
    object_detector_parametrs: ObjectDetectorParameters,
) -> Tuple[np.ndarray, torch.Tensor, torch.Tensor, torch.Tensor, torch.Tensor]:
    """Postprocess stuff."""
    copy_of_original_image = original_image.copy()

    img, affine, box, obj_detections = object_detector_postprocessing(
        copy_of_original_image, out0, out1, scale, pad, object_detector_parametrs
    )

    return (
        np.moveaxis(copy_of_original_image, 0, -1),
        torch.from_numpy(img),
        torch.from_numpy(affine),
        torch.from_numpy(box),
        torch.from_numpy(obj_detections),
    )


outputs_per_inference_engine = dict()
for inference_engine in engines.keys():
    all_preprocessed_inputs = []
    outputs_per_inference_engine[inference_engine] = []
    for index, image in enumerate(all_images):
        original_image, transformed_image, scale, pad = preprocess_detector(
            image, hand_detector_parameters.input_image_size
        )

        if inference_engine == InferenceEngine.ONNXRUNTIME_FP32:
            input_name = engines[inference_engine].get_inputs()[0].name
            inference_outputs = engines[inference_engine].run(None, {input_name: transformed_image})
            outputs = postprocess_detector(
                original_image,
                *inference_outputs,
                scale=scale,
                pad=pad,
                object_detector_parametrs=hand_detector_parameters,
            )

            outputs_per_inference_engine[inference_engine].append(outputs)

        else:  # if inference_engine != InferenceEngine.ONNXRUNTIME_FP32:
            all_preprocessed_inputs.append((original_image, transformed_image, scale, pad))

    if inference_engine != InferenceEngine.ONNXRUNTIME_FP32:
        all_model_inputs = []
        for preprocessed_input in all_preprocessed_inputs:
            all_model_inputs.append({"inputs0": preprocessed_input[1]})

        if inference_engine == InferenceEngine.CHIMERA_ORT_INT8:
            all_inference_outputs = engines[inference_engine].run_batch_ort_harness(
                inputs=all_model_inputs, threads=THREADS
            )

        elif inference_engine == InferenceEngine.CHIMERA_ISS_INT8:
            all_inference_outputs = engines[inference_engine].run_batch_inference_harness(
                inputs=all_model_inputs, threads=THREADS
            )
        else:
            raise ValueError(f"{inference_engine} is not implemented.")

        assert len(all_inference_outputs) == len(
            all_model_inputs
        ), f"Length mismatch: {len(all_inference_outputs)} vs {len(all_model_inputs)}."

        for index, inference_outputs in enumerate(all_inference_outputs):
            original_image = all_preprocessed_inputs[index][0]
            scale = all_preprocessed_inputs[index][2]
            pad = all_preprocessed_inputs[index][3]
            outputs = postprocess_detector(
                original_image,
                inference_outputs["outputs0"],
                inference_outputs["outputs1"],
                scale=scale,
                pad=pad,
                object_detector_parametrs=hand_detector_parameters,
            )

            outputs_per_inference_engine[inference_engine].append(outputs)
100%|████████████████████████████████████████████| 1/1 [00:00<00:00, 22.90it/s]
  0%|                                                    | 0/1 [00:00<?, ?it/s]
  0%|                                                                        | 0/27 [00:00<?, ?it/s]
FILM 1/27:   4%|█▉                                                 | 1/27 [00:00<00:00, 4485.89it/s]
FILM 1/27:   4%|█▉                                                 | 1/27 [00:00<00:00, 1309.90it/s]
FILM 1/27:   7%|███▉                                                 | 2/27 [00:00<00:09,  2.53it/s]
FILM 2/27:   7%|███▉                                                 | 2/27 [00:00<00:09,  2.53it/s]
FILM 2/27:   7%|███▉                                                 | 2/27 [00:00<00:09,  2.53it/s]
FILM 2/27:  11%|█████▉                                               | 3/27 [00:02<00:18,  1.31it/s]
FILM 3/27:  11%|█████▉                                               | 3/27 [00:02<00:18,  1.31it/s]
FILM 3/27:  11%|█████▉                                               | 3/27 [00:02<00:18,  1.31it/s]
FILM 3/27:  15%|███████▊                                             | 4/27 [00:03<00:22,  1.04it/s]
FILM 4/27:  15%|███████▊                                             | 4/27 [00:03<00:22,  1.04it/s]
FILM 4/27:  15%|███████▊                                             | 4/27 [00:03<00:22,  1.04it/s]
FILM 4/27:  19%|█████████▊                                           | 5/27 [00:04<00:24,  1.10s/it]
FILM 5/27:  19%|█████████▊                                           | 5/27 [00:04<00:24,  1.10s/it]
FILM 5/27:  19%|█████████▊                                           | 5/27 [00:04<00:24,  1.10s/it]
FILM 5/27:  22%|███████████▊                                         | 6/27 [00:05<00:17,  1.17it/s]
FILM 6/27:  22%|███████████▊                                         | 6/27 [00:05<00:17,  1.17it/s]
FILM 6/27:  22%|███████████▊                                         | 6/27 [00:05<00:17,  1.17it/s]
FILM 6/27:  26%|█████████████▋                                       | 7/27 [00:05<00:17,  1.14it/s]
FILM 7/27:  26%|█████████████▋                                       | 7/27 [00:05<00:17,  1.14it/s]
FILM 7/27:  26%|█████████████▋                                       | 7/27 [00:05<00:17,  1.14it/s]
FILM 7/27:  30%|███████████████▋                                     | 8/27 [00:06<00:15,  1.24it/s]
FILM 8/27:  30%|███████████████▋                                     | 8/27 [00:06<00:15,  1.24it/s]
FILM 8/27:  30%|███████████████▋                                     | 8/27 [00:06<00:15,  1.24it/s]
FILM 8/27:  33%|█████████████████▋                                   | 9/27 [00:07<00:13,  1.31it/s]
FILM 9/27:  33%|█████████████████▋                                   | 9/27 [00:07<00:13,  1.31it/s]
FILM 9/27:  33%|█████████████████▋                                   | 9/27 [00:07<00:13,  1.31it/s]
FILM 9/27:  37%|███████████████████▎                                | 10/27 [00:07<00:09,  1.70it/s]
FILM 10/27:  37%|██████████████████▉                                | 10/27 [00:07<00:09,  1.70it/s]
FILM 10/27:  37%|██████████████████▉                                | 10/27 [00:07<00:09,  1.70it/s]
FILM 10/27:  41%|████████████████████▊                              | 11/27 [00:07<00:08,  1.80it/s]
FILM 11/27:  41%|████████████████████▊                              | 11/27 [00:07<00:08,  1.80it/s]
FILM 11/27:  41%|████████████████████▊                              | 11/27 [00:07<00:08,  1.80it/s]
FILM 11/27:  44%|██████████████████████▋                            | 12/27 [00:08<00:07,  2.02it/s]
FILM 12/27:  44%|██████████████████████▋                            | 12/27 [00:08<00:07,  2.02it/s]
FILM 12/27:  44%|██████████████████████▋                            | 12/27 [00:08<00:07,  2.02it/s]
FILM 12/27:  48%|████████████████████████▌                          | 13/27 [00:08<00:06,  2.19it/s]
FILM 13/27:  48%|████████████████████████▌                          | 13/27 [00:08<00:06,  2.19it/s]
FILM 13/27:  48%|████████████████████████▌                          | 13/27 [00:08<00:06,  2.19it/s]
FILM 13/27:  52%|██████████████████████████▍                        | 14/27 [00:08<00:04,  2.68it/s]
FILM 14/27:  52%|██████████████████████████▍                        | 14/27 [00:08<00:04,  2.68it/s]
FILM 14/27:  52%|██████████████████████████▍                        | 14/27 [00:08<00:04,  2.68it/s]
FILM 14/27:  56%|████████████████████████████▎                      | 15/27 [00:09<00:04,  2.52it/s]
FILM 15/27:  56%|████████████████████████████▎                      | 15/27 [00:09<00:04,  2.52it/s]
FILM 15/27:  56%|████████████████████████████▎                      | 15/27 [00:09<00:04,  2.52it/s]
FILM 15/27:  59%|██████████████████████████████▏                    | 16/27 [00:09<00:04,  2.67it/s]
FILM 16/27:  59%|██████████████████████████████▏                    | 16/27 [00:09<00:04,  2.67it/s]
FILM 16/27:  59%|██████████████████████████████▏                    | 16/27 [00:09<00:04,  2.67it/s]
FILM 16/27:  63%|████████████████████████████████                   | 17/27 [00:10<00:03,  2.73it/s]
FILM 17/27:  63%|████████████████████████████████                   | 17/27 [00:10<00:03,  2.73it/s]
FILM 17/27:  63%|████████████████████████████████                   | 17/27 [00:10<00:03,  2.73it/s]
FILM 18/27:  67%|██████████████████████████████████                 | 18/27 [00:10<00:03,  2.73it/s]
FILM 18/27:  67%|██████████████████████████████████                 | 18/27 [00:10<00:03,  2.73it/s]
FILM 18/27:  70%|███████████████████████████████████▉               | 19/27 [00:10<00:02,  3.31it/s]
FILM 19/27:  70%|███████████████████████████████████▉               | 19/27 [00:10<00:02,  3.31it/s]
FILM 19/27:  70%|███████████████████████████████████▉               | 19/27 [00:10<00:02,  3.31it/s]
FILM 19/27:  74%|█████████████████████████████████████▊             | 20/27 [00:11<00:02,  2.70it/s]
FILM 20/27:  74%|█████████████████████████████████████▊             | 20/27 [00:11<00:02,  2.70it/s]
FILM 20/27:  74%|█████████████████████████████████████▊             | 20/27 [00:11<00:02,  2.70it/s]
FILM 20/27:  78%|███████████████████████████████████████▋           | 21/27 [00:11<00:02,  2.68it/s]
FILM 21/27:  78%|███████████████████████████████████████▋           | 21/27 [00:11<00:02,  2.68it/s]
FILM 21/27:  78%|███████████████████████████████████████▋           | 21/27 [00:11<00:02,  2.68it/s]
FILM 21/27:  81%|█████████████████████████████████████████▌         | 22/27 [00:11<00:02,  2.39it/s]
FILM 22/27:  81%|█████████████████████████████████████████▌         | 22/27 [00:11<00:02,  2.39it/s]
FILM 22/27:  81%|█████████████████████████████████████████▌         | 22/27 [00:11<00:02,  2.39it/s]
FILM 22/27:  85%|███████████████████████████████████████████▍       | 23/27 [00:12<00:01,  2.02it/s]
FILM 23/27:  85%|███████████████████████████████████████████▍       | 23/27 [00:12<00:01,  2.02it/s]
FILM 23/27:  85%|███████████████████████████████████████████▍       | 23/27 [00:12<00:01,  2.02it/s]
FILM 23/27:  89%|█████████████████████████████████████████████▎     | 24/27 [00:13<00:01,  2.04it/s]
FILM 24/27:  89%|█████████████████████████████████████████████▎     | 24/27 [00:13<00:01,  2.04it/s]
FILM 24/27:  89%|█████████████████████████████████████████████▎     | 24/27 [00:13<00:01,  2.04it/s]
FILM 24/27:  93%|███████████████████████████████████████████████▏   | 25/27 [00:13<00:00,  2.48it/s]
FILM 25/27:  93%|███████████████████████████████████████████████▏   | 25/27 [00:13<00:00,  2.48it/s]
FILM 25/27:  93%|███████████████████████████████████████████████▏   | 25/27 [00:13<00:00,  2.48it/s]
FILM 26/27:  96%|█████████████████████████████████████████████████  | 26/27 [00:13<00:00,  2.48it/s]
FILM 26/27:  96%|█████████████████████████████████████████████████  | 26/27 [00:13<00:00,  2.48it/s]
FILM 27/27: 100%|███████████████████████████████████████████████████| 27/27 [00:13<00:00,  2.48it/s]
FILM 27/27: 100%|███████████████████████████████████████████████████| 27/27 [00:13<00:00,  2.02it/s]
100%|████████████████████████████████████████████| 1/1 [00:13<00:00, 13.69s/it]
print(palm_detection_lite_cgc)
palm_detection_lite_cgc.plot_run_statistics()
╒═════════════════════╤══════════════════════════════════════════════════════════════════════════════════════════╕
 Module Name          palm_detection_lite_opt_asym_int8_q_QC_N_1d7_8MB_4kB_128GBps_128GBps_16_OFF_x1_x1        
├─────────────────────┼──────────────────────────────────────────────────────────────────────────────────────────┤
 ONNX File            /quadric/sdk-cli/examples/models/mediapipe/hand/palm_detection_lite_opt_asym_int8_q.onnx 
├─────────────────────┼──────────────────────────────────────────────────────────────────────────────────────────┤
 Product Target       QC-N                                                                                     
├─────────────────────┼──────────────────────────────────────────────────────────────────────────────────────────┤
 Number of Cores      1                                                                                        
├─────────────────────┼──────────────────────────────────────────────────────────────────────────────────────────┤
 ISS Clock Frequency  1.700                                                                                    
├─────────────────────┼──────────────────────────────────────────────────────────────────────────────────────────┤
 L2M Size             8MB                                                                                      
├─────────────────────┼──────────────────────────────────────────────────────────────────────────────────────────┤
 LRM Size             4kB                                                                                      
├─────────────────────┼──────────────────────────────────────────────────────────────────────────────────────────┤
 External Read BW     128GBps                                                                                  
├─────────────────────┼──────────────────────────────────────────────────────────────────────────────────────────┤
 External Write BW    128GBps                                                                                  
├─────────────────────┼──────────────────────────────────────────────────────────────────────────────────────────┤
 MACS per PE          16                                                                                       
├─────────────────────┼──────────────────────────────────────────────────────────────────────────────────────────┤
 Max L2M              0.728MB                                                                                  
├─────────────────────┼──────────────────────────────────────────────────────────────────────────────────────────┤
 Max LRM              1.500kB                                                                                  
├─────────────────────┼──────────────────────────────────────────────────────────────────────────────────────────┤
 Max Temp Ext Bytes   0.000MB                                                                                  
├─────────────────────┼──────────────────────────────────────────────────────────────────────────────────────────┤
 Network GMACs        0.283                                                                                    
╘═════════════════════╧══════════════════════════════════════════════════════════════════════════════════════════╛

╒════╤════════╤══════════╤══════════════════╤══════════════════════════╤════════╕
     Type    Name      shape             type                      mse    
╞════╪════════╪══════════╪══════════════════╪══════════════════════════╪════════╡
  0  Input   inputs0   [1, 3, 192, 192]  tensor[FixedPoint32<27>]  n/a    
├────┼────────┼──────────┼──────────────────┼──────────────────────────┼────────┤
  1  Output  outputs0  [1, 2016, 18]     tensor[FixedPoint32<23>]  12.437 
├────┼────────┼──────────┼──────────────────┼──────────────────────────┼────────┤
  2  Output  outputs1  [1, 2016, 1]      tensor[FixedPoint32<26>]  0.866  
╘════╧════════╧══════════╧══════════════════╧══════════════════════════╧════════╛

Post-ISS Report 1.7 GHz ***
Fully placed-and-routed gate simulation: 
╒══════════════════════════════════╤═════════╕
 Latency (ms)                      2.52    
├──────────────────────────────────┼─────────┤
 FPS                               396.95  
├──────────────────────────────────┼─────────┤
 Average Power @ 3nm SSGNP (mW)    219.00  
├──────────────────────────────────┼─────────┤
 FPS per Watt @ 3nm SSGNP (FPS/W)  1812.56 
├──────────────────────────────────┼─────────┤
 Ext Rd Bytes (MB)                 1.76    
├──────────────────────────────────┼─────────┤
 Ext Wr Bytes (MB)                 0.15    
├──────────────────────────────────┼─────────┤
 Avg Ext Rd BW (GBps)              0.68    
├──────────────────────────────────┼─────────┤
 Avg Ext Wr BW (GBps)              0.06    
├──────────────────────────────────┼─────────┤
 MAC Utilization                   6.46%   
╘══════════════════════════════════╧═════════╛
*** Data generated using 7nm SSGNP gatesim and scaled to 3nm

[SDK-CLI] : TotalCycles: 4,282,654
[SDK-CLI] : Executions/second: 396.95

compute      : ▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇ 2.578M
data_array   : ▇▇▇▇▇▇▇▇▇▇▇▇▇ 697.334K
mac          : ▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇ 836.316K
data_external:  14.166K
data_ocm     : ▇▇ 151.505K

for more information check run directory: /quadric/sdk-cli/examples/models/mediapipe/hand/ccl_build/palm_detection_lite_opt_asym_int8_q_QC_N_1d7_8MB_4kB_128GBps_128GBps_16_OFF_x1_x1/run/20260619_041054_cf7af2


2026-06-19 04:11 - INFO - epu - chimera_job - Combined plots generated and saved to: 
/quadric/sdk-cli/examples/models/mediapipe/hand/ccl_build/palm_detection_lite_opt_asym_int8_q_QC_N_1d7_8MB_4kB_128GBps_128GBps_16_OFF_x1_x1/run/20260619_041054_cf7af2/data/palm_detection_lite_opt_asym_int8_q_QC_N_1d7_8MB_4kB_128GBps_128GBps_16_OFF_x1_x1.combined.png





'/quadric/sdk-cli/examples/models/mediapipe/hand/ccl_build/palm_detection_lite_opt_asym_int8_q_QC_N_1d7_8MB_4kB_128GBps_128GBps_16_OFF_x1_x1/run/20260619_041054_cf7af2/data'

from sdk_cli.node_builtins.outputs.bounding_box_visualizer import (
    draw_detections,
    draw_roi,
)


def draw_detected_hands(
    image: torch.Tensor, boxes: torch.Tensor, detections: torch.Tensor
) -> np.ndarray:
    """Draw detected bounding boxes onto original image."""
    image_with_drawings = np.array(image.copy())
    draw_roi(image=image_with_drawings, regions_of_interest=boxes)
    draw_detections(image=image_with_drawings, detections=detections)

    return image_with_drawings


all_opts = dict()
for inference_engine in outputs_per_inference_engine.keys():
    all_opts[inference_engine] = []

for outputs in zip(
    *[
        outputs_per_inference_engine[inference_engine]
        for inference_engine in outputs_per_inference_engine.keys()
    ]
):
    ax, idx = dict(), 0
    fig = plt.figure(figsize=(4 * len(outputs_per_inference_engine.keys()), 4), tight_layout=True)

    for output, inference_engine in zip(outputs, outputs_per_inference_engine.keys()):
        idx += 1
        ax[idx] = fig.add_subplot(int("1%s%s" % (len(outputs_per_inference_engine.keys()), idx)))
        all_opts[inference_engine].append(output)
        ax[idx].imshow(draw_detected_hands(output[0].astype(np.uint8), output[3], output[4]))
        ax[idx].set_title(f"Detected Palms: {str(inference_engine).upper()}")
        ax[idx].axis("off")

    fig.show()

Hand Landmark

By using the detected palms above, hand landmakrs are detected with hand_landmark_lite. Like the palm detection, the following patterns are experimented.

  • Int8 Quantized ONNX: hand_landmark_lite_cgc
  • ISS: hand_landmark_lite_cgc

Then, by using the drawing function, those landmarks are drawn on the original images.

from typing import Optional

from PIL import Image


from sdk_cli.node_builtins.classical.denormalize_landmarks import (
    denormalize_landmarks,
)
from sdk_cli.node_builtins.classical.object_detector_postprocessing import (
    MEDIAPIPE_HAND_DETECTOR_BOUNDING_BOX_REGRESSION_PARAMETERS,
    ObjectDetectorParameters,
)
from sdk_cli.node_builtins.classical.resize.resize import one_step_resize


def preprocess_landmark(image_path: str, input_image_size: Tuple[int, int]):
    """Preprocess some stuff."""
    original_image = load_image(image_path)  # (224, 224)
    transformed_image = one_step_resize(np.moveaxis(original_image, 0, -1), (192, 192, 3)).astype(
        np.float32
    )

    transformed_image = normalize(
        np.moveaxis(transformed_image, -1, 0),
        np.array([0.0, 0.0, 0.0]),
        np.array([1.0, 1.0, 1.0]),
    )

    return original_image, transformed_image


hand_regressor_parameters: ObjectDetectorParameters = (
    MEDIAPIPE_HAND_DETECTOR_BOUNDING_BOX_REGRESSION_PARAMETERS
)

engines = {
    InferenceEngine.CHIMERA_ORT_INT8: hand_landmark_lite_cgc,
    InferenceEngine.CHIMERA_ISS_INT8: hand_landmark_lite_cgc,
}


detector_outputs_for_all_ainference_engines = []
for index in range(len(all_images)):
    detector_outputs_for_all_ainference_engines.append(
        {inference_engine: all_opts[inference_engine][index] for inference_engine in engines.keys()}
    )


landmark_outputs_per_inference_engine = dict()
for inference_engine in engines.keys():
    all_preprocessed_inputs = []
    landmark_outputs_per_inference_engine[inference_engine] = []
    for detector_output in [
        detector_output[inference_engine]
        for detector_output in detector_outputs_for_all_ainference_engines
    ]:
        original_image, detector_outputs, affines, boxes, detections = detector_output

        landmark_model_inputs = np.expand_dims(
            np.moveaxis(
                cv2.resize(
                    np.moveaxis(detector_outputs.numpy()[0], 0, -1),
                    hand_regressor_parameters.input_image_size,
                ),
                -1,
                0,
            ),
            axis=0,
        )

        landmark_outputs, flag_outputs = [], []
        if inference_engine == InferenceEngine.ONNXRUNTIME_FP32:
            for landmark_model_input, affine in zip(landmark_model_inputs, affines):
                input_name = engines[inference_engine].get_inputs()[0].name
                inference_outputs = engines[inference_engine].run(
                    None, {input_name: np.expand_dims(landmark_model_input, axis=0)}
                )

                outputs = denormalize_landmarks(
                    original_image,
                    inference_outputs[0],
                    hand_regressor_parameters.input_image_size,
                    row_size=hand_regressor_parameters.row_size,
                    affines=affine,
                )

                landmark_outputs.append(outputs[0])
                flag_outputs.append(inference_outputs[1][0])

        else:  # if inference_engine != InferenceEngine.ONNXRUNTIME_FP32:
            all_model_inputs = []
            for detector_output in detector_outputs.numpy():
                landmark_model_input = np.expand_dims(
                    np.moveaxis(
                        cv2.resize(
                            np.moveaxis(detector_output, 0, -1),
                            hand_regressor_parameters.input_image_size,
                        ),
                        -1,
                        0,
                    ),
                    axis=0,
                )

                all_model_inputs.append({"inputs0": landmark_model_input})

            if inference_engine == InferenceEngine.CHIMERA_ORT_INT8:
                all_inference_outputs = engines[inference_engine].run_batch_ort_harness(
                    inputs=all_model_inputs, threads=min(len(all_model_inputs), 6)
                )

            elif inference_engine == InferenceEngine.CHIMERA_ISS_INT8:
                all_inference_outputs = engines[inference_engine].run_batch_inference_harness(
                    inputs=all_model_inputs, threads=min(len(all_model_inputs), 6)
                )
            else:
                raise ValueError(f"{inference_engine} is not implemented.")

            for inference_outputs, affine in zip(all_inference_outputs, affines):
                outputs = denormalize_landmarks(
                    original_image,
                    inference_outputs["outputs0"],
                    hand_regressor_parameters.input_image_size,
                    row_size=hand_regressor_parameters.row_size,
                    affines=affine,
                )

                landmark_outputs.append(outputs[0])
                flag_outputs.append(inference_outputs["outputs1"][0])

        landmark_outputs_per_inference_engine[inference_engine].append(
            (
                original_image,
                np.stack(landmark_outputs),
                np.stack(flag_outputs),
                boxes,
                detections,
            )
        )
100%|████████████████████████████████████████████| 1/1 [00:00<00:00, 33.18it/s]
  0%|                                                    | 0/1 [00:00<?, ?it/s]
  0%|                                                                        | 0/16 [00:00<?, ?it/s]
FILM 1/16:   6%|███▏                                               | 1/16 [00:00<00:00, 5433.04it/s]
FILM 1/16:   6%|███▏                                               | 1/16 [00:00<00:00, 1582.76it/s]
FILM 1/16:  12%|██████▋                                              | 2/16 [00:02<00:14,  1.05s/it]
FILM 2/16:  12%|██████▋                                              | 2/16 [00:02<00:14,  1.05s/it]
FILM 2/16:  12%|██████▋                                              | 2/16 [00:02<00:14,  1.05s/it]
FILM 2/16:  19%|█████████▉                                           | 3/16 [00:02<00:11,  1.11it/s]
FILM 3/16:  19%|█████████▉                                           | 3/16 [00:02<00:11,  1.11it/s]
FILM 3/16:  19%|█████████▉                                           | 3/16 [00:02<00:11,  1.11it/s]
FILM 3/16:  25%|█████████████▎                                       | 4/16 [00:04<00:13,  1.09s/it]
FILM 4/16:  25%|█████████████▎                                       | 4/16 [00:04<00:13,  1.09s/it]
FILM 4/16:  25%|█████████████▎                                       | 4/16 [00:04<00:13,  1.09s/it]
FILM 4/16:  31%|████████████████▌                                    | 5/16 [00:04<00:09,  1.15it/s]
FILM 5/16:  31%|████████████████▌                                    | 5/16 [00:04<00:09,  1.15it/s]
FILM 5/16:  31%|████████████████▌                                    | 5/16 [00:04<00:09,  1.15it/s]
FILM 5/16:  38%|███████████████████▉                                 | 6/16 [00:05<00:07,  1.33it/s]
FILM 6/16:  38%|███████████████████▉                                 | 6/16 [00:05<00:07,  1.33it/s]
FILM 6/16:  38%|███████████████████▉                                 | 6/16 [00:05<00:07,  1.33it/s]
FILM 6/16:  44%|███████████████████████▏                             | 7/16 [00:05<00:05,  1.54it/s]
FILM 7/16:  44%|███████████████████████▏                             | 7/16 [00:05<00:05,  1.54it/s]
FILM 7/16:  44%|███████████████████████▏                             | 7/16 [00:05<00:05,  1.54it/s]
FILM 7/16:  50%|██████████████████████████▌                          | 8/16 [00:05<00:04,  1.92it/s]
FILM 8/16:  50%|██████████████████████████▌                          | 8/16 [00:05<00:04,  1.92it/s]
FILM 8/16:  50%|██████████████████████████▌                          | 8/16 [00:05<00:04,  1.92it/s]
FILM 8/16:  56%|█████████████████████████████▊                       | 9/16 [00:06<00:03,  2.21it/s]
FILM 9/16:  56%|█████████████████████████████▊                       | 9/16 [00:06<00:03,  2.21it/s]
FILM 9/16:  56%|█████████████████████████████▊                       | 9/16 [00:06<00:03,  2.21it/s]
FILM 9/16:  62%|████████████████████████████████▌                   | 10/16 [00:06<00:02,  2.35it/s]
FILM 10/16:  62%|███████████████████████████████▉                   | 10/16 [00:06<00:02,  2.35it/s]
FILM 10/16:  62%|███████████████████████████████▉                   | 10/16 [00:06<00:02,  2.35it/s]
FILM 10/16:  69%|███████████████████████████████████                | 11/16 [00:06<00:02,  2.43it/s]
FILM 11/16:  69%|███████████████████████████████████                | 11/16 [00:06<00:02,  2.43it/s]
FILM 11/16:  69%|███████████████████████████████████                | 11/16 [00:06<00:02,  2.43it/s]
FILM 11/16:  75%|██████████████████████████████████████▎            | 12/16 [00:07<00:02,  1.82it/s]
FILM 12/16:  75%|██████████████████████████████████████▎            | 12/16 [00:07<00:02,  1.82it/s]
FILM 12/16:  75%|██████████████████████████████████████▎            | 12/16 [00:07<00:02,  1.82it/s]
FILM 13/16:  81%|█████████████████████████████████████████▍         | 13/16 [00:07<00:01,  1.82it/s]
FILM 13/16:  81%|█████████████████████████████████████████▍         | 13/16 [00:07<00:01,  1.82it/s]
FILM 14/16:  88%|████████████████████████████████████████████▋      | 14/16 [00:07<00:01,  1.82it/s]
FILM 14/16:  88%|████████████████████████████████████████████▋      | 14/16 [00:07<00:01,  1.82it/s]
FILM 15/16:  94%|███████████████████████████████████████████████▊   | 15/16 [00:07<00:00,  1.82it/s]
FILM 15/16:  94%|███████████████████████████████████████████████▊   | 15/16 [00:07<00:00,  1.82it/s]
FILM 16/16: 100%|███████████████████████████████████████████████████| 16/16 [00:07<00:00,  1.82it/s]
FILM 16/16: 100%|███████████████████████████████████████████████████| 16/16 [00:07<00:00,  2.06it/s]
100%|████████████████████████████████████████████| 1/1 [00:08<00:00,  8.13s/it]
from typing import List, Optional

from sdk_cli.node_builtins.outputs.bounding_box_visualizer import (
    draw_detections,
    draw_landmarks,
    draw_roi,
)


def draw_detected_hand_landmarks(
    original_image: torch.Tensor,
    all_landmarks_per_image: torch.Tensor,
    all_flags_per_image: torch.Tensor,
    connections: List[Tuple[int, int]],
    draw_threshold: float,
    boxes: Optional[torch.Tensor] = None,
    detections: Optional[torch.Tensor] = None,
    landmark_cut: Optional[int] = None,
) -> np.ndarray:
    """Draw for fun."""
    image_with_drawings = np.array(original_image.copy())

    for all_landmarks_per_detection, all_flags_per_detection in zip(
        all_landmarks_per_image, all_flags_per_image
    ):
        for landmark, flag in zip(
            np.expand_dims(all_landmarks_per_detection, 0), all_flags_per_detection
        ):
            if flag > draw_threshold:
                landmark_to_draw = (
                    all_landmarks_per_detection[:landmark_cut, :]
                    if landmark_cut
                    else all_landmarks_per_detection
                )
                draw_landmarks(
                    image=image_with_drawings,
                    points=landmark_to_draw[:, :2],
                    connections=connections,
                )

    if boxes is not None:
        draw_roi(image=image_with_drawings, regions_of_interest=boxes)

    if detections is not None:
        draw_detections(image=image_with_drawings, detections=detections)

    return image_with_drawings


for landmark_outputs in zip(
    *[
        landmark_outputs_per_inference_engine[inference_engine]
        for inference_engine in landmark_outputs_per_inference_engine.keys()
    ]
):
    ax, idx = dict(), 0
    fig = plt.figure(
        figsize=(4 * len(landmark_outputs_per_inference_engine.keys()), 4),
        tight_layout=True,
    )

    for output, inference_engine in zip(
        landmark_outputs, landmark_outputs_per_inference_engine.keys()
    ):
        idx += 1
        ax[idx] = fig.add_subplot(
            int("1%s%s" % (len(landmark_outputs_per_inference_engine.keys()), idx))
        )
        ax[idx].imshow(
            draw_detected_hand_landmarks(
                output[0].astype(np.uint8),
                output[1],
                output[2],
                hand_regressor_parameters.connections,
                hand_regressor_parameters.draw_threshold,
                boxes=output[3],
                detections=output[4],
            )
        )
        ax[idx].set_title(f"Hand Landmarks: {str(inference_engine).upper()}")
        ax[idx].axis("off")

    fig.show()

print(hand_landmark_lite_cgc)
hand_landmark_lite_cgc.plot_run_statistics()
╒═════════════════════╤═════════════════════════════════════════════════════════════════════════════════════════╕
│ Module Name         │ hand_landmark_lite_opt_asym_int8_q_QC_N_1d7_8MB_4kB_128GBps_128GBps_16_OFF_x1_x1        │
├─────────────────────┼─────────────────────────────────────────────────────────────────────────────────────────┤
│ ONNX File           │ /quadric/sdk-cli/examples/models/mediapipe/hand/hand_landmark_lite_opt_asym_int8_q.onnx │
├─────────────────────┼─────────────────────────────────────────────────────────────────────────────────────────┤
│ Product Target      │ QC-N                                                                                    │
├─────────────────────┼─────────────────────────────────────────────────────────────────────────────────────────┤
│ Number of Cores     │ 1                                                                                       │
├─────────────────────┼─────────────────────────────────────────────────────────────────────────────────────────┤
│ ISS Clock Frequency │ 1.700                                                                                   │
├─────────────────────┼─────────────────────────────────────────────────────────────────────────────────────────┤
│ L2M Size            │ 8MB                                                                                     │
├─────────────────────┼─────────────────────────────────────────────────────────────────────────────────────────┤
│ LRM Size            │ 4kB                                                                                     │
├─────────────────────┼─────────────────────────────────────────────────────────────────────────────────────────┤
│ External Read BW    │ 128GBps                                                                                 │
├─────────────────────┼─────────────────────────────────────────────────────────────────────────────────────────┤
│ External Write BW   │ 128GBps                                                                                 │
├─────────────────────┼─────────────────────────────────────────────────────────────────────────────────────────┤
│ MACS per PE         │ 16                                                                                      │
├─────────────────────┼─────────────────────────────────────────────────────────────────────────────────────────┤
│ Max L2M             │ 1.160MB                                                                                 │
├─────────────────────┼─────────────────────────────────────────────────────────────────────────────────────────┤
│ Max LRM             │ 1.875kB                                                                                 │
├─────────────────────┼─────────────────────────────────────────────────────────────────────────────────────────┤
│ Max Temp Ext Bytes  │ 0.000MB                                                                                 │
├─────────────────────┼─────────────────────────────────────────────────────────────────────────────────────────┤
│ Network GMACs       │ 0.146                                                                                   │
╘═════════════════════╧═════════════════════════════════════════════════════════════════════════════════════════╛

╒════╤════════╤══════════╤══════════════════╤══════════════════════════╤═══════╕
│    │ Type   │ Name     │ shape            │ type                     │ mse   │
╞════╪════════╪══════════╪══════════════════╪══════════════════════════╪═══════╡
│  0 │ Input  │ inputs0  │ [1, 3, 224, 224] │ tensor[FixedPoint32<27>] │ n/a   │
├────┼────────┼──────────┼──────────────────┼──────────────────────────┼───────┤
│  1 │ Output │ outputs0 │ [1, 63]          │ tensor[FixedPoint32<23>]0.842 │
├────┼────────┼──────────┼──────────────────┼──────────────────────────┼───────┤
│  2 │ Output │ outputs1 │ [1, 1]           │ tensor[FixedPoint32<31>]0.000 │
├────┼────────┼──────────┼──────────────────┼──────────────────────────┼───────┤
│  3 │ Output │ outputs2 │ [1, 1]           │ tensor[FixedPoint32<31>]0.000 │
├────┼────────┼──────────┼──────────────────┼──────────────────────────┼───────┤
│  4 │ Output │ outputs3 │ [1, 63]          │ tensor[FixedPoint32<31>]0.000 │
╘════╧════════╧══════════╧══════════════════╧══════════════════════════╧═══════╛

Post-ISS Report 1.7 GHz ***
Fully placed-and-routed gate simulation: 
╒══════════════════════════════════╤═════════╕
│ Latency (ms)                     │ 1.49    │
├──────────────────────────────────┼─────────┤
│ FPS                              │ 671.33  │
├──────────────────────────────────┼─────────┤
│ Average Power @ 3nm SSGNP (mW)   │ 236.89  │
├──────────────────────────────────┼─────────┤
│ FPS per Watt @ 3nm SSGNP (FPS/W) │ 2833.95 │
├──────────────────────────────────┼─────────┤
│ Ext Rd Bytes (MB)                │ 2.24    │
├──────────────────────────────────┼─────────┤
│ Ext Wr Bytes (MB)                │ 0.00    │
├──────────────────────────────────┼─────────┤
│ Avg Ext Rd BW (GBps)             │ 1.47    │
├──────────────────────────────────┼─────────┤
│ Avg Ext Wr BW (GBps)             │ 0.00    │
├──────────────────────────────────┼─────────┤
│ MAC Utilization                  │ 5.62%   │
╘══════════════════════════════════╧═════════╛
*** Data generated using 7nm SSGNP gatesim and scaled to 3nm

[SDK-CLI] : TotalCycles: 2,532,271
[SDK-CLI] : Executions/second: 671.33

compute      : ▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇ 1.272M
data_array   : ▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇ 643.748K
mac          : ▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇ 551.044K
data_external:18.945K
data_ocm     : ▇ 42.743K

for more information check run directory: /quadric/sdk-cli/examples/models/mediapipe/hand/ccl_build/hand_landmark_lite_opt_asym_int8_q_QC_N_1d7_8MB_4kB_128GBps_128GBps_16_OFF_x1_x1/run/20260619_041108_ecb231


2026-06-19 04:11 - INFO - epu - chimera_job - Combined plots generated and saved to: 
/quadric/sdk-cli/examples/models/mediapipe/hand/ccl_build/hand_landmark_lite_opt_asym_int8_q_QC_N_1d7_8MB_4kB_128GBps_128GBps_16_OFF_x1_x1/run/20260619_041108_ecb231/data/hand_landmark_lite_opt_asym_int8_q_QC_N_1d7_8MB_4kB_128GBps_128GBps_16_OFF_x1_x1.combined.png





'/quadric/sdk-cli/examples/models/mediapipe/hand/ccl_build/hand_landmark_lite_opt_asym_int8_q_QC_N_1d7_8MB_4kB_128GBps_128GBps_16_OFF_x1_x1/run/20260619_041108_ecb231/data'


Table of Contents
Introduction to the Chimera SDK
Chimera SDK Quick Start Guide
Chimera SDK Command Line Interface (CLI)
Tutorial: Using SDK as a Library
Tutorials & Model Demos
Model Demos
Model Demo: Llama-2 15M (Baby Llama-2)
Model Demo: QWEN3 8B End-to-End CGC and ISS Execution
Model Demo: QWEN3 Prefill All Decoders
Model Demo: DeepSeek-R1-Distill-Qwen-1.5B End-to-End CGC and ISS Execution
Model Demo: QWEN3 Single Decoder
Model Demo: Qwen2.5-0.5B INT8 Quantization Pipeline
Model Demo: ConvNeXt Detection
Model Demo: QWEN3 Prefill Decoder Validation
Model Demo: ConvNeXt Segmentation
Model Demo: Classifiers Zoo
Model Demo: Detectors Zoo - MMDetection
Model Demo: Segmentors Zoo - MMSegmentation
Model Demo: Pose Estimators Zoo - MMPose
Model Demo: Detectors3D Zoo - MMDetection3D
MODEL Demo: Optical Character Recognition (OCR) Zoo - MMOCR
Model Demo: YOLOv3 Object Detection
Model Demo: YOLOv4 Object Detection
Model Demo: YOLOv5 Detection
Model Demo: YOLOv5 Detection and Segmentation
Model Demo: YOLOR Detection
Model Demo: YOLOX End-to-End Detection
Model Demo: YOLOv7 Detection
Model Demo: YOLOv8 Detection
Model Demo: YOLOv8 Pose Estimation
Model Demo: YOLOP Detection and Segmentation
Model Demo: QAT Vision Transformer (ViT)
Model Demo: QAT Swin Transformer
Model Demo: Mediapipe Face Pipeline
Demo: DOOM Renderer on Chimera GPNPU
Model Demo: Mediapipe Hand Pipeline
Model Demo: Whisper Tiny (Encoder + Decoder)
Model Demo: L2CS Fine-Grained Gaze Estimation
Model Demo: ASVspoof2021 LA Anti-Spoofing (LFCC-LCNN-BiLSTM)
Model Demo: UNET Tumor Segmentation
Model Demo: DETR Encoder
Model Demo: FFNet Segmentation
Model Demo: Centernet Detection
Model Demo: RetinaNet End-to-End Detection
Model Demo: Blazepose Pose Estimation
Model Demo: Pose Resnet Human Pose Estimation
Model Demo: MaskRCNN Detection and Segmentation
Model Demo: Keypoint R-CNN
Model Demo: Faster R-CNN Detection
Model Demo: FCOS Detection
Model Demo: DDRNet Classificationls
Model Demo: PI0.5 End-to-End VLA Inference
Model Demo: BEVFormer End-to-End 3D Detection
Multicore Demo
Chimera LLVM C++ Compiler
Chimera SDK Licensing Policy Documentation
Glossary


© Copyright 2026 Quadric All Rights Reserved • Privacy Policy
This documentation is preliminary and confidential. It is subject to change. Quadric does not give any warranty express or implied that the contents will be complete or accurate or up to date. The company shall not be liable for any loss, actions, claims, proceedings, demands or costs or damages whatsoever or howsoever caused arising directly or indirectly in connection with or arising out of the use of this material.

Sign in to your account

Don't have an account? Create an Account
By signing in, you are agreeing to our Terms of Use and Privacy Policy.

Develop.

Simulate.

Profile.

Collaborate.

We use cookies to enhance your browsing experience, and analyze our traffic.
By clicking "Accept All", you consent to our use of cookies.