diff --git a/studio/frontend/src/features/chat/chat-settings-sheet.tsx b/studio/frontend/src/features/chat/chat-settings-sheet.tsx index ecb6707a04..bd22cc4f55 100644 --- a/studio/frontend/src/features/chat/chat-settings-sheet.tsx +++ b/studio/frontend/src/features/chat/chat-settings-sheet.tsx @@ -723,11 +723,11 @@ export function ChatSettingsPanel({ const autoLayers = isManual && gpuLayers < 0; // GPUs actually in use: the picked subset, or all visible when none picked. const gpusInUse = selectedGpuIds ?? gpuDevices.map((d) => d.index); - // TP is off with fewer than 2 GPUs in use (single GPU, or the picker narrowed - // to one): tensor split is a no-op there and aborts on some archs. Mirrors the - // multi-GPU gate on the GPU picker / Split ratio. (Under Auto layers the whole - // TP control is hidden -- llama.cpp's --fit aborts under --split-mode tensor.) - const tpDisabled = gpusInUse.length <= 1; + // The picker must keep one GPU selected. + const singleGpuInUse = gpusInUse.length <= 1; + // TP needs at least two GPUs because tensor split is a no-op on one and may + // abort. Auto layers hides TP because --fit aborts under --split-mode tensor. + const tpDisabled = singleGpuInUse; // Manual gpu-layers ceiling = model layer count + 1 (else a safe fallback): // llama.cpp counts the output layer as one more offloadable layer past the // repeating blocks ("offloaded 33/33" needs -ngl 33 on a 32-block model), so @@ -1537,7 +1537,7 @@ export function ChatSettingsPanel({ Which GPUs this model may use. Unchecked GPUs are hidden from llama.cpp (CUDA_VISIBLE_DEVICES, or HIP_VISIBLE_DEVICES on ROCm). Leave all checked to use - every GPU. + every GPU. At least one GPU must stay selected.
@@ -1557,7 +1557,10 @@ export function ChatSettingsPanel({ checked={isGpuChecked(d.index)} onCheckedChange={() => toggleGpu(d.index)} data-test-id={`gpu-pick-${d.index}`} - disabled={modelControlsDisabled} + disabled={ + modelControlsDisabled || + (isGpuChecked(d.index) && singleGpuInUse) + } />
))}