diff options
| author | vin <git@vineetk.net> | 2025-08-23 02:26:35 -0400 |
|---|---|---|
| committer | vin <git@vineetk.net> | 2025-08-23 10:58:58 -0400 |
| commit | d49d20dd810ed2dbcef6c926921b072713366654 (patch) | |
| tree | 092cd4e3cb5a5a6698f68fa97b015336ef8b9aad | |
| parent | 78decc2ddd05519780153a8d09f68884e8d11fc6 (diff) | |
adapt asr.py for multiple file inputs
| -rw-r--r-- | asr.py | 62 |
1 files changed, 30 insertions, 32 deletions
| @@ -6,6 +6,23 @@ import json | |||
| 6 | import numpy as np | 6 | import numpy as np |
| 7 | from tqdm import tqdm | 7 | from tqdm import tqdm |
| 8 | 8 | ||
| 9 | print("Loading ASR model...") | ||
| 10 | providers = [ | ||
| 11 | "ROCMExecutionProvider", | ||
| 12 | "CPUExecutionProvider", | ||
| 13 | ] | ||
| 14 | try: | ||
| 15 | model = onnx_asr.load_model( | ||
| 16 | "nemo-parakeet-tdt-0.6b-v3", | ||
| 17 | providers=providers, | ||
| 18 | ).with_timestamps() | ||
| 19 | except Exception as e: | ||
| 20 | print(f"Failed to load the ASR model. Ensure ONNX Runtime for ROCm is installed correctly. Error: {e}") | ||
| 21 | sys.exit(1) | ||
| 22 | |||
| 23 | chunk_duration_seconds = 20 | ||
| 24 | sample_rate = 16000 | ||
| 25 | |||
| 9 | # converts TimestampedResult to JSON-serializable dictionary | 26 | # converts TimestampedResult to JSON-serializable dictionary |
| 10 | def result_to_dict(result, offset_seconds): | 27 | def result_to_dict(result, offset_seconds): |
| 11 | token_map = [ | 28 | token_map = [ |
| @@ -24,37 +41,18 @@ def result_to_dict(result, offset_seconds): | |||
| 24 | } | 41 | } |
| 25 | 42 | ||
| 26 | def main(input_file, output_file): | 43 | def main(input_file, output_file): |
| 27 | print("Loading ASR model...") | ||
| 28 | providers = [ | ||
| 29 | "ROCMExecutionProvider", | ||
| 30 | "CPUExecutionProvider", | ||
| 31 | ] | ||
| 32 | try: | ||
| 33 | model = onnx_asr.load_model( | ||
| 34 | "nemo-parakeet-tdt-0.6b-v3", | ||
| 35 | providers=providers, | ||
| 36 | ).with_timestamps() | ||
| 37 | except Exception as e: | ||
| 38 | print(f"Failed to load the ASR model. Ensure ONNX Runtime for ROCm is installed correctly. Error: {e}") | ||
| 39 | sys.exit(1) | ||
| 40 | |||
| 41 | chunk_duration_seconds = 20 | ||
| 42 | sample_rate = 16000 | ||
| 43 | |||
| 44 | print(f"Loading and resampling {input_file}...") | ||
| 45 | try: | 44 | try: |
| 46 | audio, sr = librosa.load(input_file, sr=sample_rate, mono=True) | 45 | audio, sr = librosa.load(input_file, sr=sample_rate, mono=True) |
| 47 | except Exception as e: | 46 | except Exception as e: |
| 48 | print(f"Error loading audio file: {e}") | 47 | tqdm.write(f"Error loading audio file: {e}") |
| 49 | sys.exit(1) | 48 | sys.exit(1) |
| 50 | 49 | ||
| 51 | chunk_size_samples = int(chunk_duration_seconds * sample_rate) | 50 | chunk_size_samples = int(chunk_duration_seconds * sample_rate) |
| 52 | full_transcript_data = [] | 51 | full_transcript_data = [] |
| 53 | 52 | ||
| 54 | print("Starting transcription process in chunks...") | ||
| 55 | num_chunks = (len(audio) + chunk_size_samples - 1) // chunk_size_samples | 53 | num_chunks = (len(audio) + chunk_size_samples - 1) // chunk_size_samples |
| 56 | 54 | ||
| 57 | for i in tqdm(range(num_chunks), desc="Transcribing"): | 55 | for i in tqdm(range(num_chunks), desc="Transcribing", position=1, leave=False): |
| 58 | start_sample = i * chunk_size_samples | 56 | start_sample = i * chunk_size_samples |
| 59 | end_sample = start_sample + chunk_size_samples | 57 | end_sample = start_sample + chunk_size_samples |
| 60 | chunk = audio[start_sample:end_sample] | 58 | chunk = audio[start_sample:end_sample] |
| @@ -73,21 +71,21 @@ def main(input_file, output_file): | |||
| 73 | for result in results_list: | 71 | for result in results_list: |
| 74 | full_transcript_data.append(result_to_dict(result, chunk_offset_seconds)) | 72 | full_transcript_data.append(result_to_dict(result, chunk_offset_seconds)) |
| 75 | except Exception as e: | 73 | except Exception as e: |
| 76 | print(f" Error processing chunk {i + 1}: {e}") | 74 | tqdm.write(f" Error processing chunk {i + 1}: {e}") |
| 77 | 75 | ||
| 78 | print(f"\nTranscription complete. Saving results to {output_file}...") | ||
| 79 | with open(output_file, "w") as f: | 76 | with open(output_file, "w") as f: |
| 80 | json.dump(full_transcript_data, f, indent=2) | 77 | json.dump(full_transcript_data, f, indent=2) |
| 81 | 78 | ||
| 82 | print("Done.") | ||
| 83 | # os._exit(0) workaround for ONNX Runtime bug | ||
| 84 | os._exit(0) | ||
| 85 | |||
| 86 | if __name__ == "__main__": | 79 | if __name__ == "__main__": |
| 87 | if len(sys.argv) < 3: | 80 | if len(sys.argv) < 2: |
| 88 | print("Usage: python asr.py <input_audio_file> <output_json_file>") | 81 | print("Usage: python asr.py input_audio_file1 [input_audio_file2 [input_audio_file3 [...]]]") |
| 89 | sys.exit(1) | 82 | sys.exit(1) |
| 90 | 83 | ||
| 91 | input_path = sys.argv[1] | 84 | all_inputs = sys.argv[1:] |
| 92 | output_path = sys.argv[2] | 85 | inputs = [f for f in all_inputs if not os.path.exists(os.path.splitext(f)[0] + ".json")] |
| 93 | main(input_path, output_path) | 86 | |
| 87 | for i in tqdm(inputs, desc="Processing files", position=0): | ||
| 88 | main(i, os.path.splitext(i)[0] + ".json") | ||
| 89 | |||
| 90 | # os._exit(0) workaround for ONNX Runtime bug | ||
| 91 | os._exit(0) | ||
