この記事について
前編では、input フォルダにファイルを入れるだけで、LAN内のワーカーPCが画像、PDF、OCR、動画処理を自動で実行する仕組みを作りました。
前編: フォルダに入れるだけでLAN内のPCが勝手に処理する分散処理システムを作った話
この記事はその後編です。
今回は、もう少し重めで面白い処理を追加しました。
physics_sim
blender_render
blender_animation
フォルダにJSONや .blend を置くと、ワーカーPCが物理シミュレーションやBlenderレンダリングを実行します。
追加したジョブ
追加後のワーカー能力は、だいたいこうなりました。
blender_animation
blender_render
image_grayscale
image_ocr
image_resize
image_thumbnail
pdf_ocr
pdf_to_images
physics_sim
video_thumbnail
video_transcode
前編の仕組みでは、サーバーが job_type を判定し、ワーカーは自分の capabilities に合うジョブだけを取得します。
なので、今回も同じ考え方で拡張しました。
input\physics\*.json
-> physics_sim
input\blender\*.blend
-> blender_render
input\blender-animation\*.blend
-> blender_animation
物理シミュレーション
まず入れたのは physics_sim です。
これはJSONで初期条件を書いて、ワーカーがシミュレーションし、CSVとグラフPNGを返すジョブです。
例えば振り子ならこうです。
{
"type": "pendulum",
"length": 1.0,
"gravity": 9.81,
"theta0": 0.8,
"omega0": 0.0,
"duration": 10,
"dt": 0.01
}
投入する場所はここです。
server\input\physics\pendulum_001.json
出力はこうなります。
server\output\pendulum_001_result_processed.csv
server\output\pendulum_001_plot_processed.png
対応したシミュレーションは、まずこの3つです。
pendulum
projectile
spring_mass
リアルタイムゲームの物理演算をPC間で同期するのは難しいです。 でも、こういうバッチ型のシミュレーションなら分散しやすいです。
条件の違うJSONを大量に置けば、複数ワーカーが順番に拾って結果を返してくれます。
Blender静止画レンダリング
次に blender_render を入れました。
これは .blend ファイルをワーカーPCのBlender CLIで開いて、1フレーム目をPNGとしてレンダリングするジョブです。
server\input\blender\scene.blend
-> server\output\scene_frame_0001_processed.png
内部的には、だいたいこういうコマンドです。
blender -b scene.blend -o scene_frame_#### -F PNG -f 1
BlenderはGUIを開かなくても、-b でバックグラウンド実行できます。
これが分散ワーカーと相性が良いです。
ワーカー側では blender.exe がPATHから見える時だけ、能力に blender_render を追加します。
blender_render
-> blender.exe が必要
Blenderアニメーションレンダリング
静止画ができるなら、次は動画です。
blender_animation では、.blend のアニメーションをPNG連番としてレンダリングし、FFmpegでMP4に結合します。
server\input\blender-animation\scene.blend
-> server\output\scene_animation_processed.mp4
ここではBlenderだけでなくFFmpegも必要です。
blender_animation
-> blender.exe と ffmpeg.exe が必要
そのため、ワーカーの能力判定も次のようにしました。
blender.exe がある
-> blender_render
blender.exe と ffmpeg.exe がある
-> blender_animation
Blenderはフレームを書き出す担当。 FFmpegは連番PNGをMP4にまとめる担当です。
公式blendファイルで詰まった
公式デモの blender-4.0-splash.blend を入れて試したところ、最初は認識されなかったり、失敗したりしました。
サーバーサービスが古いコードを読んでいた
まず、自動登録されない問題がありました。
ファイルはここにありました。
server\input\blender-animation\blender-4.0-splash.blend
でもジョブになりません。
原因は、メインサーバーが古いコードのままサービス起動していたことでした。
blender-animation フォルダを判定するコードを追加しても、サービスを再起動しないと反映されません。
Restart-Service DistributedOsLayerServer
サービス化していると、コードを直しただけでは反映されない。 これは当たり前ですが、実際にハマりやすいところでした。
Blenderの出力形式に引っ張られた
次に、ジョブとしては拾うけれど、レンダリング結果が出ない問題がありました。
ログにはこんなエラーが出ました。
blender finished but no rendered frames were found
調べると、blender-4.0-splash.blend はもともと出力形式が FFMPEG になっていました。
最初の実装では、Pythonスクリプトで出力形式を PNG に変えようとしていました。
でもBlender 5.1では、このファイルに対してPythonから PNG を設定しようとすると弾かれました。
そこで方針を変えました。
Pythonでレンダー設定を書き換えるのではなく、Blender CLIのオプションでPNG連番を出すようにしました。
blender -b scene.blend -o frame_#### -F PNG -s 1 -e 120 -a
その後、FFmpegでMP4に結合します。
ffmpeg -framerate 24 -i frame_%04d.png -c:v libx264 -pix_fmt yuv420p output.mp4
この方式の方が、.blend 側の元の出力設定に引っ張られにくくなります。
重いファイルは最大フレーム数を絞る
公式デモの blender-4.0-splash.blend は、1フレームだけでも約35秒かかりました。
そのまま210フレームを回すとかなり時間がかかります。
そこでMVPでは、アニメーションレンダリングの最大フレーム数を設定できるようにしました。
"blender_animation_max_frames": 120
短く試すなら、例えば24フレームにします。
"blender_animation_max_frames": 24
制限なしにしたい場合は 0 です。
"blender_animation_max_frames": 0
まず短いフレーム数で動作確認してから、本番レンダリングに入る方が安全です。
試す手順
テスト用の .blend はスクリプトで作れるようにしました。
静止画レンダリング用:
examples\blender\make-test-blend.cmd
アニメーションレンダリング用:
examples\blender\make-test-animation-blend.cmd
外部の .blend を使う場合は、置き場所で処理が変わります。
server\input\blender\scene.blend
-> 静止画PNG
server\input\blender-animation\scene.blend
-> MP4
ワーカー側では、サービス環境のPATHにBlenderとFFmpegの両方を入れます。
D:\Blender Foundation
C:\...\ffmpeg\bin
capabilities に次が出れば準備完了です。
blender_render
blender_animation
まとめ
前編で作った仕組みは、処理の中身を差し替えやすい構造でした。
サーバーはファイルを見て job_type を決める。
ワーカーは自分にできるジョブだけ取る。
結果はoutputへ戻す。
この形にしておくと、あとから重い処理を増やしやすいです。
今回追加したのは、物理シミュレーションとBlenderレンダリングでした。
physics_sim
blender_render
blender_animation
画像処理から始めた小さいMVPが、いつのまにかLAN内のレンダーファームっぽいものになってきました。
まだフレーム単位の本格分散レンダリングまではしていません。
でも、.blend をフォルダに入れたら別PCがレンダリングしてMP4を返すところまでは来ました。
こういう「普段使っているPCが、裏で少しずつ仕事を分け合う」感じはかなり面白いです。