窓を作っては壊していた人のブログ

この謎のブログタイトルの由来を知るものはもういないだろう

pyopenjtalkをWindowsでWSLなどを使わずにインストールする方法

さっさと解決策を知りたい方は以下の目次の環境構築まで飛ばしてください

背景

最近テキスト読み上げソフトウェアであるVOICEVOXとその関連ソフトウェアに注目している私です。

github.com

VOICEVOXはOSSで開発されており、実際に合成を行うCore部分や、それをラップするEngineなども公開されていて非常に興味深いプロジェクトとなっています。

さて、こういったTTSソフトは何らかの形で入力されたテキストを符号化し、その情報をもとにこねくり回して最終的に音声にするのですが(説明略)、そのテキストから符号化するのにVOICEVOXではpyopenjtalkを使っています。 このpyopenjtalk他にも色んなDNNを用いたTTSの現場でも使われていて、Twitterで見かけた情報ですが(おい)

この中で使われているDNNTTSライブラリ内部でもpyopenjtalkが使われているようです。

研究者の多くの方はUbuntuやそういったLinuxの環境で研究していると思うのですが、ちょっとDNNTTS簡単に行えるのであればやってみたい、みたいなライトユーザだったり、また今回例に挙げたVOICEVOXユーザの多くはWindowsを使っているかと思います。 pyopenjtalk自体はWindows対応しているのですが、正常にインストールすることに失敗している人が多く少しでも助けにならないかと思って以下にメモを残しておきます。

環境構築

github.com

このpyopenjtalkをWindowsでインストールするための環境を整えていきます。 ここではPythonが既に使える状態になっていると仮定して進めていきます。

pyopenjtalkを利用にあたりインストールするもの

以上

最小構成にしたい場合は

でも十分だと思います(未検証)

Visual Studio (Build Tools) のセットアップ

上記リンクからダウンロードしたインストーラを起動し、以下の画像のチェックがかかっている項目および下線が引かれているものをインストールします。

f:id:yamachu_co:20210917000647p:plain

  • C++によるデスクトップ開発

これが入っていればビルドに使うツールは揃います。

PATHの設定

システム -> システムの詳細設定 -> 環境変数 -> ~のユーザ環境変数

をたどり、PATHを探して編集画面に移ります。 この辺りは100億記事ぐらいあるので適当に探してください。

で、ここでは上記のインストーラー経由でインストールしたCMakeにPATHを通します。

f:id:yamachu_co:20210917001324p:plain

Visual Studio 2019 Preview Communityをインストールした私は

C:\Program Files (x86)\Microsoft Visual Studio\2019\Preview\Common7\IDE\CommonExtensions\Microsoft\CMake\CMake\bin

を設定しました。 このPATHにexplorerでアクセスして見つからなかったら周辺を探したりしてください(この記事を見ている多くの人はPreviewなんて入れないのでこのPATHじゃない確率が99%ぐらいです)。

お試し

pyopenjtalkのv0.1.4 (https://github.com/r9y9/pyopenjtalk/commit/dece47d7eec098ce74c5775afcbc11859d81a3ba) 以降で上記の方法でビルドできるようになっているのでインストールしてみましょう。

python3 -m venv .venv
 . .\.venv\Scripts\activate
pip install pyopenjtalk

適当なディレクトリで試してみて動いてそうなら自分の使いたいプロダクトで使っていきましょう。

終わりに

色んな人が頑張ってCMakeを入れたり色んなところ頑張ってPATHを通しているのを見て、やはりWindowsでCythonを使ったライブラリを使うのは面倒だなぁと感じて、とりあえず動かせるようにするための手順を書きなぐりました。 自分が開発している時もこれは大分面倒ではあるので、Cythonの依存をなくしたものを作ったりしています。

で、pyopenjtalkのインストール方法を紹介した後ではありますが自分のライブラリも紹介させてください。

github.com

ビルド済みのライブラリをインストール時にダウンロードし、手元でビルドさせることを排除したライブラリとなっています。 またこれは他のライブラリではおそらく実装されていないカスタム辞書読み込み機能などが付いていて、研究用途というよりも、何かしらのプロダクトを作るときに便利機能となっています。

片手間で作っているためラップ出来ている機能は少ないのですが、ぜひ試してみてください。 あとこのAPIさっさとラップしてくれ~みたいのがあったらIssueに残してくれるとよっしゃやるか~みたいになるかもしれません。

そして何よりもコントリビュートお待ちしております。

ISUCON11予選にソロ参戦して敗退しました

今年もISUCONに参戦してきました

昨年は社外の人と組んで3人チームで参加したのですが、今年はそういった話も特になかったのもありソロでの力を試してみたくソロ参戦してきました。

得点は17767点で235位(?XPathで適当に調べたけど合ってるはず)でした。 要は半分より上ですヤッター

isucon.net

やったこと

github.com

こちらのリポジトリにコミットしてあることだけです、本当にこれだけ。

今年は3台構成が可能だったのですが、それを試す時間もなく1台のアプリケーションをいじっていくだけの感じになりました。

git管理

差し戻しが出来るようにってことで今回ガッツリいじっていくGoのディレクトリとその他必要なディレクトリや、ミドルウェアの設定の管理をしました。

いい感じのMakefileを配置

2週間ほど前に練習した時に使ったMakefileを配置して、覚えるコマンドを減らしていきました。 これからはこのMakefileを育てていこうかなと思っています。

Goのバージョンアップ

Go 1.16系が使われていたので最近出たどうも速いと言われている1.17系を使うようにしました。 シュッとバージョン上げることが出来るのはGoの利点ですね。

User情報のキャッシュ

まずはINSERTやUPDATEがかかっているかみたいなことをざっくり見てキャッシュするのが簡単そうなやつからスタート。

Userのcache · yamachu/isucon11-qualify@b8c485f · GitHub

キャッシュできるものはやってしまえな考えから…この時はまだ計測とかはしていない。

getIsuListのN+1の解消

alp見たらこのエンドポイントがめちゃくちゃSUMで見たら大きかったので対処していこうってことで始めた。

サブクエリで一気に取る · yamachu/isucon11-qualify@fbb2e13 · GitHub

そもそもGo書いてないからどうやってStructにマッピングするんだよとかキレながら実装。 SQLも書けないのでググりながらやりたいことの単語を入れてそれっぽいSQLパクって 参考にして実装。

割とこの施策で上がった。

Icon画像をDBに入れるのをやめてファイルに落とし込む

DBにBlobを突っ込んでるのをやめる · yamachu/isucon11-qualify@32303f7 · GitHub

Revert "DBにBlobを突っ込んでるのをやめる" · yamachu/isucon11-qualify@ecf5301 · GitHub

Bye 画像 · yamachu/isucon11-qualify@148b715 · GitHub

一回リバートを挟んだ施策。 alpで見たらちょっとリクエスト多めかな…?と思えたので試してみた。 昔のISUCONでもDBからBlobを排除したら負荷が落ちたみたいのがあった記憶があったのもあり試した。

リバートをするのに至った理由としてはベンチで404とか302とかが返ってきて欲しいのに200が返ってきたみたいなログが見えてダメそうだと思ったから。 けどその意味をその時にちゃんと理解していればリバートいらなかったんじゃ…

ということで終了直前にこれpostIsuでロールバックかかってるじゃんに気づき(SlowQueryみてもその辺りの処理が多かったのが気になっていた)画像もロールバック(削除)したら200にならないじゃんになり試したら通った。

正直あまりスコアは上がらなかった(上がったのは1000点ぐらい)。

Bulk Insertを試す

bulk insert一番いい · yamachu/isucon11-qualify@70ce3d7 · GitHub

毎回数十件以上のINSERTするPayloadが飛んできていて、DBのロック時間がめちゃくちゃ取られるだろうなって想像してBulk Insertに変更。 2〜3000点ぐらい上がった記憶がある。

最新のISUのConditonをキャッシュする

早くなるはず(ベンチ回せない) · yamachu/isucon11-qualify@e6f1843 · GitHub

getIsuListでも行われていた最新のisuConditionを見てごにょごにょする処理。 同じクエリを使いまわしても良かったのだけれども、これテーブルに分けたほうが楽ではと思ったのでテーブル分けて実装。

getTrendはこれを採用したら一気にスコアが上がったけれども、getIsuListで使ったらスコアが10000以上落ちて何も分からなかったのでこのキャッシュはTrendだけで採用した。

反省

結局これしか出来なかった。

必死にクエリ書くのを1時間ぐらい頑張っていたけれども、最初っからテーブル分けるかRedisやOnMemoryキャッシュ試すとかに移れればよかったなと思った。 判断が遅い。

あとMariaDBのConfigにSlowQuery吐き出すためのフラグのやつがなくて出ない出ない!!!!!で騒いでたのがアホだった。

show variables like '%slow%';

でOFFになっているのを何度も見ているんだからONにするのを一回書こうねっていう………。

あと最初にコメントアウトでこの辺り数字変えると上がるはずだから変えろっていうのも忘れていたり、INDEX貼り忘れがあったりと初歩的なミスが多かった。 これやれば上がるは早めに頭を使わなくても出来るように練習をもうちょっとしておこうと思った。

後はベンチ回せない時にレスポンス合っているのかを自分で試せる施策を今後は試していきたい。

来年は頑張ろう!!!!!!来年も個人スポンサーやって応援しよう。