axinc-ai / ailia-models

The collection of pre-trained, state-of-the-art AI models for ailia SDK
2k stars 318 forks source link

Implement Kotoba-Whisper #1476

Closed ooe1123 closed 4 months ago

ooe1123 commented 4 months ago

https://github.com/axinc-ai/ailia-models/issues/1455 のPRです。

kyakuno commented 4 months ago

モデルアップロード済み。 https://storage.googleapis.com/ailia-models/kotoba-whisper/kotoba-whisper-v1.0_decoder.onnx

kyakuno commented 4 months ago

@ooe1123 現在は、longformの場合、音声全部をencodeしてから、チャンク全部をdecode、最後に重複削除してテキスト変換しているかと思います。

これを、通常のwhisperと同様に、音声をチャンク分割し、チャンク単位でencode/decodeし、途中結果をテキスト表示は可能でしょうか?

decode後の重複削除が前チャンクしか見ない場合は、1チャンク遅延をしてもよいかなと思います。重複削除が後チャンクを見る場合は、途中結果をprintしつつ、最後に綺麗なテキストをまとめてprintでも大丈夫です。

ooe1123 commented 4 months ago

@kyakuno

音声をチャンク分割し、チャンク単位でencode/decode

これを行っているのが、chunk_lengthパラメータかと思いますが、 最後にまとめてdecodeを行っているところを、逐次decodeするようにすればよさそうでしょうか?

decode後の重複削除が前チャンクしか見ない場合は、1チャンク遅延をしてもよいかなと思います。重複削除が後チャンクを見る場合は、途中結果をprintしつつ、最後に綺麗なテキストをまとめてprintでも大丈夫です。

longformの実装はtransformersを元にしており、詳細なアルゴリズムについては理解できていないため、独自に機能を追加するのは残念ながら私には難しそうです。 ちょっとできるか分かりませんが、transformersではなく、whisperを参考にして実装を考えてみた方がよいでしょうか?

kyakuno commented 4 months ago

検討、ありがとうございます。

 1. preprocess -> chunk_iter -> feature_extractor (全音声が処理されるまでロックされる)  2. generate -> chunk_iter -> forward -> greedy_search -> decode  3. tokenizer._decode_asr というフローを、feature_extractorはチャンク独立であるため、  1. generate -> chunk_iter -> feature_extractor(チャンク単位で処理) -> forward -> greedy_search -> decode -> tokenizer._decode_asr(プレビュー)  2. tokenizer._decode_asr(重複削除後) として、通常のwhisperのように逐次出力できないかなと考えています。

通常のwhisperのコードベースではなく、現在のtarnsformerベースの方が良いと思います。

ooe1123 commented 4 months ago

@kyakuno feature_extractor の使い方辺りについてみてました。

chunk_lengthオプションでは、audioをチャンク分割して(オーバーラップ部分あり)からfeature_extractorを行っていて、 longformの場合はaudio全体をfeature_extractorしてから、その後にfeatureに対して分割を行っている違いがあるかと思います。

feature_extractor処理前に分割を行う場合、チャンクサイズやオーバーラップのサイズについてどうするべきか、分からない不安要素があるように思います。

ご要望の、

feature_extractorはチャンク独立であるため、  1. generate -> chunk_iter -> feature_extractor(チャンク単位で処理) -> forward -> greedy_search -> decode -> tokenizer._decode_asr(プレビュー)  2. tokenizer._decode_asr(重複削除後)

この実装をのせる場合、longformの実装ベースというよりは、chunk_lengthオプションでの実装を拡張する形でよいのではないかと思いましたが、認識にズレはありますでしょうか?

kyakuno commented 4 months ago

feature_extractorにつきまして、実体的には、STFTを行なっているようなので、HOP_LENGTH単位で呼び出しを行えば、分割実行を行なっても出力は一致しそうな印象でした。 ただ、計測してみると、feature_extractorではほとんど時間を使っていなかったので、ここは並列化しなくても大丈夫そうです。

そのため、generate関数に、

print(models["tokenizer"].decode(sliced_tokens))
print(models["tokenizer"].decode(seek_sequence))

を入れれば、

<|0.00|>自動運転の未来を加速させる<|3.82|>
<|3.82|>アクセルの取り組み<|7.00|>
<|7.00|>AIをより早く<|8.80|>
<|8.80|>やすくすぐに始められる<|11.48|>
<|11.48|>豊かな未来を想像する企業の良き理解者になる<|16.32|>
<|16.32|>AI実装に必要な学習から推論までトータルソリューションを提供できる<|19.22|>

のように逐次、表示されたので、これで十分そうです。

kyakuno commented 4 months ago

M2 MacのBLASで88secの音声を変換するのに必要な時間。

model sec msec/token
whisper medium 119sec 135msec
whisper large 350sec 252msec
kotoba whisper large (opset 14) 267sec 268msec
kotoba whisper large (opset 17) 211sec 210msec
kyakuno commented 4 months ago

@ooe1123 opset=17でLayerNormalizationが導入されていまして、Transformer系はopset=17で動作させた方が高速になっています。 そこで、大変お手数なのですが、opset=17で再エクスポートいただくことは可能でしょうか? 今後のモデルエクスポートでは、標準的にopset=17をご利用いただいて問題ありません。 下記のidiomが、LayerNormに置き換わるかと思います。

スクリーンショット 2024-05-26 21 56 01

ooe1123 commented 4 months ago

@kyakuno

opset=17で再エクスポートいただくことは可能でしょうか?

承知致しました。 次回作業時に対応いたします。

kyakuno commented 4 months ago

すみません、よろしくお願いします🙇

kyakuno commented 4 months ago

267sec -> 211secに改善しました。

kyakuno commented 4 months ago

opset17

こんにちは先生最近手足の経練があり動機も感じますこんにちは手足の経連と動機がある場合心臓の問題がある可能性があります一度心臓の検査を受ける必要があります肝の検査を受ける必要があります。心臓の検査を受ける必要があります。心臓の検査を受る必要があります。心臓の検査を受�������診臓臓臓臓はある必要がある必要がある必要がある必要があるんです心臓臓臓はあるんです心臓はあるんです心臓はあるんです心臓はあるんです心臓はあるんです心臓はあるんです心臓はあるんです心臓はあるんです心臓はあるんです心臓のです心臓はあるんです心臓はあるんです心臓はあるんですか?心臓のです心臓はあるんですか?まずは心臓の電気活動を測定するために心電図を撮影します。また動脈硬化の状態を調べるためにエコーコー検査やMRIを行うことがあります。そうですか分かりました。そうですか分かりました。心臓病が疑われる場合は心臓専門医に紹介することがあります。ありがとうございますありがとうございます。ありがとうございます先生先生。

opset11

こんにちは先生最近手足の経練があり動機も感じますこんにちは手足の経連と動機がある場合心臓の問題がある可能性があります一度心臓の検査を受ける必要があります肝の検査を受ける必要があります。心臓の検査を受ける必要があります。心臓の検査を受る必要があります。心臓の検査を受�������診臓臓臓臓はある必要がある必要がある必要がある必要があるんです心臓臓臓はあるんです心臓はあるんです心臓はあるんです心臓はあるんです心臓はあるんです心臓はあるんです心臓はあるんです心臓はあるんです心臓はあるんです心臓のです心臓はあるんです心臓はあるんです心臓はあるんですか?心臓のです心臓はあるんですか?まずは心臓の電気活動を測定するために心電図を撮影します。また動脈硬化の状態を調べるためにエコーコー検査やMRIを行うことがあります。そうですか分かりました。そうですか分かりました。心臓病が疑われる場合は心臓専門医に紹介することがあります。ありがとうございますありがとうございます。ありがとうございます先生先生。