6.9 KiB
6.9 KiB
STORY-04: Face Detection
Epic
E1: Core Pipeline — As an engineer, I can run face detection on sampled frames in batch.
Related Requirements
| ID | Requirement |
|---|---|
| FR-02 | Face detection on all sampled frames: Lightweight detector only; no full-body or scene analysis |
| NFR-03 | GPU Memory Safety: ≤ 18GB per GPU sustained |
| NFR-01 | Throughput: ≥ 30 videos/hour/GPU |
| TC-01 | Hardware: 2× Tesla P40 24GB (compute capability 5.2, PCIe 3.0, no Tensor Cores) |
| TC-02 | CUDA/Torch Compatibility: CUDA ≤ 11.8, PyTorch ≤ 2.1.0, FP32 inference only |
| TC-04 | Framework Stack: PyTorch → ONNX → TensorRT FP32 |
Description
Implement face detection on all sampled frames using a lightweight detector (YOLOv8n or equivalent). Convert the model to ONNX and TensorRT FP32 for inference. Implement dynamic batching to maximize GPU utilization while staying within VRAM constraints. Generate face crops for classification.
Scope
In Scope
- YOLOv8n face detection model (or equivalent lightweight detector)
- ONNX export and TensorRT FP32 engine conversion
- Dynamic batching for face detection inference
- Face crop extraction and resizing to inference input size (224×224)
- GPU memory management (stay within 18GB per GPU)
- Batch size auto-tuning based on available VRAM
- Face bounding box output with confidence scores
- Handling frames with no detected faces
Out of Scope
- Frame sampling (covered in STORY-03)
- Demographic classification (covered in STORY-05)
- Confidence aggregation (covered in STORY-05)
- Results export (covered in STORY-06)
- Review UI (covered in STORY-07)
Deliverables
4.1 Face Detection Model
File: models/face_detector/
Components:
- Source Model: YOLOv8n (Ultralytics) trained on face detection dataset (WIDER Face or equivalent)
- ONNX Export:
face_detector.onnxwith proper input/output shapes- Input:
[1, 3, 640, 640](RGB, BGR depending on model) - Output:
[1, num_anchors, 4+1](bbox coordinates + confidence)
- Input:
- TensorRT Engine:
face_detector.trt(FP32, built for Tesla P40 CC 5.2)- Builder config: max_batch_size=32, max_workspace_size=4GB
- Serialization for runtime loading
- Model Metadata:
model.jsonwith input shape, normalization params, calibration data
4.2 Face Detection Runner
File: src/face_detector.py
Core components:
- Model Loader: Load TensorRT engine at startup
class FaceDetector: def __init__(self, engine_path, device='cuda'): self.engine = load_trt_engine(engine_path) self.context = self.engine.create_execution_context() self.input_shape = (1, 3, 640, 640) self.device = device - Preprocessing: Convert frame to model input format
- Resize to 640×640
- Normalize (mean=[0.485, 0.456, 0.406], std=[0.229, 0.224, 0.225])
- Convert to NHWC/NCHW as required by TensorRT
- Inference: Run batched detection on multiple frames
- Dynamic batching: accumulate frames until batch_size reached or timeout
- Execute TensorRT engine
- Parse outputs (bounding boxes + confidence scores)
- Post-processing: NMS (Non-Maximum Suppression) to remove duplicate detections
- IoU threshold: 0.45
- Confidence threshold: 0.25 (low to avoid missing faces)
- Crop Generation: Extract face crops from original frames
- Resize crops to 224×224 for classification input
- Save crops to
/scratch/{video_id}/crops/
4.3 Dynamic Batching
File: src/batcher.py
Features:
- Batch Accumulator: Collect face detections across frames
- Max batch size: auto-tuned based on available VRAM (start at 16, adjust dynamically)
- Timeout: 100ms (process batch even if not full)
- VRAM Monitoring: Track GPU memory usage and adjust batch size
- If VRAM > 16GB: reduce batch size by 25%
- If VRAM < 10GB: increase batch size by 25%
- Frame Ordering: Maintain frame-to-batch mapping for correct crop assignment
4.4 GPU Memory Management
File: src/gpu_manager.py
Features:
- Memory Tracking: Monitor GPU memory usage continuously
- Peak Allocation: Ensure total GPU memory < 18GB (leaving 6GB headroom)
- Cleanup: Explicitly free TensorRT buffers after each batch
- Per-Video Limits: Max faces per video (e.g., 100) to prevent memory issues
- Fallback: If VRAM is critically low, reduce batch size and retry
4.5 Configuration Updates
File: config.yaml (updates)
New fields:
face_detection:
model: yolo8n
model_path: /models/face_detector/face_detector.trt
input_size: 640
confidence_threshold: 0.25
iou_threshold: 0.45
max_faces_per_frame: 10
max_faces_per_video: 100
batching:
max_batch_size: 16
batch_timeout_ms: 100
vram_target_gb: 16
vram_reduce_threshold_gb: 16
vram_increase_threshold_gb: 10
Acceptance Criteria
Functional
- YOLOv8n model loads and runs inference via TensorRT FP32
- Face detection correctly identifies faces in test frames (mAP > 0.50 on WIDER Face val)
- No faces detected in frames without faces (false positive rate < 5%)
- Face crops are correctly extracted and resized to 224×224
- Dynamic batching works correctly (multiple frames processed in single batch)
- Batch size adjusts based on available VRAM
- Frames with no detected faces are handled gracefully (no crashes, no crops generated)
- NMS correctly removes duplicate detections (IoU > 0.45)
- Face bounding boxes are accurate (center coordinates within 10 pixels of ground truth)
Non-Functional
- GPU memory usage stays ≤ 18GB per GPU during face detection
- Face detection for 10 frames (batched) completes in < 2 seconds on Tesla P40
- Batch processing throughput: ≥ 50 faces/second/GPU
- Model loading time < 5 seconds at startup
- No GPU OOM errors during extended processing
Technical Constraints
- TensorRT engine is FP32 only (no FP16, no INT8)
- No Tensor Cores used (CC 5.2 constraint)
- CUDA 11.8 compatible (verified via torch.version.cuda)
- ONNX model exports without errors (verified via onnx.checker)
- Face crops are saved in JPEG format at high quality
Dependencies
- Prerequisites: STORY-01 (Foundation), STORY-03 (Frame Sampling — provides frames)
- Depends on: None (runs after frame sampling)
- Enables: STORY-05 (Classification — provides face crops)
Risks & Mitigations
| Risk | Mitigation |
|---|---|
| Tesla P40 (CC 5.2) has no Tensor Cores — slower inference | Use TensorRT engine caching; maximize batch size to compensate |
| YOLOv8n may be too large for VRAM with classification | Use YOLOv8n (smallest variant); monitor VRAM closely |
| Many faces per frame could cause VRAM spike | Limit max faces per frame; reduce batch size if needed |
| TensorRT engine build time is long | Pre-build engines; cache on disk; skip rebuild if model unchanged |
Estimated Effort
- Sprint: 5-6 (second half)
- Story Points: 21
- Dependencies: STORY-01, STORY-03