Pranav Mishra commited on
Commit
a26c11a
·
1 Parent(s): 93ceaba

Fix performance issues: updated requirements with exact versions and added model caching

Browse files
Files changed (2) hide show
  1. app.py +34 -10
  2. requirements_hf.txt +15 -9
app.py CHANGED
@@ -12,8 +12,9 @@ from typing import Dict, Any, Optional
12
  from dotenv import load_dotenv
13
  import numpy as np
14
 
15
- # Import audio processors (only the 3 ML models + external API)
16
  from audio_processors.external_api import ExternalAPIProcessor
 
17
  from audio_processors.ml_mfcc_processor import MLMFCCProcessor
18
  from audio_processors.ml_mel_cnn_processor import MLMelCNNProcessor
19
  from audio_processors.ml_raw_cnn_processor import MLRawCNNProcessor
@@ -44,8 +45,18 @@ def allowed_file(filename: str) -> bool:
44
  """Check if file extension is allowed."""
45
  return '.' in filename and filename.rsplit('.', 1)[1].lower() in ALLOWED_EXTENSIONS
46
 
 
 
 
47
  def initialize_processors():
48
- """Initialize audio processors optimized for HF Spaces deployment."""
 
 
 
 
 
 
 
49
  procs = {}
50
 
51
  # ML-trained processors (high priority - use best models only)
@@ -58,11 +69,13 @@ def initialize_processors():
58
  ml_working_count = 0
59
  for proc_key, proc_class, proc_name in ml_processors:
60
  try:
 
 
61
  processor = proc_class()
62
  if processor.is_configured():
63
  procs[proc_key] = processor
64
  ml_working_count += 1
65
- app.logger.info(f"[OK] {proc_name} loaded successfully")
66
  else:
67
  app.logger.warning(f"[WARN] {proc_name} not configured (model files missing)")
68
  except Exception as e:
@@ -73,20 +86,31 @@ def initialize_processors():
73
  external_processor = ExternalAPIProcessor()
74
  if external_processor.is_configured():
75
  procs['external_api'] = external_processor
76
- app.logger.info("[OK] External API processor initialized")
77
  else:
78
  app.logger.warning("[WARN] External API not configured")
79
  except Exception as e:
80
  app.logger.error(f"[FAIL] Failed to initialize External API: {str(e)}")
81
 
82
- # Removed whisper processors to reduce dependencies and build size
 
 
 
 
 
 
 
 
 
 
83
 
84
  app.logger.info(f"Processor initialization complete:")
85
  app.logger.info(f" ML Models loaded: {ml_working_count}/3")
86
- app.logger.info(f" Total processors: {len(procs)}")
87
 
88
  return procs
89
 
 
90
  processors = initialize_processors()
91
 
92
  @app.route('/')
@@ -95,7 +119,7 @@ def index():
95
  return jsonify({
96
  'message': 'Streaming Digit Classifier API',
97
  'status': 'running',
98
- 'version': '1.2.0',
99
  'available_processors': list(processors.keys()),
100
  'documentation': 'Frontend at Vercel, Backend API at HF Spaces'
101
  })
@@ -173,7 +197,7 @@ def process_audio():
173
  result.update({
174
  'audio_duration': round(duration, 3),
175
  'file_size': len(audio_data),
176
- 'api_version': '1.2.0'
177
  })
178
 
179
  app.logger.info(f"Processed audio with {method}: '{result['predicted_digit']}' in {result['inference_time']}s")
@@ -231,7 +255,7 @@ def process_audio_chunk():
231
  'segment_index': 0,
232
  'segment_size': len(standardized_audio),
233
  'is_streaming': True,
234
- 'api_version': '1.2.0'
235
  })
236
 
237
  app.logger.info(f"Streaming prediction: '{result['predicted_digit']}' "
@@ -294,7 +318,7 @@ def health_check():
294
  'status': 'healthy',
295
  'timestamp': time.time(),
296
  'processors': processor_health,
297
- 'version': '1.2.0',
298
  'deployment': 'huggingface-spaces'
299
  })
300
 
 
12
  from dotenv import load_dotenv
13
  import numpy as np
14
 
15
+ # Import audio processors (only essential ones for deployment)
16
  from audio_processors.external_api import ExternalAPIProcessor
17
+ from audio_processors.whisper_digit_processor import WhisperDigitProcessor
18
  from audio_processors.ml_mfcc_processor import MLMFCCProcessor
19
  from audio_processors.ml_mel_cnn_processor import MLMelCNNProcessor
20
  from audio_processors.ml_raw_cnn_processor import MLRawCNNProcessor
 
45
  """Check if file extension is allowed."""
46
  return '.' in filename and filename.rsplit('.', 1)[1].lower() in ALLOWED_EXTENSIONS
47
 
48
+ # Global processor cache for model persistence
49
+ _processor_cache = {}
50
+
51
  def initialize_processors():
52
+ """Initialize audio processors optimized for HF Spaces deployment with caching."""
53
+ global _processor_cache
54
+
55
+ # Return cached processors if already initialized
56
+ if _processor_cache:
57
+ app.logger.info(f"Using cached processors: {len(_processor_cache)} available")
58
+ return _processor_cache
59
+
60
  procs = {}
61
 
62
  # ML-trained processors (high priority - use best models only)
 
69
  ml_working_count = 0
70
  for proc_key, proc_class, proc_name in ml_processors:
71
  try:
72
+ # Initialize once and cache
73
+ app.logger.info(f"Loading {proc_name}...")
74
  processor = proc_class()
75
  if processor.is_configured():
76
  procs[proc_key] = processor
77
  ml_working_count += 1
78
+ app.logger.info(f"[OK] {proc_name} loaded successfully (cached)")
79
  else:
80
  app.logger.warning(f"[WARN] {proc_name} not configured (model files missing)")
81
  except Exception as e:
 
86
  external_processor = ExternalAPIProcessor()
87
  if external_processor.is_configured():
88
  procs['external_api'] = external_processor
89
+ app.logger.info("[OK] External API processor initialized (cached)")
90
  else:
91
  app.logger.warning("[WARN] External API not configured")
92
  except Exception as e:
93
  app.logger.error(f"[FAIL] Failed to initialize External API: {str(e)}")
94
 
95
+ # Whisper digit processor as another fallback
96
+ try:
97
+ whisper_processor = WhisperDigitProcessor()
98
+ if whisper_processor.is_configured():
99
+ procs['whisper_digit'] = whisper_processor
100
+ app.logger.info("[OK] Whisper digit processor initialized (cached)")
101
+ except Exception as e:
102
+ app.logger.error(f"[FAIL] Failed to initialize Whisper: {str(e)}")
103
+
104
+ # Cache the processors globally
105
+ _processor_cache = procs
106
 
107
  app.logger.info(f"Processor initialization complete:")
108
  app.logger.info(f" ML Models loaded: {ml_working_count}/3")
109
+ app.logger.info(f" Total processors cached: {len(procs)}")
110
 
111
  return procs
112
 
113
+ # Initialize processors on startup (cached globally)
114
  processors = initialize_processors()
115
 
116
  @app.route('/')
 
119
  return jsonify({
120
  'message': 'Streaming Digit Classifier API',
121
  'status': 'running',
122
+ 'version': '1.0.0',
123
  'available_processors': list(processors.keys()),
124
  'documentation': 'Frontend at Vercel, Backend API at HF Spaces'
125
  })
 
197
  result.update({
198
  'audio_duration': round(duration, 3),
199
  'file_size': len(audio_data),
200
+ 'api_version': '1.0.0'
201
  })
202
 
203
  app.logger.info(f"Processed audio with {method}: '{result['predicted_digit']}' in {result['inference_time']}s")
 
255
  'segment_index': 0,
256
  'segment_size': len(standardized_audio),
257
  'is_streaming': True,
258
+ 'api_version': '1.0.0'
259
  })
260
 
261
  app.logger.info(f"Streaming prediction: '{result['predicted_digit']}' "
 
318
  'status': 'healthy',
319
  'timestamp': time.time(),
320
  'processors': processor_health,
321
+ 'version': '1.0.0',
322
  'deployment': 'huggingface-spaces'
323
  })
324
 
requirements_hf.txt CHANGED
@@ -1,14 +1,14 @@
1
- # HF Spaces Requirements - Python 3.10 compatible versions (streamlined)
2
  # Core Flask API
3
  Flask==2.3.3
4
  Flask-CORS==4.0.0
5
  requests==2.31.0
6
  python-dotenv==1.0.0
7
 
8
- # Audio Processing Core
9
- numpy==1.25.0
10
  librosa==0.10.1
11
- scipy==1.11.0
12
  soundfile==0.12.1
13
 
14
  # Critical Audio Processing Libraries (Fix audio corruption)
@@ -17,12 +17,18 @@ ffmpeg-python==0.2.0
17
  audioread==3.0.0
18
  resampy==0.4.2
19
 
20
- # ML Models - PyTorch CPU
21
- torch==2.0.1
22
- torchaudio==2.0.2
 
23
 
24
- # Essential ML utilities (no pandas/datasets needed for inference)
25
- scikit-learn==1.3.0
 
 
 
 
 
26
 
27
  # Logging and utilities
28
  tqdm==4.65.0
 
1
+ # HF Spaces Requirements - Exact working versions from local system
2
  # Core Flask API
3
  Flask==2.3.3
4
  Flask-CORS==4.0.0
5
  requests==2.31.0
6
  python-dotenv==1.0.0
7
 
8
+ # Audio Processing Core - Fixed versions (avoid yanked scipy 1.11.0)
9
+ numpy==1.21.6
10
  librosa==0.10.1
11
+ scipy==1.9.3
12
  soundfile==0.12.1
13
 
14
  # Critical Audio Processing Libraries (Fix audio corruption)
 
17
  audioread==3.0.0
18
  resampy==0.4.2
19
 
20
+ # ML Models - PyTorch CPU with exact versions
21
+ torch==1.12.1
22
+ torchaudio==0.12.1
23
+ torchvision==0.13.1
24
 
25
+ # Essential ML utilities
26
+ scikit-learn==1.1.3
27
+ transformers==4.21.3
28
+ collections-extended==2.0.2
29
+
30
+ # VAD processing
31
+ webrtcvad==2.0.10
32
 
33
  # Logging and utilities
34
  tqdm==4.65.0