[Unit]
Description=LoRA training worker (arbo in-arbo LoRA training Phase 1, §4.1) — runs sd-scripts on demand
After=network-online.target
Wants=network-online.target

[Service]
Type=simple
# Runs as llmuser: only llmuser can exec the /opt/fluxgym/.venv + owns the GPU-training surface (§2).
User=llmuser
Group=llmuser
WorkingDirectory=/opt/lora-training-worker
# The worker's OWN venv (fastapi/uvicorn) — it never imports torch; it subprocesses the fluxgym venv.
ExecStart=/opt/lora-training-worker/.venv/bin/uvicorn worker.app:app --host 0.0.0.0 --port 8203
Restart=on-failure
RestartSec=5
# State + logs live under the service dir; both must be llmuser-writable (the deploy playbook chowns).
Environment=LORA_WORKER_STATE_DIR=/opt/lora-training-worker/state
Environment=LORA_WORKER_LOG_DIR=/opt/lora-training-worker/logs
Environment=LORA_WORKER_HANDOFF_ROOT=/worktank/arbo/train
# Give the training subprocess a sane PATH (accelerate is invoked by absolute path regardless).
Environment=PATH=/opt/lora-training-worker/.venv/bin:/usr/local/bin:/usr/bin:/bin
StandardOutput=append:/opt/lora-training-worker/logs/service.log
StandardError=append:/opt/lora-training-worker/logs/service.log

[Install]
WantedBy=multi-user.target
