Spaces:
Running
on
Zero
Running
on
Zero
rename somme functions
Browse files- app.py +17 -72
- app/session_utils.py +3 -3
- app/streaming_audio_processor.py +3 -4
- app/utils.py +8 -12
app.py
CHANGED
|
@@ -13,7 +13,7 @@ import os
|
|
| 13 |
from gradio.utils import get_space
|
| 14 |
|
| 15 |
from app.utils import (
|
| 16 |
-
|
| 17 |
READ_SIZE,
|
| 18 |
generate_coturn_config,
|
| 19 |
read_and_stream_audio,
|
|
@@ -24,9 +24,9 @@ from app.utils import (
|
|
| 24 |
from app.session_utils import (
|
| 25 |
on_load,
|
| 26 |
on_unload,
|
| 27 |
-
|
| 28 |
register_session_hash_code,
|
| 29 |
-
|
| 30 |
get_active_task_flag_file,
|
| 31 |
remove_active_task_flag_file
|
| 32 |
|
|
@@ -45,39 +45,29 @@ from app.ui_utils import (
|
|
| 45 |
import nemo.collections.asr as nemo_asr
|
| 46 |
from app.session_utils import (
|
| 47 |
get_active_task_flag_file,
|
| 48 |
-
|
| 49 |
)
|
| 50 |
import spaces
|
| 51 |
# --------------------------------------------------------
|
| 52 |
# Initialization
|
| 53 |
# --------------------------------------------------------
|
| 54 |
-
|
| 55 |
|
| 56 |
theme,css_style = get_custom_theme()
|
| 57 |
|
| 58 |
-
# logger.info(f'Hydra config: {OmegaConf.to_yaml(cfg)}')
|
| 59 |
-
|
| 60 |
-
from app.streaming_audio_processor import StreamingAudioProcessorConfig
|
| 61 |
-
|
| 62 |
-
|
| 63 |
-
# asr_model = None
|
| 64 |
-
|
| 65 |
-
|
| 66 |
-
|
| 67 |
-
|
| 68 |
-
|
| 69 |
|
| 70 |
with gr.Blocks(theme=theme, css=css_style) as demo:
|
| 71 |
session_hash_code = gr.State()
|
| 72 |
-
|
| 73 |
-
|
| 74 |
-
|
| 75 |
-
|
| 76 |
-
|
| 77 |
-
|
| 78 |
-
|
| 79 |
-
|
| 80 |
-
|
|
|
|
| 81 |
|
| 82 |
demo.load(fn=on_load, inputs=None, outputs=[session_hash_code, session_hash_code_box])
|
| 83 |
demo.unload(fn=on_unload)
|
|
@@ -303,28 +293,8 @@ with gr.Blocks(theme=theme, css=css_style) as demo:
|
|
| 303 |
chunk_secs, left_context_secs, right_context_secs,
|
| 304 |
streaming_policy, alignatt_thr, waitk_lagging,
|
| 305 |
exclude_sink_frames, xatt_scores_layer, hallucinations_detector]
|
| 306 |
-
def start_transcription(
|
| 307 |
-
session_hash_code,
|
| 308 |
-
task_type, lang_source, lang_target,
|
| 309 |
-
chunk_secs, left_context_secs, right_context_secs,
|
| 310 |
-
streaming_policy, alignatt_thr, waitk_lagging,
|
| 311 |
-
exclude_sink_frames, xatt_scores_layer, hallucinations_detector
|
| 312 |
-
):
|
| 313 |
-
"""Stream transcription or translation results in real time."""
|
| 314 |
-
|
| 315 |
-
accumulated = ""
|
| 316 |
-
yield f"Starting {task_type.lower()}...\n\n",gr.update(visible=False),gr.update(visible=True)
|
| 317 |
-
|
| 318 |
-
|
| 319 |
-
# Boucle sur le générateur de `task()`
|
| 320 |
-
for msg in task(session_hash_code,config_task_ui):
|
| 321 |
-
accumulated += msg
|
| 322 |
-
yield accumulated,gr.update(visible=False),gr.update(visible=True)
|
| 323 |
|
| 324 |
-
|
| 325 |
-
|
| 326 |
-
|
| 327 |
-
def start_task(
|
| 328 |
session_hash_code,
|
| 329 |
task_type, lang_source, lang_target,
|
| 330 |
chunk_secs, left_context_secs, right_context_secs,
|
|
@@ -351,7 +321,7 @@ with gr.Blocks(theme=theme, css=css_style) as demo:
|
|
| 351 |
|
| 352 |
|
| 353 |
start_task_button.click(
|
| 354 |
-
fn=
|
| 355 |
inputs=[
|
| 356 |
session_hash_code,
|
| 357 |
task_type, lang_source, lang_target,
|
|
@@ -363,18 +333,6 @@ with gr.Blocks(theme=theme, css=css_style) as demo:
|
|
| 363 |
outputs=[task_output,status_message_task,start_task_button,stop_task_button]
|
| 364 |
)
|
| 365 |
|
| 366 |
-
# start_task_button.click(
|
| 367 |
-
# fn=start_task,
|
| 368 |
-
# inputs=[
|
| 369 |
-
# session_hash_code,
|
| 370 |
-
# task_type, lang_source, lang_target,
|
| 371 |
-
# chunk_secs, left_context_secs, right_context_secs,
|
| 372 |
-
# streaming_policy, alignatt_thr, waitk_lagging,
|
| 373 |
-
# exclude_sink_frames, xatt_scores_layer, hallucinations_detector
|
| 374 |
-
# ],
|
| 375 |
-
# outputs=[task_output,status_message_task,start_task_button,stop_task_button]
|
| 376 |
-
# )
|
| 377 |
-
|
| 378 |
ui_components = [
|
| 379 |
start_stream_button, stop_stream_button,
|
| 380 |
go_to_config, audio_source_step, status_slider,walkthrough,status_message_stream
|
|
@@ -388,19 +346,6 @@ with gr.Blocks(theme=theme, css=css_style) as demo:
|
|
| 388 |
concurrency_limit=10,
|
| 389 |
)
|
| 390 |
|
| 391 |
-
# def toggle_task_buttons():
|
| 392 |
-
# return (
|
| 393 |
-
# gr.update(visible=False),
|
| 394 |
-
# gr.update(visible=True),
|
| 395 |
-
# gr.update(visible=True)
|
| 396 |
-
# )
|
| 397 |
-
|
| 398 |
-
# start_task_button.click(
|
| 399 |
-
# fn=toggle_task_buttons,
|
| 400 |
-
# inputs=None,
|
| 401 |
-
# outputs=[start_task_button, stop_task_button, stop_stream_button],
|
| 402 |
-
# queue=False
|
| 403 |
-
# )
|
| 404 |
|
| 405 |
|
| 406 |
if __name__ == "__main__":
|
|
|
|
| 13 |
from gradio.utils import get_space
|
| 14 |
|
| 15 |
from app.utils import (
|
| 16 |
+
raise_error,
|
| 17 |
READ_SIZE,
|
| 18 |
generate_coturn_config,
|
| 19 |
read_and_stream_audio,
|
|
|
|
| 24 |
from app.session_utils import (
|
| 25 |
on_load,
|
| 26 |
on_unload,
|
| 27 |
+
get_active_session_hashes,
|
| 28 |
register_session_hash_code,
|
| 29 |
+
reset_all_active_sessions,
|
| 30 |
get_active_task_flag_file,
|
| 31 |
remove_active_task_flag_file
|
| 32 |
|
|
|
|
| 45 |
import nemo.collections.asr as nemo_asr
|
| 46 |
from app.session_utils import (
|
| 47 |
get_active_task_flag_file,
|
| 48 |
+
get_session_hashe_chunks_dir
|
| 49 |
)
|
| 50 |
import spaces
|
| 51 |
# --------------------------------------------------------
|
| 52 |
# Initialization
|
| 53 |
# --------------------------------------------------------
|
| 54 |
+
reset_all_active_sessions()
|
| 55 |
|
| 56 |
theme,css_style = get_custom_theme()
|
| 57 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 58 |
|
| 59 |
with gr.Blocks(theme=theme, css=css_style) as demo:
|
| 60 |
session_hash_code = gr.State()
|
| 61 |
+
with gr.Accordion("DEGUG PANEL", open=False, visible=DEBUG):
|
| 62 |
+
session_hash_code_box = gr.Textbox(label="Session ID", interactive=False, visible=DEBUG)
|
| 63 |
+
with gr.Accordion("📊 Active Sessions Hash", open=True ,visible=DEBUG):
|
| 64 |
+
sessions_table = gr.DataFrame(
|
| 65 |
+
headers=["session_hash_code", "file", "start_time", "status"],
|
| 66 |
+
interactive=False,
|
| 67 |
+
wrap=True,
|
| 68 |
+
max_height=200,
|
| 69 |
+
)
|
| 70 |
+
gr.Timer(3.0).tick(fn=get_active_session_hashes, outputs=sessions_table)
|
| 71 |
|
| 72 |
demo.load(fn=on_load, inputs=None, outputs=[session_hash_code, session_hash_code_box])
|
| 73 |
demo.unload(fn=on_unload)
|
|
|
|
| 293 |
chunk_secs, left_context_secs, right_context_secs,
|
| 294 |
streaming_policy, alignatt_thr, waitk_lagging,
|
| 295 |
exclude_sink_frames, xatt_scores_layer, hallucinations_detector]
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 296 |
|
| 297 |
+
def start_task_asr_ast(
|
|
|
|
|
|
|
|
|
|
| 298 |
session_hash_code,
|
| 299 |
task_type, lang_source, lang_target,
|
| 300 |
chunk_secs, left_context_secs, right_context_secs,
|
|
|
|
| 321 |
|
| 322 |
|
| 323 |
start_task_button.click(
|
| 324 |
+
fn=start_task_asr_ast,
|
| 325 |
inputs=[
|
| 326 |
session_hash_code,
|
| 327 |
task_type, lang_source, lang_target,
|
|
|
|
| 333 |
outputs=[task_output,status_message_task,start_task_button,stop_task_button]
|
| 334 |
)
|
| 335 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 336 |
ui_components = [
|
| 337 |
start_stream_button, stop_stream_button,
|
| 338 |
go_to_config, audio_source_step, status_slider,walkthrough,status_message_stream
|
|
|
|
| 346 |
concurrency_limit=10,
|
| 347 |
)
|
| 348 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 349 |
|
| 350 |
|
| 351 |
if __name__ == "__main__":
|
app/session_utils.py
CHANGED
|
@@ -79,7 +79,7 @@ def ensure_tmp_dir():
|
|
| 79 |
logging.error(f"Failed to create tmp directory {TMP_DIR}: {e}")
|
| 80 |
|
| 81 |
|
| 82 |
-
def
|
| 83 |
"""Removes all temporary session_hash_code files and folders at startup."""
|
| 84 |
ensure_tmp_dir()
|
| 85 |
|
|
@@ -210,7 +210,7 @@ def unregister_session_hash_code_hash(session_hash_code: str):
|
|
| 210 |
logging.error(f"[{session_hash_code}] Error unregistering session_hash_code: {e}")
|
| 211 |
|
| 212 |
|
| 213 |
-
def
|
| 214 |
"""Returns active session_hash_codes as a list of rows for the DataFrame."""
|
| 215 |
if not os.path.exists(ACTIVE_SESSIONS_HASH_FILE):
|
| 216 |
return []
|
|
@@ -259,5 +259,5 @@ def remove_active_task_flag_file(session_hash_code: str):
|
|
| 259 |
except Exception as e:
|
| 260 |
logging.warning(f"[{session_hash_code}] Failed to remove file {fname}: {e}")
|
| 261 |
|
| 262 |
-
def
|
| 263 |
return os.path.join(TMP_DIR, f"{NAME_FOLDER_CHUNKS}{session_hash_code}")
|
|
|
|
| 79 |
logging.error(f"Failed to create tmp directory {TMP_DIR}: {e}")
|
| 80 |
|
| 81 |
|
| 82 |
+
def reset_all_active_sessions():
|
| 83 |
"""Removes all temporary session_hash_code files and folders at startup."""
|
| 84 |
ensure_tmp_dir()
|
| 85 |
|
|
|
|
| 210 |
logging.error(f"[{session_hash_code}] Error unregistering session_hash_code: {e}")
|
| 211 |
|
| 212 |
|
| 213 |
+
def get_active_session_hashes():
|
| 214 |
"""Returns active session_hash_codes as a list of rows for the DataFrame."""
|
| 215 |
if not os.path.exists(ACTIVE_SESSIONS_HASH_FILE):
|
| 216 |
return []
|
|
|
|
| 259 |
except Exception as e:
|
| 260 |
logging.warning(f"[{session_hash_code}] Failed to remove file {fname}: {e}")
|
| 261 |
|
| 262 |
+
def get_session_hashe_chunks_dir(session_hash_code: str):
|
| 263 |
return os.path.join(TMP_DIR, f"{NAME_FOLDER_CHUNKS}{session_hash_code}")
|
app/streaming_audio_processor.py
CHANGED
|
@@ -171,8 +171,7 @@ class StreamingAudioProcessor:
|
|
| 171 |
Flushes anything remaining in the buffer.
|
| 172 |
"""
|
| 173 |
logging.info("Finalizing stream. Flushing final buffer...")
|
| 174 |
-
|
| 175 |
-
|
| 176 |
-
|
| 177 |
-
return final_text
|
| 178 |
|
|
|
|
| 171 |
Flushes anything remaining in the buffer.
|
| 172 |
"""
|
| 173 |
logging.info("Finalizing stream. Flushing final buffer...")
|
| 174 |
+
for reset_text in self._flush_and_reset() :
|
| 175 |
+
logging.info(f"Received final flushed text: '{reset_text}'")
|
| 176 |
+
yield reset_text
|
|
|
|
| 177 |
|
app/utils.py
CHANGED
|
@@ -19,7 +19,7 @@ from app.session_utils import (
|
|
| 19 |
get_active_stream_flag_file,
|
| 20 |
remove_active_stream_flag_file,
|
| 21 |
remove_active_task_flag_file,
|
| 22 |
-
|
| 23 |
)
|
| 24 |
from app.ui_utils import (
|
| 25 |
SUPPORTED_LANGS_MAP
|
|
@@ -105,7 +105,7 @@ def read_and_stream_audio(filepath_to_stream: str, session_hash_code: str,read_s
|
|
| 105 |
time.sleep(chunk_duration_ms/1000)
|
| 106 |
# Save only if transcription is active
|
| 107 |
if os.path.exists(task_active_flag) :
|
| 108 |
-
chunk_dir =
|
| 109 |
if not os.path.exists(chunk_dir) :
|
| 110 |
os.makedirs(chunk_dir, exist_ok=True)
|
| 111 |
npz_path = os.path.join(chunk_dir, f"chunk_{i:05d}.npz")
|
|
@@ -114,7 +114,7 @@ def read_and_stream_audio(filepath_to_stream: str, session_hash_code: str,read_s
|
|
| 114 |
np.savez_compressed(npz_path, data=chunk_array, rate=frame_rate)
|
| 115 |
logging.debug(f"[{session_hash_code}] Saved chunk {i}/{total_chunks} (transcribe active) ({progress}%) ({npz_path}).")
|
| 116 |
|
| 117 |
-
#
|
| 118 |
|
| 119 |
logging.info(f"[{session_hash_code}] Audio streaming completed successfully.")
|
| 120 |
|
|
@@ -166,7 +166,7 @@ def task_fake(session_hash_code: str,
|
|
| 166 |
active_flag = get_active_task_flag_file(session_hash_code)
|
| 167 |
with open(active_flag, "w") as f:
|
| 168 |
f.write("1")
|
| 169 |
-
chunk_dir =
|
| 170 |
logging.info(f"[{session_hash_code}] task started. {chunk_dir}")
|
| 171 |
|
| 172 |
try:
|
|
@@ -268,7 +268,7 @@ def task(session_hash_code: str,
|
|
| 268 |
active_flag = get_active_task_flag_file(session_hash_code)
|
| 269 |
with open(active_flag, "w") as f:
|
| 270 |
f.write("1")
|
| 271 |
-
chunk_dir =
|
| 272 |
logging.info(f"[{session_hash_code}] task started. {chunk_dir}")
|
| 273 |
|
| 274 |
try:
|
|
@@ -308,8 +308,8 @@ def task(session_hash_code: str,
|
|
| 308 |
time.sleep(0.1)
|
| 309 |
|
| 310 |
# TODO
|
| 311 |
-
|
| 312 |
-
|
| 313 |
# if final_text:
|
| 314 |
# print(final_text, end='', flush=True)
|
| 315 |
# yield f"\n{final_text}"
|
|
@@ -392,7 +392,7 @@ def _is_stop_requested(session_hash_code) -> bool:
|
|
| 392 |
|
| 393 |
|
| 394 |
|
| 395 |
-
def
|
| 396 |
"""Raise an error randomly (1 out of 10 times)."""
|
| 397 |
if random.randint(1, 10) == 1:
|
| 398 |
raise RuntimeError("Random failure triggered!")
|
|
@@ -447,7 +447,3 @@ def get_current_device():
|
|
| 447 |
|
| 448 |
|
| 449 |
|
| 450 |
-
def raise_function():
|
| 451 |
-
"""Raise an error randomly (1 out of 10 times)."""
|
| 452 |
-
if random.randint(1, 50) == 1:
|
| 453 |
-
raise RuntimeError("Random failure triggered!")
|
|
|
|
| 19 |
get_active_stream_flag_file,
|
| 20 |
remove_active_stream_flag_file,
|
| 21 |
remove_active_task_flag_file,
|
| 22 |
+
get_session_hashe_chunks_dir
|
| 23 |
)
|
| 24 |
from app.ui_utils import (
|
| 25 |
SUPPORTED_LANGS_MAP
|
|
|
|
| 105 |
time.sleep(chunk_duration_ms/1000)
|
| 106 |
# Save only if transcription is active
|
| 107 |
if os.path.exists(task_active_flag) :
|
| 108 |
+
chunk_dir = get_session_hashe_chunks_dir(session_hash_code)
|
| 109 |
if not os.path.exists(chunk_dir) :
|
| 110 |
os.makedirs(chunk_dir, exist_ok=True)
|
| 111 |
npz_path = os.path.join(chunk_dir, f"chunk_{i:05d}.npz")
|
|
|
|
| 114 |
np.savez_compressed(npz_path, data=chunk_array, rate=frame_rate)
|
| 115 |
logging.debug(f"[{session_hash_code}] Saved chunk {i}/{total_chunks} (transcribe active) ({progress}%) ({npz_path}).")
|
| 116 |
|
| 117 |
+
# raise_error() # Optional injected test exception
|
| 118 |
|
| 119 |
logging.info(f"[{session_hash_code}] Audio streaming completed successfully.")
|
| 120 |
|
|
|
|
| 166 |
active_flag = get_active_task_flag_file(session_hash_code)
|
| 167 |
with open(active_flag, "w") as f:
|
| 168 |
f.write("1")
|
| 169 |
+
chunk_dir = get_session_hashe_chunks_dir(session_hash_code)
|
| 170 |
logging.info(f"[{session_hash_code}] task started. {chunk_dir}")
|
| 171 |
|
| 172 |
try:
|
|
|
|
| 268 |
active_flag = get_active_task_flag_file(session_hash_code)
|
| 269 |
with open(active_flag, "w") as f:
|
| 270 |
f.write("1")
|
| 271 |
+
chunk_dir = get_session_hashe_chunks_dir(session_hash_code)
|
| 272 |
logging.info(f"[{session_hash_code}] task started. {chunk_dir}")
|
| 273 |
|
| 274 |
try:
|
|
|
|
| 308 |
time.sleep(0.1)
|
| 309 |
|
| 310 |
# TODO
|
| 311 |
+
for final_text in streamer.finalize_stream() :
|
| 312 |
+
yield (text, "success", final_text)
|
| 313 |
# if final_text:
|
| 314 |
# print(final_text, end='', flush=True)
|
| 315 |
# yield f"\n{final_text}"
|
|
|
|
| 392 |
|
| 393 |
|
| 394 |
|
| 395 |
+
def raise_error():
|
| 396 |
"""Raise an error randomly (1 out of 10 times)."""
|
| 397 |
if random.randint(1, 10) == 1:
|
| 398 |
raise RuntimeError("Random failure triggered!")
|
|
|
|
| 447 |
|
| 448 |
|
| 449 |
|
|
|
|
|
|
|
|
|
|
|
|