pavankumarvk commited on
Commit
e07119e
·
verified ·
1 Parent(s): 5808494

Update pipeline.py

Browse files
Files changed (1) hide show
  1. pipeline.py +33 -11
pipeline.py CHANGED
@@ -229,38 +229,60 @@ audio_label_map = {
229
  1: "Fake audio"
230
  }
231
 
232
- NB_SAMP = 64600 # Expected sample length by RawNet2
 
233
 
234
  def deepfakes_audio_predict(input_audio):
235
  """
236
- Gradio gr.Audio() returns a tuple: (sample_rate, numpy_array)
237
- numpy_array is int16 by default and needs float32 normalization.
 
 
 
 
 
 
238
  """
239
  sr, x = input_audio
240
 
 
 
 
241
  x = x.astype(np.float32)
242
- if x.max() > 1.0:
243
- x = x / 32768.0 # Normalize int16 range to float32
244
 
245
- # If stereo, convert to mono by averaging channels
 
 
 
 
246
  if x.ndim == 2:
247
  x = x.mean(axis=1)
248
 
249
- # RawNet2 expects exactly nb_samp=64600 samplespad or trim
 
 
 
 
 
 
 
 
250
  if len(x) < NB_SAMP:
251
  x = np.pad(x, (0, NB_SAMP - len(x)), mode='constant')
252
  else:
253
  x = x[:NB_SAMP]
254
 
255
- # Convert to tensor with batch dimension: [1, nb_samp]
256
  x_pt = torch.tensor(x, dtype=torch.float32).unsqueeze(0)
257
 
258
  audio_model = load_audio_model()
259
 
260
  with torch.no_grad():
261
- grads = audio_model(x_pt)
 
 
 
262
 
263
- grads_np = grads.detach().numpy()
264
- result = np.argmax(grads_np)
265
 
266
  return audio_label_map[int(result)]
 
229
  1: "Fake audio"
230
  }
231
 
232
+ RAWNET_SAMPLE_RATE = 16000 # RawNet2 was trained on 16kHz audio — never change this
233
+ NB_SAMP = 64600 # Exactly 4.0375 seconds at 16kHz
234
 
235
  def deepfakes_audio_predict(input_audio):
236
  """
237
+ Gradio gr.Audio() returns a tuple: (sample_rate, numpy_array).
238
+
239
+ Critical fixes applied:
240
+ 1. Resample to RAWNET_SAMPLE_RATE (16000 Hz) — the model was trained at 16kHz.
241
+ Without this, a 44100Hz input has its first ~1.46s fed to a model expecting ~4s,
242
+ completely breaking the SincConv filterbank frequency assumptions.
243
+ 2. Stereo → mono before resampling (librosa.resample requires 1D input).
244
+ 3. Normalize AFTER resampling to avoid float64 precision issues from librosa.
245
  """
246
  sr, x = input_audio
247
 
248
+ print(f"[Audio] Input sample rate: {sr} Hz, samples: {len(x)}, dtype: {x.dtype}")
249
+
250
+ # Step 1: Convert to float32
251
  x = x.astype(np.float32)
 
 
252
 
253
+ # Step 2: Normalize int16 [-1.0, 1.0] range
254
+ if np.abs(x).max() > 1.0:
255
+ x = x / 32768.0
256
+
257
+ # Step 3: Stereo → mono (must be done before librosa.resample)
258
  if x.ndim == 2:
259
  x = x.mean(axis=1)
260
 
261
+ # Step 4: Resample to 16000 Hz THIS WAS THE ROOT CAUSE BUG
262
+ # RawNet2's SincConv filterbank is hard-coded to 16kHz frequencies.
263
+ # Feeding audio at any other sample rate produces completely wrong filter responses.
264
+ if sr != RAWNET_SAMPLE_RATE:
265
+ print(f"[Audio] Resampling from {sr} Hz → {RAWNET_SAMPLE_RATE} Hz")
266
+ x = librosa.resample(x, orig_sr=sr, target_sr=RAWNET_SAMPLE_RATE)
267
+ print(f"[Audio] After resample: {len(x)} samples ({len(x)/RAWNET_SAMPLE_RATE:.2f}s)")
268
+
269
+ # Step 5: Pad or trim to exactly NB_SAMP (64600) samples
270
  if len(x) < NB_SAMP:
271
  x = np.pad(x, (0, NB_SAMP - len(x)), mode='constant')
272
  else:
273
  x = x[:NB_SAMP]
274
 
275
+ # Step 6: Build tensor [1, NB_SAMP] and run inference
276
  x_pt = torch.tensor(x, dtype=torch.float32).unsqueeze(0)
277
 
278
  audio_model = load_audio_model()
279
 
280
  with torch.no_grad():
281
+ logits = audio_model(x_pt)
282
+
283
+ logits_np = logits.detach().numpy()
284
+ result = np.argmax(logits_np)
285
 
286
+ print(f"[Audio] Logits: {logits_np}, Predicted class: {result} ({audio_label_map[int(result)]})")
 
287
 
288
  return audio_label_map[int(result)]