mazesmazes commited on
Commit
0dad6b3
·
verified ·
1 Parent(s): f3d63ca

Deploy demo to HF Space

Browse files
Files changed (3) hide show
  1. __pycache__/app.cpython-312.pyc +0 -0
  2. app.py +52 -9
  3. packages.txt +1 -0
__pycache__/app.cpython-312.pyc CHANGED
Binary files a/__pycache__/app.cpython-312.pyc and b/__pycache__/app.cpython-312.pyc differ
 
app.py CHANGED
@@ -32,9 +32,10 @@ os.environ["MPLCONFIGDIR"] = "/tmp/matplotlib"
32
  # Disable tokenizer parallelism warning
33
  os.environ["TOKENIZERS_PARALLELISM"] = "false"
34
 
35
- import base64
36
  import html
 
37
  import sys
 
38
  from collections.abc import Callable, Mapping, Sequence
39
  from itertools import groupby
40
  from operator import itemgetter
@@ -347,27 +348,69 @@ def local_runner(model_path: str) -> Callable[[str, dict[str, Any]], dict[str, A
347
  WAKING_UP = "The model server is starting up or offline. Please try again in a few minutes."
348
 
349
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
350
  def remote_runner(
351
  endpoint_url: str, api_key: str | None
352
  ) -> Callable[[str, dict[str, Any]], dict[str, Any]]:
353
  """POST each request to a `ta serve` server (scripts/serve.py)."""
354
- headers = {"Authorization": f"Bearer {api_key}"} if api_key else {}
355
 
356
  def run_pipeline(audio: str, kwargs: dict[str, Any]) -> dict[str, Any]:
357
- # A JSON body is the only way to send `parameters` with the audio,
358
- # so the audio travels base64-encoded.
359
- payload = {
360
- "inputs": base64.b64encode(Path(audio).read_bytes()).decode(),
361
- "parameters": kwargs,
362
- }
363
  try:
364
- response = httpx.post(endpoint_url, json=payload, headers=headers, timeout=600)
 
 
 
 
 
 
365
  except httpx.TimeoutException as e:
366
  msg = "The model server took too long to respond."
367
  raise gr.Error(msg) from e
368
  except httpx.HTTPError as e:
369
  msg = f"Could not reach the model server: {e}"
370
  raise gr.Error(msg) from e
 
 
371
  if response.status_code in (502, 503, 504):
372
  raise gr.Error(WAKING_UP)
373
  if response.is_error:
 
32
  # Disable tokenizer parallelism warning
33
  os.environ["TOKENIZERS_PARALLELISM"] = "false"
34
 
 
35
  import html
36
+ import subprocess
37
  import sys
38
+ import tempfile
39
  from collections.abc import Callable, Mapping, Sequence
40
  from itertools import groupby
41
  from operator import itemgetter
 
348
  WAKING_UP = "The model server is starting up or offline. Please try again in a few minutes."
349
 
350
 
351
+ def compact_audio(audio: str) -> tuple[bytes, str]:
352
+ """`(body, content type)` for an upload: 16 kHz mono FLAC, or the file as-is.
353
+
354
+ The server decodes everything to 16 kHz mono, so sending that -- losslessly
355
+ -- changes nothing but the size: a 44.1 kHz stereo WAV shrinks ~10x, from
356
+ ~10.6 to ~1 MB a minute. RunPod's proxy refuses large bodies (413 Payload
357
+ Too Large), so this is what lets hour-long recordings through. Without
358
+ ffmpeg, or for a file it can't read, the original bytes go and the server
359
+ reports any decode error itself.
360
+ """
361
+ # To a file, not a pipe: ffmpeg seeks back to write the stream's length
362
+ # into the FLAC header, which a piped stream leaves bogus (libsndfile then
363
+ # refuses it).
364
+ with tempfile.TemporaryDirectory() as tmp:
365
+ flac = Path(tmp) / "upload.flac"
366
+ command = [
367
+ "ffmpeg", "-nostdin", "-v", "error", "-i", audio,
368
+ "-ac", "1", "-ar", "16000", "-sample_fmt", "s16", str(flac),
369
+ ] # fmt: skip
370
+ try:
371
+ subprocess.run(command, check=True, capture_output=True)
372
+ except (OSError, subprocess.CalledProcessError):
373
+ return Path(audio).read_bytes(), "application/octet-stream"
374
+ return flac.read_bytes(), "audio/flac"
375
+
376
+
377
+ def query_parameters(kwargs: Mapping[str, Any]) -> dict[str, str]:
378
+ """Pipeline options as the query string `ta serve` parses ("true", "3")."""
379
+ return {k: str(v).lower() if isinstance(v, bool) else str(v) for k, v in kwargs.items()}
380
+
381
+
382
+ TOO_LARGE = (
383
+ "This file is too large for the model server, even compressed to 16 kHz mono. "
384
+ "Try a shorter recording."
385
+ )
386
+
387
+
388
  def remote_runner(
389
  endpoint_url: str, api_key: str | None
390
  ) -> Callable[[str, dict[str, Any]], dict[str, Any]]:
391
  """POST each request to a `ta serve` server (scripts/serve.py)."""
392
+ auth = {"Authorization": f"Bearer {api_key}"} if api_key else {}
393
 
394
  def run_pipeline(audio: str, kwargs: dict[str, Any]) -> dict[str, Any]:
395
+ # Raw audio as the body, options in the query string: base64 in JSON
396
+ # would add a third to an upload the proxy already caps.
397
+ body, content_type = compact_audio(audio)
 
 
 
398
  try:
399
+ response = httpx.post(
400
+ endpoint_url,
401
+ content=body,
402
+ params=query_parameters(kwargs),
403
+ headers={**auth, "Content-Type": content_type},
404
+ timeout=600,
405
+ )
406
  except httpx.TimeoutException as e:
407
  msg = "The model server took too long to respond."
408
  raise gr.Error(msg) from e
409
  except httpx.HTTPError as e:
410
  msg = f"Could not reach the model server: {e}"
411
  raise gr.Error(msg) from e
412
+ if response.status_code == 413:
413
+ raise gr.Error(TOO_LARGE)
414
  if response.status_code in (502, 503, 504):
415
  raise gr.Error(WAKING_UP)
416
  if response.is_error:
packages.txt ADDED
@@ -0,0 +1 @@
 
 
1
+ ffmpeg