Skip to content

Commit 85214f9

Browse files
authored
Performance metrics (#401)
1 parent ec80d47 commit 85214f9

15 files changed

Lines changed: 1189 additions & 168 deletions

File tree

.github/workflows/pre_commit.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -55,4 +55,4 @@ jobs:
5555
uv sync --locked --extra tests --extra ovms
5656
- name: Run python unit tests
5757
run: |
58-
uv run pytest tests/unit
58+
uv run pytest tests/unit --cov

docs/source/guides/index.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,4 +5,5 @@
55
:hidden:
66
77
./model-configuration
8+
./performance_metrics
89
```
Lines changed: 269 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,269 @@
1+
# Performance Metrics
2+
3+
The Model API provides comprehensive performance monitoring capabilities through the `PerformanceMetrics` class. This allows to measure and analyze the performance of model inference pipeline, including detailed timing information for each stage of the inference process.
4+
5+
## Overview
6+
7+
Performance metrics are automatically collected during model inference and include information for:
8+
9+
- **Model loading time**: Time spent loading the model to the inference device
10+
- **Preprocessing time**: Time spent on input data preprocessing
11+
- **Inference time**: Time spent on actual model inference on the device
12+
- **Postprocessing time**: Time spent on output data postprocessing
13+
- **Total time**: Overall time for the complete inference pipeline
14+
- **Total minimal time**: Overall minimum time for the complete inference pipeline
15+
- **Total maxmium time**: Overall maximum time for the complete inference pipeline
16+
- **Total frames**: Total number of inferences
17+
- **FPS**: Frames Per Second
18+
19+
Each metric provides statistical information including mean, standard deviation, and individual measurements.
20+
21+
## Basic Usage
22+
23+
### Accessing Performance Metrics
24+
25+
Every model instance automatically collects performance metrics. You can access them using the `get_performance_metrics()` method:
26+
27+
```python
28+
from model_api.models import Model
29+
import cv2
30+
31+
# Create a model
32+
model = Model.create_model("path/to/your/model.xml")
33+
34+
# Perform inference
35+
image = cv2.imread("path/to/image.jpg")
36+
result = model(image)
37+
38+
# Get performance metrics
39+
metrics = model.get_performance_metrics()
40+
```
41+
42+
### Logging Performance Metrics
43+
44+
The simplest way to view performance metrics is to use the built-in logging method:
45+
46+
```python
47+
# Configure logging
48+
logging.basicConfig(level=logging.INFO, format='%(message)s')
49+
50+
# Log all performance metrics to console
51+
metrics.log_metrics()
52+
```
53+
54+
This will output detailed performance information:
55+
56+
```bash
57+
============================================================
58+
🚀 PERFORMANCE METRICS REPORT 🚀
59+
============================================================
60+
61+
📊 Model Loading:
62+
Load Time: 2.497s
63+
64+
⚙️ Processing Times (mean ± std):
65+
Preprocess: 0.001s ± 0.000s
66+
Inference: 0.570s ± 0.020s
67+
Postprocess: 0.001s ± 0.000s
68+
69+
📈 Total Time Statistics:
70+
Mean: 0.572s ± 0.020s
71+
Min: 0.556s
72+
Max: 0.642s
73+
74+
🎯 Performance Summary:
75+
Total Frames: 100
76+
FPS: 1.75
77+
============================================================
78+
```
79+
80+
## Detailed Metrics Access
81+
82+
### Individual Timing Statistics
83+
84+
You can access individual timing statistics for more detailed analysis:
85+
86+
```python
87+
# Get specific timing statistics
88+
load_time = metrics.get_load_time()
89+
preprocess_time = metrics.get_preprocess_time()
90+
inference_time = metrics.get_inference_time()
91+
postprocess_time = metrics.get_postprocess_time()
92+
total_time = metrics.get_total_time()
93+
total_min_time = metrics.get_total_time_min()
94+
total_max_time = metrics.get_total_time_max()
95+
96+
# Access statistical information
97+
print(f"Mean inference time: {inference_time.mean():.3f} seconds")
98+
print(f"Standard deviation: {inference_time.stddev():.3f} seconds")
99+
print(f"Total inference time: {inference_time.time:.3f} seconds")
100+
print(f"Number of inferences: {inference_time.count}")
101+
```
102+
103+
### Frame Rate and Throughput
104+
105+
```python
106+
# Get frames per second and total frame count
107+
fps = metrics.get_fps()
108+
total_frames = metrics.get_total_frames()
109+
110+
print(f"Processed {total_frames} frames at {fps:.2f} FPS")
111+
```
112+
113+
## Advanced Usage
114+
115+
### Batch Processing Performance
116+
117+
When processing multiple inputs, performance metrics accumulate across all inferences:
118+
119+
```python
120+
import cv2
121+
from model_api.models import DetectionModel
122+
123+
model = DetectionModel.create_model("path/to/detection/model.xml")
124+
125+
# Process multiple images
126+
images = ["image1.jpg", "image2.jpg", "image3.jpg"]
127+
for image_path in images:
128+
image = cv2.imread(image_path)
129+
result = model(image)
130+
131+
# Get accumulated metrics for all inferences
132+
metrics = model.get_performance_metrics()
133+
metrics.log_metrics()
134+
```
135+
136+
### Performance Monitoring During Inference
137+
138+
```python
139+
import cv2
140+
from model_api.models import ClassificationModel
141+
142+
model = ClassificationModel.create_model("efficientnet-b0-pytorch")
143+
image = cv2.imread("test_image.jpg")
144+
145+
# Run multiple inferences and monitor performance
146+
for i in range(100):
147+
result = model(image)
148+
149+
# Check performance every 10 inferences
150+
if (i + 1) % 10 == 0:
151+
metrics = model.get_performance_metrics()
152+
print(f"After {i + 1} inferences:")
153+
print(f" Mean inference time: {metrics.get_inference_time().mean():.3f}s")
154+
print(f" Current FPS: {metrics.get_fps():.2f}")
155+
```
156+
157+
## Performance Optimization Tips
158+
159+
### Analyzing Bottlenecks
160+
161+
Use performance metrics to identify bottlenecks in inference pipeline:
162+
163+
```python
164+
metrics = model.get_performance_metrics()
165+
166+
preprocess_time = metrics.get_preprocess_time().mean()
167+
inference_time = metrics.get_inference_time().mean()
168+
postprocess_time = metrics.get_postprocess_time().mean()
169+
170+
print("Time breakdown:")
171+
print(f" Preprocessing: {preprocess_time:.3f}s ({preprocess_time/total:.1%})")
172+
print(f" Inference: {inference_time:.3f}s ({inference_time/total:.1%})")
173+
print(f" Postprocessing: {postprocess_time:.3f}s ({postprocess_time/total:.1%})")
174+
175+
total = preprocess_time + inference_time + postprocess_time
176+
```
177+
178+
### Warm-up Considerations
179+
180+
The first few inferences may be slower due to system warm-up. Consider excluding them from performance analysis:
181+
182+
```python
183+
# Warm-up inferences
184+
for _ in range(5):
185+
model(image)
186+
187+
# Reset metrics after warm-up
188+
model.get_performance_metrics().reset()
189+
190+
# Now measure actual performance
191+
for _ in range(100):
192+
model(image)
193+
194+
metrics = model.get_performance_metrics()
195+
metrics.log_metrics()
196+
```
197+
198+
## Best Practices
199+
200+
1. **Warm-up Period**: Always include a warm-up period before measuring performance for production benchmarks.
201+
202+
2. **Multiple Runs**: Collect metrics over multiple inference runs to get statistically significant results.
203+
204+
3. **Reset Between Tests**: Reset metrics when comparing different configurations or models.
205+
206+
4. **Monitor All Stages**: Pay attention to all pipeline stages (preprocessing, inference, postprocessing) to identify bottlenecks.
207+
208+
5. **Environment Consistency**: Ensure consistent testing conditions (device state, background processes, etc.) when comparing performance.
209+
210+
## Example: Complete Performance Analysis
211+
212+
```python
213+
import cv2
214+
from model_api.models import DetectionModel
215+
216+
def analyze_model_performance(model_path, test_images, warmup_runs=5, test_runs=100):
217+
"""Complete performance analysis example."""
218+
219+
# Load model
220+
model = DetectionModel.create_model(model_path)
221+
222+
# Load test image
223+
image = cv2.imread(test_images[0])
224+
225+
print("Starting warm-up...")
226+
# Warm-up runs
227+
for _ in range(warmup_runs):
228+
model(image)
229+
230+
# Reset metrics after warm-up
231+
model.get_performance_metrics().reset()
232+
233+
print(f"Running {test_runs} test inferences...")
234+
# Performance measurement runs
235+
for i, image_path in enumerate(test_images[:test_runs]):
236+
image = cv2.imread(image_path)
237+
result = model(image)
238+
239+
# Log progress
240+
if (i + 1) % 10 == 0:
241+
print(f" Completed {i + 1}/{test_runs}")
242+
243+
# Analyze results
244+
metrics = model.get_performance_metrics()
245+
246+
print("\n" + "="*50)
247+
print("PERFORMANCE ANALYSIS RESULTS")
248+
print("="*50)
249+
250+
metrics.log_metrics()
251+
252+
# Additional analysis
253+
inference_time = metrics.get_inference_time()
254+
print(f"\nInference time analysis:")
255+
print(f" Minimum: {min(inference_time.durations):.3f}s")
256+
print(f" Maximum: {max(inference_time.durations):.3f}s")
257+
print(f" Median: {sorted(inference_time.durations)[len(inference_time.durations)//2]:.3f}s")
258+
259+
return metrics
260+
261+
# Usage
262+
if __name__ == "__main__":
263+
model_path = "path/to/your/model.xml"
264+
test_images = ["image1.jpg", "image2.jpg", "image3.jpg"] # Add more images
265+
266+
metrics = analyze_model_performance(model_path, test_images)
267+
```
268+
269+
This comprehensive performance monitoring system helps optimize model inference pipeline and ensure optimal performance in production deployments.

examples/metrics/README.md

Lines changed: 99 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,99 @@
1+
# Benchmark - a metrics API example
2+
3+
This example demonstrates how to use the Python API of OpenVINO Model API for performance analysis and metrics collection during model inference. This tutorial includes the following features:
4+
5+
- Model performance measurement
6+
- Configurable device selection (CPU, GPU, etc.)
7+
- Automatic image dataset discovery
8+
- Warm-up and test runs with customizable parameters
9+
- Detailed inference time analysis
10+
- Metrics logging and reporting
11+
- Performance statistics calculation
12+
13+
## Prerequisites
14+
15+
Install Model API from source. Please refer to the main [README](../../../README.md) for details.
16+
17+
## Run example
18+
19+
To run the example, please execute the following command:
20+
21+
```bash
22+
python benchmark.py <model_path> <dataset_path> [options]
23+
```
24+
25+
### Required Arguments
26+
27+
- `model_path` - Path to the model file (.xml)
28+
- `dataset_path` - Path to the dataset directory containing test images
29+
30+
### Optional Arguments
31+
32+
- `--device` - Device to run the model on (default: CPU)
33+
- `--warmup-runs` - Number of warmup runs (default: 5)
34+
- `--test-runs` - Number of test runs (default: 100)
35+
36+
### Examples
37+
38+
```bash
39+
# Basic usage with CPU
40+
python benchmark.py /path/to/model.xml /path/to/images
41+
42+
# Use GPU with custom parameters
43+
python benchmark.py /path/to/model.xml /path/to/images --device GPU --warmup-runs 10 --test-runs 50
44+
45+
# Show help
46+
python benchmark.py --help
47+
```
48+
49+
## Expected Output
50+
51+
The example will display:
52+
53+
- Number of images found in the dataset directory
54+
- Progress updates during warm-up and test phases
55+
- Comprehensive performance analysis results including timing statistics
56+
- Detailed metrics about the model's inference performance on the specified device
57+
58+
Example output
59+
60+
```bash
61+
OpenVINO Runtime
62+
build: 2025.2.0-19140-c01cd93e24d-releases/2025/2
63+
Reading model model.xml
64+
The model model.xml is loaded to CPU
65+
Number of model infer requests: 2
66+
Starting warm-up...
67+
Running 100 test inferences...
68+
Completed 10/100
69+
Completed 20/100
70+
Completed 30/100
71+
Completed 40/100
72+
Completed 50/100
73+
Completed 60/100
74+
Completed 70/100
75+
Completed 80/100
76+
Completed 90/100
77+
Completed 100/100
78+
============================================================
79+
🚀 PERFORMANCE METRICS REPORT 🚀
80+
============================================================
81+
82+
📊 Model Loading:
83+
Load Time: 2.497s
84+
85+
⚙️ Processing Times (mean ± std):
86+
Preprocess: 0.001s ± 0.000s
87+
Inference: 0.570s ± 0.020s
88+
Postprocess: 0.001s ± 0.000s
89+
90+
📈 Total Time Statistics:
91+
Mean: 0.572s ± 0.020s
92+
Min: 0.556s
93+
Max: 0.642s
94+
95+
🎯 Performance Summary:
96+
Total Frames: 100
97+
FPS: 1.75
98+
============================================================
99+
```

0 commit comments

Comments
 (0)