Spaces:
Runtime error
A newer version of the Gradio SDK is available: 6.19.0
The Chief Engineer β HF Space Deployment Guide
Space: build-small-hackathon/microfactory-lab
Hardware: zero-a10g (ZeroGPU)
Live: https://node.microfactory.space (custom domain)
Status: π’ LIVE β fallback URL: https://build-small-hackathon-microfactory-lab.hf.space
Quick Summary
The Gradio app was failing on HF Spaces due to three platform-specific issues:
- SSR crash β Gradio 6's Node.js SSR proxy crashes on zero-a10g
- Missing
@spaces.GPUβ ZeroGPU hardware requires at least one decorated function - Theme/CSS/head lost β pySpaces calls
demo.launch()without our custom args (Gradio 6 moved these fromBlocks()tolaunch())
All fixed. The app runs on ZeroGPU with Gemma 4 E2B (2B params, Apache 2.0, not gated).
Dual-Config Architecture
The codebase supports both local development and Space deployment from a single app.py:
| Environment | Launch Trigger | Theme Injection | ZeroGPU |
|---|---|---|---|
| Local dev | if __name__ == "__main__": demo.launch(...) |
Explicit args + monkey-patch defaults | @spaces.GPU no-op |
| HF Space | pySpaces imports module β calls demo.launch() |
Monkey-patch setdefault() fills THEME/CSS/VP_HEAD/ssr_mode |
@spaces.GPU wraps function |
Key mechanisms:
demo = build()at module level β pySpaces finds itif __name__ == "__main__":guarded β only runs locally@spaces.GPUdecorator no-ops whenConfig.zero_gpu=False(local)_patched_launchuseskwargs.setdefault()β respects explicit local args, fills defaults on Space
Space Variables (set via hf spaces variables)
| Variable | Value | Purpose |
|---|---|---|
GRADIO_SSR_MODE |
False |
Disables SSR to prevent Node.js crash |
CHIEF_ENGINEER_BACKEND |
zerogpu |
Enables live inference path |
CHIEF_ENGINEER_HF_MODEL |
google/gemma-4-E2B-it |
Model for ZeroGPU inference |
Requirements Strategy
HF Spaces builds mount only requirements.txt to /tmp/requirements.txt. The -r requirements-zerogpu.txt pattern fails because the included file isn't mounted.
Solution: ZeroGPU deps are inlined in requirements.txt:
# Core deps
gradio>=6.17,<7
ollama>=0.4
pydantic>=2.7
trimesh>=4.4
shapely>=2.0
# ZeroGPU deps (inlined β build mounts only requirements.txt)
spaces>=0.30 # @spaces.GPU decorator
torch>=2.4
transformers>=4.49 # Gemma 3/4 family
accelerate>=0.34
Code Changes in app.py
1. Module-level demo for pySpaces
def build() -> gr.Blocks:
with gr.Blocks(title="The Chief Engineer") as demo:
# ... build UI ...
return demo
demo = build() # Module level β pySpaces finds this
2. @spaces.GPU on inference function
import spaces
@spaces.GPU
def get_recommendation(part, material, description, temp, humidity, bed_position):
# Heavy inference β GPU allocated on call via ZeroGPU
...
import spaces is wrapped in a try/except shim in app.py: when the package
is absent (local base env / offline), @spaces.GPU no-ops and returns the function
unchanged. On the Space, HF provides spaces and the real decorator allocates the GPU.
3. Monkey-patch demo.launch for theme/CSS/head
# After demo = build()
_original_launch = demo.launch
def _patched_launch(**kwargs):
kwargs.setdefault("theme", THEME)
kwargs.setdefault("css", CSS)
kwargs.setdefault("head", VP_HEAD)
kwargs.setdefault("ssr_mode", False)
return _original_launch(**kwargs)
demo.launch = _patched_launch
- Local:
__main__callsdemo.launch(ssr_mode=False, server_name="0.0.0.0", ...)β explicit args win - Space: pySpaces calls
demo.launch()βsetdefault()injects THEME/CSS/VP_HEAD/ssr_mode
4. Guarded __main__ for local dev only
if __name__ == "__main__":
print(f"[chief-engineer] {llm.backend_status()} | seeded {_loaded} lessons this run")
demo.launch(ssr_mode=False, server_name="0.0.0.0", server_port=7860, share=False)
Runs locally; skipped on Space (pySpaces imports module, __name__ != "__main__").
Build & Deploy Commands
# From chief-engineer/
hf upload build-small-hackathon/microfactory-lab ./app.py app.py --repo-type space
hf upload build-small-hackathon/microfactory-lab ./requirements.txt requirements.txt --repo-type space
# Set variables (triggers rebuild)
hf spaces variables add build-small-hackathon/microfactory-lab \
-e GRADIO_SSR_MODE=False \
-e CHIEF_ENGINEER_BACKEND=zerogpu \
-e CHIEF_ENGINEER_HF_MODEL=google/gemma-4-E2B-it
# Factory reboot if needed
hf spaces restart build-small-hackathon/microfactory-lab --factory-reboot
Local Development
# In chief-engineer/
make setup # uv sync + generate assets
ollama serve & # For live Gemma (optional; fallback works offline)
make run # uv run python app.py β http://localhost:7860
- Full Astrometrics theme applied via monkey-patch defaults
- Falls back to deterministic advisor if Ollama unavailable
- All core tests pass offline:
uv run python test_core.py
Pre-flight / Verification
# Core tests (offline, fast)
uv run python test_core.py
# Preflight (needs Ollama for live path)
uv run python -m scripts.preflight
# Space logs
hf spaces logs build-small-hackathon/microfactory-lab --tail 30
hf spaces logs build-small-hackathon/microfactory-lab --build --tail 30
Troubleshooting
| Symptom | Cause | Fix |
|---|---|---|
RUNTIME_ERROR + "No @spaces.GPU function detected" |
Missing GPU decorator on zero-a10g | Add @spaces.GPU to at least one function |
| SSR crash ("Stopping Node.js server...") | Gradio 6 SSR incompatible | Set GRADIO_SSR_MODE=False + ssr_mode=False |
| Theme/CSS missing on Space | pySpaces calls launch() without args |
Monkey-patch demo.launch with setdefault() |
| Build fails: "No such file: requirements-zerogpu.txt" | -r not mounted |
Inline deps in requirements.txt |
| 503 on zero-a10g, works on cpu-basic | Hardware-specific SSR/GPU issue | Apply SSR fix + @spaces.GPU |
| "ModuleNotFoundError: spaces" locally | ZeroGPU package not installed | None needed β app.py shims spaces to a no-op when absent. Install the real path only to test ZeroGPU locally: uv sync --extra zerogpu. |
Model Details
- Model:
google/gemma-4-E2B-it(Gemma 4, Efficient 2B, instruction-tuned) - Parameters: ~2 billion (E2B = Efficient 2B)
- License: Apache 2.0 β not gated, no
HF_TOKENneeded - Architecture: Dense, multimodal (text + image), 128K context
- Endpoint: Loaded on first
analyzecall via ZeroGPU
File Tree (Space Root)
build-small-hackathon/microfactory-lab/
βββ app.py # Entry point (demo = build())
βββ README.md # Space metadata (sdk: gradio, sdk_version: 6.17.3)
βββ requirements.txt # All deps inlined
βββ assets/ # .glb meshes (benchy, bridge, cube, overhang, vase)
βββ core/ # Core library (llm, ledger, spine, widgets, viewer, etc.)
βββ learn/ # Policy learning loop
βββ ingest/ # Config distillation (Klipper/Prusa/Marlin)
βββ sim/ # Virtual printer + outcome simulator
βββ scripts/ # Helpers (preflight, bench, demo, capture)
βββ data/ # seed_lessons.jsonl (gitignored: lessons.jsonl, policy.json)
βββ test_core.py # Offline core tests
Key Files for Future Maintenance
| File | Purpose |
|---|---|
app.py |
Space entry point + local launch |
core/llm.py |
Backend abstraction (Ollama / ZeroGPU / fallback) |
core/llm_zerogpu.py |
ZeroGPU transformers path |
core/chief_engineer.py |
Brain: precedent eval + settings proposal |
core/spine.py |
Deterministic veto (material bounds) |
learn/policy.py |
Learned parametric policy (env-bucketed) |
core/theme.py |
Astrometrics THEME + CSS + VP_HEAD |
scripts/preflight.py |
GO/NO-GO gate for releases |
Next Steps / Frontiers
- Weight-level fine-tuning on accumulated ledger (named "Well-Tuned" β currently not built)
- Real distributed multi-node execution (currently single Space)
- Physical interfaces: g-code streaming, env sensors, camera defect CV
- Larger Gemma variants (E4B, 26B A4B, 31B) on larger GPUs
Last updated: 2026-06-11 β Space live on zero-a10g with ZeroGPU Gemma 4 E2B