sungo-ganpare commited on
Commit
a7307d4
·
1 Parent(s): d1aa8f4

GPU制限エラーを検知する例外クラスを追加し、処理中にGPU制限に達した場合のエラーハンドリングを強化。音声ファイル処理時にエラーを適切に報告するように修正。

Browse files
Files changed (2) hide show
  1. local_controller.py +50 -17
  2. transcribe_cli.py +1 -1
local_controller.py CHANGED
@@ -1,6 +1,7 @@
1
  import os
2
  import json
3
  import time
 
4
  import requests
5
  from pathlib import Path
6
  # from pydub import AudioSegment # 現在のコードでは直接使用されていません
@@ -109,6 +110,10 @@ def split_audio_with_ffmpeg(audio_path: str, output_dir_base: str, chunk_length_
109
 
110
  # test_space_connection, process_chunk, write_srt, write_vtt, write_json_output, write_lrc は前回とほぼ同じ
111
  # (ログ出力にファイル名を追加するなどの微調整は有効)
 
 
 
 
112
  def process_chunk(chunk_path: str, original_audio_filename: str) -> Optional[Dict]:
113
  """チャンクをSpaceに送信して処理"""
114
  chunk_name = Path(chunk_path).name
@@ -123,12 +128,16 @@ def process_chunk(chunk_path: str, original_audio_filename: str) -> Optional[Dic
123
  client = Client(SPACE_URL)
124
  break
125
  except Exception as e:
 
 
 
 
 
126
  print(f" Connection attempt {attempt + 1} for {chunk_name} (from {original_audio_filename}) failed: {e}")
127
  if attempt < 2: time.sleep(5)
128
  else: raise
129
  if client is None: return None
130
-
131
- # print(f" Sending chunk to Space: {chunk_name} (from {original_audio_filename})")
132
  result = None
133
  api_methods_to_try = [{"name": "fn_index=1", "fn_index": 1}, {"name": "fn_index=0", "fn_index": 0}, {"name": "default", "fn_index": None}]
134
  for method_info in api_methods_to_try:
@@ -139,16 +148,21 @@ def process_chunk(chunk_path: str, original_audio_filename: str) -> Optional[Dic
139
  result = client.predict(gradio_file(chunk_path))
140
  # print(f" Successfully used API method '{method_info['name']}' for {chunk_name}")
141
  break
142
- except Exception: # as e:
143
- # print(f" API method '{method_info['name']}' for {chunk_name} failed: {e}")
 
 
 
 
 
144
  result = None
145
 
146
  if result is None:
147
  print(f" All API call methods failed for {chunk_name} (from {original_audio_filename})")
148
  return None
149
-
150
- # print(f" Received response from Space for {chunk_name} (type: {type(result)})")
151
- if isinstance(result, dict): return result
152
  elif isinstance(result, str):
153
  try: return json.loads(result)
154
  except json.JSONDecodeError:
@@ -157,7 +171,15 @@ def process_chunk(chunk_path: str, original_audio_filename: str) -> Optional[Dic
157
  else:
158
  print(f" Unexpected response format for {chunk_name}: {type(result)}")
159
  return None
 
 
 
160
  except Exception as e:
 
 
 
 
 
161
  print(f"Error sending chunk {chunk_name} (from {original_audio_filename}) to Space: {e}")
162
  return None
163
 
@@ -445,8 +467,7 @@ def process_audio_file(input_path_str: str, output_dir_str: str):
445
  temp_conversion_dir = base_temp_dir / "conversion"
446
  # チャンクは split_audio_with_ffmpeg 内で output_dir_path / "temp_chunks" / audio_stem に保存される
447
 
448
- try:
449
- # WAV以外の入力はWAV (16kHz, mono) に変換
450
  if original_input_path_obj.suffix.lower() not in ['.wav']:
451
  print(f" Converting {audio_filename} to WAV...")
452
  temp_conversion_dir.mkdir(parents=True, exist_ok=True)
@@ -489,12 +510,18 @@ def process_audio_file(input_path_str: str, output_dir_str: str):
489
  print(f" Processing {len(chunk_paths)} chunks for {audio_filename} via API...")
490
  chunk_results = []
491
  for i, chunk_p_str in enumerate(chunk_paths):
492
- api_result = process_chunk(chunk_p_str, audio_filename)
493
- if api_result:
494
- chunk_results.append(api_result)
495
- print(f" Successfully processed chunk {i+1}/{len(chunk_paths)}")
496
- else:
497
- print(f" Failed to process chunk {i+1}/{len(chunk_paths)}")
 
 
 
 
 
 
498
 
499
  # APIリクエスト間の待機時間を追加
500
  if i < len(chunk_paths) - 1: # 最後のチャンクの後は待機不要
@@ -639,8 +666,14 @@ def main():
639
  for i, file_to_process_obj in enumerate(actual_files_to_process):
640
  print(f"\n--- [{i+1}/{total_to_process_count}] Processing: {file_to_process_obj.name} ---")
641
  output_dir_for_this_file = file_to_process_obj.parent.as_posix()
642
- process_audio_file(file_to_process_obj.as_posix(), output_dir_for_this_file)
643
- print(f"--- Finished: {file_to_process_obj.name} ---")
 
 
 
 
 
 
644
 
645
  print(f"\nAll {total_to_process_count} new file(s) processed.")
646
 
 
1
  import os
2
  import json
3
  import time
4
+ import sys
5
  import requests
6
  from pathlib import Path
7
  # from pydub import AudioSegment # 現在のコードでは直接使用されていません
 
110
 
111
  # test_space_connection, process_chunk, write_srt, write_vtt, write_json_output, write_lrc は前回とほぼ同じ
112
  # (ログ出力にファイル名を追加するなどの微調整は有効)
113
+ class GPUQuotaExceededError(Exception):
114
+ """GPU制限に達した場合の例外"""
115
+ pass
116
+
117
  def process_chunk(chunk_path: str, original_audio_filename: str) -> Optional[Dict]:
118
  """チャンクをSpaceに送信して処理"""
119
  chunk_name = Path(chunk_path).name
 
128
  client = Client(SPACE_URL)
129
  break
130
  except Exception as e:
131
+ error_msg = str(e).lower()
132
+ # GPU制限エラーを検知
133
+ if any(keyword in error_msg for keyword in ['gpu', 'quota', 'limit', 'exceeded', 'unavailable']):
134
+ print(f" GPU quota exceeded detected: {e}")
135
+ raise GPUQuotaExceededError(f"GPU quota exceeded: {e}")
136
  print(f" Connection attempt {attempt + 1} for {chunk_name} (from {original_audio_filename}) failed: {e}")
137
  if attempt < 2: time.sleep(5)
138
  else: raise
139
  if client is None: return None
140
+ # print(f" Sending chunk to Space: {chunk_name} (from {original_audio_filename})")
 
141
  result = None
142
  api_methods_to_try = [{"name": "fn_index=1", "fn_index": 1}, {"name": "fn_index=0", "fn_index": 0}, {"name": "default", "fn_index": None}]
143
  for method_info in api_methods_to_try:
 
148
  result = client.predict(gradio_file(chunk_path))
149
  # print(f" Successfully used API method '{method_info['name']}' for {chunk_name}")
150
  break
151
+ except Exception as api_e:
152
+ error_msg = str(api_e).lower()
153
+ # GPU制限エラーを検知
154
+ if any(keyword in error_msg for keyword in ['gpu', 'quota', 'limit', 'exceeded', 'unavailable', 'out of memory', 'resource']):
155
+ print(f" GPU quota exceeded during API call: {api_e}")
156
+ raise GPUQuotaExceededError(f"GPU quota exceeded during API call: {api_e}")
157
+ # print(f" API method '{method_info['name']}' for {chunk_name} failed: {api_e}")
158
  result = None
159
 
160
  if result is None:
161
  print(f" All API call methods failed for {chunk_name} (from {original_audio_filename})")
162
  return None
163
+ # print(f" Received response from Space for {chunk_name} (type: {type(result)})")
164
+ if isinstance(result, dict):
165
+ return result
166
  elif isinstance(result, str):
167
  try: return json.loads(result)
168
  except json.JSONDecodeError:
 
171
  else:
172
  print(f" Unexpected response format for {chunk_name}: {type(result)}")
173
  return None
174
+ except GPUQuotaExceededError:
175
+ # GPU制限エラーは再発生させて上位で処理
176
+ raise
177
  except Exception as e:
178
+ error_msg = str(e).lower()
179
+ # 最後の砦としてもう一度GPU制限エラーをチェック
180
+ if any(keyword in error_msg for keyword in ['gpu', 'quota', 'limit', 'exceeded', 'unavailable', 'out of memory', 'resource']):
181
+ print(f"GPU quota exceeded detected in general exception: {e}")
182
+ raise GPUQuotaExceededError(f"GPU quota exceeded: {e}")
183
  print(f"Error sending chunk {chunk_name} (from {original_audio_filename}) to Space: {e}")
184
  return None
185
 
 
467
  temp_conversion_dir = base_temp_dir / "conversion"
468
  # チャンクは split_audio_with_ffmpeg 内で output_dir_path / "temp_chunks" / audio_stem に保存される
469
 
470
+ try: # WAV以外の入力はWAV (16kHz, mono) に変換
 
471
  if original_input_path_obj.suffix.lower() not in ['.wav']:
472
  print(f" Converting {audio_filename} to WAV...")
473
  temp_conversion_dir.mkdir(parents=True, exist_ok=True)
 
510
  print(f" Processing {len(chunk_paths)} chunks for {audio_filename} via API...")
511
  chunk_results = []
512
  for i, chunk_p_str in enumerate(chunk_paths):
513
+ try:
514
+ api_result = process_chunk(chunk_p_str, audio_filename)
515
+ if api_result:
516
+ chunk_results.append(api_result)
517
+ print(f" Successfully processed chunk {i+1}/{len(chunk_paths)}")
518
+ else:
519
+ print(f" Failed to process chunk {i+1}/{len(chunk_paths)}")
520
+ except GPUQuotaExceededError as gpu_error:
521
+ print(f" GPU quota exceeded while processing {audio_filename}")
522
+ print(f" Error: {gpu_error}")
523
+ print(f" GPU制限に達しました。処理を強制終了します。")
524
+ raise # main()関数で捕捉するために再発生
525
 
526
  # APIリクエスト間の待機時間を追加
527
  if i < len(chunk_paths) - 1: # 最後のチャンクの後は待機不要
 
666
  for i, file_to_process_obj in enumerate(actual_files_to_process):
667
  print(f"\n--- [{i+1}/{total_to_process_count}] Processing: {file_to_process_obj.name} ---")
668
  output_dir_for_this_file = file_to_process_obj.parent.as_posix()
669
+ try:
670
+ process_audio_file(file_to_process_obj.as_posix(), output_dir_for_this_file)
671
+ print(f"--- Finished: {file_to_process_obj.name} ---")
672
+ except GPUQuotaExceededError as gpu_error:
673
+ print(f"\n=== GPU QUOTA EXCEEDED ===")
674
+ print(f"処理を中断します。GPU制限に達しました。")
675
+ print(f"Error details: {gpu_error}")
676
+ sys.exit(1) # 即座に強制終了
677
 
678
  print(f"\nAll {total_to_process_count} new file(s) processed.")
679
 
transcribe_cli.py CHANGED
@@ -987,7 +987,7 @@ if __name__ == "__main__":
987
  # ダイアログを最前面に表示する試み (環境による)
988
  root.attributes('-topmost', True)
989
  # WSL環境での初期ディレクトリを設定
990
- initial_dir = "/mnt/f/demucs_folder/htdemucs" # Windowsのユーザーディレクトリを初期値として設定
991
  selected_path = filedialog.askdirectory(
992
  title="処理対象のディレクトリを選択してください",
993
  initialdir=initial_dir
 
987
  # ダイアログを最前面に表示する試み (環境による)
988
  root.attributes('-topmost', True)
989
  # WSL環境での初期ディレクトリを設定
990
+ initial_dir = "/mnt/t/demucs_folder/htdemucs" # Windowsのユーザーディレクトリを初期値として設定
991
  selected_path = filedialog.askdirectory(
992
  title="処理対象のディレクトリを選択してください",
993
  initialdir=initial_dir