Initial import: bare-metal stacks, Server UI, GPU fan, tutorials.

Infrastructure configs for GMKtec K11 (Docker, vLLM, LocalAI, ComfyUI,
control-plane, gpu-fan agent, Server UI with CLI/file explorer/GPU fan curve).

Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
tomasz-syn-grzegorza
2026-07-05 12:02:04 +00:00
commit 359afb3a59
153 changed files with 18169 additions and 0 deletions
+63
View File
@@ -0,0 +1,63 @@
#!/usr/bin/env bash
# Shared helpers for models.catalog.yaml (simple parser, no PyYAML required).
CATALOG_FILE="${CATALOG_FILE:-$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd)/models.catalog.yaml}"
catalog_list_ids() {
grep '^ - id:' "${CATALOG_FILE}" | awk '{print $3}'
}
catalog_get_field() {
local model_id="$1"
local field="$2"
awk -v id="${model_id}" -v key="${field}:" '
$0 ~ "^ - id: " id "$" { found=1; next }
found && $0 ~ "^ - id:" { exit }
found && index($0, key) == 5 { sub(/^ [^:]+: /, ""); print; exit }
' "${CATALOG_FILE}"
}
catalog_ensure_dirs() {
local data_root="${1:-/data}"
mkdir -p \
"${data_root}/apps/vllm/huggingface" \
"${data_root}/apps/gguf/qwen3.6-27b" \
"${data_root}/apps/gguf/gemma-4-12b"
}
catalog_model_downloaded() {
local model_id="$1"
local runtime
runtime="$(catalog_get_field "${model_id}" runtime)"
case "${runtime}" in
vllm)
local hf_model
hf_model="$(catalog_get_field "${model_id}" hf_model)"
local cache="${DATA_ROOT:-/data}/apps/vllm/huggingface"
# Heuristic: HF hub cache contains repo name
local repo_path
repo_path=$(echo "${hf_model}" | tr '/' '--')
if find "${cache}/hub" -maxdepth 3 -type d -name "models--${repo_path}" 2>/dev/null | grep -q .; then
return 0
fi
return 1
;;
llamacpp)
local local_path local_dir gguf_file
local_path="$(catalog_get_field "${model_id}" local_path)"
local_dir="$(catalog_get_field "${model_id}" local_dir)"
gguf_file="$(catalog_get_field "${model_id}" gguf_file)"
if [[ -n "${local_path}" && -f "${local_path}" ]]; then
return 0
fi
if [[ -n "${local_dir}" && -n "${gguf_file}" && -f "${local_dir}/${gguf_file}" ]]; then
return 0
fi
return 1
;;
*)
return 1
;;
esac
}
+114
View File
@@ -0,0 +1,114 @@
#!/usr/bin/env bash
set -euo pipefail
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
STACK_DIR="$(cd "${SCRIPT_DIR}/.." && pwd)"
# shellcheck disable=SC1091
source "${SCRIPT_DIR}/catalog-lib.sh"
cd "${STACK_DIR}"
if [[ $# -lt 1 ]]; then
echo "Usage: $0 <catalog-model-id>"
echo ""
echo "Available models:"
catalog_list_ids | sed 's/^/ /'
exit 1
fi
MODEL_ID="$1"
if ! catalog_list_ids | grep -qx "${MODEL_ID}"; then
echo "ERROR: Unknown model id: ${MODEL_ID}"
echo "Run: ./scripts/list-models.sh"
exit 1
fi
if [[ -f .env ]]; then
set -a
# shellcheck disable=SC1091
source .env
set +a
fi
DATA_ROOT="${DATA_ROOT:-/data}"
catalog_ensure_dirs "${DATA_ROOT}"
RUNTIME="$(catalog_get_field "${MODEL_ID}" runtime)"
NAME="$(catalog_get_field "${MODEL_ID}" name)"
echo "=== Download: ${NAME} (${MODEL_ID}) ==="
echo "Runtime: ${RUNTIME}"
echo ""
case "${RUNTIME}" in
vllm)
HF_MODEL="$(catalog_get_field "${MODEL_ID}" hf_model)"
echo "Target: Hugging Face cache at ${DATA_ROOT}/apps/vllm/huggingface"
echo "Model: ${HF_MODEL}"
echo ""
HF_ENV=()
if [[ -n "${HF_TOKEN:-}" ]]; then
HF_ENV=(-e "HF_TOKEN=${HF_TOKEN}")
fi
docker run --rm \
"${HF_ENV[@]}" \
-v "${DATA_ROOT}/apps/vllm/huggingface:/root/.cache/huggingface" \
ghcr.io/huggingface/huggingface-cli:latest \
download "${HF_MODEL}"
;;
llamacpp)
DOWNLOAD_URL="$(catalog_get_field "${MODEL_ID}" download_url)"
LOCAL_PATH="$(catalog_get_field "${MODEL_ID}" local_path)"
LOCAL_DIR="$(catalog_get_field "${MODEL_ID}" local_dir)"
GGUF_FILE="$(catalog_get_field "${MODEL_ID}" gguf_file)"
MMPROJ_URL="$(catalog_get_field "${MODEL_ID}" mmproj_url)"
MMPROJ_FILE="$(catalog_get_field "${MODEL_ID}" mmproj_file)"
if [[ -n "${LOCAL_PATH}" ]]; then
DEST="${LOCAL_PATH}"
mkdir -p "$(dirname "${DEST}")"
if [[ -f "${DEST}" ]]; then
echo "Already exists: ${DEST}"
else
echo "Downloading ${DEST} ..."
wget -c -O "${DEST}" "${DOWNLOAD_URL}"
fi
elif [[ -n "${LOCAL_DIR}" && -n "${GGUF_FILE}" ]]; then
mkdir -p "${LOCAL_DIR}"
DEST="${LOCAL_DIR}/${GGUF_FILE}"
if [[ -f "${DEST}" ]]; then
echo "Already exists: ${DEST}"
else
echo "Downloading ${DEST} ..."
wget -c -O "${DEST}" "${DOWNLOAD_URL}"
fi
if [[ -n "${MMPROJ_URL}" && -n "${MMPROJ_FILE}" ]]; then
MMPROJ_DEST="${LOCAL_DIR}/${MMPROJ_FILE}"
if [[ -f "${MMPROJ_DEST}" ]]; then
echo "Already exists: ${MMPROJ_DEST}"
else
echo "Downloading ${MMPROJ_DEST} ..."
wget -c -O "${MMPROJ_DEST}" "${MMPROJ_URL}"
fi
fi
else
echo "ERROR: Catalog entry missing local_path or local_dir/gguf_file"
exit 1
fi
echo ""
echo "GGUF saved for future llama.cpp stack (stacks/llamacpp/README.md)."
echo "Standard vLLM cannot load .gguf files."
;;
*)
echo "ERROR: Unknown runtime: ${RUNTIME}"
exit 1
;;
esac
echo ""
echo "Done."
+46
View File
@@ -0,0 +1,46 @@
#!/usr/bin/env bash
set -euo pipefail
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
STACK_DIR="$(cd "${SCRIPT_DIR}/.." && pwd)"
# shellcheck disable=SC1091
source "${SCRIPT_DIR}/catalog-lib.sh"
cd "${STACK_DIR}"
if [[ -f .env ]]; then
set -a
# shellcheck disable=SC1091
source .env
set +a
fi
DATA_ROOT="${DATA_ROOT:-/data}"
catalog_ensure_dirs "${DATA_ROOT}"
echo "=== Model catalog ==="
echo "Catalog: ${CATALOG_FILE}"
echo "Data: ${DATA_ROOT}"
echo ""
printf "%-24s %-10s %-8s %s\n" "ID" "RUNTIME" "ON DISK" "NAME"
printf "%-24s %-10s %-8s %s\n" "----" "-------" "-------" "----"
while IFS= read -r model_id; do
name="$(catalog_get_field "${model_id}" name)"
runtime="$(catalog_get_field "${model_id}" runtime)"
if catalog_model_downloaded "${model_id}"; then
on_disk="yes"
else
on_disk="no"
fi
printf "%-24s %-10s %-8s %s\n" "${model_id}" "${runtime}" "${on_disk}" "${name}"
done < <(catalog_list_ids)
echo ""
echo "Download on demand: ./scripts/download-model.sh <id>"
echo "Switch vLLM profile: ./scripts/switch-model.sh <profile-name>"
echo ""
echo "Profiles in profiles/:"
ls -1 "${STACK_DIR}/profiles/"*.env 2>/dev/null | xargs -n1 basename | sed 's/^/ /' || true
+88
View File
@@ -0,0 +1,88 @@
#!/usr/bin/env bash
set -euo pipefail
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
STACK_DIR="$(cd "${SCRIPT_DIR}/.." && pwd)"
# shellcheck disable=SC1091
source "${SCRIPT_DIR}/catalog-lib.sh"
cd "${STACK_DIR}"
PROFILE_ARG="${1:-}"
if [[ -n "${PROFILE_ARG}" ]]; then
PROFILE_FILE="${STACK_DIR}/profiles/${PROFILE_ARG}.env"
if [[ ! -f "${PROFILE_FILE}" ]]; then
echo "ERROR: Profile not found: ${PROFILE_ARG}"
echo " Available:"
ls -1 "${STACK_DIR}/profiles/"*.env 2>/dev/null | xargs -n1 basename | sed 's/\.env$//' | sed 's/^/ /'
exit 1
fi
cp "${PROFILE_FILE}" .env
echo "Applied profile: ${PROFILE_ARG}"
fi
if [[ ! -f .env ]]; then
echo "ERROR: .env not found. Run: cp .env.example .env"
echo " Or use a profile: ./scripts/start.sh qwen3.6-27b-awq-128k"
exit 1
fi
set -a
# shellcheck disable=SC1091
source .env
set +a
DATA_ROOT="${DATA_ROOT:-/data}"
if [[ -z "${VLLM_MODEL:-}" ]]; then
echo "ERROR: VLLM_MODEL is empty in .env"
echo " Set a model, use a profile, or run:"
echo " ./scripts/download-model.sh qwen3.6-27b-awq-vllm"
echo " ./scripts/switch-model.sh qwen3.6-27b-awq-128k"
exit 1
fi
if [[ "${VLLM_MODEL}" == *".gguf"* ]]; then
echo "ERROR: VLLM_MODEL points to a .gguf file — standard vLLM cannot load GGUF."
echo " GGUF models are in models.catalog.yaml for future llama.cpp (stacks/llamacpp/)."
echo " For vLLM use AWQ from Hugging Face, e.g.:"
echo " ./scripts/download-model.sh qwen3.6-27b-awq-vllm"
echo " ./scripts/switch-model.sh qwen3.6-27b-awq-128k"
exit 1
fi
if ! mountpoint -q "${DATA_ROOT}" 2>/dev/null; then
echo "ERROR: ${DATA_ROOT} is not mounted"
echo " Complete disk setup (tutorial 04 part A) first"
exit 1
fi
catalog_ensure_dirs "${DATA_ROOT}"
if ! docker info &>/dev/null; then
echo "ERROR: Docker is not running"
exit 1
fi
chmod +x "${SCRIPT_DIR}/vllm-entrypoint.sh" 2>/dev/null || true
echo "=== vLLM stack ==="
echo "Model: ${VLLM_MODEL}"
echo "Served as: ${SERVED_MODEL_NAME:-qwen3.6-27b}"
echo "Context: ${MAX_MODEL_LEN:-131072} tokens"
echo "KV cache: ${KV_CACHE_DTYPE:-fp8}"
echo "Quantize: ${QUANTIZATION:-(none)}"
echo "Data root: ${DATA_ROOT}"
echo ""
docker compose --profile vllm pull
docker compose --profile vllm up -d
echo ""
echo "Started. Follow logs:"
echo " docker compose --profile vllm logs -f vllm"
echo ""
echo "Test when ready:"
echo " curl -s http://localhost:${VLLM_PORT:-8000}/v1/models | jq ."
+73
View File
@@ -0,0 +1,73 @@
#!/usr/bin/env bash
set -euo pipefail
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
STACK_DIR="$(cd "${SCRIPT_DIR}/.." && pwd)"
# shellcheck disable=SC1091
source "${SCRIPT_DIR}/catalog-lib.sh"
cd "${STACK_DIR}"
PROFILE="${1:-}"
if [[ -z "${PROFILE}" ]]; then
echo "Usage: $0 <profile-name>"
echo ""
echo "Profiles:"
ls -1 "${STACK_DIR}/profiles/"*.env 2>/dev/null | xargs -n1 basename | sed 's/\.env$//' | sed 's/^/ /'
exit 1
fi
PROFILE_FILE="${STACK_DIR}/profiles/${PROFILE}.env"
if [[ ! -f "${PROFILE_FILE}" ]]; then
echo "ERROR: Profile not found: ${PROFILE_FILE}"
echo ""
echo "Available profiles:"
ls -1 "${STACK_DIR}/profiles/"*.env 2>/dev/null | xargs -n1 basename | sed 's/\.env$//' | sed 's/^/ /'
exit 1
fi
if [[ -f .env ]]; then
set -a
# shellcheck disable=SC1091
source .env
set +a
fi
DATA_ROOT="${DATA_ROOT:-/data}"
catalog_ensure_dirs "${DATA_ROOT}"
echo "=== Switch vLLM profile: ${PROFILE} ==="
cp "${PROFILE_FILE}" .env
set -a
# shellcheck disable=SC1091
source .env
set +a
if [[ "${VLLM_MODEL:-}" == *".gguf"* ]]; then
echo "ERROR: VLLM_MODEL points to a .gguf file — vLLM does not support GGUF."
echo " Use stacks/llamacpp (future) or an AWQ Hugging Face model."
echo " See: ./scripts/list-models.sh"
exit 1
fi
if [[ -z "${VLLM_MODEL:-}" ]]; then
echo "ERROR: Profile has empty VLLM_MODEL"
exit 1
fi
echo "Model: ${VLLM_MODEL}"
echo "Served as: ${SERVED_MODEL_NAME:-qwen3.6-27b}"
echo "Context: ${MAX_MODEL_LEN:-131072}"
echo ""
if docker compose --profile vllm ps -q vllm 2>/dev/null | grep -q .; then
echo "Restarting vLLM container ..."
docker compose --profile vllm down
"${SCRIPT_DIR}/start.sh"
else
echo "vLLM not running. Start with:"
echo " ./scripts/start.sh"
fi
+26
View File
@@ -0,0 +1,26 @@
#!/usr/bin/env bash
set -euo pipefail
ARGS=(
--model "${VLLM_MODEL}"
--served-model-name "${SERVED_MODEL_NAME:-qwen3.6-27b}"
--host 0.0.0.0
--port 8000
--max-model-len "${MAX_MODEL_LEN:-131072}"
--max-num-seqs "${MAX_NUM_SEQS:-1}"
--gpu-memory-utilization "${GPU_MEMORY_UTILIZATION:-0.95}"
--kv-cache-dtype "${KV_CACHE_DTYPE:-fp8}"
--trust-remote-code
)
if [[ -n "${QUANTIZATION:-}" ]]; then
ARGS+=(--quantization "${QUANTIZATION}")
fi
if [[ -n "${VLLM_EXTRA_ARGS:-}" ]]; then
# shellcheck disable=SC2206
EXTRA=( ${VLLM_EXTRA_ARGS} )
ARGS+=("${EXTRA[@]}")
fi
exec vllm serve "${ARGS[@]}"