Paperspaceで実行するStable DiffusionからEagle連携機能を使って生成画像を自動投稿する実験


実験の経緯


Paperspaceを使って、画像生成を行っている方も増えていると思います

また「Eagle」を使って生成画像を管理してたり、Stable Diffusionの拡張機能である「Eagle-pnginfo」を使って生成した画像をEagleに送る機能を使って、タグやプロンプトを閲覧管理している方も多いと思います。

「Eagle-pnginfo」の設定項目に、「Outside Eagle server connection (url:port)」とあるので、外部アクセスもできるんだ〜
と思いきや、うまくいかず、そう単純ではなかったので、実現までの流れを記載します

*結果については、自己責任でお願いします

何故単純ではなかったのか?

 Eagleの画像管理ソフトは、macとWindowsのインストール型アプリケーションで、実行すると、PC内でサーバを立ち上げ、デフォルトのポート番号「41595」を使ってAPIを提供しています。
*要するにEagle以外のソフトで、プログラミングができれば、画面操作しなくても画像追加したり色々操作できます。

 Eagle-pnginfoは、Stable Diffusionの拡張機能として、上記のAPIを使って、自動投稿する仕組みになっています。

「Outside Eagle server connection (url:port)」の設定項目に触れている他の記事を見つけることが出来ていませんが、ほぼ「何を記載するか分からなければ空欄で…」と記載しているのがほとんどです。

 この項目が「空欄」である場合は、同一PCで、Stable DiffusionとEagleが動いていれば連携します!という意味です。

 公開しているGitのREADME.ja.mdでは

サーバアドレスを以下の形式で入力してください http://<server_ip>:<port>

 となっており、IPアドレスとポート番号をコロン「:」で区切り、スキーマとして「http://」を指定してくださいとなっております。
 従って、IPアドレスが分かって入れば、他のネットワークに存在するEagleが動いているPCに画像を投稿できると解釈できます。

 ところが、Paperspaceの場合だと、サービスは、プライベート空間であり、IPアドレスが分かりません。

*ここから戦いの始まり

どう対応したのか?

IPアドレスがわかるように公開する必要がある

 まず、Eagleはmacとwindowsでソフトを提供しているため、サーバとして設定するためには、自宅PCを外部からアクセスできるように公開しなければなりません。そのためにはIPアドレスを固定にしなくちゃ!とかルータの設定でポートを解放とか、いちいち面倒だし、外部公開は危険

 「ngrok」というサービスを使えば、自宅PCの特定ポートを外部公開してくれて、ngrokがランダム生成したドメイン名を付与してくれるので、そのドメイン宛にAPIをリクエストできれば、実現できる

 と思ったが、Eagle-pnginfoでは、IPアドレスの指定になっており、試しに「Outside Eagle server connection (url:port)」の項目へ、ngrokのドメイン名を指定してみたが、接続できなかった

Eagle-pnginfoの改造

 何故できなかったのか、コードを見ると
「stable-diffusion-webui/extensions/sdweb-eagle-pnginfo/scripts/api_util.py」

def get_url_port(server_url_port=""):
    if not server_url_port or server_url_port == "":
        return None, None
    o = urlparse(server_url_port)
    _url = f"http://{o.hostname}"
    if o.hostname != "localhost":
        _ip = ipaddress.ip_address(o.hostname)
        if _ip.version == 6:
            _url = f"http://[{o.hostname}]"
    port = o.port
    return _url, port

 となっており、設定で指定したURLを解析し、「http://」を固定でつけており、IPアドレスかどうかをしっかりチェックする仕様になっている。
 ngrokは、暗号化に対応しているため、「https://」とする必要があり、IPアドレスではなく、ドメイン名である
 そこで、下記に書き換えた

def get_url_port(server_url_port=""):
    if not server_url_port or server_url_port == "":
        return None, None
    o = urlparse(server_url_port)
    _url = f'{o.scheme}://{o.hostname}'
    port = o.port
    return _url, port

こうすることで、設定したURLがngrokのドメイン名でも可能となります
*コード改変するので、自己責任&コードの意味を理解して使ってください

設定方法

Eagle-pnginfoの設定方法については、詳しく解説はしませんが、「Outside Eagle server connection (url:port)」の設定内容例を記載します

https://XXXXXXXX.ngrok-free.app:443

XXXXXXXX部分は、ngrokが生成したランダムなドメイン名
ポート番号は、SSL暗号化しているので、443がデフォルトです

おわりに

 ある程度、知識がある方向けに記載していますので、ngrokって?Eagleって?Eagle-pnginfoって?という方は、ネット上には沢山の解説が出ていますので、是非調べてみてください
 また、試す場合は、下記の点をご理解いただいた上で、実験してみてください

  • ngrokで特定のポートを外部公開するので攻撃される危険性がある

  • Paperspace上で画像生成した場合、生成画像投稿のため外部通信が発生し、生成スピードが落ちる

  • コード改変などを伴いますので、戻せなくても自己責任で(バックアップを必ず取る)


いいなと思ったら応援しよう!