Shivam commited on
Commit
2f5908d
·
1 Parent(s): cfd5b8d

eval script in about, fix for qwen,

Browse files
Files changed (4) hide show
  1. app.py +6 -1
  2. constants.py +3 -0
  3. job_queue.py +1 -0
  4. storage.py +179 -7
app.py CHANGED
@@ -1069,10 +1069,15 @@ with gr.Blocks(title=APP_TITLE, theme=_theme, css=LEADERBOARD_CSS) as demo:
1069
  if job["req_count"]
1070
  else "no extra reqs"
1071
  )
 
 
 
 
 
1072
  with gr.Row(elem_classes=row_cls):
1073
  gr.Markdown(
1074
  f"**`{jid}`** · `{job['model_id']}` · "
1075
- f"`{job['family_id']}`{gated}{script_bit} · {extras} · "
1076
  f"{job['notes_preview'] or '—'} · {job['created_at']}",
1077
  elem_classes="ffasr-job-info",
1078
  )
 
1069
  if job["req_count"]
1070
  else "no extra reqs"
1071
  )
1072
+ email_bit = (
1073
+ f" · 📧 `{job['contact_email']}`"
1074
+ if job.get("contact_email")
1075
+ else " · 📧 *(none)*"
1076
+ )
1077
  with gr.Row(elem_classes=row_cls):
1078
  gr.Markdown(
1079
  f"**`{jid}`** · `{job['model_id']}` · "
1080
+ f"`{job['family_id']}`{gated}{script_bit} · {extras}{email_bit} · "
1081
  f"{job['notes_preview'] or '—'} · {job['created_at']}",
1082
  elem_classes="ffasr-job-info",
1083
  )
constants.py CHANGED
@@ -181,6 +181,9 @@ quantify latency. The balance between performance and latency is of practical im
181
  may run as part of a real‑time interaction with users. A Pareto plot helps visualize this tradeoff (a single metric
182
  balancing Avg WER and RTFx, e.g. area under the curve, could also be considered).
183
 
 
 
 
184
  ### Word Error Rate (WER)
185
 
186
  WER is the fraction of reference words that are substituted, inserted, or deleted:
 
181
  may run as part of a real‑time interaction with users. A Pareto plot helps visualize this tradeoff (a single metric
182
  balancing Avg WER and RTFx, e.g. area under the curve, could also be considered).
183
 
184
+ Scoring is performed by [`benchmark/dataset.py`](https://huggingface.co/spaces/treble-technologies/ffasr/blob/main/benchmark/dataset.py),
185
+ which calls `evaluate_condition_wer_timed` for each inference to compute the per‑condition WER and timing used for RTFx.
186
+
187
  ### Word Error Rate (WER)
188
 
189
  WER is the fraction of reference words that are substituted, inserted, or deleted:
job_queue.py CHANGED
@@ -1871,6 +1871,7 @@ def pending_jobs_for_render(limit: int = 60) -> list[dict[str, Any]]:
1871
  "model_id": j.model_id,
1872
  "family_id": j.family_id,
1873
  "created_at": (j.created_at or "")[:19],
 
1874
  "is_gated": j.is_gated,
1875
  "req_count": len(parse_requirements_lines(j.extra_requirements or "")),
1876
  "notes_preview": (
 
1871
  "model_id": j.model_id,
1872
  "family_id": j.family_id,
1873
  "created_at": (j.created_at or "")[:19],
1874
+ "contact_email": (j.contact_email or "").strip(),
1875
  "is_gated": j.is_gated,
1876
  "req_count": len(parse_requirements_lines(j.extra_requirements or "")),
1877
  "notes_preview": (
storage.py CHANGED
@@ -23,6 +23,8 @@ runtime default token).
23
 
24
  import io
25
  import os
 
 
26
  import tempfile
27
  from contextlib import nullcontext
28
  from pathlib import Path
@@ -127,7 +129,14 @@ def upload_to_bucket(
127
  Upload/copy/delete bucket files with progress bars disabled and Xet reporter compatibility.
128
  """
129
  if batch_bucket_files is None:
130
- raise RuntimeError("huggingface_hub bucket support is not available")
 
 
 
 
 
 
 
131
  _ensure_xet_progress_reporter_compatible()
132
  try:
133
  from huggingface_hub.utils import disable_progress_bars
@@ -145,13 +154,176 @@ def upload_to_bucket(
145
  )
146
 
147
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
148
  def download_bucket_file(path: str) -> str:
149
- """Download a single file from HF Bucket and return the local path."""
 
 
 
 
 
150
  local_dir = tempfile.mkdtemp()
151
  local_path = os.path.join(local_dir, os.path.basename(path))
152
- download_bucket_files(
153
- HF_BUCKET_ID,
154
- files=[(path, local_path)],
155
- token=HF_TOKEN,
156
- )
 
 
 
157
  return local_path
 
23
 
24
  import io
25
  import os
26
+ import shutil
27
+ import subprocess
28
  import tempfile
29
  from contextlib import nullcontext
30
  from pathlib import Path
 
129
  Upload/copy/delete bucket files with progress bars disabled and Xet reporter compatibility.
130
  """
131
  if batch_bucket_files is None:
132
+ # In-process hub lacks the bucket API (e.g. qwen-asr stack pins hub<1.0).
133
+ # Fall back to an isolated uv env that has it.
134
+ if not _bucket_uv_available():
135
+ raise RuntimeError("huggingface_hub bucket support is not available")
136
+ _upload_to_bucket_via_uv(
137
+ bucket_id, add=add, copy=copy, delete=delete, token=token
138
+ )
139
+ return
140
  _ensure_xet_progress_reporter_compatible()
141
  try:
142
  from huggingface_hub.utils import disable_progress_bars
 
154
  )
155
 
156
 
157
+ # huggingface_hub version that ships the bucket API, used by the isolated-subprocess
158
+ # fallback when the in-process hub is pinned <1.0 (e.g. the qwen-asr stack, whose
159
+ # transformers==4.57.x pin forces huggingface-hub<1.0 and so lacks bucket support).
160
+ _BUCKET_FALLBACK_HUB_SPEC = os.environ.get(
161
+ "FFASR_BUCKET_FALLBACK_HUB_SPEC", "huggingface-hub>=1.14.0"
162
+ )
163
+
164
+ _BUCKET_DOWNLOAD_SNIPPET = """\
165
+ import os, sys
166
+ from huggingface_hub import download_bucket_files
167
+
168
+ bucket_id, remote_path, local_path = sys.argv[1], sys.argv[2], sys.argv[3]
169
+ download_bucket_files(
170
+ bucket_id,
171
+ files=[(remote_path, local_path)],
172
+ token=os.environ.get("FFASR_BUCKET_DL_TOKEN") or None,
173
+ )
174
+ """
175
+
176
+ _BUCKET_UPLOAD_SNIPPET = """\
177
+ import json, os, sys
178
+ from huggingface_hub import batch_bucket_files
179
+
180
+ try:
181
+ from huggingface_hub.utils import disable_progress_bars
182
+ disable_progress_bars()
183
+ except Exception:
184
+ pass
185
+
186
+ manifest_path, bucket_id = sys.argv[1], sys.argv[2]
187
+ with open(manifest_path, encoding="utf-8") as f:
188
+ manifest = json.load(f)
189
+ add = [(src, dst) for src, dst in manifest.get("add", [])] or None
190
+ copy = [tuple(c) for c in manifest.get("copy", [])] or None
191
+ delete = list(manifest.get("delete", [])) or None
192
+ batch_bucket_files(
193
+ bucket_id,
194
+ add=add,
195
+ copy=copy,
196
+ delete=delete,
197
+ token=os.environ.get("FFASR_BUCKET_DL_TOKEN") or None,
198
+ )
199
+ """
200
+
201
+
202
+ def _bucket_uv_available() -> bool:
203
+ return shutil.which("uv") is not None
204
+
205
+
206
+ def _run_bucket_uv_snippet(
207
+ snippet: str, args: list[str], *, token: str | None = None
208
+ ) -> subprocess.CompletedProcess:
209
+ """Run ``snippet`` in an isolated ``uv`` env that has the hub bucket API.
210
+
211
+ Used when this process' ``huggingface_hub`` is pinned <1.0 (no bucket support).
212
+ ``uv`` resolves an ephemeral, cached environment with a recent ``huggingface_hub``
213
+ (plus ``hf_xet`` for Xet-backed buckets), independent of the job's pinned stack.
214
+ The Hub token is passed via ``FFASR_BUCKET_DL_TOKEN`` (never on argv).
215
+ """
216
+ uv = shutil.which("uv") or "uv"
217
+ cmd = [
218
+ uv,
219
+ "run",
220
+ "--no-project",
221
+ "--python",
222
+ "3.12",
223
+ "--with",
224
+ _BUCKET_FALLBACK_HUB_SPEC,
225
+ "--with",
226
+ "hf_xet",
227
+ "python",
228
+ "-c",
229
+ snippet,
230
+ *args,
231
+ ]
232
+ env = dict(os.environ)
233
+ tok = token or HF_TOKEN
234
+ if tok:
235
+ env["FFASR_BUCKET_DL_TOKEN"] = tok
236
+ env.setdefault("HF_HUB_DISABLE_PROGRESS_BARS", "1")
237
+ try:
238
+ return subprocess.run(
239
+ cmd,
240
+ env=env,
241
+ check=False,
242
+ capture_output=True,
243
+ text=True,
244
+ )
245
+ except FileNotFoundError as exc:
246
+ raise RuntimeError(
247
+ "huggingface_hub bucket support is not available in this environment and the "
248
+ "`uv` fallback could not be launched (uv not found on PATH)."
249
+ ) from exc
250
+
251
+
252
+ def _download_bucket_file_via_uv(path: str, local_path: str) -> None:
253
+ proc = _run_bucket_uv_snippet(
254
+ _BUCKET_DOWNLOAD_SNIPPET, [HF_BUCKET_ID, path, local_path]
255
+ )
256
+ if proc.returncode != 0 or not os.path.exists(local_path):
257
+ tail = (proc.stderr or proc.stdout or "").strip()[-2000:]
258
+ raise RuntimeError(
259
+ "Bucket download via isolated uv environment failed "
260
+ f"(exit {proc.returncode}) for '{path}'.\n{tail}"
261
+ )
262
+
263
+
264
+ def _upload_to_bucket_via_uv(
265
+ bucket_id: str,
266
+ *,
267
+ add: list[tuple[str | Path | bytes, str]] | None,
268
+ copy: list[tuple[str, str, str, str]] | None,
269
+ delete: list[str] | None,
270
+ token: str | bool | None = None,
271
+ ) -> None:
272
+ """Upload/copy/delete bucket files via the isolated ``uv`` env (hub <1.0 fallback).
273
+
274
+ ``bytes`` sources in ``add`` are materialized to temp files so the subprocess can
275
+ pass plain file paths to ``batch_bucket_files``.
276
+ """
277
+ tmpdir = tempfile.mkdtemp(prefix="ffasr_bucket_up_")
278
+ try:
279
+ add_items: list[tuple[str, str]] = []
280
+ for i, (src, dst) in enumerate(add or []):
281
+ if isinstance(src, (bytes, bytearray)):
282
+ src_path = os.path.join(tmpdir, f"add_{i}_{os.path.basename(dst) or 'blob'}")
283
+ with open(src_path, "wb") as fh:
284
+ fh.write(src)
285
+ else:
286
+ src_path = os.fspath(src)
287
+ add_items.append((src_path, dst))
288
+ manifest = {
289
+ "add": add_items,
290
+ "copy": [list(c) for c in (copy or [])],
291
+ "delete": list(delete or []),
292
+ }
293
+ import json as _json
294
+
295
+ manifest_path = os.path.join(tmpdir, "manifest.json")
296
+ with open(manifest_path, "w", encoding="utf-8") as fh:
297
+ _json.dump(manifest, fh)
298
+ snippet_token = token if isinstance(token, str) else None
299
+ proc = _run_bucket_uv_snippet(
300
+ _BUCKET_UPLOAD_SNIPPET, [manifest_path, bucket_id], token=snippet_token
301
+ )
302
+ if proc.returncode != 0:
303
+ tail = (proc.stderr or proc.stdout or "").strip()[-2000:]
304
+ raise RuntimeError(
305
+ "Bucket upload via isolated uv environment failed "
306
+ f"(exit {proc.returncode}).\n{tail}"
307
+ )
308
+ finally:
309
+ shutil.rmtree(tmpdir, ignore_errors=True)
310
+
311
+
312
  def download_bucket_file(path: str) -> str:
313
+ """Download a single file from HF Bucket and return the local path.
314
+
315
+ Uses the in-process bucket API when available; otherwise falls back to an isolated
316
+ ``uv`` environment that has a hub version with bucket support (the qwen-asr stack
317
+ pins huggingface-hub<1.0, which lacks the bucket API).
318
+ """
319
  local_dir = tempfile.mkdtemp()
320
  local_path = os.path.join(local_dir, os.path.basename(path))
321
+ if download_bucket_files is not None:
322
+ download_bucket_files(
323
+ HF_BUCKET_ID,
324
+ files=[(path, local_path)],
325
+ token=HF_TOKEN,
326
+ )
327
+ else:
328
+ _download_bucket_file_via_uv(path, local_path)
329
  return local_path