Closed kyakuno closed 5 months ago
@takumi2786 こちら、優先度を少し上げたいと考えていまして、いつ頃、実装できそうでしょうか?
g2p_enのv1にして、tensorflow v2に対応するためにplaceholderを書き換える必要がある。 https://v-crn.hatenablog.com/entry/2019/12/20/TensorFlow_2_0_0%E3%81%B8%E3%81%AE%E3%82%A2%E3%83%83%E3%83%97%E3%83%87%E3%83%BC%E3%83%88%E3%81%A7%E5%87%BA%E3%81%8F%E3%82%8F%E3%81%97%E3%81%9F%E3%82%A8%E3%83%A9%E3%83%BC%EF%BC%9AAttributeError%3A_module_ ただ、v2にはrnnがないので、tensorflow1でエクスポートする必要がある。 https://github.com/tensorflow/tensorflow/issues/32784
tensorflow 1.8のインストールにはpython3.6が必要。 https://qiita.com/Sk_s/items/d6e970d32719d44b8883
Ubuntu22.04にはpython3.6が入らないので、諦めてtorchでグラフを再構築した方が良さそう。
ChatGPTにtorchに変えてもらった。
original
['AY1', ' ', 'HH', 'AE1', 'V', ' ', 'T', 'UW1', ' ', 'HH', 'AH1', 'N', 'D', 'R', 'AH0', 'D', ' ', 'F', 'IH1', 'F', 'T', 'IY0', ' ', 'D', 'AA1', 'L', 'ER0', 'Z', ' ', 'IH0', 'N', ' ', 'M', 'AY1', ' ', 'P', 'AA1', 'K', 'AH0', 'T', ' ', '.']
['P', 'AA1', 'P', 'Y', 'AH0', 'L', 'ER0', ' ', 'P', 'EH1', 'T', 'S', ' ', ',', ' ', 'F', 'AO1', 'R', ' ', 'IH0', 'G', 'Z', 'AE1', 'M', 'P', 'AH0', 'L', ' ', 'K', 'AE1', 'T', 'S', ' ', 'AH0', 'N', 'D', ' ', 'D', 'AA1', 'G', 'Z']
['AY1', ' ', 'R', 'IH0', 'F', 'Y', 'UW1', 'Z', ' ', 'T', 'UW1', ' ', 'K', 'AH0', 'L', 'EH1', 'K', 'T', ' ', 'DH', 'AH0', ' ', 'R', 'EH1', 'F', 'Y', 'UW2', 'Z', ' ', 'ER0', 'AW1', 'N', 'D', ' ', 'HH', 'IY1', 'R', ' ', '.']
['AY1', 'M', ' ', 'AE1', 'N', ' ', 'AE2', 'K', 'T', 'IH0', 'V', 'EY1', 'SH', 'AH0', 'N', 'IH0', 'S', 'T', ' ', '.']
torch
['AY1', ' ', 'HH', 'AE1', 'V', ' ', 'T', 'UW1', ' ', 'HH', 'AH1', 'N', 'D', 'R', 'AH0', 'D', ' ', 'F', 'IH1', 'F', 'T', 'IY0', ' ', 'D', 'AA1', 'L', 'ER0', 'Z', ' ', 'IH0', 'N', ' ', 'M', 'AY1', ' ', 'P', 'AA1', 'K', 'AH0', 'T', ' ', '.']
['P', 'AA1', 'P', 'Y', 'AH0', 'L', 'ER0', ' ', 'P', 'EH1', 'T', 'S', ' ', ',', ' ', 'F', 'AO1', 'R', ' ', 'IH0', 'G', 'Z', 'AE1', 'M', 'P', 'AH0', 'L', ' ', 'K', 'AE1', 'T', 'S', ' ', 'AH0', 'N', 'D', ' ', 'D', 'AA1', 'G', 'Z']
['AY1', ' ', 'R', 'IH0', 'F', 'Y', 'UW1', 'Z', ' ', 'T', 'UW1', ' ', 'K', 'AH0', 'L', 'EH1', 'K', 'T', ' ', 'DH', 'AH0', ' ', 'R', 'EH1', 'F', 'Y', 'UW2', 'Z', ' ', 'ER0', 'AW1', 'N', 'D', ' ', 'HH', 'IY1', 'R', ' ', '.']
['AY1', 'M', ' ', 'AE1', 'N', ' ', 'AE2', 'K', 'T', 'IH0', 'V', 'EY1', 'SH', 'AH0', 'N', 'IH0', 'S', 'T', ' ', '.']
@kyakuno すみません、6月あまり稼働できておらず、まだ目処はついていないです :bow:
急ぎであれば一旦手放そうかと思いますがどうでしょうか :bow:
@takumi2786 承知しました。私の方で作業をしてみます。
@kyakuno すみません、ありがとうございます
encoderとdecoderを分離。
下記でONNXエクスポートを実施。 https://github.com/axinc-ai/g2p/tree/torch
nltk.download('cmudict') で入るのは下記。 https://github.com/nltk/nltk_data/issues/66 ライセンス。 https://github.com/cmusphinx/cmudict/blob/master/LICENSE
品詞はnltkのpos_taggerで計算されている。 https://stackoverflow.com/questions/32016545/how-does-nltk-pos-tag-work
homographは品詞によって発音が異なることをシミュレートしている。
nltkのtaggerもonnxに変換したい。
hundredは複数定義されている。
HUNDRED 1 HH AH1 N D R AH0 D
HUNDRED 2 HH AH1 N D R IH0 D
HUNDRED 3 HH AH1 N ER0 D
HUNDRED 4 HH AH1 N D ER0 D
self.cmu[word][0]だと最初のを使う。
cmuだと、 RETHINK 1 R IY0 TH IH1 NG K で、 homographsだと、 RETHINK|R IY2 TH IH1 NG K|R IY1 TH IH0 NG K|V で、アクセント記号が異なる。
nltkのtag/perceptron.pyのPerceptronTaggerでtaggingされている。
def tag(self, tokens, return_conf=False, use_tagdict=True):
"""
Tag tokenized sentences.
:params tokens: list of word
:type tokens: list(str)
"""
prev, prev2 = self.START
output = []
context = self.START + [self.normalize(w) for w in tokens] + self.END
for i, word in enumerate(tokens):
tag, conf = (
(self.tagdict.get(word), 1.0) if use_tagdict == True else (None, None)
)
print(tag, word)
if not tag:
features = self._get_features(i, word, context, prev, prev2)
tag, conf = self.model.predict(features, return_conf)
output.append((word, tag, conf) if return_conf == True else (word, tag))
prev2 = prev
prev = tag
return output
tagとwordを表示すると、辞書ベースでwordからtagが決定するものと、AIで決定するものの2種類がある。
, ,
IN for
NN example
None cats
CC and
None dogs
None i
None refuse
TO to
_get_featuresでは、前後のtagをもとに、featureを決定する。featureは、activationistだと、
defaultdict(<class 'int'>, {'bias': 1, 'i suffix ist': 1, 'i pref1 a': 1, 'i-1 tag DT': 1, 'i-2 tag VB': 1, 'i tag+i-2 tag DT VB': 1, 'i word activationist': 1, 'i-1 tag+i word DT activationist': 1, 'i-1 word an': 1, 'i-1 suffix an': 1, "i-2 word i'm": 1, 'i+1 word .': 1, 'i+1 suffix .': 1, 'i+2 word -END-': 1})
のような文字列になる。
実際の推論は下記のコードで動く。ネットワークはシンプルではある。
def predict(self, features, return_conf=False):
"""Dot-product the features and current weights and return the best label."""
scores = defaultdict(float)
for feat, value in features.items():
if feat not in self.weights or value == 0:
continue
weights = self.weights[feat]
for label, weight in weights.items():
scores[label] += value * weight
# Do a secondary alphabetic sort, for stability
best_label = max(self.classes, key=lambda label: (scores[label], label))
# compute the confidence
conf = max(self._softmax(scores)) if return_conf == True else None
return best_label, conf
onnxの変換で、seq_lenが奇数だと結果が合わなそう。
辞書にある単語も常にpredictを通すようにすると、下記の例外になる。
kyakuno@mbakk g2p_en % python3 g2p_en.py --verify
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 (109) : cmudict is prepared!
INFO model_utils.py (109) : homographs.en is prepared!
INFO model_utils.py (109) : averaged_perceptron_tagger.pickle is prepared!
INFO license.py (81) : ailiaへようこそ。ailia SDKは商用ライブラリです。特定の条件下では、無償使用いただけますが、原則として有償ソフトウェアです。詳細は https://ailia.ai/license/ を参照してください。
i have two hundred fifty dollars in my pocket.
Python(24142,0x20281a240) malloc: Incorrect checksum for freed object 0x7fbe241bb400: probably modified after being freed.
Corrupt value: 0x3db1c000bf75c000
Python(24142,0x20281a240) malloc: *** set a breakpoint in malloc_error_break to debug
zsh: abort python3 g2p_en.py --verify
iを入れた時に、shapeが(2,)になり、encoder.runでエラーになる。
ailia本体に配列の範囲外参照があるような気もする。
onnxruntimeでも例外が出る。
2024-06-26 08:03:39.036948 [E:onnxruntime:, sequential_executor.cc:514 ExecuteKernel] Non-zero status code returned while running Gather node. Name:'/Gather_12' Status Message: indices element out of data bounds, idx=2 must be within the inclusive range [-2,1]
Traceback (most recent call last):
File "/Users/kyakuno/Desktop/ailia/ailia-models-ax/natural_language_processing/g2p_en/g2p_en.py", line 270, in <module>
main()
File "/Users/kyakuno/Desktop/ailia/ailia-models-ax/natural_language_processing/g2p_en/g2p_en.py", line 264, in main
verify(encoder, decoder)
File "/Users/kyakuno/Desktop/ailia/ailia-models-ax/natural_language_processing/g2p_en/g2p_en.py", line 234, in verify
out = g2p(text, encoder, decoder)
^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/Users/kyakuno/Desktop/ailia/ailia-models-ax/natural_language_processing/g2p_en/g2p_en.py", line 175, in __call__
pron = self.predict(word, encoder, decoder)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/Users/kyakuno/Desktop/ailia/ailia-models-ax/natural_language_processing/g2p_en/g2p_en.py", line 118, in predict
h = encoder.run(
^^^^^^^^^^^^
File "/usr/local/lib/python3.11/site-packages/onnxruntime/capi/onnxruntime_inference_collection.py", line 220, in run
return self._sess.run(output_names, input_feed, run_options)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
onnxruntime.capi.onnxruntime_pybind11_state.InvalidArgument: [ONNXRuntimeError] : 2 : INVALID_ARGUMENT : Non-zero status code returned while running Gather node. Name:'/Gather_12' Status Message: indices element out of data bounds, idx=2 must be within the inclusive range [-2,1]
下記でsteps=2でループしているので、シンボル数は2以上である必要がある。
for t in range(steps):
h = self.grucell(x[:, t, :], h, w_ih, w_hh, b_ih, b_hh) # (b, h)
outputs[:, t, :] = h
return outputs
シンボル数が1の場合は、全て辞書に含まれる想定に見える。
have [10 3 24 7 2] でもエラーになる。
onnxruntime.capi.onnxruntime_pybind11_state.InvalidArgument: [ONNXRuntimeError] : 2 : INVALID_ARGUMENT : Non-zero status code returned while running Gather node. Name:'/Gather_24' Status Message: indices element out of data bounds, idx=5 must be within the inclusive range [-5,4]
stepsにはx.shape[0]が入るので動いて欲しいが、dynamic shapeがtraceできていない気がする。
for stepsがconstantになっている予感。
そういうわけではなかった。
"i"でエクスポートした場合と、"activationist"でエクスポートした場合で、onnxの深さが変わってしまう。 やはり、シーケンス長が定数になってしまっている。
forを外に出した方が良さそう。
forをencoderの外に出すことで解消。
英語の音素変換。最新版はnumpyになっているので、昔のリビジョンのtensorflowからonnxに変換する。 https://github.com/Kyubyong/g2p/blob/master/g2p_en/g2p.py もしくは、自前でtorchにweightを流し込んでonnxに変換しても良い。