Closed shibukazu closed 1 year ago
通知の多言語対応のために一旦WIPに戻します
これって今DispatchQueueに4個タスクがあったとして、バックグラウンドにした瞬間にその1つ目のタスクが実行されてたとしたら、それを止めるのはむりそうだけど、2つ目以降のタスク(のこり3つのタスク)は https://developer.apple.com/documentation/dispatch/dispatchobject/1452801-suspend これで実行とめたら、裏でリソース使わんくなってキルされないことないかな? 1つのタスクの完了だけなら30sとかでなんとか終わりそうだし(モデルによるけど)
DispatchQueueに入っているジョブに対してsuspendはめっちゃよさそうです。 ただ、「30s間はバックグラウンドで実行できるということ自体が保証されていない」ことおよび「デバイスによってはsmallモデルですら30sで終了するか不明である」ことからBackgroundTaskCompletionおよび通知は必要だと思います。
@shibukazu あ、もちろん、通知とかあった上でっていう意味やった! するとしてもまた別のプルリクでする?
なるほどです。 修正範囲が大きくなりそうなので別のPRで取り組みたいです!!
@shibukazu このコミットでggml-small.en.binがおそらくshibukazuのローカル環境の何処かを指すようになっててしまってて、こっちでビルドできないから直してもらえるとたすかる!
バックグラウンドに入って2、3秒経過してすぐにキルされたってことですか? 通知は出ましたか?
@shibukazu 通知はちゃんとでるんだけど、でた直後くらい
Message from debugger: Terminated due to signal 9
というメッセージとともにキルされる!
これが意図されたもの何かわからんから、質問をなげてみたけど、答えがつくかはわからん笑
ちなみに実機ですかね? 正直CPUとかメモリ使用率とかで強制キルはあり得そうですね
@shibukazu 実機です!
あとcancelに関しては
Cancellation causes future attempts to execute the work item to return immediately. Cancellation does not affect the execution of a work item that has already begun.
これを見た感じ始まってしまった認識タスクには影響できないっぽい..?
30sという秒数が保証されていないとすると通知の文言を修正したいです。 今日はもう寝るので、時間があるようでしたら他のPRのチェックをお願いします🤲
@shibukazu 確かに始まったタスクはもう無理なのか.... ならもうキルを防止する方法はないのか.... 賞味、結構バックグラウンドで録音できないの痛いし、なんとかしたみはあるけどなあ
本気でやろうと思えば、whisper_cppのwhisper_free
メソッドは呼べばやろうと思えばできそうかも。
https://github.com/ggerganov/whisper.cpp/blob/d7c936b44a80b8070676093fc00622333ba09cd3/whisper.cpp#L2840
モデル動いている途中にこれ読んだらどうなるかはわからんけど笑
本気でやろうと思えば、whisper_cppの
whisper_free
メソッドは呼べばやろうと思えばできそうかも。 https://github.com/ggerganov/whisper.cpp/blob/d7c936b44a80b8070676093fc00622333ba09cd3/whisper.cpp#L2840モデル動いている途中にこれ読んだらどうなるかはわからんけど笑
キルすることはできるかもしれませんが、キルされたジョブを復元してDispatchQueueの先頭に入れ直すのが難しいと思います。
一応このPRにおける残りのタスクとしては
上記達成され次第マージでよろしいでしょうか?
各タスクをDispatchWorkItemとしてラップして、このDispatchWorkItemを他のリストとかに別に保持しとけば、あとでフォアグラウンドに戻ったときにDispatchQueueに入れ直せるくない?リストからは本当に認識タスクが終わったタイミングで削除する的な。
というかまあDispatchWorkItem使わんでも必要な情報だけ適当なstruct二保存するだけでいい気もするけど
一応このPRにおける残りのタスクとしては UIApplication.shared.endBackgroundTask(identifier)をexprirationHandlerでも呼び出す 通知の文言の修正 上記達成され次第マージでよろしいでしょうか?
OK 👍
各タスクをDispatchWorkItemとしてラップして、このDispatchWorkItemを他のリストとかに別に保持しとけば、あとでフォアグラウンドに戻ったときにDispatchQueueに入れ直せるくない?リストからは本当に認識タスクが終わったタイミングで削除する的な。
というかまあDispatchWorkItem使わんでも必要な情報だけ適当なstruct二保存するだけでいい気もするけど
なるほど、いまのclosureを配列として保持しておいて、キャンセルされた場合はQueueを再構成してあげるのが良さそうですね。(既存のQueueの任意の位置に入れるのは無理そう) ただ現状のストリーミング認識の方法だと各セグメントが認識されるごとにRecognizedSpeechにTranscriptionLineを追加してしまっているので、途中でジョブがキャンセルされた場合に中途半端な認識結果を取り除いてあげるなどの後処理が必要そうですね なので、理想としては認識ジョブをクロージャ内で閉じさせるか、DBにおけるトランザクションのような感じでロールバックできる形で実装できるといいですね。
@shibukazu そうそう、Queueの再編というのを書き忘れたけど、それを意図してた。closureを配列としてもつでもいいし、自分はstreamingRecognition関数の引数の値たちを保持しとけば、あとで同じクロージャーは再現できるかなと思ってた。
ただ現状のストリーミング認識の方法だと各セグメントが認識されるごとにRecognizedSpeechにTranscriptionLineを追加してしまっているので、途中でジョブがキャンセルされた場合に中途半端な認識結果を取り除いてあげるなどの後処理が必要そうですね
確かにこの問題があるのか... まあ途中で終わっても、新しく認識やり直すときに入れるTranscriptionLineが、もうDBにはいってるやつの時間よりあとか前かを見て、すでにDBに入っているやつと重複しないようにするというのもいける??whisperがnon deterministicなら厳しいか?
まあどっちにしろこれやるとすると割と重いタスクだし一生やらなさそう笑 これでキルされなくなるなら結構大事やけど笑
遅くなってすまん!LGTM!
ごめんまじで手が滑って間違えてクローズしてもうた
Related Issue
close #287 close #288 close #289
What
Memo