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 DIRmirrors DIR tofv-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_NEXTis gone). For Cycles GPU, setprefs.compute_device_type = 'OPTIX'and enable the OPTIX devices, thenscene.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). --extensionsenables 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 abpy.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".--cpuattaches 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 alwaysfv-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
--pythonscript that raises exits 0 unless--python-exit-codeis set. blender-run sets it. render.filepathmust 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.