bezzam HF Staff commited on
Commit
e3c4506
·
verified ·
1 Parent(s): df5c0ac

Update run_eval.py

Browse files
Files changed (1) hide show
  1. run_eval.py +103 -309
run_eval.py CHANGED
@@ -1,276 +1,100 @@
 
 
 
 
 
 
 
 
 
 
 
 
1
  import argparse
2
  import os
3
- import re
 
 
 
4
  import torch
5
- from torch.nn.attention import sdpa_kernel, SDPBackend
6
- from transformers import AutoConfig, AutoModelForSpeechSeq2Seq, AutoModelForMultimodalLM, AutoModelForCTC, AutoProcessor, MODEL_FOR_MULTIMODAL_LM_MAPPING, MODEL_FOR_SPEECH_SEQ_2_SEQ_MAPPING, MODEL_FOR_CTC_MAPPING, CompileConfig
7
  import evaluate
8
  from normalizer import data_utils
 
9
  from tqdm import tqdm
10
- import random
11
- import numpy as np
12
 
13
  wer_metric = evaluate.load("wer")
14
- torch.set_float32_matmul_precision('high')
15
 
16
 
17
- def remove_brackets(text):
18
- """
19
- Remove parentheses from text, replacing them with spaces.
20
 
21
- Some models (e.g. Cohere ASR) output parentheses that would cause the
22
- normalizer to delete the enclosed text entirely, leading to false
23
- deletion errors in the predictions.
24
  """
25
- text = text.replace("(", " ").replace(")", " ")
26
- text = re.sub(r'\s+', ' ', text)
27
- return text
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
28
 
29
 
30
  def main(args):
 
31
 
32
- # Set seed due to randomness in some models (e.g. VibeVoice's acoustic tokenizer sampling)
33
- seed = 42
34
- random.seed(seed)
35
- np.random.seed(seed)
36
- torch.manual_seed(seed)
37
- torch.cuda.manual_seed_all(seed)
38
- torch.backends.cudnn.deterministic = True
39
-
40
- torch_dtype = getattr(torch, args.dtype)
41
-
42
- config = AutoConfig.from_pretrained(args.model_id, revision=args.revision)
43
- if type(config) in MODEL_FOR_SPEECH_SEQ_2_SEQ_MAPPING:
44
- cls_model = AutoModelForSpeechSeq2Seq
45
- elif type(config) in MODEL_FOR_MULTIMODAL_LM_MAPPING:
46
- cls_model = AutoModelForMultimodalLM
47
- elif type(config) in MODEL_FOR_CTC_MAPPING:
48
- cls_model = AutoModelForCTC
49
- else:
50
- raise ValueError(f"Model config of type {type(config)} not recognized in Transformers mappings.")
51
- is_ctc = cls_model == AutoModelForCTC
52
-
53
- if "vibevoice" in args.model_id.lower():
54
- model = cls_model.from_pretrained(
55
- args.model_id,
56
- dtype=torch_dtype,
57
- attn_implementation={
58
- "acoustic_tokenizer_encoder_config": "eager",
59
- "semantic_tokenizer_encoder_config": "eager",
60
- "text_config": "sdpa",
61
- }
62
- )
63
- else:
64
- model = cls_model.from_pretrained(
65
- args.model_id,
66
- dtype=torch_dtype,
67
- revision=args.revision,
68
- attn_implementation=args.attn_implementation,
69
- )
70
- model.to(args.device)
71
  model.eval()
72
  print(f"Model size: {sum(p.numel() for p in model.parameters()) / 1e9:.2f}B parameters")
73
- processor = AutoProcessor.from_pretrained(args.model_id, revision=args.revision)
74
- has_transcription_processor = hasattr(processor, "apply_transcription_request")
75
- is_cohere = "cohere" in args.model_id.lower() and "transcribe" in args.model_id.lower()
76
-
77
- # Optional prompt for audio language models, newer models should use `apply_transcription_request`
78
- text = None
79
- if "granite-speech-3.3" in args.model_id.lower():
80
- # create text prompt
81
- chat = [
82
- {
83
- "role": "system",
84
- "content": "Knowledge Cutoff Date: April 2024.\nToday's Date: December 19, 2024.\nYou are Granite, developed by IBM. You are a helpful AI assistant",
85
- },
86
- {
87
- "role": "user",
88
- "content": "<|audio|>can you transcribe the speech into a written format?",
89
- }
90
- ]
91
 
92
- text = processor.apply_chat_template(
93
- chat, tokenize=False, add_generation_prompt=True
94
- )
95
 
96
- # Extract sampling rate
97
- if hasattr(processor, "feature_extractor") and processor.feature_extractor is not None:
98
- sampling_rate = processor.feature_extractor.sampling_rate
99
- elif hasattr(processor, "audio_processor") and processor.audio_processor is not None:
100
- sampling_rate = processor.audio_processor.sampling_rate
101
- else:
102
- sampling_rate = 16_000
103
-
104
- # Set generate arguments
105
- if model.can_generate():
106
- gen_kwargs = {"max_new_tokens": args.max_new_tokens}
107
- if getattr(model.generation_config, "is_multilingual", False):
108
- gen_kwargs["language"] = "en"
109
- gen_kwargs["task"] = "transcribe"
110
- # Clear deprecated Whisper generation config fields to suppress warnings
111
- if hasattr(model.generation_config, "forced_decoder_ids"):
112
- model.generation_config.forced_decoder_ids = None
113
- if hasattr(model.generation_config, "suppress_tokens"):
114
- model.generation_config.suppress_tokens = []
115
- if hasattr(model.generation_config, "begin_suppress_tokens"):
116
- model.generation_config.begin_suppress_tokens = []
117
- if "granite-speech-3.3" in args.model_id.lower():
118
- gen_kwargs["repetition_penalty"] = 1.0
119
- elif args.max_new_tokens:
120
- raise ValueError("`max_new_tokens` should only be set for auto-regressive models, but got a CTC model.")
121
-
122
- if args.torch_compile is not None:
123
- if model.can_generate():
124
- gen_kwargs["compile_config"] = CompileConfig(mode=args.torch_compile, fullgraph=args.compile_fullgraph)
125
- # enable static k/v cache for autoregressive models
126
- model.generation_config.cache_implementation = "static"
127
- else:
128
- model = torch.compile(model, mode=args.torch_compile, fullgraph=args.compile_fullgraph)
129
-
130
- # Ensure warm-up runs when using torch.compile
131
- if args.warmup_steps is None or args.warmup_steps < 1:
132
- print("`--torch_compile` is enabled; forcing `--warmup_steps=10` to trigger compilation before timed runs.")
133
- args.warmup_steps = 10
134
-
135
- def benchmark(batch, min_new_tokens=None):
136
  # Load audio inputs
137
  audios = [audio["array"] for audio in batch["audio"]]
 
 
 
138
  minibatch_size = len(audios)
139
- sampling_rate = batch["audio"][0]["sampling_rate"]
140
- batch["audio_length_s"] = [len(audio) / sampling_rate for audio in audios]
141
- batch["audio_filepath"] = data_utils.extract_audio_filepaths_from_batch(batch, minibatch_size)
142
- if text is not None:
143
- texts=[text] * minibatch_size
144
- else:
145
- texts = None
146
 
147
  # START TIMING
148
- torch.cuda.synchronize(device=args.device)
149
- start_event = torch.cuda.Event(enable_timing=True)
150
- end_event = torch.cuda.Event(enable_timing=True)
151
- start_event.record()
152
-
153
- # 1. Pre-Processing
154
- # 1.1 Pad audios to max batch size if using torch compile to prevent re-compilations
155
- padding_size = None
156
- if minibatch_size != args.batch_size and args.torch_compile is not None:
157
- padding_size = args.batch_size - minibatch_size
158
- padding_audios = [audios[-1] for _ in range(padding_size)]
159
- audios.extend(padding_audios)
160
-
161
- if is_cohere:
162
- inputs = processor(
163
- audios,
164
- sampling_rate=sampling_rate,
165
- return_tensors="pt",
166
- language="en",
167
- punctuation=False,
168
- )
169
- elif has_transcription_processor:
170
- if "voxtral" in args.model_id.lower():
171
- inputs = processor.apply_transcription_request(
172
- language="en", # English for benchmark consistency
173
- audio=audios,
174
- model_id=args.model_id,
175
- sampling_rate=sampling_rate,
176
- format=["wav"] * len(audios),
177
- )
178
- else:
179
- inputs = processor.apply_transcription_request(audios)
180
- prompt_len = inputs["input_ids"].shape[1]
181
- elif texts is not None:
182
- inputs = processor(
183
- texts,
184
- audios,
185
- device=args.device, # Computation device; returned tensors are put on CPU
186
- return_tensors="pt",
187
- ).to(args.device)
188
- prompt_len = inputs["input_ids"].shape[1]
189
- elif not model.can_generate(): #or len(audios[0]) > processor.feature_extractor.n_samples:
190
- # 1.2 Either CTC pre-processing (normalize to mean 0, std 1), or long-form Whisper processing
191
- inputs = processor(
192
- audios,
193
- sampling_rate=sampling_rate,
194
- truncation=False,
195
- padding="longest",
196
- return_tensors="pt",
197
- return_attention_mask=True,
198
- )
199
- else:
200
- # 1.3 Standard Whisper processing: pad audios to 30-seconds and converted to log-mel
201
- if args.longform:
202
- inputs = processor(
203
- audios,
204
- sampling_rate=sampling_rate,
205
- return_tensors="pt",
206
- truncation=False,
207
- padding="longest",
208
- return_attention_mask=True,
209
- )
210
- else:
211
- inputs = processor(audios, sampling_rate=sampling_rate, return_tensors="pt", padding="longest", return_attention_mask=True, device=args.device)
212
-
213
- inputs = inputs.to(args.device, dtype=torch_dtype)
214
-
215
- # 2. Model Inference
216
- if args.torch_compile is not None:
217
- sdpa_backends = [SDPBackend.MATH]
218
- else:
219
- sdpa_backends = [SDPBackend.FLASH_ATTENTION, SDPBackend.EFFICIENT_ATTENTION, SDPBackend.MATH]
220
- with sdpa_kernel(sdpa_backends):
221
- if model.can_generate():
222
- # 2.1 Auto-regressive generation for LM-based models
223
- if args.longform:
224
- pred_ids = model.generate(**inputs, **gen_kwargs, return_timestamps=True)
225
- else:
226
- pred_ids = model.generate(**inputs, **gen_kwargs, min_new_tokens=min_new_tokens)
227
- else:
228
- # 2.2. Single forward pass for CTC
229
- with torch.no_grad():
230
- logits = model(**inputs).logits
231
- pred_ids = logits.argmax(-1)
232
-
233
- # 3. Post-processing
234
- # 3.1 Strip padded ids from predictions
235
- if padding_size is not None:
236
- pred_ids = pred_ids[:-padding_size, ...]
237
-
238
- # 3.2 Convert token ids to text transcription
239
- if is_cohere:
240
- audio_chunk_index = inputs.get("audio_chunk_index")
241
- pred_text = processor.decode(
242
- pred_ids, skip_special_tokens=True,
243
- audio_chunk_index=audio_chunk_index, language="en",
244
- )
245
- pred_text = [remove_brackets(t) for t in pred_text]
246
- elif "vibevoice" in args.model_id.lower():
247
- # VibeVoice: strip the input prompt tokens then use the model's own decode API
248
- generated_ids = pred_ids[:, prompt_len:]
249
- try:
250
- pred_text = processor.decode(generated_ids, return_format="transcription_only")
251
- except Exception as e:
252
- print(f"Batch decoding failed with error: {e}. Falling back to individual sample decoding.")
253
- pred_text = []
254
- for i, sample_ids in enumerate(generated_ids):
255
- try:
256
- decoded = processor.decode(sample_ids.unsqueeze(0), return_format="transcription_only")
257
- pred_text.append(decoded[0] if isinstance(decoded, list) else decoded)
258
- except Exception as sample_error:
259
- print(f"Sample {i} decoding failed with error: {sample_error}. Setting to empty transcript.")
260
- pred_text.append("")
261
- elif has_transcription_processor or texts is not None:
262
- # Strip input prompt tokens
263
- pred_text = processor.decode(pred_ids[:, prompt_len:], skip_special_tokens=True)
264
- elif is_ctc:
265
- # don't use skip_special_tokens as it collapses double letters
266
- pred_text = processor.batch_decode(pred_ids)
267
- else:
268
- pred_text = processor.decode(pred_ids, skip_special_tokens=True)
269
 
270
  # END TIMING
271
- end_event.record()
272
- torch.cuda.synchronize(device=args.device)
273
- runtime = start_event.elapsed_time(end_event) / 1000.0
274
 
275
  # normalize by minibatch size since we want the per-sample time
276
  batch["transcription_time_s"] = minibatch_size * [runtime / minibatch_size]
@@ -281,30 +105,38 @@ def main(args):
281
  return batch
282
 
283
  if args.warmup_steps is not None:
284
- dataset = data_utils.load_data(args)
285
- dataset = data_utils.prepare_data(dataset, sampling_rate=sampling_rate)
286
 
287
  num_warmup_samples = args.warmup_steps * args.batch_size
288
  if args.streaming:
289
- warmup_dataset = dataset.take(num_warmup_samples)
290
  else:
291
- warmup_dataset = dataset.select(range(min(num_warmup_samples, len(dataset))))
292
- warmup_dataset = iter(warmup_dataset.map(benchmark, batch_size=args.batch_size, batched=True, fn_kwargs={"min_new_tokens": args.max_new_tokens}))
 
 
 
 
293
 
294
  for _ in tqdm(warmup_dataset, desc="Warming up..."):
295
  continue
296
 
297
  dataset = data_utils.load_data(args)
 
 
298
  if args.max_eval_samples is not None and args.max_eval_samples > 0:
299
  print(f"Subsampling dataset to first {args.max_eval_samples} samples!")
300
  if args.streaming:
301
  dataset = dataset.take(args.max_eval_samples)
302
  else:
303
- dataset = dataset.select(range(min(args.max_eval_samples, len(dataset))))
304
- dataset = data_utils.prepare_data(dataset, sampling_rate=sampling_rate)
 
305
 
306
  dataset = dataset.map(
307
- benchmark, batch_size=args.batch_size, batched=True, remove_columns=["audio"],
 
308
  )
309
 
310
  all_results = {
@@ -312,7 +144,6 @@ def main(args):
312
  "transcription_time_s": [],
313
  "predictions": [],
314
  "references": [],
315
- "audio_filepath": [],
316
  }
317
  result_iter = iter(dataset)
318
  for result in tqdm(result_iter, desc="Samples..."):
@@ -320,7 +151,6 @@ def main(args):
320
  all_results[key].append(result[key])
321
 
322
  # Write manifest results (WER and RTFX)
323
- # Filtering of empty references is handled inside write_manifest.
324
  manifest_path = data_utils.write_manifest(
325
  all_results["references"],
326
  all_results["predictions"],
@@ -330,7 +160,6 @@ def main(args):
330
  args.split,
331
  audio_length=all_results["audio_length_s"],
332
  transcription_time=all_results["transcription_time_s"],
333
- audio_filepaths=all_results["audio_filepath"],
334
  )
335
  print("Results saved at path:", os.path.abspath(manifest_path))
336
 
@@ -338,7 +167,9 @@ def main(args):
338
  references=all_results["references"], predictions=all_results["predictions"]
339
  )
340
  wer = round(100 * wer, 2)
341
- rtfx = round(sum(all_results["audio_length_s"]) / sum(all_results["transcription_time_s"]), 2)
 
 
342
  print("WER:", wer, "%", "RTFx:", rtfx)
343
 
344
 
@@ -349,26 +180,25 @@ if __name__ == "__main__":
349
  "--model_id",
350
  type=str,
351
  required=True,
352
- help="Model identifier. Should be loadable with 🤗 Transformers",
353
  )
354
  parser.add_argument(
355
  "--dataset_path",
356
  type=str,
357
- default="hf-audio/open-asr-leaderboard",
358
- help="Dataset path. By default, it is `hf-audio/open-asr-leaderboard`",
359
  )
360
  parser.add_argument(
361
  "--dataset",
362
  type=str,
363
  required=True,
364
- help="Dataset name. *E.g.* `'librispeech_asr` for the LibriSpeech ASR dataset, or `'common_voice'` for Common Voice. The full list of dataset names "
365
- "can be found at `https://huggingface.co/datasets/hf-audio/open-asr-leaderboard`",
366
  )
367
  parser.add_argument(
368
  "--split",
369
  type=str,
370
  default="test",
371
- help="Split of the dataset. *E.g.* `'validation`' for the dev split, or `'test'` for the test split.",
372
  )
373
  parser.add_argument(
374
  "--device",
@@ -379,7 +209,7 @@ if __name__ == "__main__":
379
  parser.add_argument(
380
  "--batch_size",
381
  type=int,
382
- default=16,
383
  help="Number of samples to go through each streamed batch.",
384
  )
385
  parser.add_argument(
@@ -389,43 +219,16 @@ if __name__ == "__main__":
389
  help="Number of samples to be evaluated. Put a lower number e.g. 64 for testing this script.",
390
  )
391
  parser.add_argument(
392
- "--streaming",
393
- action="store_true",
394
- help="Stream the dataset lazily over the network instead of downloading it in full before the evaluation. Off by default for reproducible benchmark timings.",
 
395
  )
396
  parser.add_argument(
397
  "--max_new_tokens",
398
  type=int,
399
- default=None,
400
- help="Maximum number of tokens to generate (for auto-regressive models).",
401
- )
402
- parser.add_argument(
403
- "--longform",
404
- action="store_true",
405
- help="Whether to use longform mode.",
406
- )
407
- parser.add_argument(
408
- "--torch_compile",
409
- type=str,
410
- default=None,
411
- help="Mode for torch compiling model forward pass. Can be either 'default', 'reduce-overhead', 'max-autotune' or 'max-autotune-no-cudagraphs'.",
412
- )
413
- parser.add_argument(
414
- "--compile_fullgraph",
415
- action="store_true",
416
- help="Whether to do full graph compilation.",
417
- )
418
- parser.add_argument(
419
- "--dtype",
420
- type=str,
421
- default="bfloat16",
422
- help="The dtype to use for model loading and inference. E.g. 'bfloat16', 'float16', 'float32'.",
423
- )
424
- parser.add_argument(
425
- "--attn_implementation",
426
- type=str,
427
- default="sdpa",
428
- help="Attention implementation to use for model loading (e.g. 'sdpa', 'eager', 'flash_attention_2').",
429
  )
430
  parser.add_argument(
431
  "--warmup_steps",
@@ -433,16 +236,7 @@ if __name__ == "__main__":
433
  default=10,
434
  help="Number of warm-up steps to run before launching the timed runs.",
435
  )
436
- parser.add_argument(
437
- "--revision",
438
- type=str,
439
- default=None,
440
- help="Model revision to use (e.g. 'refs/pr/11' for a PR branch). Defaults to the main branch.",
441
- )
442
  args = parser.parse_args()
 
443
 
444
- print("*" * 100)
445
- print(f"Evaluating {args.model_id} on {args.dataset_path} / {args.dataset} / {args.split}")
446
- print("*" * 100)
447
-
448
- main(args)
 
1
+ """Evaluation script for Higgs Audio v3 models on ESB benchmark datasets.
2
+
3
+ No external dependencies beyond transformers + torch. The model bundles
4
+ its own audio preprocessing via trust_remote_code=True.
5
+
6
+ Usage:
7
+ python run_eval_higgs_audio.py \
8
+ --model_id bosonai/higgs-audio-v3-8b-stt \
9
+ --dataset_path hf-audio/esb-datasets-test-only-sorted \
10
+ --dataset ami --split test --device 0 --batch_size 4
11
+ """
12
+
13
  import argparse
14
  import os
15
+ import sys
16
+ import time
17
+ import runpy
18
+
19
  import torch
 
 
20
  import evaluate
21
  from normalizer import data_utils
22
+ from transformers import AutoModel, AutoTokenizer
23
  from tqdm import tqdm
 
 
24
 
25
  wer_metric = evaluate.load("wer")
 
26
 
27
 
28
+ def load_transcribe_fn(model_id):
29
+ """Load the bundled transcribe_batch function from the model repo.
 
30
 
31
+ Downloads all Python files needed by transcribe.py, then loads it via
32
+ runpy with the download directory on sys.path so plain (non-relative)
33
+ imports resolve to sibling files.
34
  """
35
+ from transformers.utils import cached_file
36
+
37
+ for filename in [
38
+ "transcribe.py",
39
+ "higgs_audio_collator.py",
40
+ "modeling_higgs_audio_xcodec.py",
41
+ "utils.py",
42
+ "common.py",
43
+ "configuration_higgs_audio.py",
44
+ ]:
45
+ cached_file(model_id, filename)
46
+
47
+ path = cached_file(model_id, "transcribe.py")
48
+ module_dir = os.path.dirname(path)
49
+
50
+ sys.path.insert(0, module_dir)
51
+ try:
52
+ module_globals = runpy.run_path(path)
53
+ finally:
54
+ sys.path.pop(0)
55
+
56
+ return module_globals["transcribe_batch"]
57
 
58
 
59
  def main(args):
60
+ device = f"cuda:{args.device}" if args.device >= 0 else "cpu"
61
 
62
+ model = AutoModel.from_pretrained(
63
+ args.model_id,
64
+ torch_dtype=torch.bfloat16,
65
+ trust_remote_code=True,
66
+ attn_implementation="eager",
67
+ device_map=device,
68
+ )
69
+ tokenizer = AutoTokenizer.from_pretrained(args.model_id, trust_remote_code=True)
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
70
  model.eval()
71
  print(f"Model size: {sum(p.numel() for p in model.parameters()) / 1e9:.2f}B parameters")
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
72
 
73
+ # Required for generation stop conditions
74
+ model.audio_out_bos_token_id = tokenizer.convert_tokens_to_ids("<|audio_out_bos|>")
75
+ model.audio_eos_token_id = tokenizer.convert_tokens_to_ids("<|audio_eos|>")
76
 
77
+ transcribe_batch = load_transcribe_fn(args.model_id)
78
+
79
+ def benchmark(batch):
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
80
  # Load audio inputs
81
  audios = [audio["array"] for audio in batch["audio"]]
82
+ batch["audio_length_s"] = [
83
+ len(audio) / batch["audio"][0]["sampling_rate"] for audio in audios
84
+ ]
85
  minibatch_size = len(audios)
 
 
 
 
 
 
 
86
 
87
  # START TIMING
88
+ start_time = time.time()
89
+
90
+ # INFERENCE
91
+ pred_text = transcribe_batch(
92
+ model, tokenizer, audios, sample_rates=16000,
93
+ max_new_tokens=args.max_new_tokens,
94
+ )
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
95
 
96
  # END TIMING
97
+ runtime = time.time() - start_time
 
 
98
 
99
  # normalize by minibatch size since we want the per-sample time
100
  batch["transcription_time_s"] = minibatch_size * [runtime / minibatch_size]
 
105
  return batch
106
 
107
  if args.warmup_steps is not None:
108
+ warmup_dataset = data_utils.load_data(args)
109
+ warmup_dataset = data_utils.prepare_data(warmup_dataset)
110
 
111
  num_warmup_samples = args.warmup_steps * args.batch_size
112
  if args.streaming:
113
+ warmup_dataset = warmup_dataset.take(num_warmup_samples)
114
  else:
115
+ warmup_dataset = warmup_dataset.select(
116
+ range(min(num_warmup_samples, len(warmup_dataset)))
117
+ )
118
+ warmup_dataset = iter(
119
+ warmup_dataset.map(benchmark, batch_size=args.batch_size, batched=True)
120
+ )
121
 
122
  for _ in tqdm(warmup_dataset, desc="Warming up..."):
123
  continue
124
 
125
  dataset = data_utils.load_data(args)
126
+ dataset = data_utils.prepare_data(dataset)
127
+
128
  if args.max_eval_samples is not None and args.max_eval_samples > 0:
129
  print(f"Subsampling dataset to first {args.max_eval_samples} samples!")
130
  if args.streaming:
131
  dataset = dataset.take(args.max_eval_samples)
132
  else:
133
+ dataset = dataset.select(
134
+ range(min(args.max_eval_samples, len(dataset)))
135
+ )
136
 
137
  dataset = dataset.map(
138
+ benchmark, batch_size=args.batch_size, batched=True,
139
+ remove_columns=["audio"],
140
  )
141
 
142
  all_results = {
 
144
  "transcription_time_s": [],
145
  "predictions": [],
146
  "references": [],
 
147
  }
148
  result_iter = iter(dataset)
149
  for result in tqdm(result_iter, desc="Samples..."):
 
151
  all_results[key].append(result[key])
152
 
153
  # Write manifest results (WER and RTFX)
 
154
  manifest_path = data_utils.write_manifest(
155
  all_results["references"],
156
  all_results["predictions"],
 
160
  args.split,
161
  audio_length=all_results["audio_length_s"],
162
  transcription_time=all_results["transcription_time_s"],
 
163
  )
164
  print("Results saved at path:", os.path.abspath(manifest_path))
165
 
 
167
  references=all_results["references"], predictions=all_results["predictions"]
168
  )
169
  wer = round(100 * wer, 2)
170
+ rtfx = round(
171
+ sum(all_results["audio_length_s"]) / sum(all_results["transcription_time_s"]), 2
172
+ )
173
  print("WER:", wer, "%", "RTFx:", rtfx)
174
 
175
 
 
180
  "--model_id",
181
  type=str,
182
  required=True,
183
+ help="Model identifier. Should be a HiggsAudio3 checkpoint on the HF Hub.",
184
  )
185
  parser.add_argument(
186
  "--dataset_path",
187
  type=str,
188
+ default="esb/datasets",
189
+ help="Dataset path. By default, it is `esb/datasets`.",
190
  )
191
  parser.add_argument(
192
  "--dataset",
193
  type=str,
194
  required=True,
195
+ help="Dataset name.",
 
196
  )
197
  parser.add_argument(
198
  "--split",
199
  type=str,
200
  default="test",
201
+ help="Split of the dataset.",
202
  )
203
  parser.add_argument(
204
  "--device",
 
209
  parser.add_argument(
210
  "--batch_size",
211
  type=int,
212
+ default=4,
213
  help="Number of samples to go through each streamed batch.",
214
  )
215
  parser.add_argument(
 
219
  help="Number of samples to be evaluated. Put a lower number e.g. 64 for testing this script.",
220
  )
221
  parser.add_argument(
222
+ "--no-streaming",
223
+ dest="streaming",
224
+ action="store_false",
225
+ help="Choose whether you'd like to download the entire dataset or stream it during the evaluation.",
226
  )
227
  parser.add_argument(
228
  "--max_new_tokens",
229
  type=int,
230
+ default=1024,
231
+ help="Maximum number of tokens to generate (includes the chain-of-thought block).",
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
232
  )
233
  parser.add_argument(
234
  "--warmup_steps",
 
236
  default=10,
237
  help="Number of warm-up steps to run before launching the timed runs.",
238
  )
 
 
 
 
 
 
239
  args = parser.parse_args()
240
+ parser.set_defaults(streaming=False)
241
 
242
+ main(args)