From 786c4dc7639140185d235a43ecc36779ffcb6f08 Mon Sep 17 00:00:00 2001 From: hexonal Date: Tue, 4 Aug 2026 04:05:42 -0400 Subject: [PATCH] =?UTF-8?q?feat(webui):=20=E6=8E=A2=E6=B5=8B=E6=9C=AC?= =?UTF-8?q?=E6=9C=BA=E7=9C=9F=E5=AE=9E=E5=8F=AF=E7=94=A8=E7=9A=84=E5=8A=A0?= =?UTF-8?q?=E9=80=9F=E5=99=A8=EF=BC=8CApple=20Silicon=20=E4=B8=8A=E4=B8=8D?= =?UTF-8?q?=E5=86=8D=E9=BB=98=E8=AE=A4=E9=80=80=E5=9B=9E=20CPU?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 设备下拉是 CPU 优先写死的,所以在 Apple Silicon 的 Mac 上,默认选项**静默忽略 了 GPU** —— 用户不动它就是在 CPU 上跑推理,而界面上没有任何提示说本机其实有 MPS 可用。 探测必须放在服务端:浏览器看不到 torch 是按什么后端编译的,只有 Python 进程 知道 `torch.backends.mps.is_available()` 的答案。所以 `/api/available-models` 多返回一个 `recommended_device`,前端拿到后预选对应项,并把选项文本写进提示行 (`detected: ...`),让「为什么选了这个」也可见。 顺序是 cuda -> mps -> cpu。torch 缺失或导入失败时退回 cpu —— 这条路径上 MODEL_AVAILABLE 本来就是 False,页面走的是模拟数据。 --- webui/app.py | 23 ++++++++++++++++++++++- webui/templates/index.html | 17 +++++++++++++++++ 2 files changed, 39 insertions(+), 1 deletion(-) diff --git a/webui/app.py b/webui/app.py index d240a3729..6b1b4de4b 100644 --- a/webui/app.py +++ b/webui/app.py @@ -662,12 +662,33 @@ def load_model(): except Exception as e: return jsonify({'error': f'Model loading failed: {str(e)}'}), 500 +def recommended_device(): + """Best device actually present on this machine. + + The UI's is authored CPU-first, so on an Apple Silicon Mac the + // default silently ignored the GPU; the server detects the device + // because only it can see what torch was built against. + function applyRecommendedDevice(device) { + if (!device) return; + const select = document.getElementById('device-select'); + const match = Array.from(select.options).find(o => o.value === device); + if (!match) return; + select.value = device; + const hint = select.parentElement.querySelector('.form-text'); + if (hint) { + hint.textContent = `Select the device to run the model on (detected: ${match.textContent})`; + } + } + // Populate model selection dropdown function populateModelSelect() { const modelSelect = document.getElementById('model-select');