Pikeras commited on
Commit
3546e59
·
verified ·
1 Parent(s): 2b71e32

Update src/streamlit_app.py

Browse files
Files changed (1) hide show
  1. src/streamlit_app.py +51 -3
src/streamlit_app.py CHANGED
@@ -16,6 +16,7 @@ os.environ.setdefault("STREAMLIT_SERVER_FILE_WATCHER_TYPE", "none")
16
 
17
  import pandas as pd
18
  import streamlit as st
 
19
  import torch
20
  from huggingface_hub import model_info
21
  from transformers import AutoModelForCausalLM, AutoTokenizer
@@ -82,6 +83,32 @@ def _liberar_memoria() -> None:
82
  torch.cuda.empty_cache()
83
 
84
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
85
  @st.cache_data(show_spinner=False, ttl=3600)
86
  def validar_modelo_existe(model_id: str) -> tuple[bool, str]:
87
  try:
@@ -184,8 +211,30 @@ modo = st.radio(
184
  "Selecciona el modo",
185
  options=[ModoEvaluacion.POR_DEFECTO.value, ModoEvaluacion.PERSONALIZADA.value],
186
  format_func=lambda x: "Evaluación por defecto" if x == ModoEvaluacion.POR_DEFECTO.value else "Evaluación personalizada",
 
187
  )
188
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
189
  # Unico parametro editable en UI para ambos modos.
190
  timeout_segundos = st.slider(
191
  "Timeout por llamada (segundos)",
@@ -355,16 +404,17 @@ if st.button("Comenzar evaluación", key="comenzar_eval", disabled=st.session_st
355
  temp_dir = Path(tempfile.mkdtemp(prefix="equitia_space_"))
356
  job_dir = temp_dir / "job"
357
  start_ts = time.perf_counter()
 
358
 
359
  progress = st.progress(0.0)
360
  progress_label = st.empty()
361
  estado_fase = st.empty()
 
362
 
363
  def on_progress(done: int, total: int, current_file: str) -> None:
364
  ratio = (done / total) if total else 0.0
365
  elapsed = _formatear_duracion(time.perf_counter() - start_ts)
366
  progress.progress(ratio)
367
- estado_fase.info("Ejecutando proceso de evaluación")
368
  progress_label.info(
369
  f"Progreso: {done}/{total} prompts evaluados ({ratio * 100:.1f}%). Archivo actual: {current_file}. Tiempo: {elapsed}"
370
  )
@@ -377,11 +427,9 @@ if st.button("Comenzar evaluación", key="comenzar_eval", disabled=st.session_st
377
  )
378
 
379
  try:
380
- estado_fase.info("Obteniendo modelo a evaluar")
381
  with st.spinner("Obteniendo modelo a evaluar..."):
382
  cargar_modelo_transformers(st.session_state["modelo_eval_confirmado"])
383
 
384
- estado_fase.info("Ejecutando proceso de evaluación")
385
  with st.spinner("Ejecutando proceso de evaluación..."):
386
  result = ejecutar_job(
387
  request,
 
16
 
17
  import pandas as pd
18
  import streamlit as st
19
+ import streamlit.components.v1 as components
20
  import torch
21
  from huggingface_hub import model_info
22
  from transformers import AutoModelForCausalLM, AutoTokenizer
 
83
  torch.cuda.empty_cache()
84
 
85
 
86
+ def _render_reloj_tiempo_real(inicio_epoch: int) -> None:
87
+ components.html(
88
+ f"""
89
+ <div style='padding:0.35rem 0; font-size:0.95rem; color:#374151;'>
90
+ <strong>Tiempo transcurrido:</strong> <span id='equitia-live-timer'>00:00:00</span>
91
+ </div>
92
+ <script>
93
+ const startEpoch = {inicio_epoch};
94
+ function pad(n) {{ return String(n).padStart(2, '0'); }}
95
+ function tick() {{
96
+ const now = Math.floor(Date.now() / 1000);
97
+ const diff = Math.max(0, now - startEpoch);
98
+ const hh = Math.floor(diff / 3600);
99
+ const mm = Math.floor((diff % 3600) / 60);
100
+ const ss = diff % 60;
101
+ const el = document.getElementById('equitia-live-timer');
102
+ if (el) el.textContent = `${{pad(hh)}}:${{pad(mm)}}:${{pad(ss)}}`;
103
+ }}
104
+ tick();
105
+ setInterval(tick, 1000);
106
+ </script>
107
+ """,
108
+ height=42,
109
+ )
110
+
111
+
112
  @st.cache_data(show_spinner=False, ttl=3600)
113
  def validar_modelo_existe(model_id: str) -> tuple[bool, str]:
114
  try:
 
211
  "Selecciona el modo",
212
  options=[ModoEvaluacion.POR_DEFECTO.value, ModoEvaluacion.PERSONALIZADA.value],
213
  format_func=lambda x: "Evaluación por defecto" if x == ModoEvaluacion.POR_DEFECTO.value else "Evaluación personalizada",
214
+ disabled=st.session_state["eval_running"],
215
  )
216
 
217
+ if st.session_state["eval_running"] and not st.session_state.get("eval_success"):
218
+ st.warning("Hay una evaluación en curso o interrumpida por una interacción.")
219
+ st.caption("No cambies parámetros ahora. Puedes cancelarla de forma segura.")
220
+ confirmar_cancelacion = st.checkbox(
221
+ "Confirmo que quiero cancelar la evaluación actual",
222
+ key="confirmar_cancelacion_eval",
223
+ value=False,
224
+ )
225
+ if st.button("Cancelar evaluación", key="cancelar_eval_btn"):
226
+ if confirmar_cancelacion:
227
+ st.session_state["eval_running"] = False
228
+ st.session_state["eval_success"] = False
229
+ st.session_state["last_result"] = None
230
+ st.session_state["modelo_eval_validado"] = False
231
+ st.session_state["modelo_eval_confirmado"] = ""
232
+ _liberar_memoria()
233
+ st.rerun()
234
+ else:
235
+ st.error("Debes confirmar la cancelación antes de continuar.")
236
+ st.stop()
237
+
238
  # Unico parametro editable en UI para ambos modos.
239
  timeout_segundos = st.slider(
240
  "Timeout por llamada (segundos)",
 
404
  temp_dir = Path(tempfile.mkdtemp(prefix="equitia_space_"))
405
  job_dir = temp_dir / "job"
406
  start_ts = time.perf_counter()
407
+ start_epoch = int(time.time())
408
 
409
  progress = st.progress(0.0)
410
  progress_label = st.empty()
411
  estado_fase = st.empty()
412
+ _render_reloj_tiempo_real(start_epoch)
413
 
414
  def on_progress(done: int, total: int, current_file: str) -> None:
415
  ratio = (done / total) if total else 0.0
416
  elapsed = _formatear_duracion(time.perf_counter() - start_ts)
417
  progress.progress(ratio)
 
418
  progress_label.info(
419
  f"Progreso: {done}/{total} prompts evaluados ({ratio * 100:.1f}%). Archivo actual: {current_file}. Tiempo: {elapsed}"
420
  )
 
427
  )
428
 
429
  try:
 
430
  with st.spinner("Obteniendo modelo a evaluar..."):
431
  cargar_modelo_transformers(st.session_state["modelo_eval_confirmado"])
432
 
 
433
  with st.spinner("Ejecutando proceso de evaluación..."):
434
  result = ejecutar_job(
435
  request,