Closed ooe1123 closed 4 months ago
g2p_enのトークンと互換性はありそう。
Input : To be or not to be, that is the question g2p_en : ['T', 'UW1', 'B', 'IY1', 'AO1', 'R', 'N', 'AA1', 'T', 'T', 'UW1', 'B', 'IY1', ',', 'DH', 'AE1', 'T', 'IH1', 'Z', 'DH', 'AH0', 'K', 'W', 'EH1', 'S', 'CH', 'AH0', 'N'] soundchoice-g2p : T-UW- -B-IY- -AO-R- -N-AA-T- -T-UW- -B-IY- -DH-AE-T- -IH-Z- -DH-AH- -K-W-EH-S-CH-AH-N
@ooe1123 実装、ありがとうございます!ベンチマークを使用するすると、beam searchでエラーが発生するようでして、何かコンテキストが残っているかもしれません。お手数ですが、ご確認いただけると嬉しいです。
kyakuno@mbakk soundchoice-g2p % python3 soundchoice-g2p.py -b
INFO arg_utils.py (13) : Start!
INFO arg_utils.py (163) : env_id: 2
INFO arg_utils.py (166) : MPSDNN-Apple M2
INFO model_utils.py (89) : ONNX file and Prototxt file are prepared!
INFO model_utils.py (89) : ONNX file and Prototxt file are prepared!
INFO model_utils.py (89) : ONNX file and Prototxt file are prepared!
INFO license.py (81) : ailiaへようこそ。ailia SDKは商用ライブラリです。特定の条件下では、無償使用いただけますが、原則として有償ソフトウェアです。詳細は https://ailia.ai/license/ を参照してください。
INFO soundchoice-g2p.py (311) : Input text: To be or not to be, that is the question
INFO soundchoice-g2p.py (314) : Start inference...
INFO soundchoice-g2p.py (316) : BENCHMARK mode
INFO soundchoice-g2p.py (325) : ailia processing estimation time 913 ms
Traceback (most recent call last):
File "/Users/kyakuno/Desktop/ailia/ailia-models-ax/natural_language_processing/soundchoice-g2p/soundchoice-g2p.py", line 374, in <module>
main()
File "/Users/kyakuno/Desktop/ailia/ailia-models-ax/natural_language_processing/soundchoice-g2p/soundchoice-g2p.py", line 370, in main
recognize_from_text(models)
File "/Users/kyakuno/Desktop/ailia/ailia-models-ax/natural_language_processing/soundchoice-g2p/soundchoice-g2p.py", line 320, in recognize_from_text
phonemes = predict(models, input_text)
^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/Users/kyakuno/Desktop/ailia/ailia-models-ax/natural_language_processing/soundchoice-g2p/soundchoice-g2p.py", line 303, in predict
phonemes = compute_outputs(net, p_seq, encoder_outputs)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/Users/kyakuno/Desktop/ailia/ailia-models-ax/natural_language_processing/soundchoice-g2p/soundchoice-g2p.py", line 272, in compute_outputs
hyps, scores, *_ = S2SBeamSearcher(net, args.onnx).forward(encoder_outputs)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/Users/kyakuno/Desktop/ailia/ailia-models-ax/natural_language_processing/soundchoice-g2p/beam_searcher.py", line 994, in forward
) = self.search_step(
^^^^^^^^^^^^^^^^^
File "/Users/kyakuno/Desktop/ailia/ailia-models-ax/natural_language_processing/soundchoice-g2p/beam_searcher.py", line 869, in search_step
) = self._scorer_step(
^^^^^^^^^^^^^^^^^^
File "/Users/kyakuno/Desktop/ailia/ailia-models-ax/natural_language_processing/soundchoice-g2p/beam_searcher.py", line 378, in _scorer_step
score, new_memory["ctc"] = ctc_score(inp_tokens, memory["ctc"], attn)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/Users/kyakuno/Desktop/ailia/ailia-models-ax/natural_language_processing/soundchoice-g2p/beam_searcher.py", line 145, in ctc_score
psi_init = np.expand_dims(r[start - 1, 0], axis=0)
~^^^^^^^^^^^^^^
IndexError: index 40 is out of bounds for axis 0 with size 40
To be or not to be, that is the questionの推論時間。
BLAS : 495 ms MPS : 634 ms
rnn_beam_searcher.onnxがseq2seqのdecoderに相当する。S2SBeamSearcherの中でbeam_size=16が定義されている。
S2SBeamSearcherのbeam_size=1にした上で、_update_reset_memoryのhsの16も1にすると、greedy searchにできる。
Beam Search 16 : 495ms T-UW- -B-IY- -AO-R- -N-AA-T- -T-UW- -B-IY- -DH-AE-T- -IH-Z- -DH-AH- -K-W-EH-S-CH-AH-N Greedy Search : 208ms T-UW- -B-IY- -AO-R- -N-AA-T- -T-UW- -B-IY- -DH-AE-T- -IH-Z- -DH-AH- -K-W-EH-S-CH-AH-N
rnnのアーキテクチャ https://arxiv.org/pdf/2207.13703
tokenizerは普通のbert。 token_type_idsについて。今回のケースでは全て0になりそう。 https://qiita.com/Dash400air/items/a616ef8d088e003dfd4c encode_plusはattention maskを取得するために使う。 https://zenn.dev/hellorusk/articles/7fd588cae5b173
@ooe1123 実装、ありがとうございます!ベンチマークを使用するすると、beam searchでエラーが発生するようでして、何かコンテキストが残っているかもしれません。お手数ですが、ご確認いただけると嬉しいです。
@kyakuno 問題の修正を行いました!
動作確認できました!ご対応、ありがとうございました。
@ooe1123 embeddingsの下記のコードが少し不思議でして、hidden_statesは(n_token, 1, n_token, 768)で、トークン列の末尾4つを縮退するようなコードになっていまして、こちらのコードのtorchの元コードを教えていただくことは可能でしょうか?
# get_hidden_states
layers = [-4, -3, -2, -1]
output = np.sum(hidden_states[layers], axis=0)
output = np.squeeze(output)
output = output[token_ids_word]
@kyakuno
こちらのコードのtorchの元コード
オリジナルコードでの当該部分は以下になります。 https://github.com/speechbrain/speechbrain/blob/develop/speechbrain/wordemb/transformer.py#L247-L253
@ooe1123 ありがとうございます!現在、emb.onnxについて、output shapeが(len, 1, len, 768)になっているのですが、(4, 1, len, 768)か、(n_layers, 1, len, 768)が正しそうな気がするのですが、いかがでしょうか?トークン長が、4より小さいか、bertのレイヤー数より大きくなると、推論エラーになりそうな気がしました。
@kyakuno
ご確認ありがとうございます。 input_idsの長さを変えて数パターンみてみたところ、 hidden_stateは、(13, 1, len, 768) の形状となるのが正しいようです。
soundchoice-g2p_emb.onnx を再エクスポートしてご提供致します。
お手数おかけします。よろしくお願いします!
後、追加ですみません。
token_ids_word = np.array(
[idx for idx, word_id in enumerate(encoded.word_ids()) if word_id is not None],
)
なのですが、現状の文字列の場合、サブワード分割されないので問題ないのですが、"To be or not to be, that is the questionary"を入力として、questionaryがサブワード分割されるようにした場合、
word_ids [None, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 10, None]
token_ids_word [ 1 2 3 4 5 6 7 8 9 10 11 12]
となるようでして、本来的には、最後の[10, 10]がまとめられて、
token_ids_word [ 1 2 3 4 5 6 7 8 9 10 11]
となるのが正しい気がするのですが、いかがでしょうか?
この後段で、expand_to_charsをしており、この中のwordsのshapeのword数と、embeddingのshapeのword数が一致しないと、word単位のembeddingをchar単位のembeddingに変換できないような気がしました。
雑なコードですが、下記のような論理なのかなと思いました。
max_word_id = 0
for idx in range(0, len(encoded.word_ids())):
if encoded.word_ids()[idx] == None:
continue
max_word_id = encoded.word_ids()[idx]
token_ids_word = []
for idx in range(0, max_word_id + 1):
token_ids_word.append(np.where(np.array(encoded.word_ids()) == idx)[0][0])
token_ids_word = np.array(token_ids_word)
"To be or not to be, that is the questionary"のように","が存在する場合、grapheme_pipelineで","が削除されるものの、BERTの Tokenizerでは","を単語として扱うため、token_ids_wordの数と、expand_to_charsの中のseqを分割した数も合わなくなる気がしますね。
↑の議論はすいません、専門的な知識がなくて、 この処理が本質的に何をやっているのか理解できていないため、私には是非が分からないです。
オリジナルだと embeddingsの処理はここで、 https://github.com/speechbrain/speechbrain/blob/develop/speechbrain/wordemb/transformer.py#L196-L203 expand_to_charsの処理はこちらになります。 https://github.com/speechbrain/speechbrain/blob/develop/speechbrain/wordemb/util.py#L11
承知しました。公式でテストしてみたところ、推測が正しかったので、私の方で修正します。
text = "To be or not to be, that is the question"
emb.shape torch.Size([1, 11, 768])
seq tensor([[ 0, 22, 17, 30, 4, 7, 30, 17, 20, 30, 16, 17, 22, 30, 22, 17, 30, 4,
7, 30, 22, 10, 3, 22, 30, 11, 21, 30, 22, 10, 7, 30, 19, 23, 7, 21,
22, 11, 17, 16]])
seq.shape torch.Size([1, 40])
words tensor([[0, 0, 0, 1, 1, 1, 2, 2, 2, 3, 3, 3, 3, 4, 4, 4, 5, 5, 5, 6, 6, 6, 6, 6,
7, 7, 7, 8, 8, 8, 8, 9, 9, 9, 9, 9, 9, 9, 9, 9]])
words.shape torch.Size([1, 40])
text = "To be or not to be, that is the questionary"
emb.shape torch.Size([1, 12, 768])
seq tensor([[ 0, 22, 17, 30, 4, 7, 30, 17, 20, 30, 16, 17, 22, 30, 22, 17, 30, 4,
7, 30, 22, 10, 3, 22, 30, 11, 21, 30, 22, 10, 7, 30, 19, 23, 7, 21,
22, 11, 17, 16, 3, 20, 27]])
seq.shape torch.Size([1, 43])
words tensor([[0, 0, 0, 1, 1, 1, 2, 2, 2, 3, 3, 3, 3, 4, 4, 4, 5, 5, 5, 6, 6, 6, 6, 6,
7, 7, 7, 8, 8, 8, 8, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9]])
すみません、やっぱり、公式のコードの段階で問題がありそうなので、公式に聞いてみます。 https://github.com/speechbrain/speechbrain/issues/2580
公式に乗っ取ったサンプルとしては現在のもので問題なさそうです。
https://github.com/axinc-ai/ailia-models/issues/1479 のPRです