shiko217 commited on
Commit
88f10ff
Β·
unverified Β·
1 Parent(s): adcca8a
Files changed (2) hide show
  1. app.py +35 -6
  2. requirements.txt +2 -2
app.py CHANGED
@@ -1,6 +1,18 @@
1
  import os
2
- # Force CPU usage only to avoid Hugging Face free tier CUDA initialization errors
3
- os.environ["CUDA_VISIBLE_DEVICES"] = "-1"
 
 
 
 
 
 
 
 
 
 
 
 
4
  import numpy as np
5
  import librosa
6
  import scipy.signal
@@ -9,6 +21,10 @@ import gradio as gr
9
  import tensorflow as tf
10
  import warnings
11
 
 
 
 
 
12
  # Must be called before any model is loaded.
13
  # keras.config.enable_unsafe_deserialization() unlocks Lambda layer loading
14
  # across standalone Keras 2.x / 3.x. The tf.keras path is a fallback for
@@ -167,15 +183,28 @@ def load_model():
167
  return None, str(e)
168
 
169
 
170
- # Load at startup
171
- model, model_error = load_model()
172
- if model is None:
173
- print(f"Warning: Could not load model. Error: {model_error}")
 
 
 
 
 
 
 
 
 
 
 
 
174
 
175
  preprocessor = MachineListenerPreprocessor()
176
 
177
 
178
  def predict(audio_filepath):
 
179
  if model is None:
180
  return f"Model not loaded properly. Error: {model_error}"
181
  if audio_filepath is None:
 
1
  import os
2
+
3
+ # ── Memory / thread constraints (MUST be set before importing TF) ──────────
4
+ # These prevent TensorFlow from spawning dozens of threads and over-allocating
5
+ # memory, which causes SIGSEGV (exit 139) on memory-limited containers like
6
+ # the Hugging Face free-tier Spaces.
7
+ os.environ["CUDA_VISIBLE_DEVICES"] = "-1" # Force CPU only
8
+ os.environ["TF_ENABLE_ONEDNN_OPTS"] = "0" # Disable oneDNN (saves ~200 MB)
9
+ os.environ["TF_CPP_MIN_LOG_LEVEL"] = "2" # Suppress INFO/WARNING logs
10
+ os.environ["OMP_NUM_THREADS"] = "1" # Single OpenMP thread
11
+ os.environ["TF_NUM_INTEROP_THREADS"] = "1"
12
+ os.environ["TF_NUM_INTRAOP_THREADS"] = "1"
13
+ os.environ["OPENBLAS_NUM_THREADS"] = "1"
14
+ os.environ["MKL_NUM_THREADS"] = "1"
15
+
16
  import numpy as np
17
  import librosa
18
  import scipy.signal
 
21
  import tensorflow as tf
22
  import warnings
23
 
24
+ # Lock TF threading at runtime as well (belt-and-suspenders).
25
+ tf.config.threading.set_inter_op_parallelism_threads(1)
26
+ tf.config.threading.set_intra_op_parallelism_threads(1)
27
+
28
  # Must be called before any model is loaded.
29
  # keras.config.enable_unsafe_deserialization() unlocks Lambda layer loading
30
  # across standalone Keras 2.x / 3.x. The tf.keras path is a fallback for
 
183
  return None, str(e)
184
 
185
 
186
+ # ── Lazy model loading ─────────────────────────────────────────────────────
187
+ # Loading the model at import time doubles peak memory (TF init + model
188
+ # deserialization happen simultaneously). Deferring until the first request
189
+ # keeps startup lightweight and avoids the OOM β†’ SIGSEGV on free-tier HF.
190
+ _model = None
191
+ _model_error = ""
192
+
193
+ def _get_model():
194
+ """Return the cached model, loading it on first call."""
195
+ global _model, _model_error
196
+ if _model is None and _model_error == "":
197
+ print("Lazy-loading model on first request…")
198
+ _model, _model_error = load_model()
199
+ if _model is None:
200
+ print(f"Warning: Could not load model. Error: {_model_error}")
201
+ return _model, _model_error
202
 
203
  preprocessor = MachineListenerPreprocessor()
204
 
205
 
206
  def predict(audio_filepath):
207
+ model, model_error = _get_model()
208
  if model is None:
209
  return f"Model not loaded properly. Error: {model_error}"
210
  if audio_filepath is None:
requirements.txt CHANGED
@@ -1,5 +1,5 @@
1
- tensorflow-cpu
2
  gradio
3
  librosa
4
- numpy
5
  scipy
 
1
+ tensorflow-cpu==2.16.*
2
  gradio
3
  librosa
4
+ numpy<2
5
  scipy