OmeSatoFoundation / ome2023

Other
1 stars 0 forks source link

[第6回] convert_yomi.shによって生成されるdicファイルを利用できない #80

Closed tikisi closed 5 months ago

tikisi commented 1 year ago

"第6回 教科書 6.11 自分の単語辞書を作成する"で利用するconvert_yomi.shによって生成されるdicファイルが利用できない。

以下実行時のログ convert_yomi.shの実行ログ (06/kudamono.yomiをそのまま利用)

pi@raspberrypi:~/06 $ convert_yomi.sh kudamono.yomi > kudamono.dic
Error: (they were also printed to stdout)
line 1: 
line 2: ߤ       ߤ
line 3: ֤ɤ       ֤ɤ
line 4: 
line 5: 
line 6: 
line 7: 
line 8: 
line 9: 
line 10: 
line 11: 
line 12: ʤ      ʤ
line 13: 

julius.shでdicファイルを読み込んだときのログ

pi@raspberrypi:~/06 $ julius.sh kudamono.dic
STAT: include config: /usr/local/bin/julius_conf/default.jconf
WARNING: m_chkparam: "-lmp" only for N-gram, ignored
WARNING: m_chkparam: "-lmp2" only for N-gram, ignored
STAT: jconf successfully finalized
STAT: *** loading AM00 _default
Stat: init_phmm: Reading in HMM definition
Stat: binhmm-header: variance inversed
Stat: read_binhmm: has inversed variances
Stat: read_binhmm: binary format HMM definition
Stat: read_binhmm: this HMM does not need multipath handling
Stat: init_phmm: defined HMMs:  8443
Stat: init_phmm: loading ascii hmmlist
Stat: init_phmm: logical names: 21429 in HMMList
Stat: init_phmm: base phones:    43 used in logical
Stat: init_phmm: finished reading HMM definitions
STAT: making pseudo bi/mono-phone for IW-triphone
Stat: hmm_lookup: 12 pseudo phones are added to logical HMM list
STAT: *** AM00 _default loaded
STAT: *** loading LM00 _default
STAT: reading [kudamono.dic]...
Stat: init_wordlist: reading in word list
Error: voca_load_wordlist: line 1: logical phone "" not found
Error: voca_load_wordlist: the line content was:
Error: voca_load_wordlist: line 2: logical phone "ߤ" not found
Error: voca_load_wordlist: the line content was: ߤ      ߤ
Error: voca_load_wordlist: line 3: logical phone "֤ɤ" not found
Error: voca_load_wordlist: the line content was: ֤ɤ      ֤ɤ
Error: voca_load_wordlist: line 4: logical phone "" not found
Error: voca_load_wordlist: the line content was:
Error: voca_load_wordlist: line 5: logical phone "" not found
Error: voca_load_wordlist: the line content was:
Error: voca_load_wordlist: line 6: logical phone "" not found
Error: voca_load_wordlist: the line content was:
Error: voca_load_wordlist: line 7: logical phone "" not found
Error: voca_load_wordlist: the line content was:
Error: voca_load_wordlist: line 8: logical phone "" not found
Error: voca_load_wordlist: the line content was:
Error: voca_load_wordlist: line 9: logical phone "" not found
Error: voca_load_wordlist: the line content was:
Error: voca_load_wordlist: line 10: logical phone "" not found
Error: voca_load_wordlist: the line content was:
Error: voca_load_wordlist: line 11: logical phone "" not found
Error: voca_load_wordlist: the line content was:
Error: voca_load_wordlist: line 12: logical phone "ʤ" not found
Error: voca_load_wordlist: the line content was: ʤ      ʤ
Error: voca_load_wordlist: line 13: logical phone "" not found
Error: voca_load_wordlist: the line content was:
Error: voca_load_htkdict: begin missing phones
Error: voca_load_htkdict:
Error: voca_load_htkdict: end missing phones
Error: init_wordlist: error in reading kudamono.dic: 13 words failed out of 0 words
ERROR: failed to read word list "kudamono.dic"
ERROR: m_fusion: some error occured in reading grammars
ERROR: Error in loading model

生成されたdicファイル

��� ���
�ߤ���   �ߤ���
�֤ɤ�    �֤ɤ�
��  ���
������  ������
����    ����
��  ������
��������    ��������
��  ����
������  ������
�����   �����
�ʤ� �ʤ�
�����   �����
tikisi commented 1 year ago

convert_yomi.sh中でのiconvによる文字コード変換の順番を変更することで、Julius.shで読み込み可能なdicファイルを生成できることを確認。

yomi2voca.plはyomiからdicへの変換を行うperlスクリプト、dic_tmpはyomiファイルをコピーしたファイルである。 以前はiconvでyomiファイルをeucjpに変換してからperlへ渡していたが、現在はperlへ渡した後にeucjpに変換することで期待する動作となっている。(変更後のスクリプトで生成されたdicファイルは06/kudamono.dicと一致することを確認済み。)

この原因は調査中だが、おそらくperlの扱う文字コードがラズパイ3と異なっている?のではないかと思う。

関連するスクリプト

tikisi commented 1 year ago

おそらくOSにインストールされているperlのバージョンが上がったことが原因。

perl5.26からUTF-8ロケールのデフォルト照合順序を使用するようになった。 そのため、kudamono.yomi中の文字列をutf-8で解釈していると考えられる。 https://perldoc.jp/docs/perl/5.26.0/perl5260delta.pod#Perl32can32now32do32default32collation32in32UTF-832locales32on32platforms32that32support32it

2022年度以前に利用していたraspbianは2018-04-18-raspbian-stretchであり、stretchでデフォルトでインストールされているperlのバージョンは5.24。 https://www.debian.org/releases/stretch/i386/release-notes/ch-whats-new.ja.html

対して、現在採用しているraspbianでのperlのバージョンは5.32.1である。

ip-arch commented 1 year ago

ラズパイのlocaleはおそらくUTF-8なので、 perlにEUCを処理させる従来の方法がまずいですね。 新しい方法で良いと思います。 JuliusもUTF対応してくれれば、変換不要ですね。

JuliusはUTF-8に統一と書いていますが、辞書もUTF-8で受け付けられませんか?

https://github.com/julius-speech/julius/blob/v4.6/00readme-ja.txt

UTF-8への移行について

バージョン4.5以前はテキストエンコーディングとして SJISや EUC が混在していましたが、 バージョン4.5から全て UTF-8 に変換されました.

バージョン4.5の時点でのテキストエンコード変換前のコードを "master-4.5-legacy" ブランチで保存してあります.4.5 リリース以前の コードから 4.5 までの差分を見る場合はそちらのブランチを checkout して ください.

tikisi commented 1 year ago

UTF-8の辞書ファイルを利用すると、以下のエラーが発生するため避けていました。 InternalError: codeconv: invalid multibyte sequence in the input

しかし、これはjuliusの設定ファイルでEUC-JPからUTF-8に変換するオプション(-charconv)がついていたことが原因のようです。 https://github.com/OmeSatoFoundation/ome2023/blob/8a3f521708d5641660904980de5e64de3460b5a5/contrib/JuliusMisc/julius_conf/default.jconf#L15 このオプションを削除することで、UTF-8の辞書を問題なく処理できることを確認したので以下の対応を行います。

以上で処理全体がUTF-8で行われるようになります。

また、今回の不具合が原因について再度調べてみました。 昨年度まで利用していたyomi2voca.plはEUC-JPで記述されていました。 対して、今年度利用しているyomi2voca.plはJuliusのバージョン4.5のため、UTF-8で記述されていました。 perlの内部文字列を利用するための記述(use Encode など)も見当たらなかったため、yomi2voca.pl自体を記述する文字コードでしか日本語の入力を上手く処理できなかったようです。