Spaces:
Paused
Paused
Upload 12 files
Browse files- ARCHITECTURE.md +594 -0
- SETUP_INSTRUCTIONS.txt +296 -0
- app.py +82 -7
- best_model copy.onnx +3 -0
- generate_api_key.php +56 -0
- gitattributes +35 -0
- requirements.txt +2 -1
ARCHITECTURE.md
ADDED
|
@@ -0,0 +1,594 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
# 🏗️ Architecture Diagram - Hugging Face Integration
|
| 2 |
+
|
| 3 |
+
## 📐 System Architecture
|
| 4 |
+
|
| 5 |
+
```
|
| 6 |
+
┌──────────────────────────────────────────────────────────────────────────┐
|
| 7 |
+
│ USER INTERFACE │
|
| 8 |
+
│ ┌────────────────────────────────────────────────────────────────────┐ │
|
| 9 |
+
│ │ Browser (Chrome, Firefox, Safari, etc.) │ │
|
| 10 |
+
│ │ • Upload CAPTCHA image │ │
|
| 11 |
+
│ │ • Drag & Drop support │ │
|
| 12 |
+
│ │ • Image preview │ │
|
| 13 |
+
│ │ • Result display │ │
|
| 14 |
+
│ └────────────────────────────────────────────────────────────────────┘ │
|
| 15 |
+
└──────────────────────────┬───────────────────────────────────────────────┘
|
| 16 |
+
│ HTTP/HTTPS
|
| 17 |
+
│ FormData (multipart/form-data)
|
| 18 |
+
▼
|
| 19 |
+
┌──────────────────────────────────────────────────────────────────────────┐
|
| 20 |
+
│ FRONTEND LAYER │
|
| 21 |
+
│ ┌────────────────────────────────────────────────────────────────────┐ │
|
| 22 |
+
│ │ JavaScript (assets/js/script.js) │ │
|
| 23 |
+
│ │ ┌──────────────────────────────────────────────────────────────┐ │ │
|
| 24 |
+
│ │ │ • File validation (type, size) │ │ │
|
| 25 |
+
│ │ │ • FormData creation │ │ │
|
| 26 |
+
│ │ │ • Fetch API call to backend │ │ │
|
| 27 |
+
│ │ │ • Loading state management │ │ │
|
| 28 |
+
│ │ │ • Error handling & display │ │ │
|
| 29 |
+
│ │ │ • Result rendering │ │ │
|
| 30 |
+
│ │ │ • Copy to clipboard │ │ │
|
| 31 |
+
│ │ └──────────────────────────────────────────────────────────────┘ │ │
|
| 32 |
+
│ └────────────────────────────────────────────────────────────────────┘ │
|
| 33 |
+
└──────────────────────────┬───────────────────────────────────────────────┘
|
| 34 |
+
│ POST request
|
| 35 |
+
│ FormData { captcha: File }
|
| 36 |
+
▼
|
| 37 |
+
┌──────────────────────────────────────────────────────────────────────────┐
|
| 38 |
+
│ BACKEND LAYER (PHP) │
|
| 39 |
+
│ ┌────────────────────────────────────────────────────────────────────┐ │
|
| 40 |
+
│ │ API Handler (api/process.php) │ │
|
| 41 |
+
│ │ ┌──────────────────────────────────────────────────────────────┐ │ │
|
| 42 |
+
│ │ │ 1. Validate Request Method (POST only) │ │ │
|
| 43 |
+
│ │ │ 2. Check File Upload │ │ │
|
| 44 |
+
│ │ │ 3. Validate File Type (JPEG, PNG, GIF) │ │ │
|
| 45 |
+
│ │ │ 4. Validate File Size (max 5MB) │ │ │
|
| 46 |
+
│ │ │ 5. Convert Image to Base64 │ │ │
|
| 47 |
+
│ │ │ • Read file contents │ │ │
|
| 48 |
+
│ │ │ • Get MIME type │ │ │
|
| 49 |
+
│ │ │ • Create data URI │ │ │
|
| 50 |
+
│ │ │ 6. Prepare API Request │ │ │
|
| 51 |
+
│ │ │ • JSON payload with base64 image │ │ │
|
| 52 |
+
│ │ │ • Add Authorization header │ │ │
|
| 53 |
+
│ │ │ 7. Call Hugging Face API (cURL) │ │ │
|
| 54 |
+
│ │ │ 8. Parse Response │ │ │
|
| 55 |
+
│ │ │ 9. Format & Return JSON │ │ │
|
| 56 |
+
│ │ └──────────────────────────────────────────────────────────────┘ │ │
|
| 57 |
+
│ └────────────────────────────────────────────────────────────────────┘ │
|
| 58 |
+
│ │
|
| 59 |
+
│ ┌────────────────────────────────────────────────────────────────────┐ │
|
| 60 |
+
│ │ Configuration (config.php) │ │
|
| 61 |
+
│ │ • HF_API_URL │ │
|
| 62 |
+
│ │ • HF_API_KEY │ │
|
| 63 |
+
│ │ • Upload limits & validation rules │ │
|
| 64 |
+
│ └────────────────────────────────────────────────────────────────────┘ │
|
| 65 |
+
└──────────────────────────┬───────────────────────────────────────────────┘
|
| 66 |
+
│ HTTP POST
|
| 67 |
+
│ Authorization: Bearer {API_KEY}
|
| 68 |
+
│ Content-Type: application/json
|
| 69 |
+
│ Body: { image_base64: "..." }
|
| 70 |
+
▼
|
| 71 |
+
┌──────────────────────────────────────────────────────────────────────────┐
|
| 72 |
+
│ HUGGING FACE SPACE │
|
| 73 |
+
│ ┌────────────────────────────────────────────────────────────────────┐ │
|
| 74 |
+
│ │ Flask Server (app.py) │ │
|
| 75 |
+
│ │ ┌──────────────────────────────────────────────────────────────┐ │ │
|
| 76 |
+
│ │ │ Endpoint: /predict │ │ │
|
| 77 |
+
│ │ │ ┌────────────────────────────────────────────────────────┐ │ │ │
|
| 78 |
+
│ │ │ │ 1. Authenticate Request │ │ │ │
|
| 79 |
+
│ │ │ │ • Check Authorization header │ │ │ │
|
| 80 |
+
│ │ │ │ • Verify API_KEY_SECRET │ │ │ │
|
| 81 |
+
│ │ │ │ 2. Decode Base64 Image │ │ │ │
|
| 82 |
+
│ │ │ │ 3. Auto-Crop Image (YOLO) │ │ │ │
|
| 83 |
+
│ │ │ │ • Detect captcha area using YOLO │ │ │ │
|
| 84 |
+
│ │ │ │ • Crop to highest confidence box │ │ │ │
|
| 85 |
+
│ │ │ │ • Fallback to original if no detection │ │ │ │
|
| 86 |
+
│ │ │ │ 4. Preprocess Image │ │ │ │
|
| 87 |
+
│ │ │ │ • Convert to RGB │ │ │ │
|
| 88 |
+
│ │ │ │ • Resize (Albumentations) │ │ │ │
|
| 89 |
+
│ │ │ │ • Normalize │ │ │ │
|
| 90 |
+
│ │ │ │ • ToTensor │ │ │ │
|
| 91 |
+
│ │ │ │ 5. Model Inference │ │ │ │
|
| 92 |
+
│ │ │ │ 6. Decode Predictions │ │ │ │
|
| 93 |
+
│ │ │ │ 7. Calculate Confidence │ │ │ │
|
| 94 |
+
│ │ │ │ 8. Return JSON Response │ │ │ │
|
| 95 |
+
│ │ │ └────────────────────────────────────────────────────────┘ │ │ │
|
| 96 |
+
│ │ └──────────────────────────────────────────────────────────────┘ │ │
|
| 97 |
+
│ └────────────────────────────────────────────────────────────────────┘ │
|
| 98 |
+
│ │
|
| 99 |
+
│ ┌────────────────────────────────────────────────────────────────────┐ │
|
| 100 |
+
│ │ AI Model (PyTorch) │ │
|
| 101 |
+
│ │ ┌──────────────────────────────────────────────────────────────┐ │ │
|
| 102 |
+
│ │ │ Multi-Head Model Architecture │ │ │
|
| 103 |
+
│ │ │ │ │ │
|
| 104 |
+
│ │ │ ┌─────────────────────────────────────────────────────┐ │ │ │
|
| 105 |
+
│ │ │ │ Backbone: EfficientNet (timm) │ │ │ │
|
| 106 |
+
│ │ │ │ • Feature extraction │ │ │ │
|
| 107 |
+
│ │ │ │ • Drop path regularization │ │ │ │
|
| 108 |
+
│ │ │ └──────────────┬──────────────────────────────────────┘ │ │ │
|
| 109 |
+
│ │ │ │ │ │ │
|
| 110 |
+
│ │ │ ┌─────────┴─────────┬─────────────────┐ │ │ │
|
| 111 |
+
│ │ │ ▼ ▼ ▼ │ │ │
|
| 112 |
+
│ │ │ ┌─────────┐ ┌──────────┐ ┌──────────┐ │ │ │
|
| 113 |
+
│ │ │ │ Type │ │ Object │ │ Text │ │ │ │
|
| 114 |
+
│ │ │ │ Head │ │ Head │ │ Head │ │ │ │
|
| 115 |
+
│ │ │ ├─────────┤ ├──────────┤ ├──────────┤ │ │ │
|
| 116 |
+
│ │ │ │ Linear │ │ Linear │ │ Conv2D │ │ │ │
|
| 117 |
+
│ │ │ │ Softmax │ │ Softmax │ │ BiLSTM │ │ │ │
|
| 118 |
+
│ │ │ │ │ │ │ │ Linear │ │ │ │
|
| 119 |
+
│ │ │ │ Output: │ │ Output: │ │ CTC │ │ │ │
|
| 120 |
+
│ │ │ │ text/ │ │ class │ │ Output: │ │ │ │
|
| 121 |
+
│ │ │ │ object │ │ (0-N) │ │ sequence │ │ │ │
|
| 122 |
+
│ │ │ └─────────┘ └──────────┘ └──────────┘ │ │ │
|
| 123 |
+
│ │ │ │ │ │
|
| 124 |
+
│ │ └──────────────────────────────────────────────────────────┘ │ │
|
| 125 |
+
│ │ │ │
|
| 126 |
+
│ │ Model Details: │ │
|
| 127 |
+
│ │ • Quantized INT8 (CPU optimized) │ │
|
| 128 |
+
│ │ • File: best_model_quantized.pth │ │
|
| 129 |
+
│ │ • Size: ~44MB │ │
|
| 130 |
+
│ │ • Mappings: mappings.json │ │
|
| 131 |
+
│ │ • YOLO Crop Model: best_model.onnx │ │
|
| 132 |
+
│ └──────────────────────────────────���─────────────────────────────┘ │
|
| 133 |
+
└──────────────────────────┬───────────────────────────────────────────────┘
|
| 134 |
+
│ JSON Response
|
| 135 |
+
│ {
|
| 136 |
+
│ predicted_type: "text|object",
|
| 137 |
+
│ prediction: "ABC123",
|
| 138 |
+
│ confidence: "97.8%",
|
| 139 |
+
│ ...
|
| 140 |
+
│ }
|
| 141 |
+
▼
|
| 142 |
+
┌──────────────────────────────────────────────────────────────────────────┐
|
| 143 |
+
│ RESPONSE FLOW │
|
| 144 |
+
│ │
|
| 145 |
+
│ Backend (PHP) → Frontend (JS) → User Interface │
|
| 146 |
+
│ │
|
| 147 |
+
│ Formatted JSON → Display Result → Show to User │
|
| 148 |
+
└──────────────────────────────────────────────────────────────────────────┘
|
| 149 |
+
```
|
| 150 |
+
|
| 151 |
+
---
|
| 152 |
+
|
| 153 |
+
## 🔄 Data Flow Diagram
|
| 154 |
+
|
| 155 |
+
```
|
| 156 |
+
┌─────────────┐
|
| 157 |
+
│ User │
|
| 158 |
+
│ Uploads │
|
| 159 |
+
│ CAPTCHA │
|
| 160 |
+
└──────┬──────┘
|
| 161 |
+
│
|
| 162 |
+
│ [Image File: captcha.png]
|
| 163 |
+
▼
|
| 164 |
+
┌─────────────────────────────┐
|
| 165 |
+
│ Frontend Validation │
|
| 166 |
+
│ • Type check: image/* │
|
| 167 |
+
│ • Size check: < 5MB │
|
| 168 |
+
│ • Preview generation │
|
| 169 |
+
└──────┬──────────────────────┘
|
| 170 |
+
│
|
| 171 |
+
│ [FormData]
|
| 172 |
+
▼
|
| 173 |
+
┌─────────────────────────────┐
|
| 174 |
+
│ Backend Processing │
|
| 175 |
+
│ ┌─────────────────────────┐│
|
| 176 |
+
│ │ 1. Receive Upload ││
|
| 177 |
+
│ │ File: $_FILES ││
|
| 178 |
+
│ └─────────┬───────────────┘│
|
| 179 |
+
│ ┌─────────▼───────────────┐│
|
| 180 |
+
│ │ 2. Validate ││
|
| 181 |
+
│ │ Type: JPEG/PNG/GIF ││
|
| 182 |
+
│ │ Size: < 5MB ││
|
| 183 |
+
│ │ Upload OK ││
|
| 184 |
+
│ └─────────┬───────────────┘│
|
| 185 |
+
│ ┌─────────▼───────────────┐│
|
| 186 |
+
│ │ 3. Convert to Base64 ││
|
| 187 |
+
│ │ Read: file_contents ││
|
| 188 |
+
│ │ Encode: base64 ││
|
| 189 |
+
│ │ Format: data:... ││
|
| 190 |
+
│ └─────────┬───────────────┘│
|
| 191 |
+
│ ┌─────────▼───────────────┐│
|
| 192 |
+
│ │ 4. Prepare API Call ││
|
| 193 |
+
│ │ URL: HF_API_URL ││
|
| 194 |
+
│ │ Key: HF_API_KEY ││
|
| 195 |
+
│ │ Body: JSON ││
|
| 196 |
+
│ └─────────┬───────────────┘│
|
| 197 |
+
└────────────┼─────────────────┘
|
| 198 |
+
│
|
| 199 |
+
│ [HTTP POST]
|
| 200 |
+
│ Headers:
|
| 201 |
+
│ Authorization: Bearer xxx
|
| 202 |
+
│ Content-Type: application/json
|
| 203 |
+
│ Body:
|
| 204 |
+
│ { image_base64: "data:..." }
|
| 205 |
+
▼
|
| 206 |
+
┌─────────────────────────────────────┐
|
| 207 |
+
│ Hugging Face Space │
|
| 208 |
+
│ ┌─────────────────────────────────┐│
|
| 209 |
+
│ │ 1. Authenticate ││
|
| 210 |
+
│ │ Verify API key ││
|
| 211 |
+
│ └─────────┬───────────────────────┘│
|
| 212 |
+
│ ┌─────────▼───────────────────────┐│
|
| 213 |
+
│ │ 2. Decode Image ││
|
| 214 |
+
│ │ Base64 → Binary ││
|
| 215 |
+
│ │ Binary → PIL Image ││
|
| 216 |
+
│ │ PIL → RGB ││
|
| 217 |
+
│ └─────────┬───────────────────────┘│
|
| 218 |
+
│ ┌─────────▼────────────────���──────┐│
|
| 219 |
+
│ │ 3. Preprocess ││
|
| 220 |
+
│ │ Resize: Albumentations ││
|
| 221 |
+
│ │ Normalize: ImageNet stats ││
|
| 222 |
+
│ │ ToTensor: [1, 3, H, W] ││
|
| 223 |
+
│ └─────────┬───────────────────────┘│
|
| 224 |
+
│ ┌─────────▼───────────────────────┐│
|
| 225 |
+
│ │ 4. Model Inference ││
|
| 226 |
+
│ │ Input: Tensor [1,3,H,W] ││
|
| 227 |
+
│ │ Forward pass ││
|
| 228 |
+
│ │ Output: 3 heads ││
|
| 229 |
+
│ │ • Type logits ││
|
| 230 |
+
│ │ • Object logits ││
|
| 231 |
+
│ │ • Text log_probs ││
|
| 232 |
+
│ └─────────┬───────────────────────┘│
|
| 233 |
+
│ ┌─────────▼───────────────────────┐│
|
| 234 |
+
│ │ 5. Post-processing ││
|
| 235 |
+
│ │ Softmax: Type & Object ││
|
| 236 |
+
│ │ CTC Decode: Text ││
|
| 237 |
+
│ │ Confidence: Max prob ││
|
| 238 |
+
│ └─────────┬───────────────────────┘│
|
| 239 |
+
│ ┌─────────▼───────────────────────┐│
|
| 240 |
+
│ │ 6. Format Response ││
|
| 241 |
+
│ │ JSON: ││
|
| 242 |
+
│ │ predicted_type ││
|
| 243 |
+
│ │ prediction ││
|
| 244 |
+
│ │ confidence ││
|
| 245 |
+
│ └─────────┬───────────────────────┘│
|
| 246 |
+
└────────────┼─────────────────────────┘
|
| 247 |
+
│
|
| 248 |
+
│ [HTTP 200 OK]
|
| 249 |
+
│ JSON Response
|
| 250 |
+
▼
|
| 251 |
+
┌─────────────────────────────┐
|
| 252 |
+
│ Backend Parsing │
|
| 253 |
+
│ • Extract data │
|
| 254 |
+
│ • Add timestamp │
|
| 255 |
+
│ • Calculate process time │
|
| 256 |
+
│ • Format response │
|
| 257 |
+
└──────┬──────────────────────┘
|
| 258 |
+
│
|
| 259 |
+
│ [JSON]
|
| 260 |
+
│ {
|
| 261 |
+
│ success: true,
|
| 262 |
+
│ data: { ... }
|
| 263 |
+
│ }
|
| 264 |
+
▼
|
| 265 |
+
┌─────────────────────────────┐
|
| 266 |
+
│ Frontend Rendering │
|
| 267 |
+
│ • Parse JSON │
|
| 268 |
+
│ • Update DOM │
|
| 269 |
+
│ • Show result │
|
| 270 |
+
│ • Enable copy button │
|
| 271 |
+
└──────┬──────────────────────┘
|
| 272 |
+
│
|
| 273 |
+
▼
|
| 274 |
+
┌─────────────┐
|
| 275 |
+
│ User │
|
| 276 |
+
│ Sees │
|
| 277 |
+
│ Result │
|
| 278 |
+
└─────────────┘
|
| 279 |
+
```
|
| 280 |
+
|
| 281 |
+
---
|
| 282 |
+
|
| 283 |
+
## 🧩 Component Interaction
|
| 284 |
+
|
| 285 |
+
### Frontend Components
|
| 286 |
+
|
| 287 |
+
```
|
| 288 |
+
index.php
|
| 289 |
+
├── Header (Navigation)
|
| 290 |
+
├── Hero Section
|
| 291 |
+
├── Demo Section
|
| 292 |
+
│ ├── Upload Area
|
| 293 |
+
│ │ ├── Click to upload
|
| 294 |
+
│ │ ├── Drag & drop
|
| 295 |
+
│ │ └── File input
|
| 296 |
+
│ ├── Preview Area
|
| 297 |
+
│ │ ├── Image preview
|
| 298 |
+
│ │ └── Remove button
|
| 299 |
+
│ ├── Process Button
|
| 300 |
+
│ │ ├── Loading spinner
|
| 301 |
+
│ │ └── Click handler
|
| 302 |
+
│ └── Result Area
|
| 303 |
+
│ ├── Prediction text
|
| 304 |
+
│ ├── Confidence score
|
| 305 |
+
│ ├── Process time
|
| 306 |
+
│ └── Copy button
|
| 307 |
+
├── Features Section
|
| 308 |
+
├── Pricing Section
|
| 309 |
+
└── Footer
|
| 310 |
+
|
| 311 |
+
assets/js/script.js
|
| 312 |
+
├── Particles animation
|
| 313 |
+
├── Smooth scroll
|
| 314 |
+
├── Upload handling
|
| 315 |
+
│ ├── File validation
|
| 316 |
+
│ ├── Preview generation
|
| 317 |
+
│ └── Drag & drop events
|
| 318 |
+
├── API calling
|
| 319 |
+
│ ├── FormData creation
|
| 320 |
+
│ ├── Fetch request
|
| 321 |
+
│ └── Response handling
|
| 322 |
+
├── Result display
|
| 323 |
+
│ ├── DOM updates
|
| 324 |
+
│ └── Copy to clipboard
|
| 325 |
+
└── Notification system
|
| 326 |
+
```
|
| 327 |
+
|
| 328 |
+
### Backend Components
|
| 329 |
+
|
| 330 |
+
```
|
| 331 |
+
api/process.php
|
| 332 |
+
├── Request validation
|
| 333 |
+
│ ├── Method check (POST)
|
| 334 |
+
│ ├── File check
|
| 335 |
+
│ ├── Type check
|
| 336 |
+
│ └── Size check
|
| 337 |
+
├── Image processing
|
| 338 |
+
│ ├── Read file
|
| 339 |
+
│ ├── Get MIME type
|
| 340 |
+
│ └── Base64 encoding
|
| 341 |
+
├── API communication
|
| 342 |
+
│ ├── cURL initialization
|
| 343 |
+
│ ├── Headers setup
|
| 344 |
+
│ │ ├── Content-Type
|
| 345 |
+
│ │ └── Authorization
|
| 346 |
+
│ ├── POST request
|
| 347 |
+
│ ├── Response handling
|
| 348 |
+
│ └── Error handling
|
| 349 |
+
└── Response formatting
|
| 350 |
+
├── Parse HF response
|
| 351 |
+
├── Calculate metrics
|
| 352 |
+
└── Return JSON
|
| 353 |
+
|
| 354 |
+
config.php
|
| 355 |
+
├── Site configuration
|
| 356 |
+
├── Upload configuration
|
| 357 |
+
├── API configuration
|
| 358 |
+
│ ├── HF_API_URL
|
| 359 |
+
│ └── HF_API_KEY
|
| 360 |
+
├── Database configuration
|
| 361 |
+
└── Helper functions
|
| 362 |
+
```
|
| 363 |
+
|
| 364 |
+
### Model Components
|
| 365 |
+
|
| 366 |
+
```
|
| 367 |
+
Hugging Face Space
|
| 368 |
+
├── app.py (Flask Server)
|
| 369 |
+
│ ├── Route: /
|
| 370 |
+
│ ├── Route: /predict
|
| 371 |
+
│ ├── Authentication
|
| 372 |
+
│ ├── Image preprocessing
|
| 373 |
+
│ ├── Model inference
|
| 374 |
+
│ └── Response formatting
|
| 375 |
+
├── Model (MultiHeadModel)
|
| 376 |
+
│ ├── Backbone (EfficientNet)
|
| 377 |
+
│ │ └── Feature extraction
|
| 378 |
+
│ ├── Type Head
|
| 379 |
+
│ │ ├── AdaptiveAvgPool2d
|
| 380 |
+
│ │ ├── Linear
|
| 381 |
+
│ │ └── Softmax
|
| 382 |
+
│ ├── Object Head
|
| 383 |
+
│ │ ├── AdaptiveAvgPool2d
|
| 384 |
+
│ │ ├── Linear
|
| 385 |
+
│ │ └── Softmax
|
| 386 |
+
│ └── Text Head
|
| 387 |
+
│ ├── Conv2d projection
|
| 388 |
+
│ ├── BiLSTM
|
| 389 |
+
│ ├── Linear
|
| 390 |
+
│ └── CTC Loss/Decode
|
| 391 |
+
├── Preprocessing (Albumentations)
|
| 392 |
+
│ ├── Resize
|
| 393 |
+
│ ├── Normalize
|
| 394 |
+
│ └── ToTensor
|
| 395 |
+
└── Post-processing
|
| 396 |
+
├── Softmax (type/object)
|
| 397 |
+
├── CTC Decoder (text)
|
| 398 |
+
└── Confidence calculation
|
| 399 |
+
```
|
| 400 |
+
|
| 401 |
+
---
|
| 402 |
+
|
| 403 |
+
## 🔐 Security Architecture
|
| 404 |
+
|
| 405 |
+
```
|
| 406 |
+
┌─────────────────────────────────────────────┐
|
| 407 |
+
│ Security Layers │
|
| 408 |
+
├─────────────────────────────────────────────┤
|
| 409 |
+
│ │
|
| 410 |
+
│ Layer 1: Frontend Validation │
|
| 411 |
+
│ • File type check (client-side) │
|
| 412 |
+
│ • File size check (client-side) │
|
| 413 |
+
│ • CSRF token (if implemented) │
|
| 414 |
+
│ │
|
| 415 |
+
├─────────────────────────────────────────────┤
|
| 416 |
+
│ │
|
| 417 |
+
│ Layer 2: Backend Validation │
|
| 418 |
+
│ • HTTP method check (POST only) │
|
| 419 |
+
│ • File upload validation │
|
| 420 |
+
│ • MIME type verification │
|
| 421 |
+
│ • File size enforcement (5MB) │
|
| 422 |
+
│ • Input sanitization │
|
| 423 |
+
│ │
|
| 424 |
+
├─────────────────────────────────────────────┤
|
| 425 |
+
│ │
|
| 426 |
+
│ Layer 3: API Authentication │
|
| 427 |
+
│ • Bearer token required │
|
| 428 |
+
│ • API key verification │
|
| 429 |
+
│ • Request header validation │
|
| 430 |
+
│ │
|
| 431 |
+
├─────────────────────────────────────────────┤
|
| 432 |
+
│ │
|
| 433 |
+
│ Layer 4: Hugging Face Security │
|
| 434 |
+
│ • Environment secrets │
|
| 435 |
+
│ • API key stored securely │
|
| 436 |
+
│ • Request authentication │
|
| 437 |
+
│ • Rate limiting (HF platform) │
|
| 438 |
+
│ │
|
| 439 |
+
├─────────────────────────────────────────────┤
|
| 440 |
+
│ │
|
| 441 |
+
│ Layer 5: Error Handling │
|
| 442 |
+
│ • Try-catch blocks │
|
| 443 |
+
│ • Graceful degradation │
|
| 444 |
+
│ • User-friendly errors │
|
| 445 |
+
│ • Detailed logging (server-side) │
|
| 446 |
+
│ │
|
| 447 |
+
└─────────────────────────────────────────────┘
|
| 448 |
+
|
| 449 |
+
API Key Flow:
|
| 450 |
+
1. Generate: generate_api_key.php
|
| 451 |
+
2. Store: Hugging Face Space Secrets (API_KEY_SECRET)
|
| 452 |
+
3. Configure: config.php (HF_API_KEY)
|
| 453 |
+
4. Use: api/process.php (Authorization header)
|
| 454 |
+
5. Verify: app.py (authenticate request)
|
| 455 |
+
|
| 456 |
+
Security Best Practices:
|
| 457 |
+
✅ API key not in Git (.gitignore)
|
| 458 |
+
✅ HTTPS in production
|
| 459 |
+
✅ Input validation (multiple layers)
|
| 460 |
+
✅ Error messages (no sensitive info exposed)
|
| 461 |
+
✅ Rate limiting (can be added)
|
| 462 |
+
✅ Logging (for audit trails)
|
| 463 |
+
```
|
| 464 |
+
|
| 465 |
+
---
|
| 466 |
+
|
| 467 |
+
## 📊 Performance Architecture
|
| 468 |
+
|
| 469 |
+
```
|
| 470 |
+
Performance Optimization Points:
|
| 471 |
+
|
| 472 |
+
┌──────────────────────────┐
|
| 473 |
+
│ Frontend │
|
| 474 |
+
│ • Image compression │
|
| 475 |
+
│ • Lazy loading │
|
| 476 |
+
│ • Debouncing │
|
| 477 |
+
│ • Caching results │
|
| 478 |
+
└──────────┬───────────────┘
|
| 479 |
+
│
|
| 480 |
+
▼
|
| 481 |
+
┌──────────────────────────┐
|
| 482 |
+
│ Network │
|
| 483 |
+
│ • Compression (gzip) │
|
| 484 |
+
│ • Keep-alive │
|
| 485 |
+
│ • CDN (assets) │
|
| 486 |
+
└──────────┬───────────────┘
|
| 487 |
+
│
|
| 488 |
+
▼
|
| 489 |
+
┌──────────────────────────┐
|
| 490 |
+
│ Backend │
|
| 491 |
+
│ • cURL optimization │
|
| 492 |
+
│ • Connection pooling │
|
| 493 |
+
│ • Response caching │
|
| 494 |
+
└──────────┬───────────────┘
|
| 495 |
+
│
|
| 496 |
+
▼
|
| 497 |
+
┌──────────────────────────┐
|
| 498 |
+
│ Hugging Face │
|
| 499 |
+
│ • Model quantization │
|
| 500 |
+
│ • Batch processing │
|
| 501 |
+
│ • Keep space awake │
|
| 502 |
+
│ • Warm start (ping) │
|
| 503 |
+
└──────────┬───────────────┘
|
| 504 |
+
│
|
| 505 |
+
▼
|
| 506 |
+
┌──────────────────────────┐
|
| 507 |
+
│ Model │
|
| 508 |
+
│ • INT8 quantization │
|
| 509 |
+
│ • CPU optimized │
|
| 510 |
+
│ • Efficient backbone │
|
| 511 |
+
│ • Single thread │
|
| 512 |
+
└──────────────────────────┘
|
| 513 |
+
|
| 514 |
+
Expected Response Times:
|
| 515 |
+
• Cold Start: 30-60 seconds (first request)
|
| 516 |
+
• Warm: 1-3 seconds (subsequent)
|
| 517 |
+
• Optimal: < 2 seconds (good connection)
|
| 518 |
+
|
| 519 |
+
Optimization Strategies:
|
| 520 |
+
1. Keep Space Awake: Ping every 10 min
|
| 521 |
+
2. Image Optimization: Resize before upload
|
| 522 |
+
3. Connection Pooling: Reuse cURL handles
|
| 523 |
+
4. Response Caching: Cache similar images
|
| 524 |
+
5. Upgrade HF Plan: No cold start (Pro)
|
| 525 |
+
```
|
| 526 |
+
|
| 527 |
+
---
|
| 528 |
+
|
| 529 |
+
## 🗂️ File Structure
|
| 530 |
+
|
| 531 |
+
```
|
| 532 |
+
Captchakings.com/
|
| 533 |
+
│
|
| 534 |
+
├── index.php # Main landing page
|
| 535 |
+
├── login.php # Login page
|
| 536 |
+
├── register.php # Registration page
|
| 537 |
+
├── dashboard.php # User dashboard
|
| 538 |
+
├── config.php # ⚙️ Configuration (HF_API_KEY here!)
|
| 539 |
+
│
|
| 540 |
+
├── api/
|
| 541 |
+
│ ├── process.php # 🔄 Main API handler (HF integration)
|
| 542 |
+
│ └── auth.php # Authentication API
|
| 543 |
+
│
|
| 544 |
+
├── assets/
|
| 545 |
+
│ ├── css/
|
| 546 |
+
│ │ └── style.css # Styles
|
| 547 |
+
│ ├── js/
|
| 548 |
+
│ │ └── script.js # 🔄 Frontend logic (API calls)
|
| 549 |
+
│ └── images/ # Static images
|
| 550 |
+
│
|
| 551 |
+
├── HF/ # 🤗 Hugging Face files
|
| 552 |
+
│ ├── app.py # Flask server
|
| 553 |
+
│ ├── best_model_quantized.pth # Model weights (44MB)
|
| 554 |
+
│ ├── best_model.onnx # ONNX model (43MB)
|
| 555 |
+
│ ├── mappings.json # Class mappings
|
| 556 |
+
│ ├── requirements.txt # Python dependencies
|
| 557 |
+
│ ├── Dockerfile # Docker config
|
| 558 |
+
│ ├── README.md # HF Space README
|
| 559 |
+
│ ├── INTEGRATION_GUIDE.md # 📚 Detailed guide
|
| 560 |
+
│ ├── README_INTEGRATION.md # 📖 Quick reference
|
| 561 |
+
│ ├── SETUP_INSTRUCTIONS.txt # 📋 Visual setup
|
| 562 |
+
│ ├── QUICK_REFERENCE.md # 🚀 Quick ref card
|
| 563 |
+
│ ├── ARCHITECTURE.md # 🏗️ This file!
|
| 564 |
+
│ └── generate_api_key.php # 🔑 Key generator
|
| 565 |
+
│
|
| 566 |
+
├── includes/
|
| 567 |
+
│ ├── db.php # Database connection
|
| 568 |
+
│ └── auth.php # Auth functions
|
| 569 |
+
│
|
| 570 |
+
├── uploads/ # User uploads (temp)
|
| 571 |
+
│
|
| 572 |
+
├── test_hf_integration.php # 🧪 Test utility
|
| 573 |
+
├── test_integration.bat # Windows test script
|
| 574 |
+
├── INTEGRATION_SUMMARY.md # 📄 Complete summary
|
| 575 |
+
│
|
| 576 |
+
├── .gitignore # Git ignore rules
|
| 577 |
+
├── database.sql # Database schema
|
| 578 |
+
└── README.md # Project README
|
| 579 |
+
|
| 580 |
+
Legend:
|
| 581 |
+
🔄 = Modified for HF integration
|
| 582 |
+
⚙️ = Configuration file (sensitive!)
|
| 583 |
+
🤗 = Hugging Face specific
|
| 584 |
+
📚 = Documentation
|
| 585 |
+
🧪 = Testing utility
|
| 586 |
+
🔑 = Security/API keys
|
| 587 |
+
```
|
| 588 |
+
|
| 589 |
+
---
|
| 590 |
+
|
| 591 |
+
**Made with ❤️ for CaptchaKings.com**
|
| 592 |
+
**Architecture Design: Multi-layer, Secure, Scalable**
|
| 593 |
+
**Last Updated: 2024-01-01**
|
| 594 |
+
|
SETUP_INSTRUCTIONS.txt
ADDED
|
@@ -0,0 +1,296 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
╔══════════════════════════════════════════════════════════════════════════════╗
|
| 2 |
+
║ ║
|
| 3 |
+
║ 🚀 SETUP INTEGRASI HUGGING FACE MODEL - CAPTCHAKINGS.COM ║
|
| 4 |
+
║ ║
|
| 5 |
+
║ Model sudah tidak dummy lagi! Sekarang menggunakan AI prediction real ║
|
| 6 |
+
║ dari Hugging Face Space. ║
|
| 7 |
+
║ ║
|
| 8 |
+
╚══════════════════════════════════════════════════════════════════════════════╝
|
| 9 |
+
|
| 10 |
+
|
| 11 |
+
📋 LANGKAH-LANGKAH SETUP (Total: 5 menit)
|
| 12 |
+
═══════════════════════════════════════════════════════════════════════════════
|
| 13 |
+
|
| 14 |
+
|
| 15 |
+
┌─────────────────────────────────────────────────────────────────────────────┐
|
| 16 |
+
│ STEP 1: Generate API Key │
|
| 17 |
+
└─────────────────────────────────────────────────────────────────────────────┘
|
| 18 |
+
|
| 19 |
+
1. Buka terminal/command prompt
|
| 20 |
+
2. Navigate ke folder project:
|
| 21 |
+
|
| 22 |
+
cd C:\Users\Administrator\Desktop\Captchakings.com
|
| 23 |
+
|
| 24 |
+
3. Run generator:
|
| 25 |
+
|
| 26 |
+
php HF\generate_api_key.php
|
| 27 |
+
|
| 28 |
+
4. Copy salah satu generated key (contoh):
|
| 29 |
+
|
| 30 |
+
a7f3d9e2b1c8f5a6d4e9b2c7f1a5d8e3b6c9f2a7d4e1b8c5f9a3d6e2b1c7f4a8
|
| 31 |
+
|
| 32 |
+
|
| 33 |
+
┌─────────────────────────────────────────────────────────────────────────────┐
|
| 34 |
+
│ STEP 2: Setup Hugging Face Space │
|
| 35 |
+
└─────────────────────────────────────────────────────────────────────────────┘
|
| 36 |
+
|
| 37 |
+
1. Buka browser, kunjungi:
|
| 38 |
+
|
| 39 |
+
https://huggingface.co/spaces/doniramdani820/Textbaru
|
| 40 |
+
|
| 41 |
+
2. Login ke Hugging Face account Anda
|
| 42 |
+
|
| 43 |
+
3. Klik tab "Settings" (icon gear/roda)
|
| 44 |
+
|
| 45 |
+
4. Scroll ke bagian "Variables and secrets"
|
| 46 |
+
|
| 47 |
+
5. Klik "New secret" button
|
| 48 |
+
|
| 49 |
+
6. Isi form:
|
| 50 |
+
Name: API_KEY_SECRET
|
| 51 |
+
Value: [paste key dari Step 1]
|
| 52 |
+
|
| 53 |
+
7. Klik "Save"
|
| 54 |
+
|
| 55 |
+
8. PENTING: Restart space jika diminta
|
| 56 |
+
(Biasanya otomatis restart setelah add secret)
|
| 57 |
+
|
| 58 |
+
9. Tunggu hingga status Space = "Running" (biasanya 30-60 detik)
|
| 59 |
+
|
| 60 |
+
|
| 61 |
+
┌─────────────────────────────────────────────────────────────────────────────┐
|
| 62 |
+
│ STEP 3: Update config.php │
|
| 63 |
+
└─────────────────────────────────────────────────────────────────────────────┘
|
| 64 |
+
|
| 65 |
+
1. Buka file config.php dengan text editor
|
| 66 |
+
|
| 67 |
+
2. Cari baris ini:
|
| 68 |
+
|
| 69 |
+
define('HF_API_KEY', 'YOUR_HUGGINGFACE_API_KEY');
|
| 70 |
+
|
| 71 |
+
3. Ganti dengan key yang sama dari Step 1:
|
| 72 |
+
|
| 73 |
+
define('HF_API_KEY', 'a7f3d9e2b1c8f5a6d4e9b2c7f1a5d8e3b6c9f2a7d4e1b8c5f9a3d6e2b1c7f4a8');
|
| 74 |
+
|
| 75 |
+
⚠️ Gunakan KEY YANG SAMA dengan yang di Hugging Face!
|
| 76 |
+
|
| 77 |
+
4. Save file config.php
|
| 78 |
+
|
| 79 |
+
|
| 80 |
+
┌─────────────────────────────────────────────────────────────────────────────┐
|
| 81 |
+
│ STEP 4: Test Integration │
|
| 82 |
+
└─────────────────────────────────────────────────────────────────────────────┘
|
| 83 |
+
|
| 84 |
+
1. Pastikan web server (XAMPP/WAMP) sudah running
|
| 85 |
+
|
| 86 |
+
2. Buka browser, kunjungi:
|
| 87 |
+
|
| 88 |
+
http://localhost/Captchakings.com/test_hf_integration.php
|
| 89 |
+
|
| 90 |
+
3. Check semua status indicators:
|
| 91 |
+
|
| 92 |
+
✓ Hugging Face API URL → Harus ada URL
|
| 93 |
+
✓ Hugging Face API Key → Harus masked (xxxxxxxx...xxxxxxxx)
|
| 94 |
+
✓ PHP Extension: curl → Loaded
|
| 95 |
+
✓ PHP Extension: json → Loaded
|
| 96 |
+
✓ PHP Extension: fileinfo → Loaded
|
| 97 |
+
✅ Semua konfigurasi OK!
|
| 98 |
+
✅ Connection successful!
|
| 99 |
+
✅ Hugging Face Space is running correctly!
|
| 100 |
+
|
| 101 |
+
4. Jika ada ❌ atau ⚠️:
|
| 102 |
+
- Baca error message
|
| 103 |
+
- Periksa kembali Step 1-3
|
| 104 |
+
- Lihat troubleshooting di bawah
|
| 105 |
+
|
| 106 |
+
|
| 107 |
+
┌─────────────────────────────────────────────────────────────────────────────┐
|
| 108 |
+
│ STEP 5: Test Live Prediction │
|
| 109 |
+
└─────────────────────────────────────────────────────────────────────────────┘
|
| 110 |
+
|
| 111 |
+
A. Dari Test Page (test_hf_integration.php):
|
| 112 |
+
|
| 113 |
+
1. Scroll ke bagian "Live CAPTCHA Test"
|
| 114 |
+
2. Klik "Choose File"
|
| 115 |
+
3. Pilih gambar CAPTCHA (test_captcha.html punya contoh)
|
| 116 |
+
4. Klik "🚀 Test Prediction"
|
| 117 |
+
5. Tunggu hasil (first time bisa 30-60 detik karena cold start)
|
| 118 |
+
6. Lihat hasil prediksi dengan confidence score!
|
| 119 |
+
|
| 120 |
+
B. Dari Main Website:
|
| 121 |
+
|
| 122 |
+
1. Buka: http://localhost/Captchakings.com/
|
| 123 |
+
2. Scroll ke section "Demo"
|
| 124 |
+
3. Upload/drag gambar CAPTCHA
|
| 125 |
+
4. Klik "Process CAPTCHA"
|
| 126 |
+
5. Lihat hasil REAL prediction dari AI model! 🎉
|
| 127 |
+
|
| 128 |
+
|
| 129 |
+
═══════════════════════════════════════════════════════════════════════════════
|
| 130 |
+
🎉 SELESAI! Integrasi Berhasil!
|
| 131 |
+
═══════════════════════════════════════════════════════════════════════════════
|
| 132 |
+
|
| 133 |
+
Sekarang sistem Anda menggunakan AI model yang REAL dari Hugging Face!
|
| 134 |
+
|
| 135 |
+
✅ Prediction REAL (bukan dummy)
|
| 136 |
+
✅ Confidence score REAL
|
| 137 |
+
✅ Support text & object CAPTCHA
|
| 138 |
+
✅ Process time tracking
|
| 139 |
+
|
| 140 |
+
|
| 141 |
+
═══════════════════════════════════════════════════════════════════════════════
|
| 142 |
+
🐛 TROUBLESHOOTING
|
| 143 |
+
═══════════════════════════════════════════════════════════════════════════════
|
| 144 |
+
|
| 145 |
+
|
| 146 |
+
╔════════════════════════════════════════════════════════════════════════════╗
|
| 147 |
+
║ Problem: "API key not configured" ║
|
| 148 |
+
╚════════════════════════════════════════════════════════════════════════════╝
|
| 149 |
+
|
| 150 |
+
❌ Cause: API key di config.php masih default
|
| 151 |
+
|
| 152 |
+
✅ Solution:
|
| 153 |
+
1. Check config.php
|
| 154 |
+
2. Pastikan BUKAN 'YOUR_HUGGINGFACE_API_KEY'
|
| 155 |
+
3. Harus API key yang real
|
| 156 |
+
|
| 157 |
+
|
| 158 |
+
╔════════════════════════════════════════════════════════════════════════════╗
|
| 159 |
+
║ Problem: "Connection Error" atau "Connection timeout" ║
|
| 160 |
+
╚════════════════════════════════════════════════════════════════════════════╝
|
| 161 |
+
|
| 162 |
+
❌ Possible Causes:
|
| 163 |
+
- Hugging Face Space sedang sleep (cold start)
|
| 164 |
+
- Internet connection issue
|
| 165 |
+
- Space sedang building/restarting
|
| 166 |
+
|
| 167 |
+
✅ Solutions:
|
| 168 |
+
1. Buka Space URL di browser untuk "wake up":
|
| 169 |
+
https://doniramdani820-textbaru.hf.space/
|
| 170 |
+
|
| 171 |
+
2. Tunggu 30-60 detik untuk cold start
|
| 172 |
+
|
| 173 |
+
3. Check internet connection
|
| 174 |
+
|
| 175 |
+
4. Check Space status di Hugging Face (harus "Running")
|
| 176 |
+
|
| 177 |
+
|
| 178 |
+
╔════════════════════════════════════════════════════════════════════════════╗
|
| 179 |
+
║ Problem: "Akses ditolak" (HTTP 403) ║
|
| 180 |
+
╚═════���══════════════════════════════════════════════════════════════════════╝
|
| 181 |
+
|
| 182 |
+
❌ Cause: API key tidak match
|
| 183 |
+
|
| 184 |
+
✅ Solution:
|
| 185 |
+
API key di config.php HARUS SAMA PERSIS dengan API_KEY_SECRET di HF Space!
|
| 186 |
+
|
| 187 |
+
1. Check API_KEY_SECRET di Hugging Face Space Settings
|
| 188 |
+
2. Check HF_API_KEY di config.php
|
| 189 |
+
3. Pastikan match persis (no extra spaces/newlines)
|
| 190 |
+
4. If needed, delete & create new secret
|
| 191 |
+
|
| 192 |
+
|
| 193 |
+
╔════════════════════════════════════════════════════════════════════════════╗
|
| 194 |
+
║ Problem: PHP Extension not loaded (curl/json/fileinfo) ║
|
| 195 |
+
╚════════════════════════════════════════════════════════════════════════════╝
|
| 196 |
+
|
| 197 |
+
❌ Cause: PHP extension tidak terinstall
|
| 198 |
+
|
| 199 |
+
✅ Solution:
|
| 200 |
+
|
| 201 |
+
Windows (XAMPP/WAMP):
|
| 202 |
+
1. Open php.ini
|
| 203 |
+
2. Uncomment (remove ;):
|
| 204 |
+
extension=curl
|
| 205 |
+
extension=json
|
| 206 |
+
extension=fileinfo
|
| 207 |
+
3. Restart Apache
|
| 208 |
+
|
| 209 |
+
Linux:
|
| 210 |
+
sudo apt-get install php-curl php-json
|
| 211 |
+
sudo systemctl restart apache2
|
| 212 |
+
|
| 213 |
+
|
| 214 |
+
╔════════════════════════════════════════════════════════════════════════════╗
|
| 215 |
+
║ Problem: Space status "Building" atau "Sleeping" ║
|
| 216 |
+
╚════════════════════════════════════════════════════════════════════════════╝
|
| 217 |
+
|
| 218 |
+
❌ Cause: Space tidak ready
|
| 219 |
+
|
| 220 |
+
✅ Solution:
|
| 221 |
+
1. Wait for status to become "Running"
|
| 222 |
+
2. Building biasanya 2-5 menit (pertama kali)
|
| 223 |
+
3. Sleeping: kunjungi URL untuk wake up
|
| 224 |
+
4. Monitor logs di Hugging Face Space page
|
| 225 |
+
|
| 226 |
+
|
| 227 |
+
╔════════════════════════════════════════════════════════════════════════════╗
|
| 228 |
+
║ Problem: Prediction lambat (> 10 detik) ║
|
| 229 |
+
╚════════════════════════════════════════════════════════════════════════════╝
|
| 230 |
+
|
| 231 |
+
❌ Cause: Cold start atau model loading
|
| 232 |
+
|
| 233 |
+
✅ Solutions:
|
| 234 |
+
|
| 235 |
+
A. Keep Space Awake (Recommended):
|
| 236 |
+
- Ping space setiap 10 menit
|
| 237 |
+
- Create cron job (Linux) atau Task Scheduler (Windows)
|
| 238 |
+
- Command: curl https://doniramdani820-textbaru.hf.space/
|
| 239 |
+
|
| 240 |
+
B. Upgrade Hugging Face Plan:
|
| 241 |
+
- Free tier: Space sleep after inactivity
|
| 242 |
+
- Pro plan: Persistent space (no sleep)
|
| 243 |
+
|
| 244 |
+
C. Optimize:
|
| 245 |
+
- Resize image before upload
|
| 246 |
+
- Use PNG/JPEG (not GIF)
|
| 247 |
+
- Keep image size < 500KB
|
| 248 |
+
|
| 249 |
+
|
| 250 |
+
═══════════════════════════════════════════════════════════════════════════════
|
| 251 |
+
📚 DOKUMENTASI LENGKAP
|
| 252 |
+
═══════════════════════════════════════════════════════════════════════════════
|
| 253 |
+
|
| 254 |
+
📖 Panduan Detail: HF\INTEGRATION_GUIDE.md
|
| 255 |
+
📝 Changelog & Info: HF\README_INTEGRATION.md
|
| 256 |
+
🧪 Test Utility: test_hf_integration.php
|
| 257 |
+
🔑 API Key Generator: HF\generate_api_key.php
|
| 258 |
+
|
| 259 |
+
|
| 260 |
+
═══════════════════════════════════════════════════════════════════════════════
|
| 261 |
+
🔐 SECURITY CHECKLIST
|
| 262 |
+
═══════════════════════════════════════════════════════════════════════════════
|
| 263 |
+
|
| 264 |
+
Before Production:
|
| 265 |
+
|
| 266 |
+
[ ] API key TIDAK di-commit ke Git
|
| 267 |
+
[ ] Add config.php ke .gitignore
|
| 268 |
+
[ ] HTTPS enabled
|
| 269 |
+
[ ] Error reporting OFF (production)
|
| 270 |
+
[ ] File upload validation active
|
| 271 |
+
[ ] Rate limiting implemented
|
| 272 |
+
[ ] Monitoring & logging active
|
| 273 |
+
[ ] Backup strategy ready
|
| 274 |
+
|
| 275 |
+
|
| 276 |
+
═══════════════════════════���═══════════════════════════════════════════════════
|
| 277 |
+
📞 NEED HELP?
|
| 278 |
+
═══════════════════════════════════════════════════════════════════════════════
|
| 279 |
+
|
| 280 |
+
1. Run test page: test_hf_integration.php
|
| 281 |
+
2. Check error logs (PHP & Hugging Face)
|
| 282 |
+
3. Read INTEGRATION_GUIDE.md
|
| 283 |
+
4. Verify all configurations
|
| 284 |
+
5. Check Hugging Face Space status & logs
|
| 285 |
+
|
| 286 |
+
|
| 287 |
+
═══════════════════════════════════════════════════════════════════════════════
|
| 288 |
+
|
| 289 |
+
Made with ❤️ for CaptchaKings.com
|
| 290 |
+
Model: Multi-head CAPTCHA Prediction (Text + Object)
|
| 291 |
+
Powered by: Hugging Face Spaces + PyTorch
|
| 292 |
+
|
| 293 |
+
👑 Raja Otomatisasi CAPTCHA
|
| 294 |
+
|
| 295 |
+
═══════════════════════════════════════════════════════════════════════════════
|
| 296 |
+
|
app.py
CHANGED
|
@@ -1,6 +1,7 @@
|
|
| 1 |
# server.py
|
| 2 |
# Server Flask untuk prediksi multi-head captcha yang disesuaikan untuk Hugging Face Spaces.
|
| 3 |
# Versi ini sudah dioptimalkan untuk memuat model yang terkuantisasi (INT8).
|
|
|
|
| 4 |
|
| 5 |
from flask import Flask, request, jsonify
|
| 6 |
from flask_cors import CORS
|
|
@@ -18,6 +19,7 @@ import base64
|
|
| 18 |
from io import BytesIO
|
| 19 |
import sys
|
| 20 |
import logging
|
|
|
|
| 21 |
|
| 22 |
torch.set_num_threads(1)
|
| 23 |
|
|
@@ -33,6 +35,7 @@ MODEL = None
|
|
| 33 |
MAPPINGS = None
|
| 34 |
DEVICE = None
|
| 35 |
TRANSFORMS = None
|
|
|
|
| 36 |
|
| 37 |
# ==============================================================================
|
| 38 |
# BAGIAN 2: DEFINISI MODEL (TIDAK ADA PERUBAHAN)
|
|
@@ -77,9 +80,60 @@ class MultiHeadModel(nn.Module):
|
|
| 77 |
return type_logits, object_logits, text_log_probs
|
| 78 |
|
| 79 |
# ==============================================================================
|
| 80 |
-
# BAGIAN 3: FUNGSI HELPER (
|
| 81 |
# ==============================================================================
|
| 82 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 83 |
def get_transforms(img_height, img_width):
|
| 84 |
interpolation_method = cv2.INTER_AREA
|
| 85 |
return A.Compose([
|
|
@@ -113,14 +167,28 @@ def ctc_decoder_with_confidence(log_probs, idx_to_char_map, blank_idx):
|
|
| 113 |
return final_text, avg_confidence
|
| 114 |
|
| 115 |
# ==============================================================================
|
| 116 |
-
# BAGIAN 4: INISIALISASI SERVER (VERSI UNTUK MODEL KUANTISASI)
|
| 117 |
# ==============================================================================
|
| 118 |
|
| 119 |
-
def initialize_server(model_path, mappings_path):
|
| 120 |
-
global MODEL, MAPPINGS, DEVICE, TRANSFORMS
|
| 121 |
-
logging.info("Memulai inisialisasi server dengan model terkuantisasi...")
|
| 122 |
DEVICE = torch.device("cpu") # Kuantisasi INT8 dioptimalkan untuk CPU
|
| 123 |
logging.info(f"Menggunakan device: {DEVICE}")
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 124 |
|
| 125 |
try:
|
| 126 |
if not os.path.exists(mappings_path):
|
|
@@ -220,8 +288,14 @@ def predict_endpoint():
|
|
| 220 |
return jsonify({"error": "Gagal memproses gambar."}), 500
|
| 221 |
|
| 222 |
try:
|
|
|
|
| 223 |
image_rgb = np.array(img_pil)
|
| 224 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 225 |
|
| 226 |
with torch.no_grad():
|
| 227 |
type_logits, object_logits, text_log_probs = MODEL(img_tensor)
|
|
@@ -263,9 +337,10 @@ def predict_endpoint():
|
|
| 263 |
# Menggunakan file model baru yang sudah terkuantisasi
|
| 264 |
MODEL_FILE_PATH = "best_model_quantized.pth"
|
| 265 |
MAPPINGS_FILE_PATH = "mappings.json"
|
|
|
|
| 266 |
|
| 267 |
# Inisialisasi server saat aplikasi dimulai
|
| 268 |
-
initialize_server(MODEL_FILE_PATH, MAPPINGS_FILE_PATH)
|
| 269 |
|
| 270 |
# Berguna untuk pengujian lokal
|
| 271 |
if __name__ == '__main__':
|
|
|
|
| 1 |
# server.py
|
| 2 |
# Server Flask untuk prediksi multi-head captcha yang disesuaikan untuk Hugging Face Spaces.
|
| 3 |
# Versi ini sudah dioptimalkan untuk memuat model yang terkuantisasi (INT8).
|
| 4 |
+
# Dengan tambahan cropping otomatis menggunakan YOLO sebelum prediksi.
|
| 5 |
|
| 6 |
from flask import Flask, request, jsonify
|
| 7 |
from flask_cors import CORS
|
|
|
|
| 19 |
from io import BytesIO
|
| 20 |
import sys
|
| 21 |
import logging
|
| 22 |
+
from ultralytics import YOLO
|
| 23 |
|
| 24 |
torch.set_num_threads(1)
|
| 25 |
|
|
|
|
| 35 |
MAPPINGS = None
|
| 36 |
DEVICE = None
|
| 37 |
TRANSFORMS = None
|
| 38 |
+
YOLO_MODEL = None
|
| 39 |
|
| 40 |
# ==============================================================================
|
| 41 |
# BAGIAN 2: DEFINISI MODEL (TIDAK ADA PERUBAHAN)
|
|
|
|
| 80 |
return type_logits, object_logits, text_log_probs
|
| 81 |
|
| 82 |
# ==============================================================================
|
| 83 |
+
# BAGIAN 3: FUNGSI HELPER (TERMASUK CROPPING)
|
| 84 |
# ==============================================================================
|
| 85 |
|
| 86 |
+
def crop_image_with_yolo(image_array):
|
| 87 |
+
"""
|
| 88 |
+
Crop gambar menggunakan YOLO untuk mendeteksi area captcha.
|
| 89 |
+
|
| 90 |
+
Args:
|
| 91 |
+
image_array: numpy array gambar dalam format RGB
|
| 92 |
+
|
| 93 |
+
Returns:
|
| 94 |
+
numpy array gambar yang sudah di-crop, atau gambar asli jika tidak ada deteksi
|
| 95 |
+
"""
|
| 96 |
+
global YOLO_MODEL
|
| 97 |
+
|
| 98 |
+
if YOLO_MODEL is None:
|
| 99 |
+
logging.warning("YOLO model tidak tersedia, menggunakan gambar asli tanpa crop")
|
| 100 |
+
return image_array
|
| 101 |
+
|
| 102 |
+
try:
|
| 103 |
+
# YOLO membutuhkan format BGR untuk prediksi
|
| 104 |
+
image_bgr = cv2.cvtColor(image_array, cv2.COLOR_RGB2BGR)
|
| 105 |
+
|
| 106 |
+
# Prediksi menggunakan YOLO
|
| 107 |
+
results = YOLO_MODEL.predict(image_bgr, verbose=False, device="cpu")
|
| 108 |
+
|
| 109 |
+
if not results[0].boxes or len(results[0].boxes) == 0:
|
| 110 |
+
logging.info("Tidak ada objek terdeteksi oleh YOLO, menggunakan gambar asli")
|
| 111 |
+
return image_array
|
| 112 |
+
|
| 113 |
+
# Ambil box dengan confidence tertinggi
|
| 114 |
+
best_box = sorted(results[0].boxes, key=lambda box: box.conf, reverse=True)[0]
|
| 115 |
+
x1, y1, x2, y2 = best_box.xyxy[0].cpu().numpy().astype(int)
|
| 116 |
+
|
| 117 |
+
# Crop gambar (YOLO bekerja pada BGR, jadi crop dari image_bgr)
|
| 118 |
+
cropped_bgr = image_bgr[y1:y2, x1:x2]
|
| 119 |
+
|
| 120 |
+
if cropped_bgr is None or cropped_bgr.size == 0:
|
| 121 |
+
logging.warning("Crop kosong, menggunakan gambar asli")
|
| 122 |
+
return image_array
|
| 123 |
+
|
| 124 |
+
# Convert kembali ke RGB
|
| 125 |
+
cropped_rgb = cv2.cvtColor(cropped_bgr, cv2.COLOR_BGR2RGB)
|
| 126 |
+
|
| 127 |
+
confidence = best_box.conf.item()
|
| 128 |
+
logging.info(f"Gambar berhasil di-crop dengan confidence: {confidence:.2%}")
|
| 129 |
+
|
| 130 |
+
return cropped_rgb
|
| 131 |
+
|
| 132 |
+
except Exception as e:
|
| 133 |
+
logging.error(f"Error saat cropping dengan YOLO: {e}", exc_info=True)
|
| 134 |
+
logging.info("Menggunakan gambar asli tanpa crop")
|
| 135 |
+
return image_array
|
| 136 |
+
|
| 137 |
def get_transforms(img_height, img_width):
|
| 138 |
interpolation_method = cv2.INTER_AREA
|
| 139 |
return A.Compose([
|
|
|
|
| 167 |
return final_text, avg_confidence
|
| 168 |
|
| 169 |
# ==============================================================================
|
| 170 |
+
# BAGIAN 4: INISIALISASI SERVER (VERSI UNTUK MODEL KUANTISASI + YOLO)
|
| 171 |
# ==============================================================================
|
| 172 |
|
| 173 |
+
def initialize_server(model_path, mappings_path, yolo_model_path=None):
|
| 174 |
+
global MODEL, MAPPINGS, DEVICE, TRANSFORMS, YOLO_MODEL
|
| 175 |
+
logging.info("Memulai inisialisasi server dengan model terkuantisasi dan YOLO cropping...")
|
| 176 |
DEVICE = torch.device("cpu") # Kuantisasi INT8 dioptimalkan untuk CPU
|
| 177 |
logging.info(f"Menggunakan device: {DEVICE}")
|
| 178 |
+
|
| 179 |
+
# Load YOLO model untuk cropping
|
| 180 |
+
if yolo_model_path and os.path.exists(yolo_model_path):
|
| 181 |
+
try:
|
| 182 |
+
YOLO_MODEL = YOLO(yolo_model_path)
|
| 183 |
+
logging.info(f"YOLO model berhasil dimuat dari: {yolo_model_path}")
|
| 184 |
+
except Exception as e:
|
| 185 |
+
logging.error(f"Gagal memuat YOLO model: {e}")
|
| 186 |
+
logging.info("Server akan berjalan tanpa fitur auto-cropping")
|
| 187 |
+
YOLO_MODEL = None
|
| 188 |
+
else:
|
| 189 |
+
logging.warning(f"YOLO model tidak ditemukan di: {yolo_model_path}")
|
| 190 |
+
logging.info("Server akan berjalan tanpa fitur auto-cropping")
|
| 191 |
+
YOLO_MODEL = None
|
| 192 |
|
| 193 |
try:
|
| 194 |
if not os.path.exists(mappings_path):
|
|
|
|
| 288 |
return jsonify({"error": "Gagal memproses gambar."}), 500
|
| 289 |
|
| 290 |
try:
|
| 291 |
+
# Step 1: Convert gambar ke numpy array
|
| 292 |
image_rgb = np.array(img_pil)
|
| 293 |
+
|
| 294 |
+
# Step 2: Crop gambar menggunakan YOLO (jika tersedia)
|
| 295 |
+
cropped_image = crop_image_with_yolo(image_rgb)
|
| 296 |
+
|
| 297 |
+
# Step 3: Transform dan convert ke tensor untuk prediksi
|
| 298 |
+
img_tensor = TRANSFORMS(image=cropped_image)['image'].unsqueeze(0).to(DEVICE)
|
| 299 |
|
| 300 |
with torch.no_grad():
|
| 301 |
type_logits, object_logits, text_log_probs = MODEL(img_tensor)
|
|
|
|
| 337 |
# Menggunakan file model baru yang sudah terkuantisasi
|
| 338 |
MODEL_FILE_PATH = "best_model_quantized.pth"
|
| 339 |
MAPPINGS_FILE_PATH = "mappings.json"
|
| 340 |
+
YOLO_MODEL_FILE_PATH = "best_model.onnx" # YOLO model untuk cropping
|
| 341 |
|
| 342 |
# Inisialisasi server saat aplikasi dimulai
|
| 343 |
+
initialize_server(MODEL_FILE_PATH, MAPPINGS_FILE_PATH, YOLO_MODEL_FILE_PATH)
|
| 344 |
|
| 345 |
# Berguna untuk pengujian lokal
|
| 346 |
if __name__ == '__main__':
|
best_model copy.onnx
ADDED
|
@@ -0,0 +1,3 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
version https://git-lfs.github.com/spec/v1
|
| 2 |
+
oid sha256:2ec634c29dcbfebf68a802163da23c3047dc9acd9ae6b1e5d0c07033f97013f6
|
| 3 |
+
size 103606591
|
generate_api_key.php
ADDED
|
@@ -0,0 +1,56 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
<?php
|
| 2 |
+
/**
|
| 3 |
+
* API Key Generator
|
| 4 |
+
* Generate secure random API keys untuk Hugging Face authentication
|
| 5 |
+
*/
|
| 6 |
+
|
| 7 |
+
function generateSecureAPIKey($length = 32) {
|
| 8 |
+
// Generate random bytes
|
| 9 |
+
$randomBytes = random_bytes($length);
|
| 10 |
+
|
| 11 |
+
// Convert to hexadecimal
|
| 12 |
+
$hexKey = bin2hex($randomBytes);
|
| 13 |
+
|
| 14 |
+
return $hexKey;
|
| 15 |
+
}
|
| 16 |
+
|
| 17 |
+
// Generate 3 different API keys
|
| 18 |
+
echo "=================================================\n";
|
| 19 |
+
echo " 🔐 Secure API Key Generator for HF Space\n";
|
| 20 |
+
echo "=================================================\n\n";
|
| 21 |
+
|
| 22 |
+
echo "Generated API Keys (pilih salah satu):\n\n";
|
| 23 |
+
|
| 24 |
+
for ($i = 1; $i <= 3; $i++) {
|
| 25 |
+
$apiKey = generateSecureAPIKey();
|
| 26 |
+
echo "API Key #{$i}:\n";
|
| 27 |
+
echo $apiKey . "\n\n";
|
| 28 |
+
}
|
| 29 |
+
|
| 30 |
+
echo "=================================================\n";
|
| 31 |
+
echo "Setup Instructions:\n";
|
| 32 |
+
echo "=================================================\n\n";
|
| 33 |
+
|
| 34 |
+
echo "1. HUGGING FACE SPACE:\n";
|
| 35 |
+
echo " - Buka: https://huggingface.co/spaces/doniramdani820/Textbaru\n";
|
| 36 |
+
echo " - Klik: Settings → Variables and secrets\n";
|
| 37 |
+
echo " - Add Secret:\n";
|
| 38 |
+
echo " Name: API_KEY_SECRET\n";
|
| 39 |
+
echo " Value: [paste salah satu key di atas]\n\n";
|
| 40 |
+
|
| 41 |
+
echo "2. CONFIG.PHP:\n";
|
| 42 |
+
echo " - Edit file: config.php\n";
|
| 43 |
+
echo " - Update HF_API_KEY dengan key yang sama\n";
|
| 44 |
+
echo " define('HF_API_KEY', 'paste_key_disini');\n\n";
|
| 45 |
+
|
| 46 |
+
echo "3. VERIFY:\n";
|
| 47 |
+
echo " - Buka: http://localhost/Captchakings.com/test_hf_integration.php\n";
|
| 48 |
+
echo " - Check status: semua harus hijau ✅\n\n";
|
| 49 |
+
|
| 50 |
+
echo "⚠️ SECURITY WARNING:\n";
|
| 51 |
+
echo " - JANGAN share API key ke siapa pun\n";
|
| 52 |
+
echo " - JANGAN commit API key ke Git\n";
|
| 53 |
+
echo " - Simpan di tempat yang aman\n";
|
| 54 |
+
echo "=================================================\n";
|
| 55 |
+
?>
|
| 56 |
+
|
gitattributes
ADDED
|
@@ -0,0 +1,35 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
*.7z filter=lfs diff=lfs merge=lfs -text
|
| 2 |
+
*.arrow filter=lfs diff=lfs merge=lfs -text
|
| 3 |
+
*.bin filter=lfs diff=lfs merge=lfs -text
|
| 4 |
+
*.bz2 filter=lfs diff=lfs merge=lfs -text
|
| 5 |
+
*.ckpt filter=lfs diff=lfs merge=lfs -text
|
| 6 |
+
*.ftz filter=lfs diff=lfs merge=lfs -text
|
| 7 |
+
*.gz filter=lfs diff=lfs merge=lfs -text
|
| 8 |
+
*.h5 filter=lfs diff=lfs merge=lfs -text
|
| 9 |
+
*.joblib filter=lfs diff=lfs merge=lfs -text
|
| 10 |
+
*.lfs.* filter=lfs diff=lfs merge=lfs -text
|
| 11 |
+
*.mlmodel filter=lfs diff=lfs merge=lfs -text
|
| 12 |
+
*.model filter=lfs diff=lfs merge=lfs -text
|
| 13 |
+
*.msgpack filter=lfs diff=lfs merge=lfs -text
|
| 14 |
+
*.npy filter=lfs diff=lfs merge=lfs -text
|
| 15 |
+
*.npz filter=lfs diff=lfs merge=lfs -text
|
| 16 |
+
*.onnx filter=lfs diff=lfs merge=lfs -text
|
| 17 |
+
*.ot filter=lfs diff=lfs merge=lfs -text
|
| 18 |
+
*.parquet filter=lfs diff=lfs merge=lfs -text
|
| 19 |
+
*.pb filter=lfs diff=lfs merge=lfs -text
|
| 20 |
+
*.pickle filter=lfs diff=lfs merge=lfs -text
|
| 21 |
+
*.pkl filter=lfs diff=lfs merge=lfs -text
|
| 22 |
+
*.pt filter=lfs diff=lfs merge=lfs -text
|
| 23 |
+
*.pth filter=lfs diff=lfs merge=lfs -text
|
| 24 |
+
*.rar filter=lfs diff=lfs merge=lfs -text
|
| 25 |
+
*.safetensors filter=lfs diff=lfs merge=lfs -text
|
| 26 |
+
saved_model/**/* filter=lfs diff=lfs merge=lfs -text
|
| 27 |
+
*.tar.* filter=lfs diff=lfs merge=lfs -text
|
| 28 |
+
*.tar filter=lfs diff=lfs merge=lfs -text
|
| 29 |
+
*.tflite filter=lfs diff=lfs merge=lfs -text
|
| 30 |
+
*.tgz filter=lfs diff=lfs merge=lfs -text
|
| 31 |
+
*.wasm filter=lfs diff=lfs merge=lfs -text
|
| 32 |
+
*.xz filter=lfs diff=lfs merge=lfs -text
|
| 33 |
+
*.zip filter=lfs diff=lfs merge=lfs -text
|
| 34 |
+
*.zst filter=lfs diff=lfs merge=lfs -text
|
| 35 |
+
*tfevents* filter=lfs diff=lfs merge=lfs -text
|
requirements.txt
CHANGED
|
@@ -9,4 +9,5 @@ torch==2.0.1
|
|
| 9 |
torchvision==0.15.2
|
| 10 |
timm
|
| 11 |
albumentations
|
| 12 |
-
opencv-python-headless==4.8.0.74
|
|
|
|
|
|
| 9 |
torchvision==0.15.2
|
| 10 |
timm
|
| 11 |
albumentations
|
| 12 |
+
opencv-python-headless==4.8.0.74
|
| 13 |
+
ultralytics>=8.0.0
|