Files
esh-pfi-infrastructure/docs/fleettools/blender.md
T

4.8 KiB

Blender: headless and agent-driven 3D on fv-ml1 GPU 3

Blender 5.2.2 LTS (bundled Python 3.13), runs on fv-ml1 GPU 3 (RTX PRO 6000 Blackwell, 96 GB). Stack and full notes: /home/lkraven/development/eshpfi-management/stacks/blender/README.md.

⚠ GPU 3 is borrowed. It is the fleet's reserve card for a full-size vLLM seat. Blender runs only while in use, and this access ends if a big seat moves onto the card.

Two ways in

You are… Use Shape
a script or CLI caller (renders, conversions) scripts/blender-run one-shot docker run --rm: no desktop, gone when Blender exits
an agent building scenes interactively scripts/blender-mcp (MCP, per task) a GUI Blender plus the mcp-for-blender add-on; up / status / down

Both scripts are in /home/lkraven/development/eshpfi-management/scripts/ and run from nh3-dev, reaching fv-ml1 as infra-ops@10.251.50.54 over ssh. No HTTP API and no openapi.json.

blender-run (headless)

scripts/blender-run --job /path/to/jobdir -- --python render.py -- out.png
scripts/blender-run --extensions --job /path/to/jobdir -- --python model.py
scripts/blender-run -- --python-expr 'import bpy; print(bpy.app.version_string)'
  • Always adds -b --factory-startup --python-exit-code 1. Arguments go after --.
  • Files: fv-ml1 does not mount /mnt/smithy. --job DIR mirrors DIR to fv-ml1:/tank/blender/jobs/<basename>-<hash of DIR's absolute path>/, runs with that as the working directory, and copies new or changed files back into DIR. Nothing is ever deleted locally, and a rerun starts from an exact mirror, never from leftovers. Use relative input paths inside the job. Do not run the same DIR twice at once.
  • Engines headless (tested 2026-09-28): Cycles on GPU (OptiX/CUDA), Cycles on CPU, EEVEE (EGL, no display needed, ~9 s with the shader compile on first use), Workbench. In 5.2 the EEVEE id is BLENDER_EEVEE (BLENDER_EEVEE_NEXT is gone). For Cycles GPU, set prefs.compute_device_type = 'OPTIX' and enable the OPTIX devices, then scene.cycles.device = 'GPU'. Factory startup defaults to CPU.
  • Import: STL is built in (bpy.ops.wm.stl_import). STEP, 3MF and the other add-ons need --extensions (below).
  • --extensions enables the pinned add-on set: SurfacePsycho 0.10.4 (NURBS patches, STEP/IGES export via its bundled OCP), CAD Sketcher 0.32.1, 3D-Print Toolbox 1.4.1, STEP Importer 1.2.1, Bool Tool 2.1.0, LoopTools 4.7.7, MeasureIt 1.8.4, 3MF Import/Export 2.7.7. Pins: stacks/blender/extensions.lock. If any add-on fails to enable, the run exits 1 before your script starts. It adds a few seconds of startup (the add-on wheels unpack per run), so it is off by default. CAD Sketcher's sketch operators need the GUI (they activate a workspace tool); headless they fail with "'NoneType' object has no attribute 'widget'". Operators that want a 3D View (MeasureIt, LoopTools) take a bpy.context.temp_override(area=...) with a screen datablock's VIEW_3D area. Worked calls for every add-on: scripts/blender-probes/extensions_acceptance.py. Full notes and foot-guns: the stack README, section "Extensions".
  • --cpu attaches no GPU at all (no nvidia runtime), so the run never touches GPU 3. Use it for modelling, add-ons and import/export, which is anything that does not render. It is proven for those (the extension acceptance ran that way) and for Cycles on CPU. EEVEE and Workbench are expected to fail without the GPU (untested). The container hostname is always fv-ml1-blender.
  • Budget: each run is capped at 64 GB RAM and 48 CPUs, with up to the whole 96 GB of VRAM. Keep to about 2 concurrent renders. It is not on irv-ml1, so irv-ml1's working-set budget does not apply.

⚠ Foot-guns (all measured):

  • A --python script that raises exits 0 unless --python-exit-code is set. blender-run sets it.
  • render.filepath must be absolute. Blender does not resolve a relative output path against the working directory ("cannot save 'out.png'"). Importers and Python file I/O do.
  • Harmless stderr noise: "HIPEW initialization failed" (the AMD backend probing), and "Failed to create secure directory (/defaults): Operation not permitted" (the image's runtime-dir setup running as a non-root user; reported by draupnir 2026-09-28).
  • The first OptiX render in a process includes about 1-2 s of kernel load.

blender-mcp (agents)

Register it per task, never user- or project-wide (Prime, 2026-09-27): claude mcp add blender -- /home/lkraven/development/eshpfi-management/scripts/blender-mcp. Then run scripts/blender-mcp up, wait for status to say answering, work, and run down when finished. Safe mode is on (no os/open/network in agent code), so the startup hook has already pointed Cycles at OptiX. Save to /work/…. Details and traps are in the stack README.