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.
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:
dxcomCommand – Best for quick, standard builds. - Option B:
dx_comPython 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.
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
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 1and 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.
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.
DXQ (enhanced_scheme) is supported in DX-COM v2.1.0 and later.
- Option A:
dxcomCommand – Setenhanced_schemein the JSON config file. - Option B:
dx_comPython Module – Passenhanced_schemeas 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
)
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).