L0SG commited on
Commit
fc45252
·
1 Parent(s): 4a03311

Improve generation limits and cancellation

Browse files
Files changed (4) hide show
  1. README.md +4 -1
  2. app.py +32 -12
  3. run_local.sh +2 -2
  4. tts_utils.py +1 -1
README.md CHANGED
@@ -20,7 +20,10 @@ The model selector defaults to the 30B-A3B and can switch to 2B model.
20
 
21
  The demo includes **audio understanding, speech recognition, speech translation, text reasoning, text-to-speech, and speech-to-speech**.
22
 
23
- Reasoning has no separate token cap by default for most tasks. Speech-to-speech defaults to a 1,536-token reasoning budget so the model has room for its final answer. `Max new tokens` sets a total cap shared by reasoning and the final answer.
 
 
 
24
 
25
  The hosted ZeroGPU runtime uses a prebuilt `mamba-ssm==2.3.2.post1` Blackwell wheel.
26
 
 
20
 
21
  The demo includes **audio understanding, speech recognition, speech translation, text reasoning, text-to-speech, and speech-to-speech**.
22
 
23
+ * Audio inputs support up to 15 minutes.
24
+ * Text generation defaults to 1,024 tokens and supports up to 4,096. `Max new tokens` sets a total cap shared by reasoning and the final answer. Reasoning has no separate token cap by default for most tasks.
25
+ * TTS uses a separate 256-token speech budget.
26
+ * Speech-to-speech defaults to a 1,536-token reasoning budget so the model has room for its final answer.
27
 
28
  The hosted ZeroGPU runtime uses a prebuilt `mamba-ssm==2.3.2.post1` Blackwell wheel.
29
 
app.py CHANGED
@@ -70,10 +70,10 @@ MODEL_2B_NAME = "Nemotron-Labs-Audex-2B"
70
 
71
  # Shared generation configuration
72
  SAMPLE_RATE = 16000
73
- MAX_AUDIO_DURATION_SECONDS = float(os.environ.get("AUDEX_MAX_AUDIO_SECONDS", "120"))
74
- MAX_NEW_TOKENS = int(os.environ.get("AUDEX_MAX_NEW_TOKENS", "2048"))
75
  DEFAULT_MAX_NEW_TOKENS = min(
76
- int(os.environ.get("AUDEX_DEFAULT_MAX_NEW_TOKENS", "256")),
77
  MAX_NEW_TOKENS,
78
  )
79
  DEFAULT_REASONING_BUDGET = max(
@@ -146,9 +146,12 @@ TTS_EXAMPLE_TEXT = (
146
 
147
  # Task-specific limits and feature switches
148
  TTS_MAX_NEW_TOKENS = min(
149
- int(os.environ.get("AUDEX_TTS_MAX_NEW_TOKENS", "192")),
150
  MAX_NEW_TOKENS,
151
  )
 
 
 
152
  S2S_TEXT_MAX_NEW_TOKENS = int(os.environ.get("AUDEX_S2S_TEXT_MAX_NEW_TOKENS", "2048"))
153
  S2S_REASONING_BUDGET = int(os.environ.get("AUDEX_S2S_REASONING_BUDGET", "1536"))
154
  S2S_GPU_DURATION_SECONDS = int(os.environ.get("AUDEX_S2S_GPU_DURATION_SECONDS", "120"))
@@ -833,7 +836,7 @@ def _stream_model_generate(
833
  )
834
  finally:
835
  cancel_event.set()
836
- thread.join(timeout=10)
837
 
838
 
839
  def _generate(
@@ -1336,6 +1339,7 @@ def _estimate_unified(
1336
  reasoning: bool,
1337
  reasoning_budget: int,
1338
  max_new_tokens: int,
 
1339
  temperature: float,
1340
  top_p: float,
1341
  guidance_scale: float,
@@ -1344,9 +1348,11 @@ def _estimate_unified(
1344
  ) -> int:
1345
  if task == S2S_TASK:
1346
  return S2S_GPU_DURATION_SECONDS
1347
- if task in {TEXT_TASK, TTS_TASK}:
1348
- if task == TTS_TASK and int(max_new_tokens) > TTS_MAX_NEW_TOKENS:
1349
- return 10
 
 
1350
  return _estimate_text(
1351
  prompt,
1352
  reasoning,
@@ -1374,6 +1380,7 @@ def run_unified(
1374
  reasoning: bool,
1375
  reasoning_budget: int,
1376
  max_new_tokens: int,
 
1377
  temperature: float,
1378
  top_p: float,
1379
  guidance_scale: float,
@@ -1402,7 +1409,7 @@ def run_unified(
1402
  for status, wav_path, player in _generate_tts(
1403
  runtime,
1404
  prompt,
1405
- int(max_new_tokens),
1406
  temperature,
1407
  top_p,
1408
  guidance_scale=float(guidance_scale),
@@ -1449,7 +1456,6 @@ def unified_task_defaults(
1449
  has_speech_output = settings["modality"] in {"tts", "s2s"}
1450
  reasoning = bool(settings["reasoning"])
1451
  default_max_new_tokens = int(settings.get("max_new_tokens", DEFAULT_MAX_NEW_TOKENS))
1452
- max_new_tokens_limit = int(settings.get("max_new_tokens_limit", MAX_NEW_TOKENS))
1453
  reasoning_budget_limit = _max_reasoning_budget(default_max_new_tokens)
1454
  return (
1455
  gr.update(visible=is_audio),
@@ -1479,9 +1485,10 @@ def unified_task_defaults(
1479
  float(settings["temperature"]),
1480
  float(settings["top_p"]),
1481
  gr.update(
1482
- value=TTS_MAX_NEW_TOKENS if is_tts else default_max_new_tokens,
1483
- maximum=TTS_MAX_NEW_TOKENS if is_tts else max_new_tokens_limit,
1484
  ),
 
1485
  gr.update(
1486
  value=float(settings.get("guidance_scale", 2.0)),
1487
  visible=has_speech_output,
@@ -1577,6 +1584,17 @@ with gr.Blocks(title="Nemotron-Labs-Audex") as demo:
1577
  "If reached, the displayed output is incomplete."
1578
  ),
1579
  )
 
 
 
 
 
 
 
 
 
 
 
1580
  unified_temperature = gr.Slider(
1581
  0.1,
1582
  1.5,
@@ -1638,6 +1656,7 @@ with gr.Blocks(title="Nemotron-Labs-Audex") as demo:
1638
  unified_temperature,
1639
  unified_top_p,
1640
  unified_max_new_tokens,
 
1641
  unified_guidance_scale,
1642
  unified_answer_out,
1643
  unified_thinking_out,
@@ -1669,6 +1688,7 @@ with gr.Blocks(title="Nemotron-Labs-Audex") as demo:
1669
  unified_reasoning,
1670
  unified_reasoning_budget,
1671
  unified_max_new_tokens,
 
1672
  unified_temperature,
1673
  unified_top_p,
1674
  unified_guidance_scale,
 
70
 
71
  # Shared generation configuration
72
  SAMPLE_RATE = 16000
73
+ MAX_AUDIO_DURATION_SECONDS = float(os.environ.get("AUDEX_MAX_AUDIO_SECONDS", "900"))
74
+ MAX_NEW_TOKENS = int(os.environ.get("AUDEX_MAX_NEW_TOKENS", "4096"))
75
  DEFAULT_MAX_NEW_TOKENS = min(
76
+ int(os.environ.get("AUDEX_DEFAULT_MAX_NEW_TOKENS", "1024")),
77
  MAX_NEW_TOKENS,
78
  )
79
  DEFAULT_REASONING_BUDGET = max(
 
146
 
147
  # Task-specific limits and feature switches
148
  TTS_MAX_NEW_TOKENS = min(
149
+ int(os.environ.get("AUDEX_TTS_MAX_NEW_TOKENS", "256")),
150
  MAX_NEW_TOKENS,
151
  )
152
+ TTS_30B_GPU_DURATION_SECONDS = int(
153
+ os.environ.get("AUDEX_TTS_30B_GPU_DURATION_SECONDS", "90")
154
+ )
155
  S2S_TEXT_MAX_NEW_TOKENS = int(os.environ.get("AUDEX_S2S_TEXT_MAX_NEW_TOKENS", "2048"))
156
  S2S_REASONING_BUDGET = int(os.environ.get("AUDEX_S2S_REASONING_BUDGET", "1536"))
157
  S2S_GPU_DURATION_SECONDS = int(os.environ.get("AUDEX_S2S_GPU_DURATION_SECONDS", "120"))
 
836
  )
837
  finally:
838
  cancel_event.set()
839
+ thread.join()
840
 
841
 
842
  def _generate(
 
1339
  reasoning: bool,
1340
  reasoning_budget: int,
1341
  max_new_tokens: int,
1342
+ tts_max_new_tokens: int,
1343
  temperature: float,
1344
  top_p: float,
1345
  guidance_scale: float,
 
1348
  ) -> int:
1349
  if task == S2S_TASK:
1350
  return S2S_GPU_DURATION_SECONDS
1351
+ if task == TTS_TASK:
1352
+ if model_name == DEFAULT_MODEL_NAME:
1353
+ return TTS_30B_GPU_DURATION_SECONDS
1354
+ return MAX_GPU_DURATION_SECONDS
1355
+ if task == TEXT_TASK:
1356
  return _estimate_text(
1357
  prompt,
1358
  reasoning,
 
1380
  reasoning: bool,
1381
  reasoning_budget: int,
1382
  max_new_tokens: int,
1383
+ tts_max_new_tokens: int,
1384
  temperature: float,
1385
  top_p: float,
1386
  guidance_scale: float,
 
1409
  for status, wav_path, player in _generate_tts(
1410
  runtime,
1411
  prompt,
1412
+ int(tts_max_new_tokens),
1413
  temperature,
1414
  top_p,
1415
  guidance_scale=float(guidance_scale),
 
1456
  has_speech_output = settings["modality"] in {"tts", "s2s"}
1457
  reasoning = bool(settings["reasoning"])
1458
  default_max_new_tokens = int(settings.get("max_new_tokens", DEFAULT_MAX_NEW_TOKENS))
 
1459
  reasoning_budget_limit = _max_reasoning_budget(default_max_new_tokens)
1460
  return (
1461
  gr.update(visible=is_audio),
 
1485
  float(settings["temperature"]),
1486
  float(settings["top_p"]),
1487
  gr.update(
1488
+ value=default_max_new_tokens,
1489
+ visible=not is_tts,
1490
  ),
1491
+ gr.update(value=TTS_MAX_NEW_TOKENS, visible=is_tts),
1492
  gr.update(
1493
  value=float(settings.get("guidance_scale", 2.0)),
1494
  visible=has_speech_output,
 
1584
  "If reached, the displayed output is incomplete."
1585
  ),
1586
  )
1587
+ unified_tts_max_new_tokens = gr.Slider(
1588
+ 16,
1589
+ TTS_MAX_NEW_TOKENS,
1590
+ value=TTS_MAX_NEW_TOKENS,
1591
+ step=16,
1592
+ label="Max speech tokens",
1593
+ info=(
1594
+ "Speech-token cap. If reached, generated audio may be incomplete."
1595
+ ),
1596
+ visible=False,
1597
+ )
1598
  unified_temperature = gr.Slider(
1599
  0.1,
1600
  1.5,
 
1656
  unified_temperature,
1657
  unified_top_p,
1658
  unified_max_new_tokens,
1659
+ unified_tts_max_new_tokens,
1660
  unified_guidance_scale,
1661
  unified_answer_out,
1662
  unified_thinking_out,
 
1688
  unified_reasoning,
1689
  unified_reasoning_budget,
1690
  unified_max_new_tokens,
1691
+ unified_tts_max_new_tokens,
1692
  unified_temperature,
1693
  unified_top_p,
1694
  unified_guidance_scale,
run_local.sh CHANGED
@@ -35,9 +35,9 @@ export AUDEX_TORCH_ARCH="${AUDEX_TORCH_ARCH:-$detected_arch}"
35
  export AUDEX_WHEELS_DIR="${AUDEX_WHEELS_DIR:-$APP_DIR/.local/wheels/$runtime_tag}"
36
  export AUDEX_BUILD_DIR="${AUDEX_BUILD_DIR:-$APP_DIR/.local/build/$runtime_tag}"
37
  export AUDEX_MAX_AUDIO_SECONDS="${AUDEX_MAX_AUDIO_SECONDS:-900}"
38
- export AUDEX_MAX_NEW_TOKENS="${AUDEX_MAX_NEW_TOKENS:-2048}"
39
  export AUDEX_DEFAULT_MAX_NEW_TOKENS="${AUDEX_DEFAULT_MAX_NEW_TOKENS:-1024}"
40
- export AUDEX_TTS_MAX_NEW_TOKENS="${AUDEX_TTS_MAX_NEW_TOKENS:-1024}"
41
  export AUDEX_S2S_TEXT_MAX_NEW_TOKENS="${AUDEX_S2S_TEXT_MAX_NEW_TOKENS:-2048}"
42
  export AUDEX_S2S_TTS_MAX_NEW_TOKENS="${AUDEX_S2S_TTS_MAX_NEW_TOKENS:-2400}"
43
  export GRADIO_SERVER_NAME="${GRADIO_SERVER_NAME:-0.0.0.0}"
 
35
  export AUDEX_WHEELS_DIR="${AUDEX_WHEELS_DIR:-$APP_DIR/.local/wheels/$runtime_tag}"
36
  export AUDEX_BUILD_DIR="${AUDEX_BUILD_DIR:-$APP_DIR/.local/build/$runtime_tag}"
37
  export AUDEX_MAX_AUDIO_SECONDS="${AUDEX_MAX_AUDIO_SECONDS:-900}"
38
+ export AUDEX_MAX_NEW_TOKENS="${AUDEX_MAX_NEW_TOKENS:-4096}"
39
  export AUDEX_DEFAULT_MAX_NEW_TOKENS="${AUDEX_DEFAULT_MAX_NEW_TOKENS:-1024}"
40
+ export AUDEX_TTS_MAX_NEW_TOKENS="${AUDEX_TTS_MAX_NEW_TOKENS:-256}"
41
  export AUDEX_S2S_TEXT_MAX_NEW_TOKENS="${AUDEX_S2S_TEXT_MAX_NEW_TOKENS:-2048}"
42
  export AUDEX_S2S_TTS_MAX_NEW_TOKENS="${AUDEX_S2S_TTS_MAX_NEW_TOKENS:-2400}"
43
  export GRADIO_SERVER_NAME="${GRADIO_SERVER_NAME:-0.0.0.0}"
tts_utils.py CHANGED
@@ -298,7 +298,7 @@ def stream_tts(
298
  )
299
  finally:
300
  cancel_event.set()
301
- thread.join(timeout=10)
302
 
303
 
304
  def encode_pcm_chunk(pcm: np.ndarray) -> str:
 
298
  )
299
  finally:
300
  cancel_event.set()
301
+ thread.join()
302
 
303
 
304
  def encode_pcm_chunk(pcm: np.ndarray) -> str: