feat(frank-tts-engine): synthesize on the gfx1151 iGPU via Vulkan
The NPU path is a dead end for this payload (verdict: report/tts-npu-spike-verdict-2026-10-19.md); the iGPU is the accelerator that exists on this box today, and it is already shared with frank-dragoon. - Containerfile.engine: -DGGML_VULKAN=ON, plus the three packages the door needs to configure — libvulkan-dev, spirv-headers, and glslc, which Ubuntu's glslang-tools does NOT ship (find_package(Vulkan COMPONENTS glslc REQUIRED) fails without it) — and libvulkan1 + mesa-vulkan-drivers (the RADV ICD) at runtime. No NVIDIA ICD on purpose: one Vulkan device in the enumeration is what makes the NAME Vulkan0 safe to write down. - tts-engine-start.sh: QWENTTS_DEVICE -> --device, default Vulkan0. A value that is set but EMPTY passes no flag at all, which is the CPU rollback; that is why the default is written as an -v test and not with :=, because := also fires on an empty value and would silently undo the rollback. - quadlet: AddDevice=/dev/dri + GroupAdd=keep-groups (a rootless container that drops its supplementary groups enumerates no render device). The node is not named: this host is hybrid, renderD128 is the NVIDIA card and renderD129 the amdgpu iGPU. - env: QWENTTS_DEVICE=Vulkan0 plus the device law in the header, including the rollback line. - tests: the two CPU-only assertions now assert the Vulkan shape, and a new one pins the rollback (empty device => no --device in argv). 451/451 green. Measured before writing any of it: the configure in the digest-pinned base answers "Found Vulkan: ... found components: glslc" and "Including Vulkan backend"; gate 1 (RADV GFX1151 visible to a rootless container off this base) is recorded in the verdict report.
This commit is contained in:
@@ -331,13 +331,40 @@ FAKE
|
||||
[ "$(argv --port)" = "8880" ]
|
||||
[ "$(argv --lang)" = "auto" ]
|
||||
[ "$(argv --max-batch)" = "1" ]
|
||||
# The two flags that must never appear: there is no thread count to set (it
|
||||
# comes from hardware_concurrency()/2), and naming a device on an image with
|
||||
# every GPU backend compiled out is only a new way to be wrong.
|
||||
! grep -qx -- '--device' "$ARGS_FILE"
|
||||
# The device the env names has to reach argv BY NAME: the image ships the
|
||||
# Mesa ICD and no NVIDIA one, so Vulkan0 is the gfx1151 and cannot drift onto
|
||||
# another card the way an index would.
|
||||
[ "$(argv --device)" = "Vulkan0" ]
|
||||
# The flag that must never appear: there is no thread count to set in this
|
||||
# build (it comes from hardware_concurrency()/2), so naming one would only
|
||||
# disagree with what the binary sized its pools from.
|
||||
! grep -qE -- '^--?t$|^--threads$' "$ARGS_FILE"
|
||||
}
|
||||
|
||||
@test "an empty device value is the CPU rollback: no --device reaches argv" {
|
||||
# The same entrypoint with one key cleared, which is the rollback the env
|
||||
# header documents. A script-level default that survived an explicitly empty
|
||||
# value would leave the endpoint on the iGPU with no way back except a
|
||||
# rebuild.
|
||||
cat > "$TEST_TMP/fake-tts-server" <<'FAKE'
|
||||
#!/usr/bin/env bash
|
||||
printf '%s\n' "$@" > "$ARGS_FILE"
|
||||
FAKE
|
||||
chmod +x "$TEST_TMP/fake-tts-server"
|
||||
mkdir -p "$TEST_TMP/models"
|
||||
: > "$TEST_TMP/models/$TALKER"
|
||||
: > "$TEST_TMP/models/$CODEC"
|
||||
export QWENTTS_MODEL="$TEST_TMP/models/$TALKER"
|
||||
export QWENTTS_CODEC="$TEST_TMP/models/$CODEC"
|
||||
export QWENTTS_BIN="$TEST_TMP/fake-tts-server"
|
||||
export ARGS_FILE="$TEST_TMP/argv.txt"
|
||||
export QWENTTS_DEVICE=""
|
||||
|
||||
run bash "$START"
|
||||
[ "$status" -eq 0 ] || { echo "$output"; false; }
|
||||
! grep -qx -- '--device' "$ARGS_FILE"
|
||||
}
|
||||
|
||||
@test "missing weights are a refusal that names the fetcher, before the port is bound" {
|
||||
cat > "$TEST_TMP/fake-tts-server" <<'FAKE'
|
||||
#!/usr/bin/env bash
|
||||
@@ -627,17 +654,23 @@ PY
|
||||
@test "the image build is the pinned commit with the proven cmake line" {
|
||||
# GGML_BLAS=OFF is forced by the host (libopenblas.so.0 present, no dev
|
||||
# headers) and upstream's own Dockerfile passes it ON, so this file is not a
|
||||
# copy of upstream on purpose. -j 8 and the OFF-for-every-GPU-backend list
|
||||
# are what the 2026-10-18 trial ran.
|
||||
# copy of upstream on purpose. -j 8 is what the 2026-10-18 trial ran;
|
||||
# GGML_VULKAN=ON is the 2026-10-19 iGPU cutover, and the two greps below are
|
||||
# the packages that door needs at build time and at run time.
|
||||
grep -qE '^ARG QWENTTS_COMMIT=[0-9a-f]{40}$' "$CF"
|
||||
grep -qF '5916bf7c79dbb4e66fc059cdc507a79a23a28bb4' "$CF"
|
||||
grep -qE 'git -C /src checkout --detach' "$CF"
|
||||
grep -qE 'submodule update --init' "$CF" # ggml is a submodule; without it the build cannot configure
|
||||
for flag in -DGGML_CCACHE=OFF -DGGML_BACKEND_DL=OFF -DGGML_CPU_ALL_VARIANTS=OFF \
|
||||
-DGGML_OPENMP=ON -DGGML_BLAS=OFF -DGGML_CUDA=OFF -DGGML_HIP=OFF \
|
||||
-DGGML_VULKAN=OFF -DGGML_METAL=OFF -DGGML_SYCL=OFF -DGGML_RPC=OFF; do
|
||||
-DGGML_VULKAN=ON -DGGML_METAL=OFF -DGGML_SYCL=OFF -DGGML_RPC=OFF; do
|
||||
grep -qF -- "$flag" "$CF" || { echo "build line lost $flag"; false; }
|
||||
done
|
||||
# glslc is not in glslang-tools on this distro, and the configure fails
|
||||
# without it; an image with the loader and no RADV ICD enumerates zero
|
||||
# devices and dies in device lookup after the weights load.
|
||||
grep -qE 'libvulkan-dev glslc spirv-headers' "$CF"
|
||||
grep -qE 'libvulkan1 mesa-vulkan-drivers' "$CF"
|
||||
grep -qE 'cmake --build build -j 8' "$CF"
|
||||
# OpenMP on means the runtime stage needs the OpenMP runtime, and the probe
|
||||
# runs as /bin/sh -c, so the runtime stage needs curl.
|
||||
|
||||
Reference in New Issue
Block a user