My yaml if anyone wants it (DGX Spark + Docker + Portainer.io + Prometheus + Grafana)

#12
by darkmatter2222 - opened
# Laguna S 2.1 NVFP4 — DGX Spark / Portainer Stack v4
# v4 removes shell variables that Portainer Compose would interpolate.
#
# Import in Portainer:
#   Stacks -> Add stack -> Upload -> select this file -> Deploy the stack
#
# This stack intentionally does NOT use the broken prebuilt vLLM ARM64 image.
# It starts from NVIDIA CUDA 13.0.2, creates a persistent Python 3.12 virtual
# environment, installs vLLM 0.25.1 + the Poolside-recommended FlashInfer
# packages, and then serves the already-downloaded local Laguna model.
#
# First-launch safety settings:
#   - 131,072-token context
#   - 1 concurrent sequence
#   - 70% vLLM memory budget
#   - eager execution (no CUDA graphs / torch.compile)
#   - no speculative decoding
#
# After the model is proven stable, those settings can be increased manually.

services:
  laguna-vllm:
    image: nvidia/cuda:13.0.2-devel-ubuntu24.04
    container_name: laguna-vllm
    hostname: laguna-vllm

    # Keep this disabled for the first validation. After a successful launch,
    # change to "unless-stopped" if automatic restart is desired.
    restart: "no"

    ipc: host
    stop_grace_period: 2m

    ports:
      - "8006:8006"

    environment:
      DEBIAN_FRONTEND: noninteractive
      NVIDIA_VISIBLE_DEVICES: all
      NVIDIA_DRIVER_CAPABILITIES: compute,utility
      CUTE_DSL_ARCH: sm_121a
      MAX_JOBS: "4"
      VIRTUAL_ENV: /opt/vllm025
      PATH: /opt/vllm025/bin:/usr/local/cuda/bin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin
      PYTORCH_CUDA_ALLOC_CONF: expandable_segments:True
      HF_HOME: /root/.cache/huggingface
      VLLM_CACHE_ROOT: /root/.cache/vllm
      TORCH_HOME: /root/.cache/torch

    volumes:
      # The model is already downloaded on the DGX Spark.
      - /home/darkmatter2222/models:/home/darkmatter2222/models:ro

      # Persist the installed environment and compilation/download caches.
      - laguna_vllm025_env:/opt/vllm025
      - laguna_huggingface_cache:/root/.cache/huggingface
      - laguna_vllm_cache:/root/.cache/vllm
      - laguna_flashinfer_cache:/root/.cache/flashinfer
      - laguna_torch_cache:/root/.cache/torch

    deploy:
      resources:
        reservations:
          devices:
            - driver: nvidia
              count: all
              capabilities:
                - gpu

    ulimits:
      memlock:
        soft: -1
        hard: -1
      stack:
        soft: 67108864
        hard: 67108864

    entrypoint:
      - /bin/bash
      - -lc
      - |
        set -Eeuo pipefail
  
        echo "============================================================"
        echo " Laguna S 2.1 NVFP4 bootstrap"
        echo "============================================================"
        echo "CUDA:"
        nvcc --version || true
        nvidia-smi || true
  
        echo
        echo "[1/4] Installing operating-system prerequisites..."
        apt-get update
        apt-get install -y --no-install-recommends \
          ca-certificates \
          curl \
          git \
          build-essential \
          ninja-build \
          pkg-config \
          libnuma-dev \
          python3.12 \
          python3.12-dev \
          python3.12-venv
        rm -rf /var/lib/apt/lists/*
  
        echo
        echo "[2/4] Installing uv when necessary..."
        if [ ! -x /root/.local/bin/uv ]; then
          curl -LsSf https://astral.sh/uv/install.sh | sh
        fi
        /root/.local/bin/uv --version
  
        echo
        echo "[3/4] Creating/updating persistent vLLM 0.25.1 environment..."
        if [ ! -x /opt/vllm025/bin/python ]; then
          /root/.local/bin/uv venv /opt/vllm025 -p python3.12
        fi
  
        if ! /opt/vllm025/bin/python -c \
          'import vllm,sys; sys.exit(0 if vllm.__version__ == "0.25.1" else 1)' \
          >/dev/null 2>&1; then
          /root/.local/bin/uv pip install \
            -p /opt/vllm025 \
            "vllm==0.25.1" \
            --torch-backend=cu130
        fi
  
        if ! /opt/vllm025/bin/python -c \
          'import flashinfer' >/dev/null 2>&1; then
          /root/.local/bin/uv pip install \
            -p /opt/vllm025 \
            "flashinfer-python==0.6.15.dev20260712" \
            "flashinfer-cubin==0.6.15.dev20260712" \
            "flashinfer-jit-cache==0.6.15.dev20260712" \
            --extra-index-url https://flashinfer.ai/whl/nightly/ \
            --extra-index-url https://flashinfer.ai/whl/nightly/cu130/ \
            --index-strategy unsafe-best-match
        fi
  
        echo
        echo "[4/4] Verifying runtime..."
        /opt/vllm025/bin/python - <<'PY'
        import torch
        import vllm
        import flashinfer
  
        print("Python:", __import__("sys").version)
        print("vLLM:", vllm.__version__)
        print("Torch:", torch.__version__)
        print("CUDA available:", torch.cuda.is_available())
        print("CUDA runtime:", torch.version.cuda)
        print("FlashInfer:", getattr(flashinfer, "__version__", "installed"))
  
        if vllm.__version__ != "0.25.1":
            raise RuntimeError(f"Expected vLLM 0.25.1, found {vllm.__version__}")
        if not torch.cuda.is_available():
            raise RuntimeError("CUDA is not available inside the container")
        PY
  
        if [ ! -f /home/darkmatter2222/models/Laguna-S-2.1-NVFP4/config.json ]; then
          echo "ERROR: Model was not found at /home/darkmatter2222/models/Laguna-S-2.1-NVFP4"
          echo "Check the host bind mount and model directory name."
          exit 10
        fi
  
        echo
        echo "Starting Laguna S 2.1 on port 8006..."
        exec /opt/vllm025/bin/vllm serve /home/darkmatter2222/models/Laguna-S-2.1-NVFP4 \
          --served-model-name laguna-s-2.1 \
          --host 0.0.0.0 \
          --port 8006 \
          --trust-remote-code \
          --dtype auto \
          --safetensors-load-strategy lazy \
          --gpu-memory-utilization 0.70 \
          --max-model-len 131072 \
          --max-num-seqs 1 \
          --max-num-batched-tokens 4096 \
          --enable-chunked-prefill \
          --enable-auto-tool-choice \
          --tool-call-parser poolside_v1 \
          --reasoning-parser poolside_v1 \
          --override-generation-config '{"temperature":0.7,"top_p":0.95}' \
          --kv-cache-dtype fp8 \
          --enforce-eager
  
    healthcheck:
      test:
        - CMD-SHELL
        - >-
          /opt/vllm025/bin/python -c
          "import urllib.request;
          urllib.request.urlopen('http://127.0.0.1:8006/health', timeout=5)"
      interval: 30s
      timeout: 10s
      retries: 10
      start_period: 30m

volumes:
  laguna_vllm025_env:
  laguna_huggingface_cache:
  laguna_vllm_cache:
  laguna_flashinfer_cache:
  laguna_torch_cache:

Sign up or log in to comment