Skip to content

feat: Docker/Portainer deployment for the text-to-motion demo (CPU + optional Vulkan GPU) - #6

Draft
lgcavalheiro wants to merge 1 commit into
localai-org:mainfrom
lgcavalheiro:docker-support
Draft

feat: Docker/Portainer deployment for the text-to-motion demo (CPU + optional Vulkan GPU)#6
lgcavalheiro wants to merge 1 commit into
localai-org:mainfrom
lgcavalheiro:docker-support

Conversation

@lgcavalheiro

Copy link
Copy Markdown

What

Runs the kimodo.cpp text-to-motion demo as a container (CPU by default, optional Vulkan GPU), packaged for Docker Compose / Portainer:

  • Dockerfile — multi-stage (~290 MB final image): builds kmd-generate/kmd-inspect (CMake/Ninja, C++23, KIMODO_ENABLE_VULKAN=ON) and the Go demo, and checks out GGML itself at the pinned submodule commit, so the build context does not require git submodule update --init (plain git clones and Portainer builds work).
  • docker/entrypoint.sh — on first start, downloads the GGUF weights (~1.1 GB motion + ~15 GB shared LLM2Vec text encoder, F32) into /data with SHA-256 verification against the published manifests (resumable, skipped when complete), then execs the demo on 0.0.0.0:${KIMODO_PORT:-8094}. An explicitly empty KIMODO_MODELS skips downloads entirely.
  • docker-compose.yml + docs/docker_portainer.md — Portainer-ready stack and a full deployment guide: build on the Docker host, deploy via the web editor, GPU passthrough via CDI (devices: [nvidia.com/gpu=all]), VRAM sizing (KIMODO_TEXT_LAYER_CHUNK), adding models, retrieving animated GLB / skinned GLB / BVH, troubleshooting.
  • demo/main.go — one behavioural change: the generator subprocess inherits a pre-set KIMODO_BACKEND instead of the hardcoded vulkan. The default is unchanged (vulkan auto-falls back to CPU when no device exists); this just lets a container force cpu — which is also the escape hatch for hosts where Vulkan enumeration aborts instead of returning zero devices.

Runtime dependencies worth noting

The image carries a few non-obvious runtime packages, each found the hard way on real hardware:

  • spirv-headers in the builder — GGML's CMake needs SPIRV-HeadersConfig.cmake for the Vulkan backend.
  • libx11-6/libxext6 — the NVIDIA ICD library injected by nvidia-container-toolkit (libGLX_nvidia.so.0) links them.
  • libegl1/libglx0/libglvnd0 (GLVND) — the NVIDIA ICD dlopens libEGL.so.1 during Vulkan init even with no display; without it the ICD fails inside the container with Could not get 'vkCreateInstance' while the host works fine.
  • libgomp1 — OpenMP runtime for the GGML backends on debian:trixie-slim.

Verification

Deployed end to end on a 24-core / 16 GB homelab (Ubuntu, Docker 29, Portainer CE):

  • CPU backend: 60-frame, 10-step clip in 45 s, valid animated GLB served from the gallery.
  • Optional GTX 1050 Ti 4 GB via CDI: 36 s at ~2.8 GB VRAM with KIMODO_TEXT_LAYER_CHUNK=4 (the default 8 OOMs a 4 GB card during text-encoder loading; documented in the guide).
  • Healthcheck on /api/models, weight download persistence across restarts, and the KIMODO_BACKEND=cpu fallback all verified.

Draft while I tidy the doc wording / check CI expectations — happy to adjust to whatever packaging conventions the project prefers (e.g. a different base, or splitting the demo patch into its own PR).

- Multi-stage Dockerfile (Go demo + kmd-generate, ~290 MB) with the GGML
  Vulkan backend and automatic CPU fallback; GGML is cloned at the pinned
  submodule commit so the build context needs no submodule init
- docker/entrypoint.sh downloads and SHA-256-verifies the GGUF weights
  into /data on first start, then serves the demo on 0.0.0.0:8094
- docker-compose.yml for Portainer stacks plus docs/docker_portainer.md
  covering GPU passthrough (CDI), VRAM sizing and day-2 ops
- demo: honour a pre-set KIMODO_BACKEND for the generator subprocess
  instead of hardcoding vulkan; the vulkan default still falls back to
  CPU when no device is present, and containers can now force cpu

Verified end to end on a 24-core/16 GB host: CPU generates a 60-frame
10-step clip in 45 s; with an optional GTX 1050 Ti (Vulkan, text encoder
chunked at KIMODO_TEXT_LAYER_CHUNK=4) in 36 s at ~2.8 GB VRAM.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant