Instructions to use DHDRL/adaptive-wafer-rl with libraries, inference providers, notebooks, and local apps. Follow these links to get started.
- Libraries
- stable-baselines3
How to use DHDRL/adaptive-wafer-rl with stable-baselines3:
from huggingface_sb3 import load_from_hub checkpoint = load_from_hub( repo_id="DHDRL/adaptive-wafer-rl", filename="{MODEL FILENAME}.zip", ) - Notebooks
- Google Colab
- Kaggle
| """ | |
| RUN FAIR ADVERSARIAL VALIDATION | |
| ================================ | |
| Usage: | |
| python run_fair_adversarial_validation.py \ | |
| --model_path path/to/model.zip \ | |
| --num_episodes 100 \ | |
| --gpu \ | |
| --output_dir ./fair_test_results \ | |
| --seed # \ | |
| --start_test # | |
| """ | |
| import argparse | |
| import sys | |
| from pathlib import Path | |
| import torch | |
| import numpy as np | |
| from gru_belief_policy_v3_agnostic import GRUAugmentedFeaturesExtractor | |
| from gru_env_wrappers import GRUStateManager | |
| from masked_dqn_policy import MaskedDQN, MaskedDQNPolicy | |
| from stable_baselines3 import DQN | |
| # Add parent directory to path for imports | |
| sys.path.append(str(Path(__file__).parent)) | |
| from fair_adversarial_validation_framework import FairAdversarialTestSuite | |
| from mems_adaptive_inspection_env_curriculum_v5_SOFT_RESET_STABLE import ( | |
| ResolutionAgnosticInspectionEnv, | |
| InspectionConfig, | |
| NaNSafetyWrapper | |
| ) | |
| def parse_args(): | |
| """Parse command line arguments""" | |
| parser = argparse.ArgumentParser( | |
| description='Run fair adversarial validation on MEMS inspection model' | |
| ) | |
| parser.add_argument( | |
| '--model_path', | |
| type=str, | |
| required=True, | |
| help='Path to trained model (.zip file)' | |
| ) | |
| parser.add_argument( | |
| '--num_episodes', | |
| type=int, | |
| default=50, | |
| help='Number of episodes per test case (default: 50)' | |
| ) | |
| parser.add_argument( | |
| '--output_dir', | |
| type=str, | |
| default='./fair_adversarial_results', | |
| help='Output directory for results' | |
| ) | |
| parser.add_argument( | |
| '--grid_size', | |
| type=int, | |
| default=64, | |
| help='Environment grid size (default: 64)' | |
| ) | |
| parser.add_argument( | |
| '--budget', | |
| type=int, | |
| default=3000, | |
| help='Inspection budget (default: 3000)' | |
| ) | |
| parser.add_argument( | |
| '--gpu', | |
| action='store_true', | |
| help='Use GPU acceleration for environment' | |
| ) | |
| parser.add_argument( | |
| '--seed', | |
| type=int, | |
| default=42, | |
| help='Random seed (default: 42)' | |
| ) | |
| # Resume support | |
| parser.add_argument( | |
| '--start_test', | |
| type=int, | |
| default=1, | |
| help='Start from this test number (1-based). Use to resume after timeout/crash.' | |
| ) | |
| return parser.parse_args() | |
| def main(): | |
| """Main execution""" | |
| args = parse_args() | |
| print(""" | |
| ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ | |
| β β | |
| β FAIR ADVERSARIAL VALIDATION FOR MEMS INSPECTION DQN β | |
| β β | |
| β Testing model with realistic, interpretable scenarios β | |
| β β | |
| ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ | |
| """) | |
| # Set random seeds | |
| torch.manual_seed(args.seed) | |
| np.random.seed(args.seed) | |
| # Load model | |
| print(f"\n{'='*80}") | |
| print(f"Loading Model from: {args.model_path}") | |
| print(f"{'='*80}") | |
| if not Path(args.model_path).exists(): | |
| print(f"β Model file not found: {args.model_path}") | |
| sys.exit(1) | |
| custom_objects = { | |
| "features_extractor_class": GRUAugmentedFeaturesExtractor, | |
| "policy_class": MaskedDQNPolicy, | |
| } | |
| model = MaskedDQN.load( | |
| args.model_path, | |
| custom_objects=custom_objects, | |
| device="cuda" if args.gpu else "cpu" | |
| ) | |
| print(f"β Model loaded successfully") | |
| # Create environment configuration | |
| print(f"\n{'='*80}") | |
| print(f"Creating Environment Configuration") | |
| print(f"{'='*80}") | |
| config = InspectionConfig( | |
| grid_size=args.grid_size, | |
| wafer_diameter_mm=300.0, | |
| die_size_mm=5.0, | |
| inspection_budget=args.budget, | |
| inspection_cost=1.0, | |
| defect_catch_value=100.0, | |
| false_alarm_penalty=2.0, | |
| miss_penalty=50.0, | |
| max_steps=None, | |
| prior_belief=0.1, | |
| belief_update_radius=3, | |
| belief_increase_rate=0.3, | |
| belief_decrease_rate=0.2, | |
| soft_reset=True, | |
| seed=args.seed | |
| ) | |
| print(f"β Configuration created") | |
| print(f" Grid size: {config.grid_size}x{config.grid_size}") | |
| print(f" Budget: {config.inspection_budget}") | |
| print(f" GPU acceleration: {args.gpu and torch.cuda.is_available()}") | |
| # Environment factory | |
| def env_factory(): | |
| import copy | |
| fresh_config = copy.deepcopy(config) | |
| e = ResolutionAgnosticInspectionEnv(config=fresh_config, use_gpu=args.gpu) | |
| e = NaNSafetyWrapper(e) | |
| e = GRUStateManager(e, policy=model.policy) | |
| return e | |
| # Base env for cleanup | |
| env = env_factory() | |
| # Create test suite with resume support | |
| print(f"\n{'='*80}") | |
| print(f"Initializing Fair Test Suite") | |
| print(f"{'='*80}") | |
| test_suite = FairAdversarialTestSuite( | |
| model=model, | |
| env_factory=env_factory, | |
| output_dir=args.output_dir, | |
| start_test=args.start_test | |
| ) | |
| print(f"Running {len(test_suite.test_cases)} fair tests") | |
| print(f" - Production scenarios: {sum(1 for tc in test_suite.test_cases if tc.difficulty == 'production')}") | |
| print(f" - Stress tests: {sum(1 for tc in test_suite.test_cases if tc.difficulty == 'stress')}") | |
| print(f" - Extreme tests: {sum(1 for tc in test_suite.test_cases if tc.difficulty == 'extreme')}") | |
| if args.start_test > 1: | |
| print(f" - Resuming from Test #{args.start_test}") | |
| # Run tests | |
| try: | |
| test_suite.run_all_tests(num_episodes_per_test=args.num_episodes) | |
| print(f"\n{'='*80}") | |
| print(f"β FAIR ADVERSARIAL VALIDATION COMPLETE") | |
| print(f"{'='*80}") | |
| print(f"Results saved to: {args.output_dir}") | |
| print(f"Review the files in {args.output_dir}") | |
| print(f"{'='*80}\n") | |
| except KeyboardInterrupt: | |
| print("\n\nβ οΈ Validation interrupted by user") | |
| sys.exit(1) | |
| except Exception as e: | |
| print(f"\n\nβ Error during validation: {e}") | |
| import traceback | |
| traceback.print_exc() | |
| sys.exit(1) | |
| finally: | |
| env.close() | |
| if __name__ == "__main__": | |
| main() |