モーグルとカバとパウダーの日記

モーグルやカバ(EXカービング)山スキー(BC)などがメインの日記でした。今は仕事のコンピュータ系のネタが主になっています。以前はスパム対策関連が多かったのですが最近はディープラーニング関連が多めです。

NSEG2024 新年フリープレゼン大会で音声変換と生成AIについて話しました

久しぶりにNSEG勉強会が行われたので、この1年半(実質は1年くらい)やってた、ディープラーニングを利用した音声変換やニューラル圧縮について話をしました。

NSEG 2024 新年フリープレゼン大会 - 資料一覧 - connpass nseg.connpass.com

音声変換と生成AI:開発者視点からの1.5年の振り返り - Speaker Deck
speakerdeck.com

今回、いつものような技術的な解説ではなくて、どちらかというと僕のこの1年半にあったことの振り返りを他の方にも追体験していただき、その中で音声系を中心とした生成系AIでどんなことが起きてたかを感じてもらう、みたいなものをめざしました。

なのでプレゼン資料の枚数がすごく多くなってしまったのですが、内容は薄めです。

でも、以前やった勉強会で話したことが、例えば5年前に話してたようなことが、当時はこんな感覚だったんだなってことが資料として使えたので、今回のこれも、2022~3年あたりで音声生成とか変換ってこのあたりの地点だったんだな、というのが振り替えれるものになるのではと思っています。

とにかく、ディープラーニング系の技術は元々流速早かったのが、生成系AIの流れで更に急速に速くなっているので、なんとかその流れに乗って、どう変化していくのかを味わいたいところです。

このプレゼンで書いてるように、もうあと4年以内できっと僕の能力を超えられてると思っているので…

GKE内のpostgresをGUIで触りたい

GKEのpostgresの中身を確認したいとき、一旦アプリケーションのpodのshellに入って、そこからpsqlコマンド叩いて接続してSQL叩いて、という方法で見ていました。

が、さすがにだるすぎるので、普通に簡単にGUIで見れる方法があるだろうとGPT-4様に聞いてみました。
kubectlでポートフォワード設定出来るので、ポートフォワードしてそこに繋げばいいとのこと。

kubectl port-forward svc/postgres-service 15432:5432

これでGKE内のpostgresのポート「5432」→ ローカルのポート「15432」へポートフォワードしてくれるとのこと。

でまあこれで用は足せるのですが、実は普段からk9sを使っているので、k9sを使ってもできることがわかりました。

k9sを起動して、serviceとかpodの表示をしていると上部エニューに
「<shift-f> Port-Forward」
と出てくるので、postgresのサービスやpodの上で S-f 押すと、ポートフォワードの設定画面が出るので適当に好きなフォワード先のポートを指定します。

それだけです。

これだけのことなのですが、GKE内のデータ確認の心理的めんどくささがだいぶ減りました。

Windows Update後にWSL2からXの画面表示が崩れる

WSL2で動かしているアプリのSQLite3のデータを確認するのに、WSL2上からsqlitebrowserを動かして見ていたのだけど、今日Windows Updateを掛けたら、画面がすごく崩れるようになってしまいました。

似たようなことを以前、Sourcetreeで経験していて、GPUのハードウェアアクセラレーションのせいだろうという検討が付いていたので、WSLgの設定でアクセラレーションを切れば良さそうと思いました。

ただこの件ってすごくググラビリティが低いんですよね。
「X」と「window」なのでそっちではぜんぜん該当する情報にたどり着けず。
で、WSL2から使われているのが「WSLg」だというところからググって、以下のページにたどり着けました。

github.com

というかこのくらいしか情報がない。

C:\Users\[your user name]\.wslgconfig (※「wsl」ではなく「wslg」であることに注意)

[system-distro-env]
;disable GPU in system-distro
;(must be disabled in user-distro as well, exporting this env.)
LIBGL_ALWAYS_SOFTWARE=1

これだけ設定して、WSL2の再起動

wsl --shutdown

これで無事、画面崩れが出なくなりました。

GKEでdocker push出来ない問題

GKEを使っていて、docker imageをdocker buildで作るところまでは良かったのですが、docker pushしようとすると権限がないと言われてしまってどうしてもpushできない、という問題にはまりました。

denied: Permission "artifactregistry.repositories.uploadArtifacts" denied on resource "projects/example/locations/asia-northeast1/repositories/example" (or it may not exist)

権限自体はオーナーになっているためフルで割り当てられているのにどうして…?となっていました。
オーナー権限があるため、リポジトリの登録なんかは問題なく出来てしまいます。


でもやはり権限の問題でした。

エラーメッセージから検索してこちらの方のエントリーでわかりました。

www.pospome.work


dockerイメージをpushする前に、リポジトリ認証の設定が必要で、それはGKEのイメージをpushする先のホスト毎に必要なのに、それをやっていませんでした。

https://cloud.google.com/artifact-registry/docs/docker/store-docker-container-images?hl=ja#auth

イメージを push または pull する前に、Google Cloud CLI を使用して Artifact Registry に対するリクエストを認証します。


リージョン us-central1 の Docker リポジトリの認証を設定するには、次のコマンドを実行します。

$ gcloud auth configure-docker us-central1-docker.pkg.dev


自分はてっきり、

$ gcloud auth configure-docker

すると、gcr.ioとかstaging-k8s.gcr.ioとかのcredHelpersが表示されて

gcloud credential helpers already registered correctly.

と言われるので、もう必要な設定できているのだと思っていました。


が、これだけだとダメで、例えば「asia-northeast1-docker.pkg.dev」へpushするのなら

$ gcloud auth configure-docker asia-northeast1-docker.pkg.dev

として使うGKEのホストを登録してやらないとダメなのでした。

Docker内からflask dbでPostgresを使いたいときにエラー

それまでflask-sqlalchemyからSQLite使ってテスト的に動かしていたものを、Postgresに変更しようとしていました。

それ自体は問題なかったのですが、Dockerから使っていてコンテナ内からコマンドで「flask db …」を使おうとすると、エラーが出るようになってしまったのです。


flask dbからPostgresを動かすために「psycopg2」というライブラリが必要とされるらしいのですが、これをビルドする際に必要なライブラリが必要とされていて、そこで引っかかるようでした。
その依存はどこかで自動で入れて欲しい…


なかなか情報がなくて厳しかったのですが、こちらのエントリーが大変参考になりました。

qiita.com

こちらでは

を入れれば大丈夫だったようですが、gccはすでに入っていたのにだめで、エラーでは「clang」がない、と言われたのでこっちを入れることにしました。

Dockerfileでaptでインストールしているところで

apt-get install libpq-dev clang

を追加しました。

その上で「pycopg2」をインストールします。

rye add pcysopg2

して、pyproject.tomlのdependenciesに下記を追加しました。

    "psycopg2>=2.9.9",

これでやっとこDocker内でflask db …でPostgresも触れるようになりました。

llama-indexのopenai 1.x系への対応

Pythonでllama-indexを使っているのですが、開発環境からテスト環境へ移して実行しようとしたところ、SimpleNodeParserのところで、以下のようにエラーが発生しました。

    node_parser = SimpleNodeParser.from_defaults(text_splitter=text_splitter)
                  ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
TypeError: SentenceSplitter.from_defaults() got an unexpected keyword argument 'text_splitter'

pyproject.tomlに

dependencies = [
    "openai>=0.28.0",
    "llama-index>=0.8",
...

という感じに書いていたため、openaiが1.3.xに、llama-indexが0.9.xになっており、llama-index 0.9系だと動かないようです。

そこでllama-indexを0.8のままにしておくよう、以下のように「<0.9」の指定を追加してやることでこのエラーは回避しました。

dependencies = [
    "openai>=0.28.0",
    "llama-index>=0.8, <0.9",
...

しかし今度はopenaiが1.xだと古い使い方だと動かないと言われました。

openai.lib._old_api.APIRemovedInV1:

You tried to access openai.Completion, but this is no longer supported in openai>=1.0.0 - see the README at https://github.com/openai/openai-python for the API.

You can run `openai migrate` to automatically upgrade your codebase to use the 1.0.0 interface.

Alternatively, you can pin your installation to the old version, e.g. `pip install openai==0.28`

A detailed migration guide is available here: https://github.com/openai/openai-python/discussions/742

github.com

今後Assistant APIとか使うことを考えると、openaiは早めに1.xに移行しておきたいところです。
しかし実はすでに他のコードは1.xに移行しており、これはllama-indexの中で発生しているエラーでした。

ちなみにどのバージョンからllama-indexがopenai 1.xに対応したのだろう?と思って調べてみたところ、0.8.5x台までは

openai = ">=0.26.4"

だったのが、
2023/11/8 の 0.8.64 から

openai = ">=1.1.0"

となっていました。
なので0.9.xからというわけではなく、0.8.xの途中からopenai 1.x系への対応がされたようです。

ただ今後のことを考えると、なんにしても0.8.xから0.9.xへの移行をしといたほうが良さそうに思いました。
で0.8->0.9への移行の情報を探したところnpakaさんの記事がありました。
note.com

ここの「4. ノード解析・テキスト分割・メタデータ抽出のインターフェース変更」のところに、これまでの一旦「SimpleNodeParser」を作る方法から変更されたことが書いてありました。

これまでの「0.8.x」の場合

node_parser = SimpleNodeParser(
    text_splitter=SentenceSplitter(chunk_size=512)
)
nodes = node_parser.get_nodes_from_documents(documents)


今後「0.9.x」の場合

node_parser = SentenceSplitter(chunk_size=512)
nodes = node_parser(documents)

このため、これまでnode_parserを入れたSimpleNodeParserを生成していた部分を、単にそのままこれまで使っていたSentenceSplitterを入れることで動くようになりました。

Outlookのメール送受信で0x8004010Fのエラーになる

Outlookのメール送受信をしようとすると「0x8004010F」のエラーが出てメール送受信が出来ない、という相談を受けました。
なにかやったわけではなく突然なったということでした。

これぐぐると、やばそうな障害だな…というのがわかります。

電子メールの送受信時にエラー 0x8004010F が表示される - Outlook | Microsoft Learn https://learn.microsoft.com/ja-jp/outlook/troubleshoot/synchronization/error-0x8004010f-when-sending-or-receiving-emails

つまりOutlookのDBファイルにアクセスできなくなった場合に出るエラーです。
しかし確認したところ、メール自体は表示されるため、まったくファイルへアクセス出来ない状況、というわけではありませんでした。
また設定自体も問題なく、またディスク容量も問題なくて、ファイルも壊れてはなさそうでした。

じゃあ逆になにが問題なんだ??となって色々調べてたのですがよくわからず、でもExploreでファイルを見てみたときにOneDriveの同期中になったままになっていることに気が付きました。
なにかでかい変更があってファイルの同期に時間がかかってる?と思って確認すると、OneDrive側の容量が足らなくなっていて同期ができない状況になっていることがわかりました。
このアカウントはなぜかMicrosoft365のアカウントではなく、無料の個人アカウントになっており、そのため容量が5Gになっていたので上限に達していたようです。

Microsoft365のアカウント自体はあったので、そちらのほうをOneDriveに登録し直して、OneDriveにあったデータもすべて移行して、そちらを参照するようにOutlookの設定も変更しました。
これでちゃんと送受信ができるようになりました。

Outlookの送受信ができないというエラーで、OneDriveの容量が足らないのが理由、というのはなかなか気が付きにくいです…

Flaskの稼働URLにディレクトリ名を指定する

flaskのアプリで、例えば開発用を /dev 以下に、デモ用を /demo 以下で動かしたいと思ったのでした。
これはたぶん標準機能ですぐ出来るんだろうなと思って検索したところ、flaskの起動時に環境変数「SCRIPT_NAME」でディレクトリ名を与えてやれば出来るっぽいと見かけました。…が、できない

こういう機能はどうも blueprint というモジュール使えば出来るようです。

が、なんでSCRIPT_NAME指定でダメなんだろう?と調べました。
するとやはりflask単体だとうまく行かず、gunicornから起動だとこの設定が出来るという記述がありました。

dlukes.github.io

実際に本番稼働させるには gunicorn で動かす予定でいたため、gunicornで試したところ「SCRIPT_NAME」を与えてやることで指定したディレクトリ以下で動かすことが出来ました。

werkzeugでurl_decodeのエラーが発生する

Pythonでflask_loginを使っているアプリで、下記のエラーが発生した。

ImportError: cannot import name 'url_decode' from 'werkzeug.urls'

werkzeug.urlsなんてimportしてないのになんで??と思ったら、どうもflask_loginで呼ばれているようだった。
そして、werkzeug.urlsがv3.0以降でurl_decodeがなくなっているのに、まだflask側での対応がされていないため、このエラーが発生するとのことだった。

stackoverflow.com


そこで以下のようにpyproject.tomlで、werkzeugのバージョンを2の最終の2.3に固定して、flaskを2.3以降にすることで対応できた。

"Werkzeug==2.3.7",
"flask>=2.3.3",
"flask-login>=0.6.2",

ただし、すでにwerkzeugが3が入っているとだめなので、一旦Werkzeugやflaskを外してsyncして、再度上記の依存を記述してsyncすることで対応できた。

最終的に入ったバージョンは以下の通り。

Flask==2.3.3
Flask-Login==0.6.3
Werkzeug==2.3.7

WSL2上のSQLiteデータをGUIで確認したい

WSL2上でSQLite使っているとき、簡単にデータのブラウズをしたくて、MySQL WorkbenchみたいにGUIで確認出来たらいいのにな、と思いました。
で、そういう用途はDB Browser for SQLite(sqlitebrowser)を使えば良いようです。

が、普通にWindows版のsqlitebrowserを入れてすんなり動いたのですが、WSL2上のファイルを指定するとロックされてるから見れない、と言われてしまいました。
読み取り専用で読み込もうとしてもダメ。

ChatGPT-4様に聞いてみると、WSL2上のファイルはダメだから一旦Windowsファイルシステム上へコピーすれば見れるよ、とのこと。
確かに試してみると、コピーしただけで見れるようになりました。

…が、さすがにこれはめんどくさすぎる。

最近のWSL2だとデフォルトでGUIというかWindows側でXが動くようになってて、GUIのものが使えるようになっています。
なのでWSL2にLinux用のsqlitebrowserを入れてみました。
単にapt installで入ります。

sudo apt install sqlitebrowser fonts-ipafont

WSL2上のsqlitebrowserだと問題なくDBのファイルを指定して中身を見ることができました
ただフォントが入っていないと日本語が全部「□」になってしまったため、ipafontも入れたところ問題なく表示できるようになりました。