Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

昔作った.onnxがonnxruntime 1.18でloadできない #27

Open
Hiroshiba opened this issue Aug 17, 2024 · 13 comments
Open

昔作った.onnxがonnxruntime 1.18でloadできない #27

Hiroshiba opened this issue Aug 17, 2024 · 13 comments

Comments

@Hiroshiba
Copy link
Owner

Hiroshiba commented Aug 17, 2024

概要

昔作った.onnxがonnxruntime 1.18でloadできない問題が発生しています。
このままではonnxruntimeの1.18バージョンアップができないので、なんとかしたいところです。

とりあえず知見を集めるべく、issueを作ってみました。

検証方法

onnxruntime-1.18ブランチを作ってみました。
こちらのブランチに移動してpip install -r requirements.txtすれば環境が構築できます。
(python 3.10環境が必要です)

voicevox_core内に.onnxがあるので、そちらを持ってきて試すのが手っ取り早いです。
~/Github/voicevox_coreにVOICEVOX COREリポジトリのcloneがあるとして、こちらのbashスクリプトで検証できます。

set -eux

working_dir=working/
rm -rf $working_dir
mkdir -p $working_dir

cp ~/Github/voicevox_core/model/sample.vvm/predict_duration.onnx "$working_dir/duration.onnx"
cp ~/Github/voicevox_core/model/sample.vvm/predict_intonation.onnx "$working_dir/intonation.onnx"
cp ~/Github/voicevox_core/model/sample.vvm/decode.onnx "$working_dir/decode.onnx"

python run.py \
  --yukarin_s_model_dir "$working_dir" \
  --yukarin_sa_model_dir "$working_dir" \
  --yukarin_sosoa_model_dir "$working_dir" \
  --hifigan_model_dir "$working_dir" \
  --method onnx \
  --speaker_ids 5 9

実行ログ↓

+ working_dir=working/
+ rm -rf working/
+ mkdir -p working/
+ cp /Users/[user name]/Github/voicevox_core/model/sample.vvm/predict_duration.onnx working//duration.onnx
+ cp /Users/[user name]/Github/voicevox_core/model/sample.vvm/predict_intonation.onnx working//intonation.onnx
+ cp /Users/[user name]/Github/voicevox_core/model/sample.vvm/decode.onnx working//decode.onnx
+ python run.py --yukarin_s_model_dir working/ --yukarin_sa_model_dir working/ --yukarin_sosoa_model_dir working/ --hifigan_model_dir working/ --method onnx --speaker_ids 5 9
Traceback (most recent call last):
  File "/Users/[user name]/Github/vv_core_inference/run.py", line 99, in <module>
    run(**vars(parser.parse_args()))
  File "/Users/[user name]/Github/vv_core_inference/run.py", line 59, in run
    decode_forwarder = make_decode_forwarder(
  File "/Users/[user name]/Github/vv_core_inference/vv_core_inference/onnx_decode_forwarder.py", line 12, in make_decode_forwarder
    session = onnxruntime.InferenceSession(
  File "/Users/[user name]/Github/vv_core_inference/.venv/lib/python3.10/site-packages/onnxruntime/capi/onnxruntime_inference_collection.py", line 419, in __init__
    self._create_inference_session(providers, provider_options, disabled_optimizers)
  File "/Users/[user name]/Github/vv_core_inference/.venv/lib/python3.10/site-packages/onnxruntime/capi/onnxruntime_inference_collection.py", line 472, in _create_inference_session
    sess = C.InferenceSession(session_options, self._model_path, True, self._read_config_from_model)
onnxruntime.capi.onnxruntime_pybind11_state.Fail: [ONNXRuntimeError] : 1 : FAIL : Load model from working/decode.onnx failed:Node (Unsqueeze_481) Op (Unsqueeze) [ShapeInferenceError] values in 'axes' are beyond the bounds of the computed output shape
@Hiroshiba
Copy link
Owner Author

Discordでのやり取りメモ 📝
https://discord.com/channels/879570910208733277/893889888208977960/1274198132111966251

  • ONNX v1.15.0 → v1.16.0の変更により起きたもの。ONNX RuntimeがONNXに当てるパッチも関係無い (ちなみに調査でonnx.checker.check_modelを用いるときは%60full_check=True%60としなければならない)
  • おそらくonnx/onnx#5967により起きている。この一つ前なら%60check_model%60が通る。つまりこの%60+54-20%60の「shape inferenceのfix」により起きている

  • このコミットはaxes非指定のSqueezeにshape inferenceがついたということなのでそれに関連する部分の影響でしょうか
  • https://github.com/Hiroshiba/vv_core_inference/blob/main/vv_core_inference/make_yukarin_sosoa_forwarder.py#L128
  • (dynamic axesを含む場合のshape inferenceがバグっているのか詳しいことは分かりませんがここが怪しそう)
  • 長さ1のf0を入力したときなどにバグる実装なので元を直した方が良いとは思いますが、対症療法的には対応するSqueezeのaxesを明示するコンバーターを書けば何とかなりそう?

@Hiroshiba
Copy link
Owner Author

可視化してみた感じ、
f0 → Unsqueeze → shape → ConstantOfShape → Squeeze → Unsqueeze
となってるとこの2つ目のUnsqueezeで落ちてそうでした。

そのあと Equal → Where → Softmax と続いてます。
おそらくself attentionの部分で、落ちてるUnsqueezeは mask.unsqueeze(1) してるとこだと思います。つまり問題ない。

その前のSqueezeはここ↓で、次元を指定せずにsqueeze()してました。ここの結果axesがわからなくなっちゃってそう?

mask = torch.ones_like(f0).squeeze()
h, _ = self.encoder(h, mask)

@Hiroshiba
Copy link
Owner Author

Hiroshiba commented Aug 17, 2024

onnx 1.16でOPSET 21に変換してみましたが、同じ場所で落ちて、エラーが変わるだけでした。

onnxruntime.capi.onnxruntime_pybind11_state.Fail: [ONNXRuntimeError] : 1 : FAIL : Load model from working/decode.onnx failed:Node (Unsqueeze_481) Op (Unsqueeze) [ShapeInferenceError] Unexpected axis value: 1. Expected range [-1, 1)
コード

変換コード convert_to_onnx1.16.py

"""
ONNX 1.16に変換するためのスクリプト。
"""

import argparse

import onnx
from onnx import version_converter

parser = argparse.ArgumentParser()
parser.add_argument("input", help="Input ONNX model")
parser.add_argument("output", help="Output ONNX model")
args = parser.parse_args()

OPSET = onnx.defs.onnx_opset_version()

old_model = onnx.load(args.input)

updated_model = version_converter.convert_version(old_model, target_version=OPSET)
onnx.save(updated_model, args.output)

スクリプト

set -eux

working_dir=working/
rm -rf $working_dir
mkdir -p $working_dir

cp ~/Github/voicevox_core/model/sample.vvm/predict_duration.onnx "$working_dir/duration.onnx"
cp ~/Github/voicevox_core/model/sample.vvm/predict_intonation.onnx "$working_dir/intonation.onnx"
cp ~/Github/voicevox_core/model/sample.vvm/decode.onnx "$working_dir/decode.onnx"

python convert_to_onnx1.16.py \
  "$working_dir/decode.onnx" \
  "$working_dir/decode.onnx"

python run.py \
  --yukarin_s_model_dir "$working_dir" \
  --yukarin_sa_model_dir "$working_dir" \
  --yukarin_sosoa_model_dir "$working_dir" \
  --hifigan_model_dir "$working_dir" \
  --method onnx \
  --speaker_ids 5 9

@Hiroshiba
Copy link
Owner Author

pytorch 1.13/onnx 1.16/onnxruntime 1.18で作った.onnxは普通にonnxruntime 1.18で読み込めるので、差を見比べました。
Unsqeezeの部分が違っていそう?
attributes axes 1だとダメで、INPUTS axesとして別のとこを参照してそうでした。
ちゃんとonnx知らないのですが、こっち変えるのは相当大変そう・・・?

比較画像

以前の
image

新しく作ったの
image

@Yosshi999
Copy link
Contributor

v13以降のUnsqueezeはaxesを実行時に指定できる(inputに指定できる)ようですね。そのスクショを見た感じv13でもaxesの右に+マークがついているので、結局定数(initializerからinputへの入力)としてほぞんされているかもしれないです。その+をクリックすると展開できます

@Hiroshiba
Copy link
Owner Author

Hiroshiba commented Aug 17, 2024

@Yosshi999 ありがとうございます!!
見てみたら、確かに何かが保存されていそうでした![1]のTensorっぽみですね・・・。

画像

image

@Hiroshiba
Copy link
Owner Author

Hiroshiba commented Aug 17, 2024

v13に変換すると、Unsqueezeは問題ない?っぽいもの(axesに値が入ってるもの)になる一方、Squeezeがスカラ値っぽくなってました。

↓v13に変換したonnxのUnsqueeze
image

↓v13に変換したonnxのSqueeze
image

ちなみにこれは(Unsqueeze) [ShapeInferenceError] Unexpected axis value: 1. Expected range [-1, 1)というエラーが出ます。

正しく読める.onnxの方のSqueezeはこうなってました。

image

Squeezeのaxes引数?を0にすれば解決する・・・?
(バッチサイズ1にunsqueezeしてて、そこのsqueezeをするのがここの目的なはず)

@Hiroshiba
Copy link
Owner Author

Hiroshiba commented Aug 17, 2024

@Yosshi999 またまたになってしまうのですが、onnxモデルの変換で力をお借りできないでしょうか・・・ 🙇

VOICEVOX COREリポジトリにあるonnxファイルを変換し、onnxruntime-1.18ブランチの環境でrun.pyが実行できれば勝ちなはずです!
再現方法はこのissueのdescriptionに詳しく書いています。
(といってもかなり整備できているので、リネームしてrun.py実行するだけなのですが)

decodeにはUnsqueezeが3つありますが、3つとも変換が必要なのか等は現状不明です。
Discordでやりとりがあったように、Squeeze側に引数[0, 2]を追加できればあるいは・・・という感じ・・・でしょうか。

新しいonnxruntimeで使えればその分WebGPUでの速度なども追従されるため、いろいろできる範囲も増えていくと踏んでいます!
もしよければ・・・!!!

@Yosshi999
Copy link
Contributor

onnx/onnx#6313
これが完了したので多分次のバージョンで直ってるんじゃないかと思います

@Hiroshiba
Copy link
Owner Author

おおおおありがとうございます!!!!!!!

とりあえずこのissueはopenし続けますが、onnxファイルをどうにかしなくても良いかもという方針で動こうと思います!!

@sevenc-nanashi
Copy link

Onnxruntme 1.20.1でもまだ直ってなさそう?:

In [12]: s = onnxruntime.InferenceSession("./model/sample.vvm/predict_spectrogram.onnx")
---------------------------------------------------------------------------
Fail                                      Traceback (most recent call last)
Cell In[12], line 1
----> 1 s = onnxruntime.InferenceSession("./model/sample.vvm/predict_spectrogram.onnx")

File ~/.rye/tools/ipython/lib/python3.12/site-packages/onnxruntime/capi/onnxruntime_inference_collection.py:465, in InferenceSession.__init__(self, path_or_bytes, sess_options, providers, provider_options, **kwargs)
    462 disabled_optimizers = kwargs.get("disabled_optimizers")
    464 try:
--> 465     self._create_inference_session(providers, provider_options, disabled_optimizers)
    466 except (ValueError, RuntimeError) as e:
    467     if self._enable_fallback:

File ~/.rye/tools/ipython/lib/python3.12/site-packages/onnxruntime/capi/onnxruntime_inference_collection.py:526, in InferenceSession._create_inference_session(self, providers, provider_options, disabled_optimizers)
    523 self._register_ep_custom_ops(session_options, providers, provider_options, available_providers)
    525 if self._model_path:
--> 526     sess = C.InferenceSession(session_options, self._model_path, True, self._read_config_from_model)
    527 else:
    528     sess = C.InferenceSession(session_options, self._model_bytes, False, self._read_config_from_model)

Fail: [ONNXRuntimeError] : 1 : FAIL : Load model from ./model/sample.vvm/predict_spectrogram.onnx failed:Node (m0.Unsqueeze_482) Op (Unsqueeze) [ShapeInferenceError] values in 'axes' are beyond the bounds of the computed output shape

In [13]: onnxruntime.__version__
Out[13]: '1.20.1'

@qryxip
Copy link

qryxip commented Dec 22, 2024

onnx/onnx#6314 ですが、onnx/onnxのリリースにはまだ入ってなさそうです(onnx v1.17.0では見送られたっぽい)。なので

  1. Fix shape inference for Squeeze-1,11 with dynamic input shape onnx/onnx#6314 がリリースされるのを待つ
  2. ONNX Runtimeがonnx/onnxのバージョンを上げるのを待つ
  3. 2.が含まれたONNX Runtimeがリリースされるのを待つ

ということになりそうです。

ONNX Runtime自体がonnxに対してパッチしてるので、このパッチに onnx/onnx#6314 の内容をねじ込めばなんとかなるかもしれませんが…
(もしやるとしたら、onnxruntime-builderにpatch for patchを置くことに…?)

@sevenc-nanashi
Copy link

このパッチに onnx/onnx#6314 の内容をねじ込めばなんとかなるかもしれませんが…

ローカルでビルドしたところ、動きました!具体的にはこんなパッチを追加しました:
diff.zip

ので、 onnx/onnx#6314 が含まれたonnxruntimeのリリースと同時にこのIssueは閉じても良さそう。

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

4 participants