Files
rustytorch/crates/models/rtx-vision-advanced/benches/detection_bench.rs
T
2026-03-04 00:08:42 +00:00

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);