diff --git a/docs/platforms.md b/docs/platforms.md index 57fae437..e8230c04 100644 --- a/docs/platforms.md +++ b/docs/platforms.md @@ -363,15 +363,20 @@ B70 runs land: - Expected collision: a second GPU plugin. `deploy-intel-gpu-plugin.yml` applies `deployments/gpu_plugin/base/intel-gpu-plugin.yaml` from intel-device-plugins `main` (`intel_gpu_plugin_ref` defaults to `main`, unpinned) beside the baked DaemonSet. + `eat-up.sh` therefore stops on `compute_platform=xpu` and points at + `K3D_GPU_AGENT_BACKEND=vllm`. - Expected collision: a second balloons policy. The reworked `nri_cpu_balloons` role renders one NUMA-sized `BalloonsPolicy` per node (`node.`). #21 still installs it only on `deploy_nri_balloon_policy == "yes"` (`fresh-install.sh` line 247), so - `eat-up.sh`'s `off` keeps it away; a config that turns it on meets k3d-gpu's policy. + `eat-up.sh`'s `off` keeps it away, and `eat-up.sh` stops on any other value, an + absent key included (`prompt_for_input`, which the stack path and `brownfield.sh model` + both call, turns that on). - Expected gap: the `hostPath` libraries resolve inside the k3d node container, not on the host. The node image would have to carry compatible Level Zero and OpenCL user space at those paths, or the pod would mount empty or mismatched libraries. - Expected gap: Kata (`kata-fc`, `kata-qemu`) needs `/dev/kvm` and nested virtualization inside the k3d node, which k3d-gpu does not pass through today. + `eat-up.sh` stops on `deploy_kata_containers=on`. Gaps for the #20 example instance (`docs/examples/openclaw-instance.yaml`) on k3d-gpu: diff --git a/integrations/eat/README.md b/integrations/eat/README.md index da214a23..28c35356 100644 --- a/integrations/eat/README.md +++ b/integrations/eat/README.md @@ -257,6 +257,12 @@ except where an item says otherwise, and item 11 is new there. In above. `release-1.1.0` reworks the role (`install_nri.yaml` is gone; it renders one `BalloonsPolicy` per node) and still runs it only on `deploy_nri_balloon_policy=yes` (fresh-install.sh:247), which stays off. + `prompt_for_input` turns an absent key on for `compute_platform` c + (parse-user-prompts.sh:55-66). The stack path calls it (fresh-install.sh:39), + so an absent key deploys EAT's policy there. `brownfield.sh model` calls it too, + and `deploy-inference-models.yml` then sets vLLM's `cpu_balloon_annotation` to + EAT's `vllm-balloon-tp` over k3d-gpu's `performance`. `eat-up.sh` stops before + touching the cluster on any value but `off` or `no`, absent included. 11. **The guardrail ignores the config on the brownfield path** (new in `release-1.1.0`). `deploy-agentic-stack.sh:195` sets `DEPLOY_GUARDRAILS="${DEPLOY_GUARDRAILS:-on}"` when it is sourced, and @@ -270,6 +276,15 @@ except where an item says otherwise, and item 11 is new there. In `eat-up.sh` stops before touching the cluster when the config gives `deploy_guardrails` no value (a config written for `release-1.0.3-hotfix` has none) and asks for `off` or `on`. +12. **Release-1.1.0 settings that collide with a k3d-gpu cluster.** `eat-up.sh` + stops before touching the cluster, reading each key as `read_config_file` + does, on `compute_platform=xpu` (fresh-install.sh:219 applies + intel-device-plugins' `gpu_plugin` from `main`, unpinned, beside the plugin + k3d-gpu bakes; vLLM on an Intel GPU is `K3D_GPU_AGENT_BACKEND=vllm k3d-gpu + agent up`), `deploy_kata_containers=on` (Kata needs `/dev/kvm`, which a k3d + node lacks) and `rack_scale_mode=on` (it builds its own cluster from + `rack-profile.yaml`: netplan, BGP, the NVIDIA GPU operator). None of these has + run here; each is read from source. Not a blocker on the previous pin: **AMX/AVX-512 are not required.** The CPU vLLM image (`v0.24.0`) with EAT's exact Qwen3 settings (`VLLM_CPU_SGL_KERNEL=1`, diff --git a/integrations/eat/eat-up.sh b/integrations/eat/eat-up.sh index 5c343a38..4e5ed978 100755 --- a/integrations/eat/eat-up.sh +++ b/integrations/eat/eat-up.sh @@ -66,6 +66,30 @@ esac # choice is asked for here rather than made for the user. [ -n "$(cfg_value "${EAT_CONFIG}" deploy_guardrails)" ] \ || err "${EAT_CONFIG} does not set deploy_guardrails, so ${EAT_TAG} would deploy its Qwen3Guard guardrail, which has not run on a k3d-gpu cluster; set deploy_guardrails=off (as the shipped agentic-config.cfg does) or deploy_guardrails=on" +# Settings with which ${EAT_TAG} puts a second copy of what a k3d-gpu cluster already +# runs next to it, or needs what a k3d node lacks (core/lib/cluster/deployment/fresh-install.sh): +# - its NRI balloons policy on yes (:247). prompt_for_input turns an absent key on for +# compute_platform c (parse-user-prompts.sh:55-66). The stack path calls it (:39); so +# does brownfield.sh model mode, after which deploy-inference-models.yml gives vLLM +# EAT's balloon (vllm-balloon-tp) in place of k3d-gpu's performance balloon. +# - intel-device-plugins' gpu_plugin from its main branch, unpinned, on xpu (:219, +# playbooks/deploy-intel-gpu-plugin.yml:12-14). +# - Kata Containers, which needs /dev/kvm on the node (playbooks/deploy-kata-containers.yml). +# - rack-scale mode, which builds the cluster from rack-profile.yaml: netplan, BGP and the +# NVIDIA GPU operator (:195-210). +case "$(cfg_value "${EAT_CONFIG}" deploy_nri_balloon_policy)" in + off|no) ;; + *) err "${EAT_CONFIG}: deploy_nri_balloon_policy must be off: ${EAT_TAG} deploys its own NRI balloons policy when it is on or absent, beside k3d-gpu's, which must remain the only one, and in model mode it moves vLLM to a balloon type k3d-gpu's policy does not define" ;; +esac +case "$(cfg_value "${EAT_CONFIG}" compute_platform)" in + x|xpu) err "compute_platform=xpu: ${EAT_TAG} then applies intel-device-plugins' gpu_plugin from its main branch, unpinned, beside the GPU plugin k3d-gpu bakes; for vLLM on an Intel GPU run K3D_GPU_AGENT_BACKEND=vllm k3d-gpu agent up" ;; +esac +case "$(cfg_value "${EAT_CONFIG}" deploy_kata_containers)" in + on|yes) err "deploy_kata_containers=on: Kata needs /dev/kvm on the node, and a k3d node is a container without it; set deploy_kata_containers=off" ;; +esac +case "$(cfg_value "${EAT_CONFIG}" rack_scale_mode)" in + on|yes) err "rack_scale_mode=on: ${EAT_TAG} then builds a cluster from rack-profile.yaml (netplan, BGP, the NVIDIA GPU operator), and a k3d-gpu cluster is brownfield; set rack_scale_mode=off" ;; +esac # The KV cache from the fit of EAT_FIT_MODEL, unless EAT_VLLM_KV_GIB is set. if [ -z "${EAT_VLLM_KV_GIB:-}" ] && [ -n "${EAT_FIT_MODEL:-}" ]; then command -v k3d-gpu >/dev/null 2>&1 || err "EAT_FIT_MODEL needs k3d-gpu on PATH (or set EAT_VLLM_KV_GIB)" diff --git a/tests/eat_test.sh b/tests/eat_test.sh index e841e5e3..0e6b1872 100755 --- a/tests/eat_test.sh +++ b/tests/eat_test.sh @@ -10,7 +10,10 @@ # python-runtime-sandbox) and for one that runs it under /bin/sh -c # - the check fails when the sandbox prints anything but 385 # 3. eat-up.sh refuses deploy_openshell=on, unverified on k3d-gpu, and a config with no -# deploy_guardrails value, on which release-1.1.0 deploys its guardrail. +# deploy_guardrails value, on which release-1.1.0 deploys its guardrail. It also +# refuses a deploy_nri_balloon_policy other than off (a second balloons policy), +# compute_platform=xpu (an unpinned second GPU plugin), deploy_kata_containers=on +# (no /dev/kvm in a k3d node) and rack_scale_mode=on (it builds its own cluster). # 5. The GenAI Gateway installs from copies of its charts with exact dependency # versions and every image name:tag@sha256 (gateway-charts.py, brownfield.sh). # 6. eat-opt.py puts the model optimizer's choices on EAT's own modelConfigs entry, @@ -342,6 +345,74 @@ guard_case "deploy_guardrails=on is the user's choice" pass 'deploy_guardrails=o guard_case "spaces and quotes" pass ' deploy_guardrails = "off" ' guard_case "set, then emptied: last wins" refuse 'deploy_guardrails=off' 'deploy_guardrails=' +# 3d. eat-up.sh stops before the cluster on release-1.1.0 settings that put a second copy +# of what a k3d-gpu cluster runs next to it, or that need what a k3d node lacks. Each +# case starts from the shipped config without the key's line; the key is read as +# read_config_file reads it (on -> yes, off -> no, last assignment wins). +# - deploy_nri_balloon_policy: fresh-install.sh:247 deploys EAT's NRI balloons policy +# on yes. prompt_for_input turns an absent key on for compute_platform c +# (parse-user-prompts.sh:55-66), and both the stack path (fresh-install.sh:39) and +# brownfield.sh model mode call it: only off or no pass. +# - compute_platform x or xpu: fresh-install.sh:219 applies intel-device-plugins' +# gpu_plugin from its main branch (deploy-intel-gpu-plugin.yml:12-14). +# - deploy_kata_containers on or yes: Kata needs /dev/kvm (deploy-kata-containers.yml). +# - rack_scale_mode on or yes: builds the cluster from rack-profile.yaml (netplan, BGP, +# the NVIDIA GPU operator; fresh-install.sh:195-210). +# key_case +key_case() { + local name=$1 want=$2 refused=$3 key=$4 out rc msg cfg + shift 4 + N=$((N + 1)) + cfg="${WORK}/key-${N}.cfg" + grep -v "^${key}=" "${EAT}/agentic-config.cfg" > "${cfg}" + [ "$#" -eq 0 ] || printf '%s\n' "$@" >> "${cfg}" + out=$(EAT_CONFIG="${cfg}" EAT_KUBECONFIG=/nonexistent "${EAT}/eat-up.sh" 2>&1) && rc=0 || rc=$? + if [ "${want}" = refuse ]; then msg=${refused}; else msg=${PASSED}; fi + if [ "${rc}" -ne 0 ] && grep -qF "${msg}" <<< "${out}" && { [ "${want}" = pass ] || ! grep -qF "${PASSED}" <<< "${out}"; }; then + ok "eat-up ${key} ${want}: ${name}" + else + fail "eat-up ${key} ${want}: ${name} (rc=${rc}): ${out}" + fi +} +NRI_REFUSED="deploy_nri_balloon_policy must be off" +key_case "absent (prompt_for_input turns it on)" refuse "${NRI_REFUSED}" deploy_nri_balloon_policy +key_case "on" refuse "${NRI_REFUSED}" deploy_nri_balloon_policy 'deploy_nri_balloon_policy=on' +key_case "yes" refuse "${NRI_REFUSED}" deploy_nri_balloon_policy 'deploy_nri_balloon_policy=yes' +key_case "empty" refuse "${NRI_REFUSED}" deploy_nri_balloon_policy 'deploy_nri_balloon_policy=' +key_case "off then on, last wins" refuse "${NRI_REFUSED}" deploy_nri_balloon_policy \ + 'deploy_nri_balloon_policy=off' 'deploy_nri_balloon_policy=on' +key_case "off" pass "" deploy_nri_balloon_policy 'deploy_nri_balloon_policy=off' +key_case "no" pass "" deploy_nri_balloon_policy 'deploy_nri_balloon_policy=no' +key_case "spaces and quotes" pass "" deploy_nri_balloon_policy ' deploy_nri_balloon_policy = "off" ' +cfg="${WORK}/nri-absent.cfg" +grep -v '^deploy_nri_balloon_policy=' "${EAT}/agentic-config.cfg" > "${cfg}" +out=$(EAT_CONFIG="${cfg}" EAT_KUBECONFIG=/nonexistent "${EAT}/eat-up.sh" 2>&1) || true +if grep -qF 'deploys its own NRI balloons policy when it is on or absent' <<< "${out}"; then + ok "eat-up: the balloons refusal says an absent key deploys EAT's policy on the stack path too" +else fail "eat-up: the balloons refusal ties an absent key to model mode only: ${out}"; fi +XPU_REFUSED="compute_platform=xpu" +key_case "xpu" refuse "${XPU_REFUSED}" compute_platform 'compute_platform=xpu' +key_case "x" refuse "${XPU_REFUSED}" compute_platform 'compute_platform=x' +key_case "quoted xpu" refuse "${XPU_REFUSED}" compute_platform 'compute_platform = "xpu"' +key_case "cpu" pass "" compute_platform 'compute_platform=cpu' +key_case "absent (EAT's default cpu)" pass "" compute_platform +KATA_REFUSED="deploy_kata_containers=on" +key_case "on" refuse "${KATA_REFUSED}" deploy_kata_containers 'deploy_kata_containers=on' +key_case "yes" refuse "${KATA_REFUSED}" deploy_kata_containers 'deploy_kata_containers=yes' +key_case "off then on, last wins" refuse "${KATA_REFUSED}" deploy_kata_containers \ + 'deploy_kata_containers=off' 'deploy_kata_containers=on' +key_case "off" pass "" deploy_kata_containers 'deploy_kata_containers=off' +RACK_REFUSED="rack_scale_mode=on" +key_case "on" refuse "${RACK_REFUSED}" rack_scale_mode 'rack_scale_mode=on' +key_case "yes" refuse "${RACK_REFUSED}" rack_scale_mode 'rack_scale_mode=yes' +key_case "off" pass "" rack_scale_mode 'rack_scale_mode=off' +cfg="${WORK}/xpu-reason.cfg" +cp "${EAT}/agentic-config.cfg" "${cfg}" +echo 'compute_platform=xpu' >> "${cfg}" +out=$(EAT_CONFIG="${cfg}" EAT_KUBECONFIG=/nonexistent "${EAT}/eat-up.sh" 2>&1) || true +if grep -qF 'K3D_GPU_AGENT_BACKEND=vllm' <<< "${out}"; then ok "eat-up: the xpu refusal points at vLLM on an Intel GPU through k3d-gpu agent up" +else fail "eat-up: the xpu refusal names no alternative: ${out}"; fi + # 5. The GenAI Gateway path installs pinned charts and images. EAT's # deploy-genai-gateway.yml syncs helm_charts_base_genai{,_trace} to the node, runs # `helm dependency update` on genai-gateway (Chart.yaml ranges postgresql >=13.3.0,