본문으로 건너뛰기
SDK Version: 2.3.3

Common Use Cases

This chapter provides practical, real-world scenarios with ready-to-use examples. Each use case demonstrates the implementation using the dxcom command and the dx_com Python module where applicable.

Additional Dependencies

Some examples in this chapter use torchvision for image preprocessing. Install it before running these examples:

pip install torchvision

Use Case 1: Simple Image Classification (ResNet / MobileNet)

Scenario: Compiling a pre-trained ResNet50 or MobileNetV1 model using standard image preprocessing.

  • Option A: dxcom Command – Best for quick, standard builds.
  • Option B: dx_com Python Module – Best for integration into automated scripts.

Option A: dxcom Command

Configuration File (resnet50_config.json):

{
"inputs": {
"input": [1, 3, 224, 224]
},
"calibration_method": "ema",
"calibration_num": 100,
"default_loader": {
"dataset_path": "./calibration_images",
"file_extensions": ["jpeg", "jpg", "png"],
"preprocessings": [
{"resize": {"mode": "torchvision", "size": 256, "interpolation": "BILINEAR"}},
{"centercrop": {"width": 224, "height": 224}},
{"convertColor": {"form": "BGR2RGB"}},
{"div": {"x": 255}},
{"normalize": {"mean": [0.485, 0.456, 0.406], "std": [0.229, 0.224, 0.225]}}
]
}
}

Command:

dxcom \
-m ResNet50_sim.onnx \
-c resnet50_config.json \
-o output/resnet50 \
--opt_level 1

Option B: dx_com Python Module

Complete Script (compile_resnet50.py):

import dx_com
from torch.utils.data import Dataset, DataLoader
from torchvision import transforms
from PIL import Image
import os

class ImageNetDataset(Dataset):
"""Standard ImageNet-style dataset"""
def __init__(self, image_dir, img_size=224):
self.image_dir = image_dir
self.image_files = sorted([
f for f in os.listdir(image_dir)
if f.endswith(('.jpg', '.png', '.jpeg'))
])
self.transform = transforms.Compose([
transforms.Resize((img_size, img_size)),
transforms.ToTensor(),
transforms.Normalize(
mean=[0.485, 0.456, 0.406],
std=[0.229, 0.224, 0.225]
)
])

def __len__(self):
return len(self.image_files)

def __getitem__(self, idx):
img_path = os.path.join(self.image_dir, self.image_files[idx])
image = Image.open(img_path).convert('RGB')
return self.transform(image)

# Setup
dataset = ImageNetDataset('./calibration_images', img_size=224)
dataloader = DataLoader(dataset, batch_size=1, shuffle=True)

# Compile
dx_com.compile(
model="ResNet50_sim.onnx",
output_dir="output/resnet50",
dataloader=dataloader,
calibration_method="ema",
calibration_num=100,
opt_level=1
)

print("ResNet50 compilation complete!")

Run:

python3 compile_resnet50.py

Use Case 2: Multi-Input Models (Stereo Vision)

Scenario: A stereo camera system requiring two image inputs with different dimensions.

dx_com Python Module Only

Multi-input models are only supported via the dx_com Python module. The dxcom command does not support multiple inputs.

dx_com Python Module

import dx_com
import torch
from torch.utils.data import Dataset, DataLoader
from torchvision import transforms
from PIL import Image
import os

class StereoDataset(Dataset):
"""Dataset providing stereo image pairs"""
def __init__(self, left_dir, right_dir):
self.left_dir = left_dir
self.right_dir = right_dir

# Get matching image pairs
self.image_files = sorted([
f for f in os.listdir(left_dir)
if f.endswith(('.jpg', '.png'))
])

# Different preprocessing for each input
self.transform_left = transforms.Compose([
transforms.Resize((128, 128)),
transforms.ToTensor(),
transforms.Normalize(
mean=[0.485, 0.456, 0.406],
std=[0.229, 0.224, 0.225]
)
])

self.transform_right = transforms.Compose([
transforms.Resize((256, 256)),
transforms.ToTensor(),
transforms.Normalize(
mean=[0.485, 0.456, 0.406],
std=[0.229, 0.224, 0.225]
)
])

def __len__(self):
return len(self.image_files)

def __getitem__(self, idx):
filename = self.image_files[idx]

# Load left image
left_img = Image.open(
os.path.join(self.left_dir, filename)
).convert('RGB')
left_tensor = self.transform_left(left_img)

# Load right image
right_img = Image.open(
os.path.join(self.right_dir, filename)
).convert('RGB')
right_tensor = self.transform_right(right_img)

# Return tuple of inputs (order must match model)
return left_tensor, right_tensor

# Setup
dataset = StereoDataset(
left_dir='./calibration_left',
right_dir='./calibration_right'
)
dataloader = DataLoader(dataset, batch_size=1)

# Compile multi-input model
dx_com.compile(
model="stereo_model.onnx",
output_dir="output/stereo",
dataloader=dataloader,
calibration_method="ema",
calibration_num=50, # Fewer samples needed for smaller models
opt_level=1
)

print("Stereo model compilation complete!")

Key Technical Requirements:

  • DataLoader Output: The DataLoader must return a tuple of tensors (one per input).
  • Input Mapping: The order of tensors in the tuple must align strictly with the ONNX model’s input node order.
  • Heterogeneous Inputs: Each input branch supports independent sizes and preprocessing configurations.

Use Case 3: Performance Optimization for Edge Devices

Experimental Feature

aggressive_partitioning is currently experimental and may produce unexpected results for some models.

Scenario: Deploying on embedded systems with restricted CPU resources. The goal is to maximize NPU offloading while maintaining short compilation times.

Configuration for Aggressive Partitioning

{
"inputs": {
"input": [1, 3, 224, 224]
},
"calibration_method": "ema",
"calibration_num": 50,
"default_loader": {
"dataset_path": "./calibration_images",
"file_extensions": ["jpeg", "jpg", "png"],
"preprocessings": [
{"resize": {"width": 224, "height": 224}},
{"normalize": {"mean": [0.485, 0.456, 0.406], "std": [0.229, 0.224, 0.225]}}
]
}
}

You can compile using either the dxcom command or the dx_com Python module. Choose one:

Option A: dxcom Command

dxcom \
-m efficient_model.onnx \
-c config.json \
-o output/efficient \
--aggressive_partitioning \
--opt_level 0

Option B: dx_com Python Module

import dx_com

# Maximize NPU offloading with aggressive partitioning
dx_com.compile(
model="efficient_model.onnx",
output_dir="output/efficient",
config="config.json",
aggressive_partitioning=True, # Maximize NPU usage
calibration_num=50 # Fewer samples = faster calibration
)

Optimization Strategy: Aggressive Partitioning:

  • Pros: Maximum NPU offloading, significantly reduced host CPU load and faster compilation cycles.
  • Cons: Potential for slightly higher latency compared to opt_level 1 and increased output binary size.

Use Case 4: Custom Data Type (Non-Image)

Scenario: Processing non-visual data such as audio spectrograms, time-series data, or 3D point clouds.

dx_com Python Module Only

Non-image data types are only supported via the dx_com Python module. The dxcom command only supports image data.

dx_com Python Module

import dx_com
import torch
from torch.utils.data import Dataset, DataLoader
import numpy as np
import os

class CustomDataDataset(Dataset):
"""Example: Audio spectrogram dataset"""
def __init__(self, data_dir, input_shape=(1, 64, 128)):
self.data_files = sorted([
f for f in os.listdir(data_dir)
if f.endswith('.npy')
])
self.data_dir = data_dir
self.input_shape = input_shape

def __len__(self):
return len(self.data_files)

def __getitem__(self, idx):
# Load numpy array (e.g., audio spectrogram)
data = np.load(os.path.join(self.data_dir, self.data_files[idx]))

# Normalize to [0, 1]
data = (data - data.min()) / (data.max() - data.min() + 1e-8)

# Convert to tensor with correct shape
return torch.from_numpy(data.astype(np.float32)).unsqueeze(0)

# Setup
dataset = CustomDataDataset('./spectrogram_data', input_shape=(1, 64, 128))
dataloader = DataLoader(dataset, batch_size=1)

# Compile
dx_com.compile(
model="audio_model.onnx",
output_dir="output/audio_model",
dataloader=dataloader,
calibration_method="minmax", # minmax better for non-image data
calibration_num=100,
)

Use Case 5: Enhanced Quantization (DXQ)

Scenario: Improving quantization accuracy for models where standard quantization causes unacceptable accuracy degradation.

Version Support

DXQ (enhanced_scheme) is supported in DX-COM v2.1.0 and later.

  • Option A: dxcom Command – Set enhanced_scheme in the JSON config file.
  • Option B: dx_com Python Module – Pass enhanced_scheme as a parameter directly.

Option A: dxcom Command

Configuration File (config.json):

{
"inputs": {
"input": [1, 3, 224, 224]
},
"calibration_method": "ema",
"calibration_num": 100,
"enhanced_scheme": {
"DXQ-P3": {"num_samples": 1024}
},
"default_loader": {
"dataset_path": "./calibration_images",
"file_extensions": ["jpeg", "jpg", "png"],
"preprocessings": [
{"resize": {"width": 224, "height": 224}},
{"normalize": {"mean": [0.485, 0.456, 0.406], "std": [0.229, 0.224, 0.225]}}
]
}
}

Command:

dxcom \
-m large_model.onnx \
-c config.json \
-o output/large_model_dxq \
--opt_level 1

Option B: dx_com Python Module

import dx_com

dx_com.compile(
model="large_model.onnx",
output_dir="output/large_model_dxq",
config="config.json",
enhanced_scheme={
"DXQ-P3": {"num_samples": 1024}
},
opt_level=1,
calibration_num=100
)
GPU Device Selection

By default, DX-COM automatically uses GPU if available. In multi-GPU environments, you can specify a device via quantization_device in the JSON config or the dx_com.compile() parameter (e.g., "cuda:1"). See Quantization Device for details.

For all available DXQ schemes (DXQ-P0 to DXQ-P5) and their parameters, see Enhanced Quantization Scheme (DXQ).