Unlock this feature

This feature isn’t part of your plan yet

Contact sales to get upgraded to the full DevStudio experience.

Unlock this feature

This feature isn't part of your plan yet.

Model Demo: Pose Resnet Human Pose Estimation


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/hrnet/pose_resnet/pose_resnet.ipynb.


Simple Baselines for Human Pose Estimation and Tracking

Abstract

This work provides baseline methods that are simple and effective, thus helpful for inspiring and evaluating new ideas for the field. The following table shows some mAP on COCO keypoints valid dataset.

(Excerpted from "Deep High-Resolution Representation Learning for Human Pose Estimation".)

These methods are also implemented in HRNet-Human-Pose-Estimation. In this experiment, we are going to use this implementation.

Please refer papers for details.

Human Pose Estimation as Top-Down Approach

There are two different approaches to address to multi-person pose estimation.

  • Top-down approach: A human detector first detects the location of body parts, and then a pose estimator calculaties a pose for each person.
  • Bottom-up approach: A pose estimator detects all parts of each human within an image, and then associates the parts that belong to each individual.

This model adopts top-down approach. At first, a human detector detects humans in an original image. The detected human images are passed to the pose estimation model, and it estimates pose positions like below.

Notebook Outline

In this notebook, the following steps are taken to experiment the model.

  • Environment setup
  • Compilation
  • Inference
  • (Option) Model generation, onnx export and quantization

As a result of the above, the following images are generated.

Setup

Module Installation

!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 gdown
import matplotlib.pyplot as plt
import numpy as np
import os
import onnx
from onnxruntime import InferenceSession
import onnxsim
from pathlib import Path
from PIL import Image
import sys
import urllib
import zipfile

import torch
from torch.utils.data import Subset
from torchvision.transforms import Compose, Normalize, ToTensor

from examples.models.zoo.zoo_utils import (
    download_file,
    onnx_check_and_simplify,
)
from tvm.contrib.epu.chimera_job.chimera_job import ChimeraJob
from tvm.contrib.epu.chimera_job.hw_config import HWConfig
import tvm.contrib.epu.chimera_job.constants as sdk_constants
from sdk_cli.lib.inference import InferenceEngine, batch_inference
from sdk_cli.lib.quantize import (
    QuantizedONNXModel,
    quantize_onnx_model,
)
from sdk_cli.node_builtins.outputs.bbox_label_visualizer import draw_bbox
from sdk_cli.node_builtins.outputs.keypoints_visualizer import draw_keypoints
from sdk_cli.utils.datasets import QuadricCalibration
from sdk_cli.utils.transforms import ResizePad
from tvm.contrib.epu.onnx_util import cut_onnx

Install Ultralytics

!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

HRNet-Human-Pose-Estimation Github Clone

basename = Path("HRNet-Human-Pose-Estimation")

## Install HRNet-Human-Pose-Estimation.
if basename.exists():
    print(f"Existing {basename} is used.")
else:
    url = "https://github.com/HRNet/HRNet-Human-Pose-Estimation/archive/refs/heads/master.zip"
    filename = Path(url).name

    download_file(url, filename)
    with zipfile.ZipFile(filename, "r") as fd:
        fd.extractall()

    os.rename(f"{basename}-{Path(url).stem}", basename)
    print(f"{basename} is installed.")

## Make symbolic links for later experiment.
symlink_list = ["tools", "config", "experiments"]

for sym_path in symlink_list:
    if not Path(sym_path).is_symlink():
        os.symlink(basename / sym_path, sym_path)
        print(f"{sym_path} is symbolic")
HRNet-Human-Pose-Estimation is installed.
tools is symbolic
config is symbolic
experiments is symbolic
oldpath = Path("./HRNet-Human-Pose-Estimation/lib/models")
if oldpath.exists():
    oldpath.rename(Path("./HRNet-Human-Pose-Estimation/lib/hrnetmodels"))

!sed -i 's@import models@import hrnetmodels@g' ./HRNet-Human-Pose-Estimation/lib/hrnetmodels/__init__.py

Download Pretrained Model

We are going to use pose_resnet_50_256x192.pth as a pretrained model.

MODEL_NAME = "pose_resnet_50"

weights_folder = Path("pretrained_models")
weights_folder.mkdir(exist_ok=True)
weights = weights_folder / "pose_resnet_50_256x192.pth"

pose_resnet_50_256x192_pth_url = "https://drive.google.com/uc?id=1G5vwpkN6Dr7k1Y0mpo3Cai0uHklQzNmY"

if not weights.exists():
    gdown.download(pose_resnet_50_256x192_pth_url, str(weights), quiet=False)
Downloading...
From (original): https://drive.google.com/uc?id=1G5vwpkN6Dr7k1Y0mpo3Cai0uHklQzNmY
From (redirected): https://drive.google.com/uc?id=1G5vwpkN6Dr7k1Y0mpo3Cai0uHklQzNmY&confirm=t&uuid=37430849-3fe8-488b-911b-889d97c0f1c4
To: /quadric/sdk-cli/examples/models/hrnet/pose_resnet/pretrained_models/pose_resnet_50_256x192.pth
100%|███████████████████████████████████████| 136M/136M [00:02<00:00, 46.0MB/s]

Load Model

import tools._init_paths
from config import cfg
from config import update_config
import hrnetmodels


class resnet_args:
    def __init__(self):
        self.cfg = "experiments/coco/resnet/res50_256x192_d256x3_adam_lr1e-3.yaml"
        self.opts = [
            "TEST.MODEL_FILE",
            "models/pytorch/pose_coco/pose_resnet_50_256x192.pth",
        ]
        self.modelDir = ""
        self.logDir = ""
        self.dataDir = ""


args = resnet_args()
update_config(cfg, args)

onnx_file = f"{MODEL_NAME}.onnx"

pytorch_model = hrnetmodels.pose_resnet.get_pose_net(cfg, is_train=False)

print(f"=> model generated with {str(weights)}")
pytorch_model.load_state_dict(torch.load(weights, map_location=torch.device("cpu")), strict=False)
pytorch_model.eval();
/quadric/sdk-cli/examples/models/hrnet/pose_resnet/tools/../lib/hrnetmodels/pose_hrnet.py:487: SyntaxWarning: "is" with a literal. Did you mean "=="?
  or self.pretrained_layers[0] is '*':


=> model generated with pretrained_models/pose_resnet_50_256x192.pth

Export ONNX

model_input_size = (192, 256)  # width x height
dummy_input = torch.randn(1, 3, *model_input_size[::-1], requires_grad=False)

input_edges = ["inputs0"]
output_edges = ["outputs0"]

## Export the model
torch.onnx.export(
    pytorch_model,  # model being run
    dummy_input,  # model input (or a tuple for multiple inputs)
    onnx_file,  # where to save the model (can be a file or file-like object)
    export_params=True,  # store the trained parameter weights inside the model file
    do_constant_folding=True,  # whether to execute constant folding for optimization
    opset_version=sdk_constants.DEFAULT_ONNX_OPSET,
    input_names=input_edges,  # the model's input names
    output_names=output_edges,  # the model's output names
)

onnx_model = onnx_check_and_simplify(onnx.load(onnx_file))
onnx.save(onnx_model, onnx_file)
print(f"ONNX is exported and simplified as {onnx_file}")
ONNX is exported and simplified as pose_resnet_50.onnx

Split ONNX

When the above cell is successfully executed, pose_resnet_50.onnx is generated in the current directory.

This command cell uses this onnx file to cplit to a backbone and a head.

split_edges = ["/layer4/layer4.2/relu_2/Relu_output_0"]

model = onnx.load(onnx_file)
backbone_onnx_file = f"{MODEL_NAME}-backbone.onnx"
head_onnx_file = f"{MODEL_NAME}-head.onnx"

## Extract the backbone.
sub_graph = cut_onnx(model, input_edges, split_edges)
sub_graph = onnx_check_and_simplify(sub_graph)
onnx.save(sub_graph, backbone_onnx_file)
print(f"Backbone onnx is saved as {backbone_onnx_file}")

## Extract the head.
sub_graph = cut_onnx(model, split_edges, output_edges)
sub_graph = onnx_check_and_simplify(sub_graph)
onnx.save(sub_graph, head_onnx_file)
print(f"Head onnx is saved as {head_onnx_file}")
Backbone onnx is saved as pose_resnet_50-backbone.onnx
Head onnx is saved as pose_resnet_50-head.onnx

Quantize

dataset_mean, dataset_std = (0.485, 0.456, 0.406), (0.229, 0.224, 0.225)

transforms = Compose(
    [
        ResizePad(model_input_size),
        ToTensor(),
        Normalize(dataset_mean, dataset_std),
    ]
)

## Path to directory containing data to use for for numerical range calibration during quantization
## Data is used also used to compare accuracy of fp32 and int8 models
dataset = QuadricCalibration.Dataset(transform=transforms)

## NOTE: `coco-like` is the 0th index target for `QuadricCalibration.Dataset`
coco_like_data_indices = [index for index, target in enumerate(dataset.targets) if target == 0]
coco_like_subset_of_dataset = Subset(dataset, coco_like_data_indices)

quantized_onnx_model: QuantizedONNXModel = quantize_onnx_model(
    backbone_onnx_file, coco_like_subset_of_dataset, asymmetric_activation=True
)
print(
    f"quantized onnx: {quantized_onnx_model.model_path}, tranges file: {quantized_onnx_model.tensor_ranges_path}"
)
2026-09-22 02:49 - INFO - sdk - quantize - ONNX model shapes inferred.
2026-09-22 02:50 - DEBUG - sdk - quantize - Forcing node types: []
2026-09-22 02:50 - DEBUG - sdk - quantize - ONNX Node types excluded from quantization: ['Softmax', 'Sigmoid', 'QuadricCustomOp']
2026-09-22 02:50 - DEBUG - sdk - quantize - ONNX Node names excluded from quantization: []
2026-09-22 02:50 - INFO - sdk - quantize - Starting quantization...
WARNING:root:Please use QuantFormat.QDQ for activation type QInt8 and weight type QInt8. Or it will lead to bad performance on x64.
2026-09-22 02:50 - INFO - sdk - quantize - Quantization completed! Quantized model saved to /quadric/sdk-cli/examples/models/hrnet/pose_resnet/pose_resnet_50-backbone_OpSet16_optimized_asym_int8_q.onnx
2026-09-22 02:50 - INFO - sdk - quantize - ONNX full precision model size: 89.61MB
2026-09-22 02:50 - INFO - sdk - quantize - ONNX quantized model size: 22.53MB
2026-09-22 02:50 - INFO - sdk - quantize - ONNX model shapes inferred.
2026-09-22 02:50 - INFO - sdk - quantize - ONNX Model with well-defined shapes has been saved at `/quadric/sdk-cli/examples/models/hrnet/pose_resnet/pose_resnet_50-backbone_OpSet16_optimized_asym_int8_q_shaped.onnx`.
2026-09-22 02:50 - DEBUG - sdk - quantize - Checking for FLOAT/FLOAT16 types...
2026-09-22 02:50 - INFO - sdk - quantize - Checking for remaining FLOAT/FLOAT16 types.
2026-09-22 02:50 - INFO - sdk - quantize - Model still has FLOAT/FLOAT16 types after quantization. Creating ranges for floating point tensors using calibration data...
2026-09-22 02:50 - INFO - sdk - quantize - Saved computed tensor ranges to /quadric/sdk-cli/examples/models/hrnet/pose_resnet/pose_resnet_50-backbone_OpSet16_optimized_asym_int8_q_shaped.tranges.
2026-09-22 02:50 - INFO - sdk - quantize - 
╒══════════════════════════════════════════════════════════════════════════════════════════════════════════════════════╤═════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════╕
│ Quantized ONNX Model                                                                                                 │ Tensor Ranges File                                                                                                      │
╞══════════════════════════════════════════════════════════════════════════════════════════════════════════════════════╪═════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════╡
│ /quadric/sdk-cli/examples/models/hrnet/pose_resnet/pose_resnet_50-backbone_OpSet16_optimized_asym_int8_q_shaped.onnx │ /quadric/sdk-cli/examples/models/hrnet/pose_resnet/pose_resnet_50-backbone_OpSet16_optimized_asym_int8_q_shaped.tranges │
╘══════════════════════════════════════════════════════════════════════════════════════════════════════════════════════╧═════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════╛


quantized onnx: /quadric/sdk-cli/examples/models/hrnet/pose_resnet/pose_resnet_50-backbone_OpSet16_optimized_asym_int8_q_shaped.onnx, tranges file: /quadric/sdk-cli/examples/models/hrnet/pose_resnet/pose_resnet_50-backbone_OpSet16_optimized_asym_int8_q_shaped.tranges

Compile

hw_config = HWConfig(product="QC-P")
cgc_job = ChimeraJob(
    model_p=str(quantized_onnx_model.model_path),
    hw_config=hw_config,
    trange_file=str(quantized_onnx_model.tensor_ranges_path),
)
cgc_job.compile(quiet=True)
print(cgc_job)
╒═════════════════════╤══════════════════════════════════════════════════════════════════════════════════════════════════════════════════════╕
│ Module Name         │ pose_resnet_50_backbone_OpSet16_optimized_asym_int8_q_shaped_QC_P_1d7_16MB_4kB_128GBps_128GBps_16_OFF_x1_x1          │
├─────────────────────┼──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┤
│ ONNX File           │ /quadric/sdk-cli/examples/models/hrnet/pose_resnet/pose_resnet_50-backbone_OpSet16_optimized_asym_int8_q_shaped.onnx │
├─────────────────────┼──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┤
│ Product Target      │ QC-P                                                                                                                 │
├─────────────────────┼──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┤
│ Number of Cores     │ 1                                                                                                                    │
├─────────────────────┼──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┤
│ ISS Clock Frequency │ 1.700                                                                                                                │
├─────────────────────┼──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┤
│ L2M Size            │ 16MB                                                                                                                 │
├─────────────────────┼──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┤
│ LRM Size            │ 4kB                                                                                                                  │
├─────────────────────┼──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┤
│ External Read BW    │ 128GBps                                                                                                              │
├─────────────────────┼──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┤
│ External Write BW   │ 128GBps                                                                                                              │
├─────────────────────┼──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┤
│ MACS per PE         │ 16                                                                                                                   │
├─────────────────────┼──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┤
│ Max L2M             │ 11.844MB                                                                                                             │
├─────────────────────┼──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┤
│ Max LRM             │ 3.000kB                                                                                                              │
├─────────────────────┼──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┤
│ Max Temp Ext Bytes  │ 0.000MB                                                                                                              │
├─────────────────────┼──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┤
│ Network GMACs       │ 4.004                                                                                                                │
╘═════════════════════╧══════════════════════════════════════════════════════════════════════════════════════════════════════════════════════╛

╒════╤════════╤═══════════════════════════════════════╤══════════════════╤══════════════════════════╤═══════╕
│    │ Type   │ Name                                  │ shape            │ type                     │ mse   │
╞════╪════════╪═══════════════════════════════════════╪══════════════════╪══════════════════════════╪═══════╡
│  0 │ Input  │ inputs0                               │ [1, 3, 256, 192] │ tensor[FixedPoint32<29>] │ n/a   │
├────┼────────┼───────────────────────────────────────┼──────────────────┼──────────────────────────┼───────┤
│  1 │ Output │ /layer4/layer4.2/relu_2/Relu_output_0 │ [1, 2048, 8, 6]  │ tensor[FixedPoint32<27>] │ n/a   │
╘════╧════════╧═══════════════════════════════════════╧══════════════════╧══════════════════════════╧═══════╛

Demo

A human detection can be done with any human detection models. In this experiment, we are going to use YOLOv5 for a human detection.

Inference as Batch

ChimeraJob supports batch execution for both ort and iss. This invokes specified number of threads to execute inference in parallel.

We are going to take advantage of this feature in order to finish the inference of the pose estimation faster even if there could be multiple humans in an input images.

Human Detection

from ultralytics import YOLO


## Load a model
detector = YOLO("yolov8n.pt")  # load an official model

all_image_paths = [
    "../../../common/calibration/face/daniel_maverick.png",
    # "../../../common/calibration/coco-like/33823288584_1d21cf0a26_k.jpeg",
]

bboxes_per_image = {}
for image_path in all_image_paths:
    detections = detector(image_path)[0]
    # Retrieve only human detections.
    detections = torch.cat(
        (
            detections.boxes.xyxy,
            detections.boxes.conf.reshape(-1, 1),
            detections.boxes.cls.reshape(-1, 1),
        ),
        dim=1,
    )
    bboxes_per_image[image_path] = detections[detections[..., 5] == 0]
Downloading https://github.com/ultralytics/assets/releases/download/v8.4.0/yolov8n.pt to 'yolov8n.pt': 100% ━━━━━━━━━━━━ 6.2MB 125.0MB/s 0.0s

image 1/1 /quadric/sdk-cli/examples/models/hrnet/pose_resnet/../../../common/calibration/face/daniel_maverick.png: 576x640 1 person, 1 dog, 1406.6ms
Speed: 10.5ms preprocess, 1406.6ms inference, 14.8ms postprocess per image at shape (1, 3, 576, 640)
%matplotlib inline

pic_len = len(all_image_paths)

ax, idx = {}, 0
fig = plt.figure(figsize=(5 * pic_len, 5), tight_layout=True)
for image_path, detections in bboxes_per_image.items():
    idx += 1
    ax[idx] = fig.add_subplot(int("1%s%s" % (pic_len, idx)))
    ax[idx].imshow(draw_bbox(np.array(Image.open(image_path)), detections))
    ax[idx].set_title(f"Bounding Boxes: {Path(image_path).name}")
    ax[idx].axis("off")

fig.show()

Pose Estimation

This model was trained with COCO 2017 Dataset. Keypoints info can be retrieved from annotations/person_keypoints_val2017.json in COCO 2017val.

Preprocess for Pose Estimation

There could be multiple humans detected in an image. This preprocessing is to make a list of the sub images corresponding to bounding boxes per image.

persons_per_image = {}

for image_path, detections in bboxes_per_image.items():
    frame = np.array(Image.open(image_path))
    persons_per_image[image_path] = []
    for bbox in detections:
        x1, y1, x2, y2 = bbox[:4].numpy().astype(np.int32)
        score = bbox[4]
        if score > 0.5:
            extracted_image = frame[y1:y2, x1:x2, :]
            persons_per_image[image_path].append(Image.fromarray(extracted_image))

Inference

Pose Estimation inference is done on image portions which the detection model predicts as humans. The batch inference is done on those image portions per image.

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

head_onnx_model = onnx.load(head_onnx_file)
head_session = InferenceSession(head_onnx_model.SerializeToString())

outputs_per_image = {}
for image_path, all_images in persons_per_image.items():
    all_transformed_images = []
    for image in all_images:
        transformed_image = transforms(image)

        all_transformed_images.append(
            np.expand_dims(transformed_image.numpy(), axis=0).astype(np.float32)
        )
    outputs_per_image[image_path] = {}
    THREADS = min(len(all_images), 6)
    for inference_engine, engine in engines.items():
        outputs_per_image[image_path][inference_engine] = batch_inference(
            inference_engine,
            engine,
            all_transformed_images,
            head_session=head_session,
            threads=THREADS,
        )
100%|████████████████████████████████████████████| 1/1 [00:00<00:00,  4.06it/s]
  0%|                                                    | 0/1 [00:00<?, ?it/s]
  0%|                                                                        | 0/11 [00:00<?, ?it/s]
FILM 1/11:   9%|████▋                                              | 1/11 [00:00<00:00, 3315.66it/s]
FILM 1/11:   9%|████▋                                              | 1/11 [00:00<00:00, 1075.46it/s]
FILM 1/11:  18%|█████████▋                                           | 2/11 [00:01<00:04,  1.92it/s]
FILM 2/11:  18%|█████████▋                                           | 2/11 [00:01<00:04,  1.92it/s]
FILM 2/11:  18%|█████████▋                                           | 2/11 [00:01<00:04,  1.92it/s]
FILM 2/11:  27%|██████████████▍                                      | 3/11 [00:03<00:11,  1.49s/it]
FILM 3/11:  27%|██████████████▍                                      | 3/11 [00:03<00:11,  1.49s/it]
FILM 3/11:  27%|██████████████▍                                      | 3/11 [00:03<00:11,  1.49s/it]
FILM 3/11:  36%|███████████████████▎                                 | 4/11 [00:07<00:17,  2.47s/it]
FILM 4/11:  36%|███████████████████▎                                 | 4/11 [00:07<00:17,  2.47s/it]
FILM 4/11:  36%|███████████████████▎                                 | 4/11 [00:07<00:17,  2.47s/it]
FILM 4/11:  45%|████████████████████████                             | 5/11 [00:09<00:12,  2.00s/it]
FILM 5/11:  45%|████████████████████████                             | 5/11 [00:09<00:12,  2.00s/it]
FILM 5/11:  45%|████████████████████████                             | 5/11 [00:09<00:12,  2.00s/it]
FILM 5/11:  55%|████████████████████████████▉                        | 6/11 [00:13<00:14,  2.89s/it]
FILM 6/11:  55%|████████████████████████████▉                        | 6/11 [00:13<00:14,  2.89s/it]
FILM 6/11:  55%|████████████████████████████▉                        | 6/11 [00:13<00:14,  2.89s/it]
FILM 6/11:  64%|█████████████████████████████████▋                   | 7/11 [00:15<00:09,  2.38s/it]
FILM 7/11:  64%|█████████████████████████████████▋                   | 7/11 [00:15<00:09,  2.38s/it]
FILM 7/11:  64%|█████████████████████████████████▋                   | 7/11 [00:15<00:09,  2.38s/it]
FILM 7/11:  73%|██████████████████████████████████████▌              | 8/11 [00:15<00:05,  1.77s/it]
FILM 8/11:  73%|██████████████████████████████████████▌              | 8/11 [00:15<00:05,  1.77s/it]
FILM 8/11:  73%|██████████████████████████████████████▌              | 8/11 [00:15<00:05,  1.77s/it]
FILM 8/11:  82%|███████████████████████████████████████████▎         | 9/11 [00:19<00:05,  2.57s/it]
FILM 9/11:  82%|███████████████████████████████████████████▎         | 9/11 [00:19<00:05,  2.57s/it]
FILM 9/11:  82%|███████████████████████████████████████████▎         | 9/11 [00:19<00:05,  2.57s/it]
FILM 9/11:  91%|███████████████████████████████████████████████▎    | 10/11 [00:20<00:01,  1.95s/it]
FILM 10/11:  91%|██████████████████████████████████████████████▎    | 10/11 [00:20<00:01,  1.95s/it]
FILM 10/11:  91%|██████████████████████████████████████████████▎    | 10/11 [00:20<00:01,  1.95s/it]
FILM 10/11: 100%|███████████████████████████████████████████████████| 11/11 [00:24<00:00,  2.44s/it]
FILM 11/11: 100%|███████████████████████████████████████████████████| 11/11 [00:24<00:00,  2.44s/it]
FILM 11/11: 100%|███████████████████████████████████████████████████| 11/11 [00:24<00:00,  2.18s/it]
100%|████████████████████████████████████████████| 1/1 [00:24<00:00, 24.60s/it]

Run Statistics for PoseResnet Backbone

print(cgc_job)
cgc_job.plot_run_statistics()
╒═════════════════════╤══════════════════════════════════════════════════════════════════════════════════════════════════════════════════════╕
│ Module Name         │ pose_resnet_50_backbone_OpSet16_optimized_asym_int8_q_shaped_QC_P_1d7_16MB_4kB_128GBps_128GBps_16_OFF_x1_x1          │
├─────────────────────┼──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┤
│ ONNX File           │ /quadric/sdk-cli/examples/models/hrnet/pose_resnet/pose_resnet_50-backbone_OpSet16_optimized_asym_int8_q_shaped.onnx │
├─────────────────────┼──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┤
│ Product Target      │ QC-P                                                                                                                 │
├─────────────────────┼──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┤
│ Number of Cores     │ 1                                                                                                                    │
├─────────────────────┼──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┤
│ ISS Clock Frequency │ 1.700                                                                                                                │
├─────────────────────┼──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┤
│ L2M Size            │ 16MB                                                                                                                 │
├─────────────────────┼──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┤
│ LRM Size            │ 4kB                                                                                                                  │
├─────────────────────┼──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┤
│ External Read BW    │ 128GBps                                                                                                              │
├─────────────────────┼──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┤
│ External Write BW   │ 128GBps                                                                                                              │
├─────────────────────┼──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┤
│ MACS per PE         │ 16                                                                                                                   │
├─────────────────────┼──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┤
│ Max L2M             │ 11.844MB                                                                                                             │
├─────────────────────┼──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┤
│ Max LRM             │ 3.000kB                                                                                                              │
├─────────────────────┼──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┤
│ Max Temp Ext Bytes  │ 0.000MB                                                                                                              │
├─────────────────────┼──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┤
│ Network GMACs       │ 4.004                                                                                                                │
╘═════════════════════╧══════════════════════════════════════════════════════════════════════════════════════════════════════════════════════╛

╒════╤════════╤═══════════════════════════════════════╤══════════════════╤══════════════════════════╤═══════╕
│    │ Type   │ Name                                  │ shape            │ type                     │ mse   │
╞════╪════════╪═══════════════════════════════════════╪══════════════════╪══════════════════════════╪═══════╡
│  0 │ Input  │ inputs0                               │ [1, 3, 256, 192] │ tensor[FixedPoint32<29>] │ n/a   │
├────┼────────┼───────────────────────────────────────┼──────────────────┼──────────────────────────┼───────┤
│  1 │ Output │ /layer4/layer4.2/relu_2/Relu_output_0 │ [1, 2048, 8, 6]  │ tensor[FixedPoint32<27>] │ 0.001 │
╘════╧════════╧═══════════════════════════════════════╧══════════════════╧══════════════════════════╧═══════╛

Post-ISS Report 1.7 GHz ***
Fully placed-and-routed gate simulation: 
╒══════════════════════════════════╤═════════╕
│ Latency (ms)                     │ 1.61    │
├──────────────────────────────────┼─────────┤
│ FPS                              │ 621.55  │
├──────────────────────────────────┼─────────┤
│ Average Power @ 3nm SSGNP (mW)   │ 1200.23 │
├──────────────────────────────────┼─────────┤
│ FPS per Watt @ 3nm SSGNP (FPS/W) │ 517.86  │
├──────────────────────────────────┼─────────┤
│ Ext Rd Bytes (MB)                │ 23.34   │
├──────────────────────────────────┼─────────┤
│ Ext Wr Bytes (MB)                │ 0.38    │
├──────────────────────────────────┼─────────┤
│ Avg Ext Rd BW (GBps)             │ 14.17   │
├──────────────────────────────────┼─────────┤
│ Avg Ext Wr BW (GBps)             │ 0.23    │
├──────────────────────────────────┼─────────┤
│ MAC Utilization                  │ 35.74%  │
╘══════════════════════════════════╧═════════╛
*** Data generated using 7nm SSGNP gatesim and scaled to 3nm

[SDK-CLI] : TotalCycles: 2,735,090
[SDK-CLI] : Executions/second: 621.55

compute      : ▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇ 706.853K
data_array   : ▇▇▇▇▇ 177.978K
mac          : ▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇ 1.654M
data_external: ▏ 16.686K
data_ocm     : ▇▇▇▇ 140.365K

for more information check run directory: /quadric/sdk-cli/examples/models/hrnet/pose_resnet/ccl_build/pose_resnet_50_backbone_OpSet16_optimized_asym_int8_q_shaped_QC_P_1d7_16MB_4kB_128GBps_128GBps_16_OFF_x1_x1/run/20260922_025258_279066


2026-09-22 02:53 - INFO - epu - chimera_job - Combined plots generated and saved to: 
/quadric/sdk-cli/examples/models/hrnet/pose_resnet/ccl_build/pose_resnet_50_backbone_OpSet16_optimized_asym_int8_q_shaped_QC_P_1d7_16MB_4kB_128GBps_128GBps_16_OFF_x1_x1/run/20260922_025258_279066/data/pose_resnet_50_backbone_OpSet16_optimized_asym_int8_q_shaped_QC_P_1d7_16MB_4kB_128GBps_128GBps_16_OFF_x1_x1.combined.png





'/quadric/sdk-cli/examples/models/hrnet/pose_resnet/ccl_build/pose_resnet_50_backbone_OpSet16_optimized_asym_int8_q_shaped_QC_P_1d7_16MB_4kB_128GBps_128GBps_16_OFF_x1_x1/run/20260922_025258_279066/data'

Display Inference Results

from examples.models.hrnet.hrnet_utils.hrnet_helpers import pose_resnet_postprocess

pic_len = len(engines) + 1

for (image, outputs_per_inference_engine), detections in zip(
    outputs_per_image.items(), bboxes_per_image.values()
):
    ax, idx = {}, 1
    fig = plt.figure(figsize=(4 * pic_len, 4), tight_layout=True)

    ax[idx] = fig.add_subplot(int("1%s%s" % (pic_len, idx)))
    ax[idx].imshow(np.array(Image.open(image)))
    ax[idx].set_title("Original Image")
    ax[idx].axis("off")
    for inference_engine, all_outputs in outputs_per_inference_engine.items():
        frame = np.array(Image.open(image))
        for outputs, bboxes in zip(all_outputs, detections):
            points, scores = pose_resnet_postprocess(outputs[0], bboxes.numpy())
            frame = draw_keypoints(frame, points, scores, threshold=0.2)
        idx += 1
        ax[idx] = fig.add_subplot(int("1%s%s" % (pic_len, idx)))
        ax[idx].imshow(frame)
        ax[idx].set_title(f"{MODEL_NAME}: {str(inference_engine).upper()}")
        ax[idx].axis("off")
    fig.show()

Citation

  • HRNet-Human-Pose-Estimation
@inproceedings{sun2019deep,
  title={Deep High-Resolution Representation Learning for Human Pose Estimation},
  author={Sun, Ke and Xiao, Bin and Liu, Dong and Wang, Jingdong},
  booktitle={CVPR},
  year={2019}
}

@inproceedings{xiao2018simple,
    author={Xiao, Bin and Wu, Haiping and Wei, Yichen},
    title={Simple Baselines for Human Pose Estimation and Tracking},
    booktitle = {European Conference on Computer Vision (ECCV)},
    year = {2018}
}
@software{yolov5,
  title = {YOLOv5 by Ultralytics},
  author = {Glenn Jocher},
  year = {2020},
  version = {7.0},
  license = {AGPL-3.0},
  url = {https://github.com/ultralytics/yolov5},
  doi = {10.5281/zenodo.3908559},
  orcid = {0000-0001-5950-6979}
}

Sign in to your account

Don't have an account? 
By signing in, you are agreeing to our Terms of Use and Privacy Policy.
Quadric // One architecture. Every algorithm.

Develop.

Simulate.

Profile.

Collaborate.