cluster4npu/tests/quick_test_deployment.py
HuangMason320 ccd7cdd6b9 feat: Reorganize test scripts and improve YOLOv5 postprocessing
- Move test scripts to tests/ directory for better organization
- Add improved YOLOv5 postprocessing with reference implementation
- Update gitignore to exclude *.mflow files and include main.spec
- Add debug capabilities and coordinate scaling improvements
- Enhance multi-series support with proper validation
- Add AGENTS.md documentation and example utilities

🤖 Generated with [Claude Code](https://claude.ai/code)

Co-Authored-By: Claude <noreply@anthropic.com>
2025-09-11 19:23:59 +08:00

187 lines
7.4 KiB
Python

#!/usr/bin/env python3
"""
Quick test script for YOLOv5 pipeline deployment using fixed configuration
"""
import sys
import os
# Add paths
sys.path.append(os.path.join(os.path.dirname(__file__), 'ui', 'dialogs'))
sys.path.append(os.path.join(os.path.dirname(__file__), 'core', 'functions'))
def test_mflow_loading():
"""Test loading and parsing the fixed .mflow file"""
import json
mflow_files = [
'multi_series_example.mflow',
'multi_series_yolov5_fixed.mflow',
'test.mflow'
]
print("=" * 60)
print("Testing .mflow Configuration Loading")
print("=" * 60)
for mflow_file in mflow_files:
if os.path.exists(mflow_file):
print(f"\n📄 Loading {mflow_file}:")
try:
with open(mflow_file, 'r') as f:
data = json.load(f)
# Check for postprocess nodes
postprocess_nodes = [
node for node in data.get('nodes', [])
if node.get('type') == 'ExactPostprocessNode'
]
if postprocess_nodes:
for node in postprocess_nodes:
props = node.get('properties', {})
postprocess_type = props.get('postprocess_type', 'NOT SET')
confidence_threshold = props.get('confidence_threshold', 'NOT SET')
class_names = props.get('class_names', 'NOT SET')
print(f" ✓ Found PostprocessNode: {node.get('name', 'Unnamed')}")
print(f" - Type: {postprocess_type}")
print(f" - Threshold: {confidence_threshold}")
print(f" - Classes: {len(class_names.split(',')) if isinstance(class_names, str) else 'N/A'} classes")
if postprocess_type == 'yolo_v5':
print(f" ✅ Correctly configured for YOLOv5")
else:
print(f" ❌ Still using: {postprocess_type}")
else:
print(f" ⚠ No ExactPostprocessNode found")
except Exception as e:
print(f" ❌ Error loading file: {e}")
else:
print(f"\n📄 {mflow_file}: File not found")
def test_deployment_direct():
"""Test deployment using the deployment dialog directly"""
try:
from deployment import DeploymentDialog
from PyQt5.QtWidgets import QApplication
print(f"\n" + "=" * 60)
print("Testing Direct Pipeline Deployment")
print("=" * 60)
# Load the fixed configuration
import json
config_file = 'multi_series_yolov5_fixed.mflow'
if not os.path.exists(config_file):
print(f"❌ Configuration file not found: {config_file}")
return
with open(config_file, 'r') as f:
pipeline_data = json.load(f)
print(f"✓ Loaded configuration: {pipeline_data.get('project_name', 'Unknown')}")
print(f"✓ Found {len(pipeline_data.get('nodes', []))} nodes")
# Create minimal Qt app for testing
app = QApplication.instance()
if app is None:
app = QApplication(sys.argv)
# Create deployment dialog
dialog = DeploymentDialog(pipeline_data)
print(f"✓ Created deployment dialog")
# Test analysis
print(f"🔍 Testing pipeline analysis...")
try:
from core.functions.mflow_converter import MFlowConverter
converter = MFlowConverter()
config = converter._convert_mflow_to_config(pipeline_data)
print(f"✓ Pipeline conversion successful")
print(f" - Pipeline name: {config.pipeline_name}")
print(f" - Total stages: {len(config.stage_configs)}")
# Check stage configurations
for i, stage_config in enumerate(config.stage_configs, 1):
print(f" Stage {i}: {stage_config.stage_id}")
if hasattr(stage_config, 'postprocessor_options') and stage_config.postprocessor_options:
print(f" - Postprocess type: {stage_config.postprocessor_options.postprocess_type.value}")
print(f" - Threshold: {stage_config.postprocessor_options.threshold}")
print(f" - Classes: {len(stage_config.postprocessor_options.class_names)}")
if stage_config.postprocessor_options.postprocess_type.value == 'yolo_v5':
print(f" ✅ YOLOv5 postprocessing configured correctly")
else:
print(f" ❌ Postprocessing type: {stage_config.postprocessor_options.postprocess_type.value}")
except Exception as e:
print(f"❌ Pipeline conversion failed: {e}")
import traceback
traceback.print_exc()
except ImportError as e:
print(f"❌ Cannot import deployment components: {e}")
print(f" This is expected if running outside the full application")
except Exception as e:
print(f"❌ Direct deployment test failed: {e}")
import traceback
traceback.print_exc()
def show_fix_summary():
"""Show summary of the fixes applied"""
print(f"\n" + "=" * 60)
print("FIX SUMMARY")
print("=" * 60)
print(f"\n🔧 Applied Fixes:")
print(f"1. ✅ Fixed dashboard.py postprocess property loading")
print(f" - Added missing 'postprocess_type' property")
print(f" - Added all missing postprocess properties")
print(f" - Location: ui/windows/dashboard.py:1203-1213")
print(f"\n2. ✅ Enhanced YOLOv5 postprocessing in Multidongle.py")
print(f" - Improved _process_yolo_generic method")
print(f" - Added proper NMS (Non-Maximum Suppression)")
print(f" - Enhanced live view display")
print(f"\n3. ✅ Updated .mflow configurations")
print(f" - multi_series_example.mflow: enable_postprocessing = true")
print(f" - multi_series_yolov5_fixed.mflow: Complete YOLOv5 setup")
print(f" - Added ExactPostprocessNode with yolo_v5 type")
print(f"\n🎯 Expected Results After Fix:")
print(f" - ❌ 'No Fire (Prob: -0.39)' → ✅ 'person detected (Conf: 0.85)'")
print(f" - ❌ Negative probabilities → ✅ Positive probabilities (0.0-1.0)")
print(f" - ❌ No bounding boxes → ✅ Colorful bounding boxes with labels")
print(f" - ❌ Fire detection classes → ✅ COCO 80 classes (person, car, etc.)")
print(f"\n💡 Usage Instructions:")
print(f" 1. Run: python main.py")
print(f" 2. Login to the dashboard")
print(f" 3. Load: multi_series_yolov5_fixed.mflow")
print(f" 4. Deploy the pipeline")
print(f" 5. Check Live View tab for enhanced bounding boxes")
def main():
print("Quick YOLOv5 Deployment Test")
print("=" * 60)
# Test configuration loading
test_mflow_loading()
# Test direct deployment (if possible)
test_deployment_direct()
# Show fix summary
show_fix_summary()
print(f"\n🎉 Quick test completed!")
print(f" Now try running: python main.py")
print(f" And load: multi_series_yolov5_fixed.mflow")
if __name__ == "__main__":
main()