295 lines
9.3 KiB
Rust
295 lines
9.3 KiB
Rust
//! Detection model benchmarks
|
|
//!
|
|
//! Comprehensive performance benchmarks for:
|
|
//! - YOLO v8/v9 variants (Nano, Small, Medium, Large, XLarge)
|
|
//! - R-CNN family (Fast R-CNN, Faster R-CNN, Mask R-CNN)
|
|
//! - 3D object detection (PointRCNN, VoxelNet)
|
|
//! - Real-time vs accuracy trade-offs
|
|
|
|
use criterion::{BenchmarkId, Criterion, Throughput, criterion_group, criterion_main};
|
|
use rtx_tensor::{DType, Device, Tensor};
|
|
use rtx_vision_advanced::*;
|
|
|
|
/// Benchmark helper for creating test data
|
|
struct BenchmarkHelper;
|
|
|
|
impl BenchmarkHelper {
|
|
fn create_image(batch_size: usize, height: usize, width: usize) -> Tensor {
|
|
Tensor::randn(&[batch_size, 3, height, width], &Device::default())
|
|
.expect("Failed to create benchmark image")
|
|
}
|
|
|
|
fn create_point_cloud(num_points: usize) -> Tensor {
|
|
Tensor::randn(&[num_points, 4], &Device::default())
|
|
.expect("Failed to create benchmark point cloud")
|
|
}
|
|
}
|
|
|
|
/// Benchmark YOLO v8 detection variants
|
|
fn bench_yolo_variants(c: &mut Criterion) {
|
|
let mut group = c.benchmark_group("yolo_detection");
|
|
|
|
let yolo_variants = vec![
|
|
("nano", detection::YOLOSize::Nano, (640, 640)),
|
|
("small", detection::YOLOSize::Small, (640, 640)),
|
|
("medium", detection::YOLOSize::Medium, (640, 640)),
|
|
("large", detection::YOLOSize::Large, (640, 640)),
|
|
("xlarge", detection::YOLOSize::XLarge, (640, 640)),
|
|
];
|
|
|
|
for (name, size, input_dims) in yolo_variants {
|
|
let config = detection::YOLOConfig {
|
|
model_size: size,
|
|
num_classes: 80,
|
|
confidence_threshold: 0.25,
|
|
nms_threshold: 0.45,
|
|
input_size: input_dims,
|
|
};
|
|
|
|
let mut detector = detection::YOLOv8::new(config).expect("Failed to create YOLO detector");
|
|
|
|
let test_image = BenchmarkHelper::create_image(1, input_dims.0, input_dims.1);
|
|
|
|
group.throughput(Throughput::Elements(1));
|
|
group.bench_with_input(
|
|
BenchmarkId::new("single_image", name),
|
|
&test_image,
|
|
|b, image| {
|
|
b.iter(|| detector.detect(image).expect("Detection failed"));
|
|
},
|
|
);
|
|
|
|
// Batch processing benchmark
|
|
let batch_image = BenchmarkHelper::create_image(8, input_dims.0, input_dims.1);
|
|
group.throughput(Throughput::Elements(8));
|
|
group.bench_with_input(
|
|
BenchmarkId::new("batch_8", name),
|
|
&batch_image,
|
|
|b, image| {
|
|
b.iter(|| {
|
|
detector
|
|
.detect_batch(image)
|
|
.expect("Batch detection failed")
|
|
});
|
|
},
|
|
);
|
|
}
|
|
|
|
group.finish();
|
|
}
|
|
|
|
/// Benchmark R-CNN family models
|
|
fn bench_rcnn_family(c: &mut Criterion) {
|
|
let mut group = c.benchmark_group("rcnn_detection");
|
|
|
|
// Faster R-CNN benchmark
|
|
let mut faster_rcnn =
|
|
detection::rcnn::FasterRCNN::new(80).expect("Failed to create Faster R-CNN");
|
|
|
|
let test_image = BenchmarkHelper::create_image(1, 800, 1333);
|
|
|
|
group.throughput(Throughput::Elements(1));
|
|
group.bench_function("faster_rcnn_single", |b| {
|
|
b.iter(|| faster_rcnn.detect(&test_image).expect("Detection failed"));
|
|
});
|
|
|
|
// Mask R-CNN benchmark (instance segmentation)
|
|
let mut mask_rcnn = segmentation::MaskRCNN::new(80).expect("Failed to create Mask R-CNN");
|
|
|
|
let segmentation_config = segmentation::SegmentationConfig::default();
|
|
|
|
group.bench_function("mask_rcnn_single", |b| {
|
|
b.iter(|| {
|
|
mask_rcnn
|
|
.segment(&test_image, &segmentation_config)
|
|
.expect("Segmentation failed")
|
|
});
|
|
});
|
|
|
|
group.finish();
|
|
}
|
|
|
|
/// Benchmark 3D object detection for autonomous vehicles
|
|
fn bench_3d_detection(c: &mut Criterion) {
|
|
let mut group = c.benchmark_group("3d_detection");
|
|
|
|
let point_cloud_sizes = vec![("small", 10000), ("medium", 50000), ("large", 100000)];
|
|
|
|
let mut detector = detection::three_d::PointRCNN::new().expect("Failed to create 3D detector");
|
|
|
|
for (size_name, num_points) in point_cloud_sizes {
|
|
let point_cloud = BenchmarkHelper::create_point_cloud(num_points);
|
|
|
|
group.throughput(Throughput::Elements(num_points as u64));
|
|
group.bench_with_input(
|
|
BenchmarkId::new("pointrcnn", size_name),
|
|
&point_cloud,
|
|
|b, pc| {
|
|
b.iter(|| detector.detect_3d(pc).expect("3D detection failed"));
|
|
},
|
|
);
|
|
}
|
|
|
|
group.finish();
|
|
}
|
|
|
|
/// Benchmark real-time detection performance
|
|
fn bench_realtime_performance(c: &mut Criterion) {
|
|
let mut group = c.benchmark_group("realtime_detection");
|
|
|
|
// Test different input resolutions for real-time performance
|
|
let resolutions = vec![
|
|
("320p", 320, 320),
|
|
("480p", 480, 640),
|
|
("720p", 720, 1280),
|
|
("1080p", 1080, 1920),
|
|
];
|
|
|
|
let config = detection::YOLOConfig {
|
|
model_size: detection::YOLOSize::Small, // Optimized for speed
|
|
num_classes: 80,
|
|
confidence_threshold: 0.25,
|
|
nms_threshold: 0.45,
|
|
input_size: (640, 640), // Will be overridden
|
|
};
|
|
|
|
for (res_name, height, width) in resolutions {
|
|
let mut config = config.clone();
|
|
config.input_size = (height, width);
|
|
|
|
let mut detector =
|
|
detection::YOLOv8::new(config).expect("Failed to create real-time detector");
|
|
|
|
let test_image = BenchmarkHelper::create_image(1, height, width);
|
|
let pixels = (height * width) as u64;
|
|
|
|
group.throughput(Throughput::Elements(pixels));
|
|
group.bench_with_input(
|
|
BenchmarkId::new("realtime_yolo", res_name),
|
|
&test_image,
|
|
|b, image| {
|
|
b.iter(|| detector.detect(image).expect("Real-time detection failed"));
|
|
},
|
|
);
|
|
}
|
|
|
|
group.finish();
|
|
}
|
|
|
|
/// Benchmark video object tracking
|
|
fn bench_video_tracking(c: &mut Criterion) {
|
|
let mut group = c.benchmark_group("video_tracking");
|
|
|
|
let mut tracker =
|
|
detection::video::MultiObjectTracker::new().expect("Failed to create video tracker");
|
|
|
|
// Simulate different numbers of objects to track
|
|
let object_counts = vec![1, 5, 10, 20, 50];
|
|
|
|
for num_objects in object_counts {
|
|
let mut detections = Vec::new();
|
|
|
|
// Create dummy detections
|
|
for i in 0..num_objects {
|
|
detections.push(BoundingBox::new(
|
|
i as f32 * 50.0,
|
|
i as f32 * 30.0,
|
|
40.0,
|
|
60.0,
|
|
0.8,
|
|
i % 3, // Cycle through 3 classes
|
|
));
|
|
}
|
|
|
|
group.throughput(Throughput::Elements(num_objects as u64));
|
|
group.bench_with_input(
|
|
BenchmarkId::new("multi_object_tracking", num_objects),
|
|
&detections,
|
|
|b, dets| {
|
|
b.iter(|| tracker.update(dets, 0.0).expect("Tracking failed"));
|
|
},
|
|
);
|
|
}
|
|
|
|
group.finish();
|
|
}
|
|
|
|
/// Benchmark detection accuracy vs speed trade-offs
|
|
fn bench_accuracy_speed_tradeoff(c: &mut Criterion) {
|
|
let mut group = c.benchmark_group("accuracy_speed_tradeoff");
|
|
|
|
// Different model configurations representing accuracy vs speed trade-offs
|
|
let configs = vec![
|
|
("speed_optimized", detection::YOLOSize::Nano, 0.5, 0.6), // Fast, lower accuracy
|
|
("balanced", detection::YOLOSize::Small, 0.25, 0.45), // Balanced
|
|
("accuracy_optimized", detection::YOLOSize::Large, 0.1, 0.35), // Slower, higher accuracy
|
|
];
|
|
|
|
let test_image = BenchmarkHelper::create_image(1, 640, 640);
|
|
|
|
for (config_name, model_size, conf_thresh, nms_thresh) in configs {
|
|
let config = detection::YOLOConfig {
|
|
model_size,
|
|
num_classes: 80,
|
|
confidence_threshold: conf_thresh,
|
|
nms_threshold: nms_thresh,
|
|
input_size: (640, 640),
|
|
};
|
|
|
|
let mut detector = detection::YOLOv8::new(config).expect("Failed to create detector");
|
|
|
|
group.bench_with_input(
|
|
BenchmarkId::new("tradeoff", config_name),
|
|
&test_image,
|
|
|b, image| {
|
|
b.iter(|| detector.detect(image).expect("Detection failed"));
|
|
},
|
|
);
|
|
}
|
|
|
|
group.finish();
|
|
}
|
|
|
|
/// Benchmark memory usage during detection
|
|
fn bench_memory_usage(c: &mut Criterion) {
|
|
let mut group = c.benchmark_group("memory_usage");
|
|
|
|
// Test memory usage with different batch sizes
|
|
let batch_sizes = vec![1, 4, 8, 16, 32];
|
|
|
|
let config = detection::YOLOConfig::default();
|
|
let mut detector = detection::YOLOv8::new(config).expect("Failed to create detector");
|
|
|
|
for batch_size in batch_sizes {
|
|
let batch_image = BenchmarkHelper::create_image(batch_size, 640, 640);
|
|
|
|
group.throughput(Throughput::Elements(batch_size as u64));
|
|
group.bench_with_input(
|
|
BenchmarkId::new("memory_batch", batch_size),
|
|
&batch_image,
|
|
|b, image| {
|
|
b.iter(|| {
|
|
detector
|
|
.detect_batch(image)
|
|
.expect("Batch detection failed")
|
|
});
|
|
},
|
|
);
|
|
}
|
|
|
|
group.finish();
|
|
}
|
|
|
|
criterion_group!(
|
|
benches,
|
|
bench_yolo_variants,
|
|
bench_rcnn_family,
|
|
bench_3d_detection,
|
|
bench_realtime_performance,
|
|
bench_video_tracking,
|
|
bench_accuracy_speed_tradeoff,
|
|
bench_memory_usage
|
|
);
|
|
|
|
criterion_main!(benches);
|