お知らせ

現在サイトのリニューアル作業中のため、表示が崩れているページが存在することがあります。

Web開発をしていると取り敢えずHTTPリクエストが取れる雑なモックサーバーが欲しくなることがあるので、その作り方。

確認環境

Env Ver
OS Windows 11 Pro
WSL2 -
Distoribution Ubuntu 20.04.4 LTS
PHP 8.0.29
nginx 1.18.0

作り方

  1. Windows側の hosts127.0.0.1 mock-server.test を追加
  2. /etc/nginx/conf.d に以下の設定ファイルを置く
server {
  listen       80;
  client_max_body_size 100m;
  server_name  mock-server.test;
  access_log   /var/log/nginx/mock-server.access.log;
  error_log    /var/log/nginx/mock-server.error.log;


  location ~ ^/.*$ {
    rewrite ^/.*$ / break;
    # リクエストパスの確認用
    proxy_set_header X-Request-Path $request_uri;
    proxy_pass  http://127.0.0.1:8888;
  }
}
  1. sudo service nginx restart
  2. モックサーバーのコードを書いて適当な場所に置く
<?php

$server_json = json_encode($_SERVER);

file_put_contents('log', "$server_json\n", FILE_APPEND);
  1. php -S localhost:8888
  2. http://localhost:8888/hoge にアクセスしログファイルに追記されることを確認
  3. おわり

おまけ

$_SERVER の中身をフィルタしたい時

<?php

$ignoreKeys = [
    'DOCUMENT_ROOT',
    'REMOTE_ADDR',
    'REMOTE_PORT',
    'SERVER_SOFTWARE',
    'SERVER_PROTOCOL',
    'SERVER_NAME',
    'SERVER_PORT',
    'REQUEST_URI',
    'SCRIPT_NAME',
    'SCRIPT_FILENAME',
    'PHP_SELF',
    'HTTP_HOST',
    'HTTP_CONNECTION',
    'HTTP_UPGRADE_INSECURE_REQUESTS',
    'HTTP_USER_AGENT',
    'HTTP_ACCEPT',
    'HTTP_ACCEPT_ENCODING',
    'HTTP_ACCEPT_LANGUAGE',
    'HTTP_CACHE_CONTROL',
    'REQUEST_TIME_FLOAT',
    'REQUEST_TIME'
];

$buff = array_filter($_SERVER, function($key) use($ignoreKeys) {
    return !in_array($key, $ignoreKeys);
}, ARRAY_FILTER_USE_KEY);

$server_json = json_encode($buff);

file_put_contents('log', "$server_json\n", FILE_APPEND);

HuskyとはNode.jsを利用した開発で非常によく使われているGit hooksのユーティリティだが、個人的にはこのツールの存在価値に疑問を感じている。

という訳で、この記事ではHuskyのメリデメを考えた結果と、Huskyが何をしているか、Huskyの必要性について書いてゆく。

Huskyがあるメリット

Huskyは極めて有名なツールであるため、Huskyが入っているとこのプロジェクトはGit hooksで管理されており、標準化されていることが確認できるだろう。恐らくHuskyのメリットはこれ以外に存在しないと考えている。

Huskyがあるデメリット

Huskyの管理をしないといけない、Huskyも地味にアップデートするからだ。これは明確なコストである。

そしてHuskyのコードやリポジトリを見たことがある人は多分ほとんどいないと思う。更に言えばHuskyが何をしているかすらも知らない人だっているはずだ。そんな得体の知れないものを使うのは怖いというところだ。

Huskyは何をしているか?

端的に言えばGit hooksのパスを .husky/ に設定しているだけである。
要するに git config core.hooksPath .husky を叩いているだけだ。
もう少し細かく言えば以下に相当する処理を実行している。

mkdir -p .husky/_
cp husky.sh .husky/_
git config core.hooksPath .husky

勿論、ソースコードには他の処理も書かれているのだが、実質的には上記三行が全てと言って良い。

husky.sh を活用しているケースがどれほどあるか怪しいことを考えると、本質は git config core.hooksPath .husky だと思うので、正直あるだけ邪魔では?と考えている。

Huskyの必要性

ここまででHuskyがしていることは git config core.hooksPath .husky だということが解ったが、だとしたらHuskyは本当に必要なのだろうか?私は特に理由がないのであれば package.jsonhusky install と書いてあるところに git config core.hooksPath .githooks とでも書いておけば良いのではないか?と思っている。恐らく何も不都合はないはずだ。

ただ世の中には色々な事情があり、使わざるを得ないケースもあると思う。しかし、可能であれば排除してもいいのではないか?個人的にはそう思っている。

何故この記事を書いたか

「この世からHuskyを滅ぼすため」というのはまぁ冗談だが、個人的にHuskyの存在価値があまり良くわかっておらず、多分世間の人もあまり理解できていないと勝手に考えていて、可能であればプロジェクトに入れたくないと考えているので、そのお気持ち表明というか、そんな感じだ。

Huskyのスポンサー

ここからは余談だが、Huskyには結構な数のスポンサーが付いていて、恐らく毎月それなりの収入があると思われる。以下はHuskyのスポンサーである。

個人的にHuskyは最も成功したOSSの一つではないかと考えている。理由としてHusky自体は非常に単純なプロダクトであり、コミット履歴を見てもさしたるメンテナンスがされておらず、ほぼ手放しで維持されていると思われるからだ。

しかし、Huskyはそれなりの額の寄付を集めており、この記事を書いた時点で確認できるだけでも最低 10USD * (4 + 16) + 100USD * (4 + 2) の寄付がされており、つまり800USD、日本円にして11.2万円ほどだ。何もしてないのに毎月この収入があるのは大分ありがたいだろう。他のOSSならIssueやPull Requestsに対して対応したり、コード本体のメンテナンスがあるはずだが、Huskyにそんなものはないため、プロダクトの維持コストに対して非常によく寄付を集められていると感じる。

事前準備

事前に必要なコンポーネントをインストールしておく

セットアップコマンド

MSYS2などのPOSIX互換レイヤー上のシェルで動かすことを想定

# get Stable Diffusion web UI
git clone https://github.com/AUTOMATIC1111/stable-diffusion-webui.git

# get extentions
git clone https://github.com/nolanaatama/sd-webui-tunnels stable-diffusion-webui/extensions/sd-webui-tunnels
git clone https://github.com/Mikubill/sd-webui-controlnet stable-diffusion-webui/extensions/sd-webui-controlnet
git clone https://github.com/fkunn1326/openpose-editor stable-diffusion-webui/extensions/openpose-editor
git clone https://github.com/yfszzx/stable-diffusion-webui-images-browser stable-diffusion-webui/extensions/stable-diffusion-webui-images-browser
git clone https://github.com/DominikDoom/a1111-sd-webui-tagcomplete stable-diffusion-webui/extensions/a1111-sd-webui-tagcomplete
git clone https://github.com/Bing-su/dddetailer stable-diffusion-webui/extensions/dddetailer
git clone https://github.com/mcmonkeyprojects/sd-dynamic-thresholding stable-diffusion-webui/extensions/d-dynamic-thresholding

# make resource dirs
mkdir -p stable-diffusion-webui/models/ESRGAN/
mkdir -p stable-diffusion-webui/models/Lora/
mkdir -p stable-diffusion-webui/models/VAE/
mkdir -p stable-diffusion-webui/models/hypernetworks/
mkdir -p stable-diffusion-webui/extensions/sd-webui-controlnet/models/

# get controlnet
curl -Lo stable-diffusion-webui/extensions/sd-webui-controlnet/models/t2iadapter_canny_sd14v1.pth https://huggingface.co/TencentARC/T2I-Adapter/resolve/main/models/t2iadapter_canny_sd14v1.pth
curl -Lo stable-diffusion-webui/extensions/sd-webui-controlnet/models/t2iadapter_color_sd14v1.pth https://huggingface.co/TencentARC/T2I-Adapter/resolve/main/models/t2iadapter_color_sd14v1.pth
curl -Lo stable-diffusion-webui/extensions/sd-webui-controlnet/models/t2iadapter_depth_sd14v1.pth https://huggingface.co/TencentARC/T2I-Adapter/resolve/main/models/t2iadapter_depth_sd14v1.pth
curl -Lo stable-diffusion-webui/extensions/sd-webui-controlnet/models/t2iadapter_keypose_sd14v1.pth https://huggingface.co/TencentARC/T2I-Adapter/resolve/main/models/t2iadapter_keypose_sd14v1.pth
curl -Lo stable-diffusion-webui/extensions/sd-webui-controlnet/models/t2iadapter_openpose_sd14v1.pth https://huggingface.co/TencentARC/T2I-Adapter/resolve/main/models/t2iadapter_openpose_sd14v1.pth
curl -Lo stable-diffusion-webui/extensions/sd-webui-controlnet/models/t2iadapter_seg_sd14v1.pth https://huggingface.co/TencentARC/T2I-Adapter/resolve/main/models/t2iadapter_seg_sd14v1.pth
curl -Lo stable-diffusion-webui/extensions/sd-webui-controlnet/models/t2iadapter_sketch_sd14v1.pth https://huggingface.co/TencentARC/T2I-Adapter/resolve/main/models/t2iadapter_sketch_sd14v1.pth
curl -Lo stable-diffusion-webui/extensions/sd-webui-controlnet/models/t2iadapter_style_sd14v1.pth https://huggingface.co/TencentARC/T2I-Adapter/resolve/main/models/t2iadapter_style_sd14v1.pth
curl -Lo stable-diffusion-webui/extensions/sd-webui-controlnet/models/control_v11e_sd15_ip2p.pth https://huggingface.co/lllyasviel/ControlNet-v1-1/resolve/main/control_v11e_sd15_ip2p.pth
curl -Lo stable-diffusion-webui/extensions/sd-webui-controlnet/models/control_v11e_sd15_shuffle.pth https://huggingface.co/lllyasviel/ControlNet-v1-1/resolve/main/control_v11e_sd15_shuffle.pth
curl -Lo stable-diffusion-webui/extensions/sd-webui-controlnet/models/control_v11f1e_sd15_tile.pth.pth https://huggingface.co/lllyasviel/ControlNet-v1-1/resolve/main/control_v11f1e_sd15_tile.pth.pth
curl -Lo stable-diffusion-webui/extensions/sd-webui-controlnet/models/control_v11f1p_sd15_depth.pth https://huggingface.co/lllyasviel/ControlNet-v1-1/resolve/main/control_v11f1p_sd15_depth.pth
curl -Lo stable-diffusion-webui/extensions/sd-webui-controlnet/models/control_v11p_sd15_canny.pth https://huggingface.co/lllyasviel/ControlNet-v1-1/resolve/main/control_v11p_sd15_canny.pth
curl -Lo stable-diffusion-webui/extensions/sd-webui-controlnet/models/control_v11p_sd15_inpaint.pth https://huggingface.co/lllyasviel/ControlNet-v1-1/resolve/main/control_v11p_sd15_inpaint.pth
curl -Lo stable-diffusion-webui/extensions/sd-webui-controlnet/models/control_v11p_sd15_lineart.pth https://huggingface.co/lllyasviel/ControlNet-v1-1/resolve/main/control_v11p_sd15_lineart.pth
curl -Lo stable-diffusion-webui/extensions/sd-webui-controlnet/models/control_v11p_sd15_mlsd.pth https://huggingface.co/lllyasviel/ControlNet-v1-1/resolve/main/control_v11p_sd15_mlsd.pth
curl -Lo stable-diffusion-webui/extensions/sd-webui-controlnet/models/control_v11p_sd15_normalbae.pth https://huggingface.co/lllyasviel/ControlNet-v1-1/resolve/main/control_v11p_sd15_normalbae.pth
curl -Lo stable-diffusion-webui/extensions/sd-webui-controlnet/models/control_v11p_sd15_openpose.pth https://huggingface.co/lllyasviel/ControlNet-v1-1/resolve/main/control_v11p_sd15_openpose.pth
curl -Lo stable-diffusion-webui/extensions/sd-webui-controlnet/models/control_v11p_sd15_scribble.pth https://huggingface.co/lllyasviel/ControlNet-v1-1/resolve/main/control_v11p_sd15_scribble.pth
curl -Lo stable-diffusion-webui/extensions/sd-webui-controlnet/models/control_v11p_sd15_seg.pth https://huggingface.co/lllyasviel/ControlNet-v1-1/resolve/main/control_v11p_sd15_seg.pth
curl -Lo stable-diffusion-webui/extensions/sd-webui-controlnet/models/control_v11p_sd15_softedge.pth https://huggingface.co/lllyasviel/ControlNet-v1-1/resolve/main/control_v11p_sd15_softedge.pth
curl -Lo stable-diffusion-webui/extensions/sd-webui-controlnet/models/control_v11p_sd15s2_lineart_anime.pth https://huggingface.co/lllyasviel/ControlNet-v1-1/resolve/main/control_v11p_sd15s2_lineart_anime.pth

# get embeddings
curl -Lo stable-diffusion-webui/embeddings/badhandv4.pt https://civitai.com/api/download/models/20068
curl -Lo stable-diffusion-webui/embeddings/EasyNegative.pt https://huggingface.co/datasets/gsdf/EasyNegative/resolve/main/EasyNegative.pt

# get model
# upscaler
curl -Lo stable-diffusion-webui/models/ESRGAN/4x-UltraSharp.pth https://huggingface.co/nolanaatama/ESRGAN/resolve/main/4x-UltraSharp.pth
curl -Lo stable-diffusion-webui/models/ESRGAN/TGHQFace8x_500k.pth https://huggingface.co/dwnmf/deliberatev2/resolve/main/TGHQFace8x_500k.pth

# model
curl -Lo stable-diffusion-webui/models/Stable-diffusion/AOM3A1B_orangemixs.safetensors https://huggingface.co/WarriorMama777/OrangeMixs/resolve/main/Models/AbyssOrangeMix3/AOM3A1B_orangemixs.safetensors

# vae
curl -Lo stable-diffusion-webui/models/VAE/orangemix.vae.pt https://huggingface.co/WarriorMama777/OrangeMixs/resolve/main/VAEs/orangemix.vae.pt
curl -Lo stable-diffusion-webui/models/VAE/kl-f8-anime2.ckpt https://huggingface.co/hakurei/waifu-diffusion-v1-4/resolve/main/vae/kl-f8-anime2.ckpt

起動コマンド

dddetailerの依存ライブラリインストールで初回起動はかなり時間が掛かるので気長に待つ。

./webui-user.bat

設定

  1. Settings -> User Interface
  2. Quicksettings listに以下を追加
    • , sd_vae, CLIP_stop_at_last_layers
投稿日:ソフトウェア::Stable Diffusion技術::AI

Colab Proとローカルマシンでどのくらい差が出るか簡単にベンチマークしてみたのでその結果です。

レンダリング条件

今回は以下の設定で回した結果を比較します。前回と同じです。

設定画面

ColabProでのNotebookは以下を使いました。

https://gist.github.com/Lycolia/cb432ad1b1ce083482b5487c131b5d12/80a059931c538b10d55cf9fcbf82220f24e64653

設定値は以下の通りです。

設定
Propmpt (illustration:1.0), masterpiece, best quality, 1girl, solo, happy, smile, theater, (perspective:1.3), from below, (looking away:1.2), (from side:1.0), {{shot_hair}}, smile, bangs, shaggy, (brown hair:1.1), swept_bangs, thick_eyebrows, skin_fang, closed mouth, {{purple eyes}}, gray {{jacket}}, white shirt, glasses, {{small breasts}},
Negative Prompt nsfw, (worst quality, low quality:1.4), (depth of field, blurry, bokeh:1.5), (greyscale, monochrome:1.0), multiple views, text, title, logo, signature, (tooth, lip, nose, 3d, realistic:1.0), dutch angle,(cropped:1.4), text, title, signature, logo, (loli:1.2), school satchel, pink, school bag, school uniform, from behind
Model AOM3A1B
VAE orangemix.vae.pt
Sampleing method Euler a
Sampleing steps 20
Width 512px
Height 512px
Batch count 1
Batch size 1
CFG Scale 7
Seed -1

ローカルマシンのスペック

Local 1

機材 内容 備考
OS Windows 11 Pro
M/B ASUS ROG STRIX Z390-F GAMING PCIe 3.0
CPU Intel Core i9-9900
GPU GeForce RTX 4070 Ti
MEM DDR4-3200 16GB * 4

Local 2

PCIeのバージョンを上げるとベンチスコアが伸びると聞いたので試してみた

機材 内容 備考
OS Windows 11 Pro
M/B ASUS TUF GAMING Z790-PLUS D4 PCIe 5.0
CPU Intel Core i7 13700
GPU GeForce RTX 4070 Ti
MEM DDR4-3200 16GB * 4

ベンチマーク結果

Colabは時間帯によって処理時間が変わるので2点計測しています。

4070 TiがColabProに大きく勝る結果となりました。UIの安定性や応答性でも体感ColabProを大きく上回り、ローカルストレージに出力結果や環境を溜め込み続けられる利便性があったり、起動速度に雲泥の差があったり、設定を記憶できたり、ローカルで動かせるならそれが一番楽だと感じました。

Colab Proは4:30と23:00に計測しています

グラボはZOTAC GAMING GeForce RTX 4070 Ti Trinity OCを使っていますが、発熱も60度くらいに収まるのでぼちぼち悪くないかなと思ってます。

おまけ

今回もベンチマーク中に生成された画像を何枚かピックアップして載せておきます

おまけ2

ローカルだと気楽に作れるのでサッと作ってみた高品質版

設定値は以下の通りです。

設定画面

設定
Propmpt (masterpiece, sidelighting, finely detailed beautiful eyes: 1.2), masterpiece*portrait, realistic, 3d face, glowing eyes, shiny hair, lustrous skin, (brown hair:1.1), short hair, smile, 1girl, embarassed, small breasts, theater, thick eyebrows, closed mouth, {{purple eyes}}, gray {{jacket}}, {{{{white shirt}}}}, glasses, {{small breasts}
Negative Prompt {{{{{{{nsfw}}}}}}, (worst quality, low quality:1.4), (depth of field, blurry, bokeh:1.5), (greyscale, monochrome:1.0), multiple views, text, title, logo, signature, (tooth, lip, nose, 3d, realistic:1.0), dutch angle,(cropped:1.4), text, title, signature, logo, (loli:1.2), school satchel, pink, school bag, school uniform, from behind
Model AOM3A1B
VAE orangemix.vae.pt
Sampleing steps 32
Sampleing method DPM++ SDE Karras
CFG Scale 7
Width 512px
Height 756px
Clip skip 2
Seed -1

ブートドライブの交換をする時に色々やったので、その記録です。メインはM2SSDの固着ネジの取りはずしです。

内容としてはCrucial P1 CT500P1SSD8JPSolidigm P44 Pro SSDPFKKW020X7X1に更新しました。

Solidigm P44 Pro SSDPFKKW020X7X1

既存SSDの抜去

交換するために既存のSSDを取り外す必要があったのですが、まずここでハマりました。何故かというと、ネジが固着してて回らないんですね…。そしてネジ穴が潰れて終わりました。しかし外せないと困るのでいくつか試してみました。

まずはネジすべり止め液。これを使えばネジ穴が潰れていてもたちまちネジが回るのだとか!

先端部が細くなっていて、ネジ穴だけに上手く差せそうですが実際はM2SSDのネジだと溢れました。ザラザラしてて取り除くのがやや面倒なのでマザボにはこぼさないほうがいいと思います。サラサラしてて割とドバッと出ます。

300円でネジが抜けるなら安いものだと思って買ったネジすべり止め液
液が出る先端部

ネジすべり止め液を差してみたところ。SSDの基板に掛かっていますがとりあえず無事でした。結局これは効果がなく、次の手を探ることに…。

期待も虚しく効果なし

そこで見かけたのが、なめたネジはずし精密用 なめたネジはずし精密用ハンドル付M1~2.6 No.3610-N)。これなら基板にダメージを与えずにネジを取り去れそうですが、近くに売っているところがなく断念しました。

次に浮かんだのがネジを外す道具として定評のあるネジザウルスです。ネジを掴んで回すのでネジ穴が潰れてても原理上問題ありません。ただ、背の低いM2SSDのネジを掴めるのかと、回してる時に基板をこすって壊さないかが心配でしたが、外せないとどうしようもないですし、試してみないことには解らないということもあり、一か八かの掛けで試してみることにしました。幸いこいつはヨドバシにあったのでその日のうちに買いに行きました。(翌日まで待つとかできない!

神戸に住んでるので頑張って梅田まで出張って買ってきました。(しかし、この後買い忘れに気づきもう一回行くハメに…

神戸から梅田までは30分くらいです

という訳でネジザウルスを買ってきました。

期待のネジザウルス、きっとこれなら外れてくれるはず

結果としてはM2SSDのネジの頭を掴むことができ、特に基板にダメージも与えずネジを外すことができたので良かったです。

外れた!
これでM2SSDを交換できる…。長い旅だった…。

ブートドライブのクローン

今使ってるマザボはM2SSDスロットが2つあり、片方がブートドライブになっているため、ドライブをクローンして新しいドライブをブートドライブとして使えるようにしていきます。残念ながらフリーのクローンソフトにめぼしいのがなかったのとDDコマンドを使ってまでやる気が出なかったので、かつてお世話になったAcronis True Imageの後継ソフトであるAcronis Cyber Protect Homeを頼ることにしました。

手順は簡単でツール → ディスクのクローンの作成を選び、表示されるウィザードに沿って進めるだけです。

クローンメニューはバックアップでなくツールの方にある

日本語が怪しくてやや分かりづらいですが一番上のやつで行けました。

翻訳がイマイチで日本語が分かりづらい…

NVMeSSDからNVMeSSDへのクローンだったので体感30秒くらいで終わりました。

NVMe SSDからNVMe SDDへのクローンは爆速でした

この後は新M2SSD抜去 → 元々差していたM2SSDを挿入 → 元々のブートM2SSDを抜去 → 新M2SSDに置換という手順で更新を完了しました。M2SSDの交換はPCケースを倒した状態でグラボも外してないと出来ないので、クローン作業との兼ね合いで結構面倒でした…。もう当分やりたくない作業です。

何はともあれブートドライブの容量を500GBから2TBに拡張できたのは良かったです。先日グラボを更新したのもあり、新鮮な気分です。