Skip NCNN install on headless/no-Vulkan machines

- Add _vulkan_available(): checks /dev/dri/renderD* on Linux, assumes
  true on macOS/Windows; set REALESRGAN_NCNN=force to override
- Add _test_ncnn_binary(): test-runs the binary after install and checks
  stderr for "no vulkan" — marks skipped if Vulkan init fails at runtime
- ensure_ncnn_installed() now returns early with state=skipped when no
  Vulkan detected, avoiding a wasted ~30MB download on CPU-only servers
- Recommend PyTorch CPU when available on headless (AI quality, slow but
  works); Lanczos as final fallback
- Frontend: handle state=skipped immediately (no polling needed), show
  brief informational toast; show "Headless server" note in dialog

https://claude.ai/code/session_01B58MaJCU1R6KwBDJCp8AfN
This commit is contained in:
Claude
2026-06-10 00:50:09 +00:00
parent ed2a0d7f0c
commit 717f482987
2 changed files with 154 additions and 64 deletions
+22 -5
View File
@@ -81,7 +81,13 @@ class Image_upscale_class {
deviceNote += 'NCNN Vulkan binary found. ';
}
if (!caps.realesrgan_pytorch && !caps.realesrgan_ncnn) {
deviceNote = 'No AI upscaler available — Lanczos only.';
var installState = (caps.ncnn_install_status || {}).state;
if (installState === 'skipped') {
deviceNote = 'Headless server — no Vulkan GPU. Lanczos only. '
+ 'Install Real-ESRGAN PyTorch for AI quality on CPU.';
} else {
deviceNote = 'No AI upscaler available — Lanczos only.';
}
}
var _this = this;
@@ -126,16 +132,22 @@ class Image_upscale_class {
}
/**
* Poll install-status until done/failed, showing a progress bar notification.
* Poll install-status until done/failed/skipped, showing a progress bar.
* On headless machines the server sets state=skipped immediately — no wait.
*/
async _waitForInstall(caps) {
var installStatus = caps.ncnn_install_status || {};
if (installStatus.state === 'done' || installStatus.state === 'failed') {
var terminalStates = ['done', 'failed', 'skipped'];
if (terminalStates.includes(installStatus.state)) {
if (installStatus.state === 'skipped') {
// Headless — just proceed, dialog will show Lanczos or PyTorch CPU
alertify.message(installStatus.message || 'No Vulkan GPU — using CPU upscaler.', 4);
}
return;
}
return new Promise((resolve) => {
var msg = alertify.message(
alertify.message(
`<div>Installing Real-ESRGAN AI upscaler…<br>
<progress id="esrgan-install-progress" value="0" max="100"
style="width:100%;margin-top:6px;"></progress>
@@ -158,7 +170,12 @@ class Image_upscale_class {
if (s.state === 'done') {
clearInterval(poll);
alertify.dismissAll();
alertify.success('Real-ESRGAN NCNN installed');
alertify.success('Real-ESRGAN NCNN installed.');
resolve();
} else if (s.state === 'skipped') {
clearInterval(poll);
alertify.dismissAll();
alertify.message(s.message || 'No Vulkan GPU — using CPU upscaler.', 4);
resolve();
} else if (s.state === 'failed') {
clearInterval(poll);