自作データセットでWhisperをファインチューニングする際の学習時にエラーがでる件について

実現したいこと

エラーを解消したい。原因を突き止めたい

発生している問題・分からないこと

whisperのファインチューニングを行う際にエラーが発生しました。

エラーメッセージ

error

1IndexError: Invalid key: 12 is out of bounds for size 0

該当のソースコード

独自のデータセットを学習する際にエラーが出ます。 df_fineには、df.shape → (20,2) 正解データ列と、音声ファイルパス列で、20個のデータがあります。 # HugginFaceのAudioオブジェクト作成 # トレーニング用と検証用を7対3 msk = np.random.rand(len(df_fine)) < 0.7 train_dataset = Dataset.from_pandas(df_fine[msk]).cast_column("fine_tuning_path", Audio(sampling_rate=16000)).rename_column("fine_tuning_path", "audio") validate_dataset = Dataset.from_pandas(df_fine[~msk]).cast_column("fine_tuning_path", Audio(sampling_rate=16000)).rename_column("fine_tuning_path", "audio") datasets = DatasetDict({ "train": train_dataset, "validate": validate_dataset }) datasetsには以下のものが入っています。 DatasetDict({ train: Dataset({ features: ['correct', 'audio', 'index_level_0'], num_rows: 16 }) validate: Dataset({ features: ['correct', 'audio', 'index_level_0'], num_rows: 4 }) }) # whisperのtorknizeや音響特徴量抽出を行うprocessorのHuggingFaceバージョンを定義 from transformers import WhisperProcessor processor = WhisperProcessor.from_pretrained("openai/whisper-large", language="Japanese", task="transcribe") def prepare_dataset(batch): # トークナイザーを使用して入力をエンコード inputs = processor.tokenizer(batch['correct'], padding="max_length", truncation=True, max_length=128, return_tensors="pt") # 音声データの処理(例えば、特徴量抽出など) # audio_features = processor.feature_extractor(batch["audio"], sampling_rate=16000) # データセットに期待されるキーを追加 batch.update({ 'input_ids': inputs.input_ids, 'attention_mask': inputs.attention_mask, # 'labels': ここでラベルを適切に設定 }) return batch # datasetsに対して上記の関数を適用し、特定の列を削除('correct', 'audio', '__index_level_0__')して、前処理された新しいデータセットを作成 prepared_datasets = datasets.map(prepare_dataset, remove_columns=datasets.column_names["train"], num_proc=1) prepared_datasetsには以下のものが入っています。 DatasetDict({ train: Dataset({ features: ['input_ids', 'attention_mask'], num_rows: 16 }) validate: Dataset({ features: ['input_ids', 'attention_mask'], num_rows: 4 }) }) import torch from dataclasses import dataclass from typing import Any, Dict, List, Union # 音声認識や音声からテキストへの自動変換タスクにおいて、モデルが効率的に学習できるようにデータを整形・準備するためのクラス @dataclass class DataCollatorSpeechSeq2SeqWithPadding: processor: Any def __call__(self, features: List[Dict[str, Union[List[int] , torch.Tensor]]]) -> Dict[str, torch.Tensor]: # 音響特徴量側をまとめる処理 # (一応バッチ単位でパディングしているが、すべて30秒分であるはず) input_features \ = [{"input_features": feature["input_features"]} for feature in features] batch = self.processor.feature_extractor.pad(input_features, return_tensors="pt") # トークン化された系列をバッチ単位でパディング label_features = [{"input_ids": feature["labels"]} for feature in features] labels_batch = self.processor.tokenizer.pad(label_features, return_tensors="pt") # attention_maskが0の部分は、トークンを-100に置き換えてロス計算時に無視させる # -100を無視するのは、PyTorchの仕様 labels \ = labels_batch["input_ids"].masked_fill(labels_batch.attention_mask.ne(1), -100) # BOSトークンがある場合は削除 if (labels[:, 0] == self.processor.tokenizer.bos_token_id).all().cpu().item(): labels = labels[:, 1:] # 整形したlabelsをバッチにまとめる batch["labels"] = labels return batch data_collator = DataCollatorSpeechSeq2SeqWithPadding(processor=processor) # エラーが出たら、上記のコードを実行してランタイム再起動 from transformers import Seq2SeqTrainingArguments training_args = Seq2SeqTrainingArguments( output_dir="../", # モデルのチェックポイントや訓練のログを保存するディレクトリのパス。実際のプロジェクトや実験に応じて、適切なディレクトリを指定 per_device_train_batch_size=1, # 訓練時のバッチサイズ。大きなバッチサイズは、一般に訓練の安定性を向上させるが、メモリ要求も増加 gradient_accumulation_steps=2, # 勾配を累積するステップ数 learning_rate=1e-5, # 学習 warmup_steps=500, # 学習率のウォームアップに使用するステップ数 # warmup_steps=5, max_steps=40, # 訓練を停止する最大ステップ数。これに到達すると訓練が終了 # max_steps=4000, # gradient_checkpointing=True, fp16=True, # メモリ使用量が減り、訓練速度が向上する可能性がありますが、精度に影響を与える場合 group_by_length=True, # 同じ長さのサンプルをグループ化して、パディングを最小限に抑え、訓練効率を向上 evaluation_strategy="steps", # 評価戦略。"steps"を指定すると、特定のステップ数ごとに評価が行われます。 per_device_eval_batch_size=1, # 評価時のバッチサイズ predict_with_generate=True, # 生成タスク(例えば、テキスト生成)で予測を行う際に、モデルのgenerateメソッドを使用するか generation_max_length=225, # save_steps=1000, save_steps=10, # eval_steps=1000, eval_steps=10, logging_steps=25, report_to=["tensorboard"], load_best_model_at_end=True, metric_for_best_model="wer", greater_is_better=False, push_to_hub=False, ) trainer = Seq2SeqTrainer( args=training_args, # 訓練の引数。Seq2SeqTrainingArgumentsオブジェクトを指定して、訓練の様々な設定(バッチサイズ、学習率、評価戦略など)を定義 model=model, train_dataset=prepared_datasets["train"], # 訓練データセット。前処理された訓練データセット eval_dataset=prepared_datasets["validate"], # 評価データセット。前処理された検証データセット data_collator=data_collator, # バッチ処理をカスタマイズするために使用 compute_metrics=compute_metrics, # WERを計算するカスタム設定 tokenizer=processor.tokenizer ) trainer.train()

試したこと・調べたこと

上記の詳細・結果

該当ソースコードにまとめました。

補足

特になし

コメントを投稿

0 コメント